Events in OpenCart

An article by our employee from his personal blog.









The article deals with OpenCart version> = 2.3, namely 2.3 and 3.0 are considered





The event system in OpenCart is interesting enough, it is not a predefined list of events. The interior of the engine is arranged in such a way that almost every controller method that responds to a specific route loads some files (other controllers, models, views, translations).





The OpenCart event system is generated events before and after loading the engine / module files.





For example, consider the controller admin / controller / catalog / product.php in which the index method will be called at the address /admin/index.php?route=catalog/product:





public function index() {
    $this->load->language('catalog/product');
 
    $this->document->setTitle($this->language->get('heading_title'));
 
    $this->load->model('catalog/product');
 
    $this->getList();
}
      
      



This method uses the loading of the translation file and the catalog / product model, and you can install your own handlers that change the data on both loading facts.





What events are there in OpenCart 2.3+?





As we defined earlier, there is no predefined list of events. However, the expected events can be found in the system / engine / loader.php file. $ this-> load is the Loader object.





Looking at the file, you can see that events are generated ($ this-> registry-> get ('event') -> trigger) when loading:





  • controllers





  • models





  • views





  • configs





  • translations





. OpenCart MVCl , 4 , , / . MVCl :





  • Model - , , admin/model  catalog/model





  • View - , /, admin/view  catalog/view





  • Controller -  ( , ), admin/controller  catalog/controller





  • language - , admin/language  catalog/language





 ( )  :





  • before -





  • after -





,  ( , )  .









, , , ajax ,  startup/router



, get  route



  action



   ( route).





,  startup/router



   $this-> load



,  before



, ,  null



,  after



 (c  admin/controller/startup/router.php



 OpenCart 3.0):





// Trigger the pre events
$result = $this->event->trigger('controller/' . $route . '/before', array(&$route, &$data));
 
if (!is_null($result)) {
    return $result;
}
 
// We dont want to use the loader class as it would make an controller callable.
$action = new Action($route);
 
// Any output needs to be another Action object.
$output = $action->execute($this->registry); 
 
// Trigger the post events
$result = $this->event->trigger('controller/' . $route . '/after', array(&$route, &$data, &$output));
 
if (!is_null($result)) {
    return $result;
}
 
return $output;
      
      



,





OpenCart 2.3+  before  after .





.





 before   null, ,      ,  null.  after   null  . ( //):





public function controller($route, $data = array()) {
  // Sanitize the call
  $route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route);
   
  // Keep the original trigger
  $trigger = $route;
   
  file_put_contents($_SERVER['DOCUMENT_ROOT']."/loader-controller.txt", $trigger."\n", FILE_APPEND);
   
  // Trigger the pre events
  $result = $this->registry->get('event')->trigger('controller/' . $trigger . '/before', array(&$route, &$data));
   
  // Make sure its only the last event that returns an output if required.
  if ($result != null && !$result instanceof Exception) {
    $output = $result;
  } else {
    $action = new Action($route);
    $output = $action->execute($this->registry, array(&$data));
  }
   
  // Trigger the post events
  $result = $this->registry->get('event')->trigger('controller/' . $trigger . '/after', array(&$route, &$data, &$output));
   
  if ($result && !$result instanceof Exception) {
    $output = $result;
  }
   
  if (!$output instanceof Exception) {
    return $output;
  }
  }
      
      



 before



  after



, .





 system/engine/event.php Event::trigger



 : -  ( before



  after



)   null, ( before



  after



).









(, , , ) .





, . MVCl :





  •  before : &$route  &$data





  •  after : &$route, &$data  &$output





 (  system/engine/loader.php):





  • &$route  ,  controller|view|model|language   before|after, ,  catalog/model/checkout/order/addOrderHistory/after  &$route  checkout/order/addOrderHistory





  • &$data   ( ), , tpl/twig





  • &$output   ( , ), ,





 &$data  tpl/twig .  &$output  ,  &$data  .  &$data  before  , . .





 &$output  after  , Simple Html DOM.





 &$data  before  , !





OpenCart





php  system/config/admin.php  system/config/catalog.php   $_['action_event'], , . , , * " ". " ".





OpenCart 3.0  ( , )  "" .





 ( )   event:





  • event_id - ()





  • code - , ,





  • trigger - , , admin/view/catalog/product_form/after -





  • action - ,  extension/module/productmarkedfield/eventProductFormAfter





  • status - (1/0)





  • sort_order - ( )





 





