diff --git a/sources/Action.controller.php b/sources/Action.controller.php index ae46b58dfa..9f0deabc00 100644 --- a/sources/Action.controller.php +++ b/sources/Action.controller.php @@ -24,6 +24,7 @@ abstract class Action_Controller { protected $_registered_extensions = array(); protected $_hooks = array(); + protected $_inverted_classes = null; /** * Default action handler. @@ -80,41 +81,41 @@ protected function runExtension($position, $args) } } - public function register($extensions) + public function register($classes) { + if ($this->_inverted_classes === null) + $this->_inverClasses($classes); + foreach ($this->_hooks as $hook) $this->addExtension($hook, $this->getExtensions($hook)); } protected function getExtensions($position) { - global $modSettings; - - $hook = str_replace('_controller', '', strtolower(__CLASS__)) . '_' . $position; - - if (!empty($modSettings[$hook])) - $methods = @unserialize($modSettings[$hook]); - - if (empty($methods)) + if (!empty($this->_inverted_classes[$position])) + return $this->_inverted_classes[$position]; + else return array(); + } - $return = array(); - foreach ($methods as $method) + protected function _inverClasses($classes) + { + $this->_inverted_classes = array(); + foreach ($classes as $class) { - if (is_array($method)) - $return[] = array($method[0], $method[1]); - else - $return[] = array($method, array()); + $hooks = $class::hooks(); + foreach ($hooks as $position => $hook) + { + if (!isset($this->_inverted_classes[$position])) + $this->_inverted_classes[$position] = array($hook); + else + $this->_inverted_classes[$position][] = $hook; + } } - - return $return; } - protected function addExtension($position, $extensions) + protected function addExtension($position, $classes) { - if (empty($extensions)) - return; - - $this->_registered_extensions[$position] = $extensions; + $this->_registered_extensions[$position] = $classes; } } \ No newline at end of file diff --git a/sources/SiteDispatcher.class.php b/sources/SiteDispatcher.class.php index 28eb5ca8ca..f86a8b7bcf 100644 --- a/sources/SiteDispatcher.class.php +++ b/sources/SiteDispatcher.class.php @@ -287,43 +287,45 @@ public function __construct() */ public function dispatch() { - global $modSettings; - require_once($this->_file_name); if (!empty($this->_controller_name)) { + $hook = strtolower(str_replace('_Controller', '', $this->_controller_name)); + $hook = substr($hook, -1) == 2 ? substr($hook, 0, -1) : $hook; + + $this->_loadAddons($hook); $controller = new $this->_controller_name(); - $controller->register($modSettings); + $controller->register($this->_addons); // Pre-dispatch (load templates and stuff) if (method_exists($controller, 'pre_dispatch')) $controller->pre_dispatch(); - $hook = strtolower(str_replace('_Controller', '', $this->_controller_name)); - $hook = substr($hook, -1) == 2 ? substr($hook, 0, -1) : $hook; - call_integration_hook('integrate_action_' . $hook . '_before', array($this->_function_name)); - // 3, 2, ... and go - if (method_exists($controller, $this->_function_name)) - $controller->{$this->_function_name}(); - elseif (method_exists($controller, 'action_index')) - $controller->action_index(); + if ($this->_validateMethod($controller)) + { + $callable = array($controller, $this->_function_name); + } // Fall back elseif (function_exists($this->_function_name)) { - call_user_func($this->_function_name); + $callable = $this->_function_name; } else { // Things went pretty bad, huh? // board index :P - call_integration_hook('integrate_action_boardindex_before'); + $hook = 'boardindex'; + $controller = new BoardIndex_Controller(); - $controller->action_boardindex(); - call_integration_hook('integrate_action_boardindex_after'); + $callable = array($controller, 'action_boardindex'); } + call_integration_hook('integrate_action_' . $hook . '_before', array($this->_function_name)); + + call_user_func($callable); + call_integration_hook('integrate_action_' . $hook . '_after', array($this->_function_name)); } else @@ -338,6 +340,35 @@ public function dispatch() } } + protected function _validateMethod($controller) + { + if (method_exists($controller, $this->_function_name)) + return true; + elseif (method_exists($controller, 'action_index')) + { + $this->_function_name = 'action_index'; + return true; + } + else + return false; + } + + protected function _loadAddons($hook) + { + foreach (glob(BOARDDIR . '/packages/integration/*/*.integrate.php') as $integrate_file) + require_once($integrate_file); + + $classes = get_declared_classes(); + $prefix = 'Addon_' . ucfirst($hook); + $prefix_len = strlen($prefix); + + foreach ($classes as $class) + { + if (substr($class, 0, $prefix_len) === $prefix) + $this->_addons[] = $class; + } + } + /** * Returns the current action for the system * diff --git a/sources/controllers/Display.controller.php b/sources/controllers/Display.controller.php index e43fc96c10..8b085c4d22 100644 --- a/sources/controllers/Display.controller.php +++ b/sources/controllers/Display.controller.php @@ -29,8 +29,8 @@ class Display_Controller extends Action_Controller public function __construct() { $this->_hooks = array( - 'display_pre', - 'display_topic_query', + 'pre_load', + 'topic_query', ); } @@ -60,7 +60,7 @@ public function action_display() global $options, $user_info, $board_info, $topic, $board; global $attachments, $messages_request; - $this->runExtension('display_pre', array('_REQUEST' => &$_REQUEST, 'topic' => $topic, 'board' => $board)); + $this->runExtension('pre_load', array('_REQUEST' => &$_REQUEST, 'topic' => $topic, 'board' => $board)); // What are you gonna display if these are empty?! if (empty($topic))