e9ed21c21710ff08faeb32a5ae44a0ddedb8b0ba
[Packages/TYPO3.CMS.git] / typo3 / sysext / recycler / Classes / Task / CleanerTask.php
1 <?php
2 namespace TYPO3\CMS\Recycler\Task;
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 use TYPO3\CMS\Core\Utility\GeneralUtility;
17
18 /**
19 * A task that should be run regularly that deletes deleted
20 * datasets from the DB.
21 */
22 class CleanerTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
23 {
24 /**
25 * @var int The time period, after which the rows are deleted
26 */
27 protected $period = 0;
28
29 /**
30 * @var array The tables to clean
31 */
32 protected $tcaTables = array();
33
34 /**
35 * @var \TYPO3\CMS\Core\Database\DatabaseConnection
36 */
37 protected $databaseConnection = null;
38
39 /**
40 * The main method of the task. Iterates through
41 * the tables and calls the cleaning function
42 *
43 * @return bool Returns TRUE on successful execution, FALSE on error
44 */
45 public function execute()
46 {
47 $success = true;
48 $tables = $this->getTcaTables();
49 foreach ($tables as $table) {
50 if (!$this->cleanTable($table)) {
51 $success = false;
52 }
53 }
54
55 return $success;
56 }
57
58 /**
59 * Executes the delete-query for the given table
60 *
61 * @param string $tableName
62 * @return bool
63 */
64 protected function cleanTable($tableName)
65 {
66 $queryParts = array();
67 if (isset($GLOBALS['TCA'][$tableName]['ctrl']['delete'])) {
68 $queryParts[] = $GLOBALS['TCA'][$tableName]['ctrl']['delete'] . ' = 1';
69 if ($GLOBALS['TCA'][$tableName]['ctrl']['tstamp']) {
70 $dateBefore = $this->getPeriodAsTimestamp();
71 $queryParts[] = $GLOBALS['TCA'][$tableName]['ctrl']['tstamp'] . ' < ' . $dateBefore;
72 }
73 $where = implode(' AND ', $queryParts);
74
75 $this->checkFileResourceFieldsBeforeDeletion($tableName, $where);
76
77 $this->getDatabaseConnection()->exec_DELETEquery($tableName, $where);
78 }
79
80 return $this->getDatabaseConnection()->sql_error() === '';
81 }
82
83 /**
84 * Returns the information shown in the task-list
85 *
86 * @return string Information-text fot the scheduler task-list
87 */
88 public function getAdditionalInformation()
89 {
90 $message = '';
91
92 $message .= sprintf(
93 $this->getLanguageService()->sL('LLL:EXT:recycler/Resources/Private/Language/locallang_tasks.xlf:cleanerTaskDescriptionTables'),
94 implode(', ', $this->getTcaTables())
95 );
96
97 $message .= '; ';
98
99 $message .= sprintf(
100 $this->getLanguageService()->sL('LLL:EXT:recycler/Resources/Private/Language/locallang_tasks.xlf:cleanerTaskDescriptionDays'),
101 $this->getPeriod()
102 );
103
104 return $message;
105 }
106
107 /**
108 * Sets the period after which a row is deleted
109 *
110 * @param int $period
111 */
112 public function setPeriod($period)
113 {
114 $this->period = (int)$period;
115 }
116
117 /**
118 * Returns the period after which a row is deleted
119 *
120 * @return int
121 */
122 public function getPeriod()
123 {
124 return $this->period;
125 }
126
127 /**
128 * @return int
129 */
130 public function getPeriodAsTimestamp()
131 {
132 return strtotime('-' . $this->getPeriod() . ' days');
133 }
134
135 /**
136 * Sets the TCA-tables which are cleaned
137 *
138 * @param array $tcaTables
139 */
140 public function setTcaTables($tcaTables = array())
141 {
142 $this->tcaTables = $tcaTables;
143 }
144
145 /**
146 * Returns the TCA-tables which are cleaned
147 *
148 * @return array
149 */
150 public function getTcaTables()
151 {
152 return $this->tcaTables;
153 }
154
155 /**
156 * @param \TYPO3\CMS\Core\Database\DatabaseConnection
157 */
158 public function setDatabaseConnection($databaseConnection)
159 {
160 $this->databaseConnection = $databaseConnection;
161 }
162
163 /**
164 * Checks if the table has fields for uploaded files and removes those files.
165 *
166 * @param string $table
167 * @param string $where
168 * @return void
169 */
170 protected function checkFileResourceFieldsBeforeDeletion($table, $where)
171 {
172 $fieldList = $this->getFileResourceFields($table);
173 if (!empty($fieldList)) {
174 $this->deleteFilesForTable($table, $where, $fieldList);
175 }
176 }
177
178 /**
179 * Removes all files from the given field list in the table.
180 *
181 * @param string $table
182 * @param string $where
183 * @param array $fieldList
184 * @return void
185 */
186 protected function deleteFilesForTable($table, $where, array $fieldList)
187 {
188 $rows = $this->getDatabaseConnection()->exec_SELECTgetRows(
189 implode(',', $fieldList),
190 $table,
191 $where
192 );
193 foreach ($rows as $row) {
194 foreach ($fieldList as $fieldName) {
195 $uploadDir = PATH_site . $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['uploadfolder'] . '/';
196 $fileList = GeneralUtility::trimExplode(',', $row[$fieldName]);
197 foreach ($fileList as $fileName) {
198 @unlink($uploadDir . $fileName);
199 }
200 }
201 }
202 }
203
204 /**
205 * Checks the $TCA for fields that can list file resources.
206 *
207 * @param string $table
208 * @return array
209 */
210 protected function getFileResourceFields($table)
211 {
212 $result = array();
213 if (isset($GLOBALS['TCA'][$table]['columns'])) {
214 foreach ($GLOBALS['TCA'][$table]['columns'] as $fieldName => $fieldConfiguration) {
215 if ($fieldConfiguration['config']['type'] === 'group'
216 && $fieldConfiguration['config']['internal_type'] === 'file'
217 ) {
218 $result[] = $fieldName;
219 break;
220 }
221 }
222 }
223 return $result;
224 }
225
226 /**
227 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
228 */
229 protected function getDatabaseConnection()
230 {
231 if ($this->databaseConnection === null) {
232 $this->databaseConnection = $GLOBALS['TYPO3_DB'];
233 }
234 return $this->databaseConnection;
235 }
236
237 /**
238 * @return \TYPO3\CMS\Lang\LanguageService
239 */
240 protected function getLanguageService()
241 {
242 return $GLOBALS['LANG'];
243 }
244 }