diff options
author | Benaka Moorthi <benaka.moorthi@gmail.com> | 2013-07-18 04:58:14 +0400 |
---|---|---|
committer | Benaka Moorthi <benaka.moorthi@gmail.com> | 2013-07-18 04:58:14 +0400 |
commit | e1c03ff6105aefb845ea271a538747b69fb0da84 (patch) | |
tree | f798d139158aa4920401b8079747292ae0f7b6f7 /core | |
parent | 704629b72935d20d507f73219b89013101d2c1c7 (diff) |
Refactor Piwik_PluginsManager and Piwik_Plugin class, moved plugin metadata loading to a new MetadataLoader class, allowed loading of new colors.piwik.json file.
Diffstat (limited to 'core')
-rw-r--r-- | core/Plugin.php | 62 | ||||
-rw-r--r-- | core/Plugin/MetadataLoader.php | 137 | ||||
-rw-r--r-- | core/PluginsManager.php | 43 |
3 files changed, 183 insertions, 59 deletions
diff --git a/core/Plugin.php b/core/Plugin.php index 374c179f1c..7f23f28005 100644 --- a/core/Plugin.php +++ b/core/Plugin.php @@ -18,6 +18,37 @@ class Piwik_Plugin { /** + * Name of this plugin. + * + * @var string + */ + protected $pluginName; + + /** + * Holds plugin metadata. + * + * @var array + */ + private $pluginInformation; + + /** + * Constructor. + * + * @param string|bool $pluginName A plugin name to force. If not supplied, it is set + * to last part of the class name. + */ + public function __construct($pluginName = false) + { + if (empty($pluginName)) { + $pluginName = Piwik_Common::unprefixClass(get_class($this)); + } + $this->pluginName = $pluginName; + + $metadataLoader = new Piwik_Plugin_MetadataLoader($pluginName); + $this->pluginInformation = $metadataLoader->load(); + } + + /** * Returns the plugin details * - 'description' => string // 1-2 sentence description of the plugin * - 'author' => string // plugin author @@ -32,25 +63,7 @@ class Piwik_Plugin */ public function getInformation() { - $descriptionKey = $this->getPluginName() . '_PluginDescription'; - $translation = Piwik_Translate($descriptionKey); - $info = array( - 'description' => $translation, - 'homepage' => 'http://piwik.org/', - 'author' => 'Piwik', - 'author_homepage' => 'http://piwik.org/', - 'license' => 'GPL v3 or later', - 'license_homepage' => 'http://www.gnu.org/licenses/gpl.html', - 'version' => Piwik_Version::VERSION, - 'theme' => false, - ); - - $pluginName = $this->getPluginName(); - $infoFromJson = Piwik_PluginsManager::getInstance()->loadInfoFromJson($pluginName); - if(!empty($infoFromJson)) { - $info = array_merge($info, $infoFromJson); - } - return $info; + return $this->pluginInformation; } /** @@ -138,7 +151,6 @@ class Piwik_Plugin $info = $this->getInformation(); return !empty($info['theme']) && (bool)$info['theme']; } - protected $pluginName; /** * Returns the plugin's base class name without the "Piwik_" prefix, @@ -148,16 +160,6 @@ class Piwik_Plugin */ final public function getPluginName() { - if(!empty($this->pluginName)) { - return $this->pluginName; - } - $this->pluginName = Piwik_Common::unprefixClass(get_class($this)); return $this->pluginName; } - - final public function setPluginName($pluginName) - { - $this->pluginName = $pluginName; - } - } diff --git a/core/Plugin/MetadataLoader.php b/core/Plugin/MetadataLoader.php new file mode 100644 index 0000000000..92a37ff1bb --- /dev/null +++ b/core/Plugin/MetadataLoader.php @@ -0,0 +1,137 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + * @category Piwik + * @package Piwik + */ + +/** + * Loads plugin metadata found in the following files: + * - plugin.piwik.json + * - colors.piwik.json + */ +class Piwik_Plugin_MetadataLoader +{ + const PLUGIN_JSON_FILENAME = 'plugin.piwik.json'; + const COLORS_JSON_FILENAME = 'colors.piwik.json'; + + const SHORT_COLOR_LENGTH = 4; + const LONG_COLOR_LENGTH = 7; + + /** + * The name of the plugin whose metadata will be loaded. + * + * @var string + */ + private $pluginName; + + /** + * Constructor. + * + * @param string $pluginName Name of the plugin to load metadata. + */ + public function __construct($pluginName) + { + $this->pluginName = $pluginName; + } + + /** + * Loads plugin metadata. @see Piwik_Plugin::getInformation. + * + * @return array + */ + public function load() + { + return array_merge( + $this->getDefaultPluginInformation(), + $this->loadPluginInfoJson(), + $this->loadPluginColorsJson() + ); + } + + private function getDefaultPluginInformation() + { + $descriptionKey = $this->pluginName . '_PluginDescription'; + return array( + 'description' => Piwik_Translate($descriptionKey), + 'homepage' => 'http://piwik.org/', + 'author' => 'Piwik', + 'author_homepage' => 'http://piwik.org/', + 'license' => 'GPL v3 or later', + 'license_homepage' => 'http://www.gnu.org/licenses/gpl.html', + 'version' => Piwik_Version::VERSION, + 'theme' => false, + ); + } + + private function loadPluginInfoJson() + { + $path = Piwik_PluginsManager::getPluginsDirectory() . $this->pluginName . '/' . self::PLUGIN_JSON_FILENAME; + return $this->loadJsonMetadata($path); + } + + private function loadPluginColorsJson() + { + $path = Piwik_PluginsManager::getPluginsDirectory() . $this->pluginName . '/' . self::COLORS_JSON_FILENAME; + $info = $this->loadJsonMetadata($path); + $info = $this->cleanAndValidatePluginColorsJson($path, $info); + return $info; + } + + private function cleanAndValidatePluginColorsJson($path, $info) + { + // check that if "colors" exists, it is an array + $colors = isset($info["colors"]) ? $info["colors"] : array(); + if (!is_array($colors)) { + throw new Exception("The 'colors' value in '$path' must be an object mapping names with colors."); + } + + // validate each color + foreach ($colors as $color) { + if (!$this->isStringColorValid($color)) { + throw new Exception("Invalid color string '$color' in '$path'."); + } + } + + return array("colors" => $colors); // make sure only 'colors' element is loaded + } + + private function isStringColorValid($color) + { + if (strlen($color) !== self::SHORT_COLOR_LENGTH + && strlen($color) !== self::LONG_COLOR_LENGTH + ) { + return false; + } + + if ($color[0] !== '#') { + return false; + } + + return ctype_xdigit(substr($color, 1)); // check if other digits are hex + } + + private function loadJsonMetadata($path) + { + if (!file_exists($path)) { + return array(); + } + + $json = file_get_contents($path); + if (!$json) { + return array(); + } + + $info = Piwik_Common::json_decode($json, $assoc = true); + if (!is_array($info) + || empty($info) + ) { + throw new Exception("Invalid JSON file: $path"); + } + return $info; + } +} diff --git a/core/PluginsManager.php b/core/PluginsManager.php index 7cbd3309b7..db32db0e65 100644 --- a/core/PluginsManager.php +++ b/core/PluginsManager.php @@ -64,7 +64,6 @@ class Piwik_PluginsManager const TRACKER_EVENT_PREFIX = 'Tracker.'; static private $instance = null; - const PLUGIN_JSON_FILENAME = 'plugin.piwik.json'; /** * Returns the singleton Piwik_PluginsManager @@ -171,38 +170,19 @@ class Piwik_PluginsManager */ public function readPluginsDirectory() { - $pluginsName = _glob($this->getPluginsDirectory() . '*', GLOB_ONLYDIR); + $pluginsName = _glob(self::getPluginsDirectory() . '*', GLOB_ONLYDIR); $result = array(); if ($pluginsName != false) { foreach ($pluginsName as $path) { - $name = basename($path); - $pluginStructureLooksValid = file_exists($path . "/" . $name . ".php") || file_exists($path . "/" . self::PLUGIN_JSON_FILENAME); - if ($pluginStructureLooksValid) { - $result[] = $name; + if (self::pluginStructureLooksValid($path)) { + $result[] = basename($path); } } } return $result; } - public function loadInfoFromJson($pluginName) - { - $path = $this->getPluginsDirectory() . $pluginName . '/' . self::PLUGIN_JSON_FILENAME; - if(!file_exists($path)) { - return false; - } - $json = file_get_contents($path); - if(!$json) { - return false; - } - $info = Piwik_Common::json_decode($json, $assoc = true); - if(!is_array($info) || empty($info)) { - throw new Exception("Invalid JSON file: $path"); - } - return $info; - } - - protected function getPluginsDirectory() + public static function getPluginsDirectory() { return PIWIK_INCLUDE_PATH . '/plugins/'; } @@ -517,14 +497,12 @@ class Piwik_PluginsManager throw new Exception(sprintf("The plugin filename '%s' is not a valid filename", $pluginFileName)); } - $path = $this->getPluginsDirectory() . $pluginFileName; + $path = self::getPluginsDirectory() . $pluginFileName; if (!file_exists($path)) { // Create the smallest minimal Piwik Plugin // Eg. Used for Zeitgeist default theme which does not have a Zeitgeist.php file - $minimalistPlugin = new Piwik_Plugin(); - $minimalistPlugin->setPluginName($pluginName); - return $minimalistPlugin; + return new Piwik_Plugin($pluginName); } require_once $path; @@ -625,7 +603,7 @@ class Piwik_PluginsManager $pluginName = $plugin->getPluginName(); - $path = $this->getPluginsDirectory() . $pluginName . '/lang/%s.php'; + $path = self::getPluginsDirectory() . $pluginName . '/lang/%s.php'; $defaultLangPath = sprintf($path, $langCode); $defaultEnglishLangPath = sprintf($path, 'en'); @@ -723,6 +701,13 @@ class Piwik_PluginsManager } return false; } + + private static function pluginStructureLooksValid($path) + { + $name = basename($path); + return file_exists($path . "/" . $name . ".php") + || file_exists($path . "/" . Piwik_Plugin_MetadataLoader::PLUGIN_JSON_FILENAME); + } } /** |