Dotclear

source: inc/core/class.dc.workspace.php @ 4001:a2dd2cb6fd33

Revision 4001:a2dd2cb6fd33, 13.3 KB checked in by franck <carnet.franck.paul@…>, 6 years ago (diff)

Add settings (in maintenance plugin) for CSP system

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

Sites map