|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00105 defined('MOODLE_INTERNAL') || die(); 00106 00108 require_once($CFG->libdir.'/ddllib.php'); 00109 require_once($CFG->libdir.'/xmlize.php'); 00110 require_once($CFG->libdir.'/messagelib.php'); 00111 00112 define('INSECURE_DATAROOT_WARNING', 1); 00113 define('INSECURE_DATAROOT_ERROR', 2); 00114 00123 function uninstall_plugin($type, $name) { 00124 global $CFG, $DB, $OUTPUT; 00125 00126 // recursively uninstall all module subplugins first 00127 if ($type === 'mod') { 00128 if (file_exists("$CFG->dirroot/mod/$name/db/subplugins.php")) { 00129 $subplugins = array(); 00130 include("$CFG->dirroot/mod/$name/db/subplugins.php"); 00131 foreach ($subplugins as $subplugintype=>$dir) { 00132 $instances = get_plugin_list($subplugintype); 00133 foreach ($instances as $subpluginname => $notusedpluginpath) { 00134 uninstall_plugin($subplugintype, $subpluginname); 00135 } 00136 } 00137 } 00138 00139 } 00140 00141 $component = $type . '_' . $name; // eg. 'qtype_multichoice' or 'workshopgrading_accumulative' or 'mod_forum' 00142 00143 if ($type === 'mod') { 00144 $pluginname = $name; // eg. 'forum' 00145 if (get_string_manager()->string_exists('modulename', $component)) { 00146 $strpluginname = get_string('modulename', $component); 00147 } else { 00148 $strpluginname = $component; 00149 } 00150 00151 } else { 00152 $pluginname = $component; 00153 if (get_string_manager()->string_exists('pluginname', $component)) { 00154 $strpluginname = get_string('pluginname', $component); 00155 } else { 00156 $strpluginname = $component; 00157 } 00158 } 00159 00160 echo $OUTPUT->heading($pluginname); 00161 00162 $plugindirectory = get_plugin_directory($type, $name); 00163 $uninstalllib = $plugindirectory . '/db/uninstall.php'; 00164 if (file_exists($uninstalllib)) { 00165 require_once($uninstalllib); 00166 $uninstallfunction = 'xmldb_' . $pluginname . '_uninstall'; // eg. 'xmldb_workshop_uninstall()' 00167 if (function_exists($uninstallfunction)) { 00168 if (!$uninstallfunction()) { 00169 echo $OUTPUT->notification('Encountered a problem running uninstall function for '. $pluginname); 00170 } 00171 } 00172 } 00173 00174 if ($type === 'mod') { 00175 // perform cleanup tasks specific for activity modules 00176 00177 if (!$module = $DB->get_record('modules', array('name' => $name))) { 00178 print_error('moduledoesnotexist', 'error'); 00179 } 00180 00181 // delete all the relevant instances from all course sections 00182 if ($coursemods = $DB->get_records('course_modules', array('module' => $module->id))) { 00183 foreach ($coursemods as $coursemod) { 00184 if (!delete_mod_from_section($coursemod->id, $coursemod->section)) { 00185 echo $OUTPUT->notification("Could not delete the $strpluginname with id = $coursemod->id from section $coursemod->section"); 00186 } 00187 } 00188 } 00189 00190 // clear course.modinfo for courses that used this module 00191 $sql = "UPDATE {course} 00192 SET modinfo='' 00193 WHERE id IN (SELECT DISTINCT course 00194 FROM {course_modules} 00195 WHERE module=?)"; 00196 $DB->execute($sql, array($module->id)); 00197 00198 // delete all the course module records 00199 $DB->delete_records('course_modules', array('module' => $module->id)); 00200 00201 // delete module contexts 00202 if ($coursemods) { 00203 foreach ($coursemods as $coursemod) { 00204 if (!delete_context(CONTEXT_MODULE, $coursemod->id)) { 00205 echo $OUTPUT->notification("Could not delete the context for $strpluginname with id = $coursemod->id"); 00206 } 00207 } 00208 } 00209 00210 // delete the module entry itself 00211 $DB->delete_records('modules', array('name' => $module->name)); 00212 00213 // cleanup the gradebook 00214 require_once($CFG->libdir.'/gradelib.php'); 00215 grade_uninstalled_module($module->name); 00216 00217 // Perform any custom uninstall tasks 00218 if (file_exists($CFG->dirroot . '/mod/' . $module->name . '/lib.php')) { 00219 require_once($CFG->dirroot . '/mod/' . $module->name . '/lib.php'); 00220 $uninstallfunction = $module->name . '_uninstall'; 00221 if (function_exists($uninstallfunction)) { 00222 debugging("{$uninstallfunction}() has been deprecated. Use the plugin's db/uninstall.php instead", DEBUG_DEVELOPER); 00223 if (!$uninstallfunction()) { 00224 echo $OUTPUT->notification('Encountered a problem running uninstall function for '. $module->name.'!'); 00225 } 00226 } 00227 } 00228 00229 } else if ($type === 'enrol') { 00230 // NOTE: this is a bit brute force way - it will not trigger events and hooks properly 00231 // nuke all role assignments 00232 role_unassign_all(array('component'=>$component)); 00233 // purge participants 00234 $DB->delete_records_select('user_enrolments', "enrolid IN (SELECT id FROM {enrol} WHERE enrol = ?)", array($name)); 00235 // purge enrol instances 00236 $DB->delete_records('enrol', array('enrol'=>$name)); 00237 // tweak enrol settings 00238 if (!empty($CFG->enrol_plugins_enabled)) { 00239 $enabledenrols = explode(',', $CFG->enrol_plugins_enabled); 00240 $enabledenrols = array_unique($enabledenrols); 00241 $enabledenrols = array_flip($enabledenrols); 00242 unset($enabledenrols[$name]); 00243 $enabledenrols = array_flip($enabledenrols); 00244 if (is_array($enabledenrols)) { 00245 set_config('enrol_plugins_enabled', implode(',', $enabledenrols)); 00246 } 00247 } 00248 00249 } else if ($type === 'block') { 00250 if ($block = $DB->get_record('block', array('name'=>$name))) { 00251 // Inform block it's about to be deleted 00252 if (file_exists("$CFG->dirroot/blocks/$block->name/block_$block->name.php")) { 00253 $blockobject = block_instance($block->name); 00254 if ($blockobject) { 00255 $blockobject->before_delete(); //only if we can create instance, block might have been already removed 00256 } 00257 } 00258 00259 // First delete instances and related contexts 00260 $instances = $DB->get_records('block_instances', array('blockname' => $block->name)); 00261 foreach($instances as $instance) { 00262 blocks_delete_instance($instance); 00263 } 00264 00265 // Delete block 00266 $DB->delete_records('block', array('id'=>$block->id)); 00267 } 00268 } 00269 00270 // perform clean-up task common for all the plugin/subplugin types 00271 00272 // delete calendar events 00273 $DB->delete_records('event', array('modulename' => $pluginname)); 00274 00275 // delete all the logs 00276 $DB->delete_records('log', array('module' => $pluginname)); 00277 00278 // delete log_display information 00279 $DB->delete_records('log_display', array('component' => $component)); 00280 00281 // delete the module configuration records 00282 unset_all_config_for_plugin($pluginname); 00283 00284 // delete message provider 00285 message_provider_uninstall($component); 00286 00287 // delete message processor 00288 if ($type === 'message') { 00289 message_processor_uninstall($name); 00290 } 00291 00292 // delete the plugin tables 00293 $xmldbfilepath = $plugindirectory . '/db/install.xml'; 00294 drop_plugin_tables($component, $xmldbfilepath, false); 00295 if ($type === 'mod' or $type === 'block') { 00296 // non-frankenstyle table prefixes 00297 drop_plugin_tables($name, $xmldbfilepath, false); 00298 } 00299 00300 // delete the capabilities that were defined by this module 00301 capabilities_cleanup($component); 00302 00303 // remove event handlers and dequeue pending events 00304 events_uninstall($component); 00305 00306 echo $OUTPUT->notification(get_string('success'), 'notifysuccess'); 00307 } 00308 00316 function get_component_version($component, $source='installed') { 00317 global $CFG, $DB; 00318 00319 list($type, $name) = normalize_component($component); 00320 00321 // moodle core or a core subsystem 00322 if ($type === 'core') { 00323 if ($source === 'installed') { 00324 if (empty($CFG->version)) { 00325 return false; 00326 } else { 00327 return $CFG->version; 00328 } 00329 } else { 00330 if (!is_readable($CFG->dirroot.'/version.php')) { 00331 return false; 00332 } else { 00333 $version = null; //initialize variable for IDEs 00334 include($CFG->dirroot.'/version.php'); 00335 return $version; 00336 } 00337 } 00338 } 00339 00340 // activity module 00341 if ($type === 'mod') { 00342 if ($source === 'installed') { 00343 return $DB->get_field('modules', 'version', array('name'=>$name)); 00344 } else { 00345 $mods = get_plugin_list('mod'); 00346 if (empty($mods[$name]) or !is_readable($mods[$name].'/version.php')) { 00347 return false; 00348 } else { 00349 $module = new stdclass(); 00350 include($mods[$name].'/version.php'); 00351 return $module->version; 00352 } 00353 } 00354 } 00355 00356 // block 00357 if ($type === 'block') { 00358 if ($source === 'installed') { 00359 return $DB->get_field('block', 'version', array('name'=>$name)); 00360 } else { 00361 $blocks = get_plugin_list('block'); 00362 if (empty($blocks[$name]) or !is_readable($blocks[$name].'/version.php')) { 00363 return false; 00364 } else { 00365 $plugin = new stdclass(); 00366 include($blocks[$name].'/version.php'); 00367 return $plugin->version; 00368 } 00369 } 00370 } 00371 00372 // all other plugin types 00373 if ($source === 'installed') { 00374 return get_config($type.'_'.$name, 'version'); 00375 } else { 00376 $plugins = get_plugin_list($type); 00377 if (empty($plugins[$name])) { 00378 return false; 00379 } else { 00380 $plugin = new stdclass(); 00381 include($plugins[$name].'/version.php'); 00382 return $plugin->version; 00383 } 00384 } 00385 } 00386 00395 function drop_plugin_tables($name, $file, $feedback=true) { 00396 global $CFG, $DB; 00397 00398 // first try normal delete 00399 if (file_exists($file) and $DB->get_manager()->delete_tables_from_xmldb_file($file)) { 00400 return true; 00401 } 00402 00403 // then try to find all tables that start with name and are not in any xml file 00404 $used_tables = get_used_table_names(); 00405 00406 $tables = $DB->get_tables(); 00407 00409 foreach ($tables as $table) { 00410 if (in_array($table, $used_tables)) { 00411 continue; 00412 } 00413 00414 if (strpos($table, $name) !== 0) { 00415 continue; 00416 } 00417 00418 // found orphan table --> delete it 00419 if ($DB->get_manager()->table_exists($table)) { 00420 $xmldb_table = new xmldb_table($table); 00421 $DB->get_manager()->drop_table($xmldb_table); 00422 } 00423 } 00424 00425 return true; 00426 } 00427 00433 function get_used_table_names() { 00434 $table_names = array(); 00435 $dbdirs = get_db_directories(); 00436 00437 foreach ($dbdirs as $dbdir) { 00438 $file = $dbdir.'/install.xml'; 00439 00440 $xmldb_file = new xmldb_file($file); 00441 00442 if (!$xmldb_file->fileExists()) { 00443 continue; 00444 } 00445 00446 $loaded = $xmldb_file->loadXMLStructure(); 00447 $structure = $xmldb_file->getStructure(); 00448 00449 if ($loaded and $tables = $structure->getTables()) { 00450 foreach($tables as $table) { 00451 $table_names[] = strtolower($table->name); 00452 } 00453 } 00454 } 00455 00456 return $table_names; 00457 } 00458 00463 function get_db_directories() { 00464 global $CFG; 00465 00466 $dbdirs = array(); 00467 00469 $dbdirs[] = $CFG->libdir.'/db'; 00470 00472 $plugintypes = get_plugin_types(); 00473 foreach ($plugintypes as $plugintype => $pluginbasedir) { 00474 if ($plugins = get_plugin_list($plugintype)) { 00475 foreach ($plugins as $plugin => $plugindir) { 00476 $dbdirs[] = $plugindir.'/db'; 00477 } 00478 } 00479 } 00480 00481 return $dbdirs; 00482 } 00483 00491 function set_cron_lock($name, $until, $ignorecurrent=false) { 00492 global $DB; 00493 if (empty($name)) { 00494 debugging("Tried to get a cron lock for a null fieldname"); 00495 return false; 00496 } 00497 00498 // remove lock by force == remove from config table 00499 if (is_null($until)) { 00500 set_config($name, null); 00501 return true; 00502 } 00503 00504 if (!$ignorecurrent) { 00505 // read value from db - other processes might have changed it 00506 $value = $DB->get_field('config', 'value', array('name'=>$name)); 00507 00508 if ($value and $value > time()) { 00509 //lock active 00510 return false; 00511 } 00512 } 00513 00514 set_config($name, $until); 00515 return true; 00516 } 00517 00522 function admin_critical_warnings_present() { 00523 global $SESSION; 00524 00525 if (!has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) { 00526 return 0; 00527 } 00528 00529 if (!isset($SESSION->admin_critical_warning)) { 00530 $SESSION->admin_critical_warning = 0; 00531 if (is_dataroot_insecure(true) === INSECURE_DATAROOT_ERROR) { 00532 $SESSION->admin_critical_warning = 1; 00533 } 00534 } 00535 00536 return $SESSION->admin_critical_warning; 00537 } 00538 00547 function is_float_problem() { 00548 $num1 = 2009010200.01; 00549 $num2 = 2009010200.02; 00550 00551 return ((string)$num1 === (string)$num2 or $num1 === $num2 or $num2 <= (string)$num1); 00552 } 00553 00566 function is_dataroot_insecure($fetchtest=false) { 00567 global $CFG; 00568 00569 $siteroot = str_replace('\\', '/', strrev($CFG->dirroot.'/')); // win32 backslash workaround 00570 00571 $rp = preg_replace('|https?://[^/]+|i', '', $CFG->wwwroot, 1); 00572 $rp = strrev(trim($rp, '/')); 00573 $rp = explode('/', $rp); 00574 foreach($rp as $r) { 00575 if (strpos($siteroot, '/'.$r.'/') === 0) { 00576 $siteroot = substr($siteroot, strlen($r)+1); // moodle web in subdirectory 00577 } else { 00578 break; // probably alias root 00579 } 00580 } 00581 00582 $siteroot = strrev($siteroot); 00583 $dataroot = str_replace('\\', '/', $CFG->dataroot.'/'); 00584 00585 if (strpos($dataroot, $siteroot) !== 0) { 00586 return false; 00587 } 00588 00589 if (!$fetchtest) { 00590 return INSECURE_DATAROOT_WARNING; 00591 } 00592 00593 // now try all methods to fetch a test file using http protocol 00594 00595 $httpdocroot = str_replace('\\', '/', strrev($CFG->dirroot.'/')); 00596 preg_match('|(https?://[^/]+)|i', $CFG->wwwroot, $matches); 00597 $httpdocroot = $matches[1]; 00598 $datarooturl = $httpdocroot.'/'. substr($dataroot, strlen($siteroot)); 00599 make_upload_directory('diag'); 00600 $testfile = $CFG->dataroot.'/diag/public.txt'; 00601 if (!file_exists($testfile)) { 00602 file_put_contents($testfile, 'test file, do not delete'); 00603 } 00604 $teststr = trim(file_get_contents($testfile)); 00605 if (empty($teststr)) { 00606 // hmm, strange 00607 return INSECURE_DATAROOT_WARNING; 00608 } 00609 00610 $testurl = $datarooturl.'/diag/public.txt'; 00611 if (extension_loaded('curl') and 00612 !(stripos(ini_get('disable_functions'), 'curl_init') !== FALSE) and 00613 !(stripos(ini_get('disable_functions'), 'curl_setop') !== FALSE) and 00614 ($ch = @curl_init($testurl)) !== false) { 00615 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 00616 curl_setopt($ch, CURLOPT_HEADER, false); 00617 $data = curl_exec($ch); 00618 if (!curl_errno($ch)) { 00619 $data = trim($data); 00620 if ($data === $teststr) { 00621 curl_close($ch); 00622 return INSECURE_DATAROOT_ERROR; 00623 } 00624 } 00625 curl_close($ch); 00626 } 00627 00628 if ($data = @file_get_contents($testurl)) { 00629 $data = trim($data); 00630 if ($data === $teststr) { 00631 return INSECURE_DATAROOT_ERROR; 00632 } 00633 } 00634 00635 preg_match('|https?://([^/]+)|i', $testurl, $matches); 00636 $sitename = $matches[1]; 00637 $error = 0; 00638 if ($fp = @fsockopen($sitename, 80, $error)) { 00639 preg_match('|https?://[^/]+(.*)|i', $testurl, $matches); 00640 $localurl = $matches[1]; 00641 $out = "GET $localurl HTTP/1.1\r\n"; 00642 $out .= "Host: $sitename\r\n"; 00643 $out .= "Connection: Close\r\n\r\n"; 00644 fwrite($fp, $out); 00645 $data = ''; 00646 $incoming = false; 00647 while (!feof($fp)) { 00648 if ($incoming) { 00649 $data .= fgets($fp, 1024); 00650 } else if (@fgets($fp, 1024) === "\r\n") { 00651 $incoming = true; 00652 } 00653 } 00654 fclose($fp); 00655 $data = trim($data); 00656 if ($data === $teststr) { 00657 return INSECURE_DATAROOT_ERROR; 00658 } 00659 } 00660 00661 return INSECURE_DATAROOT_WARNING; 00662 } 00663 00665 00666 00676 interface part_of_admin_tree { 00677 00693 public function locate($name); 00694 00701 public function prune($name); 00702 00708 public function search($query); 00709 00722 public function check_access(); 00723 00729 public function is_hidden(); 00730 00735 public function show_save(); 00736 } 00737 00738 00749 interface parentable_part_of_admin_tree extends part_of_admin_tree { 00750 00763 public function add($destinationname, $something); 00764 00765 } 00766 00767 00775 class admin_category implements parentable_part_of_admin_tree { 00776 00778 public $children; 00780 public $name; 00782 public $visiblename; 00784 public $hidden; 00786 public $path; 00788 public $visiblepath; 00789 00791 protected $category_cache; 00792 00800 public function __construct($name, $visiblename, $hidden=false) { 00801 $this->children = array(); 00802 $this->name = $name; 00803 $this->visiblename = $visiblename; 00804 $this->hidden = $hidden; 00805 } 00806 00815 public function locate($name, $findpath=false) { 00816 if (is_array($this->category_cache) and !isset($this->category_cache[$this->name])) { 00817 // somebody much have purged the cache 00818 $this->category_cache[$this->name] = $this; 00819 } 00820 00821 if ($this->name == $name) { 00822 if ($findpath) { 00823 $this->visiblepath[] = $this->visiblename; 00824 $this->path[] = $this->name; 00825 } 00826 return $this; 00827 } 00828 00829 // quick category lookup 00830 if (!$findpath and is_array($this->category_cache) and isset($this->category_cache[$name])) { 00831 return $this->category_cache[$name]; 00832 } 00833 00834 $return = NULL; 00835 foreach($this->children as $childid=>$unused) { 00836 if ($return = $this->children[$childid]->locate($name, $findpath)) { 00837 break; 00838 } 00839 } 00840 00841 if (!is_null($return) and $findpath) { 00842 $return->visiblepath[] = $this->visiblename; 00843 $return->path[] = $this->name; 00844 } 00845 00846 return $return; 00847 } 00848 00855 public function search($query) { 00856 $result = array(); 00857 foreach ($this->children as $child) { 00858 $subsearch = $child->search($query); 00859 if (!is_array($subsearch)) { 00860 debugging('Incorrect search result from '.$child->name); 00861 continue; 00862 } 00863 $result = array_merge($result, $subsearch); 00864 } 00865 return $result; 00866 } 00867 00874 public function prune($name) { 00875 00876 if ($this->name == $name) { 00877 return false; //can not remove itself 00878 } 00879 00880 foreach($this->children as $precedence => $child) { 00881 if ($child->name == $name) { 00882 // clear cache and delete self 00883 if (is_array($this->category_cache)) { 00884 while($this->category_cache) { 00885 // delete the cache, but keep the original array address 00886 array_pop($this->category_cache); 00887 } 00888 } 00889 unset($this->children[$precedence]); 00890 return true; 00891 } else if ($this->children[$precedence]->prune($name)) { 00892 return true; 00893 } 00894 } 00895 return false; 00896 } 00897 00905 public function add($parentname, $something) { 00906 $parent = $this->locate($parentname); 00907 if (is_null($parent)) { 00908 debugging('parent does not exist!'); 00909 return false; 00910 } 00911 00912 if ($something instanceof part_of_admin_tree) { 00913 if (!($parent instanceof parentable_part_of_admin_tree)) { 00914 debugging('error - parts of tree can be inserted only into parentable parts'); 00915 return false; 00916 } 00917 $parent->children[] = $something; 00918 if (is_array($this->category_cache) and ($something instanceof admin_category)) { 00919 if (isset($this->category_cache[$something->name])) { 00920 debugging('Duplicate admin category name: '.$something->name); 00921 } else { 00922 $this->category_cache[$something->name] = $something; 00923 $something->category_cache =& $this->category_cache; 00924 foreach ($something->children as $child) { 00925 // just in case somebody already added subcategories 00926 if ($child instanceof admin_category) { 00927 if (isset($this->category_cache[$child->name])) { 00928 debugging('Duplicate admin category name: '.$child->name); 00929 } else { 00930 $this->category_cache[$child->name] = $child; 00931 $child->category_cache =& $this->category_cache; 00932 } 00933 } 00934 } 00935 } 00936 } 00937 return true; 00938 00939 } else { 00940 debugging('error - can not add this element'); 00941 return false; 00942 } 00943 00944 } 00945 00951 public function check_access() { 00952 foreach ($this->children as $child) { 00953 if ($child->check_access()) { 00954 return true; 00955 } 00956 } 00957 return false; 00958 } 00959 00965 public function is_hidden() { 00966 return $this->hidden; 00967 } 00968 00973 public function show_save() { 00974 foreach ($this->children as $child) { 00975 if ($child->show_save()) { 00976 return true; 00977 } 00978 } 00979 return false; 00980 } 00981 } 00982 00983 00989 class admin_root extends admin_category { 00991 public $errors; 00993 public $search; 00995 public $fulltree; 00997 public $loaded; 00999 public $custom_defaults; 01000 01005 public function __construct($fulltree) { 01006 global $CFG; 01007 01008 parent::__construct('root', get_string('administration'), false); 01009 $this->errors = array(); 01010 $this->search = ''; 01011 $this->fulltree = $fulltree; 01012 $this->loaded = false; 01013 01014 $this->category_cache = array(); 01015 01016 // load custom defaults if found 01017 $this->custom_defaults = null; 01018 $defaultsfile = "$CFG->dirroot/local/defaults.php"; 01019 if (is_readable($defaultsfile)) { 01020 $defaults = array(); 01021 include($defaultsfile); 01022 if (is_array($defaults) and count($defaults)) { 01023 $this->custom_defaults = $defaults; 01024 } 01025 } 01026 } 01027 01033 public function purge_children($requirefulltree) { 01034 $this->children = array(); 01035 $this->fulltree = ($requirefulltree || $this->fulltree); 01036 $this->loaded = false; 01037 //break circular dependencies - this helps PHP 5.2 01038 while($this->category_cache) { 01039 array_pop($this->category_cache); 01040 } 01041 $this->category_cache = array(); 01042 } 01043 } 01044 01045 01053 class admin_externalpage implements part_of_admin_tree { 01054 01056 public $name; 01057 01059 public $visiblename; 01060 01062 public $url; 01063 01065 public $req_capability; 01066 01068 public $context; 01069 01071 public $hidden; 01072 01074 public $path; 01075 01077 public $visiblepath; 01078 01090 public function __construct($name, $visiblename, $url, $req_capability='moodle/site:config', $hidden=false, $context=NULL) { 01091 $this->name = $name; 01092 $this->visiblename = $visiblename; 01093 $this->url = $url; 01094 if (is_array($req_capability)) { 01095 $this->req_capability = $req_capability; 01096 } else { 01097 $this->req_capability = array($req_capability); 01098 } 01099 $this->hidden = $hidden; 01100 $this->context = $context; 01101 } 01102 01110 public function locate($name, $findpath=false) { 01111 if ($this->name == $name) { 01112 if ($findpath) { 01113 $this->visiblepath = array($this->visiblename); 01114 $this->path = array($this->name); 01115 } 01116 return $this; 01117 } else { 01118 $return = NULL; 01119 return $return; 01120 } 01121 } 01122 01129 public function prune($name) { 01130 return false; 01131 } 01132 01139 public function search($query) { 01140 $textlib = textlib_get_instance(); 01141 01142 $found = false; 01143 if (strpos(strtolower($this->name), $query) !== false) { 01144 $found = true; 01145 } else if (strpos($textlib->strtolower($this->visiblename), $query) !== false) { 01146 $found = true; 01147 } 01148 if ($found) { 01149 $result = new stdClass(); 01150 $result->page = $this; 01151 $result->settings = array(); 01152 return array($this->name => $result); 01153 } else { 01154 return array(); 01155 } 01156 } 01157 01163 public function check_access() { 01164 global $CFG; 01165 $context = empty($this->context) ? get_context_instance(CONTEXT_SYSTEM) : $this->context; 01166 foreach($this->req_capability as $cap) { 01167 if (has_capability($cap, $context)) { 01168 return true; 01169 } 01170 } 01171 return false; 01172 } 01173 01179 public function is_hidden() { 01180 return $this->hidden; 01181 } 01182 01187 public function show_save() { 01188 return false; 01189 } 01190 } 01191 01192 01198 class admin_settingpage implements part_of_admin_tree { 01199 01201 public $name; 01202 01204 public $visiblename; 01205 01207 public $settings; 01208 01210 public $req_capability; 01211 01213 public $context; 01214 01216 public $hidden; 01217 01219 public $path; 01220 01222 public $visiblepath; 01223 01234 public function __construct($name, $visiblename, $req_capability='moodle/site:config', $hidden=false, $context=NULL) { 01235 $this->settings = new stdClass(); 01236 $this->name = $name; 01237 $this->visiblename = $visiblename; 01238 if (is_array($req_capability)) { 01239 $this->req_capability = $req_capability; 01240 } else { 01241 $this->req_capability = array($req_capability); 01242 } 01243 $this->hidden = $hidden; 01244 $this->context = $context; 01245 } 01246 01254 public function locate($name, $findpath=false) { 01255 if ($this->name == $name) { 01256 if ($findpath) { 01257 $this->visiblepath = array($this->visiblename); 01258 $this->path = array($this->name); 01259 } 01260 return $this; 01261 } else { 01262 $return = NULL; 01263 return $return; 01264 } 01265 } 01266 01273 public function search($query) { 01274 $found = array(); 01275 01276 foreach ($this->settings as $setting) { 01277 if ($setting->is_related($query)) { 01278 $found[] = $setting; 01279 } 01280 } 01281 01282 if ($found) { 01283 $result = new stdClass(); 01284 $result->page = $this; 01285 $result->settings = $found; 01286 return array($this->name => $result); 01287 } 01288 01289 $textlib = textlib_get_instance(); 01290 01291 $found = false; 01292 if (strpos(strtolower($this->name), $query) !== false) { 01293 $found = true; 01294 } else if (strpos($textlib->strtolower($this->visiblename), $query) !== false) { 01295 $found = true; 01296 } 01297 if ($found) { 01298 $result = new stdClass(); 01299 $result->page = $this; 01300 $result->settings = array(); 01301 return array($this->name => $result); 01302 } else { 01303 return array(); 01304 } 01305 } 01306 01313 public function prune($name) { 01314 return false; 01315 } 01316 01326 public function add($setting) { 01327 if (!($setting instanceof admin_setting)) { 01328 debugging('error - not a setting instance'); 01329 return false; 01330 } 01331 01332 $this->settings->{$setting->name} = $setting; 01333 return true; 01334 } 01335 01341 public function check_access() { 01342 global $CFG; 01343 $context = empty($this->context) ? get_context_instance(CONTEXT_SYSTEM) : $this->context; 01344 foreach($this->req_capability as $cap) { 01345 if (has_capability($cap, $context)) { 01346 return true; 01347 } 01348 } 01349 return false; 01350 } 01351 01356 public function output_html() { 01357 $adminroot = admin_get_root(); 01358 $return = '<fieldset>'."\n".'<div class="clearer"><!-- --></div>'."\n"; 01359 foreach($this->settings as $setting) { 01360 $fullname = $setting->get_full_name(); 01361 if (array_key_exists($fullname, $adminroot->errors)) { 01362 $data = $adminroot->errors[$fullname]->data; 01363 } else { 01364 $data = $setting->get_setting(); 01365 // do not use defaults if settings not available - upgrade settings handles the defaults! 01366 } 01367 $return .= $setting->output_html($data); 01368 } 01369 $return .= '</fieldset>'; 01370 return $return; 01371 } 01372 01378 public function is_hidden() { 01379 return $this->hidden; 01380 } 01381 01386 public function show_save() { 01387 foreach($this->settings as $setting) { 01388 if (empty($setting->nosave)) { 01389 return true; 01390 } 01391 } 01392 return false; 01393 } 01394 } 01395 01396 01403 abstract class admin_setting { 01405 public $name; 01407 public $visiblename; 01409 public $description; 01411 public $defaultsetting; 01413 public $updatedcallback; 01415 public $plugin; // null means main config table 01417 public $nosave = false; 01419 public $affectsmodinfo = false; 01420 01429 public function __construct($name, $visiblename, $description, $defaultsetting) { 01430 $this->parse_setting_name($name); 01431 $this->visiblename = $visiblename; 01432 $this->description = $description; 01433 $this->defaultsetting = $defaultsetting; 01434 } 01435 01446 private function parse_setting_name($name) { 01447 $bits = explode('/', $name); 01448 if (count($bits) > 2) { 01449 throw new moodle_exception('invalidadminsettingname', '', '', $name); 01450 } 01451 $this->name = array_pop($bits); 01452 if (!preg_match('/^[a-zA-Z0-9_]+$/', $this->name)) { 01453 throw new moodle_exception('invalidadminsettingname', '', '', $name); 01454 } 01455 if (!empty($bits)) { 01456 $this->plugin = array_pop($bits); 01457 if ($this->plugin === 'moodle') { 01458 $this->plugin = null; 01459 } else if (!preg_match('/^[a-zA-Z0-9_]+$/', $this->plugin)) { 01460 throw new moodle_exception('invalidadminsettingname', '', '', $name); 01461 } 01462 } 01463 } 01464 01469 public function get_full_name() { 01470 return 's_'.$this->plugin.'_'.$this->name; 01471 } 01472 01477 public function get_id() { 01478 return 'id_s_'.$this->plugin.'_'.$this->name; 01479 } 01480 01485 public function set_affects_modinfo($affectsmodinfo) { 01486 $this->affectsmodinfo = $affectsmodinfo; 01487 } 01488 01494 public function config_read($name) { 01495 global $CFG; 01496 if (!empty($this->plugin)) { 01497 $value = get_config($this->plugin, $name); 01498 return $value === false ? NULL : $value; 01499 01500 } else { 01501 if (isset($CFG->$name)) { 01502 return $CFG->$name; 01503 } else { 01504 return NULL; 01505 } 01506 } 01507 } 01508 01516 public function config_write($name, $value) { 01517 global $DB, $USER, $CFG; 01518 01519 if ($this->nosave) { 01520 return true; 01521 } 01522 01523 // make sure it is a real change 01524 $oldvalue = get_config($this->plugin, $name); 01525 $oldvalue = ($oldvalue === false) ? null : $oldvalue; // normalise 01526 $value = is_null($value) ? null : (string)$value; 01527 01528 if ($oldvalue === $value) { 01529 return true; 01530 } 01531 01532 // store change 01533 set_config($name, $value, $this->plugin); 01534 01535 // Some admin settings affect course modinfo 01536 if ($this->affectsmodinfo) { 01537 // Clear course cache for all courses 01538 rebuild_course_cache(0, true); 01539 } 01540 01541 // log change 01542 $log = new stdClass(); 01543 $log->userid = during_initial_install() ? 0 :$USER->id; // 0 as user id during install 01544 $log->timemodified = time(); 01545 $log->plugin = $this->plugin; 01546 $log->name = $name; 01547 $log->value = $value; 01548 $log->oldvalue = $oldvalue; 01549 $DB->insert_record('config_log', $log); 01550 01551 return true; // BC only 01552 } 01553 01558 public abstract function get_setting(); 01559 01564 public function get_defaultsetting() { 01565 $adminroot = admin_get_root(false, false); 01566 if (!empty($adminroot->custom_defaults)) { 01567 $plugin = is_null($this->plugin) ? 'moodle' : $this->plugin; 01568 if (isset($adminroot->custom_defaults[$plugin])) { 01569 if (array_key_exists($this->name, $adminroot->custom_defaults[$plugin])) { // null is valid value here ;-) 01570 return $adminroot->custom_defaults[$plugin][$this->name]; 01571 } 01572 } 01573 } 01574 return $this->defaultsetting; 01575 } 01576 01583 public abstract function write_setting($data); 01584 01593 public function output_html($data, $query='') { 01594 // should be overridden 01595 return; 01596 } 01597 01603 public function set_updatedcallback($functionname) { 01604 $this->updatedcallback = $functionname; 01605 } 01606 01612 public function is_related($query) { 01613 if (strpos(strtolower($this->name), $query) !== false) { 01614 return true; 01615 } 01616 $textlib = textlib_get_instance(); 01617 if (strpos($textlib->strtolower($this->visiblename), $query) !== false) { 01618 return true; 01619 } 01620 if (strpos($textlib->strtolower($this->description), $query) !== false) { 01621 return true; 01622 } 01623 $current = $this->get_setting(); 01624 if (!is_null($current)) { 01625 if (is_string($current)) { 01626 if (strpos($textlib->strtolower($current), $query) !== false) { 01627 return true; 01628 } 01629 } 01630 } 01631 $default = $this->get_defaultsetting(); 01632 if (!is_null($default)) { 01633 if (is_string($default)) { 01634 if (strpos($textlib->strtolower($default), $query) !== false) { 01635 return true; 01636 } 01637 } 01638 } 01639 return false; 01640 } 01641 } 01642 01643 01649 class admin_setting_heading extends admin_setting { 01650 01657 public function __construct($name, $heading, $information) { 01658 $this->nosave = true; 01659 parent::__construct($name, $heading, $information, ''); 01660 } 01661 01666 public function get_setting() { 01667 return true; 01668 } 01669 01674 public function get_defaultsetting() { 01675 return true; 01676 } 01677 01682 public function write_setting($data) { 01683 // do not write any setting 01684 return ''; 01685 } 01686 01691 public function output_html($data, $query='') { 01692 global $OUTPUT; 01693 $return = ''; 01694 if ($this->visiblename != '') { 01695 $return .= $OUTPUT->heading($this->visiblename, 3, 'main'); 01696 } 01697 if ($this->description != '') { 01698 $return .= $OUTPUT->box(highlight($query, markdown_to_html($this->description)), 'generalbox formsettingheading'); 01699 } 01700 return $return; 01701 } 01702 } 01703 01704 01710 class admin_setting_configtext extends admin_setting { 01711 01713 public $paramtype; 01715 public $size; 01716 01727 public function __construct($name, $visiblename, $description, $defaultsetting, $paramtype=PARAM_RAW, $size=null) { 01728 $this->paramtype = $paramtype; 01729 if (!is_null($size)) { 01730 $this->size = $size; 01731 } else { 01732 $this->size = ($paramtype === PARAM_INT) ? 5 : 30; 01733 } 01734 parent::__construct($name, $visiblename, $description, $defaultsetting); 01735 } 01736 01742 public function get_setting() { 01743 return $this->config_read($this->name); 01744 } 01745 01746 public function write_setting($data) { 01747 if ($this->paramtype === PARAM_INT and $data === '') { 01748 // do not complain if '' used instead of 0 01749 $data = 0; 01750 } 01751 // $data is a string 01752 $validated = $this->validate($data); 01753 if ($validated !== true) { 01754 return $validated; 01755 } 01756 return ($this->config_write($this->name, $data) ? '' : get_string('errorsetting', 'admin')); 01757 } 01758 01764 public function validate($data) { 01765 // allow paramtype to be a custom regex if it is the form of /pattern/ 01766 if (preg_match('#^/.*/$#', $this->paramtype)) { 01767 if (preg_match($this->paramtype, $data)) { 01768 return true; 01769 } else { 01770 return get_string('validateerror', 'admin'); 01771 } 01772 01773 } else if ($this->paramtype === PARAM_RAW) { 01774 return true; 01775 01776 } else { 01777 $cleaned = clean_param($data, $this->paramtype); 01778 if ("$data" === "$cleaned") { // implicit conversion to string is needed to do exact comparison 01779 return true; 01780 } else { 01781 return get_string('validateerror', 'admin'); 01782 } 01783 } 01784 } 01785 01790 public function output_html($data, $query='') { 01791 $default = $this->get_defaultsetting(); 01792 01793 return format_admin_setting($this, $this->visiblename, 01794 '<div class="form-text defaultsnext"><input type="text" size="'.$this->size.'" id="'.$this->get_id().'" name="'.$this->get_full_name().'" value="'.s($data).'" /></div>', 01795 $this->description, true, '', $default, $query); 01796 } 01797 } 01798 01799 01805 class admin_setting_configtextarea extends admin_setting_configtext { 01806 private $rows; 01807 private $cols; 01808 01818 public function __construct($name, $visiblename, $description, $defaultsetting, $paramtype=PARAM_RAW, $cols='60', $rows='8') { 01819 $this->rows = $rows; 01820 $this->cols = $cols; 01821 parent::__construct($name, $visiblename, $description, $defaultsetting, $paramtype); 01822 } 01823 01831 public function output_html($data, $query='') { 01832 $default = $this->get_defaultsetting(); 01833 01834 $defaultinfo = $default; 01835 if (!is_null($default) and $default !== '') { 01836 $defaultinfo = "\n".$default; 01837 } 01838 01839 return format_admin_setting($this, $this->visiblename, 01840 '<div class="form-textarea" ><textarea rows="'. $this->rows .'" cols="'. $this->cols .'" id="'. $this->get_id() .'" name="'. $this->get_full_name() .'">'. s($data) .'</textarea></div>', 01841 $this->description, true, '', $defaultinfo, $query); 01842 } 01843 } 01844 01845 01849 class admin_setting_confightmleditor extends admin_setting_configtext { 01850 private $rows; 01851 private $cols; 01852 01860 public function __construct($name, $visiblename, $description, $defaultsetting, $paramtype=PARAM_RAW, $cols='60', $rows='8') { 01861 $this->rows = $rows; 01862 $this->cols = $cols; 01863 parent::__construct($name, $visiblename, $description, $defaultsetting, $paramtype); 01864 editors_head_setup(); 01865 } 01866 01874 public function output_html($data, $query='') { 01875 $default = $this->get_defaultsetting(); 01876 01877 $defaultinfo = $default; 01878 if (!is_null($default) and $default !== '') { 01879 $defaultinfo = "\n".$default; 01880 } 01881 01882 $editor = editors_get_preferred_editor(FORMAT_HTML); 01883 $editor->use_editor($this->get_id(), array('noclean'=>true)); 01884 01885 return format_admin_setting($this, $this->visiblename, 01886 '<div class="form-textarea"><textarea rows="'. $this->rows .'" cols="'. $this->cols .'" id="'. $this->get_id() .'" name="'. $this->get_full_name() .'">'. s($data) .'</textarea></div>', 01887 $this->description, true, '', $defaultinfo, $query); 01888 } 01889 } 01890 01891 01897 class admin_setting_configpasswordunmask extends admin_setting_configtext { 01905 public function __construct($name, $visiblename, $description, $defaultsetting) { 01906 parent::__construct($name, $visiblename, $description, $defaultsetting, PARAM_RAW, 30); 01907 } 01908 01918 public function output_html($data, $query='') { 01919 $id = $this->get_id(); 01920 $unmask = get_string('unmaskpassword', 'form'); 01921 $unmaskjs = '<script type="text/javascript"> 01922 //<![CDATA[ 01923 var is_ie = (navigator.userAgent.toLowerCase().indexOf("msie") != -1); 01924 01925 document.getElementById("'.$id.'").setAttribute("autocomplete", "off"); 01926 01927 var unmaskdiv = document.getElementById("'.$id.'unmaskdiv"); 01928 01929 var unmaskchb = document.createElement("input"); 01930 unmaskchb.setAttribute("type", "checkbox"); 01931 unmaskchb.setAttribute("id", "'.$id.'unmask"); 01932 unmaskchb.onchange = function() {unmaskPassword("'.$id.'");}; 01933 unmaskdiv.appendChild(unmaskchb); 01934 01935 var unmasklbl = document.createElement("label"); 01936 unmasklbl.innerHTML = "'.addslashes_js($unmask).'"; 01937 if (is_ie) { 01938 unmasklbl.setAttribute("htmlFor", "'.$id.'unmask"); 01939 } else { 01940 unmasklbl.setAttribute("for", "'.$id.'unmask"); 01941 } 01942 unmaskdiv.appendChild(unmasklbl); 01943 01944 if (is_ie) { 01945 // ugly hack to work around the famous onchange IE bug 01946 unmaskchb.onclick = function() {this.blur();}; 01947 unmaskdiv.onclick = function() {this.blur();}; 01948 } 01949 //]]> 01950 </script>'; 01951 return format_admin_setting($this, $this->visiblename, 01952 '<div class="form-password"><input type="password" size="'.$this->size.'" id="'.$id.'" name="'.$this->get_full_name().'" value="'.s($data).'" /><div class="unmask" id="'.$id.'unmaskdiv"></div>'.$unmaskjs.'</div>', 01953 $this->description, true, '', NULL, $query); 01954 } 01955 } 01956 01957 01963 class admin_setting_configfile extends admin_setting_configtext { 01971 public function __construct($name, $visiblename, $description, $defaultdirectory) { 01972 parent::__construct($name, $visiblename, $description, $defaultdirectory, PARAM_RAW, 50); 01973 } 01974 01985 public function output_html($data, $query='') { 01986 $default = $this->get_defaultsetting(); 01987 01988 if ($data) { 01989 if (file_exists($data)) { 01990 $executable = '<span class="pathok">✔</span>'; 01991 } else { 01992 $executable = '<span class="patherror">✘</span>'; 01993 } 01994 } else { 01995 $executable = ''; 01996 } 01997 01998 return format_admin_setting($this, $this->visiblename, 01999 '<div class="form-file defaultsnext"><input type="text" size="'.$this->size.'" id="'.$this->get_id().'" name="'.$this->get_full_name().'" value="'.s($data).'" />'.$executable.'</div>', 02000 $this->description, true, '', $default, $query); 02001 } 02002 } 02003 02004 02010 class admin_setting_configexecutable extends admin_setting_configfile { 02011 02019 public function output_html($data, $query='') { 02020 $default = $this->get_defaultsetting(); 02021 02022 if ($data) { 02023 if (file_exists($data) and is_executable($data)) { 02024 $executable = '<span class="pathok">✔</span>'; 02025 } else { 02026 $executable = '<span class="patherror">✘</span>'; 02027 } 02028 } else { 02029 $executable = ''; 02030 } 02031 02032 return format_admin_setting($this, $this->visiblename, 02033 '<div class="form-file defaultsnext"><input type="text" size="'.$this->size.'" id="'.$this->get_id().'" name="'.$this->get_full_name().'" value="'.s($data).'" />'.$executable.'</div>', 02034 $this->description, true, '', $default, $query); 02035 } 02036 } 02037 02038 02044 class admin_setting_configdirectory extends admin_setting_configfile { 02045 02053 public function output_html($data, $query='') { 02054 $default = $this->get_defaultsetting(); 02055 02056 if ($data) { 02057 if (file_exists($data) and is_dir($data)) { 02058 $executable = '<span class="pathok">✔</span>'; 02059 } else { 02060 $executable = '<span class="patherror">✘</span>'; 02061 } 02062 } else { 02063 $executable = ''; 02064 } 02065 02066 return format_admin_setting($this, $this->visiblename, 02067 '<div class="form-file defaultsnext"><input type="text" size="'.$this->size.'" id="'.$this->get_id().'" name="'.$this->get_full_name().'" value="'.s($data).'" />'.$executable.'</div>', 02068 $this->description, true, '', $default, $query); 02069 } 02070 } 02071 02072 02078 class admin_setting_configcheckbox extends admin_setting { 02080 public $yes; 02082 public $no; 02083 02093 public function __construct($name, $visiblename, $description, $defaultsetting, $yes='1', $no='0') { 02094 parent::__construct($name, $visiblename, $description, $defaultsetting); 02095 $this->yes = (string)$yes; 02096 $this->no = (string)$no; 02097 } 02098 02104 public function get_setting() { 02105 return $this->config_read($this->name); 02106 } 02107 02117 public function write_setting($data) { 02118 if ((string)$data === $this->yes) { // convert to strings before comparison 02119 $data = $this->yes; 02120 } else { 02121 $data = $this->no; 02122 } 02123 return ($this->config_write($this->name, $data) ? '' : get_string('errorsetting', 'admin')); 02124 } 02125 02133 public function output_html($data, $query='') { 02134 $default = $this->get_defaultsetting(); 02135 02136 if (!is_null($default)) { 02137 if ((string)$default === $this->yes) { 02138 $defaultinfo = get_string('checkboxyes', 'admin'); 02139 } else { 02140 $defaultinfo = get_string('checkboxno', 'admin'); 02141 } 02142 } else { 02143 $defaultinfo = NULL; 02144 } 02145 02146 if ((string)$data === $this->yes) { // convert to strings before comparison 02147 $checked = 'checked="checked"'; 02148 } else { 02149 $checked = ''; 02150 } 02151 02152 return format_admin_setting($this, $this->visiblename, 02153 '<div class="form-checkbox defaultsnext" ><input type="hidden" name="'.$this->get_full_name().'" value="'.s($this->no).'" /> ' 02154 .'<input type="checkbox" id="'.$this->get_id().'" name="'.$this->get_full_name().'" value="'.s($this->yes).'" '.$checked.' /></div>', 02155 $this->description, true, '', $defaultinfo, $query); 02156 } 02157 } 02158 02159 02165 class admin_setting_configmulticheckbox extends admin_setting { 02167 public $choices; 02168 02178 public function __construct($name, $visiblename, $description, $defaultsetting, $choices) { 02179 $this->choices = $choices; 02180 parent::__construct($name, $visiblename, $description, $defaultsetting); 02181 } 02182 02189 public function load_choices() { 02190 /* 02191 if (is_array($this->choices)) { 02192 return true; 02193 } 02194 .... load choices here 02195 */ 02196 return true; 02197 } 02198 02205 public function is_related($query) { 02206 if (!$this->load_choices() or empty($this->choices)) { 02207 return false; 02208 } 02209 if (parent::is_related($query)) { 02210 return true; 02211 } 02212 02213 $textlib = textlib_get_instance(); 02214 foreach ($this->choices as $desc) { 02215 if (strpos($textlib->strtolower($desc), $query) !== false) { 02216 return true; 02217 } 02218 } 02219 return false; 02220 } 02221 02227 public function get_setting() { 02228 $result = $this->config_read($this->name); 02229 02230 if (is_null($result)) { 02231 return NULL; 02232 } 02233 if ($result === '') { 02234 return array(); 02235 } 02236 $enabled = explode(',', $result); 02237 $setting = array(); 02238 foreach ($enabled as $option) { 02239 $setting[$option] = 1; 02240 } 02241 return $setting; 02242 } 02243 02250 public function write_setting($data) { 02251 if (!is_array($data)) { 02252 return ''; // ignore it 02253 } 02254 if (!$this->load_choices() or empty($this->choices)) { 02255 return ''; 02256 } 02257 unset($data['xxxxx']); 02258 $result = array(); 02259 foreach ($data as $key => $value) { 02260 if ($value and array_key_exists($key, $this->choices)) { 02261 $result[] = $key; 02262 } 02263 } 02264 return $this->config_write($this->name, implode(',', $result)) ? '' : get_string('errorsetting', 'admin'); 02265 } 02266 02280 public function output_html($data, $query='') { 02281 if (!$this->load_choices() or empty($this->choices)) { 02282 return ''; 02283 } 02284 $default = $this->get_defaultsetting(); 02285 if (is_null($default)) { 02286 $default = array(); 02287 } 02288 if (is_null($data)) { 02289 $data = array(); 02290 } 02291 $options = array(); 02292 $defaults = array(); 02293 foreach ($this->choices as $key=>$description) { 02294 if (!empty($data[$key])) { 02295 $checked = 'checked="checked"'; 02296 } else { 02297 $checked = ''; 02298 } 02299 if (!empty($default[$key])) { 02300 $defaults[] = $description; 02301 } 02302 02303 $options[] = '<input type="checkbox" id="'.$this->get_id().'_'.$key.'" name="'.$this->get_full_name().'['.$key.']" value="1" '.$checked.' />' 02304 .'<label for="'.$this->get_id().'_'.$key.'">'.highlightfast($query, $description).'</label>'; 02305 } 02306 02307 if (is_null($default)) { 02308 $defaultinfo = NULL; 02309 } else if (!empty($defaults)) { 02310 $defaultinfo = implode(', ', $defaults); 02311 } else { 02312 $defaultinfo = get_string('none'); 02313 } 02314 02315 $return = '<div class="form-multicheckbox">'; 02316 $return .= '<input type="hidden" name="'.$this->get_full_name().'[xxxxx]" value="1" />'; // something must be submitted even if nothing selected 02317 if ($options) { 02318 $return .= '<ul>'; 02319 foreach ($options as $option) { 02320 $return .= '<li>'.$option.'</li>'; 02321 } 02322 $return .= '</ul>'; 02323 } 02324 $return .= '</div>'; 02325 02326 return format_admin_setting($this, $this->visiblename, $return, $this->description, false, '', $defaultinfo, $query); 02327 02328 } 02329 } 02330 02331 02337 class admin_setting_configmulticheckbox2 extends admin_setting_configmulticheckbox { 02338 02344 public function get_setting() { 02345 $result = $this->config_read($this->name); 02346 if (is_null($result)) { 02347 return NULL; 02348 } 02349 if (!$this->load_choices()) { 02350 return NULL; 02351 } 02352 $result = str_pad($result, count($this->choices), '0'); 02353 $result = preg_split('//', $result, -1, PREG_SPLIT_NO_EMPTY); 02354 $setting = array(); 02355 foreach ($this->choices as $key=>$unused) { 02356 $value = array_shift($result); 02357 if ($value) { 02358 $setting[$key] = 1; 02359 } 02360 } 02361 return $setting; 02362 } 02363 02370 public function write_setting($data) { 02371 if (!is_array($data)) { 02372 return ''; // ignore it 02373 } 02374 if (!$this->load_choices() or empty($this->choices)) { 02375 return ''; 02376 } 02377 $result = ''; 02378 foreach ($this->choices as $key=>$unused) { 02379 if (!empty($data[$key])) { 02380 $result .= '1'; 02381 } else { 02382 $result .= '0'; 02383 } 02384 } 02385 return $this->config_write($this->name, $result) ? '' : get_string('errorsetting', 'admin'); 02386 } 02387 } 02388 02389 02395 class admin_setting_configselect extends admin_setting { 02397 public $choices; 02398 02407 public function __construct($name, $visiblename, $description, $defaultsetting, $choices) { 02408 $this->choices = $choices; 02409 parent::__construct($name, $visiblename, $description, $defaultsetting); 02410 } 02411 02420 public function load_choices() { 02421 /* 02422 if (is_array($this->choices)) { 02423 return true; 02424 } 02425 .... load choices here 02426 */ 02427 return true; 02428 } 02429 02436 public function is_related($query) { 02437 if (parent::is_related($query)) { 02438 return true; 02439 } 02440 if (!$this->load_choices()) { 02441 return false; 02442 } 02443 $textlib = textlib_get_instance(); 02444 foreach ($this->choices as $key=>$value) { 02445 if (strpos($textlib->strtolower($key), $query) !== false) { 02446 return true; 02447 } 02448 if (strpos($textlib->strtolower($value), $query) !== false) { 02449 return true; 02450 } 02451 } 02452 return false; 02453 } 02454 02460 public function get_setting() { 02461 return $this->config_read($this->name); 02462 } 02463 02470 public function write_setting($data) { 02471 if (!$this->load_choices() or empty($this->choices)) { 02472 return ''; 02473 } 02474 if (!array_key_exists($data, $this->choices)) { 02475 return ''; // ignore it 02476 } 02477 02478 return ($this->config_write($this->name, $data) ? '' : get_string('errorsetting', 'admin')); 02479 } 02480 02493 public function output_select_html($data, $current, $default, $extraname = '') { 02494 if (!$this->load_choices() or empty($this->choices)) { 02495 return array('', ''); 02496 } 02497 02498 $warning = ''; 02499 if (is_null($current)) { 02500 // first run 02501 } else if (empty($current) and (array_key_exists('', $this->choices) or array_key_exists(0, $this->choices))) { 02502 // no warning 02503 } else if (!array_key_exists($current, $this->choices)) { 02504 $warning = get_string('warningcurrentsetting', 'admin', s($current)); 02505 if (!is_null($default) and $data == $current) { 02506 $data = $default; // use default instead of first value when showing the form 02507 } 02508 } 02509 02510 $selecthtml = '<select id="'.$this->get_id().'" name="'.$this->get_full_name().$extraname.'">'; 02511 foreach ($this->choices as $key => $value) { 02512 // the string cast is needed because key may be integer - 0 is equal to most strings! 02513 $selecthtml .= '<option value="'.$key.'"'.((string)$key==$data ? ' selected="selected"' : '').'>'.$value.'</option>'; 02514 } 02515 $selecthtml .= '</select>'; 02516 return array($selecthtml, $warning); 02517 } 02518 02528 public function output_html($data, $query='') { 02529 $default = $this->get_defaultsetting(); 02530 $current = $this->get_setting(); 02531 02532 list($selecthtml, $warning) = $this->output_select_html($data, $current, $default); 02533 if (!$selecthtml) { 02534 return ''; 02535 } 02536 02537 if (!is_null($default) and array_key_exists($default, $this->choices)) { 02538 $defaultinfo = $this->choices[$default]; 02539 } else { 02540 $defaultinfo = NULL; 02541 } 02542 02543 $return = '<div class="form-select defaultsnext">' . $selecthtml . '</div>'; 02544 02545 return format_admin_setting($this, $this->visiblename, $return, $this->description, true, $warning, $defaultinfo, $query); 02546 } 02547 } 02548 02549 02555 class admin_setting_configmultiselect extends admin_setting_configselect { 02564 public function __construct($name, $visiblename, $description, $defaultsetting, $choices) { 02565 parent::__construct($name, $visiblename, $description, $defaultsetting, $choices); 02566 } 02567 02573 public function get_setting() { 02574 $result = $this->config_read($this->name); 02575 if (is_null($result)) { 02576 return NULL; 02577 } 02578 if ($result === '') { 02579 return array(); 02580 } 02581 return explode(',', $result); 02582 } 02583 02592 public function write_setting($data) { 02593 if (!is_array($data)) { 02594 return ''; //ignore it 02595 } 02596 if (!$this->load_choices() or empty($this->choices)) { 02597 return ''; 02598 } 02599 02600 unset($data['xxxxx']); 02601 02602 $save = array(); 02603 foreach ($data as $value) { 02604 if (!array_key_exists($value, $this->choices)) { 02605 continue; // ignore it 02606 } 02607 $save[] = $value; 02608 } 02609 02610 return ($this->config_write($this->name, implode(',', $save)) ? '' : get_string('errorsetting', 'admin')); 02611 } 02612 02619 public function is_related($query) { 02620 if (!$this->load_choices() or empty($this->choices)) { 02621 return false; 02622 } 02623 if (parent::is_related($query)) { 02624 return true; 02625 } 02626 02627 $textlib = textlib_get_instance(); 02628 foreach ($this->choices as $desc) { 02629 if (strpos($textlib->strtolower($desc), $query) !== false) { 02630 return true; 02631 } 02632 } 02633 return false; 02634 } 02635 02644 public function output_html($data, $query='') { 02645 if (!$this->load_choices() or empty($this->choices)) { 02646 return ''; 02647 } 02648 $choices = $this->choices; 02649 $default = $this->get_defaultsetting(); 02650 if (is_null($default)) { 02651 $default = array(); 02652 } 02653 if (is_null($data)) { 02654 $data = array(); 02655 } 02656 02657 $defaults = array(); 02658 $size = min(10, count($this->choices)); 02659 $return = '<div class="form-select"><input type="hidden" name="'.$this->get_full_name().'[xxxxx]" value="1" />'; // something must be submitted even if nothing selected 02660 $return .= '<select id="'.$this->get_id().'" name="'.$this->get_full_name().'[]" size="'.$size.'" multiple="multiple">'; 02661 foreach ($this->choices as $key => $description) { 02662 if (in_array($key, $data)) { 02663 $selected = 'selected="selected"'; 02664 } else { 02665 $selected = ''; 02666 } 02667 if (in_array($key, $default)) { 02668 $defaults[] = $description; 02669 } 02670 02671 $return .= '<option value="'.s($key).'" '.$selected.'>'.$description.'</option>'; 02672 } 02673 02674 if (is_null($default)) { 02675 $defaultinfo = NULL; 02676 } if (!empty($defaults)) { 02677 $defaultinfo = implode(', ', $defaults); 02678 } else { 02679 $defaultinfo = get_string('none'); 02680 } 02681 02682 $return .= '</select></div>'; 02683 return format_admin_setting($this, $this->visiblename, $return, $this->description, true, '', $defaultinfo, $query); 02684 } 02685 } 02686 02695 class admin_setting_configtime extends admin_setting { 02697 public $name2; 02698 02707 public function __construct($hoursname, $minutesname, $visiblename, $description, $defaultsetting) { 02708 $this->name2 = $minutesname; 02709 parent::__construct($hoursname, $visiblename, $description, $defaultsetting); 02710 } 02711 02717 public function get_setting() { 02718 $result1 = $this->config_read($this->name); 02719 $result2 = $this->config_read($this->name2); 02720 if (is_null($result1) or is_null($result2)) { 02721 return NULL; 02722 } 02723 02724 return array('h' => $result1, 'm' => $result2); 02725 } 02726 02733 public function write_setting($data) { 02734 if (!is_array($data)) { 02735 return ''; 02736 } 02737 02738 $result = $this->config_write($this->name, (int)$data['h']) && $this->config_write($this->name2, (int)$data['m']); 02739 return ($result ? '' : get_string('errorsetting', 'admin')); 02740 } 02741 02749 public function output_html($data, $query='') { 02750 $default = $this->get_defaultsetting(); 02751 02752 if (is_array($default)) { 02753 $defaultinfo = $default['h'].':'.$default['m']; 02754 } else { 02755 $defaultinfo = NULL; 02756 } 02757 02758 $return = '<div class="form-time defaultsnext">'. 02759 '<select id="'.$this->get_id().'h" name="'.$this->get_full_name().'[h]">'; 02760 for ($i = 0; $i < 24; $i++) { 02761 $return .= '<option value="'.$i.'"'.($i == $data['h'] ? ' selected="selected"' : '').'>'.$i.'</option>'; 02762 } 02763 $return .= '</select>:<select id="'.$this->get_id().'m" name="'.$this->get_full_name().'[m]">'; 02764 for ($i = 0; $i < 60; $i += 5) { 02765 $return .= '<option value="'.$i.'"'.($i == $data['m'] ? ' selected="selected"' : '').'>'.$i.'</option>'; 02766 } 02767 $return .= '</select></div>'; 02768 return format_admin_setting($this, $this->visiblename, $return, $this->description, false, '', $defaultinfo, $query); 02769 } 02770 02771 } 02772 02773 02779 class admin_setting_configiplist extends admin_setting_configtextarea { 02780 02790 public function validate($data) { 02791 if(!empty($data)) { 02792 $ips = explode("\n", $data); 02793 } else { 02794 return true; 02795 } 02796 $result = true; 02797 foreach($ips as $ip) { 02798 $ip = trim($ip); 02799 if (preg_match('#^(\d{1,3})(\.\d{1,3}){0,3}$#', $ip, $match) || 02800 preg_match('#^(\d{1,3})(\.\d{1,3}){0,3}(\/\d{1,2})$#', $ip, $match) || 02801 preg_match('#^(\d{1,3})(\.\d{1,3}){3}(-\d{1,3})$#', $ip, $match)) { 02802 $result = true; 02803 } else { 02804 $result = false; 02805 break; 02806 } 02807 } 02808 if($result) { 02809 return true; 02810 } else { 02811 return get_string('validateerror', 'admin'); 02812 } 02813 } 02814 } 02815 02816 02830 class admin_setting_users_with_capability extends admin_setting_configmultiselect { 02832 protected $capability; 02834 protected $includeadmins; 02835 02846 function __construct($name, $visiblename, $description, $defaultsetting, $capability, $includeadmins = true) { 02847 $this->capability = $capability; 02848 $this->includeadmins = $includeadmins; 02849 parent::__construct($name, $visiblename, $description, $defaultsetting, NULL); 02850 } 02851 02857 function load_choices() { 02858 if (is_array($this->choices)) { 02859 return true; 02860 } 02861 $users = get_users_by_capability(get_context_instance(CONTEXT_SYSTEM), 02862 $this->capability, 'u.id,u.username,u.firstname,u.lastname', 'u.lastname,u.firstname'); 02863 $this->choices = array( 02864 '$@NONE@$' => get_string('nobody'), 02865 '$@ALL@$' => get_string('everyonewhocan', 'admin', get_capability_string($this->capability)), 02866 ); 02867 if ($this->includeadmins) { 02868 $admins = get_admins(); 02869 foreach ($admins as $user) { 02870 $this->choices[$user->id] = fullname($user); 02871 } 02872 } 02873 if (is_array($users)) { 02874 foreach ($users as $user) { 02875 $this->choices[$user->id] = fullname($user); 02876 } 02877 } 02878 return true; 02879 } 02880 02886 public function get_defaultsetting() { 02887 $this->load_choices(); 02888 $defaultsetting = parent::get_defaultsetting(); 02889 if (empty($defaultsetting)) { 02890 return array('$@NONE@$'); 02891 } else if (array_key_exists($defaultsetting, $this->choices)) { 02892 return $defaultsetting; 02893 } else { 02894 return ''; 02895 } 02896 } 02897 02903 public function get_setting() { 02904 $result = parent::get_setting(); 02905 if ($result === null) { 02906 // this is necessary for settings upgrade 02907 return null; 02908 } 02909 if (empty($result)) { 02910 $result = array('$@NONE@$'); 02911 } 02912 return $result; 02913 } 02914 02921 public function write_setting($data) { 02922 // If all is selected, remove any explicit options. 02923 if (in_array('$@ALL@$', $data)) { 02924 $data = array('$@ALL@$'); 02925 } 02926 // None never needs to be written to the DB. 02927 if (in_array('$@NONE@$', $data)) { 02928 unset($data[array_search('$@NONE@$', $data)]); 02929 } 02930 return parent::write_setting($data); 02931 } 02932 } 02933 02934 02940 class admin_setting_special_adminseesall extends admin_setting_configcheckbox { 02949 public function __construct() { 02950 parent::__construct('calendar_adminseesall', get_string('adminseesall', 'admin'), 02951 get_string('helpadminseesall', 'admin'), '0'); 02952 } 02953 02960 public function write_setting($data) { 02961 global $SESSION; 02962 return parent::write_setting($data); 02963 } 02964 } 02965 02971 class admin_setting_special_selectsetup extends admin_setting_configselect { 02977 public function get_setting() { 02978 // read directly from db! 02979 return get_config(NULL, $this->name); 02980 } 02981 02988 public function write_setting($data) { 02989 global $CFG; 02990 // do not change active CFG setting! 02991 $current = $CFG->{$this->name}; 02992 $result = parent::write_setting($data); 02993 $CFG->{$this->name} = $current; 02994 return $result; 02995 } 02996 } 02997 02998 03004 class admin_setting_sitesetselect extends admin_setting_configselect { 03011 public function get_setting() { 03012 $site = get_site(); 03013 return $site->{$this->name}; 03014 } 03015 03022 public function write_setting($data) { 03023 global $DB, $SITE; 03024 if (!in_array($data, array_keys($this->choices))) { 03025 return get_string('errorsetting', 'admin'); 03026 } 03027 $record = new stdClass(); 03028 $record->id = SITEID; 03029 $temp = $this->name; 03030 $record->$temp = $data; 03031 $record->timemodified = time(); 03032 // update $SITE 03033 $SITE->{$this->name} = $data; 03034 return ($DB->update_record('course', $record) ? '' : get_string('errorsetting', 'admin')); 03035 } 03036 } 03037 03038 03045 class admin_setting_bloglevel extends admin_setting_configselect { 03052 public function write_setting($data) { 03053 global $DB, $CFG; 03054 if ($data == 0) { 03055 $blogblocks = $DB->get_records_select('block', "name LIKE 'blog_%' AND visible = 1"); 03056 foreach ($blogblocks as $block) { 03057 $DB->set_field('block', 'visible', 0, array('id' => $block->id)); 03058 } 03059 } else { 03060 // reenable all blocks only when switching from disabled blogs 03061 if (isset($CFG->bloglevel) and $CFG->bloglevel == 0) { 03062 $blogblocks = $DB->get_records_select('block', "name LIKE 'blog_%' AND visible = 0"); 03063 foreach ($blogblocks as $block) { 03064 $DB->set_field('block', 'visible', 1, array('id' => $block->id)); 03065 } 03066 } 03067 } 03068 return parent::write_setting($data); 03069 } 03070 } 03071 03072 03078 class admin_setting_courselist_frontpage extends admin_setting { 03080 public $choices; 03081 03087 public function __construct($loggedin) { 03088 global $CFG; 03089 require_once($CFG->dirroot.'/course/lib.php'); 03090 $name = 'frontpage'.($loggedin ? 'loggedin' : ''); 03091 $visiblename = get_string('frontpage'.($loggedin ? 'loggedin' : ''),'admin'); 03092 $description = get_string('configfrontpage'.($loggedin ? 'loggedin' : ''),'admin'); 03093 $defaults = array(FRONTPAGECOURSELIST); 03094 parent::__construct($name, $visiblename, $description, $defaults); 03095 } 03096 03102 public function load_choices() { 03103 global $DB; 03104 if (is_array($this->choices)) { 03105 return true; 03106 } 03107 $this->choices = array(FRONTPAGENEWS => get_string('frontpagenews'), 03108 FRONTPAGECOURSELIST => get_string('frontpagecourselist'), 03109 FRONTPAGECATEGORYNAMES => get_string('frontpagecategorynames'), 03110 FRONTPAGECATEGORYCOMBO => get_string('frontpagecategorycombo'), 03111 'none' => get_string('none')); 03112 if ($this->name == 'frontpage' and $DB->count_records('course') > FRONTPAGECOURSELIMIT) { 03113 unset($this->choices[FRONTPAGECOURSELIST]); 03114 } 03115 return true; 03116 } 03117 03123 public function get_setting() { 03124 $result = $this->config_read($this->name); 03125 if (is_null($result)) { 03126 return NULL; 03127 } 03128 if ($result === '') { 03129 return array(); 03130 } 03131 return explode(',', $result); 03132 } 03133 03140 public function write_setting($data) { 03141 if (!is_array($data)) { 03142 return ''; 03143 } 03144 $this->load_choices(); 03145 $save = array(); 03146 foreach($data as $datum) { 03147 if ($datum == 'none' or !array_key_exists($datum, $this->choices)) { 03148 continue; 03149 } 03150 $save[$datum] = $datum; // no duplicates 03151 } 03152 return ($this->config_write($this->name, implode(',', $save)) ? '' : get_string('errorsetting', 'admin')); 03153 } 03154 03162 public function output_html($data, $query='') { 03163 $this->load_choices(); 03164 $currentsetting = array(); 03165 foreach ($data as $key) { 03166 if ($key != 'none' and array_key_exists($key, $this->choices)) { 03167 $currentsetting[] = $key; // already selected first 03168 } 03169 } 03170 03171 $return = '<div class="form-group">'; 03172 for ($i = 0; $i < count($this->choices) - 1; $i++) { 03173 if (!array_key_exists($i, $currentsetting)) { 03174 $currentsetting[$i] = 'none'; //none 03175 } 03176 $return .='<select class="form-select" id="'.$this->get_id().$i.'" name="'.$this->get_full_name().'[]">'; 03177 foreach ($this->choices as $key => $value) { 03178 $return .= '<option value="'.$key.'"'.("$key" == $currentsetting[$i] ? ' selected="selected"' : '').'>'.$value.'</option>'; 03179 } 03180 $return .= '</select>'; 03181 if ($i !== count($this->choices) - 2) { 03182 $return .= '<br />'; 03183 } 03184 } 03185 $return .= '</div>'; 03186 03187 return format_admin_setting($this, $this->visiblename, $return, $this->description, false, '', NULL, $query); 03188 } 03189 } 03190 03191 03197 class admin_setting_sitesetcheckbox extends admin_setting_configcheckbox { 03203 public function get_setting() { 03204 $site = get_site(); 03205 return $site->{$this->name}; 03206 } 03207 03214 public function write_setting($data) { 03215 global $DB, $SITE; 03216 $record = new stdClass(); 03217 $record->id = SITEID; 03218 $record->{$this->name} = ($data == '1' ? 1 : 0); 03219 $record->timemodified = time(); 03220 // update $SITE 03221 $SITE->{$this->name} = $data; 03222 return ($DB->update_record('course', $record) ? '' : get_string('errorsetting', 'admin')); 03223 } 03224 } 03225 03232 class admin_setting_sitesettext extends admin_setting_configtext { 03238 public function get_setting() { 03239 $site = get_site(); 03240 return $site->{$this->name} != '' ? $site->{$this->name} : NULL; 03241 } 03242 03249 public function validate($data) { 03250 $cleaned = clean_param($data, PARAM_MULTILANG); 03251 if ($cleaned === '') { 03252 return get_string('required'); 03253 } 03254 if ("$data" == "$cleaned") { // implicit conversion to string is needed to do exact comparison 03255 return true; 03256 } else { 03257 return get_string('validateerror', 'admin'); 03258 } 03259 } 03260 03267 public function write_setting($data) { 03268 global $DB, $SITE; 03269 $data = trim($data); 03270 $validated = $this->validate($data); 03271 if ($validated !== true) { 03272 return $validated; 03273 } 03274 03275 $record = new stdClass(); 03276 $record->id = SITEID; 03277 $record->{$this->name} = $data; 03278 $record->timemodified = time(); 03279 // update $SITE 03280 $SITE->{$this->name} = $data; 03281 return ($DB->update_record('course', $record) ? '' : get_string('dbupdatefailed', 'error')); 03282 } 03283 } 03284 03285 03291 class admin_setting_special_frontpagedesc extends admin_setting { 03295 public function __construct() { 03296 parent::__construct('summary', get_string('frontpagedescription'), get_string('frontpagedescriptionhelp'), NULL); 03297 editors_head_setup(); 03298 } 03299 03304 public function get_setting() { 03305 $site = get_site(); 03306 return $site->{$this->name}; 03307 } 03308 03315 public function write_setting($data) { 03316 global $DB, $SITE; 03317 $record = new stdClass(); 03318 $record->id = SITEID; 03319 $record->{$this->name} = $data; 03320 $record->timemodified = time(); 03321 $SITE->{$this->name} = $data; 03322 return ($DB->update_record('course', $record) ? '' : get_string('errorsetting', 'admin')); 03323 } 03324 03332 public function output_html($data, $query='') { 03333 global $CFG; 03334 03335 $CFG->adminusehtmleditor = can_use_html_editor(); 03336 $return = '<div class="form-htmlarea">'.print_textarea($CFG->adminusehtmleditor, 15, 60, 0, 0, $this->get_full_name(), $data, 0, true, 'summary') .'</div>'; 03337 03338 return format_admin_setting($this, $this->visiblename, $return, $this->description, false, '', NULL, $query); 03339 } 03340 } 03341 03342 03348 class admin_setting_emoticons extends admin_setting { 03349 03353 public function __construct() { 03354 global $CFG; 03355 03356 $manager = get_emoticon_manager(); 03357 $defaults = $this->prepare_form_data($manager->default_emoticons()); 03358 parent::__construct('emoticons', get_string('emoticons', 'admin'), get_string('emoticons_desc', 'admin'), $defaults); 03359 } 03360 03366 public function get_setting() { 03367 global $CFG; 03368 03369 $manager = get_emoticon_manager(); 03370 03371 $config = $this->config_read($this->name); 03372 if (is_null($config)) { 03373 return null; 03374 } 03375 03376 $config = $manager->decode_stored_config($config); 03377 if (is_null($config)) { 03378 return null; 03379 } 03380 03381 return $this->prepare_form_data($config); 03382 } 03383 03390 public function write_setting($data) { 03391 03392 $manager = get_emoticon_manager(); 03393 $emoticons = $this->process_form_data($data); 03394 03395 if ($emoticons === false) { 03396 return false; 03397 } 03398 03399 if ($this->config_write($this->name, $manager->encode_stored_config($emoticons))) { 03400 return ''; // success 03401 } else { 03402 return get_string('errorsetting', 'admin') . $this->visiblename . html_writer::empty_tag('br'); 03403 } 03404 } 03405 03412 public function output_html($data, $query='') { 03413 global $OUTPUT; 03414 03415 $out = html_writer::start_tag('table', array('border' => 1, 'class' => 'generaltable')); 03416 $out .= html_writer::start_tag('thead'); 03417 $out .= html_writer::start_tag('tr'); 03418 $out .= html_writer::tag('th', get_string('emoticontext', 'admin')); 03419 $out .= html_writer::tag('th', get_string('emoticonimagename', 'admin')); 03420 $out .= html_writer::tag('th', get_string('emoticoncomponent', 'admin')); 03421 $out .= html_writer::tag('th', get_string('emoticonalt', 'admin'), array('colspan' => 2)); 03422 $out .= html_writer::tag('th', ''); 03423 $out .= html_writer::end_tag('tr'); 03424 $out .= html_writer::end_tag('thead'); 03425 $out .= html_writer::start_tag('tbody'); 03426 $i = 0; 03427 foreach($data as $field => $value) { 03428 switch ($i) { 03429 case 0: 03430 $out .= html_writer::start_tag('tr'); 03431 $current_text = $value; 03432 $current_filename = ''; 03433 $current_imagecomponent = ''; 03434 $current_altidentifier = ''; 03435 $current_altcomponent = ''; 03436 case 1: 03437 $current_filename = $value; 03438 case 2: 03439 $current_imagecomponent = $value; 03440 case 3: 03441 $current_altidentifier = $value; 03442 case 4: 03443 $current_altcomponent = $value; 03444 } 03445 03446 $out .= html_writer::tag('td', 03447 html_writer::empty_tag('input', 03448 array( 03449 'type' => 'text', 03450 'class' => 'form-text', 03451 'name' => $this->get_full_name().'['.$field.']', 03452 'value' => $value, 03453 ) 03454 ), array('class' => 'c'.$i) 03455 ); 03456 03457 if ($i == 4) { 03458 if (get_string_manager()->string_exists($current_altidentifier, $current_altcomponent)) { 03459 $alt = get_string($current_altidentifier, $current_altcomponent); 03460 } else { 03461 $alt = $current_text; 03462 } 03463 if ($current_filename) { 03464 $out .= html_writer::tag('td', $OUTPUT->render(new pix_emoticon($current_filename, $alt, $current_imagecomponent))); 03465 } else { 03466 $out .= html_writer::tag('td', ''); 03467 } 03468 $out .= html_writer::end_tag('tr'); 03469 $i = 0; 03470 } else { 03471 $i++; 03472 } 03473 03474 } 03475 $out .= html_writer::end_tag('tbody'); 03476 $out .= html_writer::end_tag('table'); 03477 $out = html_writer::tag('div', $out, array('class' => 'form-group')); 03478 $out .= html_writer::tag('div', html_writer::link(new moodle_url('/admin/resetemoticons.php'), get_string('emoticonsreset', 'admin'))); 03479 03480 return format_admin_setting($this, $this->visiblename, $out, $this->description, false, '', NULL, $query); 03481 } 03482 03490 protected function prepare_form_data(array $emoticons) { 03491 03492 $form = array(); 03493 $i = 0; 03494 foreach ($emoticons as $emoticon) { 03495 $form['text'.$i] = $emoticon->text; 03496 $form['imagename'.$i] = $emoticon->imagename; 03497 $form['imagecomponent'.$i] = $emoticon->imagecomponent; 03498 $form['altidentifier'.$i] = $emoticon->altidentifier; 03499 $form['altcomponent'.$i] = $emoticon->altcomponent; 03500 $i++; 03501 } 03502 // add one more blank field set for new object 03503 $form['text'.$i] = ''; 03504 $form['imagename'.$i] = ''; 03505 $form['imagecomponent'.$i] = ''; 03506 $form['altidentifier'.$i] = ''; 03507 $form['altcomponent'.$i] = ''; 03508 03509 return $form; 03510 } 03511 03519 protected function process_form_data(array $form) { 03520 03521 $count = count($form); // number of form field values 03522 03523 if ($count % 5) { 03524 // we must get five fields per emoticon object 03525 return false; 03526 } 03527 03528 $emoticons = array(); 03529 for ($i = 0; $i < $count / 5; $i++) { 03530 $emoticon = new stdClass(); 03531 $emoticon->text = clean_param(trim($form['text'.$i]), PARAM_NOTAGS); 03532 $emoticon->imagename = clean_param(trim($form['imagename'.$i]), PARAM_PATH); 03533 $emoticon->imagecomponent = clean_param(trim($form['imagecomponent'.$i]), PARAM_COMPONENT); 03534 $emoticon->altidentifier = clean_param(trim($form['altidentifier'.$i]), PARAM_STRINGID); 03535 $emoticon->altcomponent = clean_param(trim($form['altcomponent'.$i]), PARAM_COMPONENT); 03536 03537 if (strpos($emoticon->text, ':/') !== false or strpos($emoticon->text, '//') !== false) { 03538 // prevent from breaking http://url.addresses by accident 03539 $emoticon->text = ''; 03540 } 03541 03542 if (strlen($emoticon->text) < 2) { 03543 // do not allow single character emoticons 03544 $emoticon->text = ''; 03545 } 03546 03547 if (preg_match('/^[a-zA-Z]+[a-zA-Z0-9]*$/', $emoticon->text)) { 03548 // emoticon text must contain some non-alphanumeric character to prevent 03549 // breaking HTML tags 03550 $emoticon->text = ''; 03551 } 03552 03553 if ($emoticon->text !== '' and $emoticon->imagename !== '' and $emoticon->imagecomponent !== '') { 03554 $emoticons[] = $emoticon; 03555 } 03556 } 03557 return $emoticons; 03558 } 03559 } 03560 03561 03567 class admin_setting_langlist extends admin_setting_configtext { 03571 public function __construct() { 03572 parent::__construct('langlist', get_string('langlist', 'admin'), get_string('configlanglist', 'admin'), '', PARAM_NOTAGS); 03573 } 03574 03581 public function write_setting($data) { 03582 $return = parent::write_setting($data); 03583 get_string_manager()->reset_caches(); 03584 return $return; 03585 } 03586 } 03587 03588 03595 class admin_settings_country_select extends admin_setting_configselect { 03596 protected $includeall; 03597 public function __construct($name, $visiblename, $description, $defaultsetting, $includeall=false) { 03598 $this->includeall = $includeall; 03599 parent::__construct($name, $visiblename, $description, $defaultsetting, NULL); 03600 } 03601 03605 public function load_choices() { 03606 global $CFG; 03607 if (is_array($this->choices)) { 03608 return true; 03609 } 03610 $this->choices = array_merge( 03611 array('0' => get_string('choosedots')), 03612 get_string_manager()->get_list_of_countries($this->includeall)); 03613 return true; 03614 } 03615 } 03616 03617 03625 class admin_settings_num_course_sections extends admin_setting_configselect { 03626 public function __construct($name, $visiblename, $description, $defaultsetting) { 03627 parent::__construct($name, $visiblename, $description, $defaultsetting, array()); 03628 } 03629 03631 public function load_choices() { 03632 $max = get_config('moodlecourse', 'maxsections'); 03633 if (empty($max)) { 03634 $max = 52; 03635 } 03636 for ($i = 0; $i <= $max; $i++) { 03637 $this->choices[$i] = "$i"; 03638 } 03639 return true; 03640 } 03641 } 03642 03643 03649 class admin_settings_coursecat_select extends admin_setting_configselect { 03653 public function __construct($name, $visiblename, $description, $defaultsetting) { 03654 parent::__construct($name, $visiblename, $description, $defaultsetting, NULL); 03655 } 03656 03662 public function load_choices() { 03663 global $CFG; 03664 require_once($CFG->dirroot.'/course/lib.php'); 03665 if (is_array($this->choices)) { 03666 return true; 03667 } 03668 $this->choices = make_categories_options(); 03669 return true; 03670 } 03671 } 03672 03673 03679 class admin_setting_special_backupdays extends admin_setting_configmulticheckbox2 { 03683 public function __construct() { 03684 parent::__construct('backup_auto_weekdays', get_string('automatedbackupschedule','backup'), get_string('automatedbackupschedulehelp','backup'), array(), NULL); 03685 $this->plugin = 'backup'; 03686 } 03687 03693 public function load_choices() { 03694 if (is_array($this->choices)) { 03695 return true; 03696 } 03697 $this->choices = array(); 03698 $days = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'); 03699 foreach ($days as $day) { 03700 $this->choices[$day] = get_string($day, 'calendar'); 03701 } 03702 return true; 03703 } 03704 } 03705 03706 03712 class admin_setting_special_debug extends admin_setting_configselect { 03716 public function __construct() { 03717 parent::__construct('debug', get_string('debug', 'admin'), get_string('configdebug', 'admin'), DEBUG_NONE, NULL); 03718 } 03719 03725 public function load_choices() { 03726 if (is_array($this->choices)) { 03727 return true; 03728 } 03729 $this->choices = array(DEBUG_NONE => get_string('debugnone', 'admin'), 03730 DEBUG_MINIMAL => get_string('debugminimal', 'admin'), 03731 DEBUG_NORMAL => get_string('debugnormal', 'admin'), 03732 DEBUG_ALL => get_string('debugall', 'admin'), 03733 DEBUG_DEVELOPER => get_string('debugdeveloper', 'admin')); 03734 return true; 03735 } 03736 } 03737 03738 03744 class admin_setting_special_calendar_weekend extends admin_setting { 03748 public function __construct() { 03749 $name = 'calendar_weekend'; 03750 $visiblename = get_string('calendar_weekend', 'admin'); 03751 $description = get_string('helpweekenddays', 'admin'); 03752 $default = array ('0', '6'); // Saturdays and Sundays 03753 parent::__construct($name, $visiblename, $description, $default); 03754 } 03755 03761 public function get_setting() { 03762 $result = $this->config_read($this->name); 03763 if (is_null($result)) { 03764 return NULL; 03765 } 03766 if ($result === '') { 03767 return array(); 03768 } 03769 $settings = array(); 03770 for ($i=0; $i<7; $i++) { 03771 if ($result & (1 << $i)) { 03772 $settings[] = $i; 03773 } 03774 } 03775 return $settings; 03776 } 03777 03784 public function write_setting($data) { 03785 if (!is_array($data)) { 03786 return ''; 03787 } 03788 unset($data['xxxxx']); 03789 $result = 0; 03790 foreach($data as $index) { 03791 $result |= 1 << $index; 03792 } 03793 return ($this->config_write($this->name, $result) ? '' : get_string('errorsetting', 'admin')); 03794 } 03795 03803 public function output_html($data, $query='') { 03804 // The order matters very much because of the implied numeric keys 03805 $days = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'); 03806 $return = '<table><thead><tr>'; 03807 $return .= '<input type="hidden" name="'.$this->get_full_name().'[xxxxx]" value="1" />'; // something must be submitted even if nothing selected 03808 foreach($days as $index => $day) { 03809 $return .= '<td><label for="'.$this->get_id().$index.'">'.get_string($day, 'calendar').'</label></td>'; 03810 } 03811 $return .= '</tr></thead><tbody><tr>'; 03812 foreach($days as $index => $day) { 03813 $return .= '<td><input type="checkbox" class="form-checkbox" id="'.$this->get_id().$index.'" name="'.$this->get_full_name().'[]" value="'.$index.'" '.(in_array("$index", $data) ? 'checked="checked"' : '').' /></td>'; 03814 } 03815 $return .= '</tr></tbody></table>'; 03816 03817 return format_admin_setting($this, $this->visiblename, $return, $this->description, false, '', NULL, $query); 03818 03819 } 03820 } 03821 03822 03828 class admin_setting_question_behaviour extends admin_setting_configselect { 03835 public function __construct($name, $visiblename, $description, $default) { 03836 parent::__construct($name, $visiblename, $description, $default, NULL); 03837 } 03838 03843 public function load_choices() { 03844 global $CFG; 03845 require_once($CFG->dirroot . '/question/engine/lib.php'); 03846 $this->choices = question_engine::get_archetypal_behaviours(); 03847 return true; 03848 } 03849 } 03850 03851 03857 class admin_setting_pickroles extends admin_setting_configmulticheckbox { 03859 private $types; 03860 03868 public function __construct($name, $visiblename, $description, $types) { 03869 parent::__construct($name, $visiblename, $description, NULL, NULL); 03870 $this->types = $types; 03871 } 03872 03878 public function load_choices() { 03879 global $CFG, $DB; 03880 if (during_initial_install()) { 03881 return false; 03882 } 03883 if (is_array($this->choices)) { 03884 return true; 03885 } 03886 if ($roles = get_all_roles()) { 03887 $this->choices = array(); 03888 foreach($roles as $role) { 03889 $this->choices[$role->id] = format_string($role->name); 03890 } 03891 return true; 03892 } else { 03893 return false; 03894 } 03895 } 03896 03902 public function get_defaultsetting() { 03903 global $CFG; 03904 03905 if (during_initial_install()) { 03906 return null; 03907 } 03908 $result = array(); 03909 foreach($this->types as $archetype) { 03910 if ($caproles = get_archetype_roles($archetype)) { 03911 foreach ($caproles as $caprole) { 03912 $result[$caprole->id] = 1; 03913 } 03914 } 03915 } 03916 return $result; 03917 } 03918 } 03919 03920 03926 class admin_setting_configtext_with_advanced extends admin_setting_configtext { 03936 public function __construct($name, $visiblename, $description, $defaultsetting, $paramtype=PARAM_RAW, $size=null) { 03937 parent::__construct($name, $visiblename, $description, $defaultsetting, $paramtype, $size); 03938 } 03939 03945 public function get_setting() { 03946 $value = parent::get_setting(); 03947 $adv = $this->config_read($this->name.'_adv'); 03948 if (is_null($value) or is_null($adv)) { 03949 return NULL; 03950 } 03951 return array('value' => $value, 'adv' => $adv); 03952 } 03953 03961 public function write_setting($data) { 03962 $error = parent::write_setting($data['value']); 03963 if (!$error) { 03964 $value = empty($data['adv']) ? 0 : 1; 03965 $this->config_write($this->name.'_adv', $value); 03966 } 03967 return $error; 03968 } 03969 03977 public function output_html($data, $query='') { 03978 $default = $this->get_defaultsetting(); 03979 $defaultinfo = array(); 03980 if (isset($default['value'])) { 03981 if ($default['value'] === '') { 03982 $defaultinfo[] = "''"; 03983 } else { 03984 $defaultinfo[] = $default['value']; 03985 } 03986 } 03987 if (!empty($default['adv'])) { 03988 $defaultinfo[] = get_string('advanced'); 03989 } 03990 $defaultinfo = implode(', ', $defaultinfo); 03991 03992 $adv = !empty($data['adv']); 03993 $return = '<div class="form-text defaultsnext">' . 03994 '<input type="text" size="' . $this->size . '" id="' . $this->get_id() . 03995 '" name="' . $this->get_full_name() . '[value]" value="' . s($data['value']) . '" />' . 03996 ' <input type="checkbox" class="form-checkbox" id="' . 03997 $this->get_id() . '_adv" name="' . $this->get_full_name() . 03998 '[adv]" value="1" ' . ($adv ? 'checked="checked"' : '') . ' />' . 03999 ' <label for="' . $this->get_id() . '_adv">' . 04000 get_string('advanced') . '</label></div>'; 04001 04002 return format_admin_setting($this, $this->visiblename, $return, 04003 $this->description, true, '', $defaultinfo, $query); 04004 } 04005 } 04006 04007 04014 class admin_setting_configcheckbox_with_advanced extends admin_setting_configcheckbox { 04015 04025 public function __construct($name, $visiblename, $description, $defaultsetting, $yes='1', $no='0') { 04026 parent::__construct($name, $visiblename, $description, $defaultsetting, $yes, $no); 04027 } 04028 04034 public function get_setting() { 04035 $value = parent::get_setting(); 04036 $adv = $this->config_read($this->name.'_adv'); 04037 if (is_null($value) or is_null($adv)) { 04038 return NULL; 04039 } 04040 return array('value' => $value, 'adv' => $adv); 04041 } 04042 04052 public function write_setting($data) { 04053 $error = parent::write_setting($data['value']); 04054 if (!$error) { 04055 $value = empty($data['adv']) ? 0 : 1; 04056 $this->config_write($this->name.'_adv', $value); 04057 } 04058 return $error; 04059 } 04060 04068 public function output_html($data, $query='') { 04069 $defaults = $this->get_defaultsetting(); 04070 $defaultinfo = array(); 04071 if (!is_null($defaults)) { 04072 if ((string)$defaults['value'] === $this->yes) { 04073 $defaultinfo[] = get_string('checkboxyes', 'admin'); 04074 } else { 04075 $defaultinfo[] = get_string('checkboxno', 'admin'); 04076 } 04077 if (!empty($defaults['adv'])) { 04078 $defaultinfo[] = get_string('advanced'); 04079 } 04080 } 04081 $defaultinfo = implode(', ', $defaultinfo); 04082 04083 if ((string)$data['value'] === $this->yes) { // convert to strings before comparison 04084 $checked = 'checked="checked"'; 04085 } else { 04086 $checked = ''; 04087 } 04088 if (!empty($data['adv'])) { 04089 $advanced = 'checked="checked"'; 04090 } else { 04091 $advanced = ''; 04092 } 04093 04094 $fullname = $this->get_full_name(); 04095 $novalue = s($this->no); 04096 $yesvalue = s($this->yes); 04097 $id = $this->get_id(); 04098 $stradvanced = get_string('advanced'); 04099 $return = <<<EOT 04100 <div class="form-checkbox defaultsnext" > 04101 <input type="hidden" name="{$fullname}[value]" value="$novalue" /> 04102 <input type="checkbox" id="$id" name="{$fullname}[value]" value="$yesvalue" $checked /> 04103 <input type="checkbox" class="form-checkbox" id="{$id}_adv" name="{$fullname}[adv]" value="1" $advanced /> 04104 <label for="{$id}_adv">$stradvanced</label> 04105 </div> 04106 EOT; 04107 return format_admin_setting($this, $this->visiblename, $return, $this->description, 04108 true, '', $defaultinfo, $query); 04109 } 04110 } 04111 04112 04121 class admin_setting_configcheckbox_with_lock extends admin_setting_configcheckbox { 04131 public function __construct($name, $visiblename, $description, $defaultsetting, $yes='1', $no='0') { 04132 parent::__construct($name, $visiblename, $description, $defaultsetting, $yes, $no); 04133 } 04134 04140 public function get_setting() { 04141 $value = parent::get_setting(); 04142 $locked = $this->config_read($this->name.'_locked'); 04143 if (is_null($value) or is_null($locked)) { 04144 return NULL; 04145 } 04146 return array('value' => $value, 'locked' => $locked); 04147 } 04148 04158 public function write_setting($data) { 04159 $error = parent::write_setting($data['value']); 04160 if (!$error) { 04161 $value = empty($data['locked']) ? 0 : 1; 04162 $this->config_write($this->name.'_locked', $value); 04163 } 04164 return $error; 04165 } 04166 04174 public function output_html($data, $query='') { 04175 $defaults = $this->get_defaultsetting(); 04176 $defaultinfo = array(); 04177 if (!is_null($defaults)) { 04178 if ((string)$defaults['value'] === $this->yes) { 04179 $defaultinfo[] = get_string('checkboxyes', 'admin'); 04180 } else { 04181 $defaultinfo[] = get_string('checkboxno', 'admin'); 04182 } 04183 if (!empty($defaults['locked'])) { 04184 $defaultinfo[] = get_string('locked', 'admin'); 04185 } 04186 } 04187 $defaultinfo = implode(', ', $defaultinfo); 04188 04189 $fullname = $this->get_full_name(); 04190 $novalue = s($this->no); 04191 $yesvalue = s($this->yes); 04192 $id = $this->get_id(); 04193 04194 $checkboxparams = array('type'=>'checkbox', 'id'=>$id,'name'=>$fullname.'[value]', 'value'=>$yesvalue); 04195 if ((string)$data['value'] === $this->yes) { // convert to strings before comparison 04196 $checkboxparams['checked'] = 'checked'; 04197 } 04198 04199 $lockcheckboxparams = array('type'=>'checkbox', 'id'=>$id.'_locked','name'=>$fullname.'[locked]', 'value'=>1, 'class'=>'form-checkbox locked-checkbox'); 04200 if (!empty($data['locked'])) { // convert to strings before comparison 04201 $lockcheckboxparams['checked'] = 'checked'; 04202 } 04203 04204 $return = html_writer::start_tag('div', array('class'=>'form-checkbox defaultsnext')); 04205 $return .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>$fullname.'[value]', 'value'=>$novalue)); 04206 $return .= html_writer::empty_tag('input', $checkboxparams); 04207 $return .= html_writer::empty_tag('input', $lockcheckboxparams); 04208 $return .= html_writer::tag('label', get_string('locked', 'admin'), array('for'=>$id.'_locked')); 04209 $return .= html_writer::end_tag('div'); 04210 return format_admin_setting($this, $this->visiblename, $return, $this->description, true, '', $defaultinfo, $query); 04211 } 04212 } 04213 04214 04220 class admin_setting_configselect_with_advanced extends admin_setting_configselect { 04224 public function __construct($name, $visiblename, $description, $defaultsetting, $choices) { 04225 parent::__construct($name, $visiblename, $description, $defaultsetting, $choices); 04226 } 04227 04233 public function get_setting() { 04234 $value = parent::get_setting(); 04235 $adv = $this->config_read($this->name.'_adv'); 04236 if (is_null($value) or is_null($adv)) { 04237 return NULL; 04238 } 04239 return array('value' => $value, 'adv' => $adv); 04240 } 04241 04249 public function write_setting($data) { 04250 $error = parent::write_setting($data['value']); 04251 if (!$error) { 04252 $value = empty($data['adv']) ? 0 : 1; 04253 $this->config_write($this->name.'_adv', $value); 04254 } 04255 return $error; 04256 } 04257 04265 public function output_html($data, $query='') { 04266 $default = $this->get_defaultsetting(); 04267 $current = $this->get_setting(); 04268 04269 list($selecthtml, $warning) = $this->output_select_html($data['value'], 04270 $current['value'], $default['value'], '[value]'); 04271 if (!$selecthtml) { 04272 return ''; 04273 } 04274 04275 if (!is_null($default) and array_key_exists($default['value'], $this->choices)) { 04276 $defaultinfo = array(); 04277 if (isset($this->choices[$default['value']])) { 04278 $defaultinfo[] = $this->choices[$default['value']]; 04279 } 04280 if (!empty($default['adv'])) { 04281 $defaultinfo[] = get_string('advanced'); 04282 } 04283 $defaultinfo = implode(', ', $defaultinfo); 04284 } else { 04285 $defaultinfo = ''; 04286 } 04287 04288 $adv = !empty($data['adv']); 04289 $return = '<div class="form-select defaultsnext">' . $selecthtml . 04290 ' <input type="checkbox" class="form-checkbox" id="' . 04291 $this->get_id() . '_adv" name="' . $this->get_full_name() . 04292 '[adv]" value="1" ' . ($adv ? 'checked="checked"' : '') . ' />' . 04293 ' <label for="' . $this->get_id() . '_adv">' . 04294 get_string('advanced') . '</label></div>'; 04295 04296 return format_admin_setting($this, $this->visiblename, $return, $this->description, true, $warning, $defaultinfo, $query); 04297 } 04298 } 04299 04300 04306 class admin_setting_special_gradebookroles extends admin_setting_pickroles { 04310 public function __construct() { 04311 parent::__construct('gradebookroles', get_string('gradebookroles', 'admin'), 04312 get_string('configgradebookroles', 'admin'), 04313 array('student')); 04314 } 04315 } 04316 04317 04322 class admin_setting_regradingcheckbox extends admin_setting_configcheckbox { 04329 public function write_setting($data) { 04330 global $CFG, $DB; 04331 04332 $oldvalue = $this->config_read($this->name); 04333 $return = parent::write_setting($data); 04334 $newvalue = $this->config_read($this->name); 04335 04336 if ($oldvalue !== $newvalue) { 04337 // force full regrading 04338 $DB->set_field('grade_items', 'needsupdate', 1, array('needsupdate'=>0)); 04339 } 04340 04341 return $return; 04342 } 04343 } 04344 04345 04351 class admin_setting_special_coursecontact extends admin_setting_pickroles { 04355 public function __construct() { 04356 parent::__construct('coursecontact', get_string('coursecontact', 'admin'), 04357 get_string('coursecontact_desc', 'admin'), 04358 array('editingteacher')); 04359 } 04360 } 04361 04362 04367 class admin_setting_special_gradelimiting extends admin_setting_configcheckbox { 04371 function admin_setting_special_gradelimiting() { 04372 parent::__construct('unlimitedgrades', get_string('unlimitedgrades', 'grades'), 04373 get_string('unlimitedgrades_help', 'grades'), '0', '1', '0'); 04374 } 04375 04379 function regrade_all() { 04380 global $CFG; 04381 require_once("$CFG->libdir/gradelib.php"); 04382 grade_force_site_regrading(); 04383 } 04384 04391 function write_setting($data) { 04392 $previous = $this->get_setting(); 04393 04394 if ($previous === null) { 04395 if ($data) { 04396 $this->regrade_all(); 04397 } 04398 } else { 04399 if ($data != $previous) { 04400 $this->regrade_all(); 04401 } 04402 } 04403 return ($this->config_write($this->name, $data) ? '' : get_string('errorsetting', 'admin')); 04404 } 04405 04406 } 04407 04408 04414 class admin_setting_special_gradeexport extends admin_setting_configmulticheckbox { 04418 public function __construct() { 04419 parent::__construct('gradeexport', get_string('gradeexport', 'admin'), 04420 get_string('configgradeexport', 'admin'), array(), NULL); 04421 } 04422 04428 public function load_choices() { 04429 if (is_array($this->choices)) { 04430 return true; 04431 } 04432 $this->choices = array(); 04433 04434 if ($plugins = get_plugin_list('gradeexport')) { 04435 foreach($plugins as $plugin => $unused) { 04436 $this->choices[$plugin] = get_string('pluginname', 'gradeexport_'.$plugin); 04437 } 04438 } 04439 return true; 04440 } 04441 } 04442 04443 04449 class admin_setting_gradecat_combo extends admin_setting { 04451 public $choices; 04452 04461 public function __construct($name, $visiblename, $description, $defaultsetting, $choices) { 04462 $this->choices = $choices; 04463 parent::__construct($name, $visiblename, $description, $defaultsetting); 04464 } 04465 04471 public function get_setting() { 04472 global $CFG; 04473 04474 $value = $this->config_read($this->name); 04475 $flag = $this->config_read($this->name.'_flag'); 04476 04477 if (is_null($value) or is_null($flag)) { 04478 return NULL; 04479 } 04480 04481 $flag = (int)$flag; 04482 $forced = (boolean)(1 & $flag); // first bit 04483 $adv = (boolean)(2 & $flag); // second bit 04484 04485 return array('value' => $value, 'forced' => $forced, 'adv' => $adv); 04486 } 04487 04495 public function write_setting($data) { 04496 global $CFG; 04497 04498 $value = $data['value']; 04499 $forced = empty($data['forced']) ? 0 : 1; 04500 $adv = empty($data['adv']) ? 0 : 2; 04501 $flag = ($forced | $adv); //bitwise or 04502 04503 if (!in_array($value, array_keys($this->choices))) { 04504 return 'Error setting '; 04505 } 04506 04507 $oldvalue = $this->config_read($this->name); 04508 $oldflag = (int)$this->config_read($this->name.'_flag'); 04509 $oldforced = (1 & $oldflag); // first bit 04510 04511 $result1 = $this->config_write($this->name, $value); 04512 $result2 = $this->config_write($this->name.'_flag', $flag); 04513 04514 // force regrade if needed 04515 if ($oldforced != $forced or ($forced and $value != $oldvalue)) { 04516 require_once($CFG->libdir.'/gradelib.php'); 04517 grade_category::updated_forced_settings(); 04518 } 04519 04520 if ($result1 and $result2) { 04521 return ''; 04522 } else { 04523 return get_string('errorsetting', 'admin'); 04524 } 04525 } 04526 04535 public function output_html($data, $query='') { 04536 $value = $data['value']; 04537 $forced = !empty($data['forced']); 04538 $adv = !empty($data['adv']); 04539 04540 $default = $this->get_defaultsetting(); 04541 if (!is_null($default)) { 04542 $defaultinfo = array(); 04543 if (isset($this->choices[$default['value']])) { 04544 $defaultinfo[] = $this->choices[$default['value']]; 04545 } 04546 if (!empty($default['forced'])) { 04547 $defaultinfo[] = get_string('force'); 04548 } 04549 if (!empty($default['adv'])) { 04550 $defaultinfo[] = get_string('advanced'); 04551 } 04552 $defaultinfo = implode(', ', $defaultinfo); 04553 04554 } else { 04555 $defaultinfo = NULL; 04556 } 04557 04558 04559 $return = '<div class="form-group">'; 04560 $return .= '<select class="form-select" id="'.$this->get_id().'" name="'.$this->get_full_name().'[value]">'; 04561 foreach ($this->choices as $key => $val) { 04562 // the string cast is needed because key may be integer - 0 is equal to most strings! 04563 $return .= '<option value="'.$key.'"'.((string)$key==$value ? ' selected="selected"' : '').'>'.$val.'</option>'; 04564 } 04565 $return .= '</select>'; 04566 $return .= '<input type="checkbox" class="form-checkbox" id="'.$this->get_id().'force" name="'.$this->get_full_name().'[forced]" value="1" '.($forced ? 'checked="checked"' : '').' />' 04567 .'<label for="'.$this->get_id().'force">'.get_string('force').'</label>'; 04568 $return .= '<input type="checkbox" class="form-checkbox" id="'.$this->get_id().'adv" name="'.$this->get_full_name().'[adv]" value="1" '.($adv ? 'checked="checked"' : '').' />' 04569 .'<label for="'.$this->get_id().'adv">'.get_string('advanced').'</label>'; 04570 $return .= '</div>'; 04571 04572 return format_admin_setting($this, $this->visiblename, $return, $this->description, true, '', $defaultinfo, $query); 04573 } 04574 } 04575 04576 04582 class admin_setting_grade_profilereport extends admin_setting_configselect { 04586 public function __construct() { 04587 parent::__construct('grade_profilereport', get_string('profilereport', 'grades'), get_string('profilereport_help', 'grades'), 'user', null); 04588 } 04589 04595 public function load_choices() { 04596 if (is_array($this->choices)) { 04597 return true; 04598 } 04599 $this->choices = array(); 04600 04601 global $CFG; 04602 require_once($CFG->libdir.'/gradelib.php'); 04603 04604 foreach (get_plugin_list('gradereport') as $plugin => $plugindir) { 04605 if (file_exists($plugindir.'/lib.php')) { 04606 require_once($plugindir.'/lib.php'); 04607 $functionname = 'grade_report_'.$plugin.'_profilereport'; 04608 if (function_exists($functionname)) { 04609 $this->choices[$plugin] = get_string('pluginname', 'gradereport_'.$plugin); 04610 } 04611 } 04612 } 04613 return true; 04614 } 04615 } 04616 04617 04623 class admin_setting_special_registerauth extends admin_setting_configselect { 04627 public function __construct() { 04628 parent::__construct('registerauth', get_string('selfregistration', 'auth'), get_string('selfregistration_help', 'auth'), '', null); 04629 } 04630 04636 public function get_defaultsetting() { 04637 $this->load_choices(); 04638 $defaultsetting = parent::get_defaultsetting(); 04639 if (array_key_exists($defaultsetting, $this->choices)) { 04640 return $defaultsetting; 04641 } else { 04642 return ''; 04643 } 04644 } 04645 04651 public function load_choices() { 04652 global $CFG; 04653 04654 if (is_array($this->choices)) { 04655 return true; 04656 } 04657 $this->choices = array(); 04658 $this->choices[''] = get_string('disable'); 04659 04660 $authsenabled = get_enabled_auth_plugins(true); 04661 04662 foreach ($authsenabled as $auth) { 04663 $authplugin = get_auth_plugin($auth); 04664 if (!$authplugin->can_signup()) { 04665 continue; 04666 } 04667 // Get the auth title (from core or own auth lang files) 04668 $authtitle = $authplugin->get_title(); 04669 $this->choices[$auth] = $authtitle; 04670 } 04671 return true; 04672 } 04673 } 04674 04675 04679 class admin_page_pluginsoverview extends admin_externalpage { 04680 04684 public function __construct() { 04685 global $CFG; 04686 parent::__construct('pluginsoverview', get_string('pluginsoverview', 'core_admin'), 04687 "$CFG->wwwroot/$CFG->admin/plugins.php"); 04688 } 04689 } 04690 04696 class admin_page_managemods extends admin_externalpage { 04700 public function __construct() { 04701 global $CFG; 04702 parent::__construct('managemodules', get_string('modsettings', 'admin'), "$CFG->wwwroot/$CFG->admin/modules.php"); 04703 } 04704 04711 public function search($query) { 04712 global $CFG, $DB; 04713 if ($result = parent::search($query)) { 04714 return $result; 04715 } 04716 04717 $found = false; 04718 if ($modules = $DB->get_records('modules')) { 04719 $textlib = textlib_get_instance(); 04720 foreach ($modules as $module) { 04721 if (!file_exists("$CFG->dirroot/mod/$module->name/lib.php")) { 04722 continue; 04723 } 04724 if (strpos($module->name, $query) !== false) { 04725 $found = true; 04726 break; 04727 } 04728 $strmodulename = get_string('modulename', $module->name); 04729 if (strpos($textlib->strtolower($strmodulename), $query) !== false) { 04730 $found = true; 04731 break; 04732 } 04733 } 04734 } 04735 if ($found) { 04736 $result = new stdClass(); 04737 $result->page = $this; 04738 $result->settings = array(); 04739 return array($this->name => $result); 04740 } else { 04741 return array(); 04742 } 04743 } 04744 } 04745 04746 04753 class admin_setting_manageenrols extends admin_setting { 04757 public function __construct() { 04758 $this->nosave = true; 04759 parent::__construct('enrolsui', get_string('manageenrols', 'enrol'), '', ''); 04760 } 04761 04767 public function get_setting() { 04768 return true; 04769 } 04770 04776 public function get_defaultsetting() { 04777 return true; 04778 } 04779 04785 public function write_setting($data) { 04786 // do not write any setting 04787 return ''; 04788 } 04789 04796 public function is_related($query) { 04797 if (parent::is_related($query)) { 04798 return true; 04799 } 04800 04801 $textlib = textlib_get_instance(); 04802 $query = $textlib->strtolower($query); 04803 $enrols = enrol_get_plugins(false); 04804 foreach ($enrols as $name=>$enrol) { 04805 $localised = get_string('pluginname', 'enrol_'.$name); 04806 if (strpos($textlib->strtolower($name), $query) !== false) { 04807 return true; 04808 } 04809 if (strpos($textlib->strtolower($localised), $query) !== false) { 04810 return true; 04811 } 04812 } 04813 return false; 04814 } 04815 04823 public function output_html($data, $query='') { 04824 global $CFG, $OUTPUT, $DB; 04825 04826 // display strings 04827 $strup = get_string('up'); 04828 $strdown = get_string('down'); 04829 $strsettings = get_string('settings'); 04830 $strenable = get_string('enable'); 04831 $strdisable = get_string('disable'); 04832 $struninstall = get_string('uninstallplugin', 'admin'); 04833 $strusage = get_string('enrolusage', 'enrol'); 04834 04835 $enrols_available = enrol_get_plugins(false); 04836 $active_enrols = enrol_get_plugins(true); 04837 04838 $allenrols = array(); 04839 foreach ($active_enrols as $key=>$enrol) { 04840 $allenrols[$key] = true; 04841 } 04842 foreach ($enrols_available as $key=>$enrol) { 04843 $allenrols[$key] = true; 04844 } 04845 // now find all borked plugins and at least allow then to uninstall 04846 $borked = array(); 04847 $condidates = $DB->get_fieldset_sql("SELECT DISTINCT enrol FROM {enrol}"); 04848 foreach ($condidates as $candidate) { 04849 if (empty($allenrols[$candidate])) { 04850 $allenrols[$candidate] = true; 04851 } 04852 } 04853 04854 $return = $OUTPUT->heading(get_string('actenrolshhdr', 'enrol'), 3, 'main', true); 04855 $return .= $OUTPUT->box_start('generalbox enrolsui'); 04856 04857 $table = new html_table(); 04858 $table->head = array(get_string('name'), $strusage, $strenable, $strup.'/'.$strdown, $strsettings, $struninstall); 04859 $table->align = array('left', 'center', 'center', 'center', 'center', 'center'); 04860 $table->width = '90%'; 04861 $table->data = array(); 04862 04863 // iterate through enrol plugins and add to the display table 04864 $updowncount = 1; 04865 $enrolcount = count($active_enrols); 04866 $url = new moodle_url('/admin/enrol.php', array('sesskey'=>sesskey())); 04867 $printed = array(); 04868 foreach($allenrols as $enrol => $unused) { 04869 if (get_string_manager()->string_exists('pluginname', 'enrol_'.$enrol)) { 04870 $name = get_string('pluginname', 'enrol_'.$enrol); 04871 } else { 04872 $name = $enrol; 04873 } 04874 //usage 04875 $ci = $DB->count_records('enrol', array('enrol'=>$enrol)); 04876 $cp = $DB->count_records_select('user_enrolments', "enrolid IN (SELECT id FROM {enrol} WHERE enrol = ?)", array($enrol)); 04877 $usage = "$ci / $cp"; 04878 04879 // hide/show link 04880 if (isset($active_enrols[$enrol])) { 04881 $aurl = new moodle_url($url, array('action'=>'disable', 'enrol'=>$enrol)); 04882 $hideshow = "<a href=\"$aurl\">"; 04883 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/hide') . "\" class=\"icon\" alt=\"$strdisable\" /></a>"; 04884 $enabled = true; 04885 $displayname = "<span>$name</span>"; 04886 } else if (isset($enrols_available[$enrol])) { 04887 $aurl = new moodle_url($url, array('action'=>'enable', 'enrol'=>$enrol)); 04888 $hideshow = "<a href=\"$aurl\">"; 04889 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/show') . "\" class=\"icon\" alt=\"$strenable\" /></a>"; 04890 $enabled = false; 04891 $displayname = "<span class=\"dimmed_text\">$name</span>"; 04892 } else { 04893 $hideshow = ''; 04894 $enabled = false; 04895 $displayname = '<span class="notifyproblem">'.$name.'</span>'; 04896 } 04897 04898 // up/down link (only if enrol is enabled) 04899 $updown = ''; 04900 if ($enabled) { 04901 if ($updowncount > 1) { 04902 $aurl = new moodle_url($url, array('action'=>'up', 'enrol'=>$enrol)); 04903 $updown .= "<a href=\"$aurl\">"; 04904 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"$strup\" /></a> "; 04905 } else { 04906 $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" /> "; 04907 } 04908 if ($updowncount < $enrolcount) { 04909 $aurl = new moodle_url($url, array('action'=>'down', 'enrol'=>$enrol)); 04910 $updown .= "<a href=\"$aurl\">"; 04911 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/down') . "\" alt=\"$strdown\" /></a>"; 04912 } else { 04913 $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" />"; 04914 } 04915 ++$updowncount; 04916 } 04917 04918 // settings link 04919 if (isset($active_enrols[$enrol]) or file_exists($CFG->dirroot.'/enrol/'.$enrol.'/settings.php')) { 04920 $surl = new moodle_url('/admin/settings.php', array('section'=>'enrolsettings'.$enrol)); 04921 $settings = "<a href=\"$surl\">$strsettings</a>"; 04922 } else { 04923 $settings = ''; 04924 } 04925 04926 // uninstall 04927 $aurl = new moodle_url($url, array('action'=>'uninstall', 'enrol'=>$enrol)); 04928 $uninstall = "<a href=\"$aurl\">$struninstall</a>"; 04929 04930 // add a row to the table 04931 $table->data[] = array($displayname, $usage, $hideshow, $updown, $settings, $uninstall); 04932 04933 $printed[$enrol] = true; 04934 } 04935 04936 $return .= html_writer::table($table); 04937 $return .= get_string('configenrolplugins', 'enrol').'<br />'.get_string('tablenosave', 'admin'); 04938 $return .= $OUTPUT->box_end(); 04939 return highlight($query, $return); 04940 } 04941 } 04942 04943 04949 class admin_page_manageblocks extends admin_externalpage { 04953 public function __construct() { 04954 global $CFG; 04955 parent::__construct('manageblocks', get_string('blocksettings', 'admin'), "$CFG->wwwroot/$CFG->admin/blocks.php"); 04956 } 04957 04964 public function search($query) { 04965 global $CFG, $DB; 04966 if ($result = parent::search($query)) { 04967 return $result; 04968 } 04969 04970 $found = false; 04971 if ($blocks = $DB->get_records('block')) { 04972 $textlib = textlib_get_instance(); 04973 foreach ($blocks as $block) { 04974 if (!file_exists("$CFG->dirroot/blocks/$block->name/")) { 04975 continue; 04976 } 04977 if (strpos($block->name, $query) !== false) { 04978 $found = true; 04979 break; 04980 } 04981 $strblockname = get_string('pluginname', 'block_'.$block->name); 04982 if (strpos($textlib->strtolower($strblockname), $query) !== false) { 04983 $found = true; 04984 break; 04985 } 04986 } 04987 } 04988 if ($found) { 04989 $result = new stdClass(); 04990 $result->page = $this; 04991 $result->settings = array(); 04992 return array($this->name => $result); 04993 } else { 04994 return array(); 04995 } 04996 } 04997 } 04998 05004 class admin_page_managemessageoutputs extends admin_externalpage { 05008 public function __construct() { 05009 global $CFG; 05010 parent::__construct('managemessageoutputs', get_string('managemessageoutputs', 'message'), new moodle_url('/admin/message.php')); 05011 } 05012 05019 public function search($query) { 05020 global $CFG, $DB; 05021 if ($result = parent::search($query)) { 05022 return $result; 05023 } 05024 05025 $found = false; 05026 if ($processors = get_message_processors()) { 05027 $textlib = textlib_get_instance(); 05028 foreach ($processors as $processor) { 05029 if (!$processor->available) { 05030 continue; 05031 } 05032 if (strpos($processor->name, $query) !== false) { 05033 $found = true; 05034 break; 05035 } 05036 $strprocessorname = get_string('pluginname', 'message_'.$processor->name); 05037 if (strpos($textlib->strtolower($strprocessorname), $query) !== false) { 05038 $found = true; 05039 break; 05040 } 05041 } 05042 } 05043 if ($found) { 05044 $result = new stdClass(); 05045 $result->page = $this; 05046 $result->settings = array(); 05047 return array($this->name => $result); 05048 } else { 05049 return array(); 05050 } 05051 } 05052 } 05053 05059 class admin_page_defaultmessageoutputs extends admin_page_managemessageoutputs { 05063 public function __construct() { 05064 global $CFG; 05065 admin_externalpage::__construct('defaultmessageoutputs', get_string('defaultmessageoutputs', 'message'), new moodle_url('/message/defaultoutputs.php')); 05066 } 05067 } 05068 05069 05076 class admin_page_manageqbehaviours extends admin_externalpage { 05080 public function __construct() { 05081 global $CFG; 05082 parent::__construct('manageqbehaviours', get_string('manageqbehaviours', 'admin'), 05083 new moodle_url('/admin/qbehaviours.php')); 05084 } 05085 05092 public function search($query) { 05093 global $CFG; 05094 if ($result = parent::search($query)) { 05095 return $result; 05096 } 05097 05098 $found = false; 05099 $textlib = textlib_get_instance(); 05100 require_once($CFG->dirroot . '/question/engine/lib.php'); 05101 foreach (get_plugin_list('qbehaviour') as $behaviour => $notused) { 05102 if (strpos($textlib->strtolower(question_engine::get_behaviour_name($behaviour)), 05103 $query) !== false) { 05104 $found = true; 05105 break; 05106 } 05107 } 05108 if ($found) { 05109 $result = new stdClass(); 05110 $result->page = $this; 05111 $result->settings = array(); 05112 return array($this->name => $result); 05113 } else { 05114 return array(); 05115 } 05116 } 05117 } 05118 05119 05125 class admin_page_manageqtypes extends admin_externalpage { 05129 public function __construct() { 05130 global $CFG; 05131 parent::__construct('manageqtypes', get_string('manageqtypes', 'admin'), "$CFG->wwwroot/$CFG->admin/qtypes.php"); 05132 } 05133 05140 public function search($query) { 05141 global $CFG; 05142 if ($result = parent::search($query)) { 05143 return $result; 05144 } 05145 05146 $found = false; 05147 $textlib = textlib_get_instance(); 05148 require_once($CFG->dirroot . '/question/engine/bank.php'); 05149 foreach (question_bank::get_all_qtypes() as $qtype) { 05150 if (strpos($textlib->strtolower($qtype->local_name()), $query) !== false) { 05151 $found = true; 05152 break; 05153 } 05154 } 05155 if ($found) { 05156 $result = new stdClass(); 05157 $result->page = $this; 05158 $result->settings = array(); 05159 return array($this->name => $result); 05160 } else { 05161 return array(); 05162 } 05163 } 05164 } 05165 05166 05167 class admin_page_manageportfolios extends admin_externalpage { 05171 public function __construct() { 05172 global $CFG; 05173 parent::__construct('manageportfolios', get_string('manageportfolios', 'portfolio'), 05174 "$CFG->wwwroot/$CFG->admin/portfolio.php"); 05175 } 05176 05182 public function search($query) { 05183 global $CFG; 05184 if ($result = parent::search($query)) { 05185 return $result; 05186 } 05187 05188 $found = false; 05189 $textlib = textlib_get_instance(); 05190 $portfolios = get_plugin_list('portfolio'); 05191 foreach ($portfolios as $p => $dir) { 05192 if (strpos($p, $query) !== false) { 05193 $found = true; 05194 break; 05195 } 05196 } 05197 if (!$found) { 05198 foreach (portfolio_instances(false, false) as $instance) { 05199 $title = $instance->get('name'); 05200 if (strpos($textlib->strtolower($title), $query) !== false) { 05201 $found = true; 05202 break; 05203 } 05204 } 05205 } 05206 05207 if ($found) { 05208 $result = new stdClass(); 05209 $result->page = $this; 05210 $result->settings = array(); 05211 return array($this->name => $result); 05212 } else { 05213 return array(); 05214 } 05215 } 05216 } 05217 05218 05219 class admin_page_managerepositories extends admin_externalpage { 05223 public function __construct() { 05224 global $CFG; 05225 parent::__construct('managerepositories', get_string('manage', 05226 'repository'), "$CFG->wwwroot/$CFG->admin/repository.php"); 05227 } 05228 05234 public function search($query) { 05235 global $CFG; 05236 if ($result = parent::search($query)) { 05237 return $result; 05238 } 05239 05240 $found = false; 05241 $textlib = textlib_get_instance(); 05242 $repositories= get_plugin_list('repository'); 05243 foreach ($repositories as $p => $dir) { 05244 if (strpos($p, $query) !== false) { 05245 $found = true; 05246 break; 05247 } 05248 } 05249 if (!$found) { 05250 foreach (repository::get_types() as $instance) { 05251 $title = $instance->get_typename(); 05252 if (strpos($textlib->strtolower($title), $query) !== false) { 05253 $found = true; 05254 break; 05255 } 05256 } 05257 } 05258 05259 if ($found) { 05260 $result = new stdClass(); 05261 $result->page = $this; 05262 $result->settings = array(); 05263 return array($this->name => $result); 05264 } else { 05265 return array(); 05266 } 05267 } 05268 } 05269 05270 05276 class admin_setting_manageauths extends admin_setting { 05280 public function __construct() { 05281 $this->nosave = true; 05282 parent::__construct('authsui', get_string('authsettings', 'admin'), '', ''); 05283 } 05284 05290 public function get_setting() { 05291 return true; 05292 } 05293 05299 public function get_defaultsetting() { 05300 return true; 05301 } 05302 05308 public function write_setting($data) { 05309 // do not write any setting 05310 return ''; 05311 } 05312 05319 public function is_related($query) { 05320 if (parent::is_related($query)) { 05321 return true; 05322 } 05323 05324 $textlib = textlib_get_instance(); 05325 $authsavailable = get_plugin_list('auth'); 05326 foreach ($authsavailable as $auth => $dir) { 05327 if (strpos($auth, $query) !== false) { 05328 return true; 05329 } 05330 $authplugin = get_auth_plugin($auth); 05331 $authtitle = $authplugin->get_title(); 05332 if (strpos($textlib->strtolower($authtitle), $query) !== false) { 05333 return true; 05334 } 05335 } 05336 return false; 05337 } 05338 05346 public function output_html($data, $query='') { 05347 global $CFG, $OUTPUT; 05348 05349 05350 // display strings 05351 $txt = get_strings(array('authenticationplugins', 'users', 'administration', 05352 'settings', 'edit', 'name', 'enable', 'disable', 05353 'up', 'down', 'none')); 05354 $txt->updown = "$txt->up/$txt->down"; 05355 05356 $authsavailable = get_plugin_list('auth'); 05357 get_enabled_auth_plugins(true); // fix the list of enabled auths 05358 if (empty($CFG->auth)) { 05359 $authsenabled = array(); 05360 } else { 05361 $authsenabled = explode(',', $CFG->auth); 05362 } 05363 05364 // construct the display array, with enabled auth plugins at the top, in order 05365 $displayauths = array(); 05366 $registrationauths = array(); 05367 $registrationauths[''] = $txt->disable; 05368 foreach ($authsenabled as $auth) { 05369 $authplugin = get_auth_plugin($auth); 05371 $authtitle = $authplugin->get_title(); 05373 $displayauths[$auth] = $authtitle; 05374 if ($authplugin->can_signup()) { 05375 $registrationauths[$auth] = $authtitle; 05376 } 05377 } 05378 05379 foreach ($authsavailable as $auth => $dir) { 05380 if (array_key_exists($auth, $displayauths)) { 05381 continue; //already in the list 05382 } 05383 $authplugin = get_auth_plugin($auth); 05385 $authtitle = $authplugin->get_title(); 05387 $displayauths[$auth] = $authtitle; 05388 if ($authplugin->can_signup()) { 05389 $registrationauths[$auth] = $authtitle; 05390 } 05391 } 05392 05393 $return = $OUTPUT->heading(get_string('actauthhdr', 'auth'), 3, 'main'); 05394 $return .= $OUTPUT->box_start('generalbox authsui'); 05395 05396 $table = new html_table(); 05397 $table->head = array($txt->name, $txt->enable, $txt->updown, $txt->settings); 05398 $table->align = array('left', 'center', 'center', 'center'); 05399 $table->data = array(); 05400 $table->attributes['class'] = 'manageauthtable generaltable'; 05401 05402 //add always enabled plugins first 05403 $displayname = "<span>".$displayauths['manual']."</span>"; 05404 $settings = "<a href=\"auth_config.php?auth=manual\">{$txt->settings}</a>"; 05405 //$settings = "<a href=\"settings.php?section=authsettingmanual\">{$txt->settings}</a>"; 05406 $table->data[] = array($displayname, '', '', $settings); 05407 $displayname = "<span>".$displayauths['nologin']."</span>"; 05408 $settings = "<a href=\"auth_config.php?auth=nologin\">{$txt->settings}</a>"; 05409 $table->data[] = array($displayname, '', '', $settings); 05410 05411 05412 // iterate through auth plugins and add to the display table 05413 $updowncount = 1; 05414 $authcount = count($authsenabled); 05415 $url = "auth.php?sesskey=" . sesskey(); 05416 foreach ($displayauths as $auth => $name) { 05417 if ($auth == 'manual' or $auth == 'nologin') { 05418 continue; 05419 } 05420 // hide/show link 05421 if (in_array($auth, $authsenabled)) { 05422 $hideshow = "<a href=\"$url&action=disable&auth=$auth\">"; 05423 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/hide') . "\" class=\"icon\" alt=\"disable\" /></a>"; 05424 // $hideshow = "<a href=\"$url&action=disable&auth=$auth\"><input type=\"checkbox\" checked /></a>"; 05425 $enabled = true; 05426 $displayname = "<span>$name</span>"; 05427 } 05428 else { 05429 $hideshow = "<a href=\"$url&action=enable&auth=$auth\">"; 05430 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/show') . "\" class=\"icon\" alt=\"enable\" /></a>"; 05431 // $hideshow = "<a href=\"$url&action=enable&auth=$auth\"><input type=\"checkbox\" /></a>"; 05432 $enabled = false; 05433 $displayname = "<span class=\"dimmed_text\">$name</span>"; 05434 } 05435 05436 // up/down link (only if auth is enabled) 05437 $updown = ''; 05438 if ($enabled) { 05439 if ($updowncount > 1) { 05440 $updown .= "<a href=\"$url&action=up&auth=$auth\">"; 05441 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"up\" /></a> "; 05442 } 05443 else { 05444 $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" /> "; 05445 } 05446 if ($updowncount < $authcount) { 05447 $updown .= "<a href=\"$url&action=down&auth=$auth\">"; 05448 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/down') . "\" alt=\"down\" /></a>"; 05449 } 05450 else { 05451 $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" />"; 05452 } 05453 ++ $updowncount; 05454 } 05455 05456 // settings link 05457 if (file_exists($CFG->dirroot.'/auth/'.$auth.'/settings.php')) { 05458 $settings = "<a href=\"settings.php?section=authsetting$auth\">{$txt->settings}</a>"; 05459 } else { 05460 $settings = "<a href=\"auth_config.php?auth=$auth\">{$txt->settings}</a>"; 05461 } 05462 05463 // add a row to the table 05464 $table->data[] =array($displayname, $hideshow, $updown, $settings); 05465 } 05466 $return .= html_writer::table($table); 05467 $return .= get_string('configauthenticationplugins', 'admin').'<br />'.get_string('tablenosave', 'filters'); 05468 $return .= $OUTPUT->box_end(); 05469 return highlight($query, $return); 05470 } 05471 } 05472 05473 05479 class admin_setting_manageeditors extends admin_setting { 05483 public function __construct() { 05484 $this->nosave = true; 05485 parent::__construct('editorsui', get_string('editorsettings', 'editor'), '', ''); 05486 } 05487 05493 public function get_setting() { 05494 return true; 05495 } 05496 05502 public function get_defaultsetting() { 05503 return true; 05504 } 05505 05511 public function write_setting($data) { 05512 // do not write any setting 05513 return ''; 05514 } 05515 05522 public function is_related($query) { 05523 if (parent::is_related($query)) { 05524 return true; 05525 } 05526 05527 $textlib = textlib_get_instance(); 05528 $editors_available = editors_get_available(); 05529 foreach ($editors_available as $editor=>$editorstr) { 05530 if (strpos($editor, $query) !== false) { 05531 return true; 05532 } 05533 if (strpos($textlib->strtolower($editorstr), $query) !== false) { 05534 return true; 05535 } 05536 } 05537 return false; 05538 } 05539 05547 public function output_html($data, $query='') { 05548 global $CFG, $OUTPUT; 05549 05550 // display strings 05551 $txt = get_strings(array('administration', 'settings', 'edit', 'name', 'enable', 'disable', 05552 'up', 'down', 'none')); 05553 $txt->updown = "$txt->up/$txt->down"; 05554 05555 $editors_available = editors_get_available(); 05556 $active_editors = explode(',', $CFG->texteditors); 05557 05558 $active_editors = array_reverse($active_editors); 05559 foreach ($active_editors as $key=>$editor) { 05560 if (empty($editors_available[$editor])) { 05561 unset($active_editors[$key]); 05562 } else { 05563 $name = $editors_available[$editor]; 05564 unset($editors_available[$editor]); 05565 $editors_available[$editor] = $name; 05566 } 05567 } 05568 if (empty($active_editors)) { 05569 //$active_editors = array('textarea'); 05570 } 05571 $editors_available = array_reverse($editors_available, true); 05572 $return = $OUTPUT->heading(get_string('acteditorshhdr', 'editor'), 3, 'main', true); 05573 $return .= $OUTPUT->box_start('generalbox editorsui'); 05574 05575 $table = new html_table(); 05576 $table->head = array($txt->name, $txt->enable, $txt->updown, $txt->settings); 05577 $table->align = array('left', 'center', 'center', 'center'); 05578 $table->width = '90%'; 05579 $table->data = array(); 05580 05581 // iterate through auth plugins and add to the display table 05582 $updowncount = 1; 05583 $editorcount = count($active_editors); 05584 $url = "editors.php?sesskey=" . sesskey(); 05585 foreach ($editors_available as $editor => $name) { 05586 // hide/show link 05587 if (in_array($editor, $active_editors)) { 05588 $hideshow = "<a href=\"$url&action=disable&editor=$editor\">"; 05589 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/hide') . "\" class=\"icon\" alt=\"disable\" /></a>"; 05590 // $hideshow = "<a href=\"$url&action=disable&editor=$editor\"><input type=\"checkbox\" checked /></a>"; 05591 $enabled = true; 05592 $displayname = "<span>$name</span>"; 05593 } 05594 else { 05595 $hideshow = "<a href=\"$url&action=enable&editor=$editor\">"; 05596 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/show') . "\" class=\"icon\" alt=\"enable\" /></a>"; 05597 // $hideshow = "<a href=\"$url&action=enable&editor=$editor\"><input type=\"checkbox\" /></a>"; 05598 $enabled = false; 05599 $displayname = "<span class=\"dimmed_text\">$name</span>"; 05600 } 05601 05602 // up/down link (only if auth is enabled) 05603 $updown = ''; 05604 if ($enabled) { 05605 if ($updowncount > 1) { 05606 $updown .= "<a href=\"$url&action=up&editor=$editor\">"; 05607 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"up\" /></a> "; 05608 } 05609 else { 05610 $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" /> "; 05611 } 05612 if ($updowncount < $editorcount) { 05613 $updown .= "<a href=\"$url&action=down&editor=$editor\">"; 05614 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/down') . "\" alt=\"down\" /></a>"; 05615 } 05616 else { 05617 $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" />"; 05618 } 05619 ++ $updowncount; 05620 } 05621 05622 // settings link 05623 if (file_exists($CFG->dirroot.'/lib/editor/'.$editor.'/settings.php')) { 05624 $eurl = new moodle_url('/admin/settings.php', array('section'=>'editorsettings'.$editor)); 05625 $settings = "<a href='$eurl'>{$txt->settings}</a>"; 05626 } else { 05627 $settings = ''; 05628 } 05629 05630 // add a row to the table 05631 $table->data[] =array($displayname, $hideshow, $updown, $settings); 05632 } 05633 $return .= html_writer::table($table); 05634 $return .= get_string('configeditorplugins', 'editor').'<br />'.get_string('tablenosave', 'admin'); 05635 $return .= $OUTPUT->box_end(); 05636 return highlight($query, $return); 05637 } 05638 } 05639 05640 05646 class admin_setting_managelicenses extends admin_setting { 05650 public function __construct() { 05651 $this->nosave = true; 05652 parent::__construct('licensesui', get_string('licensesettings', 'admin'), '', ''); 05653 } 05654 05660 public function get_setting() { 05661 return true; 05662 } 05663 05669 public function get_defaultsetting() { 05670 return true; 05671 } 05672 05678 public function write_setting($data) { 05679 // do not write any setting 05680 return ''; 05681 } 05682 05690 public function output_html($data, $query='') { 05691 global $CFG, $OUTPUT; 05692 require_once($CFG->libdir . '/licenselib.php'); 05693 $url = "licenses.php?sesskey=" . sesskey(); 05694 05695 // display strings 05696 $txt = get_strings(array('administration', 'settings', 'name', 'enable', 'disable', 'none')); 05697 $licenses = license_manager::get_licenses(); 05698 05699 $return = $OUTPUT->heading(get_string('availablelicenses', 'admin'), 3, 'main', true); 05700 05701 $return .= $OUTPUT->box_start('generalbox editorsui'); 05702 05703 $table = new html_table(); 05704 $table->head = array($txt->name, $txt->enable); 05705 $table->align = array('left', 'center'); 05706 $table->width = '100%'; 05707 $table->data = array(); 05708 05709 foreach ($licenses as $value) { 05710 $displayname = html_writer::link($value->source, get_string($value->shortname, 'license'), array('target'=>'_blank')); 05711 05712 if ($value->enabled == 1) { 05713 $hideshow = html_writer::link($url.'&action=disable&license='.$value->shortname, 05714 html_writer::tag('img', '', array('src'=>$OUTPUT->pix_url('i/hide'), 'class'=>'icon', 'alt'=>'disable'))); 05715 } else { 05716 $hideshow = html_writer::link($url.'&action=enable&license='.$value->shortname, 05717 html_writer::tag('img', '', array('src'=>$OUTPUT->pix_url('i/show'), 'class'=>'icon', 'alt'=>'enable'))); 05718 } 05719 05720 if ($value->shortname == $CFG->sitedefaultlicense) { 05721 $displayname .= ' '.html_writer::tag('img', '', array('src'=>$OUTPUT->pix_url('i/lock'), 'class'=>'icon', 'alt'=>get_string('default'), 'title'=>get_string('default'))); 05722 $hideshow = ''; 05723 } 05724 05725 $enabled = true; 05726 05727 $table->data[] =array($displayname, $hideshow); 05728 } 05729 $return .= html_writer::table($table); 05730 $return .= $OUTPUT->box_end(); 05731 return highlight($query, $return); 05732 } 05733 } 05734 05735 05741 class admin_page_managefilters extends admin_externalpage { 05745 public function __construct() { 05746 global $CFG; 05747 parent::__construct('managefilters', get_string('filtersettings', 'admin'), "$CFG->wwwroot/$CFG->admin/filters.php"); 05748 } 05749 05756 public function search($query) { 05757 global $CFG; 05758 if ($result = parent::search($query)) { 05759 return $result; 05760 } 05761 05762 $found = false; 05763 $filternames = filter_get_all_installed(); 05764 $textlib = textlib_get_instance(); 05765 foreach ($filternames as $path => $strfiltername) { 05766 if (strpos($textlib->strtolower($strfiltername), $query) !== false) { 05767 $found = true; 05768 break; 05769 } 05770 list($type, $filter) = explode('/', $path); 05771 if (strpos($filter, $query) !== false) { 05772 $found = true; 05773 break; 05774 } 05775 } 05776 05777 if ($found) { 05778 $result = new stdClass; 05779 $result->page = $this; 05780 $result->settings = array(); 05781 return array($this->name => $result); 05782 } else { 05783 return array(); 05784 } 05785 } 05786 } 05787 05788 05806 function admin_externalpage_setup($section, $extrabutton = '', array $extraurlparams = null, $actualurl = '', array $options = array()) { 05807 global $CFG, $PAGE, $USER, $SITE, $OUTPUT; 05808 05809 $PAGE->set_context(null); // hack - set context to something, by default to system context 05810 05811 $site = get_site(); 05812 require_login(); 05813 05814 $adminroot = admin_get_root(false, false); // settings not required for external pages 05815 $extpage = $adminroot->locate($section, true); 05816 05817 if (empty($extpage) or !($extpage instanceof admin_externalpage)) { 05818 print_error('sectionerror', 'admin', "$CFG->wwwroot/$CFG->admin/"); 05819 die; 05820 } 05821 05822 // this eliminates our need to authenticate on the actual pages 05823 if (!$extpage->check_access()) { 05824 print_error('accessdenied', 'admin'); 05825 die; 05826 } 05827 05828 if (!empty($options['pagelayout'])) { 05829 // A specific page layout has been requested. 05830 $PAGE->set_pagelayout($options['pagelayout']); 05831 } else if ($section === 'upgradesettings') { 05832 $PAGE->set_pagelayout('maintenance'); 05833 } else { 05834 $PAGE->set_pagelayout('admin'); 05835 } 05836 05837 // $PAGE->set_extra_button($extrabutton); TODO 05838 05839 if (!$actualurl) { 05840 $actualurl = $extpage->url; 05841 } 05842 05843 $PAGE->set_url($actualurl, $extraurlparams); 05844 if (strpos($PAGE->pagetype, 'admin-') !== 0) { 05845 $PAGE->set_pagetype('admin-' . $PAGE->pagetype); 05846 } 05847 05848 if (empty($SITE->fullname) || empty($SITE->shortname)) { 05849 // During initial install. 05850 $strinstallation = get_string('installation', 'install'); 05851 $strsettings = get_string('settings'); 05852 $PAGE->navbar->add($strsettings); 05853 $PAGE->set_title($strinstallation); 05854 $PAGE->set_heading($strinstallation); 05855 $PAGE->set_cacheable(false); 05856 return; 05857 } 05858 05859 // Locate the current item on the navigation and make it active when found. 05860 $path = $extpage->path; 05861 $node = $PAGE->settingsnav; 05862 while ($node && count($path) > 0) { 05863 $node = $node->get(array_pop($path)); 05864 } 05865 if ($node) { 05866 $node->make_active(); 05867 } 05868 05869 // Normal case. 05870 $adminediting = optional_param('adminedit', -1, PARAM_BOOL); 05871 if ($PAGE->user_allowed_editing() && $adminediting != -1) { 05872 $USER->editing = $adminediting; 05873 } 05874 05875 $visiblepathtosection = array_reverse($extpage->visiblepath); 05876 05877 if ($PAGE->user_allowed_editing()) { 05878 if ($PAGE->user_is_editing()) { 05879 $caption = get_string('blockseditoff'); 05880 $url = new moodle_url($PAGE->url, array('adminedit'=>'0')); 05881 } else { 05882 $caption = get_string('blocksediton'); 05883 $url = new moodle_url($PAGE->url, array('adminedit'=>'1')); 05884 } 05885 $PAGE->set_button($OUTPUT->single_button($url, $caption, 'get')); 05886 } 05887 05888 $PAGE->set_title("$SITE->shortname: " . implode(": ", $visiblepathtosection)); 05889 $PAGE->set_heading($SITE->fullname); 05890 05891 // prevent caching in nav block 05892 $PAGE->navigation->clear_cache(); 05893 } 05894 05900 function admin_get_root($reload=false, $requirefulltree=true) { 05901 global $CFG, $DB, $OUTPUT; 05902 05903 static $ADMIN = NULL; 05904 05905 if (is_null($ADMIN)) { 05906 // create the admin tree! 05907 $ADMIN = new admin_root($requirefulltree); 05908 } 05909 05910 if ($reload or ($requirefulltree and !$ADMIN->fulltree)) { 05911 $ADMIN->purge_children($requirefulltree); 05912 } 05913 05914 if (!$ADMIN->loaded) { 05915 // we process this file first to create categories first and in correct order 05916 require($CFG->dirroot.'/'.$CFG->admin.'/settings/top.php'); 05917 05918 // now we process all other files in admin/settings to build the admin tree 05919 foreach (glob($CFG->dirroot.'/'.$CFG->admin.'/settings/*.php') as $file) { 05920 if ($file == $CFG->dirroot.'/'.$CFG->admin.'/settings/top.php') { 05921 continue; 05922 } 05923 if ($file == $CFG->dirroot.'/'.$CFG->admin.'/settings/plugins.php') { 05924 // plugins are loaded last - they may insert pages anywhere 05925 continue; 05926 } 05927 require($file); 05928 } 05929 require($CFG->dirroot.'/'.$CFG->admin.'/settings/plugins.php'); 05930 05931 $ADMIN->loaded = true; 05932 } 05933 05934 return $ADMIN; 05935 } 05936 05938 05945 function admin_apply_default_settings($node=NULL, $unconditional=true) { 05946 global $CFG; 05947 05948 if (is_null($node)) { 05949 $node = admin_get_root(true, true); 05950 } 05951 05952 if ($node instanceof admin_category) { 05953 $entries = array_keys($node->children); 05954 foreach ($entries as $entry) { 05955 admin_apply_default_settings($node->children[$entry], $unconditional); 05956 } 05957 05958 } else if ($node instanceof admin_settingpage) { 05959 foreach ($node->settings as $setting) { 05960 if (!$unconditional and !is_null($setting->get_setting())) { 05961 //do not override existing defaults 05962 continue; 05963 } 05964 $defaultsetting = $setting->get_defaultsetting(); 05965 if (is_null($defaultsetting)) { 05966 // no value yet - default maybe applied after admin user creation or in upgradesettings 05967 continue; 05968 } 05969 $setting->write_setting($defaultsetting); 05970 } 05971 } 05972 } 05973 05980 function admin_write_settings($formdata) { 05981 global $CFG, $SITE, $DB; 05982 05983 $olddbsessions = !empty($CFG->dbsessions); 05984 $formdata = (array)$formdata; 05985 05986 $data = array(); 05987 foreach ($formdata as $fullname=>$value) { 05988 if (strpos($fullname, 's_') !== 0) { 05989 continue; // not a config value 05990 } 05991 $data[$fullname] = $value; 05992 } 05993 05994 $adminroot = admin_get_root(); 05995 $settings = admin_find_write_settings($adminroot, $data); 05996 05997 $count = 0; 05998 foreach ($settings as $fullname=>$setting) { 05999 $original = serialize($setting->get_setting()); // comparison must work for arrays too 06000 $error = $setting->write_setting($data[$fullname]); 06001 if ($error !== '') { 06002 $adminroot->errors[$fullname] = new stdClass(); 06003 $adminroot->errors[$fullname]->data = $data[$fullname]; 06004 $adminroot->errors[$fullname]->id = $setting->get_id(); 06005 $adminroot->errors[$fullname]->error = $error; 06006 } 06007 if ($original !== serialize($setting->get_setting())) { 06008 $count++; 06009 $callbackfunction = $setting->updatedcallback; 06010 if (function_exists($callbackfunction)) { 06011 $callbackfunction($fullname); 06012 } 06013 } 06014 } 06015 06016 if ($olddbsessions != !empty($CFG->dbsessions)) { 06017 require_logout(); 06018 } 06019 06020 // Now update $SITE - just update the fields, in case other people have a 06021 // a reference to it (e.g. $PAGE, $COURSE). 06022 $newsite = $DB->get_record('course', array('id'=>$SITE->id)); 06023 foreach (get_object_vars($newsite) as $field => $value) { 06024 $SITE->$field = $value; 06025 } 06026 06027 // now reload all settings - some of them might depend on the changed 06028 admin_get_root(true); 06029 return $count; 06030 } 06031 06039 function admin_find_write_settings($node, $data) { 06040 $return = array(); 06041 06042 if (empty($data)) { 06043 return $return; 06044 } 06045 06046 if ($node instanceof admin_category) { 06047 $entries = array_keys($node->children); 06048 foreach ($entries as $entry) { 06049 $return = array_merge($return, admin_find_write_settings($node->children[$entry], $data)); 06050 } 06051 06052 } else if ($node instanceof admin_settingpage) { 06053 foreach ($node->settings as $setting) { 06054 $fullname = $setting->get_full_name(); 06055 if (array_key_exists($fullname, $data)) { 06056 $return[$fullname] = $setting; 06057 } 06058 } 06059 06060 } 06061 06062 return $return; 06063 } 06064 06071 function admin_search_settings_html($query) { 06072 global $CFG, $OUTPUT; 06073 06074 $textlib = textlib_get_instance(); 06075 if ($textlib->strlen($query) < 2) { 06076 return ''; 06077 } 06078 $query = $textlib->strtolower($query); 06079 06080 $adminroot = admin_get_root(); 06081 $findings = $adminroot->search($query); 06082 $return = ''; 06083 $savebutton = false; 06084 06085 foreach ($findings as $found) { 06086 $page = $found->page; 06087 $settings = $found->settings; 06088 if ($page->is_hidden()) { 06089 // hidden pages are not displayed in search results 06090 continue; 06091 } 06092 if ($page instanceof admin_externalpage) { 06093 $return .= $OUTPUT->heading(get_string('searchresults','admin').' - <a href="'.$page->url.'">'.highlight($query, $page->visiblename).'</a>', 2, 'main'); 06094 } else if ($page instanceof admin_settingpage) { 06095 $return .= $OUTPUT->heading(get_string('searchresults','admin').' - <a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section='.$page->name.'">'.highlight($query, $page->visiblename).'</a>', 2, 'main'); 06096 } else { 06097 continue; 06098 } 06099 if (!empty($settings)) { 06100 $return .= '<fieldset class="adminsettings">'."\n"; 06101 foreach ($settings as $setting) { 06102 if (empty($setting->nosave)) { 06103 $savebutton = true; 06104 } 06105 $return .= '<div class="clearer"><!-- --></div>'."\n"; 06106 $fullname = $setting->get_full_name(); 06107 if (array_key_exists($fullname, $adminroot->errors)) { 06108 $data = $adminroot->errors[$fullname]->data; 06109 } else { 06110 $data = $setting->get_setting(); 06111 // do not use defaults if settings not available - upgradesettings handles the defaults! 06112 } 06113 $return .= $setting->output_html($data, $query); 06114 } 06115 $return .= '</fieldset>'; 06116 } 06117 } 06118 06119 if ($savebutton) { 06120 $return .= '<div class="form-buttons"><input class="form-submit" type="submit" value="'.get_string('savechanges','admin').'" /></div>'; 06121 } 06122 06123 return $return; 06124 } 06125 06132 function admin_output_new_settings_by_page($node) { 06133 global $OUTPUT; 06134 $return = array(); 06135 06136 if ($node instanceof admin_category) { 06137 $entries = array_keys($node->children); 06138 foreach ($entries as $entry) { 06139 $return += admin_output_new_settings_by_page($node->children[$entry]); 06140 } 06141 06142 } else if ($node instanceof admin_settingpage) { 06143 $newsettings = array(); 06144 foreach ($node->settings as $setting) { 06145 if (is_null($setting->get_setting())) { 06146 $newsettings[] = $setting; 06147 } 06148 } 06149 if (count($newsettings) > 0) { 06150 $adminroot = admin_get_root(); 06151 $page = $OUTPUT->heading(get_string('upgradesettings','admin').' - '.$node->visiblename, 2, 'main'); 06152 $page .= '<fieldset class="adminsettings">'."\n"; 06153 foreach ($newsettings as $setting) { 06154 $fullname = $setting->get_full_name(); 06155 if (array_key_exists($fullname, $adminroot->errors)) { 06156 $data = $adminroot->errors[$fullname]->data; 06157 } else { 06158 $data = $setting->get_setting(); 06159 if (is_null($data)) { 06160 $data = $setting->get_defaultsetting(); 06161 } 06162 } 06163 $page .= '<div class="clearer"><!-- --></div>'."\n"; 06164 $page .= $setting->output_html($data); 06165 } 06166 $page .= '</fieldset>'; 06167 $return[$node->name] = $page; 06168 } 06169 } 06170 06171 return $return; 06172 } 06173 06187 function format_admin_setting($setting, $title='', $form='', $description='', $label=true, $warning='', $defaultinfo=NULL, $query='') { 06188 global $CFG; 06189 06190 $name = empty($setting->plugin) ? $setting->name : "$setting->plugin | $setting->name"; 06191 $fullname = $setting->get_full_name(); 06192 06193 // sometimes the id is not id_s_name, but id_s_name_m or something, and this does not validate 06194 if ($label) { 06195 $labelfor = 'for = "'.$setting->get_id().'"'; 06196 } else { 06197 $labelfor = ''; 06198 } 06199 06200 $override = ''; 06201 if (empty($setting->plugin)) { 06202 if (array_key_exists($setting->name, $CFG->config_php_settings)) { 06203 $override = '<div class="form-overridden">'.get_string('configoverride', 'admin').'</div>'; 06204 } 06205 } else { 06206 if (array_key_exists($setting->plugin, $CFG->forced_plugin_settings) and array_key_exists($setting->name, $CFG->forced_plugin_settings[$setting->plugin])) { 06207 $override = '<div class="form-overridden">'.get_string('configoverride', 'admin').'</div>'; 06208 } 06209 } 06210 06211 if ($warning !== '') { 06212 $warning = '<div class="form-warning">'.$warning.'</div>'; 06213 } 06214 06215 if (is_null($defaultinfo)) { 06216 $defaultinfo = ''; 06217 } else { 06218 if ($defaultinfo === '') { 06219 $defaultinfo = get_string('emptysettingvalue', 'admin'); 06220 } 06221 $defaultinfo = highlight($query, nl2br(s($defaultinfo))); 06222 $defaultinfo = '<div class="form-defaultinfo">'.get_string('defaultsettinginfo', 'admin', $defaultinfo).'</div>'; 06223 } 06224 06225 06226 $str = ' 06227 <div class="form-item clearfix" id="admin-'.$setting->name.'"> 06228 <div class="form-label"> 06229 <label '.$labelfor.'>'.highlightfast($query, $title).'<span class="form-shortname">'.highlightfast($query, $name).'</span> 06230 '.$override.$warning.' 06231 </label> 06232 </div> 06233 <div class="form-setting">'.$form.$defaultinfo.'</div> 06234 <div class="form-description">'.highlight($query, markdown_to_html($description)).'</div> 06235 </div>'; 06236 06237 $adminroot = admin_get_root(); 06238 if (array_key_exists($fullname, $adminroot->errors)) { 06239 $str = '<fieldset class="error"><legend>'.$adminroot->errors[$fullname]->error.'</legend>'.$str.'</fieldset>'; 06240 } 06241 06242 return $str; 06243 } 06244 06252 function any_new_admin_settings($node) { 06253 06254 if ($node instanceof admin_category) { 06255 $entries = array_keys($node->children); 06256 foreach ($entries as $entry) { 06257 if (any_new_admin_settings($node->children[$entry])) { 06258 return true; 06259 } 06260 } 06261 06262 } else if ($node instanceof admin_settingpage) { 06263 foreach ($node->settings as $setting) { 06264 if ($setting->get_setting() === NULL) { 06265 return true; 06266 } 06267 } 06268 } 06269 06270 return false; 06271 } 06272 06280 function db_replace($search, $replace) { 06281 global $DB, $CFG, $OUTPUT; 06282 06283 // TODO: this is horrible hack, we should do whitelisting and each plugin should be responsible for proper replacing... 06284 $skiptables = array('config', 'config_plugins', 'config_log', 'upgrade_log', 06285 'filter_config', 'sessions', 'events_queue', 'repository_instance_config', 06286 'block_instances', ''); 06287 06288 // Turn off time limits, sometimes upgrades can be slow. 06289 @set_time_limit(0); 06290 06291 if (!$tables = $DB->get_tables() ) { // No tables yet at all. 06292 return false; 06293 } 06294 foreach ($tables as $table) { 06295 06296 if (in_array($table, $skiptables)) { // Don't process these 06297 continue; 06298 } 06299 06300 if ($columns = $DB->get_columns($table)) { 06301 $DB->set_debug(true); 06302 foreach ($columns as $column => $data) { 06303 if (in_array($data->meta_type, array('C', 'X'))) { // Text stuff only 06304 //TODO: this should be definitively moved to DML driver to do the actual replace, this is not going to work for MSSQL and Oracle... 06305 $DB->execute("UPDATE {".$table."} SET $column = REPLACE($column, ?, ?)", array($search, $replace)); 06306 } 06307 } 06308 $DB->set_debug(false); 06309 } 06310 } 06311 06312 // delete modinfo caches 06313 rebuild_course_cache(0, true); 06314 06315 // TODO: we should ask all plugins to do the search&replace, for now let's do only blocks... 06316 $blocks = get_plugin_list('block'); 06317 foreach ($blocks as $blockname=>$fullblock) { 06318 if ($blockname === 'NEWBLOCK') { // Someone has unzipped the template, ignore it 06319 continue; 06320 } 06321 06322 if (!is_readable($fullblock.'/lib.php')) { 06323 continue; 06324 } 06325 06326 $function = 'block_'.$blockname.'_global_db_replace'; 06327 include_once($fullblock.'/lib.php'); 06328 if (!function_exists($function)) { 06329 continue; 06330 } 06331 06332 echo $OUTPUT->notification("Replacing in $blockname blocks...", 'notifysuccess'); 06333 $function($search, $replace); 06334 echo $OUTPUT->notification("...finished", 'notifysuccess'); 06335 } 06336 06337 return true; 06338 } 06339 06345 class admin_setting_managerepository extends admin_setting { 06347 private $baseurl; 06348 06352 public function __construct() { 06353 global $CFG; 06354 parent::__construct('managerepository', get_string('manage', 'repository'), '', ''); 06355 $this->baseurl = $CFG->wwwroot . '/' . $CFG->admin . '/repository.php?sesskey=' . sesskey(); 06356 } 06357 06363 public function get_setting() { 06364 return true; 06365 } 06366 06372 public function get_defaultsetting() { 06373 return true; 06374 } 06375 06381 public function get_full_name() { 06382 return 's_managerepository'; 06383 } 06384 06388 public function write_setting($data) { 06389 $url = $this->baseurl . '&new=' . $data; 06390 return ''; 06391 // TODO 06392 // Should not use redirect and exit here 06393 // Find a better way to do this. 06394 // redirect($url); 06395 // exit; 06396 } 06397 06404 public function is_related($query) { 06405 if (parent::is_related($query)) { 06406 return true; 06407 } 06408 06409 $textlib = textlib_get_instance(); 06410 $repositories= get_plugin_list('repository'); 06411 foreach ($repositories as $p => $dir) { 06412 if (strpos($p, $query) !== false) { 06413 return true; 06414 } 06415 } 06416 foreach (repository::get_types() as $instance) { 06417 $title = $instance->get_typename(); 06418 if (strpos($textlib->strtolower($title), $query) !== false) { 06419 return true; 06420 } 06421 } 06422 return false; 06423 } 06424 06430 function repository_action_url($repository) { 06431 return new moodle_url($this->baseurl, array('sesskey'=>sesskey(), 'repos'=>$repository)); 06432 } 06433 06441 public function output_html($data, $query='') { 06442 global $CFG, $USER, $OUTPUT; 06443 06444 // Get strings that are used 06445 $strshow = get_string('on', 'repository'); 06446 $strhide = get_string('off', 'repository'); 06447 $strdelete = get_string('disabled', 'repository'); 06448 06449 $actionchoicesforexisting = array( 06450 'show' => $strshow, 06451 'hide' => $strhide, 06452 'delete' => $strdelete 06453 ); 06454 06455 $actionchoicesfornew = array( 06456 'newon' => $strshow, 06457 'newoff' => $strhide, 06458 'delete' => $strdelete 06459 ); 06460 06461 $return = ''; 06462 $return .= $OUTPUT->box_start('generalbox'); 06463 06464 // Set strings that are used multiple times 06465 $settingsstr = get_string('settings'); 06466 $disablestr = get_string('disable'); 06467 06468 // Table to list plug-ins 06469 $table = new html_table(); 06470 $table->head = array(get_string('name'), get_string('isactive', 'repository'), get_string('order'), $settingsstr); 06471 $table->align = array('left', 'center', 'center', 'center', 'center'); 06472 $table->data = array(); 06473 06474 // Get list of used plug-ins 06475 $instances = repository::get_types(); 06476 if (!empty($instances)) { 06477 // Array to store plugins being used 06478 $alreadyplugins = array(); 06479 $totalinstances = count($instances); 06480 $updowncount = 1; 06481 foreach ($instances as $i) { 06482 $settings = ''; 06483 $typename = $i->get_typename(); 06484 // Display edit link only if you can config the type or if it has multiple instances (e.g. has instance config) 06485 $typeoptionnames = repository::static_function($typename, 'get_type_option_names'); 06486 $instanceoptionnames = repository::static_function($typename, 'get_instance_option_names'); 06487 06488 if (!empty($typeoptionnames) || !empty($instanceoptionnames)) { 06489 // Calculate number of instances in order to display them for the Moodle administrator 06490 if (!empty($instanceoptionnames)) { 06491 $params = array(); 06492 $params['context'] = array(get_system_context()); 06493 $params['onlyvisible'] = false; 06494 $params['type'] = $typename; 06495 $admininstancenumber = count(repository::static_function($typename, 'get_instances', $params)); 06496 // site instances 06497 $admininstancenumbertext = get_string('instancesforsite', 'repository', $admininstancenumber); 06498 $params['context'] = array(); 06499 $instances = repository::static_function($typename, 'get_instances', $params); 06500 $courseinstances = array(); 06501 $userinstances = array(); 06502 06503 foreach ($instances as $instance) { 06504 if ($instance->context->contextlevel == CONTEXT_COURSE) { 06505 $courseinstances[] = $instance; 06506 } else if ($instance->context->contextlevel == CONTEXT_USER) { 06507 $userinstances[] = $instance; 06508 } 06509 } 06510 // course instances 06511 $instancenumber = count($courseinstances); 06512 $courseinstancenumbertext = get_string('instancesforcourses', 'repository', $instancenumber); 06513 06514 // user private instances 06515 $instancenumber = count($userinstances); 06516 $userinstancenumbertext = get_string('instancesforusers', 'repository', $instancenumber); 06517 } else { 06518 $admininstancenumbertext = ""; 06519 $courseinstancenumbertext = ""; 06520 $userinstancenumbertext = ""; 06521 } 06522 06523 $settings .= '<a href="' . $this->baseurl . '&action=edit&repos=' . $typename . '">' . $settingsstr .'</a>'; 06524 06525 $settings .= $OUTPUT->container_start('mdl-left'); 06526 $settings .= '<br/>'; 06527 $settings .= $admininstancenumbertext; 06528 $settings .= '<br/>'; 06529 $settings .= $courseinstancenumbertext; 06530 $settings .= '<br/>'; 06531 $settings .= $userinstancenumbertext; 06532 $settings .= $OUTPUT->container_end(); 06533 } 06534 // Get the current visibility 06535 if ($i->get_visible()) { 06536 $currentaction = 'show'; 06537 } else { 06538 $currentaction = 'hide'; 06539 } 06540 06541 $select = new single_select($this->repository_action_url($typename, 'repos'), 'action', $actionchoicesforexisting, $currentaction, null, 'applyto' . basename($typename)); 06542 06543 // Display up/down link 06544 $updown = ''; 06545 $spacer = $OUTPUT->spacer(array('height'=>15, 'width'=>15)); // should be done with CSS instead 06546 06547 if ($updowncount > 1) { 06548 $updown .= "<a href=\"$this->baseurl&action=moveup&repos=".$typename."\">"; 06549 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"up\" /></a> "; 06550 } 06551 else { 06552 $updown .= $spacer; 06553 } 06554 if ($updowncount < $totalinstances) { 06555 $updown .= "<a href=\"$this->baseurl&action=movedown&repos=".$typename."\">"; 06556 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/down') . "\" alt=\"down\" /></a>"; 06557 } 06558 else { 06559 $updown .= $spacer; 06560 } 06561 06562 $updowncount++; 06563 06564 $table->data[] = array($i->get_readablename(), $OUTPUT->render($select), $updown, $settings); 06565 06566 if (!in_array($typename, $alreadyplugins)) { 06567 $alreadyplugins[] = $typename; 06568 } 06569 } 06570 } 06571 06572 // Get all the plugins that exist on disk 06573 $plugins = get_plugin_list('repository'); 06574 if (!empty($plugins)) { 06575 foreach ($plugins as $plugin => $dir) { 06576 // Check that it has not already been listed 06577 if (!in_array($plugin, $alreadyplugins)) { 06578 $select = new single_select($this->repository_action_url($plugin, 'repos'), 'action', $actionchoicesfornew, 'delete', null, 'applyto' . basename($plugin)); 06579 $table->data[] = array(get_string('pluginname', 'repository_'.$plugin), $OUTPUT->render($select), '', ''); 06580 } 06581 } 06582 } 06583 06584 $return .= html_writer::table($table); 06585 $return .= $OUTPUT->box_end(); 06586 return highlight($query, $return); 06587 } 06588 } 06589 06595 class admin_setting_enablemobileservice extends admin_setting_configcheckbox { 06596 06597 private $xmlrpcuse; //boolean: true => capability 'webservice/xmlrpc:use' is set for authenticated user role 06598 06603 private function is_xmlrpc_cap_allowed() { 06604 global $DB, $CFG; 06605 06606 //if the $this->xmlrpcuse variable is not set, it needs to be set 06607 if (empty($this->xmlrpcuse) and $this->xmlrpcuse!==false) { 06608 $params = array(); 06609 $params['permission'] = CAP_ALLOW; 06610 $params['roleid'] = $CFG->defaultuserroleid; 06611 $params['capability'] = 'webservice/xmlrpc:use'; 06612 $this->xmlrpcuse = $DB->record_exists('role_capabilities', $params); 06613 } 06614 06615 return $this->xmlrpcuse; 06616 } 06617 06622 private function set_xmlrpc_cap($status) { 06623 global $CFG; 06624 if ($status and !$this->is_xmlrpc_cap_allowed()) { 06625 //need to allow the cap 06626 $permission = CAP_ALLOW; 06627 $assign = true; 06628 } else if (!$status and $this->is_xmlrpc_cap_allowed()){ 06629 //need to disallow the cap 06630 $permission = CAP_INHERIT; 06631 $assign = true; 06632 } 06633 if (!empty($assign)) { 06634 $systemcontext = get_system_context(); 06635 assign_capability('webservice/xmlrpc:use', $permission, $CFG->defaultuserroleid, $systemcontext->id, true); 06636 } 06637 } 06638 06647 public function output_html($data, $query='') { 06648 global $CFG, $OUTPUT; 06649 $html = parent::output_html($data, $query); 06650 06651 if ((string)$data === $this->yes) { 06652 require_once($CFG->dirroot . "/lib/filelib.php"); 06653 $curl = new curl(); 06654 $httpswwwroot = str_replace('http:', 'https:', $CFG->wwwroot); //force https url 06655 $curl->head($httpswwwroot . "/login/index.php"); 06656 $info = $curl->get_info(); 06657 if (empty($info['http_code']) or ($info['http_code'] >= 400)) { 06658 $html .= $OUTPUT->notification(get_string('nohttpsformobilewarning', 'admin')); 06659 } 06660 } 06661 06662 return $html; 06663 } 06664 06670 public function get_setting() { 06671 global $CFG; 06672 06673 // For install cli script, $CFG->defaultuserroleid is not set so return 0 06674 // Or if web services aren't enabled this can't be, 06675 if (empty($CFG->defaultuserroleid) || empty($CFG->enablewebservices)) { 06676 return 0; 06677 } 06678 06679 require_once($CFG->dirroot . '/webservice/lib.php'); 06680 $webservicemanager = new webservice(); 06681 $mobileservice = $webservicemanager->get_external_service_by_shortname(MOODLE_OFFICIAL_MOBILE_SERVICE); 06682 if ($mobileservice->enabled and $this->is_xmlrpc_cap_allowed()) { 06683 return $this->config_read($this->name); //same as returning 1 06684 } else { 06685 return 0; 06686 } 06687 } 06688 06695 public function write_setting($data) { 06696 global $DB, $CFG; 06697 06698 //for install cli script, $CFG->defaultuserroleid is not set so do nothing 06699 if (empty($CFG->defaultuserroleid)) { 06700 return ''; 06701 } 06702 06703 $servicename = MOODLE_OFFICIAL_MOBILE_SERVICE; 06704 06705 require_once($CFG->dirroot . '/webservice/lib.php'); 06706 $webservicemanager = new webservice(); 06707 06708 if ((string)$data === $this->yes) { 06709 //code run when enable mobile web service 06710 //enable web service systeme if necessary 06711 set_config('enablewebservices', true); 06712 06713 //enable mobile service 06714 $mobileservice = $webservicemanager->get_external_service_by_shortname(MOODLE_OFFICIAL_MOBILE_SERVICE); 06715 $mobileservice->enabled = 1; 06716 $webservicemanager->update_external_service($mobileservice); 06717 06718 //enable xml-rpc server 06719 $activeprotocols = empty($CFG->webserviceprotocols) ? array() : explode(',', $CFG->webserviceprotocols); 06720 06721 if (!in_array('xmlrpc', $activeprotocols)) { 06722 $activeprotocols[] = 'xmlrpc'; 06723 set_config('webserviceprotocols', implode(',', $activeprotocols)); 06724 } 06725 06726 //allow xml-rpc:use capability for authenticated user 06727 $this->set_xmlrpc_cap(true); 06728 06729 } else { 06730 //disable web service system if no other services are enabled 06731 $otherenabledservices = $DB->get_records_select('external_services', 06732 'enabled = :enabled AND (shortname != :shortname OR shortname IS NULL)', array('enabled' => 1, 06733 'shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE)); 06734 if (empty($otherenabledservices)) { 06735 set_config('enablewebservices', false); 06736 06737 //also disable xml-rpc server 06738 $activeprotocols = empty($CFG->webserviceprotocols) ? array() : explode(',', $CFG->webserviceprotocols); 06739 $protocolkey = array_search('xmlrpc', $activeprotocols); 06740 if ($protocolkey !== false) { 06741 unset($activeprotocols[$protocolkey]); 06742 set_config('webserviceprotocols', implode(',', $activeprotocols)); 06743 } 06744 06745 //disallow xml-rpc:use capability for authenticated user 06746 $this->set_xmlrpc_cap(false); 06747 } 06748 06749 //disable the mobile service 06750 $mobileservice = $webservicemanager->get_external_service_by_shortname(MOODLE_OFFICIAL_MOBILE_SERVICE); 06751 $mobileservice->enabled = 0; 06752 $webservicemanager->update_external_service($mobileservice); 06753 } 06754 06755 return (parent::write_setting($data)); 06756 } 06757 } 06758 06764 class admin_setting_manageexternalservices extends admin_setting { 06768 public function __construct() { 06769 $this->nosave = true; 06770 parent::__construct('webservicesui', get_string('externalservices', 'webservice'), '', ''); 06771 } 06772 06778 public function get_setting() { 06779 return true; 06780 } 06781 06787 public function get_defaultsetting() { 06788 return true; 06789 } 06790 06796 public function write_setting($data) { 06797 // do not write any setting 06798 return ''; 06799 } 06800 06807 public function is_related($query) { 06808 global $DB; 06809 06810 if (parent::is_related($query)) { 06811 return true; 06812 } 06813 06814 $textlib = textlib_get_instance(); 06815 $services = $DB->get_records('external_services', array(), 'id, name'); 06816 foreach ($services as $service) { 06817 if (strpos($textlib->strtolower($service->name), $query) !== false) { 06818 return true; 06819 } 06820 } 06821 return false; 06822 } 06823 06831 public function output_html($data, $query='') { 06832 global $CFG, $OUTPUT, $DB; 06833 06834 // display strings 06835 $stradministration = get_string('administration'); 06836 $stredit = get_string('edit'); 06837 $strservice = get_string('externalservice', 'webservice'); 06838 $strdelete = get_string('delete'); 06839 $strplugin = get_string('plugin', 'admin'); 06840 $stradd = get_string('add'); 06841 $strfunctions = get_string('functions', 'webservice'); 06842 $strusers = get_string('users'); 06843 $strserviceusers = get_string('serviceusers', 'webservice'); 06844 06845 $esurl = "$CFG->wwwroot/$CFG->admin/webservice/service.php"; 06846 $efurl = "$CFG->wwwroot/$CFG->admin/webservice/service_functions.php"; 06847 $euurl = "$CFG->wwwroot/$CFG->admin/webservice/service_users.php"; 06848 06849 // built in services 06850 $services = $DB->get_records_select('external_services', 'component IS NOT NULL', null, 'name'); 06851 $return = ""; 06852 if (!empty($services)) { 06853 $return .= $OUTPUT->heading(get_string('servicesbuiltin', 'webservice'), 3, 'main'); 06854 06855 06856 06857 $table = new html_table(); 06858 $table->head = array($strservice, $strplugin, $strfunctions, $strusers, $stredit); 06859 $table->align = array('left', 'left', 'center', 'center', 'center'); 06860 $table->size = array('30%', '20%', '20%', '20%', '10%'); 06861 $table->width = '100%'; 06862 $table->data = array(); 06863 06864 // iterate through auth plugins and add to the display table 06865 foreach ($services as $service) { 06866 $name = $service->name; 06867 06868 // hide/show link 06869 if ($service->enabled) { 06870 $displayname = "<span>$name</span>"; 06871 } else { 06872 $displayname = "<span class=\"dimmed_text\">$name</span>"; 06873 } 06874 06875 $plugin = $service->component; 06876 06877 $functions = "<a href=\"$efurl?id=$service->id\">$strfunctions</a>"; 06878 06879 if ($service->restrictedusers) { 06880 $users = "<a href=\"$euurl?id=$service->id\">$strserviceusers</a>"; 06881 } else { 06882 $users = get_string('allusers', 'webservice'); 06883 } 06884 06885 $edit = "<a href=\"$esurl?id=$service->id\">$stredit</a>"; 06886 06887 // add a row to the table 06888 $table->data[] = array($displayname, $plugin, $functions, $users, $edit); 06889 } 06890 $return .= html_writer::table($table); 06891 } 06892 06893 // Custom services 06894 $return .= $OUTPUT->heading(get_string('servicescustom', 'webservice'), 3, 'main'); 06895 $services = $DB->get_records_select('external_services', 'component IS NULL', null, 'name'); 06896 06897 $table = new html_table(); 06898 $table->head = array($strservice, $strdelete, $strfunctions, $strusers, $stredit); 06899 $table->align = array('left', 'center', 'center', 'center', 'center'); 06900 $table->size = array('30%', '20%', '20%', '20%', '10%'); 06901 $table->width = '100%'; 06902 $table->data = array(); 06903 06904 // iterate through auth plugins and add to the display table 06905 foreach ($services as $service) { 06906 $name = $service->name; 06907 06908 // hide/show link 06909 if ($service->enabled) { 06910 $displayname = "<span>$name</span>"; 06911 } else { 06912 $displayname = "<span class=\"dimmed_text\">$name</span>"; 06913 } 06914 06915 // delete link 06916 $delete = "<a href=\"$esurl?action=delete&sesskey=".sesskey()."&id=$service->id\">$strdelete</a>"; 06917 06918 $functions = "<a href=\"$efurl?id=$service->id\">$strfunctions</a>"; 06919 06920 if ($service->restrictedusers) { 06921 $users = "<a href=\"$euurl?id=$service->id\">$strserviceusers</a>"; 06922 } else { 06923 $users = get_string('allusers', 'webservice'); 06924 } 06925 06926 $edit = "<a href=\"$esurl?id=$service->id\">$stredit</a>"; 06927 06928 // add a row to the table 06929 $table->data[] = array($displayname, $delete, $functions, $users, $edit); 06930 } 06931 // add new custom service option 06932 $return .= html_writer::table($table); 06933 06934 $return .= '<br />'; 06935 // add a token to the table 06936 $return .= "<a href=\"$esurl?id=0\">$stradd</a>"; 06937 06938 return highlight($query, $return); 06939 } 06940 } 06941 06942 06948 class admin_setting_manageplagiarism extends admin_setting { 06952 public function __construct() { 06953 $this->nosave = true; 06954 parent::__construct('plagiarismui', get_string('plagiarismsettings', 'plagiarism'), '', ''); 06955 } 06956 06962 public function get_setting() { 06963 return true; 06964 } 06965 06971 public function get_defaultsetting() { 06972 return true; 06973 } 06974 06980 public function write_setting($data) { 06981 // do not write any setting 06982 return ''; 06983 } 06984 06992 public function output_html($data, $query='') { 06993 global $CFG, $OUTPUT; 06994 06995 // display strings 06996 $txt = get_strings(array('settings', 'name')); 06997 06998 $plagiarismplugins = get_plugin_list('plagiarism'); 06999 if (empty($plagiarismplugins)) { 07000 return get_string('nopluginsinstalled', 'plagiarism'); 07001 } 07002 07003 $return = $OUTPUT->heading(get_string('availableplugins', 'plagiarism'), 3, 'main'); 07004 $return .= $OUTPUT->box_start('generalbox authsui'); 07005 07006 $table = new html_table(); 07007 $table->head = array($txt->name, $txt->settings); 07008 $table->align = array('left', 'center'); 07009 $table->data = array(); 07010 $table->attributes['class'] = 'manageplagiarismtable generaltable'; 07011 07012 // iterate through auth plugins and add to the display table 07013 $authcount = count($plagiarismplugins); 07014 foreach ($plagiarismplugins as $plugin => $dir) { 07015 if (file_exists($dir.'/settings.php')) { 07016 $displayname = "<span>".get_string($plugin, 'plagiarism_'.$plugin)."</span>"; 07017 // settings link 07018 $settings = "<a href=\"$CFG->wwwroot/plagiarism/$plugin/settings.php\">{$txt->settings}</a>"; 07019 // add a row to the table 07020 $table->data[] =array($displayname, $settings); 07021 } 07022 } 07023 $return .= html_writer::table($table); 07024 $return .= get_string('configplagiarismplugins', 'plagiarism'); 07025 $return .= $OUTPUT->box_end(); 07026 return highlight($query, $return); 07027 } 07028 } 07029 07030 07036 class admin_setting_webservicesoverview extends admin_setting { 07037 07041 public function __construct() { 07042 $this->nosave = true; 07043 parent::__construct('webservicesoverviewui', 07044 get_string('webservicesoverview', 'webservice'), '', ''); 07045 } 07046 07052 public function get_setting() { 07053 return true; 07054 } 07055 07061 public function get_defaultsetting() { 07062 return true; 07063 } 07064 07070 public function write_setting($data) { 07071 // do not write any setting 07072 return ''; 07073 } 07074 07082 public function output_html($data, $query='') { 07083 global $CFG, $OUTPUT; 07084 07085 $return = ""; 07086 $brtag = html_writer::empty_tag('br'); 07087 07088 // Enable mobile web service 07089 $enablemobile = new admin_setting_enablemobileservice('enablemobilewebservice', 07090 get_string('enablemobilewebservice', 'admin'), 07091 get_string('configenablemobilewebservice', 07092 'admin', ''), 0); //we don't want to display it but to know the ws mobile status 07093 $manageserviceurl = new moodle_url("/admin/settings.php?section=externalservices"); 07094 $wsmobileparam = new stdClass(); 07095 $wsmobileparam->enablemobileservice = get_string('enablemobilewebservice', 'admin'); 07096 $wsmobileparam->manageservicelink = html_writer::link($manageserviceurl, 07097 get_string('externalservices', 'webservice')); 07098 $mobilestatus = $enablemobile->get_setting()?get_string('mobilewsenabled', 'webservice'):get_string('mobilewsdisabled', 'webservice'); 07099 $wsmobileparam->wsmobilestatus = html_writer::tag('strong', $mobilestatus); 07100 $return .= $OUTPUT->heading(get_string('enablemobilewebservice', 'admin'), 3, 'main'); 07101 $return .= $brtag . get_string('enablemobilewsoverview', 'webservice', $wsmobileparam) 07102 . $brtag . $brtag; 07103 07105 $return .= $OUTPUT->heading(get_string('onesystemcontrolling', 'webservice'), 3, 'main'); 07106 $table = new html_table(); 07107 $table->head = array(get_string('step', 'webservice'), get_string('status'), 07108 get_string('description')); 07109 $table->size = array('30%', '10%', '60%'); 07110 $table->align = array('left', 'left', 'left'); 07111 $table->width = '90%'; 07112 $table->data = array(); 07113 07114 $return .= $brtag . get_string('onesystemcontrollingdescription', 'webservice') 07115 . $brtag . $brtag; 07116 07118 $row = array(); 07119 $url = new moodle_url("/admin/search.php?query=enablewebservices"); 07120 $row[0] = "1. " . html_writer::tag('a', get_string('enablews', 'webservice'), 07121 array('href' => $url)); 07122 $status = html_writer::tag('span', get_string('no'), array('class' => 'statuscritical')); 07123 if ($CFG->enablewebservices) { 07124 $status = get_string('yes'); 07125 } 07126 $row[1] = $status; 07127 $row[2] = get_string('enablewsdescription', 'webservice'); 07128 $table->data[] = $row; 07129 07131 $row = array(); 07132 $url = new moodle_url("/admin/settings.php?section=webserviceprotocols"); 07133 $row[0] = "2. " . html_writer::tag('a', get_string('enableprotocols', 'webservice'), 07134 array('href' => $url)); 07135 $status = html_writer::tag('span', get_string('none'), array('class' => 'statuscritical')); 07136 //retrieve activated protocol 07137 $active_protocols = empty($CFG->webserviceprotocols) ? 07138 array() : explode(',', $CFG->webserviceprotocols); 07139 if (!empty($active_protocols)) { 07140 $status = ""; 07141 foreach ($active_protocols as $protocol) { 07142 $status .= $protocol . $brtag; 07143 } 07144 } 07145 $row[1] = $status; 07146 $row[2] = get_string('enableprotocolsdescription', 'webservice'); 07147 $table->data[] = $row; 07148 07150 $row = array(); 07151 $url = new moodle_url("/user/editadvanced.php?id=-1"); 07152 $row[0] = "3. " . html_writer::tag('a', get_string('createuser', 'webservice'), 07153 array('href' => $url)); 07154 $row[1] = ""; 07155 $row[2] = get_string('createuserdescription', 'webservice'); 07156 $table->data[] = $row; 07157 07159 $row = array(); 07160 $url = new moodle_url("/admin/roles/check.php?contextid=1"); 07161 $row[0] = "4. " . html_writer::tag('a', get_string('checkusercapability', 'webservice'), 07162 array('href' => $url)); 07163 $row[1] = ""; 07164 $row[2] = get_string('checkusercapabilitydescription', 'webservice'); 07165 $table->data[] = $row; 07166 07168 $row = array(); 07169 $url = new moodle_url("/admin/settings.php?section=externalservices"); 07170 $row[0] = "5. " . html_writer::tag('a', get_string('selectservice', 'webservice'), 07171 array('href' => $url)); 07172 $row[1] = ""; 07173 $row[2] = get_string('createservicedescription', 'webservice'); 07174 $table->data[] = $row; 07175 07177 $row = array(); 07178 $url = new moodle_url("/admin/settings.php?section=externalservices"); 07179 $row[0] = "6. " . html_writer::tag('a', get_string('addfunctions', 'webservice'), 07180 array('href' => $url)); 07181 $row[1] = ""; 07182 $row[2] = get_string('addfunctionsdescription', 'webservice'); 07183 $table->data[] = $row; 07184 07186 $row = array(); 07187 $url = new moodle_url("/admin/settings.php?section=externalservices"); 07188 $row[0] = "7. " . html_writer::tag('a', get_string('selectspecificuser', 'webservice'), 07189 array('href' => $url)); 07190 $row[1] = ""; 07191 $row[2] = get_string('selectspecificuserdescription', 'webservice'); 07192 $table->data[] = $row; 07193 07195 $row = array(); 07196 $url = new moodle_url("/admin/webservice/tokens.php?sesskey=" . sesskey() . "&action=create"); 07197 $row[0] = "8. " . html_writer::tag('a', get_string('createtokenforuser', 'webservice'), 07198 array('href' => $url)); 07199 $row[1] = ""; 07200 $row[2] = get_string('createtokenforuserdescription', 'webservice'); 07201 $table->data[] = $row; 07202 07204 $row = array(); 07205 $url = new moodle_url("/admin/search.php?query=enablewsdocumentation"); 07206 $row[0] = "9. " . html_writer::tag('a', get_string('enabledocumentation', 'webservice'), 07207 array('href' => $url)); 07208 $status = '<span class="warning">' . get_string('no') . '</span>'; 07209 if ($CFG->enablewsdocumentation) { 07210 $status = get_string('yes'); 07211 } 07212 $row[1] = $status; 07213 $row[2] = get_string('enabledocumentationdescription', 'webservice'); 07214 $table->data[] = $row; 07215 07217 $row = array(); 07218 $url = new moodle_url("/admin/webservice/testclient.php"); 07219 $row[0] = "10. " . html_writer::tag('a', get_string('testwithtestclient', 'webservice'), 07220 array('href' => $url)); 07221 $row[1] = ""; 07222 $row[2] = get_string('testwithtestclientdescription', 'webservice'); 07223 $table->data[] = $row; 07224 07225 $return .= html_writer::table($table); 07226 07228 $return .= $brtag . $brtag . $brtag; 07229 $return .= $OUTPUT->heading(get_string('userasclients', 'webservice'), 3, 'main'); 07230 $table = new html_table(); 07231 $table->head = array(get_string('step', 'webservice'), get_string('status'), 07232 get_string('description')); 07233 $table->size = array('30%', '10%', '60%'); 07234 $table->align = array('left', 'left', 'left'); 07235 $table->width = '90%'; 07236 $table->data = array(); 07237 07238 $return .= $brtag . get_string('userasclientsdescription', 'webservice') . 07239 $brtag . $brtag; 07240 07242 $row = array(); 07243 $url = new moodle_url("/admin/search.php?query=enablewebservices"); 07244 $row[0] = "1. " . html_writer::tag('a', get_string('enablews', 'webservice'), 07245 array('href' => $url)); 07246 $status = html_writer::tag('span', get_string('no'), array('class' => 'statuscritical')); 07247 if ($CFG->enablewebservices) { 07248 $status = get_string('yes'); 07249 } 07250 $row[1] = $status; 07251 $row[2] = get_string('enablewsdescription', 'webservice'); 07252 $table->data[] = $row; 07253 07255 $row = array(); 07256 $url = new moodle_url("/admin/settings.php?section=webserviceprotocols"); 07257 $row[0] = "2. " . html_writer::tag('a', get_string('enableprotocols', 'webservice'), 07258 array('href' => $url)); 07259 $status = html_writer::tag('span', get_string('none'), array('class' => 'statuscritical')); 07260 //retrieve activated protocol 07261 $active_protocols = empty($CFG->webserviceprotocols) ? 07262 array() : explode(',', $CFG->webserviceprotocols); 07263 if (!empty($active_protocols)) { 07264 $status = ""; 07265 foreach ($active_protocols as $protocol) { 07266 $status .= $protocol . $brtag; 07267 } 07268 } 07269 $row[1] = $status; 07270 $row[2] = get_string('enableprotocolsdescription', 'webservice'); 07271 $table->data[] = $row; 07272 07273 07275 $row = array(); 07276 $url = new moodle_url("/admin/settings.php?section=externalservices"); 07277 $row[0] = "3. " . html_writer::tag('a', get_string('selectservice', 'webservice'), 07278 array('href' => $url)); 07279 $row[1] = ""; 07280 $row[2] = get_string('createserviceforusersdescription', 'webservice'); 07281 $table->data[] = $row; 07282 07284 $row = array(); 07285 $url = new moodle_url("/admin/settings.php?section=externalservices"); 07286 $row[0] = "4. " . html_writer::tag('a', get_string('addfunctions', 'webservice'), 07287 array('href' => $url)); 07288 $row[1] = ""; 07289 $row[2] = get_string('addfunctionsdescription', 'webservice'); 07290 $table->data[] = $row; 07291 07293 $row = array(); 07294 $url = new moodle_url("/admin/roles/check.php?contextid=1"); 07295 $row[0] = "5. " . html_writer::tag('a', get_string('addcapabilitytousers', 'webservice'), 07296 array('href' => $url)); 07297 $row[1] = ""; 07298 $row[2] = get_string('addcapabilitytousersdescription', 'webservice'); 07299 $table->data[] = $row; 07300 07302 $row = array(); 07303 $url = new moodle_url("/admin/webservice/testclient.php"); 07304 $row[0] = "6. " . html_writer::tag('a', get_string('testwithtestclient', 'webservice'), 07305 array('href' => $url)); 07306 $row[1] = ""; 07307 $row[2] = get_string('testauserwithtestclientdescription', 'webservice'); 07308 $table->data[] = $row; 07309 07310 $return .= html_writer::table($table); 07311 07312 return highlight($query, $return); 07313 } 07314 07315 } 07316 07317 07323 class admin_setting_managewebserviceprotocols extends admin_setting { 07324 07328 public function __construct() { 07329 $this->nosave = true; 07330 parent::__construct('webservicesui', get_string('manageprotocols', 'webservice'), '', ''); 07331 } 07332 07338 public function get_setting() { 07339 return true; 07340 } 07341 07347 public function get_defaultsetting() { 07348 return true; 07349 } 07350 07356 public function write_setting($data) { 07357 // do not write any setting 07358 return ''; 07359 } 07360 07367 public function is_related($query) { 07368 if (parent::is_related($query)) { 07369 return true; 07370 } 07371 07372 $textlib = textlib_get_instance(); 07373 $protocols = get_plugin_list('webservice'); 07374 foreach ($protocols as $protocol=>$location) { 07375 if (strpos($protocol, $query) !== false) { 07376 return true; 07377 } 07378 $protocolstr = get_string('pluginname', 'webservice_'.$protocol); 07379 if (strpos($textlib->strtolower($protocolstr), $query) !== false) { 07380 return true; 07381 } 07382 } 07383 return false; 07384 } 07385 07393 public function output_html($data, $query='') { 07394 global $CFG, $OUTPUT; 07395 07396 // display strings 07397 $stradministration = get_string('administration'); 07398 $strsettings = get_string('settings'); 07399 $stredit = get_string('edit'); 07400 $strprotocol = get_string('protocol', 'webservice'); 07401 $strenable = get_string('enable'); 07402 $strdisable = get_string('disable'); 07403 $strversion = get_string('version'); 07404 $struninstall = get_string('uninstallplugin', 'admin'); 07405 07406 $protocols_available = get_plugin_list('webservice'); 07407 $active_protocols = empty($CFG->webserviceprotocols) ? array() : explode(',', $CFG->webserviceprotocols); 07408 ksort($protocols_available); 07409 07410 foreach ($active_protocols as $key=>$protocol) { 07411 if (empty($protocols_available[$protocol])) { 07412 unset($active_protocols[$key]); 07413 } 07414 } 07415 07416 $return = $OUTPUT->heading(get_string('actwebserviceshhdr', 'webservice'), 3, 'main'); 07417 $return .= $OUTPUT->box_start('generalbox webservicesui'); 07418 07419 $table = new html_table(); 07420 $table->head = array($strprotocol, $strversion, $strenable, $struninstall, $strsettings); 07421 $table->align = array('left', 'center', 'center', 'center', 'center'); 07422 $table->width = '100%'; 07423 $table->data = array(); 07424 07425 // iterate through auth plugins and add to the display table 07426 $url = "$CFG->wwwroot/$CFG->admin/webservice/protocols.php?sesskey=" . sesskey(); 07427 foreach ($protocols_available as $protocol => $location) { 07428 $name = get_string('pluginname', 'webservice_'.$protocol); 07429 07430 $plugin = new stdClass(); 07431 if (file_exists($CFG->dirroot.'/webservice/'.$protocol.'/version.php')) { 07432 include($CFG->dirroot.'/webservice/'.$protocol.'/version.php'); 07433 } 07434 $version = isset($plugin->version) ? $plugin->version : ''; 07435 07436 // hide/show link 07437 if (in_array($protocol, $active_protocols)) { 07438 $hideshow = "<a href=\"$url&action=disable&webservice=$protocol\">"; 07439 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/hide') . "\" class=\"icon\" alt=\"$strdisable\" /></a>"; 07440 $displayname = "<span>$name</span>"; 07441 } else { 07442 $hideshow = "<a href=\"$url&action=enable&webservice=$protocol\">"; 07443 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/show') . "\" class=\"icon\" alt=\"$strenable\" /></a>"; 07444 $displayname = "<span class=\"dimmed_text\">$name</span>"; 07445 } 07446 07447 // delete link 07448 $uninstall = "<a href=\"$url&action=uninstall&webservice=$protocol\">$struninstall</a>"; 07449 07450 // settings link 07451 if (file_exists($CFG->dirroot.'/webservice/'.$protocol.'/settings.php')) { 07452 $settings = "<a href=\"settings.php?section=webservicesetting$protocol\">$strsettings</a>"; 07453 } else { 07454 $settings = ''; 07455 } 07456 07457 // add a row to the table 07458 $table->data[] = array($displayname, $version, $hideshow, $uninstall, $settings); 07459 } 07460 $return .= html_writer::table($table); 07461 $return .= get_string('configwebserviceplugins', 'webservice'); 07462 $return .= $OUTPUT->box_end(); 07463 07464 return highlight($query, $return); 07465 } 07466 } 07467 07468 07474 class admin_setting_managewebservicetokens extends admin_setting { 07475 07479 public function __construct() { 07480 $this->nosave = true; 07481 parent::__construct('webservicestokenui', get_string('managetokens', 'webservice'), '', ''); 07482 } 07483 07489 public function get_setting() { 07490 return true; 07491 } 07492 07498 public function get_defaultsetting() { 07499 return true; 07500 } 07501 07507 public function write_setting($data) { 07508 // do not write any setting 07509 return ''; 07510 } 07511 07519 public function output_html($data, $query='') { 07520 global $CFG, $OUTPUT, $DB, $USER; 07521 07522 // display strings 07523 $stroperation = get_string('operation', 'webservice'); 07524 $strtoken = get_string('token', 'webservice'); 07525 $strservice = get_string('service', 'webservice'); 07526 $struser = get_string('user'); 07527 $strcontext = get_string('context', 'webservice'); 07528 $strvaliduntil = get_string('validuntil', 'webservice'); 07529 $striprestriction = get_string('iprestriction', 'webservice'); 07530 07531 $return = $OUTPUT->box_start('generalbox webservicestokenui'); 07532 07533 $table = new html_table(); 07534 $table->head = array($strtoken, $struser, $strservice, $striprestriction, $strvaliduntil, $stroperation); 07535 $table->align = array('left', 'left', 'left', 'center', 'center', 'center'); 07536 $table->width = '100%'; 07537 $table->data = array(); 07538 07539 $tokenpageurl = "$CFG->wwwroot/$CFG->admin/webservice/tokens.php?sesskey=" . sesskey(); 07540 07541 //TODO: in order to let the administrator delete obsolete token, split this request in multiple request or use LEFT JOIN 07542 07543 //here retrieve token list (including linked users firstname/lastname and linked services name) 07544 $sql = "SELECT t.id, t.token, u.id AS userid, u.firstname, u.lastname, s.name, t.iprestriction, t.validuntil, s.id AS serviceid 07545 FROM {external_tokens} t, {user} u, {external_services} s 07546 WHERE t.creatorid=? AND t.tokentype = ? AND s.id = t.externalserviceid AND t.userid = u.id"; 07547 $tokens = $DB->get_records_sql($sql, array($USER->id, EXTERNAL_TOKEN_PERMANENT)); 07548 if (!empty($tokens)) { 07549 foreach ($tokens as $token) { 07550 //TODO: retrieve context 07551 07552 $delete = "<a href=\"".$tokenpageurl."&action=delete&tokenid=".$token->id."\">"; 07553 $delete .= get_string('delete')."</a>"; 07554 07555 $validuntil = ''; 07556 if (!empty($token->validuntil)) { 07557 $validuntil = date("F j, Y"); //TODO: language support (look for moodle function) 07558 } 07559 07560 $iprestriction = ''; 07561 if (!empty($token->iprestriction)) { 07562 $iprestriction = $token->iprestriction; 07563 } 07564 07565 $userprofilurl = new moodle_url('/user/profile.php?id='.$token->userid); 07566 $useratag = html_writer::start_tag('a', array('href' => $userprofilurl)); 07567 $useratag .= $token->firstname." ".$token->lastname; 07568 $useratag .= html_writer::end_tag('a'); 07569 07570 //check user missing capabilities 07571 require_once($CFG->dirroot . '/webservice/lib.php'); 07572 $webservicemanager = new webservice(); 07573 $usermissingcaps = $webservicemanager->get_missing_capabilities_by_users( 07574 array(array('id' => $token->userid)), $token->serviceid); 07575 07576 if (!is_siteadmin($token->userid) and 07577 key_exists($token->userid, $usermissingcaps)) { 07578 $missingcapabilities = implode(', ', 07579 $usermissingcaps[$token->userid]); 07580 if (!empty($missingcapabilities)) { 07581 $useratag .= html_writer::tag('div', 07582 get_string('usermissingcaps', 'webservice', 07583 $missingcapabilities) 07584 . ' ' . $OUTPUT->help_icon('missingcaps', 'webservice'), 07585 array('class' => 'missingcaps')); 07586 } 07587 } 07588 07589 $table->data[] = array($token->token, $useratag, $token->name, $iprestriction, $validuntil, $delete); 07590 } 07591 07592 $return .= html_writer::table($table); 07593 } else { 07594 $return .= get_string('notoken', 'webservice'); 07595 } 07596 07597 $return .= $OUTPUT->box_end(); 07598 // add a token to the table 07599 $return .= "<a href=\"".$tokenpageurl."&action=create\">"; 07600 $return .= get_string('add')."</a>"; 07601 07602 return highlight($query, $return); 07603 } 07604 } 07605 07606 07613 class admin_setting_configcolourpicker extends admin_setting { 07614 07620 protected $previewconfig = null; 07621 07630 public function __construct($name, $visiblename, $description, $defaultsetting, array $previewconfig=null) { 07631 $this->previewconfig = $previewconfig; 07632 parent::__construct($name, $visiblename, $description, $defaultsetting); 07633 } 07634 07640 public function get_setting() { 07641 return $this->config_read($this->name); 07642 } 07643 07650 public function write_setting($data) { 07651 $data = $this->validate($data); 07652 if ($data === false) { 07653 return get_string('validateerror', 'admin'); 07654 } 07655 return ($this->config_write($this->name, $data) ? '' : get_string('errorsetting', 'admin')); 07656 } 07657 07664 protected function validate($data) { 07665 if (preg_match('/^#?([a-fA-F0-9]{3}){1,2}$/', $data)) { 07666 if (strpos($data, '#')!==0) { 07667 $data = '#'.$data; 07668 } 07669 return $data; 07670 } else if (preg_match('/^[a-zA-Z]{3, 25}$/', $data)) { 07671 return $data; 07672 } else if (empty($data)) { 07673 return $this->defaultsetting; 07674 } else { 07675 return false; 07676 } 07677 } 07678 07687 public function output_html($data, $query = '') { 07688 global $PAGE, $OUTPUT; 07689 $PAGE->requires->js_init_call('M.util.init_colour_picker', array($this->get_id(), $this->previewconfig)); 07690 $content = html_writer::start_tag('div', array('class'=>'form-colourpicker defaultsnext')); 07691 $content .= html_writer::tag('div', $OUTPUT->pix_icon('i/loading', get_string('loading', 'admin'), 'moodle', array('class'=>'loadingicon')), array('class'=>'admin_colourpicker clearfix')); 07692 $content .= html_writer::empty_tag('input', array('type'=>'text','id'=>$this->get_id(), 'name'=>$this->get_full_name(), 'value'=>$this->get_setting(), 'size'=>'12')); 07693 if (!empty($this->previewconfig)) { 07694 $content .= html_writer::empty_tag('input', array('type'=>'button','id'=>$this->get_id().'_preview', 'value'=>get_string('preview'), 'class'=>'admin_colourpicker_preview')); 07695 } 07696 $content .= html_writer::end_tag('div'); 07697 return format_admin_setting($this, $this->visiblename, $content, $this->description, false, '', $this->get_defaultsetting(), $query); 07698 } 07699 } 07700 07706 class admin_setting_devicedetectregex extends admin_setting { 07707 07716 public function __construct($name, $visiblename, $description, $defaultsetting = '') { 07717 global $CFG; 07718 parent::__construct($name, $visiblename, $description, $defaultsetting); 07719 } 07720 07726 public function get_setting() { 07727 global $CFG; 07728 07729 $config = $this->config_read($this->name); 07730 if (is_null($config)) { 07731 return null; 07732 } 07733 07734 return $this->prepare_form_data($config); 07735 } 07736 07743 public function write_setting($data) { 07744 if (empty($data)) { 07745 $data = array(); 07746 } 07747 07748 if ($this->config_write($this->name, $this->process_form_data($data))) { 07749 return ''; // success 07750 } else { 07751 return get_string('errorsetting', 'admin') . $this->visiblename . html_writer::empty_tag('br'); 07752 } 07753 } 07754 07761 public function output_html($data, $query='') { 07762 global $OUTPUT; 07763 07764 $out = html_writer::start_tag('table', array('border' => 1, 'class' => 'generaltable')); 07765 $out .= html_writer::start_tag('thead'); 07766 $out .= html_writer::start_tag('tr'); 07767 $out .= html_writer::tag('th', get_string('devicedetectregexexpression', 'admin')); 07768 $out .= html_writer::tag('th', get_string('devicedetectregexvalue', 'admin')); 07769 $out .= html_writer::end_tag('tr'); 07770 $out .= html_writer::end_tag('thead'); 07771 $out .= html_writer::start_tag('tbody'); 07772 07773 if (empty($data)) { 07774 $looplimit = 1; 07775 } else { 07776 $looplimit = (count($data)/2)+1; 07777 } 07778 07779 for ($i=0; $i<$looplimit; $i++) { 07780 $out .= html_writer::start_tag('tr'); 07781 07782 $expressionname = 'expression'.$i; 07783 07784 if (!empty($data[$expressionname])){ 07785 $expression = $data[$expressionname]; 07786 } else { 07787 $expression = ''; 07788 } 07789 07790 $out .= html_writer::tag('td', 07791 html_writer::empty_tag('input', 07792 array( 07793 'type' => 'text', 07794 'class' => 'form-text', 07795 'name' => $this->get_full_name().'[expression'.$i.']', 07796 'value' => $expression, 07797 ) 07798 ), array('class' => 'c'.$i) 07799 ); 07800 07801 $valuename = 'value'.$i; 07802 07803 if (!empty($data[$valuename])){ 07804 $value = $data[$valuename]; 07805 } else { 07806 $value= ''; 07807 } 07808 07809 $out .= html_writer::tag('td', 07810 html_writer::empty_tag('input', 07811 array( 07812 'type' => 'text', 07813 'class' => 'form-text', 07814 'name' => $this->get_full_name().'[value'.$i.']', 07815 'value' => $value, 07816 ) 07817 ), array('class' => 'c'.$i) 07818 ); 07819 07820 $out .= html_writer::end_tag('tr'); 07821 } 07822 07823 $out .= html_writer::end_tag('tbody'); 07824 $out .= html_writer::end_tag('table'); 07825 07826 return format_admin_setting($this, $this->visiblename, $out, $this->description, false, '', null, $query); 07827 } 07828 07836 protected function prepare_form_data($regexes) { 07837 07838 $regexes = json_decode($regexes); 07839 07840 $form = array(); 07841 07842 $i = 0; 07843 07844 foreach ($regexes as $value => $regex) { 07845 $expressionname = 'expression'.$i; 07846 $valuename = 'value'.$i; 07847 07848 $form[$expressionname] = $regex; 07849 $form[$valuename] = $value; 07850 $i++; 07851 } 07852 07853 return $form; 07854 } 07855 07863 protected function process_form_data(array $form) { 07864 07865 $count = count($form); // number of form field values 07866 07867 if ($count % 2) { 07868 // we must get five fields per expression 07869 return false; 07870 } 07871 07872 $regexes = array(); 07873 for ($i = 0; $i < $count / 2; $i++) { 07874 $expressionname = "expression".$i; 07875 $valuename = "value".$i; 07876 07877 $expression = trim($form['expression'.$i]); 07878 $value = trim($form['value'.$i]); 07879 07880 if (empty($expression)){ 07881 continue; 07882 } 07883 07884 $regexes[$value] = $expression; 07885 } 07886 07887 $regexes = json_encode($regexes); 07888 07889 return $regexes; 07890 } 07891 } 07892 07898 class admin_setting_configmultiselect_modules extends admin_setting_configmultiselect { 07907 public function __construct($name, $visiblename, $description, $defaultsetting = array()) { 07908 parent::__construct($name, $visiblename, $description, $defaultsetting, null); 07909 } 07910 07916 public function load_choices() { 07917 if (is_array($this->choices)) { 07918 return true; 07919 } 07920 $this->choices = array(); 07921 07922 global $CFG, $DB; 07923 $records = $DB->get_records('modules', array('visible'=>1), 'name'); 07924 foreach ($records as $record) { 07925 if (file_exists("$CFG->dirroot/mod/$record->name/lib.php")) { 07926 $this->choices[$record->id] = $record->name; 07927 } 07928 } 07929 return true; 07930 } 07931 }