Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/adminlib.php
Go to the documentation of this file.
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">&#x2714;</span>';
01991             } else {
01992                 $executable = '<span class="patherror">&#x2718;</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">&#x2714;</span>';
02025             } else {
02026                 $executable = '<span class="patherror">&#x2718;</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">&#x2714;</span>';
02059             } else {
02060                 $executable = '<span class="patherror">&#x2718;</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>&nbsp;";
04905                 } else {
04906                     $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" />&nbsp;";
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&amp;action=disable&amp;auth=$auth\">";
05423                 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/hide') . "\" class=\"icon\" alt=\"disable\" /></a>";
05424                 // $hideshow = "<a href=\"$url&amp;action=disable&amp;auth=$auth\"><input type=\"checkbox\" checked /></a>";
05425                 $enabled = true;
05426                 $displayname = "<span>$name</span>";
05427             }
05428             else {
05429                 $hideshow = "<a href=\"$url&amp;action=enable&amp;auth=$auth\">";
05430                 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/show') . "\" class=\"icon\" alt=\"enable\" /></a>";
05431                 // $hideshow = "<a href=\"$url&amp;action=enable&amp;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&amp;action=up&amp;auth=$auth\">";
05441                     $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"up\" /></a>&nbsp;";
05442                 }
05443                 else {
05444                     $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" />&nbsp;";
05445                 }
05446                 if ($updowncount < $authcount) {
05447                     $updown .= "<a href=\"$url&amp;action=down&amp;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&amp;action=disable&amp;editor=$editor\">";
05589                 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/hide') . "\" class=\"icon\" alt=\"disable\" /></a>";
05590                 // $hideshow = "<a href=\"$url&amp;action=disable&amp;editor=$editor\"><input type=\"checkbox\" checked /></a>";
05591                 $enabled = true;
05592                 $displayname = "<span>$name</span>";
05593             }
05594             else {
05595                 $hideshow = "<a href=\"$url&amp;action=enable&amp;editor=$editor\">";
05596                 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/show') . "\" class=\"icon\" alt=\"enable\" /></a>";
05597                 // $hideshow = "<a href=\"$url&amp;action=enable&amp;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&amp;action=up&amp;editor=$editor\">";
05607                     $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"up\" /></a>&nbsp;";
05608                 }
05609                 else {
05610                     $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" />&nbsp;";
05611                 }
05612                 if ($updowncount < $editorcount) {
05613                     $updown .= "<a href=\"$url&amp;action=down&amp;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 . '&amp;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 . '&amp;action=edit&amp;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&amp;action=moveup&amp;repos=".$typename."\">";
06549                     $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"up\" /></a>&nbsp;";
06550                 }
06551                 else {
06552                     $updown .= $spacer;
06553                 }
06554                 if ($updowncount < $totalinstances) {
06555                     $updown .= "<a href=\"$this->baseurl&amp;action=movedown&amp;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&amp;sesskey=".sesskey()."&amp;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&amp;action=disable&amp;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&amp;action=enable&amp;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&amp;action=uninstall&amp;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."&amp;action=delete&amp;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                                         . '&nbsp;' . $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."&amp;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 }
 All Data Structures Namespaces Files Functions Variables Enumerations