Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/backup/util/settings/base_setting.class.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00035 abstract class base_setting {
00036 
00037     // Some constants defining different ui representations for the setting
00038     const UI_NONE             = 0;
00039     const UI_HTML_CHECKBOX    = 10;
00040     const UI_HTML_RADIOBUTTON = 20;
00041     const UI_HTML_DROPDOWN    = 30;
00042     const UI_HTML_TEXTFIELD   = 40;
00043 
00044     // Type of validation to perform against the value (relaying in PARAM_XXX validations)
00045     const IS_BOOLEAN = 'bool';
00046     const IS_INTEGER = 'int';
00047     const IS_FILENAME= 'file';
00048     const IS_PATH    = 'path';
00049     const IS_TEXT    = 'text';
00050 
00051     // Visible/hidden
00052     const VISIBLE = 1;
00053     const HIDDEN  = 0;
00054 
00055     // Editable/locked (by different causes)
00056     const NOT_LOCKED           = 3;
00057     const LOCKED_BY_CONFIG     = 5;
00058     const LOCKED_BY_HIERARCHY  = 7;
00059     const LOCKED_BY_PERMISSION = 9;
00060 
00061     // Type of change to inform dependencies
00062     const CHANGED_VALUE      = 1;
00063     const CHANGED_VISIBILITY = 2;
00064     const CHANGED_STATUS     = 3;
00065 
00066     protected $name;  // name of the setting
00067     protected $value; // value of the setting
00068     protected $vtype; // type of value (setting_base::IS_BOOLEAN/setting_base::IS_INTEGER...)
00069 
00070     protected $visibility; // visibility of the setting (setting_base::VISIBLE/setting_base::HIDDEN)
00071     protected $status; // setting_base::NOT_LOCKED/setting_base::LOCKED_BY_PERMISSION...
00072 
00073     protected $dependencies = array(); // array of dependent (observer) objects (usually setting_base ones)
00074     protected $dependenton = array();
00075 
00080     protected $uisetting;
00081 
00087     protected $help = array();
00088 
00089     public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) {
00090         // Check vtype
00091         if ($vtype !== self::IS_BOOLEAN && $vtype !== self::IS_INTEGER &&
00092             $vtype !== self::IS_FILENAME && $vtype !== self::IS_PATH &&
00093             $vtype !== self::IS_TEXT) {
00094             throw new base_setting_exception('setting_invalid_type');
00095         }
00096 
00097         // Validate value
00098         $value = $this->validate_value($vtype, $value);
00099 
00100         // Check visibility
00101         $visibility = $this->validate_visibility($visibility);
00102 
00103         // Check status
00104         $status = $this->validate_status($status);
00105 
00106         $this->name        = $name;
00107         $this->vtype       = $vtype;
00108         $this->value       = $value;
00109         $this->visibility  = $visibility;
00110         $this->status      = $status;
00111 
00112         // Generate a default ui
00113         $this->uisetting = new base_setting_ui($this);
00114     }
00115 
00119     public function destroy() {
00120         // Before reseting anything, call destroy recursively
00121         foreach ($this->dependencies as $dependency) {
00122             $dependency->destroy();
00123         }
00124         foreach ($this->dependenton as $dependenton) {
00125             $dependenton->destroy();
00126         }
00127         if ($this->uisetting) {
00128             $this->uisetting->destroy();
00129         }
00130         // Everything has been destroyed recursively, now we can reset safely
00131         $this->dependencies = array();
00132         $this->dependenton = array();
00133         $this->uisetting = null;
00134     }
00135 
00136     public function get_name() {
00137         return $this->name;
00138     }
00139 
00140     public function get_value() {
00141         return $this->value;
00142     }
00143 
00144     public function get_visibility() {
00145         return $this->visibility;
00146     }
00147 
00148     public function get_status() {
00149         return $this->status;
00150     }
00151 
00152     public function set_value($value) {
00153         // Validate value
00154         $value = $this->validate_value($this->vtype, $value);
00155         // Only can change value if setting is not locked
00156         if ($this->status != self::NOT_LOCKED) {
00157             switch ($this->status) {
00158                 case self::LOCKED_BY_PERMISSION:
00159                     throw new base_setting_exception('setting_locked_by_permission');
00160                 case self::LOCKED_BY_CONFIG:
00161                     throw new base_setting_exception('setting_locked_by_config');
00162             }
00163         }
00164         $oldvalue = $this->value;
00165         $this->value = $value;
00166         if ($value !== $oldvalue) { // Value has changed, let's inform dependencies
00167             $this->inform_dependencies(self::CHANGED_VALUE, $oldvalue);
00168         }
00169     }
00170 
00171     public function set_visibility($visibility) {
00172         $visibility = $this->validate_visibility($visibility);
00173 
00174         // If this setting is dependent on other settings first check that all
00175         // of those settings are visible
00176         if (count($this->dependenton) > 0 && $visibility == base_setting::VISIBLE) {
00177             foreach ($this->dependenton as $dependency) {
00178                 if ($dependency->get_setting()->get_visibility() != base_setting::VISIBLE) {
00179                     $visibility = base_setting::HIDDEN;
00180                     break;
00181                 }
00182             }
00183         }
00184 
00185         $oldvisibility = $this->visibility;
00186         $this->visibility = $visibility;
00187         if ($visibility !== $oldvisibility) { // Visibility has changed, let's inform dependencies
00188             $this->inform_dependencies(self::CHANGED_VISIBILITY, $oldvisibility);
00189         }
00190     }
00191 
00192     public function set_status($status) {
00193         $status = $this->validate_status($status);
00194 
00195         // If the setting is being unlocked first check whether an other settings
00196         // this setting is dependent on are locked. If they are then we still don't
00197         // want to lock this setting.
00198         if (count($this->dependenton) > 0 && $status == base_setting::NOT_LOCKED) {
00199             foreach ($this->dependenton as $dependency) {
00200                 if ($dependency->is_locked()) {
00201                     // It still needs to be locked
00202                     $status = base_setting::LOCKED_BY_HIERARCHY;
00203                     break;
00204                 }
00205             }
00206         }
00207 
00208         $oldstatus = $this->status;
00209         $this->status = $status;
00210         if ($status !== $oldstatus) { // Status has changed, let's inform dependencies
00211             $this->inform_dependencies(self::CHANGED_STATUS, $oldstatus);
00212         }
00213     }
00214 
00229     public function get_my_dependency_properties($settingname=null) {
00230         if ($settingname ==  null) {
00231             $settingname = $this->get_ui_name();
00232         }
00233         $dependencies = array();
00234         foreach ($this->dependenton as $dependenton) {
00235             $properties = $dependenton->get_moodleform_properties();
00236             $properties['setting'] = $settingname;
00237             $dependencies[$properties['setting'].'-'.$properties['dependenton']] = $properties;
00238             $dependencies = array_merge($dependencies, $dependenton->get_setting()->get_my_dependency_properties($settingname));
00239         }
00240         return $dependencies;
00241     }
00242 
00249     public function get_settings_depended_on() {
00250         return $this->dependenton;
00251     }
00252 
00258     public function has_dependent_settings() {
00259         return (count($this->dependencies)>0);
00260     }
00261 
00267     public function has_dependencies_on_settings() {
00268         return (count($this->dependenton)>0);
00269     }
00270 
00276     public function set_ui(backup_setting_ui $ui) {
00277         $this->uisetting = $ui;
00278     }
00279 
00285     public function get_ui() {
00286         return $this->uisetting;
00287     }
00288 
00293     public function register_dependency(setting_dependency $dependency) {
00294         if ($this->is_circular_reference($dependency->get_dependent_setting())) {
00295             $a = new stdclass();
00296             $a->alreadydependent = $this->name;
00297             $a->main = $dependentsetting->get_name();
00298             throw new base_setting_exception('setting_circular_reference', $a);
00299         }
00300         $this->dependencies[$dependency->get_dependent_setting()->get_name()] = $dependency;
00301         $dependency->get_dependent_setting()->register_dependent_dependency($dependency);
00302     }
00310     protected function register_dependent_dependency(setting_dependency $dependency) {
00311         $this->dependenton[$dependency->get_setting()->get_name()] = $dependency;
00312     }
00313 
00324     public function add_dependency(base_setting $dependentsetting, $type=null, $options=array()) {
00325         if ($this->is_circular_reference($dependentsetting)) {
00326             $a = new stdclass();
00327             $a->alreadydependent = $this->name;
00328             $a->main = $dependentsetting->get_name();
00329             throw new base_setting_exception('setting_circular_reference', $a);
00330         }
00331         // Check the settings hasn't been already added
00332         if (array_key_exists($dependentsetting->get_name(), $this->dependencies)) {
00333             throw new base_setting_exception('setting_already_added');
00334         }
00335 
00336         $options = (array)$options;
00337 
00338         if (!array_key_exists('defaultvalue', $options)) {
00339             $options['defaultvalue'] = false;
00340         }
00341 
00342         if ($type == null) {
00343             switch ($this->vtype) {
00344                 case self::IS_BOOLEAN :
00345                     if ($this->get_ui_type() == self::UI_HTML_CHECKBOX) {
00346                         if ($this->value) {
00347                             $type = setting_dependency::DISABLED_NOT_CHECKED;
00348                         } else {
00349                             $type = setting_dependency::DISABLED_CHECKED;
00350                         }
00351                     } else {
00352                         if ($this->value) {
00353                             $type = setting_dependency::DISABLED_FALSE;
00354                         } else {
00355                             $type = setting_dependency::DISABLED_TRUE;
00356                         }
00357                     }
00358                     break;
00359                 case self::IS_FILENAME :
00360                 case self::IS_PATH :
00361                 case self::IS_INTEGER :
00362                 default :
00363                     $type = setting_dependency::DISABLED_VALUE;
00364                     break;
00365             }
00366         }
00367 
00368         switch ($type) {
00369             case setting_dependency::DISABLED_VALUE :
00370                 if (!array_key_exists('value', $options)) {
00371                     throw new base_setting_exception('dependency_needs_value');
00372                 }
00373                 $dependency = new setting_dependency_disabledif_equals($this, $dependentsetting, $options['value'], $options['defaultvalue']);
00374                 break;
00375             case setting_dependency::DISABLED_TRUE :
00376                 $dependency = new setting_dependency_disabledif_equals($this, $dependentsetting, true, $options['defaultvalue']);
00377                 break;
00378             case setting_dependency::DISABLED_FALSE :
00379                 $dependency = new setting_dependency_disabledif_equals($this, $dependentsetting, false, $options['defaultvalue']);
00380                 break;
00381             case setting_dependency::DISABLED_CHECKED :
00382                 $dependency = new setting_dependency_disabledif_checked($this, $dependentsetting, $options['defaultvalue']);
00383                 break;
00384             case setting_dependency::DISABLED_NOT_CHECKED :
00385                 $dependency = new setting_dependency_disabledif_not_checked($this, $dependentsetting, $options['defaultvalue']);
00386                 break;
00387             case setting_dependency::DISABLED_EMPTY :
00388                 $dependency = new setting_dependency_disabledif_empty($this, $dependentsetting, $options['defaultvalue']);
00389                 break;
00390             case setting_dependency::DISABLED_NOT_EMPTY :
00391                 $dependency = new setting_dependency_disabledif_not_empty($this, $dependentsetting, $options['defaultvalue']);
00392                 break;
00393         }
00394         $this->dependencies[$dependentsetting->get_name()] = $dependency;
00395         $dependency->get_dependent_setting()->register_dependent_dependency($dependency);
00396     }
00397 
00398 // Protected API starts here
00399 
00400     protected function validate_value($vtype, $value) {
00401         if (is_null($value)) { // Nulls aren't validated
00402             return null;
00403         }
00404         $oldvalue = $value;
00405         switch ($vtype) {
00406             case self::IS_BOOLEAN:
00407                 $value = clean_param($oldvalue, PARAM_BOOL); // Just clean
00408                 break;
00409             case self::IS_INTEGER:
00410                 $value = clean_param($oldvalue, PARAM_INT);
00411                 if ($value != $oldvalue) {
00412                     throw new base_setting_exception('setting_invalid_integer', $oldvalue);
00413                 }
00414                 break;
00415             case self::IS_FILENAME:
00416                 $value = clean_param($oldvalue, PARAM_FILE);
00417                 if ($value != $oldvalue) {
00418                     throw new base_setting_exception('setting_invalid_filename', $oldvalue);
00419                 }
00420                 break;
00421             case self::IS_PATH:
00422                 $value = clean_param($oldvalue, PARAM_PATH);
00423                 if ($value != $oldvalue) {
00424                     throw new base_setting_exception('setting_invalid_path', $oldvalue);
00425                 }
00426                 break;
00427             case self::IS_TEXT:
00428                 $value = clean_param($oldvalue, PARAM_TEXT);
00429                 if ($value != $oldvalue) {
00430                     throw new base_setting_exception('setting_invalid_text', $oldvalue);
00431                 }
00432                 break;
00433         }
00434         return $value;
00435     }
00436 
00437     protected function validate_visibility($visibility) {
00438         if (is_null($visibility)) {
00439             $visibility = self::VISIBLE;
00440         }
00441         if ($visibility !== self::VISIBLE && $visibility !== self::HIDDEN) {
00442             throw new base_setting_exception('setting_invalid_visibility');
00443         }
00444         return $visibility;
00445     }
00446 
00447     protected function validate_status($status) {
00448         if (is_null($status)) {
00449             $status = self::NOT_LOCKED;
00450         }
00451         if ($status !== self::NOT_LOCKED && $status !== self::LOCKED_BY_CONFIG &&
00452             $status !== self::LOCKED_BY_PERMISSION && $status !== self::LOCKED_BY_HIERARCHY) {
00453             throw new base_setting_exception('setting_invalid_status', $status);
00454         }
00455         return $status;
00456     }
00457 
00458     protected function inform_dependencies($ctype, $oldv) {
00459         foreach ($this->dependencies as $dependency) {
00460             $dependency->process_change($ctype, $oldv);
00461         }
00462     }
00463 
00464     protected function is_circular_reference($obj) {
00465         // Get object dependencies recursively and check (by name) if $this is already there
00466         $dependencies = $obj->get_dependencies();
00467         if (array_key_exists($this->name, $dependencies) || $obj == $this) {
00468             return true;
00469         }
00470         // Recurse the dependent settings one by one
00471         foreach ($dependencies as $dependency) {
00472             if ($dependency->get_dependent_setting()->is_circular_reference($obj)) {
00473                 return true;
00474             }
00475         }
00476         return false;
00477     }
00478 
00479     public function get_dependencies() {
00480         return $this->dependencies;
00481     }
00482 
00483     public function get_ui_name() {
00484         return $this->uisetting->get_name();
00485     }
00486 
00487     public function get_ui_type() {
00488         return $this->uisetting->get_type();
00489     }
00490 
00497     public function set_help($identifier, $component='moodle') {
00498         $this->help = array($identifier, $component);
00499     }
00500 
00505     public function get_help() {
00506         if ($this->has_help()) {
00507             return $this->help;
00508         }
00509         return false;
00510     }
00511 
00516     public function has_help() {
00517         return (!empty($this->help));
00518     }
00519 }
00520 
00521 /*
00522  * Exception class used by all the @setting_base stuff
00523  */
00524 class base_setting_exception extends backup_exception {
00525 
00526     public function __construct($errorcode, $a=NULL, $debuginfo=null) {
00527         parent::__construct($errorcode, $a, $debuginfo);
00528     }
00529 }
 All Data Structures Namespaces Files Functions Variables Enumerations