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

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

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

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

Может показаться, что модуль имеет логичную иерархию внутри своей структуры, но, иногда, следуя по документации, случаются баги, которые не должны были появиться. Например: был у меня кейс, когда обращаясь к контроллеру через 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 или о разработке модулей для неё.