Skip to content

Исследование ядер CMS

Сравнение архитектур ядер восьми CMS для проектирования собственного ядра. Разбор механизмов расширяемости, стабильности и обновлений. Проверено по официальной документации и исходному коду. Выводы применены в Расширяемости и Центре обновлений.

Разобранные системы

Классические: 1С-Битрикс, WordPress, Drupal, TYPO3. Laravel-CMS: Statamic, Twill, Winter CMS, Botble CMS (+ Filament как admin-ядро, nwidart/laravel-modules).

Механизмы перехвата ядра — сравнение

СистемаХуки/событияИзменить значение по цепочкеЗамена без правки ядраDI
1С-БитриксEventManager, объект Event; AddEventHandler (на хит) / RegisterModuleDependences (в БД)EventResult (блокирует/меняет операцию)приоритет /local над /bitrix; наследование компонентачастичный
WordPressactions + filters на классе WP_Hookfilters — уникальный примитивchild themes, drop-ins, mu-pluginsнет (глобалы)
Drupal#[Hook]-атрибуты (11.1+) + PSR-14 eventsalter-хукиservice decoration, theme suggestionsполный (Symfony)
TYPO3SC_OPTIONS (legacy) → PSR-14 eventsнет отдельного примитиваTypoScript, decoration, XCLASSполный (Symfony)

Битрикс — уроки

  • /local над /bitrix: система обновлений автоматически переписывает только /bitrix/modules/. Любая ручная правка внутри /bitrix молча затирается при обновлении. Обработчик в /local физически вне зоны обновления → переживает апдейт.
  • init.php — свалка: признанный антипаттерн (сотни строк смешанной логики).
  • Слабые места: двойное легаси-ядро (CDatabase + D7 ORM); безопасность как ответственность разработчика → конкретные CVE (модули vote, landing, CVSS 10/10); обновления безопасности требуют активной лицензии (vendor lock-in).

WordPress — уроки

  • Filters — примитив, которого нет в Laravel: цепочка колбэков меняет и возвращает значение. Ближайший аналог в Laravel — Illuminate\Pipeline.
  • Строгая граница wp-content/ vs core — делает безопасным форс-апдейт по чексуммам.
  • Слабые места: 91% уязвимостей WP — в плагинах (11 334 за 2025); плагин = часть ядра по правам (глобальный $wpdb без прослойки); implicit-хуки без типизации и реестра.

Drupal — уроки

  • Service decoration (decorates: в services.yml) — чистый паттерн обёртки сервиса с доступом к оригиналу и приоритетом; переживает минорные апдейты.
  • Class-based хуки (#[Hook], 11.1+) с управлением порядком (OrderBefore/OrderAfter).
  • hook_update_N() — последовательные миграции схемы; hook_post_update() — data-updates.
  • Слабые места: overengineering, крутая кривая обучения, boilerplate на простую фичу.

TYPO3 — уроки

  • Иерархия предпочтений (официальная): события > hooks > decoration > XCLASS. Это и есть «лестница расширяемости».
  • XCLASS — замена класса целиком, «last resort»: ломается при смене сигнатуры без предупреждения.
  • Слабые места: четыре конфиг-синтаксиса (PHP+Fluid+TypoScript+YAML), высокий порог входа.

Statamic — что заимствуем (проверено по исходникам)

  • Манифест extra.statamic в composer.json (name/slug/editions/description), парсится классом Manifest extends PackageManifest. Расширить полем minimum-core-version — его нет ни у Statamic, ни у Twill.
  • AddonServiceProvider — декларативные свойства ($tags, $fieldtypes, $widgets)
    • автозагрузка по папкам (src/Tags/, src/Fieldtypes/).
  • UpdateScript (shouldUpdate()/update()) — версионные миграции аддона между релизами. Прямая заготовка под центр обновлений и миграции схем блоков (_v).
  • Типизированные Domain Events Saving/Saved на каждую сущность (EntrySaving/Saved, 99 файлов событий) — паттерн для Filament-ресурсов с afterSave(). Брать (лучше Twill).
  • Лицензии: editions + единый license key на сайт + периодическая валидация.

Twill — что заимствуем и что нет

  • Брать: CRUD-триада Controller/Repository/Model с базовыми классами, переопределяемыми через конфиг (base_controller/base_repository/base_model) — механизм переопределения дефолтной реализации для всего парка сразу. Trait-hooks в ModuleRepository (HandleSlugs, HandleMedias, HandleRevisions) — композиция поведения без глубокого наследования.
  • Не брать: событийная система слабая (строковый fireCmsEvent() вместо типизированных Events); Capsule — internal-механизм организации кода, не редистрибутируемый unit с манифестом; нет marketplace-контракта.

Winter CMS — что заимствуем и что нет

  • Брать: двухтабличная модель версийsystem_plugin_versions (текущая версия модуля) + system_plugin_history (журнал применённых скриптов для точного отката). Готовый паттерн центра обновлений: «откати сайт X на версию N модуля Y». Декларативный version.yaml (версия → миграции + changelog + флаг important). Каталог хуков расширения admin-форм (backend.form.extendFields, backend.list.extendColumns) — чек-лист точек расширения для Filament.
  • Не брать: транспорт обновлений (winter:update — gateway-zip, несовместим с composer); Twig + Halcyon (чужеродно для Blade/Filament); собственный Backend UI.

Botble CMS — что заимствуем и что нет

  • Брать: lifecycle плагина activate()/deactivate()/remove() (remove() чистит данные плагина); plugin.json с minimum_core_version; fluent LoadAndPublishDataTrait (DX базового провайдера); декларативный config/permissions.php (но материализовать в spatie/laravel-permission, не JSON-флаги); license-API контракт как прообраз (check/latest/download, «1 лицензия = 1 домен»).
  • Не брать: транспорт (overwrite директорий platform/core поверх ФС — хрупко, не откатывается); WP-style do_action/apply_filters (singleton-реестр с krsort/ksort — анти-Laravel магия); Envato/CodeCanyon-модель; ядро закрытое (нельзя composer require).

Итоговый принцип

Ключевая идея всех систем: строгая граница «ядро / пользовательский код» — фундамент безопасных обновлений. В Laravel она уже существует бесплатно (vendor/ vs app/). Стратегия — не копировать чужие ядра, а достроить поверх Laravel недостающие примитивы:

ДостроитьИсточник идеи
Фильтры (значение по цепочке)WordPress
Порядок слушателей (before/after)Drupal 11 / TYPO3
Открытый BlockRegistryсвоё (переделка universal)
Каскад тем + suggestionsWordPress + Drupal
Decoration с приоритетомDrupal
Манифест minimum-core-versionStatamic + своё
UpdateScript версионные миграцииStatamic
Двухтабличная модель версийWinter
Lifecycle activate/deactivate/removeBotble
Версии схем блоков (_v)WordPress Gutenberg
Реестр точек расширения cms:hooksсвоё (нет ни у кого)

Из антипаттернов явно избегать: init.php-свалки (Битрикс), глобального состояния и «плагин = ядро по правам» (WP), четырёх конфиг-синтаксисов (TYPO3), boilerplate на простую фичу (Drupal), собственного транспорта обновлений (Winter/Botble).

Внутренняя база знаний студии