For the complete documentation index, see llms.txt. This page is also available as Markdown.

Обновление с версии 9.8

Список изменений для обновления с версии JohnCMS 9.8

Маршрутизация: новый формат routes.local.php

Файл config/routes.local.php теперь должен возвращать callable, а не использовать $router напрямую.

Было:

<?php

/** @var \Johncms\Router\RouteCollection $router */

$router->map(['GET', 'POST'], '/contacts', 'modules/contacts/index.php');

Стало:

<?php

declare(strict_types=1);

use Johncms\Router\RouteCollection;
use Johncms\System\Users\User;

return static function (RouteCollection $router, User $user): void {
    $router->map(['GET', 'POST'], '/contacts', 'modules/contacts/index.php');
};

Актуальный пример есть в config/routes.local.php.example.

Маршрутизация: перенос маршрутов в модульный config/routes.php

Если у вас есть собственные модули с маршрутами в routes.local.php, рекомендуется перенести их в config/routes.php внутри папки модуля. Файл подхватывается автоматически и не требует ручного подключения.

config/routes.local.php по-прежнему поддерживается, но считается устаревшим и будет удалён в будущих версиях. При наличии файла будет выведено deprecation-предупреждение.

Пагинация: удалён форк johncms/johncms-pagination и Tools::displayPagination()

В версии 9.9 полностью удалены устаревший форк johncms/johncms-pagination (Laravel-метод ->paginate() и LengthAwarePaginator) и метод Tools::displayPagination(). Вместо них используется компонент \Johncms\Http\Pagination (PaginationFactory, PaginationGuard, Pagination).

Если в ваших модулях встречается что-либо из перечисленного, их нужно перевести на новый компонент, иначе будут ошибки «class/method not found»:

  • ->paginate(...) в запросах Eloquent (в том числе прямо в контроллере, без репозитория и use case);

  • тип Illuminate\Contracts\Pagination\LengthAwarePaginator в репозиториях, use cases и DTO;

  • вызовы $this->tools->displayPagination(...) в контроллерах;

  • вызов $paginator->render() в шаблонах (метод рендера старого пагинатора).

Типичная ошибка при пропущенной миграции:

Она возникает при первом же обращении к странице, где вызывается ->paginate(): класс пагинатора удалён вместе с форком, поэтому метод больше не работает.

Полное описание компонента — на странице «Пагинация». Ниже — краткая схема миграции.

1. Репозиторий: ->paginate()count*() + get*(limit, offset)

Было:

Стало:

2. Use case: разделите на count() и getPage()

3. Контроллер: displayPagination() / пагинатор → PaginationFactory + PaginationGuard

Было:

Стало:

4. Шаблон: $paginator->render() → готовая строка пагинации

Старый пагинатор передавался в шаблон целиком, а HTML строился вызовом его метода render(). Так делать больше нельзя — сам объект пагинатора удалён.

Было:

Стало (контроллер передаёт обычный массив элементов и уже отрендеренную строку пагинации):

Где $pagination — результат $pagination->render(), переданный контроллером.

Шаблон system::app/pagination теперь работает только с новым форматом элементов (ключ type). Легаси-ветка (элементы с name/url без type) из тем default и admin удалена. Если у вас своя тема с собственным шаблоном пагинации — приведите его к новому формату (см. шаблоны темы default).

Простой модуль: ->paginate() прямо в контроллере

В старых компактных модулях пагинатор нередко вызывался напрямую в контроллере, без репозитория и use case. Такой код тоже ломается («class not found») и требует миграции.

Было:

Стало (данные считаются через use case, а пагинация строится штатными сервисами):

Сервисы PaginationFactory/PaginationGuard и use case можно получить как аргументы метода-экшена — контейнер подставит их по типу. Не забудьте связать интерфейс репозитория в config/services.php модуля:

Готовые примеры в коде

