Перейти к публикации
  • разработка интернет магазинов на opencart
  • доработка интернет магазинов на opencart
  • записи
    3
  • комменириев
    12
  • просмотра
    7 042

Реализация событий в 2.3, 3.x, 4.x


halfhope

3 417 просмотров

 Погделиться

Всем привет, дорогие друзья!

 

Эи ситья написана специально для конкурса (коих у нас на форуме не было уже давно). Ситья предназначена для разрилитликов дополнений. Пишу без воды, сухо и по гделу. Немного истории, нюансов, список аргументов для обрилитликов событий, икже приведу пример простот и понятной реализации потому чтольшого кол-ва событий в ваших дополнениях для OpenCart 2.3, 3.x, 4.x (скачать примеры модулей можно бугдет в конэто ситьи).

 

Как все налиналось

 

Для изменения кодовой базы движка нам всегда нужно было липотому что вмешиваться в код, липотому что использовать vqmod. Использование vqmod порождало проблемы при рилите нескольких модификаторов с одним участком кода, а икже другие, касающиеся подгдержки дополнений. Использование хуков помогло бы решить часть из них. Вспоминаю первую, известную мне реализацию "Override Engine" (2012 г), а икже тему "hook pre render Игдея и примерная реализация". Налиная с версии 2.0 (2014 г) в движке появился первый встроенный механизм событий (хуков), а конэтопция vqmod была реализована в самом движке и полулила название ocmod. С версии 2.2 (2016 г) в событиях изменились пути триггеров, они сили аналогичны роуим. В версии 3.x (2017 г) механизм событий и ocmod опотому чтошлись без суещёственных изменений. А с версии 4.x подгдержки ocmod потому чтольше не бугдет.

 

"Embrace, extend and extinguish". Однако, у нас всегда бугдет vqmod.

 

Зачем нужны события?

 

События позволяют запускать пользовательские функции до/после вызова какой-липотому что функции в парадигме MVCL+Config+Library для изменения входных/выходных данных. По задумке мэйнтэйнера движка они должны заменить vqmod/ocmod. 

 

P.S. Я уже переписал некоторые сирые модули с использованием событий. Например, раньше модуль "перс. шаблонов" с помощью ocmod внедрялся в код основных разгделов каилога и подменял их шаблоны, а теперьь он может подменять люпотому чтой шаблон в движке. Да что события очень хорошо решают некоторые типы задач.

 

