MiniShop3 - новости
Привет мальчики и девочки. Давно не виделись Я к вам с замечательными новостями.
Спустя страшно представить целый год я вернулся к разработке MiniShop3 и у меня есть, что вам рассказать.
Для начала позвольте извиниться и попросить прощения за такой долгий перерыв. Год назад у меня родился ребенок, и это событие забрало у меня множество времени, которое я мог бы потратить на разработку. Время идет, мы наладили быт, и у меня получилось найти время и, самое главное, силы для возвращения к активной работе на благо сообщества.
Кроме того, за прошедшее время я сильно вырос в квалификации, и четко понимал, что сделанная ранее работа меня не устраивала по множеству причин.
Вот выдержка моих мыслей из нашего телеграм-сообщества

Там в конце я упоминаю что с популяризацией ИИ-ассистентов работа становится сильно проще. Мой верный помощник Claude Code дал мне возможность нарастить темпы, быстрее выполнить мою основную работу и сообща мы вернулись к разработке MS3.
Вот что удалось сделать буквально за две недели.
Была полностью переосмыслена работа с таблицами базы данных.
Ранее, мы использовали резолверы для создания и обновления таблиц и это почти всегда приводило к неприятностям, по мере появления новых полей. Концепция резолвера таблиц была выброшена на свалку истории. Теперь все создается красивым, удобным способом, который многие могут знать по Laravel.
Миграции можно не только накатить, но и выполнить по мере необходимости быстрый откат к прежнему состоянию.
Также я отказался от старой системы разруливания запросов. Мы строим полноценное API. Да-да также как в прекрасном Laravel.
Теперь мы умеем в PUT и DELETE.
К сожалению, весь минишоп я перевести на роуты еще не успел. Это план на ближайшее время. Зато отлично подружил их с админкой.
Теперь запрос проходит следующий путь.
GET — получает из базы информацию.
POST — создает новые записи
DELETE — отвечает за удаление записей
PUT — занят обновлением записей.
Что здесь, собственно, улучшено. Раньше огромная часть работы ложилась на модели. К примеру, модель msProductData — почти 600 строк кода. Это так называемый «Божественный класс», который отвечает вообще за все. Он преобразовывал данные, проводил проверки, модерировал права, организовывал связи между таблицами. Короче делал тот объем работы, который не свойственен классу.
Сейчас мы разделили зоны ответственности. Сервис-контроллер занимается данными. Проверяет, обогащает, объединяет данные. Модель отвечает за связь с таблицами. Просто достает данные или записывает их в базу. Смысл модели только в связи с базой данных. У нее должна быть только такая ответственность.
На самом деле здесь работы непочатый край. Мне предстоит еще разобрать и преобразовать большой объем старого кода. Но для этого заложена крепкая база. Теперь не нужно ничего придумывать, просто бери и делай.
Ну и на закуску самое сладкое. В свое время @Наумов Алексей предложил и частично реализовал концепт, по которому мы могли добавлять новые поля прямо из админки. А я взялся за кастомизацию самой страницы товара.
Идея была в том, чтобы мы могли быстро при помощи визуального конструктора добавлять и скрывать из вида поля товара (и не только товара). Также хотели распределять их по странице, разбить страницу на секции, и перемещать поля выше-ниже в нужные секции. Наш любимый extJS не дал мне такой возможности. Вся эта задумка забирала колоссальное количество времени и сил, а результата не было. Это стало для меня провалом, и по большей части причиной остановить работу.
И вот спустя время я придумал концепт, а мой ассистент Claude Code помог мне это все быстро реализовать.
На данный момент идея уже реализована и я готов ее показать.
Вот так добавляем новое поле в базу.

Вот так выглядит перечень всех доступных полей

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

А здесь у нас управление секциями

Ну и самое интересное. Вот так выглядит обновленная вкладка свойства товара

