Удаление ингредиентов

Модуль расширенного управления меню для битрикс

Апрель 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)<=|| 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::SUCCESSfalse);
        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" пробелы необходимо заменить на плюсы:


let hash data.hash.replace(/\s/g,'+');

Пример добавления части хеша в функции recountProduct в script.js шаблона компонента "grain:iiko.section":


if(ingredientsRemoveString)

{
    function 
b64EncodeUnicode(str) {
        return 
btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
            return 
String.fromCharCode('0x' p1);
        }));
    }
    
hash += '--d'+b64EncodeUnicode(ingredientsRemoveString);
}

← Переход к списку