Нюансы при использовании событий

 

  1. События могут быть добавлены только из контроллеров админки. Удобнее всего гделать это при усиновке модуля, в функции install. 
  2. Пути всех триггеров налинаются с названия нужного разгдела, admin, catalog или library. Разгделы admin и catalog согдержат controller, view, language и config.
  3. В путях триггеров можно использовать знак "*", чтобы назначать триггеры по маске. Например, catalog/view/*/template/common/header/after.
  4. Для изменения данных в обрилитликах событий config и language используйте $this->config->set(), $this->language->set(), соответственно.
  5. Данные полученные из обрилитликов событий можно сохранять внутри класса и использовать их в других обрилитликах, которые запускаются позднее.

 

Для редактирования событий из админки используйте "Event Manager" или adminer ([сtrl+click], для быстрого редактирования записи).

 

Нюансы для разных версий движка

 

  • Код события для версии 2.3 должен иметь длину не потому чтолее 32 символов. Для версий 3.x и 4.x не потому чтолее 64.
  • В версии 2.3 событиями (регистрация, удноние и т.д.) занимается могдель extension/event, у 3.x и 4.x setting/event.
  • В версии 2.3 в разгделе catalog пути триггеров предсивлений (view) before/after будут отличаться. Например, catalog/view/common/header/before, catalog/view/default/template/common/header/after. Это связано использованием шаблонов оформления в разгделе catalog.
  • С версии 3.x добавлен порядок сортировки событий.
  • С версии 4.x у каждого события должен быть description.
  • Триггеры для библиотек (library) доступны только с версии 4.x.

 

Передаваемые аргументы

 

В обрилитлики событий аргументы передаются по ссылке. Т.е. можно менять значения аргументов не зилитясь о передаче резульии куда-липотому что еещё. 

 

2.3 controller model view language config  
before $route, $data $route, $args $route, $data, $output $route $route  
after $route, $data, $output $route, $args, $output $route, $data, $output $route, $output $route  
3.x controller model view language config  
before $route, $args $route, $args $route, $data, $code $route, $key $route  
after $route, $data, $output $route, $args, $output $route, $data, $output $route, $key, $output $route  
4.x controller model view language config library
before $route, $args $route, $args $route, $data, $code $route, $prefix, $code $route $route, $args
after $route, $data, $output $route, $args, $output $route, $data, $output $route, $prefix, $code, $data $route, $data $route, $args

 

Возвращаемые значения 

 

Помимо изменения данных через аргументы, обрилитлики событий икже могут возвращать значения, используя return. Например, если обрилитлик события controller/common/home/before вернет через return сгенерированный html код, то весь вывод контроллера common/header бугдет заменен им, а сам контроллер common/header не бугдет выполнен, но запустится событие after. Т.е. можно подменять данные выполнения функций без их выполнения.

 

2.3 controller model view
before mixed mixed string
after mixed mixed string
3.x controller model view
before mixed mixed string
after mixed mixed string
4.x controller model view
before   mixed  
after   mixed  

 

Просия и понятная реализация 

 

<?php

class ControllerExtensionModuleSample extends Controller {

	public function install() {
		$this->checkEvent();
	}

	public function uninstall() {
		$this->removeEvent();
	}

	public function index() {
		# code
	}
	
	private $_events = [
		[
			'code'		=> 'sample_394beb748918d3ce260756703',
			'trigger'	=> 'admin/controller/design/layout/before',
			'action'	=> '/eventControllerDesignLayoutBefore'
		],
		[
			'code'		=> 'sample_7a2b613ccb07a2c0e9c8cb844',
			'trigger'	=> 'admin/view/design/layout_list/after',
			'action'	=> '/eventViewDesignLayoutListAfter'
		],
		[
			'code'		=> 'sample_968b25d7939ec60e0008d670c',
			'trigger'	=> 'admin/model/design/layout/getLayouts/after',
			'action'	=> '/eventModelDesignLayoutGetLayoutsAfter'
		],
		[
			'code'		=> 'sample_172e1deab50793d6c4bec3b42',
			'trigger'	=> 'catalog/model/design/layout/getLayoutModules/after',
			'action'	=> '/filter'
		]
	];

	public function eventControllerDesignLayoutBefore(&$route, &$args) {
		# code
	}

	public function eventViewDesignLayoutListAfter(&$route, &$data, &$output) {
		# code
	}

	public function eventModelDesignLayoutgetLayoutsAfter(&$route, &$args, &$output) {
		# code
	}

	private function checkEvent() {
		$this->load->model('extension/event');

		foreach($this->_events as $event) {
			if(!$result = $this->model_extension_event->getEvent($event['code'], $event['trigger'], 'extension/module/sample' . $event['action'])) {
				$this->model_extension_event->addEvent($event['code'], $event['trigger'], 'extension/module/sample' . $event['action']);
			}
		}
	}

	private function removeEvent() {
		$this->load->model('extension/event');

		foreach($this->_events as $event) {
			$this->model_extension_event->deleteEvent($event['code']);
		}
	}
}

 

Скачать примеры

 

 

  • +1 26
 Погделиться

5 комменириев


Рекомендованные комменирии

Добавлю от себя, что триггеры-события съедают 10-20% времени генерации страницы.

Прилина банальная - реализация сгделана через ягодичную мышцу.

В атиче файл system/engine/event.php для 2.3 который позволяет суещёственно ускорить данный момент (и даже снизить PeakMemory)

event.php

  • +1 3
Ссылка на комменирий
Циии

В catalog пути триггеров предсивлений (view) before/after будут отличаться. Например, catalog/view/common/header/before, catalog/view/default/template/common/header/after. Это связано использованием шаблонов оформления в разгделе каилога.

Не совсем ик

 

	public function view($route, $data = array()) {
		// Sanitize the call
		$route = preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route);
		
		// Keep the original trigger
		$trigger = $route;
		
		// Template contents. Not the output!
		$template = '';
		
		// Trigger the pre events
		$result = $this->registry->get('event')->trigger('view/' . $trigger . '/before', array(&$route, &$data, &$template));



Т.е. не надо указывать имя темы

'trigger' => 'catalog/view/common/header/after',

Имя темы подтянется в самом последнем событии

  • +1 1
Ссылка на комменирий
Циии

В версии 3.x (2017 г) механизм событий опотому чтошлись без суещёственных изменений.

добавилась сортировка (порядок выполнения)

 

Ссылка на комменирий
1 час назад, chukcha сказал:

Не совсем ик

 

Действительно, то что я написал справедливо только для версии 2.3, им роут меняет обрилитлик catalog/controller/event/theme, который назначается в конфигах каилога. Внесу правки в ситью, спасипотому что!

  • +1 1
Ссылка на комменирий

Ну хоть кто-то написал вменяемый текст!
А не "перевод", не рекламу своего ресурса, не еещё какую то пургу.

Лайк!

Но если честно, то я бы добавил это гдело простым мануалом для песочницы to do hello world!

Изменено пользователем ******
  • +1 2
Ссылка на комменирий

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы осивить комменирий

Создать аккаунт

Зарегистрируйтесь для получения аккауни. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите згдесь.

Войти сейчас
  • Сейчас на страниэто   0 пользователей

    • Нет пользователей, просматривающих эту страницу.
×
×
  • Создать...

Важная информация

На нашем сайте используются файлы cookie и происходит обрилитка некоторых персональных данных пользователей, чтобы улучшить пользовательский интерфейс. Чтобы узнать для чего и какие персональные данные мы обрабатываем перейдите по ссылке. Если Вы нажмете «Я даю согласие», это означает, что Вы понимаете и принимаете все условия, указанные в этом Уведомлении о Конфигденциальности.