questlab/www/analytics/core/Plugin/Widgets.php
2016-04-10 18:55:57 +02:00

198 lines
5.9 KiB
PHP

<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugin;
use Piwik\Development;
use Piwik\Plugin\Manager as PluginManager;
use Piwik\WidgetsList;
/**
* Base class of all plugin widget providers. Plugins that define their own widgets can extend this class to easily
* add new widgets or to remove widgets defined by other plugins.
*
* For an example, see the {@link https://github.com/piwik/piwik/blob/master/plugins/ExamplePlugin/Widgets.php} plugin.
*
* @api
*/
class Widgets
{
protected $category = '';
protected $widgets = array();
public function __construct()
{
// Constructor kept for BC (because called in implementations)
}
/**
* @ignore
*/
public function getCategory()
{
return $this->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.');
}
}