mirror of
https://github.com/avecms/AVE.cms.git
synced 2026-08-06 02:35:45 +00:00
127 lines
4.2 KiB
PHP
127 lines
4.2 KiB
PHP
<?php
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------------------
|
|
| AVE.cms
|
|
|--------------------------------------------------------------------------------------
|
|
| @package AVE.cms
|
|
| @file adminx/modules/Documents/DocumentMediaReplacement.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\Documents;
|
|
|
|
defined('BASEPATH') || die('Direct access to this location is not allowed.');
|
|
|
|
use App\Adminx\Media\MediaAudit;
|
|
use App\Adminx\Media\Model as MediaModel;
|
|
use App\Content\Fields\DocumentMediaFieldType;
|
|
use App\Content\Fields\FieldRegistry;
|
|
|
|
/** Removes superseded document media only after the document transaction succeeds. */
|
|
class DocumentMediaReplacement
|
|
{
|
|
public static function requestedFieldIds($value)
|
|
{
|
|
$value = is_array($value) ? $value : array($value);
|
|
$ids = array();
|
|
foreach ($value as $id) {
|
|
$id = (int) $id;
|
|
if ($id > 0) { $ids[$id] = $id; }
|
|
}
|
|
|
|
return array_values($ids);
|
|
}
|
|
|
|
/** Capture trusted old paths before field values are saved. */
|
|
public static function capture(array $fieldGroups, array $newValues, array $requestedFieldIds)
|
|
{
|
|
$requested = array_fill_keys(self::requestedFieldIds($requestedFieldIds), true);
|
|
if (!$requested) { return array(); }
|
|
|
|
$captured = array();
|
|
foreach ($fieldGroups as $group) {
|
|
foreach (isset($group['items']) && is_array($group['items']) ? $group['items'] : array() as $field) {
|
|
$fieldId = isset($field['Id']) ? (int) $field['Id'] : 0;
|
|
if (!isset($requested[$fieldId]) || !array_key_exists($fieldId, $newValues)) { continue; }
|
|
$typeCode = isset($field['rubric_field_type']) ? (string) $field['rubric_field_type'] : '';
|
|
$type = FieldRegistry::get($typeCode);
|
|
if (!$type instanceof DocumentMediaFieldType) { continue; }
|
|
|
|
$oldValue = isset($field['parsed']) ? $field['parsed'] : array();
|
|
$captured[$fieldId] = array(
|
|
'type' => $typeCode,
|
|
'paths' => self::uploadPaths($type->mediaPaths($oldValue)),
|
|
);
|
|
}
|
|
}
|
|
|
|
return $captured;
|
|
}
|
|
|
|
public static function removedPaths(array $captured, array $newValues)
|
|
{
|
|
$removed = array();
|
|
foreach ($captured as $fieldId => $field) {
|
|
$type = FieldRegistry::get(isset($field['type']) ? (string) $field['type'] : '');
|
|
if (!$type instanceof DocumentMediaFieldType) { continue; }
|
|
$newValue = array_key_exists($fieldId, $newValues) ? $newValues[$fieldId] : array();
|
|
$newPaths = array_fill_keys(self::uploadPaths($type->mediaPaths($newValue)), true);
|
|
foreach (isset($field['paths']) && is_array($field['paths']) ? $field['paths'] : array() as $path) {
|
|
if (!isset($newPaths[$path])) { $removed[$path] = $path; }
|
|
}
|
|
}
|
|
|
|
return array_values($removed);
|
|
}
|
|
|
|
/** Move currently unused files to the recoverable media trash. */
|
|
public static function cleanup(array $captured, array $newValues)
|
|
{
|
|
$paths = self::removedPaths($captured, $newValues);
|
|
$result = array('checked' => count($paths), 'trashed' => 0, 'kept' => 0, 'errors' => array());
|
|
if (!$paths) { return $result; }
|
|
|
|
try {
|
|
$usage = MediaAudit::inspectUsageMany($paths, 1, false);
|
|
} catch (\Throwable $e) {
|
|
$result['errors'][] = $e->getMessage();
|
|
return $result;
|
|
}
|
|
|
|
foreach ($paths as $path) {
|
|
if (!isset($usage[$path])) { continue; }
|
|
if (!empty($usage[$path]['use_count'])) {
|
|
$result['kept']++;
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
MediaModel::trash($path);
|
|
$result['trashed']++;
|
|
} catch (\Throwable $e) {
|
|
$result['errors'][] = basename($path) . ': ' . $e->getMessage();
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
protected static function uploadPaths(array $paths)
|
|
{
|
|
$result = array();
|
|
foreach ($paths as $path) {
|
|
$path = html_entity_decode(trim((string) $path), ENT_QUOTES, 'UTF-8');
|
|
$parsed = parse_url($path, PHP_URL_PATH);
|
|
$path = is_string($parsed) ? rawurldecode($parsed) : $path;
|
|
$path = '/' . ltrim(preg_replace('#/+#', '/', str_replace('\\', '/', $path)), '/');
|
|
if (strpos($path, '/uploads/') === 0 && strpos($path, '/../') === false) { $result[$path] = $path; }
|
|
}
|
|
|
|
return array_values($result);
|
|
}
|
|
}
|