Dotclear

source: inc/core/class.dc.workspace.php @ 3159:a7553434ee4c

Revision 3159:a7553434ee4c, 10.1 KB checked in by franck <carnet.franck.paul@…>, 10 years ago (diff)

Use new setting type 'array' for some settings, addresses #1833

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

Sites map