Files
2026-07-27 12:58:44 +03:00

127 lines
5.4 KiB
PHP

<?php
/*
|--------------------------------------------------------------------------------------
| AVE.cms
|--------------------------------------------------------------------------------------
| @package AVE.cms
| @file adminx/modules/Themes/Revisions.php
| @author AVE.cms <support@ave-cms.ru>
| @copyright 2007-2026 (c) AVE.cms
| @link https://ave-cms.ru
| @version 3.3
*/
namespace App\Adminx\Themes;
defined('BASEPATH') || die('Direct access to this location is not allowed.');
use App\Common\SystemTables;
use DB;
class Revisions
{
public static function table()
{
return SystemTables::table('theme_asset_revisions');
}
public static function capture($theme, $path, $action, $content, $authorId, $sourceRevisionId)
{
$content = (string) $content;
$checksum = hash('sha256', $content);
$last = DB::query(
'SELECT checksum,action FROM ' . self::table() . ' WHERE theme=%s AND asset_path=%s ORDER BY created_at DESC,id DESC LIMIT 1',
(string) $theme, (string) $path
)->getAssoc();
if ($last && (string) $last['checksum'] === $checksum && (string) $last['action'] === (string) $action) { return 0; }
DB::Insert(self::table(), array(
'theme' => (string) $theme, 'asset_path' => (string) $path, 'action' => (string) $action,
'checksum' => $checksum, 'content' => $content, 'content_size' => strlen($content),
'author_id' => (int) $authorId, 'author_name' => self::authorName($authorId),
'source_revision_id' => (int) $sourceRevisionId, 'created_at' => time(),
));
return (int) DB::insertId();
}
public static function listing($theme, $path = '', $limit = 200)
{
$sql = 'SELECT id,theme,asset_path,action,checksum,content_size,author_id,author_name,source_revision_id,created_at FROM ' . self::table() . ' WHERE theme=%s';
$args = array((string) $theme);
if ((string) $path !== '') { $sql .= ' AND asset_path=%s'; $args[] = (string) $path; }
$sql .= ' ORDER BY created_at DESC,id DESC LIMIT %i';
$args[] = max(1, min(500, (int) $limit));
array_unshift($args, $sql);
$rows = call_user_func_array(array(DB::class, 'query'), $args)->getAll() ?: array();
return array_map(array(__CLASS__, 'format'), $rows);
}
public static function one($id)
{
$row = DB::query('SELECT * FROM ' . self::table() . ' WHERE id=%i LIMIT 1', (int) $id)->getAssoc();
if (!$row) { return null; }
$row = self::format($row);
$row['content'] = (string) $row['raw']['content'];
unset($row['raw']);
return $row;
}
public static function restore($id, $authorId)
{
$revision = self::one($id);
if (!$revision) { throw new \RuntimeException('Ревизия не найдена'); }
return Model::saveFile($revision['theme'], $revision['path'], $revision['content'], $authorId, 'restore', $revision['id']);
}
public static function delete($id)
{
$exists = (int) DB::query('SELECT COUNT(*) FROM ' . self::table() . ' WHERE id=%i', (int) $id)->getValue();
if ($exists < 1) { return false; }
DB::Delete(self::table(), 'id=%i', (int) $id);
return true;
}
public static function deleteForPath($theme, $path)
{
$count = (int) DB::query('SELECT COUNT(*) FROM ' . self::table() . ' WHERE theme=%s AND asset_path=%s', (string) $theme, (string) $path)->getValue();
DB::Delete(self::table(), 'theme=%s AND asset_path=%s', (string) $theme, (string) $path);
return $count;
}
public static function deleteTheme($theme)
{
$count = (int) DB::query('SELECT COUNT(*) FROM ' . self::table() . ' WHERE theme=%s', (string) $theme)->getValue();
DB::Delete(self::table(), 'theme=%s', (string) $theme);
return $count;
}
protected static function format(array $row)
{
$labels = array(
'create' => array('Создание', 'badge-green'), 'upload' => array('Загрузка', 'badge-cyan'),
'update' => array('Сохранение', 'badge-blue'), 'manifest' => array('Реестр', 'badge-violet'),
'backup' => array('Предыдущая версия', 'badge-gray'), 'restore' => array('Восстановление', 'badge-amber'),
'delete' => array('Удаление', 'badge-red'), 'import' => array('Импорт', 'badge-cyan'),
);
$action = isset($row['action']) ? (string) $row['action'] : 'update';
$label = isset($labels[$action]) ? $labels[$action] : array($action, 'badge-gray');
$created = isset($row['created_at']) ? (int) $row['created_at'] : 0;
return array(
'id' => (int) $row['id'], 'theme' => (string) $row['theme'], 'path' => (string) $row['asset_path'],
'action' => $action, 'action_label' => $label[0], 'badge' => $label[1],
'checksum' => (string) $row['checksum'], 'size' => (int) $row['content_size'],
'size_label' => Model::formatBytes((int) $row['content_size']), 'author_id' => (int) $row['author_id'],
'author_name' => (string) $row['author_name'], 'source_revision_id' => (int) $row['source_revision_id'],
'created_at' => $created, 'created_label' => $created ? date('d.m.Y H:i:s', $created) : '-', 'raw' => $row,
);
}
protected static function authorName($id)
{
if ((int) $id <= 0) { return ''; }
$row = DB::query('SELECT name,login,email FROM ' . SystemTables::table('users') . ' WHERE id=%i LIMIT 1', (int) $id)->getAssoc();
if (!$row) { return '#' . (int) $id; }
return !empty($row['name']) ? (string) $row['name'] : (!empty($row['login']) ? '@' . $row['login'] : (string) $row['email']);
}
}