Cобрать лучшее из двух миров — фреймворков и CMS (часть 2)

Cобрать лучшее из двух миров — фреймворков и CMS (часть 2)

496

Предшествующая статья собрала довольно много, иногда очень резких, комментариев , 2-ая часть скажет о конфигурациях которые произошли в течении следующих 4х месяцев и по способности не будет повторять первую часть, которая всё ещё очень актуальна.

Для чего же
Из прошлой статьи не всем было понятно, для чего же всё это создается, определенная неувязка, которую решает продукт.
Проще всего разъяснять такие вещи на примере. CleverStyle CMS не подойдет раз:

Под вашу задачку есть CMS, которая решает задачку на сто процентов
Под вашу задачку есть CMS, которая практически подступает, вы её подпилите, обновления вас особо не беспокоят
У вас Enterprise проект

Подойдет же когда у вас проект, для которого готового решения нет, а перепиливание чего же-то отдаленного схожего будет грудой костылей, которые в последствии нереально будет обновить.

Singleton

Так же в комментах много раз упоминался «антипаттерн» одиночка, тем наиболее что наименования системного трейта этому сопутствовало.
В общем и целом это не совершенно тот одиночка, о котором можно было поразмыслить.
На самом деле это незначительно наиболее непростая штука, обеспечивающая:

единую точку сотворения системных объектов и объектов модулей
кастомизацию системных классов, начиная от полной подмены, и заканчивая поддержкой патчинга 1-го системного класса сходу несколькими компонентами (подробнее)
кэширует вызываемые классы, чтоб даже патчинг системных объектов значительно не сказывался на производительности

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

$Session = csSession::instance();
Всё что клиентскому коду необходимо знать — он получит объект сессии с прогнозируемым общественным интерфейсом, но это может быть не совершенно уникальный системный объект, или даже совершенно не он.
Так же это дозволяет без каких или плагинов и доп инстракций генерировать подсказки в IDE по всем общественным способам и свойствам системных объектов, что очень комфортно.
Аналогия из Laravel:

$Session = $app->make(‘session’)
Вот лишь тут для подсказок IDE необходимо писать инструкции.

А ещё подмененный Singleton для тестов дозволяет заместо возвращаемого объекта подсовывать что угодно, и это активно употребляется.

Composer

Было много комментариев о Composer, PSR4 и с сиим связанным. Раз незначительно углубиться в подробности того, как инсталлируются составляющие и на что влияют их зависимости, становится понятно, что Composer мягко говоря не самое подходящее решение для упаковки компонентов.
«Но ведь он так комфортен для установки библиотек!» скажете вы, и будете непременно правы.
Подключать одну и ту же библиотеку несколько раз в составе различных компонентов и мучиться из-за различных версий не кошерно.
Потому дополнительно к поддержке composer.json, composer.lock и vendor в корне проекта возник отдельный компонент с неожиданным заглавием Composer!
В процессе использования взаимодействие с самим Composer при условии что зависимости не конфликтуют сводится в нулю.
Для того, чтоб пользоваться данной красотой необходимо добавить зависимость от composer в meta.json компонента, и прописать сами зависимости, пример для модуля WebSockets:

{
"package" : "WebSockets",
"category" : "modules",
"version" : "0.29.0+build-45",
"description" : "WebSockets server based on Ratchet and React with client-side bindings as well",
"author" : "Nazar Mokrynskyi",
"website" : "cleverstyle.org/cms",
"license" : "MIT License",
"db" : [
"pool"
],
"db_support" : [
"MySQLi"
],
"provide" : "websockets",
"require" : [
"System>=2.1",
"System<=3.0",
"composer"
],
"require_composer" : {
"cboden/ratchet" : "0.3.*",
"ratchet/pawl" : "0.1.*"
},
"multilingual" : [
"interface"
],
"hide_in_menu" : 1
}
В процессе установки компонента будут собраны Composer зависимости всех компонентов, составлен финишный composer.json, и раз не возникнет конфликтов — всё установится само, раз возникнут — консольный вывод Composer будет переформатирован в HTML, и предоставлен юзеру, пусть решает что с сиим делать.

Вот таковой composer.json генерирует модуль для установки всех зависимостей:

