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