Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/grain.iiko/lib/ |
Upload File : |
<?php namespace Grain\Iiko; use \Bitrix\Main\Localization\Loc; use \Bitrix\Main\Web\Json; use \Bitrix\Main\Loader; use \Grain\Iiko\ModifierListTable; use \Grain\Iiko\ModifierImageTable; use \Grain\Iiko\ModifierListGroupTable; use \Grain\Iiko\Restaurants; Loc::loadMessages(__FILE__); class Modifier { const basketPropPrefix = 'GRAIN.IIKO.M.'; public static function get($element, \Bitrix\Sale\BasketItem $item=null) { $modifiers = array(); static $cache = array(); if(!is_array($element) || !is_array($element['PROPERTIES']) || count($element['PROPERTIES'])<=0) { $elementId = is_array($element) && isset($element['ID'])?intval($element['ID']):intval($element); if($elementId<=0 || !Loader::includeModule('iblock')) return $modifiers; if(array_key_exists($elementId,$cache)) { $element = $cache[$elementId]; } else { $result = \Bitrix\Iblock\ElementTable::getList(array( 'filter' => array('=ID'=>$elementId), 'limit' => 1, 'select' => array("ID", "IBLOCK_ID"), )); if(!$el=$result->fetch()) return $modifiers; $resultElement = \CIBlockElement::GetList(array(), array( "IBLOCK_ID" => $el['IBLOCK_ID'], "=ID" => $el['ID'] ), false, false, array( "ID", "IBLOCK_ID", "PROPERTY_modifiers") ); if (!$ob = $resultElement->GetNextElement()) return $modifiers; $element = $ob->GetFields(); $element['PROPERTIES'] = array('modifiers'=>$ob->GetProperty('modifiers')); $cache[$elementId] = $element; } } if(!is_array($element['PROPERTIES']['modifiers']) || !is_array($element['PROPERTIES']['modifiers']['~VALUE'])) return $modifiers; foreach($element['PROPERTIES']['modifiers']['~VALUE'] as $mod) { try { $modifier = Json::decode(trim($mod)); $modifier['modifierId'] = $modifier['id']; // old templates compatibility $modifiers[] = $modifier; } catch (\Exception $e) { //$e->getMessage(); } } if($item) { $basketProps = self::getBasketPropertyValues($item); foreach($modifiers as &$modifier) { if(array_key_exists(self::basketPropPrefix.$modifier['id'], $basketProps)) { $modifier['selected'] = $basketProps[self::basketPropPrefix.$modifier['id']]; } elseif($modifier['required']) { $modifier['selected'] = $modifier['minAmount']>0?$modifier['minAmount']:1; } else { $modifier['selected'] = 0; } } unset($modifier); } $modifiersTemp = $modifiers; $modifiers = array(); foreach($modifiersTemp as $modifier) { $modifier['minAmountForHtmlInput'] = 0; if($modifier['minAmount']>0) $modifier['minAmountForHtmlInput']=$modifier['minAmount']; /* this is wrong logic elseif($modifier['groupMinAmount']>0) $modifier['minAmountForHtmlInput']=$modifier['groupMinAmount']; */ $modifier['maxAmountForHtmlInput'] = 0; if($modifier['maxAmount']>0) $modifier['maxAmountForHtmlInput']=$modifier['maxAmount']; elseif($modifier['groupMaxAmount']>0) $modifier['maxAmountForHtmlInput']=$modifier['groupMaxAmount']; if(!!($data=self::checkActiveAndGetData($element['IBLOCK_ID'],$modifier['id'])) || $modifier['selected'] || $modifier['groupRequired'] || $modifier['required']) { $modifier['data'] = $data; $modifiers[] = $modifier; } } return $modifiers; } public static function getPreparedForOrder($element, \Bitrix\Sale\BasketItem $item) { $modifiers = self::get($element,$item); $modifiersPreparedForOrder = array(); foreach($modifiers as $modifier) { if($modifier['selected']<=0) continue; $newModifier = array( 'id' => $modifier['m']['id'], 'name' => $modifier['m']['name'], 'code' => $modifier['m']['code'], 'amount' => $modifier['selected'], 'price' => $modifier['m']['price'], ); if($modifier['groupId']) { $newModifier['groupId'] = $modifier['groupId']; $newModifier['groupName'] = $modifier['groupName']; } $modifiersPreparedForOrder[] = $newModifier; } return $modifiersPreparedForOrder; } public static function setModifierQuantity(\Bitrix\Sale\BasketItem $item,$modifierId,$quantity) { $modifiers = self::get($item->getProductId()); $quantity = intval($quantity); $currentModifier = false; foreach($modifiers as $modifier) { if($modifier['id']!=$modifierId) continue; $currentModifier = $modifier; break; } if(!$currentModifier) $quantity = 0; elseif(!!$currentModifier['maxAmount'] && $quantity>$currentModifier['maxAmount']) $quantity=$currentModifier['maxAmount']; elseif($quantity<$currentModifier['minAmount']) $quantity=$currentModifier['minAmount']; if(!!$currentModifier['groupId'] && !!$currentModifier['groupMaxAmount'] && $quantity>$currentModifier['groupMaxAmount']) $quantity=$currentModifier['groupMaxAmount']; $changeModifiersQuantity = array($modifierId=>$quantity); // if modifier had a group, iterate through other modifiers in group and change its quantity if neccessary if(!!$currentModifier['groupId']) { $currentQuantityInGroup = 0; $basketProps = self::getBasketPropertyValues($item); foreach($modifiers as $modifier) { if($modifier['groupId']!=$currentModifier['groupId']) continue; if($modifier['id']==$currentModifier['id']) $currentQuantity = $quantity; else $currentQuantity = array_key_exists(self::basketPropPrefix.$modifier['id'], $basketProps)?$basketProps[self::basketPropPrefix.$modifier['id']]:0; $currentQuantityInGroup += $currentQuantity; } $needToIncrease = !!$currentModifier['groupMinAmount'] && $currentQuantityInGroup<$currentModifier['groupMinAmount']?$currentModifier['groupMinAmount']-$currentQuantityInGroup:0; $needToDecrease = !!$currentModifier['groupMaxAmount'] && $currentQuantityInGroup>$currentModifier['groupMaxAmount']?$currentQuantityInGroup-$currentModifier['groupMaxAmount']:0; foreach($modifiers as $modifier) { if($modifier['groupId']!=$currentModifier['groupId'] || $modifier['id']==$currentModifier['id']) continue; $currentQuantity = array_key_exists(self::basketPropPrefix.$modifier['id'], $basketProps)?$basketProps[self::basketPropPrefix.$modifier['id']]:0; if($needToIncrease>0) { $canIncrease = !!$modifier['maxAmount']?$modifier['maxAmount']-$currentQuantity:$needToIncrease; if($canIncrease>=$needToIncrease) { $changeModifiersQuantity[$modifier['id']] = $currentQuantity+$needToIncrease; $needToIncrease = 0; } else { $changeModifiersQuantity[$modifier['id']] = $currentQuantity+$canIncrease; $needToIncrease -= $canIncrease; } } elseif($needToDecrease>0) { $canDescrease = !!$modifier['minAmount']?$currentQuantity-$modifier['minAmount']:$needToDecrease; if($canDescrease>$currentQuantity) $canDescrease=$currentQuantity; if($canDescrease>=$needToDecrease) { $changeModifiersQuantity[$modifier['id']] = $currentQuantity-$needToDecrease; $needToDecrease = 0; } else { $changeModifiersQuantity[$modifier['id']] = $currentQuantity-$canDescrease; $needToDecrease -= $canDescrease; } } else break; } } foreach($changeModifiersQuantity as $currentModifierId=>$currentQuantity) { if($currentQuantity>0) { $name = $currentModifierId; foreach($modifiers as $modifier) { if($modifier['id']!=$currentModifierId) continue; $name = $modifier['m']['name']; break; } self::saveBasketProperty($item,self::basketPropPrefix.$currentModifierId,$currentQuantity,$name); } else { self::deleteBasketProperty($item,self::basketPropPrefix.$currentModifierId); } } return $changeModifiersQuantity; } public static function getBasketPropertyValue(\Bitrix\Sale\BasketItem $item,$code) { foreach ($item->getPropertyCollection() as $property) { if($property->getField('CODE')!=$code) continue; return $property->getField('VALUE'); } return false; } public static function getBasketPropertyValues(\Bitrix\Sale\BasketItem $item) { $values = array(); foreach ($item->getPropertyCollection() as $property) $values[$property->getField('CODE')] = $property->getField('VALUE'); return $values; } public static function saveBasketProperty(\Bitrix\Sale\BasketItem $item,$code,$value=false,$name=false,$sort=false,$xmlId=false) { foreach ($item->getPropertyCollection() as $property) { if($property->getField('CODE')!=$code) continue; if($value!==false) $property->setField('VALUE', $value); if($name!==false) $property->setField('NAME', $name); if($sort!==false) $property->setField('SORT', $sort); if($xmlId!==false) $property->setField('XML_ID', $xmlId); return; } $property = $item->getPropertyCollection()->createItem(); $property->setField('CODE', strval($code)); $property->setField('VALUE', strval($value)); $property->setField('NAME', strval($name)); $property->setField('SORT', $sort!==false?$sort:'100'); if($xmlId!==false) $property->setField('XML_ID', $xmlId); } public static function deleteBasketProperty(\Bitrix\Sale\BasketItem $item,$code) { foreach ($item->getPropertyCollection() as $property) { if($property->getField('CODE')!=$code) continue; $property->delete(); return; } } public static function getGroupTree($organizationId) { if(!$organizationId) return array(); $tree = array(); $groups = array(); $resultGroup = ModifierListGroupTable::getList(array( 'filter' => array('ORGANIZATION_ID'=>$organizationId), 'order' => array('SORT'=>'ASC'), )); while($group=$resultGroup->fetch()) { $groups[$group['ID']] = $group; } $tree = array(); foreach($groups as $groupId=>$group) { if($group['PARENT_GROUP_ID']) continue; $group['DEPTH_LEVEL'] = 1; $tree[$group['ID']] = $group; unset($groups[$groupId]); } $maxLevels = 5; $level = 0; while($groups && $level++<=$maxLevels) { foreach($groups as $groupId=>$group) { if(!array_key_exists($group['PARENT_GROUP_ID'], $tree)) continue; $group['DEPTH_LEVEL'] = $tree[$group['PARENT_GROUP_ID']]['DEPTH_LEVEL'] + 1; // Insert at position with of key $indexOfParent = array_search($group['PARENT_GROUP_ID'], array_keys($tree)); $indexOfLastChild = $indexOfParent; $indexedTree = array_values($tree); for($i=($indexOfParent+1);$i<count($indexedTree);$i++) { $treeItem = $indexedTree[$i]; if($treeItem['PARENT_GROUP_ID']==$group['PARENT_GROUP_ID']) { $indexOfLastChild = $i; } } $treeTmp = $tree; $tree = array(); $i=0; foreach($treeTmp as $tmpGroupId=>$tmpGroup) { $tree[$tmpGroupId] = $tmpGroup; if($i==$indexOfLastChild) $tree[$groupId] = $group; $i++; } // /Insert at position with key unset($groups[$groupId]); } } foreach($groups as $groupId=>$group) { $group['DEPTH_LEVEL'] = 1; // Add to beginning with key $tree = array_reverse($tree, true); $tree[$group['ID']] = $group; $tree = array_reverse($tree, true); // /Add to beginning with key } return $tree; } public static function getTree($organizationId) { if(!$organizationId) return array(); $tree = self::getGroupTree($organizationId); foreach($tree as &$group) $group['ITEMS'] = array(); unset($group); $result = ModifierListTable::getList(array( 'filter' => array('ORGANIZATION_ID'=>$organizationId), 'order' => array('SORT'=>'ASC'), )); while($item=$result->fetch()) { if(isset($item['GROUP_ID']) && array_key_exists($item['GROUP_ID'], $tree)) $tree[$item['GROUP_ID']]['ITEMS'][$item['ID']] = $item; else { $tree = array_reverse($tree, true); $tree[0] = array( 'ID' => 0, 'NAME' => Loc::getMessage('GRAIN_IIKO_MODIFIER_TREE_ROOT'), 'ORGANIZATION_ID' => $organizationId, 'GROUP_ID' => '', 'SORT' => 0, 'PARENT_GROUP_ID' => 0, 'ACTIVE' => 'Y', 'DELETED' => 'N', 'ITEMS' => array( $item['ID'] => $item, ), ); $tree = array_reverse($tree, true); } } return $tree; } private static function checkActiveAndGetData($iblockId,$modifierId) { $iblockId = intval($iblockId); if($iblockId<=0) return false; static $store = array(); if(!array_key_exists($iblockId, $store)) { $store[$iblockId] = array(); if($restaurant = Restaurants::getRestaurantByProductIblockId($iblockId)) { $tree = self::getTree($restaurant['XML_ID']); foreach($tree as $group) { if($group['ACTIVE']!='Y') continue; foreach($group['ITEMS'] as $item) { if($item['ACTIVE']!='Y') continue; $itemData = array('images'=>array()); $rsModifierImage = ModifierImageTable::getList(array( 'filter' => array( 'MODIFIER_ID' => $item['ID'], ), 'order' => array( 'SORT' => 'ASC', ), )); while($modifierImage=$rsModifierImage->fetch()) { if(!$file=\CFile::GetFileArray($modifierImage['FILE_ID'])) continue; $itemData['images'][] = $file; } $store[$iblockId][$item['MODIFIER_ID']] = $itemData; } } } } return array_key_exists($modifierId,$store[$iblockId])?$store[$iblockId][$modifierId]:false; } private static function isModifierActive($iblockId,$modifierId) { $iblockId = intval($iblockId); if($iblockId<=0) return false; static $store = array(); if(!array_key_exists($iblockId, $store)) { $store[$iblockId] = array(); if($restaurant = Restaurants::getRestaurantByProductIblockId($iblockId)) { $tree = self::getTree($restaurant['XML_ID']); foreach($tree as $group) { if($group['ACTIVE']!='Y') continue; foreach($group['ITEMS'] as $item) { if($item['ACTIVE']!='Y') continue; $store[$iblockId][] = $item['MODIFIER_ID']; } } } } return in_array($modifierId,$store[$iblockId]); } public static function getRequired($productId) { $modifiersAll = self::get($productId); $groupIdAlreadyAdded = array(); $modifiers = array(); foreach($modifiersAll as $modifier) { if($modifier['required']) { $modifiers[] = array( "id" => $modifier['id'], "name" => $modifier['m']['name'], "amount" => $modifier['minAmount']>0?$modifier['minAmount']:1, "price" => $modifier['m']['price'], ); if($modifier['groupId']) $groupIdAlreadyAdded[] = $modifier['groupId']; } elseif($modifier['groupRequired'] && !in_array($modifier['groupId'],$groupIdAlreadyAdded)) { $minAmount = $modifier['groupMinAmount']; if($modifier['minAmount']>$minAmount) $minAmount = $modifier['minAmount']; if($minAmount<=0) $minAmount = 1; $groupIdAlreadyAdded[] = $modifier['groupId']; $modifiers[] = array( "id" => $modifier['id'], "name" => $modifier['m']['name'], "amount" => $minAmount, "price" => floatval($modifier['m']['price']), ); } } return $modifiers; } public static function getRequiredSelected($productId) { $modifiers = static::get($productId); $idToAmount = array(); foreach(static::getRequired($productId) as $requiredModifier) $idToAmount[$requiredModifier['id']] = $requiredModifier['amount']; foreach($modifiers as &$modifier) $modifier['selected'] = array_key_exists($modifier['id'], $idToAmount)?$idToAmount[$modifier['id']]:0; unset($modifier); return $modifiers; } public static function getRequiredModifierProps($productId) { $props = array(); $modifiers = self::getRequired($productId); foreach($modifiers as $modifier) { $props[] = array( "NAME" => $modifier['name'], "CODE" => self::basketPropPrefix.$modifier['id'], "VALUE" => $modifier['amount'], "SORT" => "100", ); } return $props; } public static function getRequiredModifiersPrice($productId) { $price = 0.0; $modifiers = self::getRequired($productId); foreach($modifiers as $modifier) $price += $modifier['price']; return $price; } public static function compact($productModifiersFull) { $modifiers = array(); if(!is_array($productModifiersFull)) return array(); foreach($productModifiersFull as $modifierFull) { $newItem = array( 'name' => isset($modifierFull['m']['name'])?$modifierFull['m']['name']:'', 'price' => isset($modifierFull['m']['price'])?floatval($modifierFull['m']['price']):0, 'weight' => isset($modifierFull['m']['weight'])?floatval($modifierFull['m']['weight']):0, ); if(isset($modifierFull['minAmount'])) $newItem['minAmount'] = $modifierFull['minAmount']; if(isset($modifierFull['maxAmount'])) $newItem['maxAmount'] = $modifierFull['maxAmount']; if(isset($modifierFull['required'])) $newItem['required'] = $modifierFull['required']; if(isset($modifierFull['groupId'])) $newItem['groupId'] = $modifierFull['groupId']; if(isset($modifierFull['groupName'])) $newItem['groupName'] = $modifierFull['groupName']; if(isset($modifierFull['groupRequired'])) $newItem['groupRequired'] = $modifierFull['groupRequired']; if(isset($modifierFull['groupMinAmount'])) $newItem['groupMinAmount'] = $modifierFull['groupMinAmount']; if(isset($modifierFull['groupMaxAmount'])) $newItem['groupMaxAmount'] = $modifierFull['groupMaxAmount']; $modifiers[$modifierFull['id']] = $newItem; } return $modifiers; } }