Files
ave-cms/system/App/Content/Fields/DocumentRelationValue.php
T
2026-07-27 15:54:12 +03:00

120 lines
3.4 KiB
PHP

<?php
/*
|--------------------------------------------------------------------------------------
| AVE.cms
|--------------------------------------------------------------------------------------
| @package AVE.cms
| @file system/App/Content/Fields/DocumentRelationValue.php
| @author AVE.cms <support@ave-cms.ru>
| @copyright 2007-2026 (c) AVE.cms
| @link https://ave-cms.ru
| @version 3.3
*/
namespace App\Content\Fields;
defined('BASEPATH') || die('Direct access to this location is not allowed.');
/** Canonical read model and legacy-storage adapter for document relation fields. */
class DocumentRelationValue
{
const FORMAT = 'ave.document-relation';
const VERSION = 1;
protected static $singleTypes = array('doc_from_rub');
protected static $multipleTypes = array(
'doc_from_rub_all', 'doc_from_rub_check', 'doc_from_rub_multi',
'doc_from_rub_search', 'analoque', 'teasers',
);
public static function supports($type)
{
$type = (string) $type;
return in_array($type, self::$singleTypes, true) || in_array($type, self::$multipleTypes, true);
}
public static function isMultiple($type)
{
return in_array((string) $type, self::$multipleTypes, true);
}
public static function normalize($type, $value)
{
$type = (string) $type;
$ids = self::ids($value);
if (!self::isMultiple($type) && $ids) { $ids = array($ids[0]); }
$items = array();
foreach ($ids as $position => $documentId) {
$items[] = array('document_id' => (int) $documentId, 'position' => (int) $position);
}
return array(
'format' => self::FORMAT,
'version' => self::VERSION,
'multiple' => self::isMultiple($type),
'items' => $items,
);
}
public static function ids($value)
{
$decoded = FieldValueCodec::decodeStructured($value, null);
$source = is_array($decoded) ? $decoded : $value;
$ids = array();
self::collect($source, $ids);
return array_values($ids);
}
public static function encodeStorage($type, $value)
{
$ids = self::ids($value);
if (!self::isMultiple($type)) { return $ids ? (string) $ids[0] : ''; }
return $ids ? FieldValueCodec::normalizeForStorage($ids) : '';
}
protected static function collect($value, array &$ids, $key = null)
{
if (is_array($value)) {
if (isset($value['format']) && (string) $value['format'] === self::FORMAT && isset($value['items'])) {
self::collect($value['items'], $ids);
return;
}
foreach (array('document_id', 'id', 'Id') as $idKey) {
if (isset($value[$idKey])) {
self::collect($value[$idKey], $ids, $idKey);
return;
}
}
foreach ($value as $itemKey => $item) { self::collect($item, $ids, $itemKey); }
return;
}
if (is_object($value)) {
self::collect((array) $value, $ids, $key);
return;
}
$raw = trim((string) $value);
if ($raw === '') { return; }
$candidates = array();
if (in_array((string) $key, array('document_id', 'id', 'Id'), true) && ctype_digit($raw)) {
$candidates[] = (int) $raw;
} elseif (ctype_digit($raw)) {
$candidates[] = (int) $raw;
} else {
foreach (preg_split('/[,;\s]+/', $raw, -1, PREG_SPLIT_NO_EMPTY) as $part) {
if (preg_match('/(?:^|\|)(\d+)(?:\|)?$/', trim((string) $part), $match)) {
$candidates[] = (int) $match[1];
}
}
}
foreach ($candidates as $documentId) {
if ($documentId > 0 && !isset($ids[$documentId])) { $ids[$documentId] = $documentId; }
}
}
}