Секции свойств можно отключать, менять местами. добавлять новые. Также их можно сворачивать для удобства.
Как мне кажется, стало намного удобнее и интереснее. Компонент msExtraFields можно отправлять на заслуженный отдых.
Все виджеты реализованы на Vue+ PrimeVue. Я планирую всю админку минишопа переписать на Vue, что даст возможность кастомизации, добавления новых возможностей, да просто привнесет свежесть.
Хочу поблагодарить друзей, которые меня поддерживали в этой работе, не давая забыть о моих обязательствах. @Евгений Webinmd @Наумов Алексей — без вас я бы не вернулся.
Также хочу поблагодарить modstore в лице @Илья Уткин
Мы обсудили некоторую финансовую стимуляцию, а также планы на создание экосистемы (поиск, фильтры, личный кабинет и прочие более мелкие компоненты).
Ну и если кто-то хочет поддержать работу рублем — то все наши реквизиты по прежнему доступны на специальной странице
Спустя страшно представить целый год я вернулся к разработке MiniShop3 и у меня есть, что вам рассказать.
Для начала позвольте извиниться и попросить прощения за такой долгий перерыв. Год назад у меня родился ребенок, и это событие забрало у меня множество времени, которое я мог бы потратить на разработку. Время идет, мы наладили быт, и у меня получилось найти время и, самое главное, силы для возвращения к активной работе на благо сообщества.
Кроме того, за прошедшее время я сильно вырос в квалификации, и четко понимал, что сделанная ранее работа меня не устраивала по множеству причин.
Вот выдержка моих мыслей из нашего телеграм-сообщества

Там в конце я упоминаю что с популяризацией ИИ-ассистентов работа становится сильно проще. Мой верный помощник Claude Code дал мне возможность нарастить темпы, быстрее выполнить мою основную работу и сообща мы вернулись к разработке MS3.
Вот что удалось сделать буквально за две недели.
Миграции phinx.
Была полностью переосмыслена работа с таблицами базы данных.
Ранее, мы использовали резолверы для создания и обновления таблиц и это почти всегда приводило к неприятностям, по мере появления новых полей. Концепция резолвера таблиц была выброшена на свалку истории. Теперь все создается красивым, удобным способом, который многие могут знать по Laravel.
Миграции можно не только накатить, но и выполнить по мере необходимости быстрый откат к прежнему состоянию.
Роуты Fast route и сервисы.
Также я отказался от старой системы разруливания запросов. Мы строим полноценное API. Да-да также как в прекрасном Laravel.
Теперь мы умеем в PUT и DELETE.
К сожалению, весь минишоп я перевести на роуты еще не успел. Это план на ближайшее время. Зато отлично подружил их с админкой.
Теперь запрос проходит следующий путь.
GET — получает из базы информацию.
POST — создает новые записи
DELETE — отвечает за удаление записей
PUT — занят обновлением записей.
- Все запросы по-прежнему разруливает единый connector.php
- Каждый запрос содержит вызываемый роут и направляется к одному базовому процессору API/Route
- Центральный процессор API уже вызывает нужный роут, а тот в свою очередь вызывает Service. Да, тоже как в Laravel.
Что здесь, собственно, улучшено. Раньше огромная часть работы ложилась на модели. К примеру, модель msProductData — почти 600 строк кода. Это так называемый «Божественный класс», который отвечает вообще за все. Он преобразовывал данные, проводил проверки, модерировал права, организовывал связи между таблицами. Короче делал тот объем работы, который не свойственен классу.
Сейчас мы разделили зоны ответственности. Сервис-контроллер занимается данными. Проверяет, обогащает, объединяет данные. Модель отвечает за связь с таблицами. Просто достает данные или записывает их в базу. Смысл модели только в связи с базой данных. У нее должна быть только такая ответственность.
На самом деле здесь работы непочатый край. Мне предстоит еще разобрать и преобразовать большой объем старого кода. Но для этого заложена крепкая база. Теперь не нужно ничего придумывать, просто бери и делай.
Конструктор полей
Ну и на закуску самое сладкое. В свое время @Наумов Алексей предложил и частично реализовал концепт, по которому мы могли добавлять новые поля прямо из админки. А я взялся за кастомизацию самой страницы товара.
Идея была в том, чтобы мы могли быстро при помощи визуального конструктора добавлять и скрывать из вида поля товара (и не только товара). Также хотели распределять их по странице, разбить страницу на секции, и перемещать поля выше-ниже в нужные секции. Наш любимый extJS не дал мне такой возможности. Вся эта задумка забирала колоссальное количество времени и сил, а результата не было. Это стало для меня провалом, и по большей части причиной остановить работу.
И вот спустя время я придумал концепт, а мой ассистент Claude Code помог мне это все быстро реализовать.
На данный момент идея уже реализована и я готов ее показать.
Вот так добавляем новое поле в базу.

Вот так выглядит перечень всех доступных полей

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

А здесь у нас управление секциями

Ну и самое интересное. Вот так выглядит обновленная вкладка свойства товара

