Dotclear

source: inc/core/class.dc.namespace.php @ 3158:568e0d0e0991

Revision 3158:568e0d0e0991, 9.8 KB checked in by franck <carnet.franck.paul@…>, 10 years ago (diff)

Add new array type for settings and prefs, closes #1833 (thank's Dsls for code)

RevLine 
[0]1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Dotclear 2.
5#
[1179]6# Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear
[0]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
[2566]24
[0]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
[2566]29
[0]30     /**
31     Object constructor. Retrieves blog settings and puts them in $settings
32     array. Local (blog) settings have a highest priority than global settings.
[2566]33
[0]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          }
[2566]43
[0]44          $this->con =& $core->con;
45          $this->table = $core->prefix.'setting';
46          $this->blog_id =& $blog_id;
[2566]47
[0]48          $this->getSettings($rs);
49     }
[2566]50
[0]51     private function getSettings($rs=null)
[2566]52     {
[0]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 ';
[2566]61
[0]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');
[2566]76
[3158]77               if ($type == 'array') {
78                    $value = @json_decode($value);
79               } else {
80                    if ($type == 'float' || $type == 'double') {
81                         $type = 'float';
82                    } elseif ($type != 'boolean' && $type != 'integer') {
83                         $type = 'string';
84                    }
[0]85               }
[2566]86
[0]87               settype($value,$type);
[2566]88
[0]89               $array = $rs->blog_id ? 'local' : 'global';
[2566]90
[0]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          }
[2566]99
[0]100          $this->settings = $this->global_settings;
[2566]101
[0]102          foreach ($this->local_settings as $id => $v) {
103               $this->settings[$id] = $v;
104          }
[2566]105
[0]106          return true;
107     }
[2566]108
[0]109     private function settingExists($id,$global=false)
110     {
111          $array = $global ? 'global' : 'local';
112          return isset($this->{$array.'_settings'}[$id]);
113     }
[2566]114
[0]115     /**
116     Returns setting value if exists.
[2566]117
[0]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          }
[2566]126
[0]127          return null;
128     }
[2566]129
[0]130     /**
[2505]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
[1179]160     /**
[0]161     Magic __get method.
162     @copydoc ::get
163     */
164     public function __get($n)
165     {
166          return $this->get($n);
167     }
[2566]168
[0]169     /**
170     Sets a setting in $settings property. This sets the setting for script
171     execution time only and if setting exists.
[2566]172
[0]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     }
[2566]182
[0]183     /**
184     Magic __set method.
185     @copydoc ::set
186     */
187     public function __set($n,$v)
188     {
189          $this->set($n,$v);
190     }
[2566]191
[0]192     /**
193     Creates or updates a setting.
[2566]194
[0]195     $type could be 'string', 'integer', 'float', 'boolean' or null. If $type is
196     null and setting exists, it will keep current setting type.
[2566]197
[0]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.
[2566]200
[0]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          }
[2566]213
[0]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          }
[2566]223
[0]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                    $type = 'string';
237               }
238          }
[3158]239          elseif ($type != 'boolean' && $type != 'integer' && $type != 'float' && $type != 'array')
[0]240          {
241               $type = 'string';
242          }
[2566]243
[0]244          # We don't change label
245          if ($label == null)
246          {
247               if (!$global && $this->settingExists($id,false)) {
248                    $label = $this->local_settings[$id]['label'];
249               } elseif ($this->settingExists($id,true)) {
250                    $label = $this->global_settings[$id]['label'];
251               }
252          }
[2566]253
[3158]254          if ($type != 'array') {
255               settype($value,$type);
256          } else {
257               $value = json_encode($value);
258          }
[2566]259
[0]260          $cur = $this->con->openCursor($this->table);
261          $cur->setting_value = ($type == 'boolean') ? (string) (integer) $value : (string) $value;
262          $cur->setting_type = $type;
263          $cur->setting_label = $label;
[2566]264
[0]265          #If we are local, compare to global value
266          if (!$global && $this->settingExists($id,true))
267          {
268               $g = $this->global_settings[$id];
269               $same_setting = $g['ns'] == $this->ns && $g['value'] == $value
270               && $g['type'] == $type && $g['label'] == $label;
[2566]271
[0]272               # Drop setting if same value as global
273               if ($same_setting && $this->settingExists($id,false)) {
274                    $this->drop($id);
275               } elseif ($same_setting) {
276                    return;
277               }
278          }
[2566]279
[0]280          if ($this->settingExists($id,$global) && $this->ns == $this->settings[$id]['ns'])
281          {
282               if ($global) {
283                    $where = 'WHERE blog_id IS NULL ';
284               } else {
285                    $where = "WHERE blog_id = '".$this->con->escape($this->blog_id)."' ";
286               }
[2566]287
[0]288               $cur->update($where."AND setting_id = '".$this->con->escape($id)."' AND setting_ns = '".$this->con->escape($this->ns)."' ");
289          }
290          else
291          {
292               $cur->setting_id = $id;
293               $cur->blog_id = $global ? null : $this->blog_id;
294               $cur->setting_ns = $this->ns;
[2566]295
[0]296               $cur->insert();
297          }
298     }
[934]299
[0]300     /**
[934]301     Rename an existing setting in a Namespace
302
303     @param    $oldId    <b>string</b>  Current setting name
304     @param    $newId    <b>string</b>  New setting name
305     @return   <b>boolean</b>
306     */
307     public function rename($oldId,$newId)
308     {
309          if (!$this->ns) {
310               throw new Exception(__('No namespace specified'));
311          }
[2566]312
[934]313          if (!array_key_exists($oldId,$this->settings) || array_key_exists($newId,$this->settings)) {
314               return false;
315          }
316
317          // Rename the setting in the settings array
318          $this->settings[$newId] = $this->settings[$oldId];
319          unset($this->settings[$oldId]);
320
321          // Rename the setting in the database
322          $strReq = 'UPDATE '.$this->table.
323               " SET setting_id = '".$this->con->escape($newId)."' ".
324               " WHERE setting_ns = '".$this->con->escape($this->ns)."' ".
325               " AND setting_id = '".$this->con->escape($oldId)."' ";
326          $this->con->execute($strReq);
327          return true;
328     }
329
330     /**
[2566]331     Removes an existing setting in a Namespace
332
[0]333     @param    id        <b>string</b>       Setting ID
334     */
335     public function drop($id)
336     {
337          if (!$this->ns) {
338               throw new Exception(__('No namespace specified'));
339          }
[2566]340
[0]341          $strReq = 'DELETE FROM '.$this->table.' ';
[2566]342
[0]343          if ($this->blog_id === null) {
344               $strReq .= 'WHERE blog_id IS NULL ';
345          } else {
346               $strReq .= "WHERE blog_id = '".$this->con->escape($this->blog_id)."' ";
347          }
[2566]348
[0]349          $strReq .= "AND setting_id = '".$this->con->escape($id)."' ";
350          $strReq .= "AND setting_ns = '".$this->con->escape($this->ns)."' ";
[2566]351
[0]352          $this->con->execute($strReq);
353     }
[2566]354
[0]355     /**
[2566]356     Removes all existing settings in a Namespace
357
[934]358     @param    force_global   <b>boolean</b> Force global pref drop
359     */
360     public function dropAll($force_global=false)
361     {
362          if (!$this->ns) {
363               throw new Exception(__('No namespace specified'));
364          }
[2566]365
[934]366          $strReq = 'DELETE FROM '.$this->table.' ';
[2566]367
[934]368          if (($force_global) || ($this->blog_id === null)) {
369               $strReq .= 'WHERE blog_id IS NULL ';
370               $global = true;
371          } else {
372               $strReq .= "WHERE blog_id = '".$this->con->escape($this->blog_id)."' ";
373               $global = false;
374          }
[2566]375
[934]376          $strReq .= "AND setting_ns = '".$this->con->escape($this->ns)."' ";
[2566]377
[934]378          $this->con->execute($strReq);
[2566]379
[934]380          $array = $global ? 'global' : 'local';
381          unset($this->{$array.'_settings'});
382          $this->{$array.'_settings'} = array();
[2566]383
[934]384          $array = $global ? 'local' : 'global';
385          $this->settings = $this->{$array.'_settings'};
386     }
[2566]387
[934]388     /**
[0]389     Returns $settings property content.
[2566]390
[0]391     @return   <b>array</b>
392     */
393     public function dumpSettings()
394     {
395          return $this->settings;
396     }
[2566]397
[0]398     /**
399     Returns $global_settings property content.
[2566]400
[0]401     @return   <b>array</b>
402     */
403     public function dumpGlobalSettings()
404     {
405          return $this->global_settings;
406     }
407
408}
Note: See TracBrowser for help on using the repository browser.

Sites map