Teknik is a suite of services with attractive and functional interfaces. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Option.php 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik;
  10. /**
  11. * Convenient key-value storage for user specified options and temporary
  12. * data that needs to be persisted beyond one request.
  13. *
  14. * ### Examples
  15. *
  16. * **Setting and getting options**
  17. *
  18. * $optionValue = Option::get('MyPlugin.MyOptionName');
  19. * if ($optionValue === false) {
  20. * // if not set, set it
  21. * Option::set('MyPlugin.MyOptionName', 'my option value');
  22. * }
  23. *
  24. * **Storing user specific options**
  25. *
  26. * $userName = // ...
  27. * Option::set('MyPlugin.MyOptionName.' . $userName, 'my option value');
  28. *
  29. * **Clearing user specific options**
  30. *
  31. * Option::deleteLike('MyPlugin.MyOptionName.%');
  32. *
  33. * @api
  34. */
  35. class Option
  36. {
  37. /**
  38. * Returns the option value for the requested option `$name`.
  39. *
  40. * @param string $name The option name.
  41. * @return string|false The value or `false`, if not found.
  42. */
  43. public static function get($name)
  44. {
  45. return self::getInstance()->getValue($name);
  46. }
  47. /**
  48. * Returns option values for options whose names are like a given pattern.
  49. *
  50. * @param string $namePattern The pattern used in the SQL `LIKE` expression
  51. * used to SELECT options.
  52. * @return array Array mapping option names with option values.
  53. */
  54. public static function getLike($namePattern)
  55. {
  56. return self::getInstance()->getNameLike($namePattern);
  57. }
  58. /**
  59. * Sets an option value by name.
  60. *
  61. * @param string $name The option name.
  62. * @param string $value The value to set the option to.
  63. * @param int $autoLoad If set to 1, this option value will be automatically loaded when Piwik is initialzed;
  64. * should be set to 1 for options that will be used in every Piwik request.
  65. */
  66. public static function set($name, $value, $autoload = 0)
  67. {
  68. return self::getInstance()->setValue($name, $value, $autoload);
  69. }
  70. /**
  71. * Deletes an option.
  72. *
  73. * @param string $name Option name to match exactly.
  74. * @param string $value If supplied the option will be deleted only if its value matches this value.
  75. */
  76. public static function delete($name, $value = null)
  77. {
  78. return self::getInstance()->deleteValue($name, $value);
  79. }
  80. /**
  81. * Deletes all options that match the supplied pattern.
  82. *
  83. * @param string $namePattern Pattern of key to match. `'%'` characters should be used as wildcards, and literal
  84. * `'_'` characters should be escaped.
  85. * @param string $value If supplied, options will be deleted only if their value matches this value.
  86. */
  87. public static function deleteLike($namePattern, $value = null)
  88. {
  89. return self::getInstance()->deleteNameLike($namePattern, $value);
  90. }
  91. public static function clearCachedOption($name)
  92. {
  93. self::getInstance()->clearCachedOptionByName($name);
  94. }
  95. /**
  96. * Clears the option value cache and forces a reload from the Database.
  97. * Used in unit tests to reset the state of the object between tests.
  98. *
  99. * @return void
  100. * @ignore
  101. */
  102. public static function clearCache()
  103. {
  104. $option = self::getInstance();
  105. $option->loaded = false;
  106. $option->all = array();
  107. }
  108. /**
  109. * @var array
  110. */
  111. private $all = array();
  112. /**
  113. * @var bool
  114. */
  115. private $loaded = false;
  116. /**
  117. * Singleton instance
  118. * @var \Piwik\Option
  119. */
  120. private static $instance = null;
  121. /**
  122. * Returns Singleton instance
  123. *
  124. * @return \Piwik\Option
  125. */
  126. private static function getInstance()
  127. {
  128. if (self::$instance == null) {
  129. self::$instance = new self;
  130. }
  131. return self::$instance;
  132. }
  133. /**
  134. * Private Constructor
  135. */
  136. private function __construct()
  137. {
  138. }
  139. protected function clearCachedOptionByName($name)
  140. {
  141. if (isset($this->all[$name])) {
  142. unset($this->all[$name]);
  143. }
  144. }
  145. protected function getValue($name)
  146. {
  147. $this->autoload();
  148. if (isset($this->all[$name])) {
  149. return $this->all[$name];
  150. }
  151. $value = Db::fetchOne('SELECT option_value ' .
  152. 'FROM `' . Common::prefixTable('option') . '` ' .
  153. 'WHERE option_name = ?', $name);
  154. if ($value === false) {
  155. return false;
  156. }
  157. $this->all[$name] = $value;
  158. return $value;
  159. }
  160. protected function setValue($name, $value, $autoLoad = 0)
  161. {
  162. $autoLoad = (int)$autoLoad;
  163. Db::query('INSERT INTO `' . Common::prefixTable('option') . '` (option_name, option_value, autoload) ' .
  164. ' VALUES (?, ?, ?) ' .
  165. ' ON DUPLICATE KEY UPDATE option_value = ?',
  166. array($name, $value, $autoLoad, $value));
  167. $this->all[$name] = $value;
  168. }
  169. protected function deleteValue($name, $value)
  170. {
  171. $sql = 'DELETE FROM `' . Common::prefixTable('option') . '` WHERE option_name = ?';
  172. $bind[] = $name;
  173. if (isset($value)) {
  174. $sql .= ' AND option_value = ?';
  175. $bind[] = $value;
  176. }
  177. Db::query($sql, $bind);
  178. $this->clearCache();
  179. }
  180. protected function deleteNameLike($name, $value = null)
  181. {
  182. $sql = 'DELETE FROM `' . Common::prefixTable('option') . '` WHERE option_name LIKE ?';
  183. $bind[] = $name;
  184. if (isset($value)) {
  185. $sql .= ' AND option_value = ?';
  186. $bind[] = $value;
  187. }
  188. Db::query($sql, $bind);
  189. $this->clearCache();
  190. }
  191. protected function getNameLike($name)
  192. {
  193. $sql = 'SELECT option_name, option_value FROM `' . Common::prefixTable('option') . '` WHERE option_name LIKE ?';
  194. $bind = array($name);
  195. $result = array();
  196. foreach (Db::fetchAll($sql, $bind) as $row) {
  197. $result[$row['option_name']] = $row['option_value'];
  198. }
  199. return $result;
  200. }
  201. /**
  202. * Initialize cache with autoload settings.
  203. *
  204. * @return void
  205. */
  206. protected function autoload()
  207. {
  208. if ($this->loaded) {
  209. return;
  210. }
  211. $all = Db::fetchAll('SELECT option_value, option_name
  212. FROM `' . Common::prefixTable('option') . '`
  213. WHERE autoload = 1');
  214. foreach ($all as $option) {
  215. $this->all[$option['option_name']] = $option['option_value'];
  216. }
  217. $this->loaded = true;
  218. }
  219. }