Хуки в формах администрирования Интернет-магазина

#
Re: Хуки в формах администрирования Интернет-магазина
В общем, разобрался со всем)
Целью данного хука является кастомизации форм центра администрирования: перемещение полей между вкладками и скрытие ненужных полей и вкладок.
Если что не верно или криво написано - поправьте. Но все работает как надо!

Для работы создаем файл observer.php в папке /modules/admin/form/action/controller/type/edit/ и размещаем в нем следующий код:
<?php
defined('HOSTCMS') || exit('HostCMS: access denied.');
/**
* Observer
*
* @package HostCMS
* @version 6.x
* @author Hostmake LLC
* @copyright © 2005-2015 ООО "Хостмэйк" (Hostmake LLC), http://www.hostcms.ru
*/

class Admin_Form_Action_Controller_Type_Edit_Observer
{
    static public function onBeforeExecute($controller, $args)
    {
        list($operation, $Admin_Form_Controller) = $args;

        if (is_null($operation))
        {
            switch (get_class($controller))
            {
                case 'Shop_Item_Controller_Edit': //Интернет магазин

                    switch (get_class($controller->getObject()))
                    {
                        case 'Shop_Item_Model': //Товар
                           //ОСНОВНОЙ КОД
                        break;
                    }
                break;
            }
        }
    }
}

Для примера я взял форму редактирования для товара интернет-магазина. По аналогии с примером можно сделать обработчики для других форм центра администрирования.

В файл bootstrap.php, который лежит в корне сайта, добавляем хук
Core_Event::attach('Admin_Form_Action_Controller_Type_Edit.onBeforeExecute', array('Admin_Form_Action_Controller_Type_Edit_Observer', 'onBeforeExecute'));


Теперь основной код по блокам:
1. Получаем все вкладки формы и записываем их в переменные, с которыми и будем работать
$oMainTab = $controller->getTab('main'); //Основные
$oDescriptionTab = $controller->getTab('Description'); //Описание
$oExportImportTab = $controller->getTab('ExportImport'); //Экспорт/Импорт
$oAssociatedsTab = $controller->getTab('Associateds'); //Сопутствующие
$oPropertyTab = $controller->getTab('Property'); //Доп. св-ва
$oAdditionalTab = $controller->getTab('additional'); //Дополнительные


2. Срытие вкладки
$oAssociatedsTab->active(0);


3. Скрытие поля (работает не для всех полей!)
$controller->getField('length')->divAttr(array('style' => 'display:none'));


Т.к. скрытие работает далеко не для всех полей, то выходом из положения является создание новой вкладки и перемещение на нее нужных для отображения данных, и скрытие остальных вкладок. Код приведен ниже.

4. Создание новой вкладки
$oAdmin_Form_Tab_Entity = Admin_Form_Entity::factory('Tab')
    ->name('home')
    ->caption('Общие');

$controller->addTabBefore($oAdmin_Form_Tab_Entity, $oMainTab); //Размещаем вкладку перед вкладкой "Основные"
$oHomeTab = $controller->getTab('home'); //Сохраняем в переменную


Если просто перенести поле на новую пустую вкладку - то тогда слетят стили, и все будет криво. Поэтому делаем следующий трюк:

5. Перенос первого поля на новую пустую вкладку (для примера взято поле Название товара)
$aFields = $oMainTab->getFields();
foreach ($aFields as $aField){
    $aChilds=$aField->getChildren();
    (count($aChilds)>0) && isset($aChilds[0]->name) && ($aChilds[0]->name=='name') && $oMainTab->move($aField,$oHomeTab);
}


6. Перенос простых полей с других вкладок
$oAdditionalTab->moveAfter($controller->getField('shop_id'), $controller->getField('name'), $oHomeTab); //Поле id с вкладки Дополнительные


Но, к примеру, поле image просто так не перенесешь. Поэтому пример ниже

