[СДЕЛАЙ САМ] Сравнение товаров MiniShop2 просто!

Приветствую, у меня было много безуспешных попыток подружиться с компонентом Comparision, но каждый раз он оказывался слишком сложным. В итоге, я написал своё, простое, если не сказать, примитивное, решение.

Как это работает
Есть форма, которая отправляет на сервер list — название списка, чтобы не сравнивать тапочки и телевизоры (лучше всего указывать название категории), id товара добавляемого к сравнению, ctx — ключ контекста, если необходимо, по умолчанию будет установлено значение web.

На сервере переданный id будет добавлен в сессию, в специальный массив, если отсутствовал там, в противном случае он будет удален из сравнения. Например, если добавить товар с ID = 29 в список (list) с именем «Обувь» в $_SESSION['compare'] будет такая картина
[
    'web' => [
        'Обувь' => [
            '29' => 1
        ]
    ]
];
После этого остаётся на отдельной странице вывести списки сравнения, для этого есть сниппет getCompareLists, который получает из сессии все списки, а так же товары и их опции.

Параметры сниппета getCompareLists
  • tplWrapper — чанк обёртки принимает плейсхолдеры $nav и $content
  • tplNav- чанк элемента блока переключения списков, принимает плейсхолдеры $list (имя списка) и $idx (порядковый номер)
  • tplContent- чанк элемента блока с содержимым списка, принимает плейсхолдеры $list (имя списка), $idx (порядковый номер) и $rows (поля и их значения)
  • tplRow — чанк для вывода одного поля, принимает плейсхолдеры $field и $data
  • tplDefault — чанк вывода значения поля у конкретного товара, принимает плейсхолдеры $field и $product. Однако, например, если вам нужно в поле с ценой выводить ещё и старую цену, вы можете назвать параметр tplPrice и создать для него отдельный чанк со своей логикой, аналогично можно поступить с любым полем.
  • tplActions — если последней строкой нужно вывести какие-то действия, например удаление из избранного, укажите в этом параметре значение соответствующего чанка. Плейсхолдеры те же что и в tplDefault
  • fields — список полей по которым будет происходить сравнение (массив или json), точно работает с основными полями товара и опциями, но поскольку товары получаются методом getObject(), возможно там будут и TV. Можно этот параметр не указывать, но тогда обязательно должен существовать сниппет snippets/snippet.getcomparefields.php в виде файла, в админке можно не создавать.
Спиппет snippets/snippet.getcomparefields.php получает ключи и описания всех опций определенной категории (list), дополнительно включает туда pagetitle, thumb и price.

Как это реализовать
Пример реализации есть в моём репозитории, если всё что там есть, кажется вам сложным, значит это решение вам не подходит.

Для отправки формы проще всего использовать AjaxFormitLogin или AjaxForm. Пример вызова можно посмотреть тут, а чанк с формой лежит здесь.

Для обработки формы нам понадобится сниппет Comparision (нужно создать его в админке), который использует одноименный класс.

Чтобы надпись на кнопке менялась, понадобится JavaScript, который нужно подключить в подвале на всех страницах, где есть управление списками сравнения, и класс afl-compare-btn. Вывод общего количества товаров добавленных к сравнению не реализован, за ненадобностью, но в ответе сервера в e.detail.response.data.counts есть как общее количество товаров для сравнения во всех списках, так и количество товаров в каждом списке отдельно. Реализовать показ этой информации на сайте, можно по аналогии с изменением текста кнопки.

Пример страницы со списками сравнения можно посмотреть здесь.

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

Спасибо за внимание!

О том как поблагодарить автора и поддержать сообщество можно узнать тут
Артур Шевченко
25 апреля 2023, 18:54
modx.pro
3
862
+7
Поблагодарить автора Отправить деньги

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

deleted
25 апреля 2023, 19:21
0
На сервере переданный id будет добавлен в сессию
А почему в сессию, а не в куки? Я через куки делал сравнение и избранное, ничего на сервер отправлять не нужно и не пропадёт через неделю при окончании сессии) Кстати, если выбрать хранение корзины в базе, она исчезнет когда сессия кончится или нет?
    Артур Шевченко
    25 апреля 2023, 19:58
    0
    В сессию, потому что мне так захотелось))) Длительное хранение не требуется. В целом, можно просто заменить $_SESSION на $_COOKIE и будет храниться в куках.

    Что касается корзины в БД, то логика подсказывает, что не исчезнет.
      Николай Савин
      26 апреля 2023, 09:17
      0
      Хранение корзины в базе было придумано как раз для того, чтобы не связываться с сессией. Так что — ничего общего.
      Корзина исчезнет — когда отработает скрипт удаления старых записей или ее удалят руками
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    4