Dotclear

source: inc/core/class.dc.namespace.php @ 3773:69941ff7dc4d

Revision 3773:69941ff7dc4d, 12.5 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

Switch settingsExists method from private to public, closes #2273

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

Sites map