PageRenderTime 47ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/inc/core/class.dc.namespace.php

https://bitbucket.org/dotclear/dotclear/
PHP | 432 lines | 262 code | 56 blank | 114 comment | 75 complexity | 2cd6eb5d01e408bdf629f048d08e3f37 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0
  1. <?php
  2. # -- BEGIN LICENSE BLOCK ---------------------------------------
  3. #
  4. # This file is part of Dotclear 2.
  5. #
  6. # Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear
  7. # Licensed under the GPL version 2.0 license.
  8. # See LICENSE file or
  9. # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  10. #
  11. # -- END LICENSE BLOCK -----------------------------------------
  12. if (!defined('DC_RC_PATH')) { return; }
  13. /**
  14. @ingroup DC_CORE
  15. @brief Blog namespace for settings handler
  16. */
  17. class dcNamespace
  18. {
  19. protected $con; ///< <b>connection</b> Database connection object
  20. protected $table; ///< <b>string</b> Settings table name
  21. protected $blog_id; ///< <b>string</b> Blog ID
  22. protected $global_settings = array(); ///< <b>array</b> Global settings array
  23. protected $local_settings = array(); ///< <b>array</b> Local settings array
  24. protected $settings = array(); ///< <b>array</b> Associative settings array
  25. protected $ns; ///< <b>string</b> Current namespace
  26. /**
  27. Object constructor. Retrieves blog settings and puts them in $settings
  28. array. Local (blog) settings have a highest priority than global settings.
  29. @param name <b>string</b> ID for this namespace
  30. */
  31. public function __construct(&$core, $blog_id, $name, $rs=null)
  32. {
  33. if (preg_match('/^[a-zA-Z][a-zA-Z0-9]+$/',$name)) {
  34. $this->ns = $name;
  35. } else {
  36. throw new Exception(sprintf(__('Invalid setting dcNamespace: %s'),$name));
  37. }
  38. $this->con =& $core->con;
  39. $this->table = $core->prefix.'setting';
  40. $this->blog_id =& $blog_id;
  41. $this->getSettings($rs);
  42. }
  43. private function getSettings($rs=null)
  44. {
  45. if ($rs == null) {
  46. $strReq = 'SELECT blog_id, setting_id, setting_value, '.
  47. 'setting_type, setting_label, setting_ns '.
  48. 'FROM '.$this->table.' '.
  49. "WHERE (blog_id = '".$this->con->escape($this->blog_id)."' ".
  50. 'OR blog_id IS NULL) '.
  51. "AND setting_ns = '".$this->con->escape($this->ns)."' ".
  52. 'ORDER BY setting_id DESC ';
  53. try {
  54. $rs = $this->con->select($strReq);
  55. } catch (Exception $e) {
  56. trigger_error(__('Unable to retrieve settings:').' '.$this->con->error(), E_USER_ERROR);
  57. }
  58. }
  59. while ($rs->fetch())
  60. {
  61. if ($rs->f('setting_ns') != $this->ns){
  62. break;
  63. }
  64. $id = trim($rs->f('setting_id'));
  65. $value = $rs->f('setting_value');
  66. $type = $rs->f('setting_type');
  67. if ($type == 'array') {
  68. $value = @json_decode($value,true);
  69. } else {
  70. if ($type == 'float' || $type == 'double') {
  71. $type = 'float';
  72. } elseif ($type != 'boolean' && $type != 'integer') {
  73. $type = 'string';
  74. }
  75. }
  76. settype($value,$type);
  77. $array = $rs->blog_id ? 'local' : 'global';
  78. $this->{$array.'_settings'}[$id] = array(
  79. 'ns' => $this->ns,
  80. 'value' => $value,
  81. 'type' => $type,
  82. 'label' => (string) $rs->f('setting_label'),
  83. 'global' => $rs->blog_id == ''
  84. );
  85. }
  86. $this->settings = $this->global_settings;
  87. foreach ($this->local_settings as $id => $v) {
  88. $this->settings[$id] = $v;
  89. }
  90. return true;
  91. }
  92. private function settingExists($id,$global=false)
  93. {
  94. $array = $global ? 'global' : 'local';
  95. return isset($this->{$array.'_settings'}[$id]);
  96. }
  97. /**
  98. Returns setting value if exists.
  99. @param n <b>string</b> Setting name
  100. @return <b>mixed</b>
  101. */
  102. public function get($n)
  103. {
  104. if (isset($this->settings[$n]['value'])) {
  105. return $this->settings[$n]['value'];
  106. }
  107. return null;
  108. }
  109. /**
  110. Returns global setting value if exists.
  111. @param n <b>string</b> setting name
  112. @return <b>mixed</b>
  113. */
  114. public function getGlobal($n)
  115. {
  116. if (isset($this->global_settings[$n]['value'])) {
  117. return $this->global_settings[$n]['value'];
  118. }
  119. return null;
  120. }
  121. /**
  122. Returns local setting value if exists.
  123. @param n <b>string</b> setting name
  124. @return <b>mixed</b>
  125. */
  126. public function getLocal($n)
  127. {
  128. if (isset($this->local_settings[$n]['value'])) {
  129. return $this->local_settings[$n]['value'];
  130. }
  131. return null;
  132. }
  133. /**
  134. Magic __get method.
  135. @copydoc ::get
  136. */
  137. public function __get($n)
  138. {
  139. return $this->get($n);
  140. }
  141. /**
  142. Sets a setting in $settings property. This sets the setting for script
  143. execution time only and if setting exists.
  144. @param n <b>string</b> Setting name
  145. @param v <b>mixed</b> Setting value
  146. */
  147. public function set($n,$v)
  148. {
  149. if (isset($this->settings[$n])) {
  150. $this->settings[$n]['value'] = $v;
  151. }
  152. }
  153. /**
  154. Magic __set method.
  155. @copydoc ::set
  156. */
  157. public function __set($n,$v)
  158. {
  159. $this->set($n,$v);
  160. }
  161. /**
  162. Creates or updates a setting.
  163. $type could be 'string', 'integer', 'float', 'boolean' or null. If $type is
  164. null and setting exists, it will keep current setting type.
  165. $value_change allow you to not change setting. Useful if you need to change
  166. a setting label or type and don't want to change its value.
  167. @param id <b>string</b> Setting ID
  168. @param value <b>mixed</b> Setting value
  169. @param type <b>string</b> Setting type
  170. @param label <b>string</b> Setting label
  171. @param value_change <b>boolean</b> Change setting value or not
  172. @param global <b>boolean</b> Setting is global
  173. */
  174. public function put($id,$value,$type=null,$label=null,$value_change=true,$global=false)
  175. {
  176. if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]+$/',$id)) {
  177. throw new Exception(sprintf(__('%s is not a valid setting id'),$id));
  178. }
  179. # We don't want to change setting value
  180. if (!$value_change)
  181. {
  182. if (!$global && $this->settingExists($id,false)) {
  183. $value = $this->local_settings[$id]['value'];
  184. } elseif ($this->settingExists($id,true)) {
  185. $value = $this->global_settings[$id]['value'];
  186. }
  187. }
  188. # Setting type
  189. if ($type == 'double')
  190. {
  191. $type = 'float';
  192. }
  193. elseif ($type === null)
  194. {
  195. if (!$global && $this->settingExists($id,false)) {
  196. $type = $this->local_settings[$id]['type'];
  197. } elseif ($this->settingExists($id,true)) {
  198. $type = $this->global_settings[$id]['type'];
  199. } else {
  200. if (is_array($value)) {
  201. $type = 'array';
  202. } else {
  203. $type = 'string';
  204. }
  205. }
  206. }
  207. elseif ($type != 'boolean' && $type != 'integer' && $type != 'float' && $type != 'array')
  208. {
  209. $type = 'string';
  210. }
  211. # We don't change label
  212. if ($label == null)
  213. {
  214. if (!$global && $this->settingExists($id,false)) {
  215. $label = $this->local_settings[$id]['label'];
  216. } elseif ($this->settingExists($id,true)) {
  217. $label = $this->global_settings[$id]['label'];
  218. }
  219. }
  220. if ($type != 'array') {
  221. settype($value,$type);
  222. } else {
  223. $value = json_encode($value);
  224. }
  225. $cur = $this->con->openCursor($this->table);
  226. $cur->setting_value = ($type == 'boolean') ? (string) (integer) $value : (string) $value;
  227. $cur->setting_type = $type;
  228. $cur->setting_label = $label;
  229. #If we are local, compare to global value
  230. if (!$global && $this->settingExists($id,true))
  231. {
  232. $g = $this->global_settings[$id];
  233. $same_setting = $g['ns'] == $this->ns && $g['value'] == $value
  234. && $g['type'] == $type && $g['label'] == $label;
  235. # Drop setting if same value as global
  236. if ($same_setting && $this->settingExists($id,false)) {
  237. $this->drop($id);
  238. } elseif ($same_setting) {
  239. return;
  240. }
  241. }
  242. if ($this->settingExists($id,$global) && $this->ns == $this->settings[$id]['ns'])
  243. {
  244. if ($global) {
  245. $where = 'WHERE blog_id IS NULL ';
  246. } else {
  247. $where = "WHERE blog_id = '".$this->con->escape($this->blog_id)."' ";
  248. }
  249. $cur->update($where."AND setting_id = '".$this->con->escape($id)."' AND setting_ns = '".$this->con->escape($this->ns)."' ");
  250. }
  251. else
  252. {
  253. $cur->setting_id = $id;
  254. $cur->blog_id = $global ? null : $this->blog_id;
  255. $cur->setting_ns = $this->ns;
  256. $cur->insert();
  257. }
  258. }
  259. /**
  260. Rename an existing setting in a Namespace
  261. @param $oldId <b>string</b> Current setting name
  262. @param $newId <b>string</b> New setting name
  263. @return <b>boolean</b>
  264. */
  265. public function rename($oldId,$newId)
  266. {
  267. if (!$this->ns) {
  268. throw new Exception(__('No namespace specified'));
  269. }
  270. if (!array_key_exists($oldId,$this->settings) || array_key_exists($newId,$this->settings)) {
  271. return false;
  272. }
  273. // Rename the setting in the settings array
  274. $this->settings[$newId] = $this->settings[$oldId];
  275. unset($this->settings[$oldId]);
  276. // Rename the setting in the database
  277. $strReq = 'UPDATE '.$this->table.
  278. " SET setting_id = '".$this->con->escape($newId)."' ".
  279. " WHERE setting_ns = '".$this->con->escape($this->ns)."' ".
  280. " AND setting_id = '".$this->con->escape($oldId)."' ";
  281. $this->con->execute($strReq);
  282. return true;
  283. }
  284. /**
  285. Removes an existing setting in a Namespace
  286. @param id <b>string</b> Setting ID
  287. */
  288. public function drop($id)
  289. {
  290. if (!$this->ns) {
  291. throw new Exception(__('No namespace specified'));
  292. }
  293. $strReq = 'DELETE FROM '.$this->table.' ';
  294. if ($this->blog_id === null) {
  295. $strReq .= 'WHERE blog_id IS NULL ';
  296. } else {
  297. $strReq .= "WHERE blog_id = '".$this->con->escape($this->blog_id)."' ";
  298. }
  299. $strReq .= "AND setting_id = '".$this->con->escape($id)."' ";
  300. $strReq .= "AND setting_ns = '".$this->con->escape($this->ns)."' ";
  301. $this->con->execute($strReq);
  302. }
  303. /**
  304. Removes all existing settings in a Namespace
  305. @param force_global <b>boolean</b> Force global pref drop
  306. */
  307. public function dropAll($force_global=false)
  308. {
  309. if (!$this->ns) {
  310. throw new Exception(__('No namespace specified'));
  311. }
  312. $strReq = 'DELETE FROM '.$this->table.' ';
  313. if (($force_global) || ($this->blog_id === null)) {
  314. $strReq .= 'WHERE blog_id IS NULL ';
  315. $global = true;
  316. } else {
  317. $strReq .= "WHERE blog_id = '".$this->con->escape($this->blog_id)."' ";
  318. $global = false;
  319. }
  320. $strReq .= "AND setting_ns = '".$this->con->escape($this->ns)."' ";
  321. $this->con->execute($strReq);
  322. $array = $global ? 'global' : 'local';
  323. unset($this->{$array.'_settings'});
  324. $this->{$array.'_settings'} = array();
  325. $array = $global ? 'local' : 'global';
  326. $this->settings = $this->{$array.'_settings'};
  327. }
  328. /**
  329. Returns $ns property content.
  330. @return <b>string</b>
  331. */
  332. public function dumpNamespace()
  333. {
  334. return $this->ns;
  335. }
  336. /**
  337. Returns $settings property content.
  338. @return <b>array</b>
  339. */
  340. public function dumpSettings()
  341. {
  342. return $this->settings;
  343. }
  344. /**
  345. Returns $local_settings property content.
  346. @return <b>array</b>
  347. */
  348. public function dumpLocalSettings()
  349. {
  350. return $this->local_settings;
  351. }
  352. /**
  353. Returns $global_settings property content.
  354. @return <b>array</b>
  355. */
  356. public function dumpGlobalSettings()
  357. {
  358. return $this->global_settings;
  359. }
  360. }