{
"repositories" : [
{
"type" : "package",
"package" : {
"name" : "modules/Http_server",
"version" : "0.8.0+build-13",
"require" : {"react/http" : "0.4.*"},
"dist" : {
"url" : "/web/cscms.org/www/components/modules/Composer/empty.zip",
"type" : "zip"
}
}
},
{
"type" : "package",
"package" : {
"name" : "modules/WebSockets",
"version" : "0.24.0+build-38",
"require" : {
"cboden/ratchet" : "0.3.*",
"ratchet/pawl" : "0.1.*"
},
"dist" : {
"url" : "/web/cscms.org/www/components/modules/Composer/empty.zip",
"type" : "zip"
}
}
}
],
"require" : {
"modules/Http_server" : "0.8.0+build-13",
"modules/WebSockets" : "0.24.0+build-38"
}
}
Виртуальные пакеты объявляются на месте, от их же сходу ставится зависимость, таковым образом разрешение конфликтов на сто процентов лежит на обычных механизмах Composer (zip файл это единственное что необходимо иметь реальное иметь в файловой системе, он полностью пуст снутри).

Разделение логики и представления

В эталоне на сервере никакого представления.
Пока готово как пример в клиентской части модуля магазина (ниже), хотя и будет обновляться с внедрением JSON-LD для малого размера серверного кода и наилучшей индексации.
На данный момент страница продукта магазина в коде смотрится так:

<section data-date="0" data-id="1" data-in_stock="24" data-price="20" data-soon="0" is="cs-shop-item">
<div id="images">
<img alt="" src="http://cscms.org/storage/public/Plupload/2015-01-03/18/2_031854a812c6b264b.jpg">
<img alt="" src="http://cscms.org/storage/public/Plupload/2015-01-03/18/2_035654a812ec26d24.jpg">
<img alt="" src="http://cscms.org/storage/public/Plupload/2015-01-03/18/2_035654a812ec1c834.jpg">
</div>
<div id="videos">
<a href="https://www.youtube.com/watch?v=rHBxJCq99jA"> </a>
<a href="https://www.youtube.com/watch?v=bmtbg5b7_Aw"> </a>
</div>
<h1>Boots</h1>
<div id="description">
<p>Nice boots</p>
</div>
<div id="attributes">
<table>
<tr>
<td>Size</td>
<td>2</td>
</tr>
</table>
</div>
</section>
То есть не имеет ничего общего с тем, как оно смотрится на страничке, как это устроено тоже упоминалось.

Стиль кодировки

То, что дают PSR мне не чрезвычайно нравится, потому стиль кодировки был незначительно обновлен в wiki, дополнительно сейчас в репозитории лежат файлы конфигурации стиля кодировки и инспекций PhpStorm, при открытии проекта он сходу будет сконфигурирован подабающим образом.
Все новейшие файлы форматируются сиим стилем, старенькые файлы при редактировании тоже.
Просьба уважать стиль создателя проекта)

Рефакторинг

В промежутке от версии 1.0 в порядок приводилось ядро, в итоге широкого рефакторинга система стала значительно понятнее и наиболее прогнозируемая, а так же стали возможными некие функции, как то работа в Request/Response режиме (о чём дальше).

Глобально:

класс csTrigger был переименован в csEvent, чтоб больше не сбивать с толку, так же был упрощен и возникли новейшие способности, как то одноразовая подписка на событие, как jQuery.fn.one()
дополнительно возник cs.Event на фронтенде с теми же способами, порядком аргументов что и csEvent на сервере
csSession образовался опосля еще одного рефакторинга csUser, дозволяет дополнительно убыстрить работу в асинхронном режиме
csRoute объединил функциональность, отвечающую за маршрутизацию, которая по историческим причинам была сразу в csConfig и csIndex, что было далековато не разумеется
$_SERVER оборачивается в массиво-схожий объект для простоты получения подходящей инфы независимо от конфигурации, это позволило избавиться от дублирования кода
ExitException употребляется заместо exit/die в тех редких местах, где они были, посторонние библиотеки просто патчатся автоматическим поиском и подменой для поддержки данной функциональности, критическая фича для режима Request/Response
некие интегрированные функции, работающие с глобальным контекстом, были изменены на обертки (header() -> _header()), посторонние библиотеки просто патчатся автоматическим поиском и подменой для поддержки данной функциональности (или раз употребляются места имен — просто объявляется пользовательская header() в том пространстве), критическая фича для режима Request/Response

