CS Cart или через терни к черной дыре костылей и оптимизаций

от автора

Совсем недавно, я стал разработчиком модулей для CS Cart. Случилось это по воле случая: меня взяли на работу в Петербургскую сеть интернет магазинов, торгующих вейпами и всякими интересными штуками для удовлетворения потребностей физического характера страждущих пар и одиночек (кто не понял — еще не дорос ). Оба интернет магазина развернуты на двух витринах с разными доменами, но одной админкой и общей базой данных. Что же с ней не так? Думаю о CMS написано много, но я добавлю свою ложку дегтя в бочку с дегтем .

Путешествие в модуль через лес директорий

В процессе разработки первого модуля для этой платформы, я столкнулся со множеством проблем, которых, как я полагал, имея опыт работы с ООП, а также с CMS MODX Revo, быть не должно. Первое, что бросилось в глаза — это очень сложная и запутанная структура модуля:

root/ ├─ app/ │  └ addons/                                     <- Модули и расширения │    └ [id_модуля]/                              <- Папка модуля │       ├─ controllers/                          <- Расширение контроллеров │       │  ├─ backend/                           <- Панель администратора │       │  │  ├─ [ваш_контроллер].php            <- Новый контроллер │       │  │  ├─ [контроллер].pre.php            <- Расширение перед контроллером │       │  │  └─ [контроллер].post.php           <- Расширение после контроллером │       │  ├─ common/                            <- Общие контроллеры │       │  │  ├─ [ваш_контроллер].php │       │  │  ├─ [контроллер].pre.php │       │  │  └─ [контроллер].post.php │       │  └─ frontend/                          <- Контроллеры витрины │       │     ├─ [ваш_контроллер].php │       │     ├─ [контроллер].pre.php │       │     └─ [контроллер].post.php │       ├─ database/                             <- MySQL файлы │       ├─ schemas/                              <- Расширение PHP схем │       │  └─ [папка_схем]/                      <- Папка схемы (тип схемы) │       │     └─ [название_схемы].post.php       <- Расширение после схемы │       ├─ Tygh/                                 <- Классы │       │  ├─ Shippings/                         <- Доставки │       │  │  └─ Services/                       <- Службы доставки │       │  │     └─ [СлужбаДоставки].php         <- Ваша служба доставки │       │  └─ [ВашКласс].php                     <- Любой новый класс │       ├─ addon.xml                             <- Главный файл модуля │       ├─ config.php                            <- Константы │       ├─ func.php                              <- Функции и расширения хуков │       └─ init.php                              <- Подключение хуков ├─ design/ │  ├ backend/                                    <- Шаблоны панели администратора │  │ ├ css/                                      <- Стили панели администратора │  │ │ └ addons/ │  │ │   └ [id_модуля]/                          <- Ваш модуль │  │ │     ├ styles.css                          <- Ваши стили │  │ │     └ styles.less │  │ ├ mail/                                     <- Email и шаблоны счетов │  │ │ └ templates/ │  │ │   └ addons/                               <- Модули и аддоны │  │ │     └ [id_модуля]/                        <- Папка модуля │  │ │       ├ hooks/                            <- Подключение к хукам │  │ │       │ └ [тип_хука]/                     <- Папка хука │  │ │       │   ├ [название_хука].pre.tpl       <- Код перед хуком │  │ │       │   ├ [название_хука].post.tpl      <- Код после хука │  │ │       │   └ [название_хука].override.tpl  <- Переписать хук │  │ │       ├ [шаблон_письма]_subj.tpl/ │  │ │       └ [шаблон_письма].tpl/ │  │ ├ media/                                    <- Статические данные │  │ │ └ images/ │  │ │   └ addons/ │  │ │     └ [id_модуля]/                        <- Изображения вашего модуля │  │ │       ├ изображение_1.jpg/ │  │ │       └ изображение_2.png/ │  │ └ templates/                                <- Шаблоны │  │   └ addons/ │  │     └ [id_модуля]/ │  │       ├ hooks/                              <- Подключение к хукам │  │       │ ├ index/                            <- Папка хука │  │       │ │ ├ scripts.post.tpl                <- Хук подключения вашего скрипта │  │       │ │ └ styles.post.tpl                 <- Хук подключения вашего стиля │  │       │ └ [тип_хука]/ │  │       │   ├ [название_хука].pre.tpl         <- Ваш код перед хуком │  │       │   ├ [название_хука].post.tpl        <- Ваш код после хука │  │       │   └ [название_хука].override.tpl    <- Ваш код перепишет хук │  │       ├ views/                              <- Собственная страница │  │       │ └ [ваш_контроллер]/                 <- Контроллер │  │       │   └ [режим_контроллера].tpl         <- Режим (mode) контроллера │  │       └ overrides/                          <- Переписать любой шаблон │  │         └ ...                               <- Создайте нужную структуру │  │ │  └ themes/                                     <- Дизайн витрины — темы │    └ [название_темы]/                          <- Название темы │      ├ css/                                    <- Стили │      │ └ addons/ │      │   └ [id_модуля]/ │      │     ├ styles.css                        <- Ваш стиль CSS │      │     └ styles.less                       <- Ваш стиль LESS │      ├ mail/                                   <- Шаблоны писем и счетов │      │ └ templates/ │      │   └ addons/ │      │     └ [id_модуля]/ │      │       ├ hooks/                          <- Раширение через хуки │      │       │ └ [тип_хука]/ │      │       │   ├ [название_хука].pre.tpl │      │       │   ├ [название_хука].post.tpl │      │       │   └ [название_хука].override.tpl │      │       ├ [шаблон_письма]_subj.tpl/       <- Шаблон темы письма │      │       └ [шаблон_письма].tpl/            <- Шаблон письма │      ├ media/                                  <- Статические данные │      │ └ images/ │      │   └ addons/                             <- Изображения модуля │      │     └ [id_модуля]/ │      │       ├ изображение_1.jpg/ │      │       └ изображение_2.png/ │      └ templates/                              <- Шаблоны │        └ addons/ │          └ [id_модуля]/                        <- Ваш модуль │            ├ hooks/                            <- Расширение хуков │            │ ├ index/                          <- Папка хука │            │ │ ├ scripts.post.tpl              <- Хук подключения вашего скрипта │            │ │ └ styles.post.tpl               <- Хук подключения вашего стиля │            │ └ [тип_хука]/                     <- Папка хука │            │   ├ [название_хука].pre.tpl       <- Ваш код перед хуком │            │   ├ [название_хука].post.tpl      <- Ваш код после хука │            │   └ [название_хука].override.tpl  <- Перезаписать хук целиком │            ├ views/                            <- Новая страница │            │ └ [ваш_контроллер]/               <- Папка вашего контроллера │            │   └ [режим_контроллера].tpl       <- Шаблон для режима контроллера │            └ overrides/                        <- Переписать любой шаблон темы │              └ ...                             <- Файл который нужно переписать │ ├ js/                                            <- Скрипты модуля │ └ addons/ │   └ [id_модуля]/ │     └ func.js/ └ var/                                           <- Хранилище шаблонов модуля   └ themes_repository/                           <- Используется при установке     └ [название_темы]/       └ ...

