update Piwik to version 2.16 (fixes #91)
This commit is contained in:
parent
296343bf3b
commit
d885a4baa9
5833 changed files with 418860 additions and 226988 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue