Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Steur <thomas.steur@googlemail.com>2014-11-27 06:43:37 +0300
committerThomas Steur <thomas.steur@googlemail.com>2014-11-27 06:43:37 +0300
commita2d438198f171e0844318e1bec45c0bc7573e1a2 (patch)
tree0cbd74b1fd19d0712695982de2b2389c3d71d224 /core/Settings
parenta3d51aa45295105752f16e252a8e11eb59002d8e (diff)
refs #6728 automatically cache settings in tracker cache if used in tracker mode.
As soon as a setting is used in tracker mode we will cache it now making it much easier for developers to use settings in tracker mode and we will no longer query the database on each tracking request if a setting is requested apart from cache creation. Refactored the settings API under the hood to make this possible. The classes were doing things they were not supposed to do. For instance settings class also took care of storage which it should not and settings class took care of many validation things that should be done in a setting class. I cleaned up that code and it is also much better testable now.
Diffstat (limited to 'core/Settings')
-rw-r--r--core/Settings/Setting.php89
-rw-r--r--core/Settings/Storage.php144
-rw-r--r--core/Settings/Storage/Factory.php29
-rw-r--r--core/Settings/StorageInterface.php12
-rw-r--r--core/Settings/UserSetting.php2
5 files changed, 269 insertions, 7 deletions
diff --git a/core/Settings/Setting.php b/core/Settings/Setting.php
index be35345b2d..3288387671 100644
--- a/core/Settings/Setting.php
+++ b/core/Settings/Setting.php
@@ -8,6 +8,8 @@
*/
namespace Piwik\Settings;
+use Piwik\Piwik;
+use Piwik\SettingsServer;
/**
* Base setting type class.
@@ -152,6 +154,7 @@ abstract class Setting
* @var StorageInterface
*/
private $storage;
+ private $pluginName;
/**
* Constructor.
@@ -201,7 +204,7 @@ abstract class Setting
/**
* Sets the object used to persist settings.
*
- * @return StorageInterface
+ * @param StorageInterface $storage
*/
public function setStorage(StorageInterface $storage)
{
@@ -209,6 +212,26 @@ abstract class Setting
}
/**
+ * @internal
+ * @ignore
+ * @return StorageInterface
+ */
+ public function getStorage()
+ {
+ return $this->storage;
+ }
+
+ /**
+ * Sets th name of the plugin the setting belongs to
+ *
+ * @param string $pluginName
+ */
+ public function setPluginName($pluginName)
+ {
+ $this->pluginName = $pluginName;
+ }
+
+ /**
* Returns the previously persisted setting value. If no value was set, the default value
* is returned.
*
@@ -217,7 +240,23 @@ abstract class Setting
*/
public function getValue()
{
- return $this->storage->getSettingValue($this);
+ $this->checkHasEnoughReadPermission();
+
+ return $this->storage->getValue($this);
+ }
+
+ /**
+ * Returns the previously persisted setting value. If no value was set, the default value
+ * is returned.
+ *
+ * @return mixed
+ * @throws \Exception If the current user is not allowed to change the value of this setting.
+ */
+ public function removeValue()
+ {
+ $this->checkHasEnoughWritePermission();
+
+ return $this->storage->deleteValue($this);
}
/**
@@ -228,7 +267,51 @@ abstract class Setting
*/
public function setValue($value)
{
- return $this->storage->setSettingValue($this, $value);
+ $this->checkHasEnoughWritePermission();
+
+ if ($this->validate && $this->validate instanceof \Closure) {
+ call_user_func($this->validate, $value, $this);
+ }
+
+ if ($this->transform && $this->transform instanceof \Closure) {
+ $value = call_user_func($this->transform, $value, $this);
+ } elseif (isset($this->type)) {
+ settype($value, $this->type);
+ }
+
+ return $this->storage->setValue($this, $value);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ private function checkHasEnoughWritePermission()
+ {
+ // When the request is a Tracker request, allow plugins to write settings
+ if (SettingsServer::isTrackerApiRequest()) {
+ return;
+ }
+
+ if (!$this->isWritableByCurrentUser()) {
+ $errorMsg = Piwik::translate('CoreAdminHome_PluginSettingChangeNotAllowed', array($this->getName(), $this->pluginName));
+ throw new \Exception($errorMsg);
+ }
+ }
+
+ /**
+ * @throws \Exception
+ */
+ private function checkHasEnoughReadPermission()
+ {
+ // When the request is a Tracker request, allow plugins to read settings
+ if (SettingsServer::isTrackerApiRequest()) {
+ return;
+ }
+
+ if (!$this->isReadableByCurrentUser()) {
+ $errorMsg = Piwik::translate('CoreAdminHome_PluginSettingReadNotAllowed', array($this->getName(), $this->pluginName));
+ throw new \Exception($errorMsg);
+ }
}
/**
diff --git a/core/Settings/Storage.php b/core/Settings/Storage.php
new file mode 100644
index 0000000000..09525cb6d3
--- /dev/null
+++ b/core/Settings/Storage.php
@@ -0,0 +1,144 @@
+<?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\Settings;
+use Piwik\Option;
+
+/**
+ * Base setting type class.
+ *
+ * @api
+ */
+class Storage implements StorageInterface
+{
+
+ /**
+ * Array containing all plugin settings values: Array( [setting-key] => [setting-value] ).
+ *
+ * @var array
+ */
+ private $settingsValues = array();
+
+ // for lazy loading of setting values
+ private $settingValuesLoaded = false;
+
+ private $pluginName;
+
+ public function __construct($pluginName)
+ {
+ $this->pluginName = $pluginName;
+ }
+
+ /**
+ * Saves (persists) the current setting values in the database.
+ */
+ public function save()
+ {
+ $this->loadSettingsIfNotDoneYet();
+
+ Option::set($this->getOptionKey(), serialize($this->settingsValues));
+ }
+
+ /**
+ * Removes all settings for this plugin from the database. Useful when uninstalling
+ * a plugin.
+ */
+ public function deleteAllValues()
+ {
+ Option::delete($this->getOptionKey());
+
+ $this->settingsValues = array();
+ $this->settingValuesLoaded = false;
+ }
+
+ /**
+ * 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 getValue(Setting $setting)
+ {
+ $this->loadSettingsIfNotDoneYet();
+
+ 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 setValue(Setting $setting, $value)
+ {
+ $this->loadSettingsIfNotDoneYet();
+
+ $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 deleteValue(Setting $setting)
+ {
+ $this->loadSettingsIfNotDoneYet();
+
+ $key = $setting->getKey();
+
+ if (array_key_exists($key, $this->settingsValues)) {
+ unset($this->settingsValues[$key]);
+ }
+ }
+
+ public function getOptionKey()
+ {
+ return 'Plugin_' . $this->pluginName . '_Settings';
+ }
+
+ private function loadSettingsIfNotDoneYet()
+ {
+ if ($this->settingValuesLoaded) {
+ return;
+ }
+
+ $this->settingValuesLoaded = true;
+ $this->settingsValues = $this->loadSettings();
+ }
+
+ protected function loadSettings()
+ {
+ $values = Option::get($this->getOptionKey());
+
+ if (!empty($values)) {
+ return unserialize($values);
+ }
+
+ return array();
+ }
+
+}
diff --git a/core/Settings/Storage/Factory.php b/core/Settings/Storage/Factory.php
new file mode 100644
index 0000000000..c007e30e9f
--- /dev/null
+++ b/core/Settings/Storage/Factory.php
@@ -0,0 +1,29 @@
+<?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\Settings\Storage;
+
+use Piwik\Settings\Storage;
+use Piwik\SettingsServer;
+use Piwik\Tracker\SettingsStorage;
+
+class Factory
+{
+ public static function make($pluginName)
+ {
+ if (SettingsServer::isTrackerApiRequest()) {
+ $storage = new SettingsStorage($pluginName);
+ } else {
+ $storage = new Storage($pluginName);
+ }
+
+ return $storage;
+ }
+
+}
diff --git a/core/Settings/StorageInterface.php b/core/Settings/StorageInterface.php
index 74693f9ddb..7ffcac0d60 100644
--- a/core/Settings/StorageInterface.php
+++ b/core/Settings/StorageInterface.php
@@ -22,7 +22,7 @@ interface StorageInterface
* @throws \Exception In case 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);
+ public function getValue(Setting $setting);
/**
* Removes the value for the given setting. Make sure to call `save()` afterwards, otherwise the removal has no
@@ -30,7 +30,7 @@ interface StorageInterface
*
* @param Setting $setting
*/
- public function removeSettingValue(Setting $setting);
+ public function deleteValue(Setting $setting);
/**
* Sets (overwrites) the value for the given setting. Make sure to call `save()` afterwards, otherwise the change
@@ -43,7 +43,13 @@ interface StorageInterface
* @throws \Exception In case 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);
+ public function setValue(Setting $setting, $value);
+
+ /**
+ * Removes all settings for this plugin from the database. Useful when uninstalling
+ * a plugin.
+ */
+ public function deleteAllValues();
/**
* Saves (persists) the current setting values in the database.
diff --git a/core/Settings/UserSetting.php b/core/Settings/UserSetting.php
index fa29269707..80cf66ebf2 100644
--- a/core/Settings/UserSetting.php
+++ b/core/Settings/UserSetting.php
@@ -108,7 +108,7 @@ class UserSetting extends Setting
if ($setting instanceof UserSetting) {
$setting->setUserLogin($userLogin);
- $pluginSettings->removeSettingValue($setting);
+ $setting->removeValue();
}
}