Subversion Repositories oidplus

Rev

Rev 1050 | Rev 1116 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
1086 daniel-mar 5
 * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft
2 daniel-mar 6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
1050 daniel-mar 20
namespace ViaThinkSoft\OIDplus;
511 daniel-mar 21
 
1086 daniel-mar 22
// phpcs:disable PSR1.Files.SideEffects
23
\defined('INSIDE_OIDPLUS') or die;
24
// phpcs:enable PSR1.Files.SideEffects
25
 
261 daniel-mar 26
// OIDplusConfig contains settings that are stored in the database.
294 daniel-mar 27
// Not to be confused with OIDplusBaseConfig which is the basic ("static")
28
// configuration stored in userdata/baseconfig/config.inc.php,
261 daniel-mar 29
// e.g. database access credentials.
730 daniel-mar 30
class OIDplusConfig extends OIDplusBaseClass implements OIDplusGetterSetterInterface {
2 daniel-mar 31
 
269 daniel-mar 32
        /*public*/ const PROTECTION_EDITABLE = 0;
33
        /*public*/ const PROTECTION_READONLY = 1;
34
        /*public*/ const PROTECTION_HIDDEN   = 2;
263 daniel-mar 35
 
326 daniel-mar 36
        protected $configTableReadOnce = false; // this ensures that all $values and $descriptions were read
37
 
75 daniel-mar 38
        protected $values = array();
295 daniel-mar 39
        protected $descriptions = array();
682 daniel-mar 40
        protected $protectSettings = array();
41
        protected $visibleSettings = array();
263 daniel-mar 42
        protected $validateCallbacks = array();
13 daniel-mar 43
 
263 daniel-mar 44
        public function prepareConfigKey($name, $description, $init_value, $protection, $validateCallback) {
326 daniel-mar 45
                // Check if the protection flag is valid
263 daniel-mar 46
                switch ($protection) {
47
                        case OIDplusConfig::PROTECTION_EDITABLE:
48
                                $protected = 0;
49
                                $visible   = 1;
50
                                break;
51
                        case OIDplusConfig::PROTECTION_READONLY:
52
                                $protected = 1;
53
                                $visible   = 1;
54
                                break;
55
                        case OIDplusConfig::PROTECTION_HIDDEN:
56
                                $protected = 1;
57
                                $visible   = 0;
58
                                break;
59
                        default:
360 daniel-mar 60
                                throw new OIDplusException(_L('Invalid protection flag, use OIDplusConfig::PROTECTION_* constants'));
263 daniel-mar 61
                }
295 daniel-mar 62
 
326 daniel-mar 63
                // Check length limitations given by the database tables
166 daniel-mar 64
                if (strlen($name) > 50) {
360 daniel-mar 65
                        throw new OIDplusException(_L('Config key name "%1" is too long (max %2).',$name,50));
166 daniel-mar 66
                }
67
                if (strlen($description) > 255) {
360 daniel-mar 68
                        throw new OIDplusException(_L('Description for config key "%1" is too long (max %2).',$name,255));
166 daniel-mar 69
                }
326 daniel-mar 70
 
71
                // Read all values and descriptions from the database once.
150 daniel-mar 72
                $this->buildConfigArray();
326 daniel-mar 73
 
74
                // Figure out if we need to create/update something at database level
150 daniel-mar 75
                if (!isset($this->values[$name])) {
326 daniel-mar 76
                        // Case A: The config setting does not exist in the database. So we create it now.
614 daniel-mar 77
                        try {
78
                                OIDplus::db()->query("insert into ###config (name, description, value, protected, visible) values (?, ?, ?, ?, ?)", array($name, $description, $init_value, $protected, $visible));
1050 daniel-mar 79
                        } catch (\Exception $e) {
614 daniel-mar 80
                                // After a software update that introduced a new config setting,
81
                                // there will be a race-condition at this place, because
82
                                // jsTree and content are loading simultaneously!
83
                                // So we ignore the error here.
84
                        }
155 daniel-mar 85
                        $this->values[$name] = $init_value;
295 daniel-mar 86
                        $this->descriptions[$name] = $description;
682 daniel-mar 87
                        $this->protectSettings[$name] = $protected;
88
                        $this->visibleSettings[$name] = $visible;
326 daniel-mar 89
                } else {
90
                        // Case B: The config setting exists ...
91
                        if ($this->descriptions[$name] != $description) {
92
                                // ... but the human readable description is different.
93
                                // We want to give the plugin authors the possibility to automatically update the config descriptions for their plugins
94
                                // So we just edit the description
95
                                OIDplus::db()->query("update ###config set description = ? where name = ?", array($description, $name));
96
                                $this->descriptions[$name] = $description;
97
                        }
682 daniel-mar 98
                        if ($this->protectSettings[$name] != $protected) {
99
                                OIDplus::db()->query("update ###config set protected = ? where name = ?", array($protected, $name));
100
                                $this->protectSettings[$name] = $protected;
101
                        }
102
                        if ($this->visibleSettings[$name] != $visible) {
103
                                OIDplus::db()->query("update ###config set visible = ? where name = ?", array($visible, $name));
104
                                $this->visibleSettings[$name] = $visible;
105
                        }
150 daniel-mar 106
                }
326 daniel-mar 107
 
108
                // Register the validation callback
263 daniel-mar 109
                if (!is_null($validateCallback)) {
110
                        $this->validateCallbacks[$name] = $validateCallback;
111
                }
13 daniel-mar 112
        }
113
 
326 daniel-mar 114
        public function clearCache() {
115
                $this->configTableReadOnce = false;
116
                $this->buildConfigArray();
117
        }
118
 
150 daniel-mar 119
        protected function buildConfigArray() {
326 daniel-mar 120
                if ($this->configTableReadOnce) return;
121
 
122
                $this->values = array();
123
                $this->descriptions = array();
682 daniel-mar 124
                $this->protectSettings = array();
125
                $this->visibleSettings = array();
126
                $res = OIDplus::db()->query("select name, description, protected, visible, value from ###config");
326 daniel-mar 127
                while ($row = $res->fetch_object()) {
128
                        $this->values[$row->name] = $row->value;
129
                        $this->descriptions[$row->name] = $row->description;
682 daniel-mar 130
                        $this->protectSettings[$row->name] = $row->protected;
131
                        $this->visibleSettings[$row->name] = $row->visible;
75 daniel-mar 132
                }
326 daniel-mar 133
 
134
                $this->configTableReadOnce = true;
150 daniel-mar 135
        }
75 daniel-mar 136
 
261 daniel-mar 137
        public function getValue($name, $default=null) {
326 daniel-mar 138
                // Read all config settings once and write them in array $this->values
150 daniel-mar 139
                $this->buildConfigArray();
326 daniel-mar 140
 
141
                // Now we can see if our desired attribute is available
60 daniel-mar 142
                if (isset($this->values[$name])) {
143
                        return $this->values[$name];
144
                } else {
261 daniel-mar 145
                        return $default;
60 daniel-mar 146
                }
46 daniel-mar 147
        }
148
 
74 daniel-mar 149
        public function exists($name) {
326 daniel-mar 150
                return !is_null($this->getValue($name, null));
74 daniel-mar 151
        }
152
 
14 daniel-mar 153
        public function setValue($name, $value) {
574 daniel-mar 154
                // Read all config settings once and write them in array $this->values
155
                $this->buildConfigArray();
156
 
326 daniel-mar 157
                if (isset($this->values[$name])) {
574 daniel-mar 158
                        // Avoid unnecessary database writes
326 daniel-mar 159
                        if ($this->values[$name] == $value) return;
574 daniel-mar 160
                } else {
161
                        throw new OIDplusException(_L('Config value "%1" cannot be written because it was not prepared!', $name));
326 daniel-mar 162
                }
163
 
263 daniel-mar 164
                // Give plugins the possibility to stop the process by throwing an Exception (e.g. if the value is invalid)
326 daniel-mar 165
                // Required is that the plugin previously prepared the config setting using prepareConfigKey()
263 daniel-mar 166
                if (isset($this->validateCallbacks[$name])) {
167
                        $this->validateCallbacks[$name]($value);
14 daniel-mar 168
                }
257 daniel-mar 169
 
14 daniel-mar 170
                // Now change the value in the database
261 daniel-mar 171
                OIDplus::db()->query("update ###config set value = ? where name = ?", array($value, $name));
66 daniel-mar 172
                $this->values[$name] = $value;
14 daniel-mar 173
        }
174
 
672 daniel-mar 175
        public function setValueNoCallback($name, $value) {
176
                // Read all config settings once and write them in array $this->values
177
                $this->buildConfigArray();
178
 
179
                if (isset($this->values[$name])) {
180
                        // Avoid unnecessary database writes
181
                        if ($this->values[$name] == $value) return;
182
                } else {
183
                        throw new OIDplusException(_L('Config value "%1" cannot be written because it was not prepared!', $name));
184
                }
185
 
186
                // Now change the value in the database
187
                OIDplus::db()->query("update ###config set value = ? where name = ?", array($value, $name));
188
                $this->values[$name] = $value;
189
        }
190
 
569 daniel-mar 191
        public function delete($name) {
326 daniel-mar 192
                if ($this->configTableReadOnce) {
193
                        if (isset($this->values[$name])) {
194
                                OIDplus::db()->query("delete from ###config where name = ?", array($name));
195
                        }
196
                } else {
197
                        // We do not know if the value exists.
198
                        // buildConfigArray() would do many reads which are unnecessary.
199
                        // So we just do a MySQL command to delete the stuff:
294 daniel-mar 200
                        OIDplus::db()->query("delete from ###config where name = ?", array($name));
201
                }
326 daniel-mar 202
 
203
                unset($this->values[$name]);
204
                unset($this->descriptions[$name]);
205
                unset($this->validateCallbacks[$name]);
682 daniel-mar 206
                unset($this->protectSettings[$name]);
207
                unset($this->visibleSettings[$name]);
294 daniel-mar 208
        }
209
 
569 daniel-mar 210
}