[MODX] Подсказки по работе и заготовки для MiniShop2

Пример вывода msProducts

[[!msProducts?
  &limit=`7`
  &parents=`19`
  &depth=`10`
  &includeThumbs=`360x270`
  &includeTVs=`1`
  &tpl=`tpl.msProducts.action.item.GO`
  &where=`{"Data.old_price:!=":"0"}`
]]

Добавить превьюшки

Медиа - Управление медия - MS2 Images - thumbnails (Чтобы не было обрезки надо указать zc : 0)

[[+image]] — плейсхолдер для большого изображения при выводе в msProducts.

Если нужно сделать несколько вариантов изображения, то вот примерно такой код нужно разместить в thumbnails:

{
"tiny":{"w":100,"h":100,"q":90,"zc":"1","bg":"ffffff"},
"210x210":{"w":210,"h":210,"q":90,"zc":"1","bg":"ffffff"},
"normal":{"w":550,"h":550,"q":90,"zc":"1","bg":"ffffff"}
}

Показать товары в древе ресурсов

Системные настройки - minishop2 - Показывать в дереве по умолчанию (ms2_product_show_in_tree_default)

Файл, который отвечает за обработку событий по Ajax, отправляемых на /assets/components/minishop2/action.php, в частности cart/add cart/change cart/remove cart/clean cart/get order/add order/submit order/getcost order/getrequired order/clean order/get оказывается плагином, который называется miniShop2.


Пара фильтров для вывода msProducts

  • &where=`{"Data.old_price:!=":"0"}` — Вывести товары с особой ценой
  • &where=`{"Data.new":"1"}` — Вывести товары с отметкой Новый
  • &where=`{"Data.popular":"1"}` — Вывести товары с отметкой Популярный
  • &where=`{"Data.favorite":"1"}` — Вывести товары с отметкой Особый

Добавить в корзину несколько товаров

В моем случае попытка запустить цикл скриптом увенчалась неудачей. Решил не писать костыли вроде СетТаймаут, и закрыть вопрос чуть более правильно.

Вносим изменения в палагин miniShop2: внутри case OnLoadWebDocument добавляем что вроде:

case 'cart/add/multiple': 
$ids = explode(",", $_POST['ids']);
foreach($ids as $id){
	$response = $miniShop2->cart->add($id, 1, $_POST['options']);
}
break;

По-хорошему следовало бы внедриться в файл assets/components/minishop2/js/web/default.js И там настроить правильную запаковку, отсылку и обработку данных, но заморачиваться с этим сейчас нет времени и желания, поэтому закроем костылем. Костыль не страшный. Просто мы сами сделаем все операции с данными:

// HTML код для данного скрипта решил не выкладывать, т.к. все равно верстка индивидаульна. Пробежитесь по скрипту, просто главное логику понять
$(".order-trigger").click(function(){ // это типа кнопка "положить в корзину много товаров"
	pw = $('.product-wrapper').find('.ms2_product'); 
	prodIds = []; //айдишники товаров (именнотоваров, а не ресурсов)
	pw.each(function(){ // находим каждый товар
    var t = $(this);
    var thisCheck = t.find('.checked-product').prop('checked');
    if(thisCheck){
      prodIds[prodIds.length] = parseInt(t.find('.product_id').val());
    }
	});
  var data =[ // такой массив ожидается на сервере
    {name: 'ids',	value: prodIds},
    {name: 'count',	value: '1'},
    {name: 'options',	value: '[]'},
    {name: 'ms2_action',	value: 'cart/add/multiple'},
    {name: 'ctx',	value: 'web'},
  ];
	console.log(data);
	$.ajax({
		type: "POST",
		data: data,
		url:'/assets/components/minishop2/action.php',
		dataType:'json',
		success: function(data){
      if(success == true){
        $.jGrowl("Товары комплекта добавлены в корзину",{ theme: 'ms2-message-success' }); // выводим сообщение об успешной операции
      }
		},
		error: function (xhr, ajaxOptions, thrownError){
			console.log(xhr.responseText);
		}
	});
	
});

Изменить цену товаров в корзине minishop2 при добавлении определенного товара

