Dotclear

source: inc/core/class.dc.namespace.php @ 3203:fef95060f0b0

Revision 3203:fef95060f0b0, 9.9 KB checked in by franck <carnet.franck.paul@…>, 9 years ago (diff)

New array setting/pref are stored with 'array' type rather than 'string'

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

Sites map