Common breakages and how to avoid them
Семь граблей, на которые чаще всего наступают ИИ-ассистенты (и люди). Формат каждого пункта: симптом → причина → как правильно.
1. Правка .tpl «не применилась»
Симптом: файл шаблона изменён, а на сайте — старая версия.
Причина: шаблоны компилируются в PHP и кэшируются в storage/cache/tpl/. Инвалидация — по времени изменения файла (mtime), и она ненадёжна: при копировании по FTP/scp или откате из бэкапа файл может приехать со старым mtime, и движок продолжит использовать кэш.
Как правильно: после каждой правки шаблонов сбрасывать кэш — php bin/celena cache:clear (или в панели: Настройки → Производительность → Очистить кеш). Взять за привычку: правка .tpl и очистка кэша — одно действие.
2. SQL под «не ту» СУБД
Симптом: код работал локально, а на сервере — ошибка SQL (или наоборот); чаще всего ломаются отчёты и «сырые» запросы.
Причина: Celena работает и на MySQL, и на PostgreSQL — а ассистент по привычке пишет диалектный SQL. Не переносятся: из MySQL — обратные кавычки ` `, GROUP_CONCAT, DATE_FORMAT, UNIX_TIMESTAMP, ON DUPLICATE KEY UPDATE, LIMIT x,y; из PostgreSQL — ILIKE, приведение ::type, RETURNING, ON CONFLICT, string_agg`. Вторая ошибка — писать имя таблицы строкой без префикса.
Как правильно: запросы — через $conn->builder('table') (QueryBuilder сам генерирует переносимый SQL). Если без сырого SQL никак — только конструкции, общие для обеих СУБД, и имена таблиц через $conn->table('name') (подставит префикс из .env).
3. Комментарий { … } съел не то
Симптом: после «закомментирования» куска шаблона страница ломается, выводится мусор или сайт зацикливается.
Причина: комментарий вырезается до первого }. Если внутри закомментированного куска встречается своё } (например, конструкция вида {p.*} или вложенный комментарий) — комментарий закрывается раньше времени, и «хвост» оживает как рабочий код шаблона. В худшем случае оживает {include …} и получается рекурсия.
Как правильно: комментировать короткие фразы без фигурных скобок и звёздочек внутри. Отключаемый блок кода не комментировать, а удалять — история правок и бэкапы для того и существуют.
4. Скрипт с CDN «молча не работает»
Симптом: подключили библиотеку с jsDelivr/unpkg/Google Fonts — на странице она не работает, в консоли браузера ошибки о блокировке.
Причина: Content-Security-Policy сайта (задана в .htaccess) разрешает скрипты и стили только со своего домена (script-src 'self'). Внешние CDN блокируются браузером намеренно — это защита от подмены чужого кода.
Как правильно: скачать файл и положить локально — в templates/<тема>/assets/ или plugins/<плагин>/assets/. Расширять список разрешённых доменов в CSP — только осознанно и в крайнем случае (например, счётчик аналитики).
5. Правка штатной темы вместо форка
Симптом: сайт выглядел как надо, но после обновления CMS все правки внешнего вида исчезли.
Причина: правили templates/default/ или templates/commerce/ напрямую, а обновление заливает штатные темы поверх (см. «Зоны движка»).
Как правильно: скопировать штатную тему под своим именем (templates/mysite/), поправить theme.json, включить в панели — и дальше править только копию. Обновления её не трогают.
6. PHP-код в .tpl
Симптом: на странице виден сам код — текст <?php … ?> вместо результата его работы.
Причина: шаблонизатор Celena намеренно не выполняет PHP: <?php и <?= экранируются как обычный текст. Это защита — шаблон не может стать «чёрным ходом» в сервер.
Как правильно: в шаблонах — только теги движка: {var}, [if]…[/if], [foreach]…[/foreach], {include} и т.д. (см. «Шаблоны»). Нужна логика или данные из базы — она пишется в плагине: свой тег шаблонизатора или async-блок, а шаблон лишь выводит готовые переменные.
7. Файлы кода в public/uploads/
Симптом: «положили скрипт в uploads, а он отдаёт 403 / не выполняется».
Причина: выполнение PHP в public/uploads/ заблокировано на уровне сервера — намеренно. Каталог загрузок доступен на запись через панель, и исполняемый код там — первое, что ищет злоумышленник.
Как правильно: код живёт только в plugins/ и templates/; public/uploads/ — исключительно для медиафайлов из панели. Соседняя грабля — права доступа: файлы должны принадлежать пользователю веб-сервера, иначе после ручного копирования сайт может встретить вас ошибкой 500. Копировали файлы от root — верните владельца (chown).