diff options
author | Thomas Steur <thomas.steur@googlemail.com> | 2014-06-30 04:18:34 +0400 |
---|---|---|
committer | Thomas Steur <thomas.steur@googlemail.com> | 2014-06-30 04:18:34 +0400 |
commit | c70371aa61d7b25cfb6f604f765965564e23e292 (patch) | |
tree | 2d73e79dedfb1be97e41aafb04f810c0b0569455 /core | |
parent | a630dead90724060c23f9ac8ddec97cb06fcd8b5 (diff) |
refs #5326 as mentioned in the ticket once we have simplified the reports we can simplify the widgets api even more which is done in this commit, it might be not perfect yet but again much better than before
Diffstat (limited to 'core')
-rw-r--r-- | core/FrontController.php | 80 | ||||
-rw-r--r-- | core/Plugin/Widgets.php | 108 | ||||
-rw-r--r-- | core/WidgetsList.php | 32 |
3 files changed, 181 insertions, 39 deletions
diff --git a/core/FrontController.php b/core/FrontController.php index 3753980f24..2861e3cb0b 100644 --- a/core/FrontController.php +++ b/core/FrontController.php @@ -14,7 +14,9 @@ use Piwik\API\Request; use Piwik\API\ResponseBuilder; use Piwik\Plugin\Controller; use Piwik\Plugin\Report; +use Piwik\Plugin\Widgets; use Piwik\Session; +use \Piwik\Plugins\CoreHome\Controller as CoreHomeController; /** * This singleton dispatches requests to the appropriate plugin Controller. @@ -105,45 +107,69 @@ class FrontController extends Singleton { $controllerClassName = $this->getClassNameController($module); - // FrontController's autoloader - if (!class_exists($controllerClassName, false)) { - $moduleController = PIWIK_INCLUDE_PATH . '/plugins/' . $module . '/Controller.php'; - if (!is_readable($moduleController)) { - throw new Exception("Module controller $moduleController not found!"); - } - require_once $moduleController; // prefixed by PIWIK_INCLUDE_PATH - } + // TRY TO FIND ACTION IN CONTROLLER + if (class_exists($controllerClassName)) { - $class = $this->getClassNameController($module); - /** @var $controller Controller */ - $controller = new $class; - if ($action === false) { - $action = $controller->getDefaultAction(); - } + $class = $this->getClassNameController($module); + /** @var $controller Controller */ + $controller = new $class; - if (!is_callable(array($controller, $action))) { + $controllerAction = $action; + if ($controllerAction === false) { + $controllerAction = $controller->getDefaultAction(); + } - $report = Report::factory($module, $action); - $actionToCall = 'renderReportWidget'; - $actionToCheck = $action; + if (is_callable(array($controller, $controllerAction))) { - if (empty($report) && !empty($action) && 'menu' === substr($action, 0, 4)) { - $actionToCheck = lcfirst(substr($action, 4)); - $report = Report::factory($module, $actionToCheck); - $actionToCall = 'renderReportMenu'; + return array($controller, $controllerAction); } - if (empty($report)) { - throw new Exception("Action '$action' not found in the controller '$controllerClassName'."); + if ($action === false) { + $this->triggerControllerActionNotFoundError($controller, $controllerAction); } + } + + // TRY TO FIND ACTION IN WIDGET + $widget = Widgets::factory($module, $action); + + if (!empty($widget)) { + + $parameters['widgetModule'] = $module; + $parameters['widgetMethod'] = $action; + + return array(new CoreHomeController(), 'renderWidget'); + } + + // TRY TO FIND ACTION IN REPORT + $report = Report::factory($module, $action); + + if (!empty($report)) { + $parameters['reportModule'] = $module; - $parameters['reportAction'] = $actionToCheck; + $parameters['reportAction'] = $action; + + return array(new CoreHomeController(), 'renderReportWidget'); + } + + if (!empty($action) && 'menu' === substr($action, 0, 4)) { + $reportAction = lcfirst(substr($action, 4)); // menuGetPageUrls => getPageUrls + $report = Report::factory($module, $reportAction); - return $this->makeController('CoreHome', $actionToCall, $parameters); + if (!empty($report)) { + $parameters['reportModule'] = $module; + $parameters['reportAction'] = $reportAction; + + return array(new CoreHomeController(), 'renderReportMenu'); + } } - return array($controller, $action); + $this->triggerControllerActionNotFoundError($module, $action); + } + + protected function triggerControllerActionNotFoundError($module, $action) + { + throw new Exception("Action '$action' not found in the module '$module'."); } protected function getClassNameController($module) diff --git a/core/Plugin/Widgets.php b/core/Plugin/Widgets.php index 201fe743f6..db69c6e794 100644 --- a/core/Plugin/Widgets.php +++ b/core/Plugin/Widgets.php @@ -8,6 +8,7 @@ */ namespace Piwik\Plugin; +use Piwik\Plugin\Manager as PluginManager; use Piwik\WidgetsList; /** @@ -20,10 +21,113 @@ use Piwik\WidgetsList; */ class Widgets { + protected $category = ''; + protected $widgets = array(); + + private $module = ''; + + public function __construct() + { + $this->module = $this->getModule(); + } + + public function getCategory() + { + return $this->category; + } + + private function getModule() + { + $className = get_class($this); + $className = explode('\\', $className); + + return $className[2]; + } + /** - * Configures the widgets. Here you can for instance add or remove widgets. + * @api */ - public function configure(WidgetsList $widgetsList) + protected function addWidget($name, $method, $parameters = array()) + { + // to be developer friendly we could check whether such a method exists (in controller or widget) and if + // not throw an exception so the developer does not have to handle with typos etc. I do not want to do this + // right now because of performance but if we add a development setting in config we could do such check + $this->addWidgetWithCustomCategory($this->category, $name, $method, $parameters); + } + + protected function addWidgetWithCustomCategory($category, $name, $method, $parameters = array()) + { + $this->widgets[] = array('category' => $category, + 'name' => $name, + 'params' => $parameters, + 'method' => $method, + 'module' => $this->module); + } + + /** + * @api + */ + protected function init() + { + } + + public function getWidgets() { + $this->widgets = array(); + + $this->init(); + + return $this->widgets; + } + + /** + * Configures the widgets. Here you can for instance remove widgets. + */ + public function configureWidgetsList(WidgetsList $widgetsList) + { + + } + + /** + * @return \Piwik\Plugin\Widgets[] + */ + public static function getAllWidgets() + { + return PluginManager::getInstance()->findComponents('Widgets', 'Piwik\\Plugin\\Widgets'); + } + + public static function factory($module, $action) + { + if (empty($module) || empty($action)) { + return; + } + + try { + $plugin = PluginManager::getInstance()->getLoadedPlugin($module); + } catch (\Exception $e) { + // we are not allowed to use possible widgets, plugin is not active + return; + } + + /** @var Widgets $widgetContainer */ + $widgetContainer = $plugin->findComponent('Widgets', 'Piwik\\Plugin\\Widgets'); + + if (empty($widgetContainer)) { + // plugin does not define any widgets, we cannot do anything + return; + } + + if (!is_callable(array($widgetContainer, $action))) { + // widget does not implement such a method, we cannot do anything + return; + } + + // the widget class implements such an action, but we have to check whether it is actually exposed and whether + // it was maybe disabled by another plugin, this is only possible by checking the widgetslist, unfortunately + if (!WidgetsList::isDefined($module, $action)) { + return; + } + + return $widgetContainer; } } diff --git a/core/WidgetsList.php b/core/WidgetsList.php index 420f5f76b6..531d802405 100644 --- a/core/WidgetsList.php +++ b/core/WidgetsList.php @@ -8,8 +8,8 @@ */ namespace Piwik; -use Piwik\Plugin\Manager as PluginManager; use Piwik\Plugin\Report; +use Piwik\Plugin\Widgets; /** * Manages the global list of reports that can be displayed as dashboard widgets. @@ -61,11 +61,15 @@ class WidgetsList extends Singleton $widgets = array(); foreach (self::$widgets as $key => $v) { - if (isset($widgets[Piwik::translate($key)])) { - $v = array_merge($widgets[Piwik::translate($key)], $v); + $category = Piwik::translate($key); + + if (isset($widgets[$category])) { + $v = array_merge($widgets[$category], $v); } - $widgets[Piwik::translate($key)] = $v; + + $widgets[$category] = $v; } + return $widgets; } @@ -80,8 +84,6 @@ class WidgetsList extends Singleton */ Piwik::postEvent('WidgetsList.addWidgets'); - /** @var \Piwik\Plugin\Widgets[] $widgets */ - $widgets = PluginManager::getInstance()->findComponents('Widgets', 'Piwik\\Plugin\\Widgets'); $widgetsList = self::getInstance(); foreach (Report::getAllReports() as $report) { @@ -90,8 +92,17 @@ class WidgetsList extends Singleton } } - foreach ($widgets as $widget) { - $widget->configure($widgetsList); + $widgetContainers = Widgets::getAllWidgets(); + foreach ($widgetContainers as $widgetContainer) { + $widgets = $widgetContainer->getWidgets(); + + foreach ($widgets as $widget) { + $widgetsList->add($widget['category'], $widget['name'], $widget['module'], $widget['method'], $widget['params']); + } + } + + foreach ($widgetContainers as $widgetContainer) { + $widgetContainer->configureWidgetsList($widgetsList); } } } @@ -143,8 +154,9 @@ class WidgetsList extends Singleton */ static public function add($widgetCategory, $widgetName, $controllerName, $controllerAction, $customParameters = array()) { - $widgetName = Piwik::translate($widgetName); + $widgetName = Piwik::translate($widgetName); $widgetUniqueId = 'widget' . $controllerName . $controllerAction; + foreach ($customParameters as $name => $value) { if (is_array($value)) { // use 'Array' for backward compatibility; @@ -203,7 +215,7 @@ class WidgetsList extends Singleton static public function isDefined($controllerName, $controllerAction) { $widgetsList = self::get(); - foreach ($widgetsList as $widgetCategory => $widgets) { + foreach ($widgetsList as $widgets) { foreach ($widgets as $widget) { if ($widget['parameters']['module'] == $controllerName && $widget['parameters']['action'] == $controllerAction |