Корзина

18 ноября 2016, 00:51

Этот класс инициализируется методом miniShop2::initialize(), и должен реализовывать интерфейс msCartInterface.

Обязательные методы интерфейса:

  • initialize — Инициализирует класс в контекст. Может загружать скрипты и стили.
  • add — Добавляет товар в корзину, обязателен параметр id.
  • remove — Удаляет товар из корзины, обязателен параметр key
  • change — Изменение количества товара в корзине, обязательны key и count
  • clean — Полная очистка корзины
  • status — Возвращает статус корзины: общую стоимость, вес и количество товаров
  • get — Возвращает содержимое корзины, целиком
  • set — Перезаписывает содержимое корзины полученным массивом cart

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

Свой класс для контекста вы можете указать в системной настройке ms2_cart_handler_class. Про регистрацию служб читайте в отдельном разделе.

Инициализация

if ($miniShop2 = $modx->getService('miniShop2')) {
    // Инициализируем класс в текущий контекст
    $miniShop2->initialize($modx->context->key);

    print_r($miniShop2->cart->add(5)); // Добавляем товар с id = 5 и печатаем ответ
    print_r($miniShop2->cart->get()); // Получаем и распечатываем содержимое корзины
    print_r($miniShop2->cart->status()); // Получаем и распечатываем состояние корзины
}

После инициализации класса miniShop2 корзина со всеми методами доступна в $miniShop2->cart. Учитывая, что имя класса берётся из системных настроек, у каждого контекста может быть своя корзина.

Можно конфигурировать msCartHandler при инициализации:

// Инициализируем класс в текущий контекст
$scriptProperties = array(
    'json_response' => true, // возвращать ответы в JSON
    'max_count' => 1000, // максимальное число товаров для добавления за один раз
    'allow_deleted' => false, // не добавлять в корзину товары с deleted = 1
    'allow_unpublished' => false, // не добавлять в корзину товары с published = 0
);
$miniShop2->initialize($modx->context->key, $scriptProperties);

Работать с корзиной напрямую нельзя, только через методы класса.

Системные события

Класс msCartHandler генерирует определённые события при работе с корзиной. Для удобства, вот они в виде заготовки-плагина:

<?php
switch ($modx->event->name) {
    // События на добавление товара
    case 'msOnBeforeAddToCart': break; // получает $product, $count, $options и $cart
    case 'msOnAddToCart': break; // получает $key и $cart

    // Удаление товара из корзины
    case 'msOnBeforeRemoveFromCart': break; // получает $key и $cart
    case 'msOnRemoveFromCart': break; // получает $key и $cart

    // Изменение количества
    case 'msOnBeforeChangeInCart': break; // получает $key, $count и $cart
    case 'msOnChangeInCart': break; // получает $key, $count и $cart

    // Очистка корзины
    case 'msOnBeforeEmptyCart': break; // получает $cart
    case 'msOnEmptyCart': break; // получает $cart
}

Во всех методах присутствует объект $cart - это сам класс msCartHandler, со всеми методами.

Переменная $key это ключ элемента корзины, формируется как:

md5($id . json_encode($data));
// где $id - это идентификатор товара, а $data - массив параметров, присланных при добавлении

Переменная $count обозначает количество товара, обычное число.

Примеры

Если мы хотим изменить товар перед добавлением, то нужно воспользоваться событием msOnBeforeAddToCart, в котором есть объект $product.

case 'msOnBeforeAddToCart':
    $product->set('new_price', 5555);
    break;

Вы можете делать с товаром что угодно, даже сохранить ему новую цену через $product->save();. Еще в этом событии есть массив $data — дополнительные параметры, присланные юзером при добавлении товара в корзину. Там может быть цвет, размер и вообще, что угодно. Если его изменить, то продукт добавится с изменённым $key.

А теперь меняем цену товара после добавления. В этом событии у нас уже нет товара, есть только корзина и ключ:

case 'msOnAddToCart':
    $tmp = $cart->get();
    $tmp[$key]['price'] = 1000;
    $cart->set($tmp);
    break;

таким образом можно менять содержимое корзины при любом событии, $cart есть везде.