Dotclear

source: inc/core/class.dc.namespace.php @ 3731:3770620079d4

Revision 3731:3770620079d4, 12.3 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

Simplify licence block at the beginning of each file

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    private function settingExists($id, $global = false)
104    {
105        $array = $global ? 'global' : 'local';
106        return isset($this->{$array . '_settings'}[$id]);
107    }
108
109    /**
110    Returns setting value if exists.
111
112    @param    n        <b>string</b>        Setting name
113    @return    <b>mixed</b>
114     */
115    public function get($n)
116    {
117        if (isset($this->settings[$n]['value'])) {
118            return $this->settings[$n]['value'];
119        }
120
121        return;
122    }
123
124    /**
125    Returns global setting value if exists.
126
127    @param    n        <b>string</b>        setting name
128    @return    <b>mixed</b>
129     */
130    public function getGlobal($n)
131    {
132        if (isset($this->global_settings[$n]['value'])) {
133            return $this->global_settings[$n]['value'];
134        }
135
136        return;
137    }
138
139    /**
140    Returns local setting value if exists.
141
142    @param    n        <b>string</b>        setting name
143    @return    <b>mixed</b>
144     */
145    public function getLocal($n)
146    {
147        if (isset($this->local_settings[$n]['value'])) {
148            return $this->local_settings[$n]['value'];
149        }
150
151        return;
152    }
153
154    /**
155    Magic __get method.
156    @copydoc ::get
157     */
158    public function __get($n)
159    {
160        return $this->get($n);
161    }
162
163    /**
164    Sets a setting in $settings property. This sets the setting for script
165    execution time only and if setting exists.
166
167    @param    n        <b>string</b>        Setting name
168    @param    v        <b>mixed</b>        Setting value
169     */
170    public function set($n, $v)
171    {
172        if (isset($this->settings[$n])) {
173            $this->settings[$n]['value'] = $v;
174        }
175    }
176
177    /**
178    Magic __set method.
179    @copydoc ::set
180     */
181    public function __set($n, $v)
182    {
183        $this->set($n, $v);
184    }
185
186    /**
187    Creates or updates a setting.
188
189    $type could be 'string', 'integer', 'float', 'boolean' or null. If $type is
190    null and setting exists, it will keep current setting type.
191
192    $value_change allow you to not change setting. Useful if you need to change
193    a setting label or type and don't want to change its value.
194
195    @param    id            <b>string</b>        Setting ID
196    @param    value        <b>mixed</b>        Setting value
197    @param    type            <b>string</b>        Setting type
198    @param    label        <b>string</b>        Setting label
199    @param    value_change    <b>boolean</b>        Change setting value or not
200    @param    global        <b>boolean</b>        Setting is global
201     */
202    public function put($id, $value, $type = null, $label = null, $value_change = true, $global = false)
203    {
204        if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]+$/', $id)) {
205            throw new Exception(sprintf(__('%s is not a valid setting id'), $id));
206        }
207
208        # We don't want to change setting value
209        if (!$value_change) {
210            if (!$global && $this->settingExists($id, false)) {
211                $value = $this->local_settings[$id]['value'];
212            } elseif ($this->settingExists($id, true)) {
213                $value = $this->global_settings[$id]['value'];
214            }
215        }
216
217        # Setting type
218        if ($type == 'double') {
219            $type = 'float';
220        } elseif ($type === null) {
221            if (!$global && $this->settingExists($id, false)) {
222                $type = $this->local_settings[$id]['type'];
223            } elseif ($this->settingExists($id, true)) {
224                $type = $this->global_settings[$id]['type'];
225            } else {
226                if (is_array($value)) {
227                    $type = 'array';
228                } else {
229                    $type = 'string';
230                }
231            }
232        } elseif ($type != 'boolean' && $type != 'integer' && $type != 'float' && $type != 'array') {
233            $type = 'string';
234        }
235
236        # We don't change label
237        if ($label == null) {
238            if (!$global && $this->settingExists($id, false)) {
239                $label = $this->local_settings[$id]['label'];
240            } elseif ($this->settingExists($id, true)) {
241                $label = $this->global_settings[$id]['label'];
242            }
243        }
244
245        if ($type != 'array') {
246            settype($value, $type);
247        } else {
248            $value = json_encode($value);
249        }
250
251        $cur                = $this->con->openCursor($this->table);
252        $cur->setting_value = ($type == 'boolean') ? (string) (integer) $value : (string) $value;
253        $cur->setting_type  = $type;
254        $cur->setting_label = $label;
255
256        #If we are local, compare to global value
257        if (!$global && $this->settingExists($id, true)) {
258            $g            = $this->global_settings[$id];
259            $same_setting = $g['ns'] == $this->ns && $g['value'] == $value
260                && $g['type'] == $type && $g['label'] == $label;
261
262            # Drop setting if same value as global
263            if ($same_setting && $this->settingExists($id, false)) {
264                $this->drop($id);
265            } elseif ($same_setting) {
266                return;
267            }
268        }
269
270        if ($this->settingExists($id, $global) && $this->ns == $this->settings[$id]['ns']) {
271            if ($global) {
272                $where = 'WHERE blog_id IS NULL ';
273            } else {
274                $where = "WHERE blog_id = '" . $this->con->escape($this->blog_id) . "' ";
275            }
276
277            $cur->update($where . "AND setting_id = '" . $this->con->escape($id) . "' AND setting_ns = '" . $this->con->escape($this->ns) . "' ");
278        } else {
279            $cur->setting_id = $id;
280            $cur->blog_id    = $global ? null : $this->blog_id;
281            $cur->setting_ns = $this->ns;
282
283            $cur->insert();
284        }
285    }
286
287    /**
288    Rename an existing setting in a Namespace
289
290    @param     $oldId     <b>string</b>     Current setting name
291    @param     $newId     <b>string</b>     New setting name
292    @return     <b>boolean</b>
293     */
294    public function rename($oldId, $newId)
295    {
296        if (!$this->ns) {
297            throw new Exception(__('No namespace specified'));
298        }
299
300        if (!array_key_exists($oldId, $this->settings) || array_key_exists($newId, $this->settings)) {
301            return false;
302        }
303
304        // Rename the setting in the settings array
305        $this->settings[$newId] = $this->settings[$oldId];
306        unset($this->settings[$oldId]);
307
308        // Rename the setting in the database
309        $strReq = 'UPDATE ' . $this->table .
310        " SET setting_id = '" . $this->con->escape($newId) . "' " .
311        " WHERE setting_ns = '" . $this->con->escape($this->ns) . "' " .
312        " AND setting_id = '" . $this->con->escape($oldId) . "' ";
313        $this->con->execute($strReq);
314        return true;
315    }
316
317    /**
318    Removes an existing setting in a Namespace
319
320    @param    id        <b>string</b>        Setting ID
321     */
322    public function drop($id)
323    {
324        if (!$this->ns) {
325            throw new Exception(__('No namespace specified'));
326        }
327
328        $strReq = 'DELETE FROM ' . $this->table . ' ';
329
330        if ($this->blog_id === null) {
331            $strReq .= 'WHERE blog_id IS NULL ';
332        } else {
333            $strReq .= "WHERE blog_id = '" . $this->con->escape($this->blog_id) . "' ";
334        }
335
336        $strReq .= "AND setting_id = '" . $this->con->escape($id) . "' ";
337        $strReq .= "AND setting_ns = '" . $this->con->escape($this->ns) . "' ";
338
339        $this->con->execute($strReq);
340    }
341
342    /**
343    Removes all existing settings in a Namespace
344
345    @param    force_global    <b>boolean</b>    Force global pref drop
346     */
347    public function dropAll($force_global = false)
348    {
349        if (!$this->ns) {
350            throw new Exception(__('No namespace specified'));
351        }
352
353        $strReq = 'DELETE FROM ' . $this->table . ' ';
354
355        if (($force_global) || ($this->blog_id === null)) {
356            $strReq .= 'WHERE blog_id IS NULL ';
357            $global = true;
358        } else {
359            $strReq .= "WHERE blog_id = '" . $this->con->escape($this->blog_id) . "' ";
360            $global = false;
361        }
362
363        $strReq .= "AND setting_ns = '" . $this->con->escape($this->ns) . "' ";
364
365        $this->con->execute($strReq);
366
367        $array = $global ? 'global' : 'local';
368        unset($this->{$array . '_settings'});
369        $this->{$array . '_settings'} = array();
370
371        $array          = $global ? 'local' : 'global';
372        $this->settings = $this->{$array . '_settings'};
373    }
374
375    /**
376    Returns $ns property content.
377
378    @return    <b>string</b>
379     */
380    public function dumpNamespace()
381    {
382        return $this->ns;
383    }
384
385    /**
386    Returns $settings property content.
387
388    @return    <b>array</b>
389     */
390    public function dumpSettings()
391    {
392        return $this->settings;
393    }
394
395    /**
396    Returns $local_settings property content.
397
398    @return    <b>array</b>
399     */
400    public function dumpLocalSettings()
401    {
402        return $this->local_settings;
403    }
404
405    /**
406    Returns $global_settings property content.
407
408    @return    <b>array</b>
409     */
410    public function dumpGlobalSettings()
411    {
412        return $this->global_settings;
413    }
414
415}
Note: See TracBrowser for help on using the repository browser.

Sites map