Apply PSR-12 code style (#3886)
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / cronjob / DailyCleanUpCronjob.class.php
1 <?php
2
3 namespace wcf\system\cronjob;
4
5 use wcf\data\cronjob\Cronjob;
6 use wcf\data\object\type\ObjectTypeCache;
7 use wcf\system\flood\FloodControl;
8 use wcf\system\user\multifactor\EmailMultifactorMethod;
9 use wcf\system\visitTracker\VisitTracker;
10 use wcf\system\WCF;
11 use wcf\util\FileUtil;
12
13 /**
14 * Cronjob for a daily system cleanup.
15 *
16 * @author Marcel Werk
17 * @copyright 2001-2020 WoltLab GmbH
18 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
19 * @package WoltLabSuite\Core\System\Cronjob
20 */
21 class DailyCleanUpCronjob extends AbstractCronjob
22 {
23 /**
24 * @inheritDoc
25 */
26 public function execute(Cronjob $cronjob)
27 {
28 parent::execute($cronjob);
29
30 // clean up search keywords
31 $sql = "SELECT AVG(searches) AS searches
32 FROM wcf" . WCF_N . "_search_keyword";
33 $statement = WCF::getDB()->prepareStatement($sql);
34 $statement->execute();
35 if (($row = $statement->fetchArray()) !== false) {
36 $sql = "DELETE FROM wcf" . WCF_N . "_search_keyword
37 WHERE searches <= ?
38 AND lastSearchTime < ?";
39 $statement = WCF::getDB()->prepareStatement($sql);
40 $statement->execute([
41 \floor($row['searches'] / 4),
42 TIME_NOW - 86400 * 30,
43 ]);
44 }
45
46 // clean up notifications
47 $sql = "DELETE FROM wcf" . WCF_N . "_user_notification
48 WHERE time < ?";
49 $statement = WCF::getDB()->prepareStatement($sql);
50 $statement->execute([
51 TIME_NOW - 86400 * USER_CLEANUP_NOTIFICATION_LIFETIME,
52 ]);
53
54 // clean up user activity events
55 $sql = "DELETE FROM wcf" . WCF_N . "_user_activity_event
56 WHERE time < ?";
57 $statement = WCF::getDB()->prepareStatement($sql);
58 $statement->execute([
59 TIME_NOW - 86400 * USER_CLEANUP_ACTIVITY_EVENT_LIFETIME,
60 ]);
61
62 // clean up profile visitors
63 $sql = "DELETE FROM wcf" . WCF_N . "_user_profile_visitor
64 WHERE time < ?";
65 $statement = WCF::getDB()->prepareStatement($sql);
66 $statement->execute([
67 TIME_NOW - 86400 * USER_CLEANUP_PROFILE_VISITOR_LIFETIME,
68 ]);
69
70 // tracked visits
71 $sql = "DELETE FROM wcf" . WCF_N . "_tracked_visit
72 WHERE objectTypeID = ?
73 AND visitTime < ?";
74 $statement1 = WCF::getDB()->prepareStatement($sql);
75 $sql = "DELETE FROM wcf" . WCF_N . "_tracked_visit_type
76 WHERE objectTypeID = ?
77 AND visitTime < ?";
78 $statement2 = WCF::getDB()->prepareStatement($sql);
79
80 WCF::getDB()->beginTransaction();
81 $objectTypes = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.visitTracker.objectType');
82 foreach ($objectTypes as $objectType) {
83 // get lifetime
84 $lifetime = ($objectType->lifetime ?: VisitTracker::DEFAULT_LIFETIME);
85
86 // delete data
87 $statement1->execute([
88 $objectType->objectTypeID,
89 $lifetime,
90 ]);
91 $statement2->execute([
92 $objectType->objectTypeID,
93 $lifetime,
94 ]);
95 }
96 WCF::getDB()->commitTransaction();
97
98 // clean up cronjob log
99 $sql = "DELETE FROM wcf" . WCF_N . "_cronjob_log
100 WHERE execTime < ?";
101 $statement = WCF::getDB()->prepareStatement($sql);
102 $statement->execute([
103 TIME_NOW - (86400 * 7),
104 ]);
105
106 // clean up session access log
107 $sql = "DELETE FROM wcf" . WCF_N . "_acp_session_access_log
108 WHERE sessionLogID IN (
109 SELECT sessionLogID
110 FROM wcf" . WCF_N . "_acp_session_log
111 WHERE lastActivityTime < ?
112 )";
113 $statement = WCF::getDB()->prepareStatement($sql);
114 $statement->execute([
115 TIME_NOW - (86400 * 30),
116 ]);
117
118 // clean up session log
119 $sql = "DELETE FROM wcf" . WCF_N . "_acp_session_log
120 WHERE lastActivityTime < ?";
121 $statement = WCF::getDB()->prepareStatement($sql);
122 $statement->execute([
123 TIME_NOW - (86400 * 30),
124 ]);
125
126 // clean up search data
127 $sql = "DELETE FROM wcf" . WCF_N . "_search
128 WHERE searchTime < ?";
129 $statement = WCF::getDB()->prepareStatement($sql);
130 $statement->execute([
131 TIME_NOW - 86400,
132 ]);
133
134 // clean up expired edit history entries
135 if (MODULE_EDIT_HISTORY) {
136 if (EDIT_HISTORY_EXPIRATION) {
137 $sql = "DELETE FROM wcf" . WCF_N . "_edit_history_entry
138 WHERE obsoletedAt < ?";
139 $statement = WCF::getDB()->prepareStatement($sql);
140 $statement->execute([
141 TIME_NOW - 86400 * EDIT_HISTORY_EXPIRATION,
142 ]);
143 }
144 } else {
145 // edit history is disabled, prune old versions
146 $sql = "DELETE FROM wcf" . WCF_N . "_edit_history_entry";
147 $statement = WCF::getDB()->prepareStatement($sql);
148 $statement->execute();
149 }
150
151 // clean up user authentication failure log
152 if (ENABLE_USER_AUTHENTICATION_FAILURE) {
153 $sql = "DELETE FROM wcf" . WCF_N . "_user_authentication_failure
154 WHERE time < ?";
155 $statement = WCF::getDB()->prepareStatement($sql);
156 $statement->execute([
157 TIME_NOW - 86400 * USER_AUTHENTICATION_FAILURE_EXPIRATION,
158 ]);
159 }
160
161 if (MODIFICATION_LOG_EXPIRATION > 0) {
162 $sql = "DELETE FROM wcf" . WCF_N . "_modification_log
163 WHERE time < ?";
164 $statement = WCF::getDB()->prepareStatement($sql);
165 $statement->execute([
166 TIME_NOW - 86400 * MODIFICATION_LOG_EXPIRATION,
167 ]);
168 }
169
170 // clean up error logs
171 $files = @\glob(WCF_DIR . 'log/*.txt');
172 if (\is_array($files)) {
173 foreach ($files as $filename) {
174 if (\filemtime($filename) < TIME_NOW - 86400 * 14) {
175 @\unlink($filename);
176 }
177 }
178 }
179
180 // clean up temporary folder
181 $tempFolder = FileUtil::getTempFolder();
182 $it = new \RecursiveIteratorIterator(
183 new \RecursiveDirectoryIterator($tempFolder, \FilesystemIterator::SKIP_DOTS),
184 \RecursiveIteratorIterator::CHILD_FIRST
185 );
186 foreach ($it as $file) {
187 if ($file->getPathname() === $tempFolder) {
188 continue;
189 }
190 if ($file->getPathname() === $tempFolder . '/.htaccess') {
191 continue;
192 }
193
194 if ($file->getMTime() < TIME_NOW - 86400) {
195 if ($file->isDir()) {
196 @\rmdir($file->getPathname());
197 } elseif ($file->isFile()) {
198 @\unlink($file->getPathname());
199 }
200 }
201 }
202
203 // clean up proxy images
204 if (MODULE_IMAGE_PROXY && IMAGE_PROXY_ENABLE_PRUNE) {
205 $it = new \RecursiveIteratorIterator(
206 new \RecursiveDirectoryIterator(WCF_DIR . 'images/proxy/', \FilesystemIterator::SKIP_DOTS),
207 \RecursiveIteratorIterator::CHILD_FIRST
208 );
209 foreach ($it as $file) {
210 if ($file->getPathname() === WCF_DIR . 'images/proxy/.htaccess') {
211 continue;
212 }
213
214 if ($file->isFile() && $file->getMTime() < (TIME_NOW - 86400 * IMAGE_PROXY_EXPIRATION)) {
215 @\unlink($file->getPathname());
216 }
217 }
218 }
219
220 if (BLACKLIST_SFS_ENABLE) {
221 $timeLimit = TIME_NOW - 31 * 86400;
222
223 $sql = "DELETE FROM wcf" . WCF_N . "_blacklist_entry
224 WHERE lastSeen < ?";
225 $statement = WCF::getDB()->prepareStatement($sql);
226 $statement->execute([
227 \gmdate('Y-m-d H:i:s', $timeLimit),
228 ]);
229
230 $sql = "DELETE FROM wcf" . WCF_N . "_blacklist_status
231 WHERE date < ?";
232 $statement = WCF::getDB()->prepareStatement($sql);
233 $statement->execute([
234 \gmdate('Y-m-d', $timeLimit),
235 ]);
236 }
237
238 FloodControl::getInstance()->prune();
239 EmailMultifactorMethod::prune();
240 }
241 }