Логика: пользователь > страница > раздел > сайт (нижестоящий перекрывает вышестоящий)
В типовом сценарии SF4 итоговые значения для страницы собираются как последовательное наложение уровней, где каждый следующий уровень перезаписывает одноимённые ключи предыдущего:
- Сайт: значения из
{site_dir}/simai.data/.site.property.php - Раздел: значения из
/.property.phpпо цепочке директорий (наследование от корня{site_dir}к текущей папке) - Страница: значения из той же
/.property.php, но из веткиpage[<имя_файла>] - Пользователь: значения из сессионного хранилища (обычно storageId
"user"), если конкретный интерфейс/режим их использует
Наследование разделов реализовано через проход по сегментам пути и array_merge() на каждом шаге: это значит, что более глубокая папка перекрывает более верхнюю по ключам (без рекурсивного мерджа вложенных массивов).
Отдельная практическая деталь: в админ-редакторе значений ключи перед объединением нормализуются (приводятся к нижнему регистру). Поэтому безопаснее и предсказуемее держать коды настроек в одном стиле (обычно lower_snake_case) и не полагаться на различие регистра.
Пример сборки “эффективных” значений (показана именно файловая логика + опциональный пользовательский оверрайд):
<?php
declare(strict_types=1);
use SIMAI\Main\Configuration\Page;
use SIMAI\Main\Configuration\Property;
use SIMAI\Main\Configuration\Section;
$siteDir = '/ru'; // {site_dir}
$currentDir = '/ru/catalog/'; // директория текущего раздела
$pagePath = '/ru/catalog/index.php';
$siteValues = [];
$sitePropertyPath = $_SERVER['DOCUMENT_ROOT'] . $siteDir . '/simai.data/.site.property.php';
if (file_exists($sitePropertyPath)) {
$siteValues = (array) require $sitePropertyPath;
}
$sectionValues = (array) Section::getRecursionArray($currentDir, $siteDir);
$pageValues = (array) Page::getArray($pagePath);
// Пользовательские значения — если вы используете режим/интерфейс,
// который накладывает сессионные overrides (например, демо-настройки)
$userValues = (array) Property::getArray('user');
$effective = array_merge($siteValues, $sectionValues, $pageValues, $userValues);
Применение: при изменении значения на уровне страницы оно перекрывает раздел и сайт; пользовательские настройки перекрывают страницу
На практике переопределение в UI устроено так, что у каждого поля есть режим:
- использовать значение родителя (не сохранять на текущем уровне)
- задать своё значение (сохранить на текущем уровне и тем самым перекрыть родителя)
В админ-формах это реализовано через “флаг редактирования” поля: если поле помечено как не редактируемое на текущем уровне, оно не попадает в массив сохранения и, соответственно, продолжает браться из PARENT_VALUES (то есть из агрегированных значений уровней выше). Если поле включили для редактирования — значение записывается в соответствующий файл уровня:
- уровень раздела →
/.property.php→ веткаsection - уровень страницы →
/.property.php→ веткаpage[имя_файла] - уровень сайта →
{site_dir}/simai.data/.site.property.php
Пользовательский уровень в SF4 хранится в сессии. В демо-настройках это используется явно: значение сохраняется в "user" только если оно действительно отличается от “базовых” значений, собранных из site/section/page. Это позволяет быстро “поиграть” параметрами без правок файлов и без влияния на других пользователей.
Перемещение/копирование настроек: описать процесс переноса конфигов между уровнями (site → section → page) вручную или через инструменты (если есть)
В SF4 “перемещение” значения между уровнями по сути означает: записать параметр на другом уровне и снять переопределение на текущем. Это можно делать двумя способами.
Через интерфейсы настройки (рекомендуемый путь):
- Откройте уровень, куда переносите (например, раздел) и задайте нужное значение поля.
- Откройте уровень, откуда переносите (например, страница) и переключите поле в режим “использовать значение родителя” (то есть отключите редактирование поля на этом уровне).
- Сохраните оба уровня. В результате параметр останется только на нужном уровне, а нижний уровень перестанет хранить override.
Вручную через файлы (когда нужно массово/аккуратно перенести набор настроек):
- перенос страница → раздел: переместить ключ(и) из
page[имя_файла]вsectionвнутри одного и того же/.property.php, затем удалить их из страницы - перенос раздел → сайт: добавить ключ(и) в
{site_dir}/simai.data/.site.property.php, затем удалить их изsectionв/.property.php
Пример “страница → раздел” в одном /.property.php (до/после):
<?php
return [
'section' => [
'layout_type' => 'wide-fixed',
],
'page' => [
'index.php' => [
'layout_type' => 'wide-fluid', // было override только для index.php
],
],
];
Если нужно перенести layout_type = wide-fluid на весь раздел, делаете так:
<?php
return [
'section' => [
'layout_type' => 'wide-fluid', // стало общим для раздела (и наследников)
],
'page' => [
'index.php' => [
// layout_type удалён: страница теперь берёт значение из section
],
],
];
Если “копирование”, а не “перемещение” — просто оставляете ключ и на нижнем уровне (override будет точечно перекрывать общий параметр).
Напомнить: использовать коды (не ID) при переносе; проверять пути в simai.data/config
В файловых *.property.php ключи — это коды полей (строки), и редакторы/сборка работают именно с ними. Поэтому при переносах:
- переносите код → значение, а не “ID сущности” и не привязки к конкретным инфоблокам/разделам
- следите, чтобы код существовал в схеме настроек (в
{site_dir}/simai.data/config/*.config.php), иначе UI может не показать поле или покажет его некорректно - проверяйте, что работаете в правильном
{site_dir}(в мультисайтовой структуре у каждого сайта свойsimai.data)
Если при переносе вы меняете ещё и “как поле выглядит/какого оно типа”, это уже не перенос значений, а изменение схемы — такие правки делаются в {site_dir}/simai.data/config (и при необходимости — в локальных .structure.config.php на уровне конкретной директории), а затем уже переносится/согласуется слой значений в *.property.php.