Проще всего ориентироваться на уже переведённые штатные модули. В качестве компактных образцов посмотрите:

  • modules/notifications — минимальный пример: репозиторий с countNotifications()/getNotifications(limit, offset), use case с count()/getPage() и контроллер IndexController с PaginationFactory/PaginationGuard.

  • modules/community — несколько списков с сортировками и фильтрами (учитывайте сохранение query-параметров в ссылках пагинации).

Если у вас несложный модуль, проще всего скопировать структуру из modules/notifications и адаптировать под свои сущности.

Конвертация существующих данных (одноразовые команды)

В версии 9.9 редактор BB-кодов заменён на CKEditor (личные сообщения, библиотека, загрузки и комментарии к ним, а также комментарии фотоальбомов), а в библиотеке и загрузках добавлены ЧПУ на основе slug-ов. Чтобы привести уже существующие данные к новому формату, после обновления нужно один раз выполнить консольные команды.

Команды запускаются через CLI-вход system/bin/console:

Особенности:

  • Команды одноразовые: после успешного запуска факт выполнения сохраняется в файле config/autoload/one_time_tasks.local.php, и повторный запуск будет пропущен с предупреждением. Чтобы выполнить команду повторно намеренно, добавьте флаг --force.

  • Команды конвертации BB-кодов поддерживают флаг --dry-run (показывает, сколько записей будет затронуто, без сохранения изменений) и --batch-size (размер пакета обработки, по умолчанию 500).

  • Конвертация BB-кодов идемпотентна: записи, уже сохранённые в HTML, повторно не обрабатываются.

Нормализация ссылок в постах форума

Команда forum:normalize-message-links нужна, если при переносе форума все ссылки в текстах постов оказались завёрнуты во внутренний редирект /redirect/?url=…, а ссылки на посты и темы остались в устаревшем виде (?act=show_post&id=N, ?type=topic&id=N) и ходят через 301-редиректы. Команда:

  • снимает обёртку /redirect/ со своих (внутренних) ссылок, делая их прямыми; внешние ссылки остаются нетронутыми;

  • переписывает ?act=show_post&id=N в канонический адрес поста /forum/post/N/;

  • переписывает ?type=topic&id=N в ЧПУ темы (если тема существует).

Свой домен определяется по johncms.homeurl. Если исходные ссылки в постах содержат другой домен (например, старый адрес сайта), передайте его через --domain (опцию можно повторять):

Команда одноразовая (--force для повторного запуска) и поддерживает --dry-run и --batch-size (по умолчанию 500).

Модуль «Коллекции»: создание таблиц

В версии 9.9 добавлен новый модуль «Коллекции» (collections). При обновлении существующей установки его таблицы не создаются автоматически — веб-инсталлятор запускается только на чистой системе. Поэтому после обновления нужно один раз выполнить скрипт из папки install:

Скрипт создаёт пять таблиц модуля: collections, collection_fields, collection_sections, collection_items, collection_item_values.

Особенности:

  • Скрипт безопасен при повторном запуске: если таблица collections уже существует, он ничего не делает и сообщает, что модуль установлен.

  • По умолчанию демо-данные не создаются. Чтобы завести демонстрационную коллекцию «Blog» с парой полей, разделом и элементом, добавьте флаг --demo:

  • Модуль должен быть перечислен в installed_modules в файле config/autoload/modules.global.php. В штатной поставке он там уже есть; если конфигурационный файл правился вручную, добавьте 'collections' в список, иначе скрипт не найдёт класс установщика модуля.

После установки управление коллекциями доступно в админ-панели по адресу /admin/collections.

Модуль «Согласия»: создание таблиц

В версии 9.9 добавлен новый модуль «Согласия» (consent) — справочник согласий на обработку персональных данных и журнал их принятия. При обновлении существующей установки его таблицы не создаются автоматически. Поэтому после обновления нужно один раз выполнить скрипт из папки install:

Скрипт создаёт две таблицы модуля: consents (справочник согласий) и consent_log (журнал принятых согласий).

