Апрель 5, 2024
Теги: События, Модули grain, Интеграция с iiko
Удаление ингредиентов, для модуля Интеграция с iiko от 4.1. Пример использования событий "OnEncodeBasketHash", "OnEncodeBasketHashForProduct", "OnDecodeBasketHash", а также добавление комментария к позиции заказа при помощи "OnBuildIikoOrderBody".
В данном примере подразумевается, что файл script.js шаблона компонента "grain:iiko.section" доработан таким образом, что в хеш позиции корзины добавляется элемент --d[строка со списком удаляемых ингредиентов, сконвертированная в base64].
<?php
namespace Partner;
use Grain\Iiko\Size;
use Grain\Iiko\Modifier;
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'grain.iiko',
'OnEncodeBasketHash',
'\Partner\IngredientRemove::onEncodeBasketHash'
);
/* не используется в данной конфигурации, просто пример
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'grain.iiko',
'OnEncodeBasketHashForProduct',
'\Partner\IngredientRemove::onEncodeBasketHashForProduct'
);
*/
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'grain.iiko',
'OnDecodeBasketHash',
'\Partner\IngredientRemove::onDecodeBasketHash'
);
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'grain.iiko',
'OnBuildIikoOrderBody',
'\Partner\IngredientRemove::onBuildIikoOrderBody'
);
class IngredientRemove
{
const basketPropCode = 'GRAIN.IIKO.D';
public static function onEncodeBasketHash(\Bitrix\Main\Event $event)
{
$productId = $event->getParameter('PRODUCT_ID'); // идентификатор товара
$propertyValues = $event->getParameter('PROPERTY_VALUES'); // массив свойств позиции корзины
$hash = $event->getParameter('HASH'); // хэш, сформированный стандартной функцией
foreach($propertyValues as $propertyValue)
{
if(!is_string($propertyValue['CODE']) || !is_string($propertyValue['VALUE']) || strlen($propertyValue['VALUE'])<=0)
continue;
if($propertyValue['CODE']!=static::basketPropCode)
continue;
$hash .= '--d'.base64_encode($propertyValue['VALUE']);
}
$result = new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $hash);
return $result;
}
public static function onEncodeBasketHashForProduct(\Bitrix\Main\Event $event)
{
$productId = $event->getParameter('PRODUCT_ID'); // идентификатор товара
$sizes = $event->getParameter('SIZES'); // массив размеров
$modifiers = $event->getParameter('MODIFIERS'); // массив модификаторов
$additional = $event->getParameter('ADDITIONAL'); // любые дополнительные данные (можно добавить в шаблонах компонентов в 4-й параметр функции Basket::encodeBasketHashForProduct)
$hash = $event->getParameter('HASH'); // хэш, сформированный стандартной функцией
if(is_array($additional) && is_array($additional['removedIngredients']))
{
$ingredientsString = '';
foreach($additional['removedIngredients'] as $ingredient)
$ingredientsString .= ($ingredientsString?', ':'').$ingredient;
$hash .= '--d'.base64_encode($ingredientsString);
}
$result = new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $hash);
return $result;
}
public static function onDecodeBasketHash(\Bitrix\Main\Event $event)
{
$productHash = $event->getParameter('HASH'); // хэш для декодирования
$return = array('productId'=>0,'productHash'=>$productHash,'properties'=>array());
if(is_int($productHash) || (is_string($productHash) && preg_match("/^[0-9]+$/",$productHash)))
{
$return['productId'] = intval($productHash);
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $return);
}
$components = explode('--',$productHash);
$sizes = false;
$modifiers = false;
for($i=0;$i<count($components);$i++)
{
if(is_string($components[$i]) && substr($components[$i],0,1)=='p')
{
$return['productId'] = intval(substr($components[$i],1));
if($return['productId']<=0)
return false;
}
elseif(is_string($components[$i]) && substr($components[$i],0,1)=='s')
{
if(!is_array($sizes))
$sizes = Size::get($return['productId']);
$sizeId = substr($components[$i],1);
foreach($sizes as $size)
{
if($size['sizeId']!=$sizeId)
continue;
$return['properties'][] = array(
'NAME' => $size['s']['name'],
'CODE' => Size::basketPropCode,
'VALUE' => $sizeId,
);
break;
}
}
elseif(is_string($components[$i]) && substr($components[$i],0,1)=='m')
{
list($modifierId,$quantity) = explode(':',substr($components[$i],1));
if(strlen($modifierId)<=0 || intval($quantity)<=0)
continue;
if(!is_array($modifiers))
$modifiers = Modifier::get($return['productId']);
foreach($modifiers as $modifier)
{
if($modifier['id']!=$modifierId)
continue;
$return['properties'][] = array(
'NAME' => $modifier['m']['name'],
'CODE' => Modifier::basketPropPrefix.$modifierId,
'VALUE' => $quantity,
);
break;
}
}
// добавленная часть, разбор убираемых ингредиентов и добавление в свойство позиции корзины
elseif(is_string($components[$i]) && substr($components[$i],0,1)=='d')
{
$removeString = substr($components[$i],1);
$removeString = str_replace(' ', '+', $removeString);
$propertyValue = htmlspecialchars_decode(base64_decode($removeString));
$return['properties'][] = array(
'NAME' => "Убрать",
'CODE' => static::basketPropCode,
'VALUE' => $propertyValue,
);
}
// /добавленная часть, разбор убираемых ингредиентов и добавление в свойство позиции корзины
}
if($return['productId']<=0)
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, false);
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $return);
}
public static function onBuildIikoOrderBody(\Bitrix\Main\Event $event)
{
$restaurant = $event->getParameter('RESTAURANT');
$order = $event->getParameter('ORDER');
$params = $event->getParameter('PARAMS');
$body = $event->getParameter('BODY');
foreach ($event->getResults() as $eventResult) // получение данных после другого обработчика, если он был
{
if($eventResult->getType() == \Bitrix\Main\EventResult::ERROR)
continue;
if($eventResult->getParameters())
$body = $eventResult->getParameters();
}
$index = 0;
foreach ($order->getBasket() as $basketItem)
{
$productId = intval($basketItem->getProductId());
if($productId<=0)
continue;
$rsElements = \CIBlockElement::GetList(
array(),
array("=ID"=>$productId),
false,
array("nTopCount"=>1),
array("ID","IBLOCK_ID","XML_ID","NAME")
);
if(!$ob=$rsElements->GetNextElement())
continue;
$element = $ob->GetFields();
$basketPropertyCollection = $basketItem->getPropertyCollection();
foreach($basketPropertyCollection->getPropertyValues() as $v)
{
if($v['CODE']!=static::basketPropCode)
continue;
if(isset($body['order']['items'][$index]))
{
$body['order']['items'][$index]['comment'] = $v['NAME'].': '.$v['VALUE'];
}
break;
}
$index++;
}
$result = new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $body);
return $result;
}
}
При получении хеша в функции changeCart в script.js шаблона компонента "grain:iiko.section" пробелы необходимо заменить на плюсы:
Пример добавления части хеша в функции recountProduct в script.js шаблона компонента "grain:iiko.section":