PageRenderTime 58ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/inc/core/class.dc.workspace.php

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