Dotclear

source: inc/core/class.dc.settings.php @ 3730:5c45a5df9a59

Revision 3730:5c45a5df9a59, 14.2 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

Code formatting (PSR-2)

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    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;
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    {
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