Множество остальных конфигураций перечислять нет смысла, release-notes.md выше 480 строчек с детализированным описанием главных конфигураций и советами к плавному обновлению.

Больше рефакторинга прекрасного и различного ещё будет. Отчасти отрефакторен системный модуль, но лишь отчасти.

Статический анализ

Ранее весь статический анализ заключался в инспекциях IDE PhpStorm, на данный момент же каждый коммит дополнительно инспектируют SensioLabsInsight и Scrutinizer.
На текущий момент исправлены все Major недостатки, которые они понаходили, и отчасти Minor/Warning. Эти два инструмента творят чудеса статического анализа.
Инструменты активно употребляются, их отчёты будут уменьшаться с каждым коммитом.

Релизы

Начиная с 1.110 все сборки автоматизированы, в случае прохождения тестов опосля каждого коммита ночная сборка улетает на SourceForge в папку nightly, раз это релиз — собирается релизная версия и падает в stable/{version} там же.
Это упрощает релизы и убирает все те неудобства, которые появлялись с публикацией релизов в виде страницы со ссылками на файлы в Dropbox.

Новейшие фичи

Во-первых, некие составляющие, которые уже довольно издавна разрабатывались и числятся стабильными выросли до версии 1.0.
Во-вторых, было бы грустно констатировать что из коробки никакой новейшей функциональности за 4 месяца не возникло.

Http сервер
В один прекрасный момент уже упоминалось тут. Это модуль, который реализовывает Http сервер на PHP, что дозволяет в рамках 1-го процесса обрабатывать множество запросов и очень хорошо сказывается на производительности (в несколько раз).
Раз соблюдать несколько легких правил, то все составляющие будут работать в этом режиме без конфигураций.

WebSockets
Тоже было тут, тесновато интегрирует WebSockets с CleverStyle CMS, позволяя отправлять данные клиенту и обратно фактически в настоящем времени без лишней перегрузки, по принципу устройства похоже на модуль Http сервера.

Магазин
Возник модуль магазина. Изготовлена попытка сотворения модуля общего назначения, то есть из коробки нет функционала накопительных скидок, акций, спецпредложений и различных остальных вещей.
Тем не наименее модуль имеет набор событий, с помощью которых всё это довольно просто можно воплотить конкретно в том виде, который для вас нужен.
Так же вся клиенсткая часть построена на интернет-компонентах, и изменяется полностью хоть каким вероятным методом, вы ограничены лишь собственной фантаизей (при этом никаких обычных шаблонов нет и не будет).

Оплата Bitcoin
Модуль магазина поддерживает подключаемые системы оплаты с помощью интерфейса очень общего назначения. Этот модуль первым реализует этот интефейс, предоставляя возможность оплаты Bitcoin (находится автоматическая конвертация неких валют по текущему курсу).

Подсветка синтаксиса
Библиотека, как и все другие, пропатчена для работы с интернет-компонентами, дружит с зрительными редакторами. Как-то в блоге нужна была подстветка синтаксиса, возникла интеграция библиотеки Prism для этих целей.

Напоследок

Система активно развивается, код становится чище, проще, понятнее, зарастает новейшей функциональностью, повсевременно дополняется и поддерживается актуальной документация.

Обратная сопоставимость сохранялась всю ветку версий 1.x, версия 1.110 была крайней из данной серии.
Устаревший код был не так давно удален в связи с переходом на 2.х версии, так же малое требование к версии сейчас PHP 5,5+.
При условии что все советы по обновлению выполнялись, обновление с 1.110 до 2.x очень тривиальное.

Проще всего запустить и испытать с помощью Docker
Весь начальный код на GitHub, там же wiki с документацией.

P.S. habrahabr.ru Рисунки опосля средины поста тоже есть, занятные, но их кушает парсер хабра в момент публикации, почему — пока не понятно, будут добавлены как лишь поправят.