В частности в моем случае задача была такая:

Если добавлен «товар» «Установка», то стоимсоть всех товаров в корзине увеличивается на 15%.

О тот как добавить несколько товаров в корзину 1 кликом пожно почитать тут.

Открываем код сниппета msCart и начинаем ваять костыль!

// Находим в коде
$cart = $miniShop2->cart->get();

// и сразу после вставляем:
$ustanovka = false;
foreach($cart as $k => $v){
  if($v['id'] == 39){ // Это id товара, который являет собой услугу "Установка" цифра соотвествует id ресурса
    $ustanovka = true;
  }
}
/********/

// Далее по коду ищем что-то такое:
foreach ($cart as $k => $v)

И после него вставляем :
if($ustanovka){
	$v['price'] = $v['price']*1.15;
}

Фильтрация mFilter

Пример вывода:

[[!mFilter2?
  &parents=`[[*id]]`
  &element=`msProducts`
  &limit=`21`
  &includeThumbs=`240x180`
  &includeTVs=`1`
  &filters=`
  ms|price:number
  ,ms|vendor:vendors`
  &toPlaceholders=`my.`
  &tpl=`tpl.msProducts.row.GO`
  &tplFilter.outer.default=`tpl.mFilter2.filter.outer.GO` // кастомный tpl
  &tplFilter.outer.ms|price=`tpl.mFilter2.filter.slider`  // стандартный tpl (обратить внимание на "ms|price" - это связь с фильтром из параметра "filters")
  &tplFilter.row.ms|price=`tpl.mFilter2.filter.number`    // стандартный tpl
]]

Изменение цены при добавлении в корзину minishop2

Цена в minishop2 по курсу валюты

  • Создаем TV usd_price:
    Тип: чекбокс;
    возможные значения: Да==1||Нет==0;
    Значение по умолчанию: Нет==0.
  • Создаем системную настройку: ms2_usd_value, значение — 80 (нынешний курс валюты)
  • Создаем плагин на событие msOnBeforeAddToCart

Код плагина (не забыть установить системное событие):

if ($modx->event->name == 'msOnBeforeAddToCart') {
  $tv = $modx->getObject('modTemplateVar', array('name' => 'usd_price'));
  $modx->log(xPDO::LOG_LEVEL_ERROR, $tv->getValue($product->get('id'))); // для дебага
  $modx->log(xPDO::LOG_LEVEL_ERROR, $modx->getOption('ms2_usd_value')); // для дебага
  if($tv->getValue($product->get('id')) != 0){
    $newPrice = (int)$modx->getOption('ms2_usd_value') * (int)$product->get('price');
    $product->set('price', $newPrice);
  }
}

Поместить параметр вывода в плейсхолдер

Речь идет о том, чтобы в санке бала возможность вывести какой-то параметр, который был передан при вызове сниппета. К примеру параметр tpl будет доступен в [[+property.tpl]]. И так со всеми параметрами.

Эта штука реализована в MIGX и иногда бывает крайне полезна. К примеру в проекте у меня есть шаблон вывода товаров, он одинаковый везде, но кое-где нужно использовать класс col-xs-3, а где-то col-xs-4. Делать под это условие с привязкой за шаблон, или тем более создавать отдельный чанк не хочется. Куда проще - передать класс при вызове сниппета.

Но такого функционала в msProducts не предусмотрено. Ок, добавим - нужно просто скопировать часть кода ниже в код сниппета msProducts:

// Этот код разместить перед блоком "Processing rows" (...if (!empty($rows) && is_array($rows)) {...):
$properties = array();
foreach ($scriptProperties as $property => $value) { 
  $properties['property.' . $property] = $value;
}

// Эту строчку добавить перед $tpl = $pdoFetch->defineChunk($row)... В общем перед выводом всех данных в чанк
$row = array_merge($row, $properties);

Разная цена в зависимости от кол-ва товара в корзине

Код плагина:

Стоит отметить, что поля price500/price5/price4/price3/price2 были созданы предварительно.

