[FEATURE] Recover deleted pages recursively to top of rootline
[Packages/TYPO3.CMS.git] / typo3 / sysext / recycler / Classes / Utility / RecyclerUtility.php
1 <?php
2 namespace TYPO3\CMS\Recycler\Utility;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Core\Type\Bitmask\Permission;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20
21 /**
22 * Helper class for the 'recycler' extension.
23 */
24 class RecyclerUtility
25 {
26 /************************************************************
27 * USER ACCESS
28 *
29 *
30 ************************************************************/
31 /**
32 * Checks the page access rights (Code for access check mostly taken from FormEngine)
33 * as well as the table access rights of the user.
34 *
35 * @param string $table The table to check access for
36 * @param string $row Record array
37 * @return bool Returns TRUE is the user has access, or FALSE if not
38 */
39 public static function checkAccess($table, $row)
40 {
41 $backendUser = static::getBackendUser();
42
43 // Checking if the user has permissions? (Only working as a precaution, because the final permission check is always down in TCE. But it's good to notify the user on beforehand...)
44 // First, resetting flags.
45 $hasAccess = false;
46 $calcPRec = $row;
47 BackendUtility::fixVersioningPid($table, $calcPRec);
48 if (is_array($calcPRec)) {
49 if ($table === 'pages') {
50 // If pages:
51 // @todo: find a decent way for non-admins to get deleted pages respecting the permissions WITHOUT some isInWebMount stuff.
52 $calculatedPermissions = $backendUser->calcPerms($calcPRec);
53 $hasAccess = (bool)($calculatedPermissions & Permission::PAGE_EDIT);
54 } else {
55 $calculatedPermissions = $backendUser->calcPerms(BackendUtility::getRecord('pages', $calcPRec['pid']));
56 // Fetching pid-record first.
57 $hasAccess = (bool)($calculatedPermissions & Permission::CONTENT_EDIT);
58 }
59 // Check internals regarding access:
60 if ($hasAccess) {
61 $hasAccess = $backendUser->recordEditAccessInternals($table, $calcPRec);
62 }
63 }
64 if (!$backendUser->check('tables_modify', $table)) {
65 $hasAccess = false;
66 }
67 return $hasAccess;
68 }
69
70 /**
71 * Returns the path (visually) of a page $uid, fx. "/First page/Second page/Another subpage"
72 * Each part of the path will be limited to $titleLimit characters
73 * Deleted pages are filtered out.
74 *
75 * @param int $uid Page uid for which to create record path
76 * @param string $clause is additional where clauses, eg.
77 * @param int $titleLimit Title limit
78 * @param int $fullTitleLimit Title limit of Full title (typ. set to 1000 or so)
79 * @return mixed Path of record (string) OR array with short/long title if $fullTitleLimit is set.
80 */
81 public static function getRecordPath($uid, $clause = '', $titleLimit = 1000, $fullTitleLimit = 0)
82 {
83 $uid = (int)$uid;
84 $output = ($fullOutput = '/');
85 if ($uid === 0) {
86 return $output;
87 }
88 $databaseConnection = static::getDatabaseConnection();
89 $clause = trim($clause) !== '' ? ' AND ' . $clause : '';
90 $loopCheck = 100;
91 while ($loopCheck > 0) {
92 $loopCheck--;
93 $res = $databaseConnection->exec_SELECTquery('uid,pid,title,deleted,t3ver_oid,t3ver_wsid', 'pages', 'uid=' . $uid . $clause);
94 if ($res !== false) {
95 $row = $databaseConnection->sql_fetch_assoc($res);
96 $databaseConnection->sql_free_result($res);
97 BackendUtility::workspaceOL('pages', $row);
98 if (is_array($row)) {
99 BackendUtility::fixVersioningPid('pages', $row);
100 $uid = (int)$row['pid'];
101 $output = '/' . htmlspecialchars(GeneralUtility::fixed_lgd_cs($row['title'], $titleLimit)) . $output;
102 if ($row['deleted']) {
103 $output = '<span class="text-danger">' . $output . '</span>';
104 }
105 if ($fullTitleLimit) {
106 $fullOutput = '/' . htmlspecialchars(GeneralUtility::fixed_lgd_cs($row['title'], $fullTitleLimit)) . $fullOutput;
107 }
108 } else {
109 break;
110 }
111 } else {
112 break;
113 }
114 }
115 if ($fullTitleLimit) {
116 return array($output, $fullOutput);
117 } else {
118 return $output;
119 }
120 }
121
122 /**
123 * Gets the name of the field with the information whether a record is deleted.
124 *
125 * @param string $tableName Name of the table to get the deleted field for
126 * @return string Name of the field with the information whether a record is deleted
127 */
128 public static function getDeletedField($tableName)
129 {
130 $TCA = self::getTableTCA($tableName);
131 if ($TCA && isset($TCA['ctrl']['delete']) && $TCA['ctrl']['delete']) {
132 return $TCA['ctrl']['delete'];
133 }
134 return '';
135 }
136
137 /**
138 * Check if parent record is deleted
139 *
140 * @param int $pid
141 * @return bool
142 */
143 public static function isParentPageDeleted($pid) {
144 if ((int)$pid === 0) {
145 return false;
146 }
147 $db = static::getDatabaseConnection();
148 $res = $db->exec_SELECTquery('deleted', 'pages', 'uid=' . (int)$pid);
149 if ($res !== false) {
150 $record = $db->sql_fetch_assoc($res);
151 return (bool)$record['deleted'];
152 }
153 return false;
154 }
155
156 /**
157 * Get pid of uid
158 *
159 * @param int $uid
160 * @param string $table
161 * @return int
162 */
163 public static function getPidOfUid($uid, $table) {
164 $db = static::getDatabaseConnection();
165 $res = $db->exec_SELECTquery('pid', $table, 'uid=' . (int)$uid);
166 if ($res !== false) {
167 $record = $db->sql_fetch_assoc($res);
168 return $record['pid'];
169 }
170 return 0;
171 }
172
173 /**
174 * Gets the TCA of the table used in the current context.
175 *
176 * @param string $tableName Name of the table to get TCA for
177 * @return array|FALSE TCA of the table used in the current context
178 */
179 public static function getTableTCA($tableName)
180 {
181 $TCA = false;
182 if (isset($GLOBALS['TCA'][$tableName])) {
183 $TCA = $GLOBALS['TCA'][$tableName];
184 }
185 return $TCA;
186 }
187
188 /**
189 * Returns an instance of DatabaseConnection
190 *
191 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
192 */
193 protected static function getDatabaseConnection()
194 {
195 return $GLOBALS['TYPO3_DB'];
196 }
197
198 /**
199 * Returns the BackendUser
200 *
201 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
202 */
203 protected static function getBackendUser()
204 {
205 return $GLOBALS['BE_USER'];
206 }
207
208 /**
209 * Returns an instance of LanguageService
210 *
211 * @return \TYPO3\CMS\Lang\LanguageService
212 */
213 protected static function getLanguageService()
214 {
215 return $GLOBALS['LANG'];
216 }
217
218 /**
219 * Returns the modifyable tables of the current user
220 */
221 public static function getModifyableTables()
222 {
223 if ((bool)$GLOBALS['BE_USER']->user['admin']) {
224 $tables = array_keys($GLOBALS['TCA']);
225 } else {
226 $tables = explode(',', $GLOBALS['BE_USER']->groupData['tables_modify']);
227 }
228 return $tables;
229 }
230 }