1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * @package moodlecore 19 * @copyright 2010 Sam Hemelryk 20 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 21 */ 22 23 /** 24 * Generic abstract dependency class 25 * 26 * @copyright 2010 Sam Hemelryk 27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 28 */ 29 abstract class setting_dependency { 30 31 /** 32 * Used to define the type of a dependency. 33 * 34 * Note with these that checked and true, and not checked and false are equal. 35 * This is because the terminology differs but the resulting action is the same. 36 * Reduces code! 37 */ 38 const DISABLED_VALUE = 0; 39 const DISABLED_NOT_VALUE = 1; 40 const DISABLED_TRUE = 2; 41 const DISABLED_FALSE = 3; 42 const DISABLED_CHECKED = 4; 43 const DISABLED_NOT_CHECKED = 5; 44 const DISABLED_EMPTY = 6; 45 const DISABLED_NOT_EMPTY = 7; 46 47 /** 48 * The parent setting (primary) 49 * @var base_setting 50 */ 51 protected $setting; 52 /** 53 * The dependent setting (secondary) 54 * @var base_setting 55 */ 56 protected $dependentsetting; 57 /** 58 * The default setting 59 * @var mixed 60 */ 61 protected $defaultvalue; 62 /** 63 * The last value the dependent setting had 64 * @var mixed 65 */ 66 protected $lastvalue; 67 /** 68 * Creates the dependency object 69 * @param base_setting $setting The parent setting or the primary setting if you prefer 70 * @param base_setting $dependentsetting The dependent setting 71 * @param mixed $defaultvalue The default value to assign if the dependency is unmet 72 */ 73 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) { 74 $this->setting = $setting; 75 $this->dependentsetting = $dependentsetting; 76 $this->defaultvalue = $defaultvalue; 77 $this->lastvalue = $dependentsetting->get_value(); 78 } 79 80 /** 81 * Destroy all circular references. It helps PHP 5.2 a lot! 82 */ 83 public function destroy() { 84 // No need to destroy anything recursively here, direct reset. 85 $this->setting = null; 86 $this->dependentsetting = null; 87 } 88 89 /** 90 * Processes a change is setting called by the primary setting 91 * @param int $changetype 92 * @param mixed $oldvalue 93 * @return bool 94 */ 95 final public function process_change($changetype, $oldvalue) { 96 // Check the type of change requested. 97 switch ($changetype) { 98 // Process a status change. 99 case base_setting::CHANGED_STATUS: 100 return $this->process_status_change($oldvalue); 101 // Process a visibility change. 102 case base_setting::CHANGED_VISIBILITY: 103 return $this->process_visibility_change($oldvalue); 104 // Process a value change. 105 case base_setting::CHANGED_VALUE: 106 return $this->process_value_change($oldvalue); 107 } 108 // Throw an exception if we get this far. 109 throw new backup_ui_exception('unknownchangetype'); 110 } 111 /** 112 * Processes a visibility change 113 * @param bool $oldvisibility 114 * @return bool 115 */ 116 protected function process_visibility_change($oldvisibility) { 117 // Store the current dependent settings visibility for comparison. 118 $prevalue = $this->dependentsetting->get_visibility(); 119 // Set it regardless of whether we need to. 120 $this->dependentsetting->set_visibility($this->setting->get_visibility()); 121 // Return true if it changed. 122 return ($prevalue != $this->dependentsetting->get_visibility()); 123 } 124 /** 125 * All dependencies must define how they would like to deal with a status change 126 * @param int $oldstatus 127 */ 128 abstract protected function process_status_change($oldstatus); 129 /** 130 * All dependencies must define how they would like to process a value change 131 */ 132 abstract protected function process_value_change($oldvalue); 133 /** 134 * Gets the primary setting 135 * @return backup_setting 136 */ 137 public function get_setting() { 138 return $this->setting; 139 } 140 /** 141 * Gets the dependent setting 142 * @return backup_setting 143 */ 144 public function get_dependent_setting() { 145 return $this->dependentsetting; 146 } 147 /** 148 * This function enforces the dependency 149 */ 150 abstract public function enforce(); 151 /** 152 * Returns an array of properties suitable to be used to define a moodleforms 153 * disabled command 154 * @return array 155 */ 156 abstract public function get_moodleform_properties(); 157 /** 158 * Returns true if the dependent setting is locked by this setting_dependency. 159 * @return bool 160 */ 161 abstract public function is_locked(); 162 } 163 164 /** 165 * A dependency that disables the secondary setting if the primary setting is 166 * equal to the provided value 167 * 168 * @copyright 2010 Sam Hemelryk 169 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 170 */ 171 class setting_dependency_disabledif_equals extends setting_dependency { 172 /** 173 * The value to compare to 174 * @var mixed 175 */ 176 protected $value; 177 /** 178 * Creates the dependency 179 * 180 * @param base_setting $setting 181 * @param base_setting $dependentsetting 182 * @param mixed $value 183 * @param mixed $defaultvalue 184 */ 185 public function __construct(base_setting $setting, base_setting $dependentsetting, $value, $defaultvalue = false) { 186 parent::__construct($setting, $dependentsetting, $defaultvalue); 187 $this->value = ($value) ? (string)$value : 0; 188 } 189 /** 190 * Returns true if the dependent setting is locked by this setting_dependency. 191 * @return bool 192 */ 193 public function is_locked() { 194 // If the setting is locked or the dependent setting should be locked then return true. 195 if ($this->setting->get_status() !== base_setting::NOT_LOCKED || 196 $this->evaluate_disabled_condition($this->setting->get_value())) { 197 return true; 198 } 199 // Else the dependent setting is not locked by this setting_dependency. 200 return false; 201 } 202 /** 203 * Processes a value change in the primary setting 204 * @param mixed $oldvalue 205 * @return bool 206 */ 207 protected function process_value_change($oldvalue) { 208 if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_PERMISSION || 209 $this->dependentsetting->get_status() == base_setting::LOCKED_BY_CONFIG) { 210 // When setting is locked by permission or config do not apply dependencies. 211 return false; 212 } 213 $prevalue = $this->dependentsetting->get_value(); 214 // If the setting is the desired value enact the dependency. 215 $settingvalue = $this->setting->get_value(); 216 if ($this->evaluate_disabled_condition($settingvalue)) { 217 // The dependent setting needs to be locked by hierachy and set to the 218 // default value. 219 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY); 220 221 // For checkboxes the default value is false, but when the setting is 222 // locked, the value should inherit from the parent setting. 223 if ($this->defaultvalue === false) { 224 $this->dependentsetting->set_value($settingvalue); 225 } else { 226 $this->dependentsetting->set_value($this->defaultvalue); 227 } 228 } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) { 229 // We can unlock the dependent setting. 230 $this->dependentsetting->set_status(base_setting::NOT_LOCKED); 231 } 232 // Return true if the value has changed for the dependent setting. 233 return ($prevalue != $this->dependentsetting->get_value()); 234 } 235 /** 236 * Processes a status change in the primary setting 237 * @param mixed $oldstatus 238 * @return bool 239 */ 240 protected function process_status_change($oldstatus) { 241 // Store the dependent status. 242 $prevalue = $this->dependentsetting->get_status(); 243 // Store the current status. 244 $currentstatus = $this->setting->get_status(); 245 if ($currentstatus == base_setting::NOT_LOCKED) { 246 if ($prevalue == base_setting::LOCKED_BY_HIERARCHY && 247 !$this->evaluate_disabled_condition($this->setting->get_value())) { 248 // Dependency has changes, is not fine, unlock the dependent setting. 249 $this->dependentsetting->set_status(base_setting::NOT_LOCKED); 250 } 251 } else { 252 // Make sure the dependent setting is also locked, in this case by hierarchy. 253 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY); 254 } 255 // Return true if the dependent setting has changed. 256 return ($prevalue != $this->dependentsetting->get_status()); 257 } 258 /** 259 * Enforces the dependency if required. 260 * @return bool True if there were changes 261 */ 262 public function enforce() { 263 // This will be set to true if ANYTHING changes. 264 $changes = false; 265 // First process any value changes. 266 if ($this->process_value_change($this->setting->get_value())) { 267 $changes = true; 268 } 269 // Second process any status changes. 270 if ($this->process_status_change($this->setting->get_status())) { 271 $changes = true; 272 } 273 // Finally process visibility changes. 274 if ($this->process_visibility_change($this->setting->get_visibility())) { 275 $changes = true; 276 } 277 return $changes; 278 } 279 /** 280 * Returns an array of properties suitable to be used to define a moodleforms 281 * disabled command 282 * @return array 283 */ 284 public function get_moodleform_properties() { 285 return array( 286 'setting' => $this->dependentsetting->get_ui_name(), 287 'dependenton' => $this->setting->get_ui_name(), 288 'condition' => 'eq', 289 'value' => $this->value 290 ); 291 } 292 293 /** 294 * Evaluate the current value of the setting and return true if the dependent setting should be locked or false. 295 * This function should be abstract, but there will probably be existing sub-classes so we must provide a default 296 * implementation. 297 * @param mixed $value The value of the parent setting. 298 * @return bool 299 */ 300 protected function evaluate_disabled_condition($value) { 301 return $value == $this->value; 302 } 303 } 304 305 /** 306 * A dependency that disables the secondary setting if the primary setting is 307 * not equal to the provided value 308 * 309 * @copyright 2011 Darko Miletic <dmiletic@moodlerooms.com> 310 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 311 */ 312 class setting_dependency_disabledif_not_equals extends setting_dependency_disabledif_equals { 313 314 /** 315 * Evaluate the current value of the setting and return true if the dependent setting should be locked or false. 316 * @param mixed $value The value of the parent setting. 317 * @return bool 318 */ 319 protected function evaluate_disabled_condition($value) { 320 return $value != $this->value; 321 } 322 323 /** 324 * Returns an array of properties suitable to be used to define a moodleforms 325 * disabled command 326 * @return array 327 */ 328 public function get_moodleform_properties() { 329 return array( 330 'setting' => $this->dependentsetting->get_ui_name(), 331 'dependenton' => $this->setting->get_ui_name(), 332 'condition' => 'notequal', 333 'value' => $this->value 334 ); 335 } 336 } 337 338 /** 339 * Disable if a value is in a list. 340 */ 341 class setting_dependency_disabledif_in_array extends setting_dependency_disabledif_equals { 342 343 /** 344 * Evaluate the current value of the setting and return true if the dependent setting should be locked or false. 345 * @param mixed $value The value of the parent setting. 346 * @return bool 347 */ 348 protected function evaluate_disabled_condition($value) { 349 return in_array($value, $this->value); 350 } 351 352 /** 353 * Returns an array of properties suitable to be used to define a moodleforms 354 * disabled command 355 * @return array 356 */ 357 public function get_moodleform_properties() { 358 return array( 359 'setting' => $this->dependentsetting->get_ui_name(), 360 'dependenton' => $this->setting->get_ui_name(), 361 'condition' => 'eq', 362 'value' => $this->value 363 ); 364 } 365 } 366 367 /** 368 * This class is here for backwards compatibility (terrible name). 369 */ 370 class setting_dependency_disabledif_equals2 extends setting_dependency_disabledif_in_array { 371 } 372 373 /** 374 * A dependency that disables the secondary element if the primary element is 375 * true or checked 376 * 377 * @copyright 2010 Sam Hemelryk 378 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 379 */ 380 class setting_dependency_disabledif_checked extends setting_dependency_disabledif_equals { 381 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) { 382 parent::__construct($setting, $dependentsetting, true, $defaultvalue); 383 $this->value = true; 384 } 385 /** 386 * Returns an array of properties suitable to be used to define a moodleforms 387 * disabled command 388 * @return array 389 */ 390 public function get_moodleform_properties() { 391 return array( 392 'setting' => $this->dependentsetting->get_ui_name(), 393 'dependenton' => $this->setting->get_ui_name(), 394 'condition' => 'checked' 395 ); 396 } 397 } 398 399 /** 400 * A dependency that disables the secondary element if the primary element is 401 * false or not checked 402 * 403 * @copyright 2010 Sam Hemelryk 404 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 405 */ 406 class setting_dependency_disabledif_not_checked extends setting_dependency_disabledif_equals { 407 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) { 408 parent::__construct($setting, $dependentsetting, false, $defaultvalue); 409 $this->value = false; 410 } 411 /** 412 * Returns an array of properties suitable to be used to define a moodleforms 413 * disabled command 414 * @return array 415 */ 416 public function get_moodleform_properties() { 417 return array( 418 'setting' => $this->dependentsetting->get_ui_name(), 419 'dependenton' => $this->setting->get_ui_name(), 420 'condition' => 'notchecked' 421 ); 422 } 423 } 424 425 /** 426 * A dependency that disables the secondary setting if the value of the primary setting 427 * is not empty. 428 * 429 * @copyright 2010 Sam Hemelryk 430 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 431 */ 432 class setting_dependency_disabledif_not_empty extends setting_dependency_disabledif_equals { 433 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) { 434 parent::__construct($setting, $dependentsetting, false, $defaultvalue); 435 $this->value = false; 436 } 437 438 /** 439 * Evaluate the current value of the setting and return true if the dependent setting should be locked or false. 440 * @param mixed $value The value of the parent setting. 441 * @return bool 442 */ 443 protected function evaluate_disabled_condition($value) { 444 return !empty($value); 445 } 446 447 /** 448 * Returns an array of properties suitable to be used to define a moodleforms 449 * disabled command 450 * @return array 451 */ 452 public function get_moodleform_properties() { 453 return array( 454 'setting' => $this->dependentsetting->get_ui_name(), 455 'dependenton' => $this->setting->get_ui_name(), 456 'condition' => 'notequal', 457 'value' => '' 458 ); 459 } 460 } 461 462 /** 463 * A dependency that disables the secondary setting if the value of the primary setting 464 * is empty. 465 * 466 * @copyright 2010 Sam Hemelryk 467 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 468 */ 469 class setting_dependency_disabledif_empty extends setting_dependency_disabledif_equals { 470 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) { 471 parent::__construct($setting, $dependentsetting, false, $defaultvalue); 472 $this->value = false; 473 } 474 475 /** 476 * Evaluate the current value of the setting and return true if the dependent setting should be locked or false. 477 * @param mixed $value The value of the parent setting. 478 * @return bool 479 */ 480 protected function evaluate_disabled_condition($value) { 481 return empty($value); 482 } 483 484 /** 485 * Returns an array of properties suitable to be used to define a moodleforms 486 * disabled command 487 * @return array 488 */ 489 public function get_moodleform_properties() { 490 return array( 491 'setting' => $this->dependentsetting->get_ui_name(), 492 'dependenton' => $this->setting->get_ui_name(), 493 'condition' => 'notequal', 494 'value' => '' 495 ); 496 } 497 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body