switch ($modx->event->name) {
  case 'msOnChangeInCart': case 'msOnAddToCart': case 'msOnRemoveFromCart':
  $tmp = $cart->get();
  //$modx->log(xPDO::LOG_LEVEL_ERROR, print_r($tmp, true));
  foreach ($tmp as $key1 => $value) {
    if ($product = $modx->getObject('msProduct', $value['id'])) {
      $quantity = $value['count'];
      if ($quantity > 499) { $tmp[$key1]['price'] = $product->get('price500'); }
      elseif ($quantity > 99) { $tmp[$key1]['price'] = $product->get('price5'); }
      elseif ($quantity > 49) { $tmp[$key1]['price'] = $product->get('price4'); }
      elseif ($quantity > 29) { $tmp[$key1]['price'] = $product->get('price3'); }
      elseif ($quantity > 9) { $tmp[$key1]['price'] = $product->get('price2'); }
      else {
        $realPrice = $product->get('price');
        $tmp[$key1]['price'] = $realPrice;
      }
    }
  }
  //$modx->log(xPDO::LOG_LEVEL_ERROR, $realPrice);
  $cart->set($tmp);
  break;
}

Расширение свойств классов MiniShop2

Переходим в папку core/components/minishop2/custom/ и выбираем подходящее место для файлика - в зависимости от того, что мы саобираемся расширять. Допустим это будет order. Создаем файл с любым названием, которое оканчивается на .class.php.

Внутри этого файлика пишем

class msOrderHandlerMy extends msOrderHandler{
  // И тут уже можно переопределить существующий метод, либо создать свой.
}

После этого переходим в системные настройки MiniShop2, и там указываем имя вашего класса (мой пример msOrderHandlerMy) в настройке ms2_order_handler_class, или ms2_cart_handler_class для нового msCartHandler

Родные методы храняться в файлах:
core/components/minishop2/model/minishop2/msorderhandler.class.php
core/components/minishop2/model/minishop2/mscarthandler.class.php
core/components/minishop2/model/minishop2/msdeliveryhandler.class.php
core/components/minishop2/model/minishop2/mspaymenthandler.class.php

Динамически обновлять цены при изменении кол-ва в корзине

Эта задача наиболее актуальна при разных ценах на товары в зависимости от кол-ва. (см. пункт выше)

Нам надо будет подправить JS файлик assest/components/minishop2/js/web/default.js, а также расширить класс msCartHandler (см. выше)

Создаем файлик по инструкции:

class msCartHandlerMy extends msCartHandler{
  public function status($data = array())
  {
    $status = array(
      'total_count' => 0,
      'total_cost' => 0,
      'total_weight' => 0,
    );
    $status['cart'] = $this->cart; // Добавляем только эту строчку к оригинальному методу
    foreach ($this->cart as $item) {
      if (empty($item['ctx']) || $item['ctx'] == $this->ctx) {
        $status['total_count'] += $item['count'];
        $status['total_cost'] += $item['price'] * $item['count'];
        $status['total_weight'] += $item['weight'] * $item['count'];
      }
    }
    $status = array_merge($data, $status);

    $response = $this->ms2->invokeEvent('msOnGetStatusCart', array(
      'status' => $status,
      'cart' => $this,
    ));
    if ($response['success']) {
      $status = $response['data']['status'];
    }

    return $status;
  }
}