Секции свойств можно отключать, менять местами. добавлять новые. Также их можно сворачивать для удобства.
Как мне кажется, стало намного удобнее и интереснее. Компонент msExtraFields можно отправлять на заслуженный отдых.
Все виджеты реализованы на Vue+ PrimeVue. Я планирую всю админку минишопа переписать на Vue, что даст возможность кастомизации, добавления новых возможностей, да просто привнесет свежесть.
Благодарности.
Хочу поблагодарить друзей, которые меня поддерживали в этой работе, не давая забыть о моих обязательствах. @Евгений Webinmd @Наумов Алексей — без вас я бы не вернулся.
Также хочу поблагодарить modstore в лице @Илья Уткин
Мы обсудили некоторую финансовую стимуляцию, а также планы на создание экосистемы (поиск, фильтры, личный кабинет и прочие более мелкие компоненты).
Ну и если кто-то хочет поддержать работу рублем — то все наши реквизиты по прежнему доступны на специальной странице
Комментарии: 36
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
1. Будет ли поддержка modx3?
2. Продукты будут в отдельной таблице?
3. Миграции phinx — а xpdo объекты будут работать? Миграция будет запускаться вручную или при обновлении компонента? Например, при создании поля, что будет происходить?
Если придираться, то:
Сервис — это бизнес-логика и обработка данных
Репозиторий — запросы к базе
Контроллер — запросы, ответы и валидация данных
То есть, контроллер вызывает сервис, сервис вызывает репозиторий, а он в свою очередь обращается к модели.
Так MS3 целиком предназначен для MODX3. Я не занимаюсь развитием платформы для MODX2.
Тут ничего не изменилось. Поля товара как хранились в ms2_products так и хранятся.
А как ты их между собой связал? Это же разные сущности.
Если вопрос о том, как новые поля попадут в xpdo модель — то там наш старый привычный еще из ms2 способ, который на лету обновляет $meta['map']
Цепочка загрузки:
- 1. OnMODXInit → $ms3->loadMap()
- 2. MiniShop3::loadMap() → $this->extraFields->loadMap()
- 3. ExtraFields::loadMap() → загружает ms3_extra_fields (active=1)
- 4. ExtraFields::getFieldInfo() → формирует метаданные
- 5. ExtraFields::addFieldToMap() → МОДИФИЦИРУЕТ $modx->map[$class] ← ВОТ ГДЕ МАГИЯ!
- 6. xPDO видит новые поля как нативные
Тут я бы разделил ответ1. Репозиторий — это паттерн. Нет четких правил по его использованию или обязательств его использовать. Так что каждый волен делать так, как видит. Вот Laravel до пятой версии вообще всю логику внутри моделей тягал и ничего.
2. На практике, насколько я видел как пишут другие, сервис и репозиторий по сути своей одно и тоже. Их задача разгрузить контроллер, вынести логику в отдельный контейнер.
Я вижу так.
Контроллер принимает запрос от API и отдает ответ. На этом все. Его зона ответственности Request-Магия-Response.
Репозиторий и\или Service — логика. Здесь идет разбор запроса, обращения к DB, построение ответа. Задача сервиса — подготовить ответ согласно запроса.
Model — исключительно работа с базой. Ее задача сходит в базу и выполнить поставленную задачу.
Но, похоже, это не так. Тогда вопрос: а зачем нужен Phinx? При создании новых полей он не участвует, новые таблицы не создаёт. Миграции происходят только при обновлении компонента?
Допустим, в новой версии компонента добавлено новое поле — значит, нужно создавать новую миграцию и обновлять схему ещё раз?
Честно говоря, я не понимаю явного преимущества использования phinx в этом кейсе.
Может быть, просто потому что я с такими неприятностями не сталкивался.
Путь такой.
1. Заполняю модальное окно данными, жму сохранить
2. Контроллер создает миграцию (Alter table Add column) и сразу же ее запускает. Вот на этом моменте используется phinx
3. Делаем запись в таблицу extra_fields.
4. Ну и где то за кадром происходит слияние нативной карты модели msProductData и новых дополнительных полей.
Примерно такая же схема при удалении поля.
Жму кнопку удалить, создается миграция на удаление колонки из таблицы. Она запускается сразу же, после создания.
Почему схема такая, а не предложенный тобой вариант.
Ну для начала поля из extra_field можно отключать. Колонка физически остается в базе данных, но перестает попадать в карту msProductData. Это может быть полезным.
Кроме того физически перегенерированную карту msProductData обновление минишопа просто перезапишет. Можно конечно это разрулить на уровне резолверов, но зачем? Предложенная схема вроде справляется с задачей
Ты используешь phinx как контейнер, в котором вызываешь xPDO Manager. То есть, миграции выполняются через xPDO и поэтому phinx получается здесь немного избыточным.
Но это, конечно, просто мое мнение. Я сейчас тоже решаю использовать phinx в PageBlocks, ведь в 3 версии у меня в планах создавать динамично кастомные таблицы. Склоняюсь к тому, чтобы отказаться от xPDO и использовать свой конструктор запросов для работы с базой.
Еще через год-два надоест писать на xPDO, и захочется нормальный Eloquent.
А потом и установку\обновление перенести на Composer + запуск консольных скриптов через Symfony/Console, раз уже используется Phinx.
Давай, Николай! Может, ты заставишь сообщество MODX перейти на современные технологии! У меня с моей mmx-инициативой не взлетело, увы.
Коля увлекся реактом. Там на годы вперед есть чем заняться в плане прокачки скилов и повышения удовлетворения от работы. Коля уже даже с PHP не работает. Допускаю, что он поэтому хочет использовать питоновкий FastAPI в минишопе )
И claude code не особо поможет, если нет понимания дизайна приложения. Нужно иметь хотя бы базовое представление что такое сервисный слой, что такое инфраструктурный. Чем они отличаются. И что сервис никак не может быть репозиторием )
Я это не в обиду Коле. Просто он поставил себе очень высокую планку, которую сложно достичь в MODX без серъезного уровня квалификации, опыта и упорства. Но парадокс в том, что как только ты выходишь из мира фриланса и получаешь опыт работы в больших и серьезных проектах, то тебе уже не хочется возвращаться в MODX )))
Спасибо за ваше критическое замечание. Мы обязательно его рассмотрим в отведенные сроки.
Прошу заметить, что несмотря на архитектурно-инфраструктурные пробелы, приложение все равно становится лучше и современнее. Некоторые xpdo модели, за счет выноса логики в отдельный слой похудели в разы. А эту самую логику в отдельных слоях (как бы они не назывались) теперь можно подменять через DI
Но проблема в том, что минишоп нужен только в MODX. Отдельно он не взлетит. Уже есть готовые раскрученные решения и с ними конкуренцию выиграть невозможно. Плюс спрос на личные интернет магазины заметно упал, так как все перемещаются на торговые площадки (озон, вайлдберис, яндекс, сбермаркет и т.д.). Так что овчинка не стоит выделки ¯\_(ツ)_/¯
П.С.
Кстати, еще в прошлом году на хабре видел бенчмарки роутеров. И симфоневый был быстрее ;)
Смотря что считать овчинкой. Я взял на себя обязательства в свое время, и считаю делом чести их выполнить. Кроме того ребята поддержали дело донатами, и тем более должны увидеть результат. А уж использовать его, или нет — каждый сам для себя решит.
Не знаю, насколько это честно.
Мне тоже за доработку pdoTools обещали финансовую мотивацию. Я мог бы взять деньги, выкатить продукт и отвалить. Но я посчитал честным отказаться, хотя деньги предложили достойные. Я физически не вытяну доведение до ума новой версии. И не хочу, чтобы мне потом предъявили.
Возможно у тебя есть свои планы на минишоп3, но если нет, то это просто способ заработать денюжку с неясным результатом. Что-то мне подсказывает, что никто после тебя не полезет в него и не будет его развивать. Но это чисто моё видение ситуации. Буду раз, если ошибаюсь )
Если тебя не устраивает MODX — без проблем. Используй то, что считаешь нужным. Никто же не мешает. Но зачем приходить в гости в чужую ветку и критиковать буквально через слово? Да еще и критиковать без конструктива.
То, что мы используем не самые свежие технологии, или используем их как то не так — это наш выбор.
Админка реально древняя.
Начинаешь что-то писать — и сразу осознаёшь, какой адский путь предстоит пройти, чтобы сделать одну-единственную страницу со списком и управлением.
И всё это — как в старые добрые времена с процессорами и extJs.
Руки опускаются, интерес моментально пропадает. 😅
Я, имея опыт работы с разными CMS и фреймворками, могу более менее объективно оценить MODX. Это просто инструмент для небольших сайтов, блогов и интернет-магазинов. Даже при среднем всплеске посещаемости у нас в компании он падал. Пришлось сильно его оптимизировать, чтобы он вывозил 2 млн. посещений в месяц. Иногда костылить.
Но могу твердо сказать, что он лучше вордпресса и на 10 голов выше сраного битрикса. Но тем не менее, нахваливать его я не собираюсь. И это никакой не негатив. Просто здравая реальная оценка. Каждый инструмент хорош в чем-то одном.
Вообще, складывается ощущение, что вы все уже похоронили MODX. Ибо у вас про него нужно говорить или хорошо, или ничего. Как о сами знаете ком )
П.С. Было бы круто, если бы переписали админку на Vue. Не уверен, что это остановило бы падение популярности MODX. Но стало бы более удобно кастомизировать админскую часть.
Хотя как вариант можно админскую часть своего пакета сделать отдельно. Например, для минишопа свою админку запилить. Современную.
Ранее в modx 2.8.8 и ms2:
/core/components/minishop2/custom/cart/msсartcustomhandler.class.php
В ms3 вижу контроллер корзины:
/core/components/minishop3/src/Controllers/Cart/Cart.php
Ещё msPre потом надо будет обновить, и уйму всего переписать после обновления modx с 2.8.8 на 3.1.2
То же самое по идее и в MS3. Только тут уже нужно использовать namespace и use. Я подготовлю документацию в скором времени. Кроме того будет визуальная утилита подключения служб, вместо того чтобы в консоли команды запускать.
Можно пример с использованием namespace? Типа такой:
Разумеется сразу после addPackage
И ещё смотрю системные настройки там, где обработчик Класс обработчик корзины ms3_cart_handler_class
msCartHandler
надо же сменить обработчик например на msCustomCartHandler правильно?
Для начала все это не движ от Symfony DB и Controllers. В MiniShop3 обычный классический PHP подход. Почитай про PSR-4, крайне рекомендую.
Во-вторых, про метод addPackage в MODX3 забудь. Это делается один раз автоматически при загрузке MODX. Далее MiniShop3, MODX, PHP уже знают про все классы, которые есть в каталоге /core/components/minishop3/src/
Если ты создаешь любой кастомный класс, например
ты обязан использовать namespace. В твоем случае это будет
И полное имя подключаемого класса будет Именно такое имя тебе нужно указывать в системных настройках или подключаемых сервисах.
Вот примерная заготовка для создания класса. расширяющего стандартную корзину
Ну и в системных настойках нужно указать имя расширенного класса (путь не нужен, он по namespace уже известен).
Я сделаю инструмент для подключения классов, без прописывания системных настроек
Будет отдельная инструкция.
Честно говоря, не до конца понимаю зачем ты в принципе лезешь в дебри, для тебя не понятные. Это разработка для программистов. Анонса всеобщего использования минишопа еще не было. Часть архитектуры еще не готова, то что готово, до конца не оттестировано. Если прям так тянет пощупать компонент — изучай то, что готово и анонсировано.
Вот удивительно, а почему например в YandexMarket2 поддерживается сразу MODX2 и MODX3, также как и cityFields, и другие модули… Ведь куда логичнее было бы сделать также с minishop2 и mSearch2.
YandexMarket2 — это маленький компонент, где для совместимости с MODX нужно было десяток строк подправить. Я уже сто раз отвечал на этот вопрос.
Minishop2 — огромный продукт с устаревшей архитектурой и кодовой базой — нам дали шанс сделать все с нуля как надо, по современнному, вместо того, чтобы тянуть и дальше старье.
То же самое mSearch2 — это очень большой и очень старый продукт. Для своего времени он был прорывным, но уже много лет как устарел, не отвечает современным требования ни в чем. Ни архитектурой, ни кодовой базой, ни зависимостями — его тоже нужно писать с нуля, сохранив бренд и общий смысл.
Хорошие новости — это будет сильно быстрее, чем история с минишопом.
Очень ждём!
Есть один комментарий, смотрю я на скрин и понимаю, что опять придётся для всех цветов и размеров делать отдельные товары так как поле Остаток на складе у них общее (что не может быть — 1 цвет + 1 размер и поле остаток).
Идеальный вариант отдельная вкладка в товаре с таблицей в которой поля: Артикул (может быть одинаковый по цветам), Цвет, Размер, Остаток на складе.
Или ИИ подсказал?
Я конечно понимаю, что PrimeVue красочный, многофункциональный, но затаскивать такого монстра с фаршем под капотом, ну такое себе…