| @copyright 2007-2026 (c) AVE.cms | @link https://ave-cms.ru | @version 3.3 */ define('BASEPATH', str_replace('\\', '/', dirname(__DIR__))); define('DS', DIRECTORY_SEPARATOR); @ini_set('display_errors', '0'); header('Cache-Control: no-store'); header('X-Robots-Tag: noindex, nofollow, noarchive'); $maintenanceFile = BASEPATH . '/storage/updates/maintenance.json'; $maintenance = is_file($maintenanceFile) ? json_decode((string) file_get_contents($maintenanceFile), true) : null; $token = isset($_POST['token']) ? (string) $_POST['token'] : (isset($_GET['token']) ? (string) $_GET['token'] : ''); if (!is_array($maintenance) || empty($maintenance['job_id']) || empty($maintenance['recovery_token_hash']) || !preg_match('/^[a-f0-9]{48}$/', $token) || !hash_equals((string) $maintenance['recovery_token_hash'], hash('sha256', $token))) { http_response_code(404); exit('Not found'); } $jobFile = BASEPATH . '/storage/updates/jobs/' . basename((string) $maintenance['job_id']) . '/job.json'; $job = is_file($jobFile) ? json_decode((string) file_get_contents($jobFile), true) : null; if (!is_array($job) || empty($job['journal'])) { http_response_code(404); exit('Not found'); } $error = ''; $done = false; if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['confirm']) && $_POST['confirm'] === 'rollback') { try { foreach (array_reverse($job['journal']) as $entry) { $actual = isset($entry['actual']) ? (string) $entry['actual'] : ''; if ($actual === '' || strpos(str_replace('\\', '/', $actual), BASEPATH . '/') !== 0) { throw new RuntimeException('Recovery journal contains an unsafe path'); } if (!empty($entry['existed'])) { $backup = isset($entry['backup']) ? (string) $entry['backup'] : ''; if (!is_file($backup)) { throw new RuntimeException('Recovery backup is incomplete'); } @mkdir(dirname($actual), 0755, true); $temporary = $actual . '.recovery-' . bin2hex(random_bytes(4)); if (!copy($backup, $temporary) || !@rename($temporary, $actual)) { @unlink($temporary); throw new RuntimeException('Cannot restore ' . basename($actual)); } } elseif (is_file($actual) && !@unlink($actual)) { throw new RuntimeException('Cannot remove added file'); } } if (!empty($job['database_applied']) && !empty($job['database_backup']) && is_dir($job['database_backup'])) { require_once BASEPATH . '/system/preload.php'; if (\App\Common\CoreUpdate\DatabaseBackup::complete($job['database_backup'])) { \App\Common\CoreUpdate\DatabaseBackup::restore($job['database_backup']); } } @unlink($maintenanceFile); $job['status'] = 'rolled_back'; $job['message'] = 'Аварийный откат выполнен'; $job['updated_at'] = date(DATE_ATOM); $tmp = $jobFile . '.tmp-' . bin2hex(random_bytes(4)); file_put_contents($tmp, json_encode($job, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n", LOCK_EX); @rename($tmp, $jobFile); $done = true; } catch (Throwable $exception) { $error = $exception->getMessage(); } } function recoveryEscape($value) { return htmlspecialchars((string) $value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } ?>Восстановление AVE.cms

Откат завершён

Файлы и база данных восстановлены. Можно вернуться на сайт и проверить журнал обновления.

Перейти на сайт

Аварийное восстановление

Будет восстановлено состояние до патча . Используйте действие только если контрольная проверка или панель управления не запускается.