category; } private function getModule() { $className = get_class($this); $className = explode('\\', $className); return $className[2]; } /** * Adds a widget. You can add a widget by calling this method and passing the name of the widget as well as a method * name that will be executed to render the widget. The method can be defined either directly here in this widget * class or in the controller in case you want to reuse the same action for instance in the menu etc. * @api */ protected function addWidget($name, $method, $parameters = array()) { $this->addWidgetWithCustomCategory($this->category, $name, $method, $parameters); } /** * Adds a widget with a custom category. By default all widgets that you define in your class will be added under * the same category which is defined in the {@link $category} property. Sometimes you may have a widget that * belongs to a different category where this method comes handy. It does the same as {@link addWidget()} but * allows you to define the category name as well. * @api */ protected function addWidgetWithCustomCategory($category, $name, $method, $parameters = array()) { $this->checkIsValidWidget($name, $method); $this->widgets[] = array('category' => $category, 'name' => $name, 'params' => $parameters, 'method' => $method, 'module' => $this->getModule()); } /** * Here you can add one or multiple widgets. To do so call the method {@link addWidget()} or * {@link addWidgetWithCustomCategory()}. * @api */ protected function init() { } /** * @ignore */ public function getWidgets() { $this->widgets = array(); $this->init(); return $this->widgets; } /** * Allows you to configure previously added widgets. * For instance you can remove any widgets defined by any plugin by calling the * {@link \Piwik\WidgetsList::remove()} method. * * @param WidgetsList $widgetsList * @api */ public function configureWidgetsList(WidgetsList $widgetsList) { } /** * @return \Piwik\Plugin\Widgets[] * @ignore */ public static function getAllWidgets() { return PluginManager::getInstance()->findComponents('Widgets', 'Piwik\\Plugin\\Widgets'); } /** * @ignore * @return Widgets|null */ public static function factory($module, $action) { if (empty($module) || empty($action)) { return; } $pluginManager = PluginManager::getInstance(); try { if (!$pluginManager->isPluginActivated($module)) { return; } $plugin = $pluginManager->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; } private function checkIsValidWidget($name, $method) { if (!Development::isEnabled()) { return; } if (empty($name)) { Development::error('No name is defined for added widget having method "' . $method . '" in ' . get_class($this)); } if (Development::isCallableMethod($this, $method)) { return; } $controllerClass = 'Piwik\\Plugins\\' . $this->getModule() . '\\Controller'; if (!Development::methodExists($this, $method) && !Development::methodExists($controllerClass, $method)) { Development::error('The added method "' . $method . '" neither exists in "' . get_class($this) . '" nor "' . $controllerClass . '". Make sure to define such a method.'); } $definedInClass = get_class($this); if (Development::methodExists($controllerClass, $method)) { if (Development::isCallableMethod($controllerClass, $method)) { return; } $definedInClass = $controllerClass; } Development::error('The method "' . $method . '" is not callable on "' . $definedInClass . '". Make sure the method is public.'); } }