Subversion Repositories oidplus

Rev

Rev 326 | Rev 511 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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.  
  20. // OIDplusConfig contains settings that are stored in the database.
  21. // Not to be confused with OIDplusBaseConfig which is the basic ("static")
  22. // configuration stored in userdata/baseconfig/config.inc.php,
  23. // e.g. database access credentials.
  24. class OIDplusConfig implements OIDplusConfigInterface {
  25.  
  26.         /*public*/ const PROTECTION_EDITABLE = 0;
  27.         /*public*/ const PROTECTION_READONLY = 1;
  28.         /*public*/ const PROTECTION_HIDDEN   = 2;
  29.  
  30.         protected $configTableReadOnce = false; // this ensures that all $values and $descriptions were read
  31.  
  32.         protected $values = array();
  33.         protected $descriptions = array();
  34.         protected $validateCallbacks = array();
  35.  
  36.         public function prepareConfigKey($name, $description, $init_value, $protection, $validateCallback) {
  37.                 // Check if the protection flag is valid
  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:
  52.                                 throw new OIDplusException(_L('Invalid protection flag, use OIDplusConfig::PROTECTION_* constants'));
  53.                 }
  54.  
  55.                 // Check length limitations given by the database tables
  56.                 if (strlen($name) > 50) {
  57.                         throw new OIDplusException(_L('Config key name "%1" is too long (max %2).',$name,50));
  58.                 }
  59.                 if (strlen($description) > 255) {
  60.                         throw new OIDplusException(_L('Description for config key "%1" is too long (max %2).',$name,255));
  61.                 }
  62.  
  63.                 // Read all values and descriptions from the database once.
  64.                 $this->buildConfigArray();
  65.  
  66.                 // Figure out if we need to create/update something at database level
  67.                 if (!isset($this->values[$name])) {
  68.                         // Case A: The config setting does not exist in the database. So we create it now.
  69.                         OIDplus::db()->query("insert into ###config (name, description, value, protected, visible) values (?, ?, ?, ?, ?)", array($name, $description, $init_value, $protected, $visible));
  70.                         $this->values[$name] = $init_value;
  71.                         $this->descriptions[$name] = $description;
  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.                         }
  81.                 }
  82.  
  83.                 // Register the validation callback
  84.                 if (!is_null($validateCallback)) {
  85.                         $this->validateCallbacks[$name] = $validateCallback;
  86.                 }
  87.         }
  88.  
  89.         public function clearCache() {
  90.                 $this->configTableReadOnce = false;
  91.                 $this->buildConfigArray();
  92.         }
  93.  
  94.         protected function buildConfigArray() {
  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;
  103.                 }
  104.  
  105.                 $this->configTableReadOnce = true;
  106.         }
  107.  
  108.         public function getValue($name, $default=null) {
  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
  118.                 $this->buildConfigArray();
  119.  
  120.                 // Now we can see if our desired attribute is available
  121.                 if (isset($this->values[$name])) {
  122.                         return $this->values[$name];
  123.                 } else {
  124.                         return $default;
  125.                 }
  126.         }
  127.  
  128.         public function exists($name) {
  129.                 return !is_null($this->getValue($name, null));
  130.         }
  131.  
  132.         public function setValue($name, $value) {
  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.  
  139.                 // Give plugins the possibility to stop the process by throwing an Exception (e.g. if the value is invalid)
  140.                 // Required is that the plugin previously prepared the config setting using prepareConfigKey()
  141.                 if (isset($this->validateCallbacks[$name])) {
  142.                         $this->validateCallbacks[$name]($value);
  143.                 }
  144.  
  145.                 // Now change the value in the database
  146.                 OIDplus::db()->query("update ###config set value = ? where name = ?", array($value, $name));
  147.                 $this->values[$name] = $value;
  148.         }
  149.  
  150.         public function deleteConfigKey($name) {
  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:
  159.                         OIDplus::db()->query("delete from ###config where name = ?", array($name));
  160.                 }
  161.  
  162.                 unset($this->values[$name]);
  163.                 unset($this->descriptions[$name]);
  164.                 unset($this->validateCallbacks[$name]);
  165.         }
  166.  
  167. }