:





  •  ( install)





  •  ( uninstall)





, , !





, OpenCart 2.3  extension/event, OpenCart 3.0 setting/event.





,  $sort_order (  event  OpenCart 3.0):





public function addEvent($code, $trigger, $action, $status = 1, $sort_order = 0) {
    $this->db->query("INSERT INTO `" . DB_PREFIX . "event` SET `code` = '" . $this->db->escape($code) . "', `trigger` = '" . $this->db->escape($trigger) . "', `action` = '" . $this->db->escape($action) . "', `sort_order` = '" . (int)$sort_order . "', `status` = '" . (int)$status . "'");
 
    return $this->db->getLastId();
}
      
      



, .





:





  • code - ,





  • trigger - ,  admin/view/catalog/product_form/after





  • action - , , extension/module/productmarkedfield/eventProductFormAfter  , , ,





"Controller" . $sRelPath . $sFileName
      
      



 sRelPath  ,  sFileName  .  ControllerExtensionModuleProductmarkedfield





  • status - /,





  • sort_order - (OpenCart 3.0), , , 0





 trigger  action. trigger   ()   ( )   admin  catalog,  action  ,  admin  catalog. ,





  • trigger - admin/view/catalog/product_form/after, action - extension/module/productmarkedfield/eventProductFormAfter,  admin/controller/extension/module/productmarkedfield.php  ControllerExtensionModuleProductmarkedfield::eventProductFormAfter





  • trigger - catalog/model/checkout/order/addOrderHistory/after, action - extension/module/productmarkedfield/eventaddOrderHistoryAfter,  catalog/controller/extension/module/productmarkedfield.php  ControllerExtensionModuleProductmarkedfield::eventaddOrderHistoryAfter





/ ,     .





OpenCart 2.3 :





$this->load->model('extension/event');
 
// "   " -      (   )
$this->model_extension_event->addEvent(
  'productmarkedfield', // 
  'admin/view/catalog/product_form/after', // 
  'extension/module/productmarkedfield/eventProductFormAfter' //
      
      



  OpenCart 3.0 :





$this->load->model('setting/event');
 
// "   " -      (   )
$this->model_setting_event->addEvent(
  'productmarkedfield',
  'admin/view/catalog/product_form/after',
  'extension/module/productmarkedfield/eventProductFormAfter'
      
      



, !





system/engine/action.php Action::execute



   action



   Exception



:





$reflection = new ReflectionClass($class);
         
if ($reflection->hasMethod($this->method) && $reflection->getMethod($this->method)->getNumberOfRequiredParameters() <= count($args)) {
    return call_user_func_array(array($controller, $this->method), $args);
} else {
    return new \Exception('Error: Could not call ' . $this->route . '/' . $this->method . '!');
}
      
      







.





OpenCart 2.3  extension/event



  deleteEvent



   ( OpenCart 2.3):





public function deleteEvent($code) {
    $this->db->query("DELETE FROM `" . DB_PREFIX . "event` WHERE `code` = '" . $this->db->escape($code) . "'");
}
      
      



OpenCart 3.0 .  deleteEvent



  ,  deleteEventByCode



  ,  deleteEvent



  OpenCart 2.3 ( OpenCart 3.0):





public function deleteEvent($event_id) {
    $this->db->query("DELETE FROM `" . DB_PREFIX . "event` WHERE `event_id` = '" . (int)$event_id . "'");
}
 
public function deleteEventByCode($code) {
    $this->db->query("DELETE FROM `" . DB_PREFIX . "event` WHERE `code` = '" . $this->db->escape($code) . "'");
}
      
      



OpenCart 2.3 :





$this->load->model('extension/event');
$this->model_extension_event->deleteEvent('productmarkedfield');
      
      



OpenCart 3.0:





$this->load->model('setting/event');
$this->model_setting_event->deleteEvent('productmarkedfield');
      
      







The OpenCart event system is quite interesting, it allows a lot and is flexible, but not without drawbacks. Most confusing is the fact that to change the interface (view load events), you need to manually work with the DOM.





To understand the content of the event arguments, you need to examine the source code of the loaded files, and in the case of views, you also need to examine the controller that passes data to that view. However, over time, this fact grows from "disadvantage to dignity" revealing the beauty of the OpenCart engine.









Author: Vitaly Buturlin





A source








All Articles