События (хуки)

Модератор
Re: События (хуки)
Пример вывода названия документа перед показом версии документа (с версии 6.0.5):
class Document_Version_Observer
{
   static public function onBeforeExecute($object, $args)
   {
      ?><h1><?php echo htmlspecialchars($object->Document->name)?></h1><?php
   }
}

// Add document_version observer
Core_Event::attach('document_version.onBeforeExecute', array('Document_Version_Observer', 'onBeforeExecute'));
Re: События (хуки)
Потребовалось выводить размеры изображений производителей магазина в XML, т.к. автоматически они туда не передаются. Пример реализации:

class Shop_Producer_Observer
{
   static public function onBeforeGetXml($object, $args)
   {
     $file_small_path = $object->getSmallFilePath();
     $file_large_path = $object->getLargeFilePath();     

      $file_small_size = Core_Image::getImageSize($file_small_path);
      if ($file_small_size) {
        $object
          ->addXmlTag('image_small_width', $file_small_size['width'])
          ->addXmlTag('image_small_height', $file_small_size['height']);
      }
     
      $file_large_size = Core_Image::getImageSize($file_large_path);
      if ($file_large_size) {
        $object
          ->addXmlTag('image_large_width', $file_large_size['width'])
          ->addXmlTag('image_large_height', $file_large_size['height']);
      }
   }
}


Вызов в bootstrap.php:
Core_Event::attach('shop_producer.onBeforeGetXml', array('Shop_Producer_Observer', 'onBeforeGetXml'));
Компания Оригинал - www.original2.ru
Модератор
Re: События (хуки)
original,
с Вашего позволения пару замечаний:
1. Получить полные пути к малому и большому изображению лучше методами getSmallFilePath() и getLargeFilePath()
2. addXmlTag() можно писать цепочкой:
$object
->addXmlTag('image_small_width', $file_small_size['width'])
->addXmlTag('image_small_height', $file_small_size['height']);
Re: События (хуки)
HostCMS, исправили.
Компания Оригинал - www.original2.ru
Re: События (хуки)
Такая проблема, пишу свой обработчик:

function foo($object, $args)
{
   $oNewTab = Core::factory('Admin_Form_Entity_Tab')->caption("Новая вкладка")->name('newtab');
   $exportYes = new Admin_Form_Entity_Checkbox();
   $exportYes
      ->value(1)
      ->caption("некийтекст")
      ->name("export")
   ;
   $oNewTab->add($exportYes);
   $object->addTabAfter($oNewTab, $object->getTab('main'));
}

Core_Event::attach('Shop_Item_Controller_Edit.onAfterSetObject', 'foo');
И планируется, что данная вкладка появится после вкладки "Основные", но она появляется перед вкладкой "Дополнительные", т.е. почти в конце.


Дело в том, что Ваш код по расфасовке вкладок выполняется после моего:

// Получаем стандартные вкладки
            $oMainTab = $this->getTab('main');
            $oAdditionalTab = $this->getTab('additional');

            // Добавляем новые вкладки
            $this->addTabAfter($oShopGroupDescriptionTab =
               Core::factory('Admin_Form_Entity_Tab')
               ->caption(Core::_('Shop_Group.tab_group_description'))
               ->name('Description'), $oMainTab);
            $this->addTabAfter($oShopGroupSeoTab = Core::factory('Admin_Form_Entity_Tab')
               ->caption(Core::_('Shop_Group.tab_group_seo'))
               ->name('SEO'), $oShopGroupDescriptionTab);
            $this->addTabAfter($oShopGroupImportExportTab =
               Core::factory('Admin_Form_Entity_Tab')
               ->caption(Core::_('Shop_Group.tab_yandex_market'))
               ->name('ImportExport'), $oShopGroupSeoTab);
