diff --git a/sources/ElkArte/EventManager.php b/sources/ElkArte/EventManager.php index 625fd7edc4..b8a642d5ca 100644 --- a/sources/ElkArte/EventManager.php +++ b/sources/ElkArte/EventManager.php @@ -42,9 +42,15 @@ class EventManager /** @var object Instances of the controller. */ protected $_source = null; + /** @var object Instances of the modules. */ + protected $_modules = []; + /** @var string[] List of classes already registered. */ protected $_classes = array(); + /** @var int Remembers the depth of nested modules triggers. */ + protected $depth = 0; + /** @var null|string[] List of classes declared, kept here just to avoid call get_declared_classes at each trigger */ protected $_declared_classes = null; @@ -67,6 +73,7 @@ public function __construct() public function setSource($source) { $this->_source = $source; + $this->_modules[0] = ['i' => $source, 'c' => '']; } /** @@ -80,8 +87,17 @@ public function setSource($source) * * @return bool */ - public function trigger($position, $args = array()) + public function trigger($partial_position, $args = array()) { + if ($this->depth == 0) + { + $position = $partial_position; + } + else + { + $position = $this->_modules[$this->depth]['c'] . '.' . $partial_position; + } + // Nothing registered against this event, just return if (!array_key_exists($position, $this->_registered_events) || !$this->_registered_events[$position]->hasEvents()) { @@ -114,7 +130,7 @@ public function trigger($position, $args = array()) else { // Access to the calling classes properties - $this->_source->provideDependencies($dep, $dependencies); + $this->_modules[$this->depth]['i']->provideDependencies($dep, $dependencies); } } } @@ -131,6 +147,8 @@ public function trigger($position, $args = array()) // Do what we know we should do... if we find it. if (is_callable(array($instance, $method_name))) { + $instance->setEventManager($this); + $this->pushModule($instance, $class_name); // Don't send $dependencies if there are none / the method can't use them if (empty($dependencies)) { @@ -141,10 +159,23 @@ public function trigger($position, $args = array()) $this->_checkParameters($class_name, $method_name, $dependencies); call_user_func_array(array($instance, $method_name), $dependencies); } + $this->unsetModule($this->depth); } } } + protected function pushModule($instance, $class_name) + { + $this->depth += 1; + $this->_modules[$this->depth] = ['i' => $instance, 'c' => $class_name]; + } + + protected function unsetModule($depth) + { + unset($this->_modules[$this->depth]); + $this->depth = $depth - 1; + } + /** * Retrieves or creates the instance of an object. * diff --git a/sources/ElkArte/Mentions/MentionType/AbstractEventMessage.php b/sources/ElkArte/Mentions/MentionType/AbstractEventMessage.php index d345301865..5456ca00de 100644 --- a/sources/ElkArte/Mentions/MentionType/AbstractEventMessage.php +++ b/sources/ElkArte/Mentions/MentionType/AbstractEventMessage.php @@ -15,11 +15,13 @@ use ElkArte\HttpReq; use ElkArte\UserInfo; +use ElkArte\Modules\AbstractModule; +use ElkArte\EventManager; /** * Class AbstractEventMessage */ -abstract class AbstractEventMessage implements EventInterface +abstract class AbstractEventMessage extends AbstractModule implements EventInterface { /** @var string The identifier of the mention (the name that is stored in the db) */ protected static $_type = ''; @@ -42,6 +44,14 @@ public function __construct(HttpReq $http_req, UserInfo $user) $this->user = $user; } + /** + * {@inheritdoc } + */ + public static function hooks(EventManager $eventsManager) + { + return []; + } + /** * This static function is used to find the events to attach to a controller. * The implementation of this abstract class is empty because it's diff --git a/sources/ElkArte/Modules/AbstractModule.php b/sources/ElkArte/Modules/AbstractModule.php index cb68733ac9..2f51e5ab34 100644 --- a/sources/ElkArte/Modules/AbstractModule.php +++ b/sources/ElkArte/Modules/AbstractModule.php @@ -15,6 +15,7 @@ use ElkArte\HttpReq; use ElkArte\UserInfo; +use ElkArte\EventManager; /** * Abstract AbstractModule Provides some standard values to modules @@ -29,6 +30,9 @@ abstract class AbstractModule implements ModuleInterface /** @var \ElkArte\UserInfo|null User Info ValuesContainer */ protected $user; + /** @var \ElkArte\EventManager|null Events for all our fans! */ + protected $event; + /** * AbstractModule constructor. * @@ -41,6 +45,16 @@ public function __construct(HttpReq $req, UserInfo $user) $this->user = $user; } + /** + * Sets the event manager. + * + * @param \ElkArte\EventManager $event + */ + public function setEventManager(EventManager $event) + { + $this->event = $event; + } + /** * Helper function to see if a request is asking for any api processing * diff --git a/sources/ElkArte/Modules/Calendar/BoardIndex.php b/sources/ElkArte/Modules/Calendar/BoardIndex.php index 8b814f259b..ba32e0b771 100644 --- a/sources/ElkArte/Modules/Calendar/BoardIndex.php +++ b/sources/ElkArte/Modules/Calendar/BoardIndex.php @@ -57,6 +57,7 @@ public function pre_load() 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'], ); + $this->event->trigger('pre_load', ['eventOptions' => $eventOptions]); $context += Cache::instance()->quick_get('calendar_index_offset_' . ($this->user->time_offset + $modSettings['time_offset']), 'subs/Calendar.subs.php', 'cache_getRecentEvents', array($eventOptions)); // Whether one or multiple days are shown on the board index.