[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/lib/plugins/config/core/ -> Configuration.php (source)

   1  <?php
   2  
   3  namespace dokuwiki\plugin\config\core;
   4  
   5  use dokuwiki\plugin\config\core\Setting\Setting;
   6  use dokuwiki\plugin\config\core\Setting\SettingNoClass;
   7  use dokuwiki\plugin\config\core\Setting\SettingNoDefault;
   8  use dokuwiki\plugin\config\core\Setting\SettingNoKnownClass;
   9  use dokuwiki\plugin\config\core\Setting\SettingUndefined;
  10  
  11  /**
  12   * Holds all the current settings and proxies the Loader and Writer
  13   *
  14   * @author Chris Smith <chris@jalakai.co.uk>
  15   * @author Ben Coburn <btcoburn@silicodon.net>
  16   * @author Andreas Gohr <andi@splitbrain.org>
  17   */
  18  class Configuration {
  19  
  20      const KEYMARKER = '____';
  21  
  22      /** @var Setting[] metadata as array of Settings objects */
  23      protected $settings = array();
  24      /** @var Setting[] undefined and problematic settings */
  25      protected $undefined = array();
  26  
  27      /** @var array all metadata */
  28      protected $metadata;
  29      /** @var array all default settings */
  30      protected $default;
  31      /** @var array all local settings */
  32      protected $local;
  33      /** @var array all protected settings */
  34      protected $protected;
  35  
  36      /** @var bool have the settings been changed since loading from disk? */
  37      protected $changed = false;
  38  
  39      /** @var Loader */
  40      protected $loader;
  41      /** @var Writer */
  42      protected $writer;
  43  
  44      /**
  45       * ConfigSettings constructor.
  46       */
  47      public function __construct() {
  48          $this->loader = new Loader(new ConfigParser());
  49          $this->writer = new Writer();
  50  
  51          $this->metadata = $this->loader->loadMeta();
  52          $this->default = $this->loader->loadDefaults();
  53          $this->local = $this->loader->loadLocal();
  54          $this->protected = $this->loader->loadProtected();
  55  
  56          $this->initSettings();
  57      }
  58  
  59      /**
  60       * Get all settings
  61       *
  62       * @return Setting[]
  63       */
  64      public function getSettings() {
  65          return $this->settings;
  66      }
  67  
  68      /**
  69       * Get all unknown or problematic settings
  70       *
  71       * @return Setting[]
  72       */
  73      public function getUndefined() {
  74          return $this->undefined;
  75      }
  76  
  77      /**
  78       * Have the settings been changed since loading from disk?
  79       *
  80       * @return bool
  81       */
  82      public function hasChanged() {
  83          return $this->changed;
  84      }
  85  
  86      /**
  87       * Check if the config can be written
  88       *
  89       * @return bool
  90       */
  91      public function isLocked() {
  92          return $this->writer->isLocked();
  93      }
  94  
  95      /**
  96       * Update the settings using the data provided
  97       *
  98       * @param array $input as posted
  99       * @return bool true if all updates went through, false on errors
 100       */
 101      public function updateSettings($input) {
 102          $ok = true;
 103  
 104          foreach($this->settings as $key => $obj) {
 105              $value = isset($input[$key]) ? $input[$key] : null;
 106              if($obj->update($value)) {
 107                  $this->changed = true;
 108              }
 109              if($obj->hasError()) $ok = false;
 110          }
 111  
 112          return $ok;
 113      }
 114  
 115      /**
 116       * Save the settings
 117       *
 118       * This save the current state as defined in this object, including the
 119       * undefined settings
 120       *
 121       * @throws \Exception
 122       */
 123      public function save() {
 124          // only save the undefined settings that have not been handled in settings
 125          $undefined = array_diff_key($this->undefined, $this->settings);
 126          $this->writer->save(array_merge($this->settings, $undefined));
 127      }
 128  
 129      /**
 130       * Touch the settings
 131       *
 132       * @throws \Exception
 133       */
 134      public function touch() {
 135          $this->writer->touch();
 136      }
 137  
 138      /**
 139       * Load the extension language strings
 140       *
 141       * @return array
 142       */
 143      public function getLangs() {
 144          return $this->loader->loadLangs();
 145      }
 146  
 147      /**
 148       * Initalizes the $settings and $undefined properties
 149       */
 150      protected function initSettings() {
 151          $keys = array_merge(
 152              array_keys($this->metadata),
 153              array_keys($this->default),
 154              array_keys($this->local),
 155              array_keys($this->protected)
 156          );
 157          $keys = array_unique($keys);
 158  
 159          foreach($keys as $key) {
 160              $obj = $this->instantiateClass($key);
 161  
 162              if($obj->shouldHaveDefault() && !isset($this->default[$key])) {
 163                  $this->undefined[$key] = new SettingNoDefault($key);
 164              }
 165  
 166              $d = isset($this->default[$key]) ? $this->default[$key] : null;
 167              $l = isset($this->local[$key]) ? $this->local[$key] : null;
 168              $p = isset($this->protected[$key]) ? $this->protected[$key] : null;
 169  
 170              $obj->initialize($d, $l, $p);
 171          }
 172      }
 173  
 174      /**
 175       * Instantiates the proper class for the given config key
 176       *
 177       * The class is added to the $settings or $undefined arrays and returned
 178       *
 179       * @param string $key
 180       * @return Setting
 181       */
 182      protected function instantiateClass($key) {
 183          if(isset($this->metadata[$key])) {
 184              $param = $this->metadata[$key];
 185              $class = $this->determineClassName(array_shift($param), $key); // first param is class
 186              $obj = new $class($key, $param);
 187              $this->settings[$key] = $obj;
 188          } else {
 189              $obj = new SettingUndefined($key);
 190              $this->undefined[$key] = $obj;
 191          }
 192          return $obj;
 193      }
 194  
 195      /**
 196       * Return the class to load
 197       *
 198       * @param string $class the class name as given in the meta file
 199       * @param string $key the settings key
 200       * @return string
 201       */
 202      protected function determineClassName($class, $key) {
 203          // try namespaced class first
 204          if(is_string($class)) {
 205              $modern = str_replace('_', '', ucwords($class, '_'));
 206              $modern = '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting' . $modern;
 207              if($modern && class_exists($modern)) return $modern;
 208              // try class as given
 209              if(class_exists($class)) return $class;
 210              // class wasn't found add to errors
 211              $this->undefined[$key] = new SettingNoKnownClass($key);
 212          } else {
 213              // no class given, add to errors
 214              $this->undefined[$key] = new SettingNoClass($key);
 215          }
 216          return '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting';
 217      }
 218  
 219  }