и сдвигает мою вкладку в конец... пичалька
Re: События (хуки)
А где весь список событий узнать? Хотя бы просто список без комментариев?
Re: События (хуки)
mrspd,
в исходном коде
Модератор
Re: События (хуки)
repairmanjack,
если Вы посмотрите код Shop_Item_Controller_Edit, то увидите, что после вызова
parent::setObject($object);
идет как раз модификация формы и Вы, соответственно, добавляете свою вкладку после нужно поля, а наш стандартный код после Вашего добавления добавляет еще и свои вкладки после того же поля, соответственно Ваше смещается. Попробуйте навесить на onBeforeExecute.
mrspd, Вы можете посмотреть в коде системы, поискав по строке "Core_Event::notify". Обращаю внимание, что текущий список событий не является исчерпывающим и по согласованию мы можем добавить новые требуемые события.
Re: События (хуки)
На неделе пробовал поработать с событиями (хуками), делал отправку смс-уведомлений при поступлении заказа в магазине.
Пример реализации:
1. в bootstrap.php, после блока if (Core_Auth::logged()) {...} добавляем код:
Core_Event::attach('Shop_Payment_System_Handler.onAfterProcessOrder', array('Shop_Payment_System_Observer', 'onAfterProcessOrder'));

2. в modules\shop\payment\system\ добавляем файл observer.php, содержимое:
<?php

defined('HOSTCMS') || exit('HostCMS: access denied.');

/**
* Shop payment system observer
*
* @package HostCMS 6
* @version 6.x
* @author Hostmake LLC
* @copyright © 2005-2012 ООО "Хостмэйк" (Hostmake LLC), http://www.hostcms.ru
*/
class Shop_Payment_System_Observer
{
   static public function onAfterProcessOrder($object, $args)
   {
        if (SENDER) { //константа определяющая отправлять смс или нет
            
            $object = $object->getShopOrder();

            $oShopOrder = Core_Entity::factory('Shop_Order', $object->id);
            $oShop = $oShopOrder->Shop;
            $aShopOrderItems = $oShopOrder->Shop_Order_Items->findAll();
            
            $fShopOrderItemSum = 0.0;
            
            if(count($aShopOrderItems) > 0)
            {
                foreach ($aShopOrderItems as $oShopOrderItem)
                {
                    $sItemAmount = $oShopOrderItem->getAmount();
                    $fShopOrderItemSum += $sItemAmount;
                }
            }
            
            //здесь уже на основе API смс-провайдера отправляем смс.
            echo "id заказа: " . $object->id . "<br>";
            echo "время заказа: " . $object->datetime . "<br>";
            echo "сумма заказа: " . sprintf("%.2f", $fShopOrderItemSum) . " " . $oShop->Shop_Currency->name;
            
        }
   }
}

3. И самое главное, в файле modules\shop\payment\system\handler.php служба поддержка внесла множество изменений, которые вероятно будут доступны в следующих обновлениях.
Например: Core_Event::notify('Shop_Payment_System_Handler.onAfterProcessOrder', $this); и т.п.
Получить новый файл можно повторно установив обновление 6.0.5. Модератор.
Модератор
Re: События (хуки)
Ограничение способа оплаты в зависимости от выбранного типа доставки (доступно с версии 6.0.6 или после повторной установки обновления 6.0.5). Код вносится в блок "case 3:" типовой дин. страницы корзины:
// Форма оплаты
   case 3:
      $_SESSION['hostcmsOrder']['shop_delivery_condition_id'] = intval(Core_Array::getPost('shop_delivery_condition_id', 0));

      $Shop_Payment_System_Controller_Show = new Shop_Payment_System_Controller_Show($oShop);

      // -- ADD
      class Shop_Payment_System_Controller_Observer
      {
         static public function onBeforeShow($object, $args)
         {
            if (isset($_SESSION['hostcmsOrder']['shop_delivery_condition_id']))
            {
               // Условие доставки
               $shop_delivery_condition_id = $_SESSION['hostcmsOrder']['shop_delivery_condition_id'];
               
               $oShop_Delivery = Core_Entity::factory('Shop_Delivery_Condition', $shop_delivery_condition_id)->Shop_Delivery;
               
               // Если тип доставки имеет код 1
               if ($oShop_Delivery->id == 1)
               {
                  // Добавляем способ оплаты только "Робокасса"
                  $object->clearEntities()
                     ->addEntity(
                        Core_Entity::factory('Shop_Payment_System', 9)
                     );
               }
            }
         }
      }

      // Add observer
      Core_Event::attach('Shop_Payment_System_Controller_Show.onBeforeShow', array('Shop_Payment_System_Controller_Observer', 'onBeforeShow'));
      // -- /add


      $Shop_Payment_System_Controller_Show
         ->xsl(
            Core_Entity::factory('Xsl')->getByName(
               Core_Array::get(Core_Page::instance()->libParams, 'paymentSystemXsl')
            )
         )
         ->show();
   break;
Авторизация