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