PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.1
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
← All changes | back/Controllers/Configuration/Security.php +0 -599 10.0.1 → 11.1.1 View file →
@@ -1,599 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\Controllers\Configuration;
4 -
5 -use AcyMailing\Classes\UrlClass;
6 -use AcyMailing\Classes\UserClass;
7 -
8 -trait Security
9 -{
10 - private $messagesNoHtml = [];
11 -
12 - public function checkDB($returnMode = '', $fromConfiguration = true)
13 - {
14 - $correctTablesStructure = $this->getCorrectTablesStructure();
15 - $currentTablesStructure = $this->getCurrentTablesStructure($correctTablesStructure);
16 - $this->fixCurrentStructure($correctTablesStructure, $currentTablesStructure);
17 -
18 - $this->cleanDuplicatedUrls($fromConfiguration);
19 - $this->addMissingUserKeys();
20 -
21 - if ($returnMode === 'report') {
22 - return $this->messagesNoHtml;
23 - }
24 -
25 - if (empty($this->messagesNoHtml)) {
26 - echo '<i class="acymicon-check-circle acym__color__green"></i>';
27 - } else {
28 - $nbMessages = count($this->messagesNoHtml);
29 - foreach ($this->messagesNoHtml as $i => $oneMsg) {
30 - echo '<span style="color:'.$oneMsg['color'].'">'.$oneMsg['msg'].'</span>';
31 -
32 - if ($i < $nbMessages) {
33 - echo '<br />';
34 - }
35 - }
36 - }
37 -
38 - exit;
39 - }
40 -
41 - private function getCorrectTablesStructure(): array
42 - {
43 - $correctTablesStructure = [
44 - 'structure' => [],
45 - 'createTable' => [],
46 - 'indexes' => [],
47 - 'constraints' => [],
48 - ];
49 -
50 - $queries = file_get_contents(ACYM_BACK.'tables.sql');
51 - $tables = explode('CREATE TABLE IF NOT EXISTS ', $queries);
52 -
53 - foreach ($tables as $oneTable) {
54 - if (strpos($oneTable, '`#__') !== 0) {
55 - continue;
56 - }
57 -
58 - $tableName = substr($oneTable, 1, strpos($oneTable, '`', 1) - 1);
59 - $correctTablesStructure['createTable'][$tableName] = 'CREATE TABLE IF NOT EXISTS '.$oneTable;
60 - $correctTablesStructure['indexes'][$tableName] = [];
61 - $correctTablesStructure['constraints'][$tableName] = [];
62 -
63 - $fields = explode("\n", $oneTable);
64 - foreach ($fields as $key => $oneField) {
65 - if (strpos($oneField, '#__') === 1) {
66 - continue;
67 - }
68 - $oneField = rtrim(trim($oneField), ',');
69 -
70 - if (substr($oneField, 0, 1) === '`') {
71 - $columnName = substr($oneField, 1, strpos($oneField, '`', 1) - 1);
72 - $correctTablesStructure['structure'][$tableName][$columnName] = trim($oneField, ',');
73 - continue;
74 - }
75 -
76 - if (strpos($oneField, 'PRIMARY KEY') === 0) {
77 - $correctTablesStructure['indexes'][$tableName]['PRIMARY'] = $oneField;
78 - } elseif (strpos($oneField, 'INDEX') === 0) {
79 - $firstBackquotePos = strpos($oneField, '`');
80 - $indexName = substr($oneField, $firstBackquotePos + 1, strpos($oneField, '`', $firstBackquotePos + 1) - $firstBackquotePos - 1);
81 -
82 - $correctTablesStructure['indexes'][$tableName][$indexName] = $oneField;
83 - } elseif (strpos($oneField, 'FOREIGN KEY') !== false) {
84 - preg_match('/(#__fk.*)\`/Uis', $fields[$key - 1], $matchesConstraints);
85 - preg_match('/(#__.*)\`\(`(.*)`\)/Uis', $fields[$key + 1], $matchesTable);
86 - preg_match('/\`(.*)\`/Uis', $oneField, $matchesColumn);
87 - if (!empty($matchesConstraints) && !empty($matchesTable) && !empty($matchesColumn)) {
88 - $correctTablesStructure['constraints'][$tableName][$matchesConstraints[1]] = [
89 - 'table' => $matchesTable[1],
90 - 'column' => $matchesColumn[1],
91 - 'table_column' => $matchesTable[2],
92 - ];
93 - }
94 - }
95 - }
96 - }
97 -
98 - $correctTablesStructure['tableNames'] = array_keys($correctTablesStructure['structure']);
99 -
100 - return $correctTablesStructure;
101 - }
102 -
103 - private function getCurrentTablesStructure(array $correctTablesStructure): array
104 - {
105 - $currentTablesStructure = [];
106 -
107 - foreach ($correctTablesStructure['tableNames'] as $oneTableName) {
108 - try {
109 - $columns = acym_loadObjectList('SHOW COLUMNS FROM '.$oneTableName);
110 - } catch (\Exception $e) {
111 - $columns = null;
112 - }
113 -
114 - if (!empty($columns)) {
115 - foreach ($columns as $oneField) {
116 - $currentTablesStructure[$oneTableName][$oneField->Field] = $oneField->Field;
117 - }
118 - continue;
119 - }
120 -
121 - $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
122 - $this->messagesNoHtml[] = [
123 - 'error' => false,
124 - 'color' => 'blue',
125 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_LOAD_COLUMNS_ERROR', $oneTableName, $errorMessage),
126 - ];
127 -
128 - if (strpos($errorMessage, 'marked as crashed')) {
129 - try {
130 - $isError = acym_query('REPAIR TABLE '.$oneTableName);
131 - } catch (\Exception $e) {
132 - $isError = null;
133 - }
134 -
135 - if ($isError === null) {
136 - $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
137 - $this->messagesNoHtml[] = [
138 - 'error' => true,
139 - 'color' => 'red',
140 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_REPAIR_TABLE_ERROR', $oneTableName, $errorMessage),
141 - ];
142 - } else {
143 - $this->messagesNoHtml[] = [
144 - 'error' => false,
145 - 'color' => 'green',
146 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_REPAIR_TABLE_SUCCESS', $oneTableName),
147 - ];
148 - }
149 - continue;
150 - } else {
151 - try {
152 - $isError = acym_query($correctTablesStructure['createTable'][$oneTableName]);
153 - } catch (\Exception $e) {
154 - $isError = null;
155 - }
156 -
157 - if ($isError === null) {
158 - $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
159 - $this->messagesNoHtml[] = [
160 - 'error' => true,
161 - 'color' => 'red',
162 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_CREATE_TABLE_ERROR', $oneTableName, $errorMessage),
163 - ];
164 - } else {
165 - $this->messagesNoHtml[] = [
166 - 'error' => false,
167 - 'color' => 'green',
168 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_CREATE_TABLE_SUCCESS', $oneTableName),
169 - ];
170 - }
171 - }
172 - }
173 -
174 - return $currentTablesStructure;
175 - }
176 -
177 - private function fixCurrentStructure(array $correctTablesStructure, array $currentTablesStructure)
178 - {
179 - foreach ($correctTablesStructure['tableNames'] as $oneTableName) {
180 - if (empty($currentTablesStructure[$oneTableName])) {
181 - continue;
182 - }
183 -
184 - $this->addMissingColumns($correctTablesStructure['structure'][$oneTableName], $currentTablesStructure[$oneTableName], $oneTableName);
185 - $this->removeExtraColumns($correctTablesStructure['structure'][$oneTableName], $currentTablesStructure[$oneTableName], $oneTableName);
186 - $this->fixDefaultValues($correctTablesStructure['structure'][$oneTableName], $oneTableName);
187 - $this->addMissingTableKeys($correctTablesStructure['indexes'][$oneTableName], $oneTableName);
188 - $this->addMissingTableConstraints($correctTablesStructure['constraints'][$oneTableName], $oneTableName);
189 - }
190 - }
191 -
192 - private function addMissingColumns(array $correctTableColumns, array $currentTableColumnNames, string $oneTableName)
193 - {
194 - $idealColumnNames = array_keys($correctTableColumns);
195 - $missingColumns = array_diff($idealColumnNames, $currentTableColumnNames);
196 -
197 - if (empty($missingColumns)) {
198 - return;
199 - }
200 -
201 - foreach ($missingColumns as $oneColumn) {
202 - $this->messagesNoHtml[] = [
203 - 'error' => false,
204 - 'color' => 'blue',
205 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_MISSING_COLUMN', $oneColumn, $oneTableName),
206 - ];
207 -
208 - try {
209 - $isError = acym_query('ALTER TABLE '.$oneTableName.' ADD '.$correctTableColumns[$oneColumn]);
210 - } catch (\Exception $e) {
211 - $isError = null;
212 - }
213 -
214 - if ($isError === null) {
215 - $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
216 - $this->messagesNoHtml[] = [
217 - 'error' => true,
218 - 'color' => 'red',
219 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_ADD_COLUMN_ERROR', $oneColumn, $oneTableName, $errorMessage),
220 - ];
221 - } else {
222 - $this->messagesNoHtml[] = [
223 - 'error' => false,
224 - 'color' => 'green',
225 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_ADD_COLUMN_SUCCESS', $oneColumn, $oneTableName),
226 - ];
227 - }
228 - }
229 - }
230 -
231 - private function removeExtraColumns(array $correctTableColumns, array $currentTableColumnNames, string $oneTableName)
232 - {
233 - $idealColumnNames = array_keys($correctTableColumns);
234 - $extraColumns = array_diff($currentTableColumnNames, $idealColumnNames);
235 -
236 - if (empty($extraColumns)) {
237 - return;
238 - }
239 -
240 - foreach ($extraColumns as $oneColumn) {
241 - $this->messagesNoHtml[] = [
242 - 'error' => false,
243 - 'color' => 'blue',
244 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_EXTRA_COLUMN', $oneColumn, $oneTableName),
245 - ];
246 -
247 - try {
248 - $isError = acym_query('ALTER TABLE '.$oneTableName.' DROP COLUMN `'.acym_secureDBColumn($oneColumn).'`');
249 - } catch (\Exception $e) {
250 - $isError = null;
251 - }
252 -
253 - if ($isError === null) {
254 - $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
255 - $this->messagesNoHtml[] = [
256 - 'error' => true,
257 - 'color' => 'red',
258 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_EXTRA_COLUMN_ERROR', $oneColumn, $oneTableName, $errorMessage),
259 - ];
260 - } else {
261 - $this->messagesNoHtml[] = [
262 - 'error' => false,
263 - 'color' => 'green',
264 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_EXTRA_COLUMN_SUCCESS', $oneColumn, $oneTableName),
265 - ];
266 - }
267 - }
268 - }
269 -
270 - private function fixDefaultValues($correctTableColumns, $oneTableName)
271 - {
272 - $oneTableName = str_replace('#__', acym_getPrefix(), $oneTableName);
273 - try {
274 - $currentTableColumns = acym_loadObjectList(
275 - 'SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, COLUMN_TYPE
276 - FROM information_schema.COLUMNS
277 - WHERE TABLE_SCHEMA = DATABASE()
278 - AND TABLE_NAME = '.acym_escapeDB($oneTableName),
279 - 'COLUMN_NAME'
280 - );
281 -
282 - if (empty($currentTableColumns)) {
283 - return;
284 - }
285 - } catch (\Exception $e) {
286 - $this->messagesNoHtml[] = [
287 - 'error' => true,
288 - 'color' => 'orange',
289 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_ERROR_GET_COLUMNS', $oneTableName, $e->getMessage()),
290 - ];
291 -
292 - return;
293 - }
294 -
295 - foreach ($correctTableColumns as $oneColumn => $oneColumnDefinition) {
296 - $defaultValue = '';
297 - if (preg_match('#DEFAULT ([^ ]+)$#Ui', $oneColumnDefinition, $matches)) {
298 - $defaultValue = $matches[1];
299 - }
300 -
301 - if (strlen($defaultValue) === 0) {
302 - continue;
303 - }
304 - $currentDefault = $currentTableColumns[$oneColumn]->COLUMN_DEFAULT;
305 - if (!empty($currentDefault)) {
306 - $currentDefault = trim($currentDefault, "'\"");
307 - }
308 - $expectedDefault = trim($defaultValue, "'\"");
309 -
310 - if (strtoupper($expectedDefault) === 'NULL') {
311 - $expectedDefault = null;
312 - }
313 -
314 - $isNullable = strtoupper($currentTableColumns[$oneColumn]->IS_NULLABLE) === 'YES';
315 -
316 - if ($isNullable && $currentDefault === '') {
317 - $currentDefault = null;
318 - }
319 -
320 - if (!$isNullable && $currentDefault === null) {
321 - $currentDefault = '';
322 - }
323 -
324 - if ($currentDefault === $expectedDefault) {
325 - continue;
326 - }
327 -
328 - if (!empty($currentTableColumns[$oneColumn]->COLUMN_DEFAULT) && substr($currentTableColumns[$oneColumn]->COLUMN_DEFAULT, 0, 1) === '"') {
329 - $currentTableColumns[$oneColumn]->COLUMN_DEFAULT = '\''.substr($currentTableColumns[$oneColumn]->COLUMN_DEFAULT, 1, -1).'\'';
330 - }
331 -
332 - $isColumnDefaultEmpty = empty($currentTableColumns[$oneColumn]->COLUMN_DEFAULT) && $currentTableColumns[$oneColumn]->COLUMN_DEFAULT !== '0';
333 -
334 - if (!$isColumnDefaultEmpty && $currentTableColumns[$oneColumn]->COLUMN_DEFAULT === $defaultValue) {
335 - continue;
336 - }
337 -
338 - $this->messagesNoHtml[] = [
339 - 'error' => false,
340 - 'color' => 'blue',
341 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_WRONG_DEFAULT_VALUE', $oneColumn, $oneTableName),
342 - ];
343 -
344 - try {
345 - $isError = acym_query('ALTER TABLE '.$oneTableName.' CHANGE `'.acym_secureDBColumn($oneColumn).'` '.$oneColumnDefinition);
346 - } catch (\Exception $e) {
347 - $isError = null;
348 - }
349 -
350 - if ($isError === null) {
351 - $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
352 - $this->messagesNoHtml[] = [
353 - 'error' => true,
354 - 'color' => 'red',
355 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_WRONG_DEFAULT_VALUE_ERROR', $oneColumn, $oneTableName, $errorMessage),
356 - ];
357 - } else {
358 - $this->messagesNoHtml[] = [
359 - 'error' => false,
360 - 'color' => 'green',
361 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_WRONG_DEFAULT_VALUE_SUCCESS', $oneColumn, $oneTableName),
362 - ];
363 - }
364 - }
365 - }
366 -
367 - private function addMissingTableKeys(array $correctTableIndexes, string $oneTableName)
368 - {
369 - $results = acym_loadObjectList('SHOW INDEX FROM '.$oneTableName, 'Key_name');
370 - if (empty($results)) {
371 - $results = [];
372 - }
373 -
374 - foreach ($correctTableIndexes as $name => $query) {
375 - $name = acym_prepareQuery($name);
376 - if (in_array($name, array_keys($results))) {
377 - continue;
378 - }
379 -
380 -
381 - $keyName = $name === 'PRIMARY' ? 'primary key' : 'index '.$name;
382 -
383 - $this->messagesNoHtml[] = [
384 - 'error' => false,
385 - 'color' => 'blue',
386 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_MISSING_INDEX', $keyName, $oneTableName),
387 - ];
388 -
389 - try {
390 - $isError = acym_query('ALTER TABLE '.$oneTableName.' ADD '.$query);
391 - } catch (\Exception $e) {
392 - $isError = null;
393 - }
394 -
395 - if ($isError === null) {
396 - $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
397 - $this->messagesNoHtml[] = [
398 - 'error' => true,
399 - 'color' => 'red',
400 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_ADD_INDEX_ERROR', $keyName, $oneTableName, $errorMessage),
401 - ];
402 - } else {
403 - $this->messagesNoHtml[] = [
404 - 'error' => false,
405 - 'color' => 'green',
406 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_ADD_INDEX_SUCCESS', $keyName, $oneTableName),
407 - ];
408 - }
409 - }
410 - }
411 -
412 - private function addMissingTableConstraints(array $correctTableConstraints, string $oneTableName)
413 - {
414 - if (empty($correctTableConstraints)) {
415 - return;
416 - }
417 -
418 - $tableNameQuery = str_replace('#__', acym_getPrefix(), $oneTableName);
419 - $databaseName = acym_loadResult('SELECT DATABASE();');
420 - $foreignKeys = acym_loadObjectList(
421 - 'SELECT i.CONSTRAINT_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME, k.COLUMN_NAME
422 - FROM information_schema.TABLE_CONSTRAINTS AS i
423 - JOIN information_schema.KEY_COLUMN_USAGE AS k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME
424 - WHERE i.TABLE_NAME = '.acym_escapeDB($tableNameQuery).' AND i.CONSTRAINT_TYPE = "FOREIGN KEY" AND i.TABLE_SCHEMA = '.acym_escapeDB($databaseName),
425 - 'CONSTRAINT_NAME'
426 - );
427 -
428 - acym_query('SET foreign_key_checks = 0');
429 -
430 - foreach ($correctTableConstraints as $constraintName => $constraintInfo) {
431 - $constraintTableNamePrefix = str_replace('#__', acym_getPrefix(), $constraintInfo['table']);
432 - $constraintName = str_replace('#__', acym_getPrefix(), $constraintName);
433 -
434 - if (!empty($foreignKeys[$constraintName]) && $foreignKeys[$constraintName]->REFERENCED_TABLE_NAME === $constraintTableNamePrefix && $foreignKeys[$constraintName]->REFERENCED_COLUMN_NAME === $constraintInfo['table_column'] && $foreignKeys[$constraintName]->COLUMN_NAME === $constraintInfo['column']) {
435 - continue;
436 - }
437 -
438 - $this->messagesNoHtml[] = [
439 - 'error' => false,
440 - 'color' => 'blue',
441 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_WRONG_FOREIGN_KEY', $constraintName, $oneTableName),
442 - ];
443 -
444 - if (!empty($foreignKeys[$constraintName])) {
445 - try {
446 - $isError = acym_query('ALTER TABLE `'.$oneTableName.'` DROP FOREIGN KEY `'.$constraintName.'`');
447 - } catch (\Exception $e) {
448 - $isError = null;
449 - }
450 -
451 - if ($isError === null) {
452 - $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
453 - $this->messagesNoHtml[] = [
454 - 'error' => true,
455 - 'color' => 'red',
456 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_ADD_FOREIGN_KEY_ERROR', $constraintName, $oneTableName, $errorMessage),
457 - ];
458 - continue;
459 - }
460 - }
461 -
462 - try {
463 - $isError = acym_query(
464 - 'ALTER TABLE `'.$oneTableName.'` ADD CONSTRAINT `'.$constraintName.'` FOREIGN KEY (`'.$constraintInfo['column'].'`) REFERENCES `'.$constraintInfo['table'].'` (`'.$constraintInfo['table_column'].'`) ON DELETE NO ACTION ON UPDATE NO ACTION;'
465 - );
466 - } catch (\Exception $e) {
467 - $isError = null;
468 - }
469 -
470 - if ($isError === null) {
471 - $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
472 - $this->messagesNoHtml[] = [
473 - 'error' => true,
474 - 'color' => 'red',
475 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_ADD_FOREIGN_KEY_ERROR', $constraintName, $oneTableName, $errorMessage),
476 - ];
477 - } else {
478 - $this->messagesNoHtml[] = [
479 - 'error' => false,
480 - 'color' => 'green',
481 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_ADD_FOREIGN_KEY_SUCCESS', $constraintName, $oneTableName),
482 - ];
483 - }
484 - }
485 -
486 - acym_query('SET foreign_key_checks = 1');
487 - }
488 -
489 - private function cleanDuplicatedUrls(bool $fromConfiguration)
490 - {
491 - if (!$fromConfiguration) {
492 - return;
493 - }
494 -
495 - $urlClass = new UrlClass();
496 - $duplicatedUrls = $urlClass->getDuplicatedUrls();
497 -
498 - if (empty($duplicatedUrls)) {
499 - return;
500 - }
501 -
502 - $maxExecutionTime = intval(ini_get('max_execution_time'));
503 - $time = time();
504 - $interrupted = false;
505 - $this->messagesNoHtml[] = [
506 - 'error' => false,
507 - 'color' => 'blue',
508 - 'msg' => acym_translation('ACYM_CHECKDB_DUPLICATED_URLS'),
509 - ];
510 -
511 - if (empty($maxExecutionTime) || $maxExecutionTime - 20 < 20) {
512 - $maxExecutionTime = 20;
513 - } else {
514 - $maxExecutionTime -= 20;
515 - }
516 -
517 - acym_increasePerf();
518 - while (!empty($duplicatedUrls)) {
519 - $urlClass->delete($duplicatedUrls);
520 -
521 - if (time() - $time > $maxExecutionTime) {
522 - $interrupted = true;
523 - break;
524 - }
525 -
526 - $duplicatedUrls = $urlClass->getDuplicatedUrls();
527 - }
528 -
529 - if (empty($interrupted)) {
530 - $this->messagesNoHtml[] = [
531 - 'error' => false,
532 - 'color' => 'green',
533 - 'msg' => acym_translation('ACYM_CHECKDB_DUPLICATED_URLS_SUCCESS'),
534 - ];
535 - } else {
536 - $this->messagesNoHtml[] = [
537 - 'error' => false,
538 - 'color' => 'blue',
539 - 'msg' => acym_translation('ACYM_CHECKDB_DUPLICATED_URLS_REMAINING'),
540 - ];
541 - }
542 - }
543 -
544 - private function addMissingUserKeys()
545 - {
546 - $userClass = new UserClass();
547 - $nbAddedKeys = $userClass->addMissingKeys();
548 -
549 - if (!empty($nbAddedKeys)) {
550 - $this->messagesNoHtml[] = [
551 - 'error' => false,
552 - 'color' => 'green',
553 - 'msg' => acym_translationSprintf('ACYM_CHECKDB_ADDED_KEYS', $nbAddedKeys),
554 - ];
555 - }
556 - }
557 -
558 - public function redomigration()
559 - {
560 - $newConfig = new \stdClass();
561 - $newConfig->migration = 0;
562 - $this->config->save($newConfig);
563 -
564 - acym_redirect(acym_completeLink('dashboard', false, true));
565 - }
566 -
567 - public function scanSiteFiles()
568 - {
569 - $maliciousFiles = [];
570 - $siteFiles = acym_getFiles(ACYM_ROOT, '.', true, true);
571 - foreach ($siteFiles as $oneFilePath) {
572 - $lastSlashPos = strrpos($oneFilePath, '/');
573 - if (!empty($lastSlashPos) && strpos($oneFilePath, ACYM_UPLOAD_FOLDER_THUMBNAIL) !== false && preg_match(
574 - '/.*thumbnail.*php.*$/',
575 - substr($oneFilePath, $lastSlashPos + 1)
576 - )) {
577 - $maliciousFiles[] = $oneFilePath;
578 - } elseif (filesize($oneFilePath) < 10000) {
579 - $fileContent = file_get_contents($oneFilePath);
580 - if (preg_match('/^<\?php echo "jm"\."te"\."st"; \?>$/U', $fileContent)) {
581 - $maliciousFiles[] = $oneFilePath;
582 - } elseif (preg_match('/^<\?php\n\$[a-z]+\s*=\s*\$_COOKIE\s*;/Ui', $fileContent)) {
583 - $maliciousFiles[] = $oneFilePath;
584 - }
585 - }
586 - }
587 -
588 - ob_start();
589 - if (!empty($maliciousFiles)) {
590 - $message = acym_translation('ACYM_MALICIOUS_FILES');
591 - $message .= '<ul><li>'.implode('</li><li>', $maliciousFiles).'</li></ul>';
592 - acym_display($message, 'error', false);
593 - } else {
594 - acym_display(acym_translation('ACYM_NO_MALICIOUS_FILES'), 'success', false);
595 - }
596 - $message = ob_get_clean();
597 - acym_sendAjaxResponse($message);
598 - }
599 -}