Система сохранила бесплатную модель распространения и открытый исходный код (MIT), но исходный код был полностью переписан под MVC архитектуру и автозагрузку PSR-0. Многие «велосипеды» были убраны из системы, а их место заняли популярные компоненты: symfony http foundation, laravel eloquent и многие другие.
Переработка архитектуры системы
Обсуждая 2ую версию системы многие пользователи habrahabr советовали существенно переработать систему с учетом современных тенденций: добавить менеджер зависимостей и версий composer, ввести устоявшуюся MVC архитектуру и привести код к единому PSR-1/2 стилю. Код 2ой версии действительно имел достаточно низкое качество и об него можно было сломать ногу (
Внедрить современные инструменты и принципы разработки приложений было просто необходимо, однако переписывать существующий код было практически нереально — поэтому было принято решение переработать архитектуру системы «с нуля».
Система была разделена на несколько функциональных частей: базовая структура, ядро, консоль. Для каждой части был создан репозиторий, настроен composer и проект был опубликован на packagist. Все части связываются при помощи зависимостей в composer.json базового компонента.
Отказ от велосипедов
За последние годы разработки приложений я познакомился с большинством популярных фреймворков, такими как symfony, laravel, yii и codeigniter. Большинство «идей взаимодействий», которые я пытался самостоятельно реализовать в своей CMS,
Итак, следующие собственные части «велосипеда» были заменены на уже устоявшиеся популярные компоненты:
- Работа с сетью (Networking): symfony http foundation
- Работа с базой данных (DB manager): laravel eloquent
- Безопасность HTML кода: HTML purifier
- Работа с консолью: symfony console
- Ядро кеширования (Caching): php fast cache
- Отладка (Debugging): debugBar
- Работа с почтой (Mailer): swiftmailer
- oAuth 2.0 авторизация: hybridauth
Для некоторых из используемых компонентов были написаны «потомки», расширяющие или упрощающие функциональные возможности компонента для нужд системы. Использование данных компонентов позволило достаточно упростить базовое ядро системы и снизить порог вхождения для других разработчиков.
Производительность и совместимость
А не ввести ли нам поддержку php-5.2 и не юзнуть ли polyfill? Нет, нет и еще раз нет. Сейчас, на волне выхода php 7.1 и движения к deprecated 5.5 нет абсолютно никакого смысла поддерживать устаревшие версии php. Соблазн использовать polyfill, конечно, велик, но и от него можно отказаться дабы не усложнять и без того непростую систему.
FFCMS 3 будет работать на любом интерпретаторе php начиная с версии 5.5, в связке nginx — php-fpm, apache2 — php или любыми другими связками (при условии переписания правил перезаписи uri).
Производительность системы существенно не пострадала, хотя расход ресурсов стал несколько большим, чем во 2ой версии (оно и не мудрено),
Шаблонизация (или голый php?)
В данном споре бойцы сломали немало мечей, но единого мнения в вопросе нет. Многие считают, что самого синтаксиса php вполне достаточно для шаблонизации, а некоторые без twig и blade не видят своей жизни. Во 2ой версии системы использовался twig, но мной было принято решение ограничиться классическим php синтаксисом для генерации html кода в представлениях.
// экшен контроллера:
public function actionIndex()
{
// blablabla
return $this->view->render('dir/file', [
'param' => 'my value'
]);
}
// вьюшка
<h1>Demo view</h1>
<p>param value is: <?= $param ?>
С UI осталось все по прежнему — jquery & bootstrap вполне проверенная временем связка.
БД, запросы и ActiveRecords
Для взаимодействия с базой данных в рамках PHP существует множество различных путей. Кто то работает с голым PDO, кто то с Doctrine и QueryBuilder'ами. В FFCMS используется библиотека laravel eloquent, которая позволяет взаимодействовать с базой данных по средствам сборщика запросов (Query builder) а так же при помощи подхода ActiveRecords.
ActiveRecords очень удобны для работы с БД и существенно упрощает и сокращает синтаксис запросов. Конечно, это не полноценный ORM уровня Doctrine, однако для целей CMS его вполне достаточно.
Миграции
Без миграций и их дальнейшего «деплоя» сейчас никуда. Нет, есть конечно же люди использующие mysqldump/pg_dump но мы не будем следовать этим путем. В ffcms 3 присутствует стандартная реализация миграций — классы с 3мя методами up(), seed() и down(), возможность создания, применения и отката миграций. Стандартные миграции хранятся в /Private/Migrations, но при помощи MigrationsManager могут быть имплементированы миграции из любых директорий.
Отладка
Для удобства быстрой отладки и профилирования запросов в ffcms встроен функционал phpdebugbar. Данный механизм позволяет выполнять отладку «на скорую руку», когда нет возможности или времени на подключение xdebug/zenddebug. Отладчик выглядит в виде панели и доступен для включения в настройках админ панели.
Тестирование
Тестирование работоспособности продукта вручную не является тенденцией современной разработки. Для целей автоматического тестирования кода системы и UI была внедрена система автоматических тестов — codeception, которая сочетает в себе стандартное unit-тестирование и acceptance тестирование интерфейсов.
Тесты можно запустить из корня при помощи команды codecept run, предварительно запустив selenium с драйвером для chrome или другого браузера. Так же необходимо отредактировать конфиг тестового окружения (/tests/acceptance.suite.yml) под вашу прослойку. Для настройки тестов есть небольшой документ с инструкциями к применению (документ не был изначально предназначен для «всех глаз», уж простите).
Расширения
В виду наличия PSR-0 автозагрузки система расширений была пересмотрена. Сейчас все расширения разделены на 2 типа — приложения и виджеты, первые — занимают определенный корневой URI в зависимости от контроллера и при помощи actions обрабатывают те или иные запросы; вторые — предназначены для отображения в каком-либо месте представлений путем прямого обращения к классу виджета.
Кроме того, весь набор «реализаций» может быть завернут в один пакет и при помощи git-а и composer-а соблюдая стандарт автозагрузки может распространятся как самодостаточная реализация. Ярким примером является реализация форума или демо-пакет.
Что ж, мой рассказ достаточно затянулся, но пожалуй в одну статью все уместить невозможно. Буду рад ответить на ваши вопросы и выслушать ваши пожелания.
> Официальный сайт: ffcms.org (зеркало: ffcms.ru)
> Проект на github: phpffcms
> Документация администратора и разработчика: doc.ffcms.ru (в процессе доработки).
Комментарии (77)
Fortop
17.01.2017 21:53Composer-то поддерживается или нет?
zenn
17.01.2017 22:03Конечно, это указано прям в статье и несколько раз. На всякий случай: composer.json / packagist
Fortop
17.01.2017 22:04Действительно указано, причём практически в самом начале.
Значит я очень невнимательно прочёлzenn
17.01.2017 22:08Ничего, бывает, у меня под вечер у самого глаза еле открыты после рабочего дня и пары публикаций. Зато теперь вы в этом точно уверены, а на последок подкину вам метод развертки проекта в 3 команды:
# установим глобальный asset плагин composer global require "fxp/composer-asset-plugin:1.2.*" # выполняем установку ffcms в ./path/to/root composer create-project phpffcms/ffcms ./path/to/root 3.0.0 --keep-vcs # загрузка последних обновлений composer update # инициализация консольного установщика php console.php main:install
Развлекайтесь ;)
denisyukphp
17.01.2017 22:51На своём сайте вы сравниваете свою CMS с Битриксом, Вордпрессом, Джумлой и другими. Не думали развиваться в сторону какой-нибудь нишевой CRM и дальше монетизировать её? Потому как рынок CMS сильно перегрет, куча документации и видео по ним, да и такую же систему можно быстро поднять на фреймворке или слепить из компонентов, если будет необходимость.
zenn
17.01.2017 22:58Я задумывался над этим вопросом, возможно действительно следует сделать уклон в какое-то определенное нишевое направление, хотя в самых перспективных (eCommerce) конкурентов еще больше.
maxic
17.01.2017 23:18В e-commerce фактически кроме Magento и Opencart ничего стоящего по архитектуре нет
Остальные — сплошной архитектурный говнокод
Но составить им конкуренцию уже практически невозможно, уж очень они хорошиustasby
18.01.2017 02:29+2В опенкарте есть архитектура? Да вы явно не заглядывали в него, он из <цензура> и палок, из стоящих как минимум есть cs-cart, readyscript, prestashop. А Magento, вы представляете стоимость разработки и поддержки, да 99.9% всех магазинов никогда столько прибыли то не принесут.
maxic
18.01.2017 02:53Это вы не заглядывали в него. Я с ним каждый день "сплю". Вот не рассказывайте мне про opencart и тем более про г… престу, cs… и т.п. Вы еще скажите что в битрикс "архитектура" есть...:)
Alexufo
18.01.2017 03:53лапша код там в опенкарте, млять тонна одинаковых шаблонов распиханных по папкам, 6 шагов регистрации юзеру, 5 форм отображения одних и тех же данных "информация о пользователе".
нет быстрого заказа, а править корзину нааяксенную через все ядро...
Престашоп не имеет в коробке самовывоз. Я промолчу.
maxic
18.01.2017 04:30-1Ну сразу видно что в opencart вы полный дилетант.
Даже и комментировать не буду
Видел звон — не знаю где он. "Раз установил"v-derckach
23.01.2017 15:20Вот не заглядывал в последние версии, но 1.х-2.0 — расширения — через патчинг исходных файлов? Серьёзно? И костыли для обхода этого, но никак не нормальная система хуков и автозагрузки… Совместимость тщательно тестировать приходится даже при обновлении на минорные версии…
В общем, не хочу материться, но на этой штуке можно что-то сделать, красивый MVC, да, но поддерживать её — свят-свят-свят!
maxic
18.01.2017 04:48-1Opencart приведен в соответствии с законодательствам многих стран, где обязательным считается поэтапное оформление заказа и регистрация данных о покупателе. Быстро учить мат. часть e-commerce систем а не умничать здесь
В opencart существует большое множество модулей одно страничного оформления заказов как и быстрая регистрация в "пару" полей. Если законодательством вашей страны разрешено одно страничное оформление заказа с минимальными данными о покупателе — устанавливайте, там сложного ничего нет, таких модулей валомAlexufo
18.01.2017 09:25Я работал несколько лет с опенкартом, сопровождал пару магазинов, прочувствовал все прелести обточки напильником этого "алмаза" с модулями и без модулей, платными и не платными. Работал и с битриксом.
Напомните, в каком году OC вышел, в 2011? С тех пор он не поменялся вообще, если не считать бутстрапа со 2 версии и мелочей, которые ничего не сменяют кардинального. То что он рука об руку идет с vqmod уже все объясняет.maxic
18.01.2017 09:33Серьезно? :) Не менялся?
Ну конечно, не специалист кроме boostrap-a больше ничего не увидит.
Там глобальные изменения на уровне архитектуры, кода.
И нету vQmod -а уже, уже забыли про него давно.
Знаете, судя по вашим ответам, вы всё видели "издалека" и "пару раз"
Мне если честно, как руководителю IT проектов e-commerce систем (senior), смешно читать ваши ответы. Ну ладно бы студент такое писал, но в профиле у вас стоит "тех. директор" (чего правда?) И такие ляпы выдаете.Alexufo
18.01.2017 10:02В общем то я вас понимаю. Если вы руководитель — веры терять нельзя. Пишу без сарказма.
У меня с этим делом все самоубийственно плохо.maxic
18.01.2017 10:42-2Это демагогия с вашей стороны.
Когда за спиной 20 лет разработок и большое портфолио в веб разработке (и кстати своя cms как у автора тоже есть, и на которой десятки проектов крутились) и работа на всех cms и fw — то здесь нет выбора — он один в e-commerce: Magento или opencart
Всё
Magento для серьезных проектов
Opencart для простых и средних (которых 99%)
Конкурентов то нету :)
woocommerce с его неандертальским говнокодом? Или битрикс у которого понятие архитектура отсутствует напрочь, но агрессивный маркетинг. Преста с говно архитектурой? Остальные я рассматривал детально — там вообще ужас.
Никто и близко не встал по архитектуре с opencart и magento
Но вы не специалист в области архитектуры — это и так видно. Вам она просто не понятна. Для вас архитектура — это код. Не путайте грешное с праведным.
Alexufo
18.01.2017 10:54Дискуссии над предметом, который приносит хлеб, заведомо бессмысленны. Вы его всегда будете защищать выдавая личные предпочтения и опыт за плюсы, а если кто-то несогласен — дилетантство.
Работать с битриксом мне куда удобнее, хоть я его терпеть не могу.
oxidmod
18.01.2017 11:21есть еще такие штуки как shopware (http://www.shopwaredemo.de/) для действительно сложных проектов и OXID (http://demoshop.oxid-esales.com/professional-edition/) для случаев попроще
Alexufo
18.01.2017 03:59+1Умоляю!
Займите нишу!
Это дерьмо вроде опенкарта и престы ожирело и застряло в норе как винни-пух! Я кровью обливаюсь когда меня просят совета, а что я скажу? Шлю к мерчиуму какому нибудь. Хоть глаза бы не видели мои больше кода этих cms.
Из опенсурсного в екоммерсе НЕТУ НИЧЕГО нормального вообще! Кучу лет!
Толпа просто попрет как только пойдут слухи о минимальстичном современном движке интернет магазина.maxic
18.01.2017 04:39-3Если вы не работали с opencart — то давайте не умничать.
По вашим ламерским ответам об opencart я очень быстро понял "who is who" вы. А о наборе кармы по "перепечаткам" тем более "всё с вами ясно"arteast
18.01.2017 09:44+4Либо у вас какой-то другой opencart, либо развился стокгольмский синдром. Можно говорить, что опенкарт лучше <другой ecommerce solution name>, но код оставляет желать лучшего.
Несколько примеров:
- контроллеры прибиты гвоздями к вью, к конкретному шаблону. Пример: попробуйте разобрать ajax-овый аккордеон в чекауте на отдельные странички, и посмотрите, сколько придется править в контроллерах.
- в каждом методе каждого контроллера есть десятки строк кода, просто пробрасывающие строки из language во view
- километры копипащенных полей в формах view безмолвно вопиют. Обработка custom fields в тех же вью добавляет свою мощную ноту в том хоре.
- используется давняя хорошая традиция защищаться от XSS путем HTML-эскейпа записей в базе данных
- как устанавливаются 100500 обещанных нам расширений? Путем накатывания патча на код!
maxic
18.01.2017 10:26-3Всё закончили. Ваш бред, даже не хочу комментировать
Вы даже не понимаете о чем пишите
О стандартизации и унификации вы даже понятия не имеете. И для вас в шаблонах таскать "вычисления" — это нормальное дело я так понял, но только не для профи, и не для нормальной архитектуры
И ничего править не надо — перехватил хуком loader и подставляй любые свои значения, любые шаблоны.
Да это и не надо. Так как все унифицировано и стандартизировано.
Насчет патча на код — это уж вообще рассмешили. Сразу видно "смотрел поверхностно давно".
Там давно уже есть система ивентов, а оверлорд хуки можно было делать еще в 1.5,x. (в архитектуре это заложено — но вам это не понятно видно было) Хочешь пользуйся не хочешь не пользуйся — есть выбор. Есть квалификация — пользуешься всей мощью архитектуры, нету — пишешь "ваш" бред. И причем здесь escape XSS к БД, все параметры очищаются еще на точке входа, escape — это просто контрольный выстрел и признак хорошего тона, там большего и не надо уже ничего
Если вы не специалист то даже не поймете, что opencart даже в 1.5.x можно было не использовать vqmod. vqmod — это для учеников, домохозяек, дилетантов, блондинок и за счет них популяризации opencartPeretyaka
18.01.2017 12:05+3Вы бы сосредоточились на аргументах, а не оскорбляли собеседников, глядишь и что-то бы полезное было в вашей дискуссии.
Я не спец по OC, но вот открыв рандомный файл, я как-то уже не очень горю желанием его изучать:
https://github.com/opencart/opencart/blob/master/upload/catalog/controller/product/product.php
Ну а с точки зрения архитектуры. Давайте пообщаемся про разделение и связывание, очередя, микросервисы, котейнеры, масштабирование. А так: с какой-то то там версии добавили систему ивентов. Это вряд ли можно назвать архитектурой, просто костыли, которые лучше оверлоад и которые были проверены и вдоль и поперек откатаны задолго до 2011 года, не понятно почему они не использовались в проекте изначально.maxic
18.01.2017 15:23-3Давайте вы вначале изучите и поработаете хотя бы годик с opencart — потом обсудим
Ok
А так это бесполезный треп — как с Alexufo — который поверхностно с ним знакомAlexufo
19.01.2017 15:15+1ну как поверхностно. Я перепиливал шаблон полностью, прокидывал новые поля в адмику, и удивился как в битриксе удобнее вставлять компоненты вместо правки сотен вьюх с их сотнями контроллеров. Я устал просто бродить по иерархии OC.
Нельзя просто так взять и сделать тему с 0 в OC. Я не понимаю предназначение тем, где обязательными являются одновременно сотня файлов.
И сделал вывод — OC не сделан для кастомизациии тем, если не считать кастомизацией перебивание цветов в css.maxic
19.01.2017 15:46+1Почему? Можно спокойно делать css только или для одного файла
Поверхностно видно и из этого поста
Делаете папку с темой но не все файлы переписывает а только header.tpl и stylesheet
В header.tpl меняете только путь к stylesheet
Всё
Не знаю что вы там чудили еще
В контроллерах стоит же проверка есть ли файл в папке кастомной темы если нет брать с default
Надо изменить какой то шаблон в своей теме — берете только нужный файл
Какие проблемы то :)Alexufo
19.01.2017 16:12Мне нужна тема которую я сам хочу. Никакие другие папки и шаблоны не нужны. В теме 170 файлов вьюх Это для кого?)
Мне нужно пара другая шаблонов куда я хочу прикрутить компоненты типа корзин, каталога, правки профиля с адресом, и еще несколько форм. А ОС не позволяет ни менять название шаблонов ни удалять их, я уж молчу про соблюдение папочной структуры и бесконечного прыгания по ним в поисках нужного места в шаблоне. Там профиль юзера выводится разными вьюхами в разных местах.
Либо переписывай все ядро, либо вся кастомизация это правка цветов в css. Меня это не устраивает. Меня темизация в wordpress устраивает.
Мне не нужно ни сравнение товара, ни страница производителей, тьма каких то шаблонов оплаты которой нет. я хочу сделать чистый шаблон который меня устраивает а не архитектуру движка. В OC с этим плохо. Поэтому все темы выглядят 1 к 1 — так дешевле.oxidmod
19.01.2017 16:21может дело в том, что ОС не CMS, в отличии от WP?
Alexufo
19.01.2017 16:25а что же тогда, если она контент менеджмент товаров позволяет делать?
По сути то одна фигня, сущность — товар или запись.Ввод и вывод. А дальше куча возможных сортировок, группировок, фильтров на отображении.
maxic
19.01.2017 17:27:) А что это? Ой… как с "вами" тяжело (у одного квалификации ноль в opencart — уже раздает "советы" и строит "мнения", второй просто "умник", теритий не читает мат. часть, но зато все "вопят")
Вы вообще знаете что такое CMS?
"система управления содержимым" — понимаете?
opencart — управляет содержимым.
Это CMS
PHP e-commerce CMS
maxic
19.01.2017 17:20Я же написал как, в чем проблема то
Новая тема — переписываете туда только файлы которые изменяете — всё
Вы понимаете суть унификации и стандартизации? Я вижу что нет, как и 99.99% здесь. Я как то статью писал здесь — " Мы плюём на стандарты" — 99% ответов было "а зачем они надо" и куча малолеток нах… ла минусов
Если вы хотите вообще сделать поля шаблонов для контроллеров — не вопрос. Есть куча модулей бесплатных которые это делают. Но это костыльно и НЕ правильно. И они не нужны (можно даже посмотреть по количеству скачиваний их
Alexufo
19.01.2017 19:29О какой унификации речь)))))))))))), если 99% тем для опенкарта это "замаскируй под современный магазин OC c помощью css"?
Хочешь перенести поиск в футер? лезть в контроллер, назначай вывод туда!
И так абсолютно с каждым выводом.
А теперь вспомни что и контроллер это тоже 170 файлов в 9 папках!
Итого: для кастомизации темы нужно работать минимум с 300 файлов раскиданных в 18 папках!
Показатель гибкости — это обьем тем, по которым не ясно, что за движок. В случае ОС это определяется сразу. Как таковых тем по ОС нет и не было, есть костыли над теми же 170 файлами в 9 папках.
Меня не устраивает ни привязка к папкам, ни огромное количество копипаста, ни разделение шаблонов. Про отсутствие ЧПУ я даже не говорю. Я знаю что значит делать темы для OC и пресса. И последний даже рядом по гибкости ставить не хочеться.
Можно назвать это унификацией, стандартизацией, дилетанством. Да. Только это не снимает абсолютно никаких вопросов.maxic
19.01.2017 19:55-1:)
Смешно — хочешь перенести поиск вниз — не надо ничего править. Кто вас такому "учил"?
Сразу видно — не специалист
Далее даже не хочется и читать ваши "потуги" чего то "понять"Alexufo
20.01.2017 14:56не хочется, потому что священная корова.
По факту именно так и есть: перенос вывода (поиск я не про голую html форму имел ввиду) между вьюхами без правки контроллера не обходится. Такое поведение еще поискать нужно.
Fortop
18.01.2017 14:20+1Тут вот выше посоветовали…
Глянул…
https://github.com/opencart/opencart/blob/master/upload/catalog/controller/product/product.php#L229
пример кода из опенкарт$data['text_select'] = $this->language->get('text_select'); $data['text_manufacturer'] = $this->language->get('text_manufacturer'); $data['text_model'] = $this->language->get('text_model'); $data['text_reward'] = $this->language->get('text_reward'); $data['text_points'] = $this->language->get('text_points'); $data['text_stock'] = $this->language->get('text_stock'); $data['text_discount'] = $this->language->get('text_discount'); $data['text_tax'] = $this->language->get('text_tax'); $data['text_option'] = $this->language->get('text_option'); $data['text_minimum'] = sprintf($this->language->get('text_minimum'), $product_info['minimum']); $data['text_write'] = $this->language->get('text_write'); $data['text_login'] = sprintf($this->language->get('text_login'), $this->url->link('account/login', '', true), $this->url->link('account/register', '', true)); $data['text_note'] = $this->language->get('text_note'); $data['text_tags'] = $this->language->get('text_tags'); $data['text_related'] = $this->language->get('text_related'); $data['text_payment_recurring'] = $this->language->get('text_payment_recurring'); $data['text_loading'] = $this->language->get('text_loading'); $data['entry_qty'] = $this->language->get('entry_qty'); $data['entry_name'] = $this->language->get('entry_name'); $data['entry_review'] = $this->language->get('entry_review'); $data['entry_rating'] = $this->language->get('entry_rating'); $data['entry_good'] = $this->language->get('entry_good'); $data['entry_bad'] = $this->language->get('entry_bad'); $data['button_cart'] = $this->language->get('button_cart'); $data['button_wishlist'] = $this->language->get('button_wishlist'); $data['button_compare'] = $this->language->get('button_compare'); $data['button_upload'] = $this->language->get('button_upload'); $data['button_continue'] = $this->language->get('button_continue'); $this->load->model('catalog/review'); $data['tab_description'] = $this->language->get('tab_description'); $data['tab_attribute'] = $this->language->get('tab_attribute'); $data['tab_review'] = sprintf($this->language->get('tab_review'), $product_info['reviews']); $data['product_id'] = (int)$this->request->get['product_id']; $data['manufacturer'] = $product_info['manufacturer']; $data['manufacturers'] = $this->url->link('product/manufacturer/info', 'manufacturer_id=' . $product_info['manufacturer_id']); $data['model'] = $product_info['model']; $data['reward'] = $product_info['reward']; $data['points'] = $product_info['points']; $data['description'] = html_entity_decode($product_info['description'], ENT_QUOTES, 'UTF-8');
maxic
18.01.2017 15:31-2:) Вот я так и знал про этот вопрос
Да по "детству" его часто задают — но там все продумано и сделано согласно стадартов
Если сами ответите поставлю пятерку
Что здесь не понятного "почему"?
Детский вопрос.
Даю наводку — "мухи отдельно — котлеты отдельно", "безопасность" (это же e-commerce решение, а не солянка обьявления обьектов в шаблонах и таскания обьектов по шаблонам ;) )), "парадигма MVC" и т пFortop
18.01.2017 15:34+1Подождите мальчик…
Вопрос был об архитектуре, котлетах и мухах.
То, что я вижу в коде, это помойка в одном месте.
О DataMapper нет, не слышали?
И как приведенный код улучшает «безопасность»?maxic
18.01.2017 15:43-1То что и услышал в ответ — вы кодер а не архитектор и не понимаете стандартов архитектур
Даже не понимаете элементарный код из архитектуры и почему он такой
Ну да все привыкли таскать и вызывать обьекты в шаблонах, плюя при этом на стандарты
Еще раз даю наводку — в шаблонах не должна быть логика взаимодействия с обьектами, только с выводом массива данных. Ресурсы должны быть разделены. Шаблон — это "конечная" View — там уже никакого взаимодействия обьектов быть не должно (оно во View должно быть, а не в шаблонах). "безопасность" если таскать обьекты по всему коду mvc — могут быть проблемы утечек памяти, переполнение памяти и связанных с этим проблем и атак. Четкое разделение ресурсов снижает вероятность такой атаки. Своего рода "песочницы" если примитивно обьяснятьсяFortop
18.01.2017 15:46Ещё раз для двоечников…
Что вы слышали о маппинге?
Как этот конкретный код улучшает безопасность?
Fortop
18.01.2017 16:30+1И так, как говорят братья беларусы — панеслася
Разбираем этот кусок кода частично
$this->document->addScript('catalog/view/javascript/jquery/magnific/jquery.magnific-popup.min.js'); $this->document->addStyle('catalog/view/javascript/jquery/magnific/magnific-popup.css'); $this->document->addScript('catalog/view/javascript/jquery/datetimepicker/moment.js'); $this->document->addScript('catalog/view/javascript/jquery/datetimepicker/bootstrap-datetimepicker.min.js'); $this->document->addStyle('catalog/view/javascript/jquery/datetimepicker/bootstrap-datetimepicker.min.css');
А если я хочу подменить шаблон и использовать другой? Мне копипастить весь action контроллера?
Скрипты, связанные с шаблоном, обязаны быть связаны только с ним, а не с action контроллера
А если я захочу выводить не html, а отдавать json? Опять копипаст?
Маппинг данных для шаблона$data['heading_title'] = $product_info['name']; $data['text_select'] = $this->language->get('text_select'); $data['text_manufacturer'] = $this->language->get('text_manufacturer'); $data['text_model'] = $this->language->get('text_model'); $data['text_reward'] = $this->language->get('text_reward'); $data['text_points'] = $this->language->get('text_points'); $data['text_stock'] = $this->language->get('text_stock'); $data['text_discount'] = $this->language->get('text_discount'); $data['text_tax'] = $this->language->get('text_tax'); $data['text_option'] = $this->language->get('text_option'); $data['text_minimum'] = sprintf($this->language->get('text_minimum'), $product_info['minimum']); $data['text_write'] = $this->language->get('text_write'); $data['text_login'] = sprintf($this->language->get('text_login'), $this->url->link('account/login', '', true), $this->url->link('account/register', '', true)); $data['text_note'] = $this->language->get('text_note'); $data['text_tags'] = $this->language->get('text_tags'); $data['text_related'] = $this->language->get('text_related'); $data['text_payment_recurring'] = $this->language->get('text_payment_recurring'); $data['text_loading'] = $this->language->get('text_loading'); $data['entry_qty'] = $this->language->get('entry_qty'); $data['entry_name'] = $this->language->get('entry_name'); $data['entry_review'] = $this->language->get('entry_review'); $data['entry_rating'] = $this->language->get('entry_rating'); $data['entry_good'] = $this->language->get('entry_good'); $data['entry_bad'] = $this->language->get('entry_bad'); $data['button_cart'] = $this->language->get('button_cart'); $data['button_wishlist'] = $this->language->get('button_wishlist'); $data['button_compare'] = $this->language->get('button_compare'); $data['button_upload'] = $this->language->get('button_upload'); $data['button_continue'] = $this->language->get('button_continue'); $this->load->model('catalog/review'); $data['tab_description'] = $this->language->get('tab_description'); $data['tab_attribute'] = $this->language->get('tab_attribute'); $data['tab_review'] = sprintf($this->language->get('tab_review'), $product_info['reviews']); $data['product_id'] = (int)$this->request->get['product_id']; $data['manufacturer'] = $product_info['manufacturer']; $data['manufacturers'] = $this->url->link('product/manufacturer/info', 'manufacturer_id=' . $product_info['manufacturer_id']); $data['model'] = $product_info['model']; $data['reward'] = $product_info['reward']; $data['points'] = $product_info['points']; $data['description'] = html_entity_decode($product_info['description'], ENT_QUOTES, 'UTF-8');
maxic
18.01.2017 16:44-2Бред. Набирайтесь опыта и поработайте с opencart
Вы неосознанный бред несете
Даже без комментариев, это просто смешно и по детскиFortop
18.01.2017 16:57+1Естественно.
Потому что всего вашего образования — два класса и коридор.
Если я начну 5-тилетним задвигать теорию суперструн для них это тоже будет выглядеть бредом, как и для вас.
А какие громкие слова об архитектуре… :D
maxic
18.01.2017 16:11Я вам не мальчик далеко а в отцы гожусь скорее всего
У меня сыну наверно больше чем вам
Не надо панибратства, я с вами не "пил"
Одно дело выявлять ламеров, которые "кричат" соврешнно при этом не знакомые с продуктом и не могут анализировать и тем более делать "выводы", а другое личное оскорблениеFortop
18.01.2017 16:44+2Сыну больше чем мне? :D
Да вы у нас скорострел… Как я погляжу…
И ламер наблюдается пока один — это конкретно вы.
Основная ваша проблема в том, что знаний у вас близко к нулю.
Рассуждать о безопасности с таким кодом…
// это вызов в контроллере $category_info = $this->model_catalog_category->getCategory($path_id); // а это сам метод... public function getCategory($category_id) { $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "category c LEFT JOIN " . DB_PREFIX . "category_description cd ON (c.category_id = cd.category_id) LEFT JOIN " . DB_PREFIX . "category_to_store c2s ON (c.category_id = c2s.category_id) WHERE c.category_id = '" . (int)$category_id . "' AND cd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND c2s.store_id = '" . (int)$this->config->get('config_store_id') . "' AND c.status = '1'"); return $query->row; }
Ну, наверное, конечно можно… местами…
Но я бы не стал
Реализация opencart имеет право на жизнь как коробочное нерасширяемое приложение для конечного пользователя.
Когда вся кастомизация заключается в смене «шкурки».
Вопрос «безопасности» очень сильно открыт…
Вопрос расширяемости… увольте.
maxic
18.01.2017 17:17-7Рот закрой хорошо "обученный" идиот
Собрались два тролля с нулем мозгов и шаловливыми руками говнокодингаAlexufo
19.01.2017 19:33+1не можешь атаковать мысль, атакуй мыслителя ©
maxic
19.01.2017 20:02Начнем с того что этот дебил, подъехавший на "блатной" козе, первым перешел на личные оскорбления (посмотрите исходный пост чей он)
Вот и получил ответ адекватный
И в табло бы за такое получил
Все предельно просто.
То что он нес бред — это и так видно
Я тоже с 20 летним опытом работы в web разработке когда родился opencart тоже так "подьезжал" к Даниэлю (разработчику opencart) с детскими (это я уже вижу по прошествии времени) вопросами в таком же стиле как ваши или того "гражданина". Но после многих лет работы с opencart — v понял насколько гениально простое это архитектурное решения а самое главное очень функциональное и гибкое
Fortop
20.01.2017 07:30Что вы мелете? Какие 20 лет разработки?
Два класса и коридор.
Вы Кнута и Фаулера хотя бы держали?
maxic
20.01.2017 10:41-1Тебя еще на ху@ не посылали — там 3.14й туда
"Я ругаюсь матом потому что мне жаль своего драгоценного времени на демагогию с хорошо обученными идиотами" © Мой
oxidmod
18.01.2017 16:01+1Open Cart — это труевый MVC. Но к тому же дубовый и простой как доска. Потому оно и так))
maxic
18.01.2017 16:16Совершенно верно — все гениальное просто
opencart архитектура простая как "доска", но при этом очень стандартная, функциональная, гибкая, унифицированная и безопасная
Поэтому и популярная среди разработчиков и пользователей
MetaDone
17.01.2017 22:54мельком посмотрел и не увидел никакого контейнера зависимостей. что-нибудь подобное используется? и почему вместо твига решили «откатиться» к php-шаблонам?
zenn
17.01.2017 23:03Что вы имеете в виду под «контейнером зависимостей», применение паттерна DI? Он используется, достаточно редко для передачи в конструкторы моделей определенных объектов, которые наследуют интерфейс или базовый класс. Твиг достаточно удобен, но по сравнению с «голым» php различие в синтаксисе не велико (за исключением плюшек типа extend) а местами синтаксис выглядит неявным (к примеру сравнения, к этому синтаксису я привыкал достаточно долго).
MetaDone
17.01.2017 23:13Что вы имеете в виду под «контейнером зависимостей», применение паттерна DI?
да, это и имеется в виду. я обычно для мелких домашних проектов, которые собираю из разных пакетов, использую https://github.com/auraphp/Aura.Di — простой, легкий и удобный, а еще не тянет кучу всего за собой
еще вопрос — а как экранируете вывод в шаблонах? например тут
с твигом по этому поводу париться бы не пришлось, да и вот такого тоже не было быzenn
17.01.2017 23:32Возможно, конечно от «прослоек совместимости» в качестве «потомков» под крупные пакеты стоит применить нечто универсальное, пока не сильно задумывался над этим (но по мере роста объема кода это, возможно, будет неизбежным).
По твигу — действительно, ескейп решается |e насколько помню, но от назначения переменных и операций с ними вряд ли бы спасло (phpdoc там сделан для автокомплита). По поводу эскейпа — в большинстве случаев при отображении используются атрибуты моделей, которые завернуты в html purifier в зависимости от определенных types() входящих пользовательских данных (если для атрибута не указан принудительный тип[text|html|!secure], он автоматом упадет в очистку).
Hazrat
17.01.2017 22:56-3Мне кажется тратить силы на разработку еще одной CMS на PHP это как минимум не перспективно. Откуда энтузиазм? было бы интересно что-нибудь на NodeJS, например.
zenn
17.01.2017 23:05Ну почему же, возможно конкуренция среди Node проектов и ниже, но как минимум я использую cms для ряда своих и не только проектов, хотя сказать что поддержка собственного кода дается легче, чем код популярного фреймворка не могу.
Alexufo
18.01.2017 04:00+2да конечно нода! Ага! Для кого она? На пыхе просто без вариантов, если цель — большая аудитория. Семерка вышла, все, стесняться больше нечего.
oxidmod
18.01.2017 00:19почему же всеже не на базе фреймворка?
зы. я знаю, что компосер лучший фреймворк, но всеже (тем более что половину компонент вытянули из симфони, так почему не симфони?)
zenn
18.01.2017 08:12Я не раз рассматривал такой вариант, в том числе symfony, но мне показалось что для целей CMS у него слишком избыточная система роутинга, а сам фреймворк излишне использует паттерн DI. Нет, конечно я не говорю о том, что это плохо — symfony пожалуй один из самых качественных по уровню близости кода к java фреймворк, но для моих целей он показался слишком тяжелым. На symfony, кстати, есть достаточно неплохая cms — livestreet и в ней как раз таки можно заметить сложности разработки простых расширений, вызванные использованием symfony в качестве основы.
oxidmod
18.01.2017 11:28ну сложность архитектуры не от симфони зависит. это лишь клей, который связывает воедино независимые компоненты, половину из которых вы и так используете.
OnYourLips
18.01.2017 01:08-4Очень хорошая дипломная работа. Однозначно на пятёрку тянет.
Но не формат хабра.zenn
18.01.2017 08:14+3С чего вы взяли что это дипломная работа? Это вполне рабочая система, которая уже используется на моих личных проектах и надеюсь заинтересует других людей.
Как вы определяете, что является форматом habrahabr? Или я ошибся с тегами публикации и она ни коем образом не относится к php, cms и ооп?
xRay
19.01.2017 09:16А роутинг на чем построен? К примеру для кастомных ЧПУ-ссылок.
zenn
19.01.2017 09:22Роутинг реализован простейшим образом — каждый корневой URI (к примеру, /demo/) будет автоматически адресован контроллеру \Apps\Controller\Front\Demo. Если вас не устраивает такое дело событий — без особых усилий можно назначить как статический алиас, так и динамический каллбэк. Более подробно — тут и тут
artygrand
25.01.2017 10:59Получается, чтобы у новостей был адрес /news/ffcms3-announce а не /content/read/news/ffcms3-announce нужно для каждой новости прописывать роут?
zenn
25.01.2017 11:01Да, это «узкое» место текеущего роутера, в этом случае не поможет динамический callback, а статические маршруты придется добавлять для всех адресов. Возможно в будущих релизах я пересмотрю роутер в сторону расширения до нужного вам функционала ('/news/*' => '/content/read/news/*')
maxic
"Современненько", но слишком усложнено
Не "есть хорошо" во View делать вот такие вызовы
$data = (new EntityCommentData($comment, false))->make();
Во View (шаблона фактически) лучше отправлять уже "рассчитанные" данные контроллером
Т е архитектура все равно с "костылями"
zenn
Спасибо что заметили, да, использовать во view инициацию модели, пусть она и является «сущностью» не есть хороший тон, видимо данный код избежал рефакторинга и был мной упущен (проверил «вьюхи» — на самом деле, это единичный случай и он будет исправлен).
Данный участок кода будет переработан, везде модели инициируются и выполняют все необходимые действия в рамках контроллера.
maxic
Я бы еще советовал сделать переносимый контроллерами registry обьектов
Чтобы не было вот такого: Str::likeEmpty($tagName)
Тогда будет $this->registry->str->likeEmpty($tagName)
Как то архитектура будет более унифицирована
И тогда не надо будет делать в контролерах new… (new там тоже как то коряво выглядит)
Короче есть еще над чем подумать вам