Dotclear

source: inc/core/class.dc.settings.php @ 2991:bcd75776d061

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

Use dcCore pass as argument to constructor instead of global one.
$core property must be at least protected to not be considered as a settings.

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

Sites map