Предисловие
Так уж сложилось, что 5 лет назад, будучи ещё начинающим программистом, благодаря моему неистребимому желанию иметь своё мнение, я сошёл с протореной дороги написания модулей под сторонние системы и ступил на тернистый путь написания своей CMS. Я буду писать «Я» поскольку являюсь архитектором системы, но писал я не один, всё это время со мной работали программист и дизайнер, и они являются соавторами всех версий системы. Сейчас же мне хочется представить на обсуждение публики те принципы написания систем, к которым я пришёл сейчас. Также, я думаю, данный пост будет интересен тем, кто пошёл в своём развитии той же дорогой, что и я.
CMS называется Artof CMS. Текущая версия — Artof CMS 3
История версий
Artof CMS 1
Первый опыт создания системы с хоть каким-то разделением компонентов. Не буду составлять гордых списков «Достоинства/Недостатки». Напишу лишь об особенностях:
- Метод написания — на 90-95% процедурный. Тогда был пхп4, а классы представлялись чем-то непонятным и ненужным (есть же функции!)
- Было введено понятие «Ядро», состоящее из файлов с функциями, сторонних классов и библиотек — вобщем всё в куче.
- Весь функционал на уровне выше нулевого реализовался плагинами. Включая авторизацию, шаблоны, константы, настройки и прочее.
- Плагины расширялись подплагинами (на уровне просто подключения файлов подплагинов (если есть) в плагины).
- Точки входа у каждого плагина находились внутри себя, и начинались с подключения файла инициализации.
- ХТМЛ-шаблоны хранятся в БД. Шаблонизатор рекурсивный.
- Жуткая тяга к написанию универсальных плагинов типа Каталог или Страницы, а при возникновении новых задач постоянное внесение в эти плагины дополнительных, настраиваемых опций.
- Плагины не переписывались а модифицировались. Локальный экземпляр системы для любого проекта всегда был один — текущий. Разница между всеми проектами состояла лишь в наборе плагинов и настройках с шаблонами.
Artof CMS 2
- Были введены общие точки входа в корне проекта.
- Функционал каждого плагина стал помещаться в одноимённый плагину класс (вроде модели), хотя контролеры работы плагина всё равно были в отдельных файлах.
- Появился Раутер
- Появилась утилита кеширования, а вместе с ней печальный опыт кеширования результатов запросов к БД в файлы
- ХТМЛ-шаблоны стали компилироваться в PHP-файлы и научились понимать IF, SWITCH, DATE, SUBSTR конструкции
- Пришло слабое осознание того, что всё универсализировать невозможно, и стоит сосредоточиться на текущих задачах.
Artof CMS 3
Абсолютно новая по структуре система. О ней то я буду писать ниже.
Архитектура
Система постороена на HMVC архитектуре.
Самый верхний уровень — это MVC-плагин
Промежуточный уровень — это MVC-шаблон (простите за каламбур, речь идёт не о паттерне проектирования, а о наборе универсальных родительских классов, реализующих базовый функционал данного шаблона). Далее буду называть «Шаблон».
Нижний уровень — общий для всех Шаблонов MVC-родитель — virtualplugin, содержащий универсальные методы для упрощения работы с данными в MVC, и задающий структуру Шаблонов и Плагинов.
Компоненты и файлы системы подразделяются на:
Утилиты — классы, на разном уровне выполняющие различные задачи. Утилиты могут быть низкоуровневыми или нет, использовать друг друга и т.п.
Драйвера — классы, предназначенные для работы со сторонними системами (например платёжными), типами БД (mysql, mysqli) и кеширования (filecache, memcache) и так далее.
Типы — классы, определяющие работу с определённым типом данных через утилиту конструктора форм. Типы могут быть как стандартные (строка, текст, число), так и собственного сочинения (группа, дисциплина, тег). Все типы расширяют класс абстрактного универсального типа и обязаны предоставлять одни и те же методы для определённых задач.
Шаблоны — папки, содержащие конфигурационный XML-файл, и MVC-структуру, реализующую функционал шаблона.
Плагины — папки, по структуре повторяющие шаблоны, по-умолчанию просто переопределяющие имя плагина и полностью наследующие функционал, но дающие возможность изменить до 100% всего функционала Шаблона. Это удобно с точки зрения того, что большинство плагинов похожи друг на друга на 70-90%, и конечно же всегда не хочется копипастить функционал.
Точки входа — файлы в корне проекта, в каждом из которых своим способом производится инициализация.
Кэш — вместилище временных файлов (Тумбиналы, настройки, скомпилированные шаблоны и проч.)
Аплоды — вместилище загружаемых на проект файлов. Как то изображения, файлы.
Статика — элементы дизайна, стили, скрипты, шрифты и прочее, общее для системы и не относящееся к плагинам/Шаблонам.
Классы
Файлы классов подгружаются автолодом.
Объекты классов получаются через библиотекарь классов.
Если класс имеет интерфейс isingleton, библиотекарь возвращает объект из собственного репозитория
Объекты доступны в репозитории библиотекаря через ArrayAccess (можно записывать, удалять, изменять)
Глобалы
Доступны через утилиту globals, сами же суперглобалы GET, REQUEST, POST, COOKIE, SESSION чистятся при инициализации.
Также через эту утилиту осуществляется быстрый доступ к правам пользователя, списку плагинов, языкам.
Нейминг и структура контроллеров
Каждая из точек входа (admin, index, ajax, file, image) пытается вызвать из указанного плагина свой метод, состоящий из имени точки входа и суффикса действия (например admin_categories или index_list), если таковой нет, пытается вызвать метод по-умолчанию. Если и такового нет, генерирует 404.
Таким образом предоставляется простор для переопределения методов из Шаблонов новыми методами из Плагинов, давая простор масштабированию.
Вьюверы и Модели не имеют настолько строгих структур и их структура остаётся на совести разработчика.
По неймингу методов и переменных я не стал морочиться всякими Венгерскими концепциями…
- константы большими буквами, в названии методов — сначала объект, потом действие совершаемое над объектом, переменные и методы — с андерлайнами и без больших букв.
- параметры методов — не более 3х штук.
- файлы классов имеют суффикс .class
Конструктор форм и типы
Эта связка позволяет автоматизировать процессы
- Приведения видов базы/форм/данных_к_выводу
- Построения форм
- Валидации форм
- Определения, какие данные из каких полей где надо выводить
- Сортировки
- Конкретизации (как в яндекс-маркете к примеру, подбор характеристик)
Таким образом, настройкой полей к примеру для каталога занимается не программист, а дизайнер/менеджер, просто набирая поля и проставляя настройки и галочки для каждого из полей. Остальное конструктор делает самостоятельно.
На уровне программиста нужно лишь согласно спецификации вызвать нужные методы из менеджера форм/конструктора форм, не вдаваясь в работу типов.
Система HOOKS/BOOTSTRAPS
HOOK — системный «крюк» к которому можно прицепить функционал. HOOK объявляется при каждом действии, будь то показ страницы или какие-то изменения данных. Вместе с определением хука передаются багажные данные для использования в BOOTSTRAP-ах
BOOTSTRAP — системная «петля» для цепляния за хук. Принимает багажные данные из хука и совершает какие-либо действия.
Назначением HOOK-ам BOOTSTRAP-ов занимается администратор.
Например плагин Пользователи, зарегистрировался человек. Админ прицепил на этот хук бутстреп добавления в список рассылки и заведение аккаунта в блогах.
Раутер
- Раутер не обрабатывает URI заканчивающиеся на .php. Только директории и .html
- Каждое правило в раутере сразу определяет принадлежность к плагину.
- Возможно использование поддоменов
- Подстановка соответствий через $ в гет запрос
- Работает на preg_match() — пока никаких идей насчёт оптимизации этого нет.
Работа с меню
Каждый из плагинов предосталяет набор меню.
Эти меню можно разместить в одной из областей каркаса.
У каждого меню есть собстваенные настройки, указывая которые определяется поведение и внешний вид меню.
Можно определить, на каких страницах данное меню будет отображаться.
Этим занимается дизайнер.
HTML-шаблоны
Компилируются в PHP.
Работает синтаксис IF, SWITCH, DATE, SUBSTR
Подразделяются на шаблоны дизайна, шаблоны писем и CSS-стили.
Шаблон автоматически определяет принадлежащие ему языковые константы
Ведётся история сохранения шаблонов.
Заключение
Вобщем, я постарался дать не слишком подробную обзорную концепцию структуры и возможностей системы. Тех кто сейчас будет обвинять меня в велосипедостроении попрошу не тратить буквы: ) Я прекрасно знаю о количестве систем и фреймворков в сети.
Хотелось бы услышать критику, комментарии и вопросы в адрес написанного.