====== Скрыть товары и модификации товаров, которых нет на основном складе ======
===== Товары =====
Хотим скрыть товары, которых нет в наличии на текущем складе. Назначаем наблюдатель для события ''onBeforeRedeclaredShow'' класса ''Shop_Controller_Show'':
* В ''bootstrap.php'' добавляем код:// Идентификатор интернет-магазина
define('REGION_PRICES_SHOP_ID', 4);
// KAD: Скрываем товары, которых нет в наличии на текущем складе
Core_Event::attach('Shop_Controller_Show.onBeforeRedeclaredShow', array('Kad_Shop_Item_Observers_Hidenotavailableitems', 'onBeforeRedeclaredShow'));
* В директории ''/modules/kad/shop/item/observers/'' создаем файл ''hidenotavailableitems.php'' со следующим содержимым:getEntity()->id
)
&&
!$object->item
)
{
$oShop = Core_Entity::factory('Shop', REGION_PRICES_SHOP_ID);
$oCurrent_Warehouse = $oShop->Shop_Warehouses->getDefault();
// Вариант 1. Некорректный, но менее затратный вариант, в этом случае ярлыки товаров не будут
// проверяться на наличие на текущем складе, а будут выводится все время
$object->shopItems()
->queryBuilder()
->leftJoin('shop_warehouse_items', 'shop_warehouse_items.shop_item_id', '=', 'shop_items.id')
->open()
->where('shop_warehouse_items.count', '>', 0)
->where('shop_warehouse_items.shop_warehouse_id', '=', $oCurrentWarehouse->id)
->setOr()
->where('shop_items.shortcut_id', '!=', 0)
->close()
;
// // Вариант 2. Корректный, с LEFT JOIN, но более затратный, в этом случае все ярлыки будут корректно
// // обрабатываться условием наличия на складе. Данный вариант предусматривает сложное объединение таблиц через LEFT JOIN ... OR
// // и может выполняется значительное время, особенно на объемных интернет-магазинах
// $object->shopItems()
// ->queryBuilder()
// ->leftJoin('shop_warehouse_items', 'shop_warehouse_items.shop_item_id', '=', 'shop_items.id', array(
// array('OR' => array('shop_warehouse_items.shop_item_id', '=', Core_QueryBuilder::expression('`shop_items`.`shortcut_id`'))),
// )
// )
// ->where('shop_warehouse_items.count', '>', 0)
// ->where('AND' => array('shop_warehouse_items.shop_warehouse_id', '=', $oCurrentWarehouse->id))
// ;
// var_dump($object->shopItems()->queryBuilder()->build());
}
}
}
* Решение предусматривает обработку ярлыков, но с ними могут быть проблемы в интернет-магазинах с большим количеством товаров, из-за чего в наблюдателе предусмотрено два варианта выборки, один из них отбрасывает ярлыки при сравнении, а другой корректно обрабатывает их, но может выполняться значительно время (см. комментарии в наблюдателе).
===== Модификации =====
Хотим скрыть модификации товаров, которых нет в наличии на текущем складе. Назначаем наблюдатель для события ''onBeforeShowXmlModifications'' сущности ''shop_item'':
* В ''bootstrap.php'' добавляем код:// KAD: Скрываем товары, которых нет в наличии на текущем складе
Core_Event::attach('shop_item.onBeforeShowXmlModifications', array('Kad_Shop_Item_Observers_Hidenotavailablemods', 'onBeforeShowXmlModifications'));
* В директории ''/modules/kad/shop/item/observers/'' создаем файл ''hidenotavailablemods.php'' со следующим содержимым:shop_id
)
)
{
$oShop = Core_Entity::factory('Shop', REGION_PRICES_SHOP_ID);
$oCurrent_Warehouse = $oShop->Shop_Warehouses->getDefault();
$args[0]->queryBuilder()
->select('shop_items.*')
->leftJoin('shop_warehouse_items', 'shop_warehouse_items.shop_item_id', '=', 'shop_items.id', array(
array(
'AND' => array('shop_warehouse_items.shop_warehouse_id', '=', $oCurrent_Warehouse->id)
)
)
)
->where('shop_warehouse_items.count', '>', 0);
}
}
}
Константа ''REGION_PRICES_SHOP_ID'' задает идентификатор интернет-магазина, для которого хотим скрыть товары и модификации товаров.
Если наблюдатель не срабатывает на странице интернет-магазина, то возможно в ТДС используется класс, наследованный от ''Shop_Controller_Show'', например, с названием ''My_Shop_Controller_Show'', или другой. Для такого класса нужно назначить наблюдатель отдельно. В ''bootstrap.php'' добавляем код:
Core_Event::attach('My_Shop_Controller_Show.onBeforeRedeclaredShow', array('Kad_Shop_Item_Observers_Hidenotavailableitems', 'onBeforeRedeclaredShow'));