Может показаться, что модуль имеет логичную иерархию внутри своей структуры, но, иногда, следуя по документации, случаются баги, которые не должны были появиться. Например: был у меня кейс, когда обращаясь к контроллеру через AJAX функцию, встроенную в класс CMS JS упорно не хотела работать с моим контроллером, хотя сделано всё было четко по документации. Поискав информацию и обратившись к комьюнити, состоящем, в основном из 3-4 активных завсегдатаев-разработчиков, я понял, что даже сами разработчики этой платформы не могут ответить на вопрос о том, почему их функция ведет себя некорректно.

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

То что мертво — труп, но потыкать палкой нужно

Второй задачей, которую поставило руководство, являлась оптимизация сайтов этого магазина. Я взялся за нее без энтузиазма, понимая, что это мертворожденное существо, и мы с коллегой путем мучений и отключения всего того зоопарка модулей, что были установлены до моего появления со словами: «А че бы нет?!» — добились улучшенных показателей Google и в LightHouse, но прироста, в 20 единиц на одном сайте и 10 на другом, было не достаточно. Тогда я полез смотреть БД более детально. Поняв, что БД у данной CMS — набор несвязанных друг с другом таблиц, я понял, что все взаимодействия с базой и связки данных проходят через PHP, что, как я считаю, неправильно. Почему сделано именно так? — всё просто: CMS создавалась в 2003-2004 годах, и в качестве движка для СУБД использовался MyISAM.

MyISAM — сам по себе, довольно медленный движок и он не рассчитан на 50 000 (!) товаров (о количестве поговорим позже). Более того связывание таблиц этом движке реализовано не так хорошо как, скажем, в том же InnoDB. Из-за этого сервер начинает очень страдать при одновременном обращении 500 — 1000 пользователей.

Теперь поговорим о количестве товаров. Откуда 50 000 спросите вы? «Потому что» — отвечу я. Дело в том, что одну из витрин отдали на SEO какому то подозрительному фрилансеру из Беларуси. Странность его суждений заключается в разнообразных уловках и ухищрениях. Например: для улучшения видимости сайта он просил коллегу создать несуществующую номенклатуру и каждый день подгружать несуществующий товар. Аргументировал он это тем, что пользователи будут искать товары из этого несуществующего списка и попадать к нам на сайт, на этот товар. Понятно, что пользователь уйдет сразу же после этого, так как товара в наличии нет и никогда не было и не будет. Сайт ни капельки не продвигается, а руководство с упорством продолжает считать мнение данного «спеца» авторитетней мнения штатного программиста и контент-менеджера.

Такое количество номенклатуры — аномально и это, в свою очередь, также подвергает оба сайта зависаниям, лагам и другим неприятным вещам.

Нужна скрепка? Плати 100 баксов

Последняя проблема, которую я освещу в данной статье — это плата за любое мелкое допиливание этого «зомби». Хочешь стандартный функционал cron в панеле админа — плати. Подключить метрику не через утиную гуску, а так, чтобы она не нагружала клиент — плати. И другие малозначимые, но иногда важные изменения — стоят денег. Ценник, как правило, начинается от 100$ за модуль. Да, разработчикам, как и мне, хочется кушац, но у меня сложилось впечатление, что CMS и её стандартные модули специально не доведены до нормального состояния. А так как структуру всех классов и методов знают только создатели данной CMS, то они и являются, по сути, монополистами на рынке, так как любой фрилансер или штатный проггер, не сможет нормально сделать модуль с первого раза, используя недописанную и костыльную документацию, что предлагается на данный момент.

Заключение

Я не верю, что ситуация с данной CMS когда нибудь изменится и мне, действительно, жаль тех, кто имея огромную номенклатурную базу сидит на ней и платит за все доделки баснословные деньги. Но хочется верить, что, хотя бы в моем магазине, я сумею побороть некоторые её недостатки.

Надеюсь, статья Вам была интересна. Я буду писать еще о своих изысканиях в этой CMS или о разработке модулей для неё.

ссылка на оригинал статьи https://habr.com/ru/post/558778/