Переходим теперь к файлику assets/components/minishop2/js/web/default.js. Находим status: function (status) {, и там через console.log(status); для начала убеждаемся, что получаем данные о корзине, и о каждом товаре.

И теперь в этом методе уже куда угодно сортируем полученные данные. Например так:

$.each(status.cart, function(key, value) {
	$("#" + key).find(".price").text(miniShop2.Utils.formatPrice(value.price));
});
// Я разместил перед вот этой строчкой:
// if ($(miniShop2.Order.orderCost, miniShop2.Order.order).length) {

Комментарии (2)

  1. Евгений 13 сентября 2019, 16:13 # 0
    Добрый день.

    а не подскажете как сделать добавление/удаление товара в(из) корзину(ы) по чекбоксу на странице оформления заказа? т.е. при установке галочки определённый товар добавлялся в корзину, а при снятии этой галочки чтобы удалялся из корзины. как добавить — понятно вроде, а вот как убрать?
    1. Сергей 12 декабря 2019, 02:18(Комментарий был изменён) # 0
      Доброго времени суток, сейчас уже нет внутри OnLoadWebDocument никаких case
      Можете подсказать куда сейчас надо это вписать?
      Это по поводу «Добавить в корзину несколько товаров»
      *Комментарий будет опубликован после проверки модератором

      Комментарии easyComm

      Адель 13 мая 2018, 00:55

      По вопросу @Добавить в корзину несколько товаров@

      По костылю,
      order-trigger - класс кнопки субмит
      product-wrapper - контейнер продуктов
      checked-product - контейнер продукта
      product_id - класс инпута

      Полная разметка:

      <form method="post" class="ms2_form ajax_form">
      <div class="row ms2_product product-wrapper">
      <!--Товар-->
      <div class="col-md-6 col-lg-3 checked-product">
      <input type="hidden" name="id" value="15">
      <input type="text" name="count" class="product_id" value="1">
      <input type="hidden" name="options" value="[]">
      </div>
      <!--//Товар-->
      <!--Товар-->
      <div class="col-md-6 col-lg-3 checked-product">
      <input type="hidden" name="id" value="16">
      <input type="text" name="count" class="product_id" value="1">
      <input type="hidden" name="options" value="[]">
      </div>
      <!--//Товар-->

      <div class="col-md-3 offset-md-3">
      <button class="btn btn-default pull-right order-trigger" type="submit" name="ms2_action" value="cart/add">
      <i class="glyphicon glyphicon-barcode"></i> Заказать уборку
      </button>
      </div>

      </div>

      <input type="hidden" name="af_action" value="65f6fa23530619c59498039f76a127c9">
      </form>

      Правильно ли я логику понял?

      Адель 13 мая 2018, 00:39

      case 'cart/add/multiple':
      $ids = explode(",", $_POST['ids']);
      foreach($ids as $id){
      $response = $miniShop2->cart->add($id, 1, $_POST['options']);
      }
      break;

      При "Добавить в корзину несколько товаров" изменении приложения minishop2 ругается на разметку фенома, тк там чистый JS.

      Я не силен в феноме, быть может кто нибудь переведет его в JS.

      И по выдаче этой статьи не найти, я можно сказать душу продал пока искал что то похожее.

      Администратор

      Если феном выдает ошибки, то просто оберните JS код в {ignore} ... {ignore}.
      Это может выглядеть так:

      Василий 03 апреля 2018, 21:12

      Прошу помощи. Установил MS2 и получил проблему с превьюшками. Картинки в галерею товара загружаются, ресайзятся как указано в системных настройках. А превью не создаются. Вместо них дефолтный логотип ms2. Подскажите, где искать?

      Администратор

      Давайте попробуем разобраться. Какие настройки у вас в системе стоят и как вы пытаетесь вывести изображение? Пример кода, пожалуйста.

      Похожие статьи

      Генератор настроек MIGX

      Документация на русском по MODX MIGX

      Подсказки по работе и заготовки для MiniShop2

      Импорт и экспорт в MiniShop2. Реализация 1

      pdoPage и getImageList - Постраничная навигация MIGX

      Как включить HTTPS (SSL) в MODX - Подробная инструкция

      Генерация YML для выгрузки в маркет

      Примеры работы с API MODX

      Расширение свойств товаров minishop2

      Примеры выборки where, optionFilters, innerJoin

      pThumb - ресайз изображений. Примеры использования.

      Примеры использования

      Сайт на обслуживании (выключить сайт)

      Вывести getImageList только если он не пустой

      Тип поля "Список ресурсов" (resourcelist) с ограничением по родителю (parents)

      Оформление и настройка easyComm. Комментарии и отзывы на сайте.

      Добавить в письмо контактную информацию

      Поиск на сайте с пакетом SimpleSearch

      Простая и симпатичная галерея fancybox

      Вывод tv-параметров в формате -

      Галерея. Вывести обложки альбомов и фотографии

      Подсчет и вывод количества потомков ресурса в MODX

      Отредактировать письмо о заказе - добавить ТВ поле, или что-то еще

      Quip для MODX. Более рабочий вариант

      pdoResources Заготовки для работы

      Сниппет для вывода размера и расширения файла

      Простой аудио-плеер HTML5

      Вывести список всех опций MiniShop2

      Как контролировать кэш CSS и скриптов

      Изменить цену на товар в зависимости от количества при добавлении в корзину minishop2

      Слайдер Slick slider в контенте ресурса

      Подключить MODX в стороннем PHP файле

      Простейшая авторизация

      Красивое адаптивное меню под pdoMenu

      Массово обновить ТВ, или другое поле через базу

      Как создать ресурс процессором $modx->runProcessor('resource/create', $props)

      Изменить формат номера заказа

      Создать свою страницу в админке

      Сообщение о том, что сайт использует Cookie

      Получить grandparent. Вывести родитель родителя

      Симпатичный список файлов, загружаемых к ресурсу через MIGX

      Создать источник файлов

      Установить шаблон по-умолчанию для новых, создаваемых ресурсов

      Вывести все доступные плейсхолдеры

      Отредактировать шаблон письма

      Добавить скрипт перед тегом body

      Общая сумма по каждому товару в корзине Minishop2

      Создать раздел с паролем на сайте MODX

      Что делать если ее приходит почта администратору

      Фильтрация по TV параметрам в msProducts

      Дата на русском

      FontAwesome - часто используемые иконки для шаблонов MODX

      Создать пакет с пользовательской таблицей

      Курсы валют с cbr.ru на PHP

      Заготовки для работы

      Обязательный чекбокс при оформлении заказа

      getResources заготовки

      Загрузка сниппета после загрузки страницы через AjaxSnippet

      Соответствие названия классов с названиями таблиц в MySQL

      Баннеры с использованием BannerY

      Разбить вывод pdoResources на несколько колонок (блоков)

      Обработка остатков заказа в miniShop2

      CSS для постраничной навигации pdoPage

      Вывести время загрузки (формирования) страницы

      Расширить таблицу site_content (объект modResource) за 5 минут

      Счетчик посещений и скачиваний для сортировки ресурсов

      Вырезать кавычки — фильтр-сниппет MODX

      Обновить alias (псевдоним) у всех ресурсов

      Динамическое поле emailSubject в FormIt

      Бесплатная доставка от 5000 рублей в MiniShop2

      Скрыть информацию о том, что сайт работает на MODX

      Отсортировать ресурсы по количеству комментариев Quip MODx

      Изменить цену на товар, если в корзине лежит товар из особой категории minishop2

      Создать редирект через autoRedirector API

      Вывести 404 ошибку по настройке TV MODX

      Ответ для сервиса moneta.ru

      Email сделать не обязательным полем

      Как разместить исходный код сниппета на сайте, в документации

      Ускорить установку MODX revo до пары кликов

      Постраничная навигация — набор параметров и CSS PdoPage

      Сделать поле размер обязательным

      Не работает подгрузка товаров ajax mfilter2 на мобильном

      Сделать все элементы статичными для Git и IDE

      Cортировать по списку id в pdoResources и pdoTools

      Кастомный чанк для AdminPanel

      Настройка стилей для комментариев Tickets

      Подключить текстовой редактор к доп. полям ресурса

      Разместить корзину внутри блока с оформлением заказа

      Динамическая замена шаблона ресурса - плагин

      Вывести список всех родителей в ТВ поле ресурса

      Вложенные условия в xPDO MODX

      Плагин для формирования замороженных URL с редиректом

      Приветственный экран / заглушка на сайт

      Вывести список всех емэйлов miniShop2

      Если getParentIds не работает в плагине

      Как получить данные пользователя сразу после авторизации через API

      xPDO Выборка из одной таблицы с зацепкой значения из другой

      Контролировать кэширование файлов CSS и JS MiniShop2

      Не приходят / не отправляются письма - в чем причина?

      Кэширование в MODX: использование $modx->cacheManager

      Наш сайт использует куки, нажмите «ОК» если вы не против
      OK