Особенности:

  • Скрипт безопасен при повторном запуске: если таблица consents уже существует, он ничего не делает и сообщает, что модуль установлен.

  • Модуль должен быть перечислен в installed_modules в файле config/autoload/modules.global.php. В штатной поставке он там уже есть; если конфигурационный файл правился вручную, добавьте 'consent' в список, иначе скрипт не найдёт класс установщика модуля.

  • Так как добавлен новый PSR-4 неймспейс Johncms\Modules\Consent\, после выкладки кода нужно обновить автозагрузчик Composer: composer dump-autoload.

После установки управление согласиями доступно в админ-панели по адресу /admin/consents, а журнал принятых согласий — по /admin/consents/log.

Модуль «Контакты»: создание таблицы

В версии 9.9 добавлен новый модуль «Контакты» (contacts) — публичная страница с контактной информацией и формой обратной связи. При обновлении существующей установки его таблица не создаётся автоматически. Поэтому после обновления нужно один раз выполнить скрипт из папки install:

Скрипт создаёт таблицу contact_messages, в которой хранятся полученные обращения.

Особенности:

  • Скрипт безопасен при повторном запуске: если таблица contact_messages уже существует, он ничего не делает и сообщает, что модуль установлен.

  • Модуль должен быть перечислен в installed_modules в файле config/autoload/modules.global.php. В штатной поставке он там уже есть; если конфигурационный файл правился вручную, добавьте 'contacts' в список, иначе скрипт не найдёт класс установщика модуля.

  • Так как добавлен новый PSR-4 неймспейс Johncms\Modules\Contacts\, после выкладки кода нужно обновить автозагрузчик Composer: composer dump-autoload.

После установки настройки контактов доступны в админ-панели по адресу /admin/contacts, полученные обращения — по /admin/contacts/messages, а публичная страница — по /contacts/.

Что нужно сделать после установки:

  • Заполнить контактные данные в админке (/admin/contacts): e-mail, телефон, адрес, часы работы, ссылки на соцсети. Текстовые поля мультиязычные: если значение для текущего языка не заполнено, показывается значение для языка сайта по умолчанию, а если и его нет — английское.

  • Включить форму обратной связи флажком «Включить форму обратной связи» — по умолчанию она выключена, и на странице выводится только контактная информация.

  • При необходимости указать «E-mail для уведомлений». Если поле пустое, уведомления о новых обращениях уходят на e-mail сайта из системных настроек.

  • Уведомления отправляются через очередь писем, поэтому у сайта должен быть настроен планировщик (cron), который её разбирает. Без него обращения продолжат сохраняться в базе, но письма отправляться не будут.

  • Если нужно согласие на обработку персональных данных на форме, добавьте в модуле «Согласия» (/admin/consents) активное согласие с контекстом contacts — его чекбокс появится на форме, а факт принятия попадёт в журнал.

В версии 9.9 в модуль «Согласия» добавлена страница «Cookie-баннер» (/admin/cookie-banner), а у счётчиков аналитики появилась опция «Загружать только после согласия на cookie». Настройки самого баннера хранятся в конфигурации (config('johncms')) и не требуют изменений в базе, но для опции счётчиков в таблицу cms_counters добавлен столбец require_cookie_consent.

При обновлении существующей установки столбец не добавляется автоматически. Поэтому после обновления нужно один раз выполнить скрипт из папки install:

Особенности:

  • Скрипт безопасен при повторном запуске: если столбец require_cookie_consent уже существует, он ничего не делает и сообщает, что таблица актуальна.

  • Опция счётчика работает вместе с cookie-баннером: счётчик с включённым флагом подключается на странице только после того, как посетитель примет баннер (/admin/cookie-banner → включить баннер). До согласия код счётчика изолирован в <template> и не выполняется. Если баннер выключен, получить согласие нельзя, и такой счётчик загружаться не будет.

  • Cookie-баннер выводится только в публичной теме default.

Последнее обновление

Это было полезно?