И так, триггер (trigger) в CMS Joomla - это некий обработчик или событие, позволяющее работать с данными в определенный момент выполнения сценария web-приложения. В данной статье, я приведу кусочки кода и демонстрационный пример, как можно создавать свои обработчики и использовать их в своих плагинах, расширяя функционал компонента не влезая в его код.  

     Наверняка при разработке плагинов вы уже встречали системные, контентые и прочие события, к примеру для использования коротких кодов {shortcodes} в статьях для корректировки, скрытия или вывода некой информации. В данном примере мы будем создавать собственное событие, но только для своих компонентов.

     Представим, что у нас есть компонент (скачать можно в конце статьи) формирующий некую форму, предназначенную для заполнения пользователями веб-сайта.

 1

      Обратите внимание на выделенные слова "МОЛОТОК" и "ЛОМ", данные так называемые "стоп" слова мы в плагине с помощью триггера и будем обрабатывать перед сохранением формы в базу данных. 

      Постараюсь кратко рассказать как формируются триггеры в компонентах, за их создание, используется класс "JEventDispatcher" - это класс отвечающий за обработку событий. Предлагаю наглядно посмотреть на примере кода из контроллера, обратите внимание на строки 34, 36, 103, их я отдельно прокомментировал:

  1. // No direct access
  2. defined( '_JEXEC' ) or die;
  3.  
  4. /**
  5.  * Controller
  6.  * @author Korotkov Vadim
  7.  */
  8. class TesttriggerControllerCreate extends JControllerForm
  9. {
  10.  
  11.           /**
  12.           * Class constructor
  13.           * @param array $config
  14.           */
  15.          function __construct( $config = array() )
  16.          {
  17.                 $this->view_list = 'create';
  18.                 parent::__construct( $config );
  19.          }
  20.  
  21.         public function save($key = null, $urlVar = null) {
  22.        
  23.         // Check for request forgeries.
  24.         JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
  25.  
  26.         $app   = JFactory::getApplication();
  27.         $model = $this->getModel();
  28.         $table = $model->getTable();
  29.         $data  = $this->input->post->get('jform', array(), 'array');
  30.         $context = "$this->option.edit.$this->context";
  31.  
  32.         // Test init trigger plugins
  33.         // мы подгружаем файлы нашего плагина
  34.         JPluginHelper::importPlugin('test');
  35.         // инициализируем класс диспетчера
  36.         $dispatcher = JEventDispatcher::getInstance(); 
  37.  
  38.         // Determine the name of the primary key for the data.
  39.        if (empty($key))
  40.        {
  41.               $key = $table->getKeyName();
  42.        }
  43.  
  44.        // To avoid data collisions the urlVar may be different from the primary key.
  45.        if (empty($urlVar))
  46.        {
  47.                $urlVar = $key;
  48.        }
  49.  
  50.        $recordId = $this->input->getInt($urlVar);
  51.  
  52.        // Populate the row id from the session.
  53.        $data[$key] = $recordId;
  54.  
  55.        // Validate the posted data.
  56.        // Sometimes the form needs some posted data, such as for plugins and modules.
  57.        $form = $model->getForm($data, false);
  58.  
  59.        if (!$form)
  60.        {
  61.               $app->enqueueMessage($model->getError(), 'error');
  62.               return false;
  63.        }
  64.  
  65.        // Test whether the data is valid.
  66.        $validData = $model->validate($form, $data);
  67.  
  68.        // Check for validation errors.
  69.        if ($validData === false)
  70.        {
  71.               // Get the validation messages.
  72.               $errors = $model->getErrors();
  73.  
  74.               // Push up to three validation messages out to the user.
  75.               for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++)
  76.               {
  77.                      if ($errors[$i] instanceof Exception)
  78.                      {
  79.                             $app->enqueueMessage($errors[$i]->getMessage(), 'warning');
  80.                      }
  81.                      else
  82.                      {
  83.                      $app->enqueueMessage($errors[$i], 'warning');
  84.                      }
  85.               }
  86.  
  87.        // Save the data in the session.
  88.        $app->setUserState($context . '.data', $data);
  89.  
  90.        // Redirect back to the edit screen.
  91.        $this->setRedirect(
  92.               JRoute::_(
  93.                      'index.php?option=' . $this->option . '&view=' . $this->view_item
  94.                      . $this->getRedirectToItemAppend($recordId, $urlVar), false
  95.               )
  96.        );
  97.  
  98.        return false;
  99.        }
  100.  
  101.        // Passed Validation: Process the test plugins to integrate with other applications
  102.        // используем событие плагина
  103.        $dispatcher->trigger('onSaveTest', array(&$validData)); 
  104.  
  105.        // Attempt to save the data.
  106.        if (!$model->save($validData))
  107.        {
  108.               // Save the data in the session.
  109.               $app->setUserState($context . '.data', $validData);
  110.  
  111.               // Redirect back to the edit screen.
  112.               $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()));
  113.               $this->setMessage($this->getError(), 'error');
  114.  
  115.               $this->setRedirect(
  116.                      JRoute::_(
  117.                             'index.php?option=' . $this->option . '&view=' . $this->view_item
  118.                             . $this->getRedirectToItemAppend($recordId, $urlVar), false
  119.                      )
  120.               );
  121.  
  122.               return false;
  123.        }
  124.  
  125.        $langKey = $this->text_prefix . ($recordId == 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS';
  126.        $prefix  = JFactory::getLanguage()->hasKey($langKey) ? $this->text_prefix : 'JLIB_APPLICATION';
  127.  
  128.        $this->setMessage(JText::_($prefix . ($recordId == 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS'));
  129.  
  130.        // Clear the record id and data from the session.
  131.        $this->releaseEditId($context, $recordId);
  132.        $app->setUserState($context . '.data', null);
  133.  
  134.        $url = 'index.php?option=' . $this->option . '&view=' . $this->view_list
  135.        . $this->getRedirectToListAppend();
  136.  
  137.        // Check if there is a return value
  138.        $return = $this->input->get('return', null, 'base64');
  139.  
  140.        if (!is_null($return) && JUri::isInternal(base64_decode($return)))
  141.        {
  142.               $url = base64_decode($return);
  143.        }
  144.  
  145.        // Redirect to the list screen.
  146.        $this->setRedirect(JRoute::_($url, false));
  147.  
  148.  
  149.        // Invoke the postSave method to allow for the child class to access the model.
  150.        $this->postSaveHook($model, $validData);
  151.  
  152.        return true;
  153.     }
  154.  
  155. }

      В данном контроллере создавая диспетчер для события 'onSaveTest' (это будет наименование метода в плагине), мы передаем данные в плагин из приходящей формы, где и будем их обрабатывать, в случае необходимости. Стоит так же обратить внимание на вызов метода  JPluginHelper::importPlugin('test');, тут мы подгружаем файлы плагина не стандартного типа/группы 'test', т.е. явно даем понять, что будем использовать в плагине собственные события.

     Для примера я разработал плагин (скачать можно в конце статьи) позволяющий удалять слова которые будут указаны в настройках:

plg

     Исходный кода плагина с событием 'onSaveTest':

  1. /**
  2.  * @package     Joomla.Plugin
  3.  * @subpackage  Test.Testtrigger
  4.  *
  5.  * @copyright   Copyright (C) 2017 Korotkov Vadim. http://siterybinsk.ru/ All rights reserved.
  6.  * @license     GNU General Public License version 2 or later; see LICENSE.txt
  7.  */
  8.  
  9. defined ( '_JEXEC' ) or  die ;
  10.  
  11. /**
  12.  * An example custom profile plugin.
  13.  *
  14.  * @since  1.6
  15.  */
  16. class PlgTestTesttrigger  extends JPlugin
  17. {
  18.  
  19.      /**
  20.       * Load the language file on instantiation.
  21.       *
  22.       * @var    boolean
  23.       * @since  3.1
  24.       */
  25.      protected  $autoloadLanguage  =  true ;
  26.  
  27.      /**
  28.       * Constructor
  29.       *
  30.       * @param   object  &$subject  The object to observe
  31.       * @param   array   $config    An array that holds the plugin configuration
  32.       *
  33.       * @since   1.5
  34.       */
  35.      public  function __construct ( & $subject ,  $config )
  36.      {
  37.            parent ::__construct ( $subject ,  $config ) ;
  38.      }
  39.  
  40.      /**
  41.       * This event is triggered after form has been submitted
  42.       *
  43.       * @param   mixed     $data        The associated data for the form.
  44.       *
  45.       * @return  boolean
  46.       *
  47.       * @since   1.6
  48.       */
  49.      public  function onSaveTest ( & $data )  {
  50.  
  51.          $stopWord  =  $this -> params -> get ( 'remove_fulltext' ,  '' ) ;
  52.  
  53.          $arrStopWord  =  array ( ) ;
  54.          $arrStopWord  =  array_map ( 'trim' ,  explode ( ',' ,  $stopWord ) ) ;
  55.  
  56.          $data [ 'fulltext' ]  =  $this -> replace ( $arrStopWord ,  $data [ 'fulltext' ] ) ;
  57.  
  58.          return  null ;
  59.  
  60.      }
  61.  
  62.      private  function replace ( $arrStopWord  =  array ( ) ,  $fulltext  =  '' )  {
  63.  
  64.          if (  ! empty ( $arrStopWord )  )  {
  65.              foreach (  $arrStopWord  as  $word  )  {
  66.                  $fulltext  =  preg_replace ( "/{$word}/ui" , JText ::_ ( 'PLG_TEST_TESTTRIGGER_CENSOR' ) ,  $fulltext ) ;
  67.              }
  68.          }
  69.  
  70.          return  $fulltext ;
  71.  
  72.      }
  73.  
  74. }
  75.  

В итоге после обработки данных мы получим вот такой результат:

2

Т.е. слова: 'молоток' и 'лом' успешно были заменены.

Собственно ничего сложного в данной конструкции и реализации нет, а польза от использования триггеров, в Вашем компоненте значительно упростит и ускорит обработку данных в определенных местах, без его правки исходного кода.

Скачать установочные файлы:

zip
Компонент com_testtrigger (размер: 33.68 kb, скачиваний: 4)
Тестирование проводилось на CMS joomla 3.7.5, PHP 7.1.5
zip
Плагин для компонента com_testtrigger (размер: 3.09 kb, скачиваний: 4)
Тестирование проводилось на CMS joomla 3.7.5, PHP 7.1.5
Просто поддержать нас
Создание сайтов

Читайте также:

Полезное из Web