7. Перенос простых И сложных полей с вкладки Основные
$aMoveFields = array( //Массив названий полей, которые надо перенести на новую вкладку
   'image',
    'path',
    //'image_small_height',
    //'image_small_width',
    //'image_large_height',
    //'image_large_width',
    'shop_group_id', //Группа
    'shortcut_group_id[]', //Доп.группа
    //'modification_id', //Модификация для товара
    //'type',
    'datetime',
    //'start_datetime',
    //'end_datetime',
    //'showed', //Счетчик показов
    //'marking', //Артикул
    'weight',
    'shop_measure_id',
    //'tags[]',
    //'shop_producer_id', //Производитель
    //'siteuser_group_id', //Группа доступа
    //'shop_seller_id', //Продавец
    'indexing',
    'active',
    //'apply_purchase_discount', //Учитывать для скидки от суммы заказа
    //'length',
    //'width',
    //'height',
    'sorting'
    );

foreach (array_reverse($oMainTab->getFields()) as $oField) //Перебор полей
{
    foreach (array_reverse($oField->getChildren()) as $aChild)
    {
        if (isset($aChild->name) && in_array($aChild->name, $aMoveFields))
        {
            switch ($aChild->name) //Дополнительная обработка полей
            {
                case 'shop_group_id': //Группа
                    $aChild->divAttr(array('class' => 'form-group col-xs-12 col-sm-4')); //Размер
                    $aChild->filter(0); //Скрываем фильтр по полю
                    break;
                case 'shortcut_group_id[]': //Доп.группа
                    $aChild->divAttr(array('class' => 'form-group col-xs-12 col-sm-8')); //Размер
                    break;
            }
            $oMainTab->moveAfter($aChild, $controller->getField('name'), $oHomeTab);
        }
    }
}


8. Поле Цены переносим отдельно, сохраняя его вид и формат
$aFields = $oMainTab->getFields();
foreach ($aFields as $key => $oField)
{
    $aChilds=$oField->getChildren();
    if (isset($aChilds[1]))
    {
        $aChildsOther=$aChilds[1]->getChildren();
        isset($aChildsOther[0]->name) && ($aChildsOther[0]->name=='price') && $oMainTab->move($oField,$oHomeTab);
    }
}


9. Перенос всех полей с одной вкладки на другую
foreach ($oPropertyTab->getFields() as $aField) //Переносим доп. свойства на вкладку Описание
{
    $oPropertyTab->move($aField, $oDescriptionTab);
}


10. Переименование поля
$controller->getField('path')->caption('Путь(url)');


