К содержанию

miniShop2 3.0 Alpha релиз.

Друзья впервые за 5 лет, после версии 2.4 команда minishop2 пришла к кардинальным, не косметическим изменениям, и впервые за всю историю компонента мы готовим к выпуску мажорный релиз.


Введение



Внимание эта заметка предназначена для опытных разработчиков сайтов и компонентов для minishop2.
Релиз пока не доступен для общей установки, и находится в отдельной ветке репозитория. Это альфа релиз — то есть, он не подходит для продакшена. Задача Альфа релиза — пощупать общую реализацию идеи. На этом этапе мы еще можем что-то выбросить, что-то добавить, а можем вообще по другому реализовать идею, что уже произошло. Первый альфа релиз был представлен в закрытом чате разработчиков, и после обсуждения было принято решение изменить реализацию.

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

Что нового



Меняем структуру файлов.

Для затравки начнем с того, что все контроллеры-хэндлеры будут вынесены за пределы каталога модели в новый каталог handlers. Каталог models/ предназначен для хранения классов управляющих записями базы данных. Хранить в этом каталоге логику — некорректно. Так же как, например, некорректно хранить логику в шаблонах и тем более производить там какие-либо вычисления, как многие любят делать.

Что сделано:

1. Добавлен каталог /components/nminishop2/handlers/
2. В этот каталог вынесены файлы

  • mscarthandler
  • msdeliveryhandler
  • mspaymenthandler
  • msorderhandler
3. В каталоге /components/nminishop2/model/minishop2/, на прежнем месте нахождения указанных файлов сделаны временные заглушки следующего содержания

<?php

//Deprecated: use handlers from catalog core/components/minishop2/handlers/
require_once dirname(__FILE__, 3) . '/handlers/mscarthandler.class.php';
Такой подход позволит при обращении к любому хэндлеру по старому адресу перенаправить запрос и не вызовет ошибку. Обратите внимание что файлы помечены как Deprecated и в следующих релизах будут удалены совсем.

Рекомендация:

Проследите что ваши компоненты (если они как-то работают с контроллерами minishop2) ссылаются на корректный путь, а лучше перед загрузкой файлов контроллеров проверяют на существование файлы классов по обновленному пути

Проследите что классы вашего сайта, в особенности контроллеры в каталоге components/minishop2/custom/ которые наследуют и расширяют стандартные контроллеры minishop2 — проверяют на существование файлы классов перед их загрузкой и в первую очередь проверяют на существование каталог handlers/

Примерно вот такой код поможет подготовить ваши кастомные классы-контроллеры к обновлению. Он не сломает работы существующей логики, но уже учтет обновление, и сможет загрузить контроллер по обновленному пути.

$newBaseCartHandler = dirname(__FILE__, 3) . '/handlers/mscarthandler.class.php';
$oldBaseCartHandler = dirname(__FILE__, 3) . '/model/minishop2/mscarthandler.class.php';

if (!class_exists('msCartInterface')) {
    if (file_exists($newBaseCartHandler)) {
        require_once $newBaseCartHandler;
    } else {
        require_once $oldBaseCartHandler;
    }
}

Корзину и временные поля заказа больше не обязательно хранить в сессии.

Главная цель текущего обновления, основной вопрос которым задалась команда разработки это проблемы с сессией.

В современном мире часто приходится реализовывать фронт на базе JS фреймворков, принимать заказ из мобильного приложения или через API из других источников (сторонние маркетплейсы, например). И не всегда удается правильно поднять сессию, чтобы при каждом обращении к API минишопа добавлять изменять уже существующую корзину или дополнять заполняемый заказ.

Возникла идея избавиться от сессий совсем и хранить данные в базе, что мы собственно, и сделали.

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

Было примерно так:
$_SESSION[minishop2]['cart'][$key] = $cartItem;

Стало вот так
$this->storageHandler->add($cartItem);

Теперь ни класс корзина, ни класс заказа не знают ничего о том, где хранятся данные. Их задача просто дернуть нужный метод хранилища. А хранилищ может быть много разных. Из коробки доступен старый вариант хранилища Сессия. Это по-прежнему основной вариант, работающий так же, как и раньше.

Также добавлено новое хранилище — База данных. Вы без каких-либо проблем можете добавлять свои хранилища, например файловый вариант (что-то вроде кэша).

