Rev 326 | Rev 511 | 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 |
||
5 | * Copyright 2019 Daniel Marschall, ViaThinkSoft |
||
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 | |||
261 | daniel-mar | 20 | // OIDplusConfig contains settings that are stored in the database. |
294 | daniel-mar | 21 | // Not to be confused with OIDplusBaseConfig which is the basic ("static") |
22 | // configuration stored in userdata/baseconfig/config.inc.php, |
||
261 | daniel-mar | 23 | // e.g. database access credentials. |
24 | class OIDplusConfig implements OIDplusConfigInterface { |
||
2 | daniel-mar | 25 | |
269 | daniel-mar | 26 | /*public*/ const PROTECTION_EDITABLE = 0; |
27 | /*public*/ const PROTECTION_READONLY = 1; |
||
28 | /*public*/ const PROTECTION_HIDDEN = 2; |
||
263 | daniel-mar | 29 | |
326 | daniel-mar | 30 | protected $configTableReadOnce = false; // this ensures that all $values and $descriptions were read |
31 | |||
75 | daniel-mar | 32 | protected $values = array(); |
295 | daniel-mar | 33 | protected $descriptions = array(); |
263 | daniel-mar | 34 | protected $validateCallbacks = array(); |
13 | daniel-mar | 35 | |
263 | daniel-mar | 36 | public function prepareConfigKey($name, $description, $init_value, $protection, $validateCallback) { |
326 | daniel-mar | 37 | // Check if the protection flag is valid |
263 | daniel-mar | 38 | switch ($protection) { |
39 | case OIDplusConfig::PROTECTION_EDITABLE: |
||
40 | $protected = 0; |
||
41 | $visible = 1; |
||
42 | break; |
||
43 | case OIDplusConfig::PROTECTION_READONLY: |
||
44 | $protected = 1; |
||
45 | $visible = 1; |
||
46 | break; |
||
47 | case OIDplusConfig::PROTECTION_HIDDEN: |
||
48 | $protected = 1; |
||
49 | $visible = 0; |
||
50 | break; |
||
51 | default: |
||
360 | daniel-mar | 52 | throw new OIDplusException(_L('Invalid protection flag, use OIDplusConfig::PROTECTION_* constants')); |
263 | daniel-mar | 53 | } |
295 | daniel-mar | 54 | |
326 | daniel-mar | 55 | // Check length limitations given by the database tables |
166 | daniel-mar | 56 | if (strlen($name) > 50) { |
360 | daniel-mar | 57 | throw new OIDplusException(_L('Config key name "%1" is too long (max %2).',$name,50)); |
166 | daniel-mar | 58 | } |
59 | if (strlen($description) > 255) { |
||
360 | daniel-mar | 60 | throw new OIDplusException(_L('Description for config key "%1" is too long (max %2).',$name,255)); |
166 | daniel-mar | 61 | } |
326 | daniel-mar | 62 | |
63 | // Read all values and descriptions from the database once. |
||
150 | daniel-mar | 64 | $this->buildConfigArray(); |
326 | daniel-mar | 65 | |
66 | // Figure out if we need to create/update something at database level |
||
150 | daniel-mar | 67 | if (!isset($this->values[$name])) { |
326 | daniel-mar | 68 | // Case A: The config setting does not exist in the database. So we create it now. |
261 | daniel-mar | 69 | OIDplus::db()->query("insert into ###config (name, description, value, protected, visible) values (?, ?, ?, ?, ?)", array($name, $description, $init_value, $protected, $visible)); |
155 | daniel-mar | 70 | $this->values[$name] = $init_value; |
295 | daniel-mar | 71 | $this->descriptions[$name] = $description; |
326 | daniel-mar | 72 | } else { |
73 | // Case B: The config setting exists ... |
||
74 | if ($this->descriptions[$name] != $description) { |
||
75 | // ... but the human readable description is different. |
||
76 | // We want to give the plugin authors the possibility to automatically update the config descriptions for their plugins |
||
77 | // So we just edit the description |
||
78 | OIDplus::db()->query("update ###config set description = ? where name = ?", array($description, $name)); |
||
79 | $this->descriptions[$name] = $description; |
||
80 | } |
||
150 | daniel-mar | 81 | } |
326 | daniel-mar | 82 | |
83 | // Register the validation callback |
||
263 | daniel-mar | 84 | if (!is_null($validateCallback)) { |
85 | $this->validateCallbacks[$name] = $validateCallback; |
||
86 | } |
||
13 | daniel-mar | 87 | } |
88 | |||
326 | daniel-mar | 89 | public function clearCache() { |
90 | $this->configTableReadOnce = false; |
||
91 | $this->buildConfigArray(); |
||
92 | } |
||
93 | |||
150 | daniel-mar | 94 | protected function buildConfigArray() { |
326 | daniel-mar | 95 | if ($this->configTableReadOnce) return; |
96 | |||
97 | $this->values = array(); |
||
98 | $this->descriptions = array(); |
||
99 | $res = OIDplus::db()->query("select name, description, value from ###config"); |
||
100 | while ($row = $res->fetch_object()) { |
||
101 | $this->values[$row->name] = $row->value; |
||
102 | $this->descriptions[$row->name] = $row->description; |
||
75 | daniel-mar | 103 | } |
326 | daniel-mar | 104 | |
105 | $this->configTableReadOnce = true; |
||
150 | daniel-mar | 106 | } |
75 | daniel-mar | 107 | |
261 | daniel-mar | 108 | public function getValue($name, $default=null) { |
326 | daniel-mar | 109 | if (isset($this->values[$name])) { |
110 | // There is a rare case where this might succeed even |
||
111 | // before buildConfigArray() was called once: |
||
112 | // If a setValue() was called, and then getValue() for |
||
113 | // that same name! |
||
114 | return $this->values[$name]; |
||
115 | } |
||
116 | |||
117 | // Read all config settings once and write them in array $this->values |
||
150 | daniel-mar | 118 | $this->buildConfigArray(); |
326 | daniel-mar | 119 | |
120 | // Now we can see if our desired attribute is available |
||
60 | daniel-mar | 121 | if (isset($this->values[$name])) { |
122 | return $this->values[$name]; |
||
123 | } else { |
||
261 | daniel-mar | 124 | return $default; |
60 | daniel-mar | 125 | } |
46 | daniel-mar | 126 | } |
127 | |||
74 | daniel-mar | 128 | public function exists($name) { |
326 | daniel-mar | 129 | return !is_null($this->getValue($name, null)); |
74 | daniel-mar | 130 | } |
131 | |||
14 | daniel-mar | 132 | public function setValue($name, $value) { |
326 | daniel-mar | 133 | // Avoid unnecessary database writes |
134 | // We do not call getValue() or buildConfigArray(), because they could cause an unnecessary database read |
||
135 | if (isset($this->values[$name])) { |
||
136 | if ($this->values[$name] == $value) return; |
||
137 | } |
||
138 | |||
263 | daniel-mar | 139 | // Give plugins the possibility to stop the process by throwing an Exception (e.g. if the value is invalid) |
326 | daniel-mar | 140 | // Required is that the plugin previously prepared the config setting using prepareConfigKey() |
263 | daniel-mar | 141 | if (isset($this->validateCallbacks[$name])) { |
142 | $this->validateCallbacks[$name]($value); |
||
14 | daniel-mar | 143 | } |
257 | daniel-mar | 144 | |
14 | daniel-mar | 145 | // Now change the value in the database |
261 | daniel-mar | 146 | OIDplus::db()->query("update ###config set value = ? where name = ?", array($value, $name)); |
66 | daniel-mar | 147 | $this->values[$name] = $value; |
14 | daniel-mar | 148 | } |
149 | |||
294 | daniel-mar | 150 | public function deleteConfigKey($name) { |
326 | daniel-mar | 151 | if ($this->configTableReadOnce) { |
152 | if (isset($this->values[$name])) { |
||
153 | OIDplus::db()->query("delete from ###config where name = ?", array($name)); |
||
154 | } |
||
155 | } else { |
||
156 | // We do not know if the value exists. |
||
157 | // buildConfigArray() would do many reads which are unnecessary. |
||
158 | // So we just do a MySQL command to delete the stuff: |
||
294 | daniel-mar | 159 | OIDplus::db()->query("delete from ###config where name = ?", array($name)); |
160 | } |
||
326 | daniel-mar | 161 | |
162 | unset($this->values[$name]); |
||
163 | unset($this->descriptions[$name]); |
||
164 | unset($this->validateCallbacks[$name]); |
||
294 | daniel-mar | 165 | } |
166 | |||
360 | daniel-mar | 167 | } |