Руководство Melbis Shop: оглавление
Набор методов платформы, которые не относятся ни к шаблонизатору, ни к базе данных, но нужны в коде модуля время от времени: узнать, кто выполняется сейчас, вызвать функцию своего модуля, собрать путь к загруженному файлу, оборвать страницу и отдать вместо неё другую.
UnitName() — имя выполняющегося модуля.
Может пригодиться в библиотечных функциях, которым нужно знать, кто их
вызвал (например, чтобы загрузить языковые теги именно этого
модуля):
$tags = MELBIS_INC_LANGS_Tags($tpl, MELBIS()->UnitName());UnitParam() — объявленные входные
параметры всех загруженных модулей, массивом «имя модуля → список
объявлений». Инструмент интроспекции: нужен служебным и отладочным
модулям, которые строят карту проекта, а не обычному коду витрины.
UnitFunc($mName, ...$mParams) вызывает
вспомогательную функцию текущего модуля по короткому имени: движок сам
добавляет префикс модуля, принятый соглашением об именовании (см.
«Принятые обозначения»).
// Внутри модуля melbis_store_card вызовет MELBIS_STORE_CARD_Price()
$price = MELBIS()->UnitFunc('Price', $store, $currency);Смысл не в экономии символов, а в том, что имя функции перестаёт зависеть от имени модуля: переименовали модуль — переименовали функции, а вызовы остались прежними. Если функции с таким именем нет, разбор останавливается с ошибкой.
Граница у UnitFunc одна: он зовёт функции
своего модуля. Функция, которую вызывают чужие юниты, —
библиотечная: ей место в inc-модуле, зовётся она полным именем, и внутри
себя она тоже ходит полными именами — контекст имени принадлежит
вызвавшему юниту, и UnitFunc собрал бы имя от него.
В модуле с пространством имён метод тоже нужен, и по более
важной причине. Свою функцию, имя которой известно на месте,
там зовут просто по имени — Price($store, $currency), без
всякого UnitFunc. А вот имя, пришедшее данными, PHP по
текущему пространству не разрешает: строка в переменной
всегда считается полным именем, и $func = 'Price'; $func();
уйдёт искать глобальную Price. Собрать правильное имя может
только тот, кто знает выполняющийся модуль, — этим UnitFunc
и остаётся полезен:
// Диспетчер веб-модуля: имя функции пришло из POST
return MELBIS()->UnitFunc($mVars['post']['func'], $mVars);Обе формы имени метод проверяет сам — сначала
модуль\Имя, затем прежнюю МОДУЛЬ_Имя, —
поэтому один и тот же диспетчер работает и в плоском модуле, и в
объявленном.
UnitRun($mUnit, $mFunc, ...$mParams)
подключает юнит и выполняет его функцию под его именем
— как если бы её позвали изнутри этого юнита, поэтому
UnitFunc внутри вызова работает. Этим методом агентский
эндпоинт запускает AI-инструменты, и это его единственное
назначение.
Из кешируемого модуля вызов запрещён — движок остановит страницу с ошибкой. Причина в зависимостях: запрос, выполненный под чужим именем, припишется не звавшему, и кеш звавшего перестанет зависеть от таблицы, которую он на самом деле читает. Модулю, которому нужна чужая функция, нужна библиотека: подключите её в манифесте и зовите функцию по имени напрямую — заодно уцелеют ссылки, о чём предупреждает абзац ниже.
$answer = MELBIS()->UnitRun('melbis_agent_user', 'MELBIS_AGENT_USER', $action, $user_id, $command, $params);Имя функции здесь передаётся целиком, поэтому у юнита с пространством
имён оно пишется через слеш — 'melbis_agent_user\Main'.
Ссылки через эти методы не проходят. Аргументы
собираются в массив, а массив теряет связь с переменной вызывающего,
поэтому функция с &$ в подписи получит копию и молча
отработает вхолостую. Такие функции зовут по имени напрямую — в модуле с
пространством имён это как раз обычный короткий вызов.
FilePath($mUploadTime, $mFileName = '')
строит путь к файлу по дате его загрузки — картинки и вложения
раскладываются по каталогам вида
files/2026/07_22/14_30/:
$url = MELBIS()->FilePath($image['upload_time'], $image['file_name']);Без имени файла вернёт путь к каталогу, со слешем на конце — в этом
виде метод повторяет шаблонный модификатор |path. Если
передать null вместо даты, метод переключается на каталог
текущей группы шаблонов: так адресуются статические файлы
оформления.
С именем файла добавляется проверка WebP. Для
.jpg, .jpeg и .png метод смотрит,
есть ли уже готовая WebP-версия в кеше, и если есть — возвращает путь к
ней, а если нет — к оригиналу. Важно, что FilePath
ничего не конвертирует: он только пользуется тем, что
уже сконвертировано. Создают кеш модификаторы |webp и
|text:webp — они делают преобразование на ходу, при первом
же выводе картинки (см. «Модификаторы»). Поэтому путь от
FilePath ведёт на WebP только для файлов, которые витрина
уже хоть раз показывала.
В вёрстке пользуйтесь модификаторами; метод нужен, когда путь участвует в логике модуля — например, при проверке существования файла или при сборке ссылки для внешней выгрузки.
Модуль, прерывающий работу нештатно, обязан снять служебную
блокировку компиляции кеша — это делают методы Stop() и
Halt(). Они описаны в разделе «Журналы, ошибки и
метрики».
Иногда модуль посреди работы выясняет, что показывать нечего: товар удалён, раздел закрыт, ссылка устарела. Вместо того чтобы возвращать пустой фрагмент в уже собираемую страницу, её можно оборвать и отдать браузеру другую целиком.
function MELBIS_INC_404()
{
MELBIS()->Stop();
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
MELBIS()->Run('melbis_base_404', []);
header('Content-type: text/html; charset='.MELBIS_CHARSET);
echo MELBIS()->Fetch();
exit;
}По строкам:
Stop() — первым делом. Текущий модуль
держит служебную блокировку компиляции своего кеша, и до её штатного
снятия дело не дойдёт: в конце стоит exit. Без
Stop() следующий запрос к этому модулю будет считать, что
кеш компилируется другим процессом, и ждать впустую.Run($mUnitName, $mParams) — тот же
метод, которым корневой скрипт запускает точку входа; здесь он запускает
модуль страницы 404. Этот модуль должен быть отмечен в IDE как модуль
входной точки.Fetch() — возвращает собранный HTML
строкой. Этим он и отличается от
Publish(), который тот же результат печатает сам и заодно
отправляет Content-Type. Строка нужна там, где заголовки вы
ставите вручную — как здесь, где статусом ответа должен быть именно
404.exit — ни Stop(), ни
Halt() не прерывают выполнение PHP сами по себе.Приём удобно держать в библиотеке (inc) и вызывать из
любого модуля, которому понадобилось прервать страницу.