Расскажу немного подробнее о том, как работает хранилище реализованное для базы данных.

Был добавлен новый статус заказа «Оформляется» — «Processed»
При первом добавлении товара в корзину, создается пустой заказ с таким статусом. По мере обновления корзины и оформления заказа данные обновляются и в конце концов он переходит в статус Новый заказ

Здесь появляется дополнительное весомое преимущество подхода. Есть возможность видеть корзины еще до оформления заказа. Это полезно для аналитики. Также можно видеть брошенные корзины и предпринимать необходимые действия, имея контактные данные клиента.

Второе весомое преимущество подхода — это возможность переключаться между устройствами.
Авторизованный клиент, начав набирать корзину на телефоне, без труда переключается на компьютер и видит там свою корзину продолжая оформлять заказ.
Думаю, многие оценят!

Ну и самое главное — ради чего все затевалось — теперь стало легче работать из сторонних приложений используя API минишопа.
К примеру я могу через свое мобильное приложение кидать товары в корзину и не париться о том как восстановить на стороне сервера сессию, которая по идее при каждом запросе поднимается заново с новым идентификатором. Не нужно изобретать велосипеды и хранить сессию где-то в свойствах юзера. И так далее.

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

Тип хранилища переключается через системную настройку ms2_tmp_storage
Из коробки доступны две опции — db и session

Рекомендация:

Уважаемые разработчики — Вам обязательно нужно подготовить свои сайты и компоненты для использования нашего обновления!

Основное на что нужно обратить внимание — это использование сессии напрямую.

Я часто встречаю (да и сам писал) код следующего содержания
//  Это условный плагин который пересчитывает корзину
$cart = $_SESSION['minishop2']['cart'];
// Здесь что-нибудь делаем с корзиной, меняем цену одного из товаров например
$cart[$key]['price'] =  1000;
// Пишем обновление в корзину
 $_SESSION['minishop2']['cart'] = $cart;

Теперь придется учитывать вариант, при котором корзина или поля заказа хранятся не в сессии.
На самом деле ничего нового делать не нужно, просто воспользоваться API минишопа, который давным-давно придуман. Давайте перепишем код по правильному

$ms2 = $modx->getService('minishop2');
$ms2->initialize('web');
$cart = $ms2->cart->get();
// Здесь что-нибудь делаем с корзиной, меняем цену одного из товаров например
$cart[$key]['price'] =  1000;
// Пишем обновление в корзину
$ms2->cart->set($cart);

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

Требуется ваша помощь


Друзья — так как это обновление очень серьезное — не хочется торопиться с релизом.
Приглашаю вас принять участие в тестировании.
Вы можете сделать следующее:

1. Развернуть простые тестовые сайты, установить minishop2 из отдельной ветки и просто протестировать работу с корзиной и заказом. Причем как в режиме session так и в режиме db
2. Развернуть dev версии своих действующих сайтов и установить обновление туда. Реальные кейсы — позволят собрать больше ошибок
3. Ну и конечно поучаствовать непосредственно в коде проекта. Почти наверняка есть неучтенные нюансы, о которых не подумали.

Подробнее о методике тестирования будет отдельная заметка.

По просьбам создан сбор на дальнейшее развитие miniShop2
Огромное спасибо, всем кто поддерживает и донатит!
Николай Савин
Николай Савин
17 октября 2021, 10:58
modx.pro
3 293
Реклама

Комментарии: 27

Василий Наумкин
Василий Наумкин Администратор
18 октября 2021, 10:21
Я бы предложил вместо miniShop2 3.0 сделать просто miniShop3

