Заказчик поставил задачу:
Цитата:
товары (А), которые становятся модификациями для других товаров (Б), должны оставаться в своей группе, а под родительский товар (Б) в качестве модификации отправляется ярлык товара А. Также необходимо реализовать возможность добавления к товару модификации из товаров, находящихся в других группах товаров или разделах каталога (сейчас модификации товаров можно выбрать только в рамках одной текущей группы товаров)
Реализация:
1. В файл /bootstrap.php добавляем:
Core_Event::attach('Shop_Item_Controller_Edit.onBeforeExecute', array('Shop_Item_Controller_Observer', 'onBeforeExecute'));
Core_Event::attach('shop_item.onBeforeShowXmlModifications', array('Shop_Item_Observer', 'onBeforeShowXmlModifications'));
Core_Event::attach('Shop_Item_Controller_Edit.onBeforeApplyObjectProperty', array('Shop_Item_Controller_Observer', 'onBeforeApplyObjectProperty'));
2. Создаем файл /modules/shop/item/controller/observer.php
<?php
defined('HOSTCMS') || exit('HostCMS: access denied.');
/**
* Observer
*
* @package HostCMS
* @version 6.x
*/
class Shop_Item_Controller_Observer
{
static public function onBeforeExecute($object, $operation)
{
$model = $object->getObject();
if($model instanceof Shop_Item_Model) { // Если редактируется товар
// Получим id товара, который сейчас редактируется
$shopItemId = !empty($model->id) ? $model->id : null;
// Выберем из базы все товары
$oShop_Items = Core_Entity::factory('Shop_Item');
$oShop_Items
->queryBuilder()
->where('id', '!=', $shopItemId)
->setAnd()
->where('name', '!=', '')
->setAnd()
->where('modification_id', '=', '0')
->setAnd()
->where('shortcut_id', '=', '0')
->setAnd()
->where('active', '=', '1')
->clearOrderBy()->orderBy('name', 'ASC');
$aShop_Items = $oShop_Items->findAll();
$options = array('...');
foreach($aShop_Items as $oShop_Item) {
// Исключим из списка все модификации, что бы нельзя было сделать товар модификацией для модификации
$oShop_Items
->queryBuilder()
->clear()
->where('modification_id', '!=', '0')
->setAnd()
->where('shortcut_id', '=', $oShop_Item->id);
$aShopItemModifications = $oShop_Items->findAll();
if(!empty($aShopItemModifications[0])) {
continue;
}
$options[$oShop_Item->id] = $oShop_Item->name;
}
$oMainTab = $object->getTab('main'); // Получим содержимое основной вкладки
$oField = $oMainTab->getField('modification_id'); // Получим select с модификациями
$oField->options($options);
}
}
static public function onBeforeApplyObjectProperty($object, $controller)
{
$model = $object->getObject();
if($model instanceof Shop_Item_Model) { // Если редактируется товар
if(!empty($_POST['modification_id'])) {
// Удалим все ярлыки данного товара, которые являются модификациями
// Нужно для того, что бы товар мог быть модификацией лишь для одного товара
Core_QueryBuilder::delete('shop_items')
->open()
->where('shortcut_id', '=', $model->id)
->setAnd()
->where('modification_id', '!=', '0')
->close()
->setAnd()
->where('modification_id', '=', $model->id)
->execute();
$oNewItem = Core_Entity::factory('Shop_Item');
$oNewItem->shop_id = $model->shop_id;
$oNewItem->name = $model->name;
$oNewItem->shortcut_id = $model->id;
$oNewItem->modification_id = intval($_POST['modification_id']);
$oNewItem->save();
// Игнорируем стандартный обработчик HOSTCMS, который превращал товар в модификацию
$object->addSkipColumn('modification_id');
}
}
}
}
3. Создаем файл /modules/shop/item/observer.php
<?php
defined('HOSTCMS') || exit('HostCMS: access denied.');
/**
* Observer
*
* @package HostCMS
* @version 6.x
*/
class Shop_Item_Observer
{
/*
Задача состоит в том, что бы среди модификаций заменить ярлыки на настоящие товары
*/
public static function onBeforeShowXmlModifications($object, $modifications)
{
// Ищем среди модификаций товара ярлыки
$oCore_QueryBuilder_Select2 = Core_QueryBuilder::select('shortcut_id') // поле shortcut_id хранит id товара, на который указывает ярлык
->from('shop_items')
->where('modification_id', '=', $object->id)
->setAnd()
->where('shortcut_id', '!=', '0')
->setAnd()
->where('deleted', '=', '0');
$modifications[0]
->queryBuilder()
->clear() // Очищаем запрос
->select('*')
->from('shop_items')
->open()
->where('modification_id', '=', $object->id)
->setOr()
// Включаем в выборку "родителей" ярлыков
->where('id', 'IN', $oCore_QueryBuilder_Select2)
->close()
->setAnd()
// Исключаем из выборки сами ярлыки
->where('shortcut_id', '=', '0');
}
}