1<?php 2 3namespace dokuwiki\plugin\config\core\Setting; 4 5use dokuwiki\plugin\config\core\Configuration; 6 7/** 8 * Class Setting 9 */ 10class Setting { 11 /** @var string unique identifier of this setting */ 12 protected $key = ''; 13 14 /** @var mixed the default value of this setting */ 15 protected $default = null; 16 /** @var mixed the local value of this setting */ 17 protected $local = null; 18 /** @var mixed the protected value of this setting */ 19 protected $protected = null; 20 21 /** @var array valid alerts, images matching the alerts are in the plugin's images directory */ 22 static protected $validCautions = array('warning', 'danger', 'security'); 23 24 protected $pattern = ''; 25 protected $error = false; // only used by those classes which error check 26 protected $input = null; // only used by those classes which error check 27 protected $caution = null; // used by any setting to provide an alert along with the setting 28 29 /** 30 * Constructor. 31 * 32 * The given parameters will be set up as class properties 33 * 34 * @see initialize() to set the actual value of the setting 35 * 36 * @param string $key 37 * @param array|null $params array with metadata of setting 38 */ 39 public function __construct($key, $params = null) { 40 $this->key = $key; 41 42 if(is_array($params)) { 43 foreach($params as $property => $value) { 44 $property = trim($property, '_'); // we don't use underscores anymore 45 $this->$property = $value; 46 } 47 } 48 } 49 50 /** 51 * Set the current values for the setting $key 52 * 53 * This is used to initialize the setting with the data read form the config files. 54 * 55 * @see update() to set a new value 56 * @param mixed $default default setting value 57 * @param mixed $local local setting value 58 * @param mixed $protected protected setting value 59 */ 60 public function initialize($default = null, $local = null, $protected = null) { 61 $this->default = $default; 62 $this->local = $local; 63 $this->protected = $protected; 64 } 65 66 /** 67 * update changed setting with user provided value $input 68 * - if changed value fails error check, save it to $this->_input (to allow echoing later) 69 * - if changed value passes error check, set $this->_local to the new value 70 * 71 * @param mixed $input the new value 72 * @return boolean true if changed, false otherwise (also on error) 73 */ 74 public function update($input) { 75 if(is_null($input)) return false; 76 if($this->isProtected()) return false; 77 78 $value = is_null($this->local) ? $this->default : $this->local; 79 if($value == $input) return false; 80 81 if($this->pattern && !preg_match($this->pattern, $input)) { 82 $this->error = true; 83 $this->input = $input; 84 return false; 85 } 86 87 $this->local = $input; 88 return true; 89 } 90 91 /** 92 * Should this type of config have a default? 93 * 94 * @return bool 95 */ 96 public function shouldHaveDefault() { 97 return true; 98 } 99 100 /** 101 * Get this setting's unique key 102 * 103 * @return string 104 */ 105 public function getKey() { 106 return $this->key; 107 } 108 109 /** 110 * Get the key of this setting marked up human readable 111 * 112 * @param bool $url link to dokuwiki.org manual? 113 * @return string 114 */ 115 public function getPrettyKey($url = true) { 116 $out = str_replace(Configuration::KEYMARKER, "»", $this->key); 117 if($url && !strstr($out, '»')) {//provide no urls for plugins, etc. 118 if($out == 'start') { 119 // exception, because this config name is clashing with our actual start page 120 return '<a href="http://www.dokuwiki.org/config:startpage">' . $out . '</a>'; 121 } else { 122 return '<a href="http://www.dokuwiki.org/config:' . $out . '">' . $out . '</a>'; 123 } 124 } 125 return $out; 126 } 127 128 /** 129 * Returns setting key as an array key separator 130 * 131 * This is used to create form output 132 * 133 * @return string key 134 */ 135 public function getArrayKey() { 136 return str_replace(Configuration::KEYMARKER, "']['", $this->key); 137 } 138 139 /** 140 * What type of configuration is this 141 * 142 * Returns one of 143 * 144 * 'plugin' for plugin configuration 145 * 'template' for template configuration 146 * 'conf' for core configuration 147 * 148 * @return string 149 */ 150 public function getType() { 151 if(substr($this->getKey(), 0, 10) == 'plugin' . Configuration::KEYMARKER) { 152 return 'plugin'; 153 } else if(substr($this->getKey(), 0, 7) == 'tpl' . Configuration::KEYMARKER) { 154 return 'template'; 155 } else { 156 return 'conf'; 157 } 158 } 159 160 /** 161 * Build html for label and input of setting 162 * 163 * @param \admin_plugin_config $plugin object of config plugin 164 * @param bool $echo true: show inputted value, when error occurred, otherwise the stored setting 165 * @return string[] with content array(string $label_html, string $input_html) 166 */ 167 public function html(\admin_plugin_config $plugin, $echo = false) { 168 $disable = ''; 169 170 if($this->isProtected()) { 171 $value = $this->protected; 172 $disable = 'disabled="disabled"'; 173 } else { 174 if($echo && $this->error) { 175 $value = $this->input; 176 } else { 177 $value = is_null($this->local) ? $this->default : $this->local; 178 } 179 } 180 181 $key = htmlspecialchars($this->key); 182 $value = formText($value); 183 184 $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>'; 185 $input = '<textarea rows="3" cols="40" id="config___' . $key . 186 '" name="config[' . $key . ']" class="edit" ' . $disable . '>' . $value . '</textarea>'; 187 return array($label, $input); 188 } 189 190 /** 191 * Should the current local value be saved? 192 * 193 * @see out() to run when this returns true 194 * @return bool 195 */ 196 public function shouldBeSaved() { 197 if($this->isProtected()) return false; 198 if($this->local === null) return false; 199 if($this->default == $this->local) return false; 200 return true; 201 } 202 203 /** 204 * Generate string to save local setting value to file according to $fmt 205 * 206 * @see shouldBeSaved() to check if this should be called 207 * @param string $var name of variable 208 * @param string $fmt save format 209 * @return string 210 */ 211 public function out($var, $fmt = 'php') { 212 if($fmt != 'php') return ''; 213 214 $tr = array("\\" => '\\\\', "'" => '\\\''); // escape the value 215 $out = '$' . $var . "['" . $this->getArrayKey() . "'] = '" . strtr(cleanText($this->local), $tr) . "';\n"; 216 217 return $out; 218 } 219 220 /** 221 * Returns the localized prompt 222 * 223 * @param \admin_plugin_config $plugin object of config plugin 224 * @return string text 225 */ 226 public function prompt(\admin_plugin_config $plugin) { 227 $prompt = $plugin->getLang($this->key); 228 if(!$prompt) $prompt = htmlspecialchars(str_replace(array('____', '_'), ' ', $this->key)); 229 return $prompt; 230 } 231 232 /** 233 * Is setting protected 234 * 235 * @return bool 236 */ 237 public function isProtected() { 238 return !is_null($this->protected); 239 } 240 241 /** 242 * Is setting the default? 243 * 244 * @return bool 245 */ 246 public function isDefault() { 247 return !$this->isProtected() && is_null($this->local); 248 } 249 250 /** 251 * Has an error? 252 * 253 * @return bool 254 */ 255 public function hasError() { 256 return $this->error; 257 } 258 259 /** 260 * Returns caution 261 * 262 * @return false|string caution string, otherwise false for invalid caution 263 */ 264 public function caution() { 265 if(!empty($this->caution)) { 266 if(!in_array($this->caution, Setting::$validCautions)) { 267 throw new \RuntimeException( 268 'Invalid caution string (' . $this->caution . ') in metadata for setting "' . $this->key . '"' 269 ); 270 } 271 return $this->caution; 272 } 273 // compatibility with previous cautionList 274 // TODO: check if any plugins use; remove 275 if(!empty($this->cautionList[$this->key])) { 276 $this->caution = $this->cautionList[$this->key]; 277 unset($this->cautionList); 278 279 return $this->caution(); 280 } 281 return false; 282 } 283 284} 285