Это сняло бы массу проблем с расположением файлов, переездом рабочих сайтов и разработкой дополнений. Тем более, что домен для него давно куплен и ждёт своего часа — minishop3.com
    Николай Савин
    Николай Савин Администратор
    18 октября 2021, 10:25
    Вась обсуждали, даже голосовали — решили вот таким путем пойти потому что
    1. semver
    2. Устоявшийся бренд
    3. В коде практически всех компонентов, расширяющих минишоп, плагинов, расширенных классов getService(minishop2) и $ms2 фигурируют.
    4. У нас есть большая задумка по более глобальному рефакторингу, если она выстрелит — там может переименуем.
      Николай Савин
      Николай Савин Администратор
      18 октября 2021, 10:29
      Еще дополню — в целом решили на второй ветке MODX оставаться на текущем именовании (по крайней мере пока мелкими шажками правки вносим), а на MODX3 все равно всю экосистему переделывать — там уже ms3 сделать
    Наумов Алексей
    Наумов Алексей Администратор
    19 октября 2021, 09:04
    Николай, добрый день! Раз уж мажорная версия, может быть стоит и вот с этим навести порядок сразу? modx.pro/help/21786
    Не так давно я писал об этой неоднозначности с email и phone в miniShop2.
      Николай Савин
      Николай Савин Администратор
      19 октября 2021, 09:12
      Привет. Не хотелось бы смешивать в одном релизе разные темы. Этот релиз про хранение временных данных.
      У меня пока задача сломать людям сайты только одним способом )).
      Дойдут руки и до твоего вопроса, он зафиксирован и висит в Issue. Как и более 70 других.
      Идем по порядку, чтобы проще было искать проблемы.
      А мажорные релизы теперь часто будут.
      Навскидку в ближайшее время будет полностью изменен JS API (вернее он в принципе появится), что повлечет за собой полное изменение JS и появление продвинутой мини-корзины и возможность работать из JS фремворков
        Наумов Алексей
        Наумов Алексей Администратор
        19 октября 2021, 09:41
        окей) хорошо. Предположил, что частые мажорные релизы тоже не гуд, они ломают людям сайты, заставляют или многое переделывать или «забивать» на обновление компонента. Но и без них, конечно, никуда
          Николай Савин
          Николай Савин Администратор
          19 октября 2021, 09:44
          Щас удивлю наверное кого-то, но обновляться в общем то не обязательно.
          Мажорные релизы предназначены для новых сайтов.
          А старый сайт если работает на текущей версии — пусть себе работает, зачем его обновлять.
            Наумов Алексей
            Наумов Алексей Администратор
            19 октября 2021, 09:54
            В общем да… в частном нет… к сожалению (
            1. Проблемы безопасности, находят уязвимость, в старой версии (не важно чего, MODX или miniShop) никто исправлять не будет — обновляйте!
            2. Проблема совместимости со сторонними компонентами. Подключен у нас модуль интеграции со СДЭК, обновили они свое API, компонент соответствующий для MODX обновился, но он теперь работает только на свежем miniShop, обновляйте!
      Алексей
      Алексей Проверенный
      21 октября 2021, 07:43
      может быть глупый вопрос — но что с дополнениями минишопа? ли они работать на новой версии? тот же mfiltre2 и office — либо надо ждать пока авторы перепишут их под новую версию?
        Николай Савин
        Николай Савин Администратор
        21 октября 2021, 08:31
        Алексей вы вообще анонс читали? Изменения коснулись корзины и системы оформления заказа. Какое к этому имеют отношение офис и фильтр?
        Дополнения касающиеся темы — нужно тестировать и адаптировать (если будут найдены проблемы).
        И я специально в этом посте подробно описываю что изменяется, на что обратить внимание — чтобы у авторов компонентов была подробная информация
        R2m0x94 (Vasily)
        R2m0x94 (Vasily) Старожил
        28 октября 2021, 15:46
        У меня такая ошибка в журнале новой версии minishop2 2.9.3-pl, PHP 8.0, MODX 2.8.3-pl:
        [2021-10-28 15:26:20] (ERROR @ /core/model/modx/modx.class.php: 1677) [OnMODXInit]
        Deprecated: Required parameter $entry follows optional parameter $action in /core/components/minishop2/model/minishop2/minishop2.class.php on line 918
        Только распаковался, у кого-то было также?
          Николай Савин
          Николай Савин Администратор
          28 октября 2021, 15:49
          Это не совсем ошибка ms2. Здесь дело в PHP8.
          Насколько я знаю MODX в целом пока не готов к PHP8.
          Справедливости ради в данном случае MODX не при чем, тут нужно вносить правки в minishop2.
          Это уже запланировано и впереди полный рефакторинг кода
            R2m0x94 (Vasily)
            R2m0x94 (Vasily) Старожил
            28 октября 2021, 16:05
            Временно задал в 918 строке $entry = 0, вроде ошибки нет))
              Николай Савин
              Николай Савин Администратор
              28 октября 2021, 16:07
              Корректнее было бы совсем убрать значение по умолчанию. Ошибка в том, что такие параметры со значениями по умолчанию должны стоять в конце.
          Константин Ильин
          24 ноября 2021, 16:03
          miniShop2 2.9.3-pl
          MODX Revolution 2.8.3-pl
          Google Chrome последний
          ctrl+F5 нажимал

          Что-то с z-index у списка выбора опции, не могу выбрать опции

          prnt.sc/20s4etp
            Николай Савин
            Николай Савин Администратор
            24 ноября 2021, 16:12
            Это компонент extJS встроенный в modx — по идее не к минишопу вопросы. ms2 просто вызывает компонент
              Константин Ильин
              24 ноября 2021, 16:16
              а где можно проверить компонент, точнее говоря где такой же вызов компонента?

              Например здесь норм
              prnt.sc/20s66rs

              Видимо модальное окно выше по z-index
            Евгений Лазарев
            19 января 2022, 18:49
            Добрый день уважаемые разработчики. У меня к вам вопрос: есть ли возможность в новой версии усовершенствовать код в default.js minishop2.Order.add
            $field.val(response.data[key]).removeClass('error').closest(miniShop2.Order.inputParent).removeClass('error');
            Дело в том что иногда нужно добавить свои radio, но изза этого кода получается что всем radio в аттрибут value пишется новое значение.
              Николай Савин
              Николай Савин Администратор
              20 января 2022, 00:18
              Вы без проблем можете использовать свою логику внутри собственного доработанного файл скриптов. Он подключается через соответствующую системную настройку.
                Евгений Лазарев
                20 января 2022, 00:39
                Да я знаю. Просто я топлю за оригинальный файл, к тому же я пока не смог придумать ситуацию где бы для input[type=radio] нужно было применять действия, которые написаны в файле. Даже для delivery и payment сделаны соответствующие исключения. По факту на мой взгляд написано верно, но не для такого типа input. Есть ли возможность указать исключение для них?
                  Николай Савин
                  Николай Савин Администратор
                  20 января 2022, 12:22
                  В этом году весь JS будет полностью переписан на современный стиль. Без jQuery зависимости, возможно в модульном решении, при котором нужные модули подключаются по мере необходимости. Выбросим галерею, которой все равно никто не пользуется. Появится JS API. Будут, думаю, нативные события, а не колбэки. Ну и так далее. Не вижу смысла переписывать или как то модифицировать то, что есть сейчас. Там все целиком пора выбрасывать.
            Алекс Назаренко
            09 августа 2022, 14:38
            Как теперь можно в кастомном классе msCartHandler c помощью функции change отправить в корзину новую цену при изменении количества товара?
            Раньше вопрос решался добавлением однойстроки
            $this->cart[$key]['price'] = 100;
            А теперь, что дописать, чтобы изменить цену на 100?
              Николай Савин
              Николай Савин Администратор
              09 августа 2022, 20:08
              Метод change по заложенной в него логике отвечает только за изменение количества.
              Чтобы изменить цену — корректнее будет использовать метод set, передав туда исправленную корзину.
                Алекс Назаренко
                09 августа 2022, 21:55
                Так а где эту корзину исправлять? Она исправляется в
                public function change($key, $count)
                где и проверяется количество товара, от которого зависит цена.
                Мне нужно именно из этого метода отправить, до обновления это делалось легко.
                  Николай Савин
                  Николай Савин Администратор
                  10 августа 2022, 11:44
                  У вас же кастомный класс корзины. Значит в любом месте, где это удобно по вашей бизнес-логике сделать, пишите примерно следующее
                  // сохраняете корзину в переменную
                  $cart = $this->get();
                  // Тут меняете корзину
                  $cart[$key]['price'] = 100;
                  // Перезаписываете корзину
                  $this->set($cart);
                  И это совсем не обязательно делать внутри класса корзины. Можно использовать функционал плагинов. Только там будет немного другое обращение к корзине через $ms2->cart->get() и set() соотвественно
                    Алекс Назаренко
                    10 августа 2022, 14:27
                    Спасибо! Плагины лишний раз использовать не люблю.
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              27