Вот, вроде, и все) Мы кастомизировали форму, как нам надо. Полный код файла observer.php ниже.
Что бы кастомизировать форму только для конкретного каталога, можно добавить условие проверки id магазина $controller->getField('shop_id'->value;

<?php
defined('HOSTCMS') || exit('HostCMS: access denied.');
/**
* Observer
*
* @package HostCMS
* @version 6.x
* @author Hostmake LLC
* @copyright © 2005-2015 ООО "Хостмэйк" (Hostmake LLC), http://www.hostcms.ru
*/

class Admin_Form_Action_Controller_Type_Edit_Observer
{
    static public function onBeforeExecute($controller, $args)
    {
        list($operation, $Admin_Form_Controller) = $args;

        if (is_null($operation))
        {
            switch (get_class($controller))
            {
                case 'Shop_Item_Controller_Edit': //Интернет магазин

                    switch (get_class($controller->getObject()))
                    {
                        case 'Shop_Item_Model': //Товар

                            /*Узнаем id магазина (если надо)*/
                            //$aShopId=$controller->getField('shop_id')->value;

                            /*Табы*/
                            $oMainTab = $controller->getTab('main'); //Основные
                            $oDescriptionTab = $controller->getTab('Description'); //Описание
                            $oExportImportTab = $controller->getTab('ExportImport'); //Экспорт/Импорт
                            $oAssociatedsTab = $controller->getTab('Associateds'); //Сопутствующие
                            $oPropertyTab = $controller->getTab('Property'); //Доп. св-ва
                            $oAdditionalTab = $controller->getTab('additional'); //Дополнительные


                            /*Создание новой вкладки*/
                            $oAdmin_Form_Tab_Entity = Admin_Form_Entity::factory('Tab')
                                ->name('home')
                                ->caption('Общие');

                            $controller->addTabBefore($oAdmin_Form_Tab_Entity, $oMainTab); //Размещаем вкладку перед вкладкой "Основные"
                            $oHomeTab = $controller->getTab('home'); //Сохраняем в переменную


                            /*Перенос первого поля*/
                            $aFields = $oMainTab->getFields();
                            foreach ($aFields as $aField){
                                $aChilds=$aField->getChildren();
                                (count($aChilds)>0) && isset($aChilds[0]->name) && ($aChilds[0]->name=='name') && $oMainTab->move($aField,$oHomeTab);
                            }


                            /*Перенос полей с др вкладок*/
                            $oAdditionalTab->moveAfter($controller->getField('shop_id'), $controller->getField('name'), $oHomeTab); //Поле id с вкладки Дополнительные


                            /*Переименование поля*/
                            $controller->getField('path')->caption('Путь(url)');


                            /*Перенос полей с вкладки Основные*/
                            $aMoveFields = array( //Массив названий полей, которые надо перенести на новую вкладку
                                'image',
                                'path',
                                //'image_small_height',
                                //'image_small_width',
                                //'image_large_height',
                                //'image_large_width',
                                'shop_group_id', //Группа
                                'shortcut_group_id[]', //Доп.группа
                                //'modification_id', //Модификация для товара
                                //'type',
                                'datetime',
                                //'start_datetime',
                                //'end_datetime',
                                //'showed', //Счетчик показов
                                //'marking', //Артикул
                                'weight',
                                'shop_measure_id',
                                //'tags[]',
                                //'shop_producer_id', //Производитель
                                //'siteuser_group_id', //Группа доступа
                                //'shop_seller_id', //Продавец
                                'indexing',
                                'active',
                                //'apply_purchase_discount', //Учитывать для скидки от суммы заказа
                                //'length',
                                //'width',
                                //'height',
                                'sorting'
                                );

                            foreach (array_reverse($oMainTab->getFields()) as $oField) //Перебор полей
                            {
                                foreach (array_reverse($oField->getChildren()) as $aChild)
                                {
                                    if (isset($aChild->name) && in_array($aChild->name, $aMoveFields))
                                    {
                                        switch ($aChild->name) //Дополнительная обработка полей
                                        {
                                            case 'shop_group_id': //Группа
                                                $aChild->divAttr(array('class' => 'form-group col-xs-12 col-sm-4')); //Размер
                                                $aChild->filter(0); //Скрываем фильтр по полю
                                                break;
                                            case 'shortcut_group_id[]': //Доп.группа
                                                $aChild->divAttr(array('class' => 'form-group col-xs-12 col-sm-8')); //Размер
                                                break;
                                        }
                                        $oMainTab->moveAfter($aChild, $controller->getField('name'), $oHomeTab);
                                    }
                                }
                            }              


                            /*Перенос цен*/
                            $aFields = $oMainTab->getFields();
                            foreach ($aFields as $key => $oField)
                            {
                                $aChilds=$oField->getChildren();
                                if (isset($aChilds[1]))
                                {
                                    $aChildsOther=$aChilds[1]->getChildren();
                                    isset($aChildsOther[0]->name) && ($aChildsOther[0]->name=='price') && $oMainTab->move($oField,$oHomeTab);
                                }
                            }


                            /*Поля Скрываются*/
                            //$controller->getField('length')->divAttr(array('style' => 'display:none'));
                                

                            /*Перенос всех полей с одной вкладки на другую*/
                            foreach ($oPropertyTab->getFields() as $aField) //Переносим доп. свойства на вкладку Описание
                            {
                                $oPropertyTab->move($aField, $oDescriptionTab);
                            }


                            /*Скрытие вкладок*/
                            $oMainTab->active(0);
                            $oAssociatedsTab->active(0);
                            $oAdditionalTab->active(0);
                            $oPropertyTab->active(0);

                        break;
                    }
                break;
            }
        }
    }
}
Авторизация