Pull to refresh

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

Reading time6 min
Views9.5K

Совсем недавно, я стал разработчиком модулей для 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 или о разработке модулей для неё.

Tags:
Hubs:
Total votes 9: ↑8 and ↓1+7
Comments24

Articles