Dotclear

source: inc/core/class.dc.settings.php @ 2989:e039b91d334e

Revision 2989:e039b91d334e, 11.9 KB checked in by Nicolas <nikrou77@…>, 10 years ago (diff)

Use dcCore pass as argument to constructor instead of global one.

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 settings handler
17
18dcSettings provides blog settings management. This class instance exists as
19dcBlog $settings property. You should create a new settings instance when
20updating another blog settings.
21*/
22class dcSettings
23{
24     protected $con;          ///< <b>connection</b> Database connection object
25     protected $table;        ///< <b>string</b> Settings table name
26     protected $blog_id;      ///< <b>string</b> Blog ID
27
28     protected $namespaces = array();        ///< <b>array</b> Associative namespaces array
29
30     protected $ns;           ///< <b>string</b> Current namespace
31
32     /**
33     Object constructor. Retrieves blog settings and puts them in $namespaces
34     array. Local (blog) settings have a highest priority than global settings.
35
36     @param    core      <b>dcCore</b>       dcCore object
37     @param    blog_id   <b>string</b>       Blog ID
38     */
39     public function __construct($core,$blog_id)
40     {
41          $this->core = &$core;
42          $this->con = &$core->con;
43          $this->table = $core->prefix.'setting';
44          $this->blog_id = &$blog_id;
45          $this->loadSettings();
46     }
47
48     /**
49     Retrieves all namespaces (and their settings) from database, with one query.
50     */
51     private function loadSettings()
52     {
53          $strReq = 'SELECT blog_id, setting_id, setting_value, '.
54                    'setting_type, setting_label, setting_ns '.
55                    'FROM '.$this->table.' '.
56                    "WHERE blog_id = '".$this->con->escape($this->blog_id)."' ".
57                    'OR blog_id IS NULL '.
58                    'ORDER BY setting_ns ASC, setting_id DESC';
59          try {
60               $rs = $this->con->select($strReq);
61          } catch (Exception $e) {
62               trigger_error(__('Unable to retrieve namespaces:').' '.$this->con->error(), E_USER_ERROR);
63          }
64
65          /* Prevent empty tables (install phase, for instance) */
66          if ($rs->isEmpty()) {
67               return;
68          }
69
70          do {
71               $ns = trim($rs->f('setting_ns'));
72               if (!$rs->isStart()) {
73                    // we have to go up 1 step, since namespaces construction performs a fetch()
74                    // at very first time
75                    $rs->movePrev();
76               }
77               $this->namespaces[$ns] = new dcNamespace($this->core, $this->blog_id, $ns,$rs);
78          } while(!$rs->isStart());
79     }
80
81
82     /**
83     Create a new namespace. If the namespace already exists, return it without modification.
84
85     @param    ns   <b>string</b>       Namespace name
86     @return   <b>dcNamespace</b>  The namespace created
87     */
88     public function addNamespace($ns)
89     {
90          if (!array_key_exists($ns, $this->namespaces)) {
91               $this->namespaces[$ns] = new dcNamespace($this->core, $this->blog_id, $ns);
92          }
93          return $this->namespaces[$ns];
94     }
95
96     /**
97     Rename a namespace.
98
99     @param    oldNs     <b>string</b>  Old namespace name
100     @param    newNs     <b>string</b>  New namespace name
101     @return   <b>boolean</b>
102     */
103     public function renNamespace($oldNs,$newNs)
104     {
105          if (!array_key_exists($oldNs, $this->namespaces) || array_key_exists($newNs, $this->namespaces)) {
106               return false;
107          }
108
109          // Rename the namespace in the namespace array
110          $this->namespaces[$newNs] = $this->namespaces[$oldNs];
111          unset($this->namespaces[$oldNs]);
112
113          // Rename the namespace in the database
114          $strReq = 'UPDATE '.$this->table.
115               " SET setting_ns = '".$this->con->escape($newNs)."' ".
116               " WHERE setting_ns = '".$this->con->escape($oldNs)."' ";
117          $this->con->execute($strReq);
118          return true;
119     }
120
121     /**
122     Delete a whole namespace with all settings pertaining to it.
123
124     @param    ns   <b>string</b>  Namespace name
125     @return   <b>boolean</b>
126     */
127     public function delNamespace($ns)
128     {
129          if (!array_key_exists($ns, $this->namespaces)) {
130               return false;
131          }
132
133          // Remove the namespace from the namespace array
134          unset($this->namespaces[$ns]);
135
136          // Delete all settings from the namespace in the database
137          $strReq = 'DELETE FROM '.$this->table.
138               " WHERE setting_ns = '".$this->con->escape($ns)."' ";
139          $this->con->execute($strReq);
140          return true;
141     }
142
143     /**
144     Returns full namespace with all settings pertaining to it.
145
146     @param    ns   <b>string</b>       Namespace name
147     @return   <b>dcNamespace</b>
148     */
149     public function get($ns)
150     {
151          return $this->namespaces[$ns];
152     }
153
154     /**
155     Magic __get method.
156     @copydoc ::get
157     */
158     public function __get($n)
159     {
160          if (!array_key_exists($n, $this->namespaces)) {
161               // For backward compatibility only: the developer tried to access
162               // a setting directly, without passing via a namespace.
163               $this->raiseDeprecated('old_style_get');
164               return $this->getSetting($n);
165          }
166          return $this->get($n);
167     }
168
169     /**
170     Magic __set method.
171     @copydoc ::set
172     */
173     public function __set($n,$v)
174     {
175          $this->set($n,$v);
176     }
177
178     /**
179     Returns $namespaces property content.
180
181     @return   <b>array</b>
182     */
183     public function dumpNamespaces()
184     {
185          return $this->namespaces;
186     }
187
188     /**
189     Raises a E_USER_NOTICE errror for deprecated functions.
190     This allows the developer to know he's been using deprecated functions.
191
192     @param    name <b>string</b>  Name of the deprecated function that was called.
193     */
194     private function raiseDeprecated($name)
195     {
196          if (DC_DEBUG) {
197               $trace = debug_backtrace();
198               array_shift($trace);
199               $grand = array_shift($trace);
200               $msg = 'Deprecated function called. (';
201               $msg .= 'dcSettings::'.$name . ' was called from '.$grand['file'].' ['.$grand['line'].'])';
202               trigger_error($msg, E_USER_NOTICE);
203          }
204     }
205
206     /**
207     @deprecated Please set your settings via $core->blog->settings->{namespace}->{setting}
208
209     Sets a setting in $settings property. This sets the setting for script
210     execution time only and if setting exists.
211
212     @param    n         <b>string</b>       Setting name
213     @param    v         <b>mixed</b>        Setting value
214     */
215     public function set($n,$v)
216     {
217          // For backward compatibility only: the developer tried to access
218          // a setting directly, without passing via a namespace.
219          $this->raiseDeprecated('old_style_set');
220
221          if (!$this->ns) {
222               throw new Exception(__('No namespace specified'));
223          }
224
225          if (isset($this->namespaces[$this->ns]->$n)) {
226               $this->namespaces[$this->ns]->$n['value'] = $v;
227          } else {
228               $this->namespaces[$this->ns]->$n = array(
229                    'ns' => $this->ns,
230                    'value' => $v,
231                    'type' => gettype($n),
232                    'label' => '',
233                    'global' => false
234               );
235          }
236     }
237
238     /**
239     @deprecated Please access your settings via $core->blog->settings->{namespace}->...
240
241     Sets a working namespace. You should do this before accessing any setting.
242
243     @param    ns        <b>string</b>       Namespace name
244     */
245     public function setNamespace($ns)
246     {
247          $this->raiseDeprecated('setNamespace');
248          if (preg_match('/^[a-zA-Z][a-zA-Z0-9]+$/',$ns)) {
249               $this->ns = $ns;
250          } else {
251               throw new Exception(sprintf(__('Invalid setting namespace: %s'),$ns));
252          }
253     }
254
255     /**
256     @deprecated Please set your settings via $core->blog->settings->{namespace}->put()
257
258     Creates or updates a setting.
259
260     $type could be 'string', 'integer', 'float', 'boolean' or null. If $type is
261     null and setting exists, it will keep current setting type.
262
263     $value_change allow you to not change setting. Useful if you need to change
264     a setting label or type and don't want to change its value.
265
266     Don't forget to set namespace before calling this method.
267
268     @param    id             <b>string</b>       Setting ID
269     @param    value          <b>mixed</b>        Setting value
270     @param    type           <b>string</b>       Setting type
271     @param    label          <b>string</b>       Setting label
272     @param    value_change   <b>boolean</b>      Change setting value or not
273     @param    global         <b>boolean</b>      Setting is global
274     */
275     public function put($id,$value,$type=null,$label=null,$value_change=true,$global=false)
276     {
277          $this->raiseDeprecated('put');
278          if (!$this->ns) {
279               throw new Exception(__('No namespace specified'));
280          }
281          if (!isset($this->namespaces[$this->ns])) {
282               // Create namespace if needed
283               $this->namespaces[$this->ns] = new dcNamespace($this->core, $this->blog_id, $this->ns);
284          }
285          $this->namespaces[$this->ns]->put($id, $value, $type, $label, $value_change, $global);
286     }
287
288     /**
289     @deprecated Please get your settings via $core->blog->settings->{namespace}->{setting}
290
291     Returns setting value if exists.
292
293     @param    n         <b>string</b>       Setting name
294     @return   <b>mixed</b>
295     */
296     public function getSetting($n)
297     {
298          if ($this->namespaces['system']->get($n) != null) {
299               // Give preference to system settings
300               return $this->namespaces['system']->get($n);
301          } else {
302               // Parse all the namespaces
303               foreach (array_keys($this->namespaces) as $id => $ns) {
304                    if ($this->namespaces[$ns]->get($n) != null) {
305                         // Return the first setting with matching name
306                         return $this->namespaces[$ns]->get($n);
307                    }
308               }
309          }
310
311          return null;
312     }
313
314     /**
315     @deprecated Please get your settings via $core->blog->settings->{namespace}->dumpSettings
316
317     Returns all settings content.
318
319     @return   <b>array</b>
320     */
321     public function dumpSettings()
322     {
323          // For backward compatibility only: the developer tried to access
324          // the settings directly, without passing via a namespace.
325          $this->raiseDeprecated('dumpSettings');
326
327          $settings = array();
328          // Parse all the namespaces
329          foreach (array_keys($this->namespaces) as $id => $ns) {
330               $settings = array_merge($settings, $this->namespaces[$ns]->dumpSettings());
331          }
332
333          return $settings;
334     }
335
336     /**
337     @deprecated Please get your settings via $core->blog->settings->{namespace}->dumpGlobalSettings
338
339     Returns all global settings content.
340
341     @return   <b>array</b>
342     */
343     public function dumpGlobalSettings()
344     {
345          // For backward compatibility only: the developer tried to access
346          // the settings directly, without passing via a namespace.
347          $this->raiseDeprecated('dumpGlobalSettings');
348
349          $settings = array();
350          // Parse all the namespaces
351          foreach (array_keys($this->namespaces) as $id => $ns) {
352               $settings = array_merge($settings, $this->namespaces[$ns]->dumpGlobalSettings());
353          }
354
355          return $settings;
356     }
357
358     /**
359     Returns a list of settings matching given criteria, for any blog.
360     <b>$params</b> is an array taking the following
361     optionnal parameters:
362
363     - ns : retrieve setting from given namespace
364     - id : retrieve only settings corresponding to the given id
365
366     @param    params         <b>array</b>        Parameters
367     @return   <b>record</b>  A record
368     */
369     public function getGlobalSettings($params=array())
370     {
371          $strReq = "SELECT * from ".$this->table." ";
372          $where = array();
373          if (!empty($params['ns'])) {
374               $where[] = "setting_ns = '".$this->con->escape($params['ns'])."'";
375          }
376          if (!empty($params['id'])) {
377               $where[] = "setting_id = '".$this->con->escape($params['id'])."'";
378          }
379          if (isset($params['blog_id'])) {
380               if (!empty($params['blog_id'])) {
381                    $where[] = "blog_id = '".$this->con->escape($params['blog_id'])."'";
382               } else {
383                    $where[] = "blog_id IS NULL";
384               }
385          }
386          if (count($where) != 0) {
387               $strReq .= " WHERE ".join(" AND ", $where);
388          }
389          $strReq .= " ORDER by blog_id";
390          return $this->con->select($strReq);
391     }
392
393     /**
394     Updates a setting from a given record
395
396     @param    rs        <b>record</b>       the setting to update
397     */
398     public function updateSetting($rs)
399     {
400          $cur = $this->con->openCursor($this->table);
401          $cur->setting_id = $rs->setting_id;
402          $cur->setting_value = $rs->setting_value;
403          $cur->setting_type = $rs->setting_type;
404          $cur->setting_label = $rs->setting_label;
405          $cur->blog_id = $rs->blog_id;
406          $cur->setting_ns = $rs->setting_ns;
407          if ($cur->blog_id == null) {
408                    $where = 'WHERE blog_id IS NULL ';
409          } else {
410               $where = "WHERE blog_id = '".$this->con->escape($cur->blog_id)."' ";
411          }
412          $cur->update($where."AND setting_id = '".$this->con->escape($cur->setting_id)."' AND setting_ns = '".$this->con->escape($cur->setting_ns)."' ");
413     }
414
415     /**
416     Drops a setting from a given record
417
418     @param    rs        <b>record</b>       the setting to drop
419     @return   int       number of deleted records (0 if setting does not exist)
420     */
421     public function dropSetting($rs) {
422          $strReq = "DELETE FROM ".$this->table.' ';
423          if ($rs->blog_id == null) {
424               $strReq .= 'WHERE blog_id IS NULL ';
425          } else {
426               $strReq .= "WHERE blog_id = '".$this->con->escape($rs->blog_id)."' ";
427          }
428          $strReq .= "AND setting_id = '".$this->con->escape($rs->setting_id)."' AND setting_ns = '".$this->con->escape($rs->setting_ns)."' ";
429          return $this->con->execute($strReq);
430     }
431}
Note: See TracBrowser for help on using the repository browser.

Sites map