64c4a4765bea858b6566328da48460baafe083ab
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Controller / Action / Tool / CleanUp.php
1 <?php
2 namespace TYPO3\CMS\Install\Controller\Action\Tool;
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\Install\Controller\Action;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19
20 /**
21 * Clean up page
22 */
23 class CleanUp extends Action\AbstractAction {
24
25 /**
26 * Status messages of submitted actions
27 *
28 * @var array
29 */
30 protected $actionMessages = array();
31
32 /**
33 * Executes the tool
34 *
35 * @return string Rendered content
36 */
37 protected function executeAction() {
38 if (isset($this->postValues['set']['clearTables'])) {
39 $this->actionMessages[] = $this->clearSelectedTables();
40 }
41 if (isset($this->postValues['set']['resetBackendUserUc'])) {
42 $this->actionMessages[] = $this->resetBackendUserUc();
43 }
44
45 $this->view->assign('cleanableTables', $this->getCleanableTableList());
46
47 $typo3TempData = $this->getTypo3TempStatistics();
48 $this->view->assign('typo3TempData', $typo3TempData);
49
50 $this->view->assign('actionMessages', $this->actionMessages);
51 return $this->view->render();
52 }
53
54 /**
55 * Get list of existing tables that could be truncated.
56 *
57 * @return array List of cleanable tables with name, description and number of rows
58 */
59 protected function getCleanableTableList() {
60 $tableCandidates = array(
61 array(
62 'name' => 'be_sessions',
63 'description' => 'Backend user sessions'
64 ),
65 array(
66 'name' => 'cache_imagesizes',
67 'description' => 'Cached image sizes',
68 ),
69 array(
70 'name' => 'cache_md5params',
71 'description' => 'Frontend redirects',
72 ),
73 array(
74 'name' => 'fe_sessions',
75 'description' => 'Frontend user sessions',
76 ),
77 array(
78 'name' => 'fe_session_data',
79 'description' => 'Frontend user session data',
80 ),
81 array(
82 'name' => 'sys_history',
83 'description' => 'Tracking of database record changes through TYPO3 backend forms',
84 ),
85 array(
86 'name' => 'sys_lockedrecords',
87 'description' => 'Record locking of backend user editing',
88 ),
89 array(
90 'name' => 'sys_log',
91 'description' => 'General log table',
92 ),
93 array(
94 'name' => 'sys_preview',
95 'description' => 'Workspace preview links',
96 ),
97 array(
98 'name' => 'tx_extensionmanager_domain_model_extension',
99 'description' => 'List of TER extensions',
100 ),
101 array(
102 'name' => 'tx_rsaauth_keys',
103 'description' => 'Login process key storage'
104 ),
105 );
106 $database = $this->getDatabaseConnection();
107 $allTables = array_keys($database->admin_get_tables());
108 $tables = array();
109 foreach ($tableCandidates as $candidate) {
110 if (in_array($candidate['name'], $allTables)) {
111 $candidate['rows'] = $database->exec_SELECTcountRows('*', $candidate['name']);
112 $tables[] = $candidate;
113 }
114 }
115 return $tables;
116 }
117
118 /**
119 * Truncate selected tables
120 *
121 * @return \TYPO3\CMS\Install\Status\StatusInterface
122 */
123 protected function clearSelectedTables() {
124 $clearedTables = array();
125 $database = $this->getDatabaseConnection();
126 foreach ($this->postValues['values'] as $tableName => $selected) {
127 if ($selected == 1) {
128 $database->exec_TRUNCATEquery($tableName);
129 $clearedTables[] = $tableName;
130 }
131 }
132 if (count($clearedTables)) {
133 /** @var \TYPO3\CMS\Install\Status\OkStatus $message */
134 $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\OkStatus::class);
135 $message->setTitle('Cleared tables');
136 $message->setMessage('List of cleared tables: ' . implode(', ', $clearedTables));
137 } else {
138 /** @var \TYPO3\CMS\Install\Status\OkStatus $message */
139 $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\InfoStatus::class);
140 $message->setTitle('No tables selected to clear');
141 }
142 return $message;
143 }
144
145 /**
146 * Reset uc field of all be_users to empty string
147 *
148 * @return \TYPO3\CMS\Install\Status\StatusInterface
149 */
150 protected function resetBackendUserUc() {
151 $database = $this->getDatabaseConnection();
152 $database->exec_UPDATEquery('be_users', '', array('uc' => ''));
153 /** @var \TYPO3\CMS\Install\Status\OkStatus $message */
154 $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\OkStatus::class);
155 $message->setTitle('Reset all backend users preferences');
156 return $message;
157 }
158
159 /**
160 * Data for the typo3temp/ deletion view
161 *
162 * @return array Data array
163 */
164 protected function getTypo3TempStatistics() {
165 $data = array();
166 $pathTypo3Temp= PATH_site . 'typo3temp/';
167 $postValues = $this->postValues['values'];
168
169 $condition = '0';
170 if (isset($postValues['condition'])) {
171 $condition = $postValues['condition'];
172 }
173 $numberOfFilesToDelete = 0;
174 if (isset($postValues['numberOfFiles'])) {
175 $numberOfFilesToDelete = $postValues['numberOfFiles'];
176 }
177 $subDirectory = '';
178 if (isset($postValues['subDirectory'])) {
179 $subDirectory = $postValues['subDirectory'];
180 }
181
182 // Run through files
183 $fileCounter = 0;
184 $deleteCounter = 0;
185 $criteriaMatch = 0;
186 $timeMap = array('day' => 1, 'week' => 7, 'month' => 30);
187 $directory = @dir($pathTypo3Temp . $subDirectory);
188 if (is_object($directory)) {
189 while ($entry = $directory->read()) {
190 $absoluteFile = $pathTypo3Temp . $subDirectory . '/' . $entry;
191 if (@is_file($absoluteFile)) {
192 $ok = FALSE;
193 $fileCounter++;
194 if ($condition) {
195 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($condition)) {
196 if (filesize($absoluteFile) > $condition * 1024) {
197 $ok = TRUE;
198 }
199 } else {
200 if (fileatime($absoluteFile) < $GLOBALS['EXEC_TIME'] - (int)$timeMap[$condition] * 60 * 60 * 24) {
201 $ok = TRUE;
202 }
203 }
204 } else {
205 $ok = TRUE;
206 }
207 if ($ok) {
208 $hashPart = substr(basename($absoluteFile), -14, 10);
209 // This is a kind of check that the file being deleted has a 10 char hash in it
210 if (
211 !preg_match('/[^a-f0-9]/', $hashPart)
212 || substr($absoluteFile, -6) === '.cache'
213 || substr($absoluteFile, -4) === '.tbl'
214 || substr($absoluteFile, -4) === '.css'
215 || substr($absoluteFile, -3) === '.js'
216 || substr($absoluteFile, -5) === '.gzip'
217 || substr(basename($absoluteFile), 0, 8) === 'installTool'
218 ) {
219 if ($numberOfFilesToDelete && $deleteCounter < $numberOfFilesToDelete) {
220 $deleteCounter++;
221 unlink($absoluteFile);
222 } else {
223 $criteriaMatch++;
224 }
225 }
226 }
227 }
228 }
229 $directory->close();
230 }
231 $data['numberOfFilesMatchingCriteria'] = $criteriaMatch;
232 $data['numberOfDeletedFiles'] = $deleteCounter;
233
234 if ($deleteCounter > 0) {
235 $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\OkStatus::class);
236 $message->setTitle('Deleted ' . $deleteCounter . ' files from typo3temp/' . $subDirectory . '/');
237 $this->actionMessages[] = $message;
238 }
239
240 $data['selectedCondition'] = $condition;
241 $data['numberOfFiles'] = $numberOfFilesToDelete;
242 $data['selectedSubDirectory'] = $subDirectory;
243
244 // Set up sub directory data
245 $data['subDirectories'] = array(
246 '' => array(
247 'name' => '',
248 'filesNumber' => count(GeneralUtility::getFilesInDir($pathTypo3Temp)),
249 ),
250 );
251 $directories = dir($pathTypo3Temp);
252 if (is_object($directories)) {
253 while ($entry = $directories->read()) {
254 if (is_dir($pathTypo3Temp . $entry) && $entry != '..' && $entry != '.') {
255 $data['subDirectories'][$entry]['name'] = $entry;
256 $data['subDirectories'][$entry]['filesNumber'] = count(GeneralUtility::getFilesInDir($pathTypo3Temp . $entry));
257 $data['subDirectories'][$entry]['selected'] = FALSE;
258 if ($entry === $data['selectedSubDirectory']) {
259 $data['subDirectories'][$entry]['selected'] = TRUE;
260 }
261 }
262 }
263 }
264 $data['numberOfFilesInSelectedDirectory'] = $data['subDirectories'][$data['selectedSubDirectory']]['filesNumber'];
265
266 return $data;
267 }
268
269 }