update Piwik to version 2.16 (fixes #91)

This commit is contained in:
oliver 2016-04-10 18:55:57 +02:00
commit d885a4baa9
5833 changed files with 418860 additions and 226988 deletions

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -8,24 +8,24 @@
*/
namespace Piwik\Plugin;
use Piwik\Option;
use Piwik\Piwik;
use Piwik\Settings\Setting;
use Piwik\Settings\Storage;
use Piwik\Settings\StorageInterface;
use Piwik\SettingsServer;
use Piwik\Tracker\SettingsStorage;
/**
* Base class of all plugin settings providers. Plugins that define their own configuration settings
* can extend this class to easily make their settings available to Piwik users.
*
*
* Descendants of this class should implement the {@link init()} method and call the
* {@link addSetting()} method for each of the plugin's settings.
*
*
* For an example, see the {@link Piwik\Plugins\ExampleSettingsPlugin\ExampleSettingsPlugin} plugin.
*
*
* @api
*/
abstract class Settings implements StorageInterface
abstract class Settings
{
const TYPE_INT = 'integer';
const TYPE_FLOAT = 'float';
@ -48,27 +48,52 @@ abstract class Settings implements StorageInterface
*/
private $settings = array();
/**
* Array containing all plugin settings values: Array( [setting-key] => [setting-value] ).
*
* @var array
*/
private $settingsValues = array();
private $introduction;
private $pluginName;
protected $pluginName;
/**
* @var StorageInterface
*/
protected $storage;
/**
* Constructor.
*
* @param string $pluginName The name of the plugin these settings are for.
*/
public function __construct($pluginName)
public function __construct($pluginName = null)
{
$this->pluginName = $pluginName;
if (!empty($pluginName)) {
$this->pluginName = $pluginName;
} else {
$classname = get_class($this);
$parts = explode('\\', $classname);
if (3 <= count($parts)) {
$this->pluginName = $parts[2];
}
}
$this->storage = Storage\Factory::make($this->pluginName);
$this->init();
$this->loadSettings();
}
/**
* @ignore
*/
public function getPluginName()
{
return $this->pluginName;
}
/**
* @ignore
* @return Setting
*/
public function getSetting($name)
{
if (array_key_exists($name, $this->settings)) {
return $this->settings[$name];
}
}
/**
@ -90,7 +115,7 @@ abstract class Settings implements StorageInterface
/**
* Returns the introduction text for this plugin's settings.
*
*
* @return string
*/
public function getIntroduction()
@ -106,14 +131,17 @@ abstract class Settings implements StorageInterface
public function getSettingsForCurrentUser()
{
$settings = array_filter($this->getSettings(), function (Setting $setting) {
return $setting->canBeDisplayedForCurrentUser();
return $setting->isWritableByCurrentUser();
});
uasort($settings, function ($setting1, $setting2) use ($settings) {
$settings2 = $settings;
uasort($settings, function ($setting1, $setting2) use ($settings2) {
/** @var Setting $setting1 */ /** @var Setting $setting2 */
if ($setting1->getOrder() == $setting2->getOrder()) {
// preserve order for settings having same order
foreach ($settings as $setting) {
foreach ($settings2 as $setting) {
if ($setting1 === $setting) {
return -1;
}
@ -142,12 +170,57 @@ abstract class Settings implements StorageInterface
return $this->settings;
}
/**
* Makes a new plugin setting available.
*
* @param Setting $setting
* @throws \Exception If there is a setting with the same name that already exists.
* If the name contains non-alphanumeric characters.
*/
protected function addSetting(Setting $setting)
{
$name = $setting->getName();
if (!ctype_alnum(str_replace('_', '', $name))) {
$msg = sprintf('The setting name "%s" in plugin "%s" is not valid. Only underscores, alpha and numerical characters are allowed', $setting->getName(), $this->pluginName);
throw new \Exception($msg);
}
if (array_key_exists($name, $this->settings)) {
throw new \Exception(sprintf('A setting with name "%s" does already exist for plugin "%s"', $setting->getName(), $this->pluginName));
}
$this->setDefaultTypeAndFieldIfNeeded($setting);
$this->addValidatorIfNeeded($setting);
$setting->setStorage($this->storage);
$setting->setPluginName($this->pluginName);
$this->settings[$name] = $setting;
}
/**
* Saves (persists) the current setting values in the database.
*/
public function save()
{
Option::set($this->getOptionKey(), serialize($this->settingsValues));
$this->storage->save();
SettingsStorage::clearCache();
/**
* Triggered after a plugin settings have been updated.
*
* **Example**
*
* Piwik::addAction('Settings.MyPlugin.settingsUpdated', function (Settings $settings) {
* $value = $settings->someSetting->getValue();
* // Do something with the new setting value
* });
*
* @param Settings $settings The plugin settings object.
*/
Piwik::postEvent(sprintf('Settings.%s.settingsUpdated', $this->pluginName), array($this));
}
/**
@ -158,138 +231,9 @@ abstract class Settings implements StorageInterface
{
Piwik::checkUserHasSuperUserAccess();
Option::delete($this->getOptionKey());
$this->settingsValues = array();
}
$this->storage->deleteAllValues();
/**
* Returns the current value for a setting. If no value is stored, the default value
* is be returned.
*
* @param Setting $setting
* @return mixed
* @throws \Exception If the setting does not exist or if the current user is not allowed to change the value
* of this setting.
*/
public function getSettingValue(Setting $setting)
{
$this->checkIsValidSetting($setting->getName());
if (array_key_exists($setting->getKey(), $this->settingsValues)) {
return $this->settingsValues[$setting->getKey()];
}
return $setting->defaultValue;
}
/**
* Sets (overwrites) the value of a setting in memory. To persist the change, {@link save()} must be
* called afterwards, otherwise the change has no effect.
*
* Before the setting is changed, the {@link Piwik\Settings\Setting::$validate} and
* {@link Piwik\Settings\Setting::$transform} closures will be invoked (if defined). If there is no validation
* filter, the setting value will be casted to the appropriate data type.
*
* @param Setting $setting
* @param string $value
* @throws \Exception If the setting does not exist or if the current user is not allowed to change the value
* of this setting.
*/
public function setSettingValue(Setting $setting, $value)
{
$this->checkIsValidSetting($setting->getName());
if ($setting->validate && $setting->validate instanceof \Closure) {
call_user_func($setting->validate, $value, $setting);
}
if ($setting->transform && $setting->transform instanceof \Closure) {
$value = call_user_func($setting->transform, $value, $setting);
} elseif (isset($setting->type)) {
settype($value, $setting->type);
}
$this->settingsValues[$setting->getKey()] = $value;
}
/**
* Unsets a setting value in memory. To persist the change, {@link save()} must be
* called afterwards, otherwise the change has no effect.
*
* @param Setting $setting
*/
public function removeSettingValue(Setting $setting)
{
$this->checkHasEnoughPermission($setting);
$key = $setting->getKey();
if (array_key_exists($key, $this->settingsValues)) {
unset($this->settingsValues[$key]);
}
}
/**
* Makes a new plugin setting available.
*
* @param Setting $setting
* @throws \Exception If there is a setting with the same name that already exists.
* If the name contains non-alphanumeric characters.
*/
protected function addSetting(Setting $setting)
{
if (!ctype_alnum($setting->getName())) {
$msg = sprintf('The setting name "%s" in plugin "%s" is not valid. Only alpha and numerical characters are allowed', $setting->getName(), $this->pluginName);
throw new \Exception($msg);
}
if (array_key_exists($setting->getName(), $this->settings)) {
throw new \Exception(sprintf('A setting with name "%s" does already exist for plugin "%s"', $setting->getName(), $this->pluginName));
}
$this->setDefaultTypeAndFieldIfNeeded($setting);
$this->addValidatorIfNeeded($setting);
$setting->setStorage($this);
$this->settings[$setting->getName()] = $setting;
}
private function getOptionKey()
{
return 'Plugin_' . $this->pluginName . '_Settings';
}
private function loadSettings()
{
$values = Option::get($this->getOptionKey());
if (!empty($values)) {
$this->settingsValues = unserialize($values);
}
}
private function checkIsValidSetting($name)
{
$setting = $this->getSetting($name);
if (empty($setting)) {
throw new \Exception(sprintf('The setting %s does not exist', $name));
}
$this->checkHasEnoughPermission($setting);
}
/**
* @param $name
* @return Setting|null
*/
private function getSetting($name)
{
if (array_key_exists($name, $this->settings)) {
return $this->settings[$name];
}
SettingsStorage::clearCache();
}
private function getDefaultType($controlType)
@ -320,30 +264,16 @@ abstract class Settings implements StorageInterface
return $defaultControlTypes[$type];
}
/**
* @param $setting
* @throws \Exception
*/
private function checkHasEnoughPermission(Setting $setting)
{
// When the request is a Tracker request, allow plugins to read/write settings
if(SettingsServer::isTrackerApiRequest()) {
return;
}
if (!$setting->canBeDisplayedForCurrentUser()) {
$errorMsg = Piwik::translate('CoreAdminHome_PluginSettingChangeNotAllowed', array($setting->getName(), $this->pluginName));
throw new \Exception($errorMsg);
}
}
private function setDefaultTypeAndFieldIfNeeded(Setting $setting)
{
if (!is_null($setting->uiControlType) && is_null($setting->type)) {
$hasControl = !is_null($setting->uiControlType);
$hasType = !is_null($setting->type);
if ($hasControl && !$hasType) {
$setting->type = $this->getDefaultType($setting->uiControlType);
} elseif (!is_null($setting->type) && is_null($setting->uiControlType)) {
} elseif ($hasType && !$hasControl) {
$setting->uiControlType = $this->getDefaultCONTROL($setting->type);
} elseif (is_null($setting->uiControlType) && is_null($setting->type)) {
} elseif (!$hasControl && !$hasType) {
$setting->type = static::TYPE_STRING;
$setting->uiControlType = static::CONTROL_TEXT;
}
@ -360,7 +290,7 @@ abstract class Settings implements StorageInterface
$setting->validate = function ($value) use ($setting, $pluginName) {
$errorMsg = Piwik::translate('CoreAdminHome_PluginSettingsValueNotAllowed',
array($setting->title, $pluginName));
array($setting->title, $pluginName));
if (is_array($value) && $setting->type == Settings::TYPE_ARRAY) {
foreach ($value as $val) {