Added one new function find_key_name() to retrieve the
[moodle.git] / lib / adminlib.php
CommitLineData
a4e10845 1<?php
88a7228a 2
3/**
4 * adminlib.php - Contains functions that only administrators will ever need to use
5 *
a4e10845 6 * @author Martin Dougiamas and many others
88a7228a 7 * @version $Id$
8 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
9 * @package moodlecore
10 */
11
12/**
ead29342 13 * Upgrade plugins
88a7228a 14 *
15 * @uses $db
16 * @uses $CFG
ead29342 17 * @param string $type The type of plugins that should be updated (e.g. 'enrol', 'qtype')
18 * @param string $dir The directory where the plugins are located (e.g. 'question/questiontypes')
19 * @param string $return The url to prompt the user to continue to
eef868d1 20 */
ead29342 21function upgrade_plugins($type, $dir, $return) {
e69ef14b 22 global $CFG, $db;
173cc1c3 23
ead29342 24 if (!$plugs = get_list_of_plugins($dir) ) {
25 error('No '.$type.' plugins installed!');
173cc1c3 26 }
27
583fad99 28 $updated_plugins = false;
29 $strpluginsetup = get_string('pluginsetup');
30
ead29342 31 foreach ($plugs as $plug) {
173cc1c3 32
ead29342 33 $fullplug = $CFG->dirroot .'/'.$dir.'/'. $plug;
173cc1c3 34
ead29342 35 unset($plugin);
173cc1c3 36
bbbf2d40 37 if (is_readable($fullplug .'/version.php')) {
ead29342 38 include_once($fullplug .'/version.php'); // defines $plugin with version etc
173cc1c3 39 } else {
40 continue; // Nothing to do.
41 }
42
e79a09a2 43 $oldupgrade = false;
44 $newupgrade = false;
7c006e34 45 if (is_readable($fullplug . '/db/'. $CFG->dbtype . '.php')) {
46 include_once($fullplug . '/db/'. $CFG->dbtype . '.php'); // defines old upgrading function
e79a09a2 47 $oldupgrade = true;
48 }
db8bd7a6 49 if (is_readable($fullplug . '/db/upgrade.php')) {
7c006e34 50 include_once($fullplug . '/db/upgrade.php'); // defines new upgrading function
e79a09a2 51 $newupgrade = true;
52 }
53
ead29342 54 if (!isset($plugin)) {
173cc1c3 55 continue;
56 }
57
ead29342 58 if (!empty($plugin->requires)) {
59 if ($plugin->requires > $CFG->version) {
60 $info->pluginname = $plug;
61 $info->pluginversion = $plugin->version;
173cc1c3 62 $info->currentmoodle = $CFG->version;
ead29342 63 $info->requiremoodle = $plugin->requires;
583fad99 64 if (!$updated_plugins) {
eef868d1 65 print_header($strpluginsetup, $strpluginsetup, $strpluginsetup, '',
583fad99 66 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
67 false, '&nbsp;', '&nbsp;');
68 }
69 upgrade_log_start();
ead29342 70 notify(get_string('pluginrequirementsnotmet', 'error', $info));
583fad99 71 $updated_plugins = true;
173cc1c3 72 unset($info);
73 continue;
74 }
75 }
76
ead29342 77 $plugin->name = $plug; // The name MUST match the directory
173cc1c3 78
ead29342 79 $pluginversion = $type.'_'.$plug.'_version';
173cc1c3 80
ead29342 81 if (!isset($CFG->$pluginversion)) {
82 set_config($pluginversion, 0);
173cc1c3 83 }
eef868d1 84
ead29342 85 if ($CFG->$pluginversion == $plugin->version) {
173cc1c3 86 // do nothing
ead29342 87 } else if ($CFG->$pluginversion < $plugin->version) {
583fad99 88 if (!$updated_plugins) {
eef868d1 89 print_header($strpluginsetup, $strpluginsetup, $strpluginsetup, '',
a36f058e 90 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
91 false, '&nbsp;', '&nbsp;');
173cc1c3 92 }
e79a09a2 93 $updated_plugins = true;
583fad99 94 upgrade_log_start();
ead29342 95 print_heading($plugin->name .' plugin needs upgrading');
e79a09a2 96 $db->debug = true;
97 @set_time_limit(0); // To allow slow databases to complete the long SQL
98
d87a9d73 99 if ($CFG->$pluginversion == 0) { // It's a new install of this plugin
e79a09a2 100 /// Both old .sql files and new install.xml are supported
101 /// but we priorize install.xml (XMLDB) if present
102 $status = false;
db8bd7a6 103 if (file_exists($fullplug . '/db/install.xml')) {
450cf307 104 $status = install_from_xmldb_file($fullplug . '/db/install.xml'); //New method
e79a09a2 105 } else if (file_exists($fullplug .'/db/'. $CFG->dbtype .'.sql')) {
106 $status = modify_database($fullplug .'/db/'. $CFG->dbtype .'.sql'); //Old method
eef868d1 107 } else {
7c006e34 108 $status = true;
d87a9d73 109 }
e79a09a2 110
111 $db->debug = false;
eef868d1 112 /// Continue with the instalation, roles and other stuff
e79a09a2 113 if ($status) {
114 // OK so far, now update the plugins record
115 set_config($pluginversion, $plugin->version);
116 if (!update_capabilities($dir.'/'.$plug)) {
117 error('Could not set up the capabilities for '.$module->name.'!');
118 }
119 notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess');
120 } else {
121 notify('Installing '. $plugin->name .' FAILED!');
122 }
d87a9d73 123 } else { // Upgrade existing install
e79a09a2 124 /// Run de old and new upgrade functions for the module
125 $oldupgrade_function = $type.'_'.$plugin->name .'_upgrade';
126 $newupgrade_function = 'xmldb_' . $type.'_'.$plugin->name .'_upgrade';
127
128 /// First, the old function if exists
129 $oldupgrade_status = true;
130 if ($oldupgrade && function_exists($oldupgrade_function)) {
131 $db->debug = true;
132 $oldupgrade_status = $oldupgrade_function($CFG->$pluginversion);
133 } else if ($oldupgrade) {
134 notify ('Upgrade function ' . $oldupgrade_function . ' was not available in ' .
135 $fullplug . '/db/' . $CFG->dbtype . '.php');
136 }
137
138 /// Then, the new function if exists and the old one was ok
139 $newupgrade_status = true;
140 if ($newupgrade && function_exists($newupgrade_function) && $oldupgrade_status) {
141 $db->debug = true;
142 $newupgrade_status = $newupgrade_function($CFG->$pluginversion);
143 } else if ($newupgrade) {
144 notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' .
145 $fullplug . '/db/upgrade.php');
146 }
147
148 $db->debug=false;
149 /// Now analyze upgrade results
150 if ($oldupgrade_status && $newupgrade_status) { // No upgrading failed
151 // OK so far, now update the plugins record
152 set_config($pluginversion, $plugin->version);
153 if (!update_capabilities($dir.'/'.$plug)) {
154 error('Could not update '.$plugin->name.' capabilities!');
d87a9d73 155 }
e79a09a2 156 notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess');
157 } else {
158 notify('Upgrading '. $plugin->name .' from '. $CFG->$pluginversion .' to '. $plugin->version .' FAILED!');
173cc1c3 159 }
160 }
d87a9d73 161 echo '<hr />';
173cc1c3 162 } else {
583fad99 163 upgrade_log_start();
ead29342 164 error('Version mismatch: '. $plugin->name .' can\'t downgrade '. $CFG->$pluginversion .' -> '. $plugin->version .' !');
173cc1c3 165 }
166 }
167
583fad99 168 upgrade_log_finish();
169
170 if ($updated_plugins) {
173cc1c3 171 print_continue($return);
172 die;
173 }
174}
175
88a7228a 176/**
177 * Find and check all modules and load them up or upgrade them if necessary
178 *
179 * @uses $db
180 * @uses $CFG
181 * @param string $return The url to prompt the user to continue to
182 * @todo Finish documenting this function
eef868d1 183 */
173cc1c3 184function upgrade_activity_modules($return) {
173cc1c3 185
e69ef14b 186 global $CFG, $db;
173cc1c3 187
88a7228a 188 if (!$mods = get_list_of_plugins('mod') ) {
189 error('No modules installed!');
173cc1c3 190 }
191
583fad99 192 $updated_modules = false;
193 $strmodulesetup = get_string('modulesetup');
194
173cc1c3 195 foreach ($mods as $mod) {
196
88a7228a 197 if ($mod == 'NEWMODULE') { // Someone has unzipped the template, ignore it
173cc1c3 198 continue;
199 }
200
88a7228a 201 $fullmod = $CFG->dirroot .'/mod/'. $mod;
173cc1c3 202
203 unset($module);
204
88a7228a 205 if ( is_readable($fullmod .'/version.php')) {
206 include_once($fullmod .'/version.php'); // defines $module with version etc
173cc1c3 207 } else {
88a7228a 208 notify('Module '. $mod .': '. $fullmod .'/version.php was not readable');
173cc1c3 209 continue;
210 }
211
d6eb06b6 212 $oldupgrade = false;
213 $newupgrade = false;
7c006e34 214 if ( is_readable($fullmod .'/db/' . $CFG->dbtype . '.php')) {
215 include_once($fullmod .'/db/' . $CFG->dbtype . '.php'); // defines old upgrading function
d6eb06b6 216 $oldupgrade = true;
217 }
db8bd7a6 218 if ( is_readable($fullmod . '/db/upgrade.php')) {
7c006e34 219 include_once($fullmod . '/db/upgrade.php'); // defines new upgrading function
d6eb06b6 220 $newupgrade = true;
173cc1c3 221 }
222
223 if (!isset($module)) {
224 continue;
225 }
226
227 if (!empty($module->requires)) {
228 if ($module->requires > $CFG->version) {
229 $info->modulename = $mod;
230 $info->moduleversion = $module->version;
231 $info->currentmoodle = $CFG->version;
232 $info->requiremoodle = $module->requires;
583fad99 233 if (!$updated_modules) {
eef868d1 234 print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '',
583fad99 235 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
236 false, '&nbsp;', '&nbsp;');
237 }
238 upgrade_log_start();
173cc1c3 239 notify(get_string('modulerequirementsnotmet', 'error', $info));
583fad99 240 $updated_modules = true;
173cc1c3 241 unset($info);
242 continue;
243 }
244 }
245
246 $module->name = $mod; // The name MUST match the directory
eef868d1 247
88a7228a 248 if ($currmodule = get_record('modules', 'name', $module->name)) {
173cc1c3 249 if ($currmodule->version == $module->version) {
250 // do nothing
251 } else if ($currmodule->version < $module->version) {
d6eb06b6 252 /// If versions say that we need to upgrade but no upgrade files are available, notify and continue
253 if (!$oldupgrade && !$newupgrade) {
254 notify('Upgrade files ' . $mod . ': ' . $fullmod . '/db/' . $CFG->dbtype . '.php or ' .
255 $fullmod . '/db/upgrade.php were not readable');
256 continue;
257 }
583fad99 258 if (!$updated_modules) {
eef868d1 259 print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '',
a36f058e 260 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
261 false, '&nbsp;', '&nbsp;');
173cc1c3 262 }
583fad99 263 upgrade_log_start();
88a7228a 264 print_heading($module->name .' module needs upgrading');
d6eb06b6 265
266 /// Run de old and new upgrade functions for the module
267 $oldupgrade_function = $module->name . '_upgrade';
268 $newupgrade_function = 'xmldb_' . $module->name . '_upgrade';
269
270 /// First, the old function if exists
271 $oldupgrade_status = true;
272 if ($oldupgrade && function_exists($oldupgrade_function)) {
273 $db->debug = true;
274 $oldupgrade_status = $oldupgrade_function($currmodule->version, $module);
ba05965e 275 } else if ($oldupgrade) {
d6eb06b6 276 notify ('Upgrade function ' . $oldupgrade_function . ' was not available in ' .
277 $mod . ': ' . $fullmod . '/db/' . $CFG->dbtype . '.php');
d6eb06b6 278 }
279
280 /// Then, the new function if exists and the old one was ok
281 $newupgrade_status = true;
ba05965e 282 if ($newupgrade && function_exists($newupgrade_function) && $oldupgrade_status) {
d6eb06b6 283 $db->debug = true;
284 $newupgrade_status = $newupgrade_function($currmodule->version, $module);
ba05965e 285 } else if ($newupgrade) {
d6eb06b6 286 notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' .
287 $mod . ': ' . $fullmod . '/db/upgrade.php');
d6eb06b6 288 }
289
e79a09a2 290 $db->debug=false;
d6eb06b6 291 /// Now analyze upgrade results
668896e5 292 if ($oldupgrade_status && $newupgrade_status) { // No upgrading failed
d6eb06b6 293 // OK so far, now update the modules record
294 $module->id = $currmodule->id;
295 if (! update_record('modules', $module)) {
296 error('Could not update '. $module->name .' record in modules table!');
173cc1c3 297 }
d6eb06b6 298 remove_dir($CFG->dataroot . '/cache', true); // flush cache
299 notify(get_string('modulesuccess', '', $module->name), 'notifysuccess');
300 echo '<hr />';
301 } else {
d6eb06b6 302 notify('Upgrading '. $module->name .' from '. $currmodule->version .' to '. $module->version .' FAILED!');
173cc1c3 303 }
bbbf2d40 304
d6eb06b6 305 /// Update the capabilities table?
bbbf2d40 306 if (!update_capabilities('mod/'.$module->name)) {
307 error('Could not update '.$module->name.' capabilities!');
308 }
309
173cc1c3 310 $updated_modules = true;
eef868d1 311
173cc1c3 312 } else {
583fad99 313 upgrade_log_start();
88a7228a 314 error('Version mismatch: '. $module->name .' can\'t downgrade '. $currmodule->version .' -> '. $module->version .' !');
173cc1c3 315 }
eef868d1 316
173cc1c3 317 } else { // module not installed yet, so install it
583fad99 318 if (!$updated_modules) {
eef868d1 319 print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '',
a36f058e 320 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
321 false, '&nbsp;', '&nbsp;');
173cc1c3 322 }
583fad99 323 upgrade_log_start();
173cc1c3 324 print_heading($module->name);
325 $updated_modules = true;
326 $db->debug = true;
327 @set_time_limit(0); // To allow slow databases to complete the long SQL
d6eb06b6 328
329 /// Both old .sql files and new install.xml are supported
330 /// but we priorize install.xml (XMLDB) if present
db8bd7a6 331 if (file_exists($fullmod . '/db/install.xml')) {
d6eb06b6 332 $status = install_from_xmldb_file($fullmod . '/db/install.xml'); //New method
333 } else {
334 $status = modify_database($fullmod .'/db/'. $CFG->dbtype .'.sql'); //Old method
335 }
336
e79a09a2 337 $db->debug = false;
d6eb06b6 338 /// Continue with the instalation, roles and other stuff
339 if ($status) {
88a7228a 340 if ($module->id = insert_record('modules', $module)) {
bbbf2d40 341 if (!update_capabilities('mod/'.$module->name)) {
342 error('Could not set up the capabilities for '.$module->name.'!');
343 }
a8f68426 344 notify(get_string('modulesuccess', '', $module->name), 'notifysuccess');
88a7228a 345 echo '<hr />';
173cc1c3 346 } else {
88a7228a 347 error($module->name .' module could not be added to the module list!');
173cc1c3 348 }
eef868d1 349 } else {
88a7228a 350 error($module->name .' tables could NOT be set up successfully!');
173cc1c3 351 }
352 }
e5bd4e58 353
354 /// Check submodules of this module if necessary
355
356 include_once($fullmod.'/lib.php'); // defines upgrading function
357
358 $submoduleupgrade = $module->name.'_upgrade_submodules';
359 if (function_exists($submoduleupgrade)) {
360 $submoduleupgrade();
361 }
362
363
364 /// Run any defaults or final code that is necessary for this module
365
a5c0990e 366 if ( is_readable($fullmod .'/defaults.php')) {
367 // Insert default values for any important configuration variables
9e6e7502 368 unset($defaults);
eef868d1 369 include_once($fullmod .'/defaults.php');
f9a2e515 370 if (!empty($defaults)) {
371 foreach ($defaults as $name => $value) {
372 if (!isset($CFG->$name)) {
373 set_config($name, $value);
374 }
a5c0990e 375 }
376 }
377 }
173cc1c3 378 }
379
583fad99 380 upgrade_log_finish(); // finish logging if started
381
382 if ($updated_modules) {
173cc1c3 383 print_continue($return);
384 die;
385 }
386}
387
eef868d1 388/**
f3221af9 389 * This function will return FALSE if the lock fails to be set (ie, if it's already locked)
80be7ee3 390 *
391 * @param string $name ?
392 * @param bool $value ?
393 * @param int $staleafter ?
394 * @param bool $clobberstale ?
395 * @todo Finish documenting this function
f3221af9 396 */
397function set_cron_lock($name,$value=true,$staleafter=7200,$clobberstale=false) {
398
399 if (empty($name)) {
400 mtrace("Tried to get a cron lock for a null fieldname");
401 return false;
402 }
403
404 if (empty($value)) {
405 set_config($name,0);
406 return true;
407 }
408
409 if ($config = get_record('config','name',$name)) {
410 if (empty($config->value)) {
411 set_config($name,time());
412 } else {
413 // check for stale.
414 if ((time() - $staleafter) > $config->value) {
415 mtrace("STALE LOCKFILE FOR $name - was $config->value");
416 if (!empty($clobberstale)) {
417 set_config($name,time());
418 return true;
419 }
420 } else {
421 return false; // was not stale - ie, we're ok to still be running.
422 }
423 }
424 }
425 else {
426 set_config($name,time());
427 }
428 return true;
429}
a597f8a8 430
fb06b255 431function print_progress($done, $total, $updatetime=5, $sleeptime=1, $donetext='') {
a597f8a8 432 static $starttime;
433 static $lasttime;
434
435 if (empty($starttime)) {
436 $starttime = $lasttime = time();
437 $lasttime = $starttime - $updatetime;
438 echo '<table width="500" cellpadding="0" cellspacing="0" align="center"><tr><td width="500">';
439 echo '<div id="bar" style="border-style:solid;border-width:1px;width:500px;height:50px;">';
440 echo '<div id="slider" style="border-style:solid;border-width:1px;height:48px;width:10px;background-color:green;"></div>';
441 echo '</div>';
442 echo '<div id="text" align="center" style="width:500px;"></div>';
443 echo '</td></tr></table>';
444 echo '</div>';
445 }
446
a597f8a8 447 $now = time();
448
449 if ($done && (($now - $lasttime) >= $updatetime)) {
450 $elapsedtime = $now - $starttime;
451 $projectedtime = (int)(((float)$total / (float)$done) * $elapsedtime) - $elapsedtime;
452 $percentage = format_float((float)$done / (float)$total, 2);
453 $width = (int)(500 * $percentage);
454
fb06b255 455 if ($projectedtime > 10) {
456 $projectedtext = ' Ending: '.format_time($projectedtime);
457 } else {
458 $projectedtext = '';
459 }
460
a597f8a8 461 echo '<script>';
fb06b255 462 echo 'document.getElementById("text").innerHTML = "'.addslashes($donetext).' '.$done.' done.'.$projectedtext.'";'."\n";
a597f8a8 463 echo 'document.getElementById("slider").style.width = \''.$width.'px\';'."\n";
464 echo '</script>';
465
466 $lasttime = $now;
467 sleep($sleeptime);
468 }
469}
583fad99 470
471////////////////////////////////////////////////
472/// upgrade logging functions
473////////////////////////////////////////////////
474
475$upgradeloghandle = false;
26c91c73 476$upgradelogbuffer = '';
477// I did not find out how to use static variable in callback function,
478// the problem was that I could not flush the static buffer :-(
479global $upgradeloghandle, $upgradelogbuffer;
583fad99 480
481/**
482 * Check if upgrade is already running.
483 *
484 * If anything goes wrong due to missing call to upgrade_log_finish()
485 * just restart the browser.
486 *
487 * @param string warning message indicating upgrade is already running
488 * @param int page reload timeout
489 */
490function upgrade_check_running($message, $timeout) {
491 if (!empty($_SESSION['upgraderunning'])) {
492 print_header();
493 redirect(me(), $message, $timeout);
494 }
495}
496
497/**
498 * Start logging of output into file (if not disabled) and
499 * prevent aborting and concurrent execution of upgrade script.
500 *
501 * Please note that you can not write into session variables after calling this function!
502 *
503 * This function may be called repeatedly.
504 */
505function upgrade_log_start() {
426a369b 506 global $CFG, $upgradeloghandle;
583fad99 507
508 if (!empty($_SESSION['upgraderunning'])) {
509 return; // logging already started
510 }
511
512 @ignore_user_abort(true); // ignore if user stops or otherwise aborts page loading
513 $_SESSION['upgraderunning'] = 1; // set upgrade indicator
426a369b 514 if (empty($CFG->dbsessions)) { // workaround for bug in adodb, db session can not be restarted
515 session_write_close(); // from now on user can reload page - will be displayed warning
516 }
583fad99 517 make_upload_directory('upgradelogs');
518 ob_start('upgrade_log_callback', 2); // function for logging to disk; flush each line of text ASAP
dedb2304 519 register_shutdown_function('upgrade_log_finish'); // in case somebody forgets to stop logging
583fad99 520}
521
522/**
523 * Terminate logging of output, flush all data, allow script aborting
524 * and reopen session for writing. Function error() does terminate the logging too.
525 *
526 * Please make sure that each upgrade_log_start() is properly terminated by
527 * this function or error().
528 *
529 * This function may be called repeatedly.
530 */
531function upgrade_log_finish() {
426a369b 532 global $CFG, $upgradeloghandle, $upgradelogbuffer;
583fad99 533
534 if (empty($_SESSION['upgraderunning'])) {
535 return; // logging already terminated
536 }
537
538 @ob_end_flush();
26c91c73 539 if ($upgradelogbuffer !== '') {
540 @fwrite($upgradeloghandle, $upgradelogbuffer);
40896537 541 $upgradelogbuffer = '';
26c91c73 542 }
543 if ($upgradeloghandle and ($upgradeloghandle !== 'error')) {
544 @fclose($upgradeloghandle);
40896537 545 $upgradeloghandle = false;
26c91c73 546 }
426a369b 547 if (empty($CFG->dbsessions)) {
548 @session_start(); // ignore header errors, we only need to reopen session
549 }
583fad99 550 $_SESSION['upgraderunning'] = 0; // clear upgrade indicator
551 if (connection_aborted()) {
552 die;
553 }
554 @ignore_user_abort(false);
555}
556
557/**
558 * Callback function for logging into files. Not more than one file is created per minute,
559 * upgrade session (terminated by upgrade_log_finish()) is always stored in one file.
560 *
561 * This function must not output any characters or throw warnigns and errors!
562 */
563function upgrade_log_callback($string) {
26c91c73 564 global $CFG, $upgradeloghandle, $upgradelogbuffer;
583fad99 565
566 if (empty($CFG->disableupgradelogging) and ($string != '') and ($upgradeloghandle !== 'error')) {
567 if ($upgradeloghandle or ($upgradeloghandle = @fopen($CFG->dataroot.'/upgradelogs/upg_'.date('Ymd-Hi').'.html', 'a'))) {
26c91c73 568 $upgradelogbuffer .= $string;
569 if (strlen($upgradelogbuffer) > 2048) { // 2kB write buffer
570 @fwrite($upgradeloghandle, $upgradelogbuffer);
571 $upgradelogbuffer = '';
572 }
583fad99 573 } else {
574 $upgradeloghandle = 'error';
575 }
576 }
577 return $string;
578}
579
57e35f32 580/**
581 * Try to verify that dataroot is not accessible from web.
582 * It is not 100% correct but might help to reduce number of vulnerable sites.
583 *
584 * Protection from httpd.conf and .htaccess is not detected properly.
585 */
586function is_dataroot_insecure() {
587 global $CFG;
588
589 $siteroot = str_replace('\\', '/', strrev($CFG->dirroot.'/')); // win32 backslash workaround
590
591 $rp = preg_replace('|https?://[^/]+|i', '', $CFG->wwwroot, 1);
592 $rp = strrev(trim($rp, '/'));
593 $rp = explode('/', $rp);
594 foreach($rp as $r) {
595 if (strpos($siteroot, '/'.$r.'/') === 0) {
596 $siteroot = substr($siteroot, strlen($r)+1); // moodle web in subdirectory
597 } else {
598 break; // probably alias root
599 }
600 }
601
602 $siteroot = strrev($siteroot);
603 $dataroot = str_replace('\\', '/', $CFG->dataroot.'/');
604
605 if (strpos($dataroot, $siteroot) === 0) {
606 return true;
607 }
608 return false;
609}
6e4dc10f 610
611/// =============================================================================================================
612/// administration tree classes and functions
613
614
615// n.b. documentation is still in progress for this code
616
617/// INTRODUCTION
618
619/// This file performs the following tasks:
620/// -it defines the necessary objects and interfaces to build the Moodle
621/// admin hierarchy
eef868d1 622/// -it defines the admin_externalpage_setup(), admin_externalpage_print_header(),
6e4dc10f 623/// and admin_externalpage_print_footer() functions used on admin pages
624
625/// ADMIN_SETTING OBJECTS
626
eef868d1 627/// Moodle settings are represented by objects that inherit from the admin_setting
6e4dc10f 628/// class. These objects encapsulate how to read a setting, how to write a new value
629/// to a setting, and how to appropriately display the HTML to modify the setting.
630
631/// ADMIN_SETTINGPAGE OBJECTS
632
633/// The admin_setting objects are then grouped into admin_settingpages. The latter
634/// appear in the Moodle admin tree block. All interaction with admin_settingpage
635/// objects is handled by the admin/settings.php file.
636
637/// ADMIN_EXTERNALPAGE OBJECTS
638
639/// There are some settings in Moodle that are too complex to (efficiently) handle
640/// with admin_settingpages. (Consider, for example, user management and displaying
641/// lists of users.) In this case, we use the admin_externalpage object. This object
642/// places a link to an external PHP file in the admin tree block.
643
644/// If you're using an admin_externalpage object for some settings, you can take
645/// advantage of the admin_externalpage_* functions. For example, suppose you wanted
646/// to add a foo.php file into admin. First off, you add the following line to
647/// admin/settings/first.php (at the end of the file) or to some other file in
648/// admin/settings:
649
eef868d1 650/// $ADMIN->add('userinterface', new admin_externalpage('foo', get_string('foo'),
6e4dc10f 651/// $CFG->wwwdir . '/' . '$CFG->admin . '/foo.php', 'some_role_permission'));
652
653/// Next, in foo.php, your file structure would resemble the following:
654
655/// require_once('.../config.php');
656/// require_once($CFG->libdir.'/adminlib.php');
657/// $adminroot = admin_get_root();
658/// admin_externalpage_setup('foo', $adminroot);
659/// // functionality like processing form submissions goes here
660/// admin_externalpage_print_header($adminroot);
661/// // your HTML goes here
662/// admin_externalpage_print_footer($adminroot);
663
664/// The admin_externalpage_setup() function call ensures the user is logged in,
665/// and makes sure that they have the proper role permission to access the page.
666
667/// The admin_externalpage_print_header() function prints the header (it figures
668/// out what category and subcategories the page is classified under) and ensures
669/// that you're using the admin pagelib (which provides the admin tree block and
670/// the admin bookmarks block).
671
672/// The admin_externalpage_print_footer() function properly closes the tables
673/// opened up by the admin_externalpage_print_header() function and prints the
674/// standard Moodle footer.
675
676/// ADMIN_CATEGORY OBJECTS
677
678/// Above and beyond all this, we have admin_category objects. These objects
679/// appear as folders in the admin tree block. They contain admin_settingpage's,
680/// admin_externalpage's, and other admin_category's.
681
682/// OTHER NOTES
683
684/// admin_settingpage's, admin_externalpage's, and admin_category's all inherit
685/// from part_of_admin_tree (a pseudointerface). This interface insists that
686/// a class has a check_access method for access permissions, a locate method
687/// used to find a specific node in the admin tree, and a path method used
688/// to determine the path to a specific node in the $ADMIN tree.
689
690/// admin_category's inherit from parentable_part_of_admin_tree. This pseudo-
691/// interface ensures that the class implements a recursive add function which
692/// accepts a part_of_admin_tree object and searches for the proper place to
693/// put it. parentable_part_of_admin_tree implies part_of_admin_tree.
694
695/// Please note that the $this->name field of any part_of_admin_tree must be
696/// UNIQUE throughout the ENTIRE admin tree.
697
698/// The $this->name field of an admin_setting object (which is *not* part_of_
699/// admin_tree) must be unique on the respective admin_settingpage where it is
700/// used.
701
702
703/// MISCELLANEOUS STUFF (used by classes defined below) ///////////////////////
704include_once($CFG->dirroot . '/backup/lib.php');
705
706/// CLASS DEFINITIONS /////////////////////////////////////////////////////////
707
708/**
709 * Pseudointerface for anything appearing in the admin tree
710 *
711 * The pseudointerface that is implemented by anything that appears in the admin tree
712 * block. It forces inheriting classes to define a method for checking user permissions
713 * and methods for finding something in the admin tree.
714 *
715 * @author Vincenzo K. Marcovecchio
716 * @package admin
717 */
718class part_of_admin_tree {
719
720 /**
721 * Finds a named part_of_admin_tree.
722 *
723 * Used to find a part_of_admin_tree. If a class only inherits part_of_admin_tree
724 * and not parentable_part_of_admin_tree, then this function should only check if
725 * $this->name matches $name. If it does, it should return a reference to $this,
726 * otherwise, it should return a reference to NULL.
727 *
728 * If a class inherits parentable_part_of_admin_tree, this method should be called
729 * recursively on all child objects (assuming, of course, the parent object's name
730 * doesn't match the search criterion).
731 *
732 * @param string $name The internal name of the part_of_admin_tree we're searching for.
733 * @return mixed An object reference or a NULL reference.
734 */
eef868d1 735 function &locate($name) {
736 trigger_error('Admin class does not implement method <strong>locate()</strong>', E_USER_WARNING);
737 return;
6e4dc10f 738 }
4672d955 739
740 /**
741 * Removes named part_of_admin_tree.
742 *
743 * @param string $name The internal name of the part_of_admin_tree we want to remove.
744 * @return boolean success.
745 */
746 function prune($name) {
eef868d1 747 trigger_error('Admin class does not implement method <strong>prune()</strong>', E_USER_WARNING);
4672d955 748 return;
eef868d1 749 }
4672d955 750
6e4dc10f 751 /**
752 * Verifies current user's access to this part_of_admin_tree.
753 *
754 * Used to check if the current user has access to this part of the admin tree or
755 * not. If a class only inherits part_of_admin_tree and not parentable_part_of_admin_tree,
756 * then this method is usually just a call to has_capability() in the site context.
757 *
758 * If a class inherits parentable_part_of_admin_tree, this method should return the
759 * logical OR of the return of check_access() on all child objects.
760 *
761 * @return bool True if the user has access, false if she doesn't.
762 */
eef868d1 763 function check_access() {
764 trigger_error('Admin class does not implement method <strong>check_access()</strong>', E_USER_WARNING);
765 return;
6e4dc10f 766 }
eef868d1 767
6e4dc10f 768 /**
769 * Determines the path to $name in the admin tree.
770 *
771 * Used to determine the path to $name in the admin tree. If a class inherits only
772 * part_of_admin_tree and not parentable_part_of_admin_tree, then this method should
773 * check if $this->name matches $name. If it does, $name is pushed onto the $path
774 * array (at the end), and $path should be returned. If it doesn't, NULL should be
775 * returned.
776 *
777 * If a class inherits parentable_part_of_admin_tree, it should do the above, but not
778 * return NULL on failure. Instead, it pushes $this->name onto $path, and then
779 * recursively calls path() on its child objects. If any are non-NULL, it should
780 * return $path (being certain that the last element of $path is equal to $name).
781 * If they are all NULL, it returns NULL.
782 *
783 * @param string $name The internal name of the part_of_admin_tree we're searching for.
784 * @param array $path Not used on external calls. Defaults to empty array.
785 * @return mixed If found, an array containing the internal names of each part_of_admin_tree that leads to $name. If not found, NULL.
786 */
eef868d1 787 function path($name, $path = array()) {
788 trigger_error('Admin class does not implement method <strong>path()</strong>', E_USER_WARNING);
789 return;
6e4dc10f 790 }
791}
792
793/**
794 * Pseudointerface implemented by any part_of_admin_tree that has children.
795 *
796 * The pseudointerface implemented by any part_of_admin_tree that can be a parent
797 * to other part_of_admin_tree's. (For now, this only includes admin_category.) Apart
eef868d1 798 * from ensuring part_of_admin_tree compliancy, it also ensures inheriting methods
6e4dc10f 799 * include an add method for adding other part_of_admin_tree objects as children.
800 *
801 * @author Vincenzo K. Marcovecchio
802 * @package admin
803 */
804class parentable_part_of_admin_tree extends part_of_admin_tree {
eef868d1 805
6e4dc10f 806 /**
807 * Adds a part_of_admin_tree object to the admin tree.
808 *
809 * Used to add a part_of_admin_tree object to this object or a child of this
810 * object. $something should only be added if $destinationname matches
811 * $this->name. If it doesn't, add should be called on child objects that are
812 * also parentable_part_of_admin_tree's.
813 *
814 * @param string $destinationname The internal name of the new parent for $something.
815 * @param part_of_admin_tree &$something The object to be added.
816 * @return bool True on success, false on failure.
817 */
eef868d1 818 function add($destinationname, &$something) {
819 trigger_error('Admin class does not implement method <strong>add()</strong>', E_USER_WARNING);
820 return;
6e4dc10f 821 }
eef868d1 822
6e4dc10f 823}
824
825/**
826 * The object used to represent folders (a.k.a. categories) in the admin tree block.
eef868d1 827 *
6e4dc10f 828 * Each admin_category object contains a number of part_of_admin_tree objects.
829 *
830 * @author Vincenzo K. Marcovecchio
831 * @package admin
832 */
833class admin_category extends parentable_part_of_admin_tree {
834
835 /**
836 * @var mixed An array of part_of_admin_tree objects that are this object's children
837 */
838 var $children;
eef868d1 839
6e4dc10f 840 /**
841 * @var string An internal name for this category. Must be unique amongst ALL part_of_admin_tree objects
842 */
843 var $name;
eef868d1 844
6e4dc10f 845 /**
846 * @var string The displayed name for this category. Usually obtained through get_string()
847 */
848 var $visiblename;
eef868d1 849
6e4dc10f 850 // constructor for an empty admin category
851 // $name is the internal name of the category. it MUST be unique in the entire hierarchy
852 // $visiblename is the displayed name of the category. use a get_string for this
853
854 /**
855 * Constructor for an empty admin category
856 *
857 * @param string $name The internal name for this category. Must be unique amongst ALL part_of_admin_tree objects
858 * @param string $visiblename The displayed named for this category. Usually obtained through get_string()
859 * @return mixed Returns the new object.
860 */
861 function admin_category($name, $visiblename) {
862 $this->children = array();
863 $this->name = $name;
864 $this->visiblename = $visiblename;
865 }
eef868d1 866
6e4dc10f 867 /**
868 * Finds the path to the part_of_admin_tree called $name.
869 *
870 * @param string $name The internal name that we're searching for.
871 * @param array $path Used internally for recursive calls. Do not specify on external calls. Defaults to array().
872 * @return mixed An array of internal names that leads to $name, or NULL if not found.
873 */
874 function path($name, $path = array()) {
eef868d1 875
6e4dc10f 876 $path[count($path)] = $this->name;
eef868d1 877
6e4dc10f 878 if ($this->name == $name) {
879 return $path;
880 }
eef868d1 881
6e4dc10f 882 foreach($this->children as $child) {
883 if ($return = $child->path($name, $path)) {
884 return $return;
885 }
886 }
eef868d1 887
6e4dc10f 888 return NULL;
eef868d1 889
6e4dc10f 890 }
891
892 /**
893 * Returns a reference to the part_of_admin_tree object with internal name $name.
894 *
895 * @param string $name The internal name of the object we want.
896 * @return mixed A reference to the object with internal name $name if found, otherwise a reference to NULL.
897 */
898 function &locate($name) {
eef868d1 899
6e4dc10f 900 if ($this->name == $name) {
901 return $this;
902 }
eef868d1 903
6e4dc10f 904 foreach($this->children as $child) {
905 if ($return =& $child->locate($name)) {
906 return $return;
907 }
908 }
909 $return = NULL;
910 return $return;
911 }
912
4672d955 913 /**
914 * Removes part_of_admin_tree object with internal name $name.
915 *
916 * @param string $name The internal name of the object we want to remove.
917 * @return boolean success
918 */
919 function prune($name) {
920
921 if ($this->name == $name) {
922 return false; //can not remove itself
923 }
924
925 foreach($this->children as $precedence => $child) {
926 if ($child->name == $name) {
927 // found it!
eef868d1 928 unset($this->children[$precedence]);
4672d955 929 return true;
930 }
931 if ($this->children[$precedence]->prune($name)) {
932 return true;
933 }
934 }
935 return false;
936 }
937
6e4dc10f 938 /**
939 * Adds a part_of_admin_tree to a child or grandchild (or great-grandchild, and so forth) of this object.
940 *
941 * @param string $destinationame The internal name of the immediate parent that we want for &$something.
942 * @param mixed &$something A part_of_admin_tree object to be added.
943 * @param int $precedence The precedence of &$something when displayed. Smaller numbers mean it'll be displayed higher up in the admin menu. Defaults to '', meaning "next available position".
944 * @return bool True if successfully added, false if &$something is not a part_of_admin_tree or if $name is not found.
945 */
946 function add($destinationname, &$something, $precedence = '') {
eef868d1 947
6e4dc10f 948 if (!is_a($something, 'part_of_admin_tree')) {
949 return false;
950 }
951
952 if ($destinationname == $this->name) {
953 if ($precedence === '') {
954 $this->children[] = $something;
955 } else {
956 if (isset($this->children[$precedence])) { // this should never, ever be triggered in a release version of moodle.
957 echo ('<font style="color: red;">There is a precedence conflict in the category ' . $this->name . '. The object named ' . $something->name . ' is overwriting the object named ' . $this->children[$precedence]->name . '.</font><br />');
958 }
959 $this->children[$precedence] = $something;
960 }
961 return true;
962 }
eef868d1 963
6e4dc10f 964 unset($entries);
eef868d1 965
6e4dc10f 966 $entries = array_keys($this->children);
eef868d1 967
6e4dc10f 968 foreach($entries as $entry) {
969 $child =& $this->children[$entry];
970 if (is_a($child, 'parentable_part_of_admin_tree')) {
971 if ($child->add($destinationname, $something, $precedence)) {
972 return true;
973 }
974 }
975 }
eef868d1 976
6e4dc10f 977 return false;
eef868d1 978
6e4dc10f 979 }
eef868d1 980
6e4dc10f 981 /**
982 * Checks if the user has access to anything in this category.
983 *
984 * @return bool True if the user has access to atleast one child in this category, false otherwise.
985 */
986 function check_access() {
eef868d1 987
6e4dc10f 988 $return = false;
989 foreach ($this->children as $child) {
990 $return = $return || $child->check_access();
991 }
eef868d1 992
6e4dc10f 993 return $return;
eef868d1 994
6e4dc10f 995 }
eef868d1 996
6e4dc10f 997}
998
999/**
1000 * Links external PHP pages into the admin tree.
1001 *
1002 * See detailed usage example at the top of this document (adminlib.php)
1003 *
1004 * @author Vincenzo K. Marcovecchio
1005 * @package admin
1006 */
1007class admin_externalpage extends part_of_admin_tree {
1008
eef868d1 1009 /**
6e4dc10f 1010 * @var string An internal name for this external page. Must be unique amongst ALL part_of_admin_tree objects
1011 */
1012 var $name;
eef868d1 1013
6e4dc10f 1014 /**
1015 * @var string The displayed name for this external page. Usually obtained through get_string().
1016 */
1017 var $visiblename;
eef868d1 1018
6e4dc10f 1019 /**
1020 * @var string The external URL that we should link to when someone requests this external page.
1021 */
1022 var $url;
eef868d1 1023
6e4dc10f 1024 /**
1025 * @var string The role capability/permission a user must have to access this external page.
1026 */
2ce38b70 1027 var $req_capability;
eef868d1 1028
6e4dc10f 1029 /**
1030 * Constructor for adding an external page into the admin tree.
1031 *
1032 * @param string $name The internal name for this external page. Must be unique amongst ALL part_of_admin_tree objects.
1033 * @param string $visiblename The displayed name for this external page. Usually obtained through get_string().
1034 * @param string $url The external URL that we should link to when someone requests this external page.
38d2d43b 1035 * @param mixed $req_capability The role capability/permission a user must have to access this external page. Defaults to 'moodle/site:config'.
6e4dc10f 1036 */
2ce38b70 1037 function admin_externalpage($name, $visiblename, $url, $req_capability = 'moodle/site:config') {
6e4dc10f 1038 $this->name = $name;
1039 $this->visiblename = $visiblename;
1040 $this->url = $url;
38d2d43b 1041 if (is_array($req_capability)) {
1042 $this->req_capability = $req_capability;
1043 } else {
1044 $this->req_capability = array($req_capability);
1045 }
6e4dc10f 1046 }
eef868d1 1047
6e4dc10f 1048 /**
1049 * Finds the path to the part_of_admin_tree called $name.
1050 *
1051 * @param string $name The internal name that we're searching for.
1052 * @param array $path Used internally for recursive calls. Do not specify on external calls. Defaults to array().
1053 * @return mixed An array of internal names that leads to $name, or NULL if not found.
1054 */
1055 function path($name, $path = array()) {
1056 if ($name == $this->name) {
1057 array_push($path, $this->name);
1058 return $path;
1059 } else {
1060 return NULL;
1061 }
1062 }
eef868d1 1063
6e4dc10f 1064 /**
1065 * Returns a reference to the part_of_admin_tree object with internal name $name.
1066 *
1067 * @param string $name The internal name of the object we want.
1068 * @return mixed A reference to the object with internal name $name if found, otherwise a reference to NULL.
1069 */
1070 function &locate($name) {
1071 $return = ($this->name == $name ? $this : NULL);
1072 return $return;
1073 }
4672d955 1074
1075 function prune($name) {
1076 return false;
1077 }
1078
6e4dc10f 1079 /**
2ce38b70 1080 * Determines if the current user has access to this external page based on $this->req_capability.
6e4dc10f 1081 *
1082 * @uses CONTEXT_SYSTEM
1083 * @uses SITEID
1084 * @return bool True if user has access, false otherwise.
1085 */
1086 function check_access() {
1087 if (!get_site()) {
1088 return true; // no access check before site is fully set up
1089 }
eef868d1 1090 $context = get_context_instance(CONTEXT_SYSTEM, SITEID);
38d2d43b 1091 foreach($this->req_capability as $cap) {
1092 if (has_capability($cap, $context)) {
1093 return true;
1094 }
1095 }
1096 return false;
6e4dc10f 1097 }
1098
1099}
1100
1101/**
1102 * Used to group a number of admin_setting objects into a page and add them to the admin tree.
1103 *
1104 * @author Vincenzo K. Marcovecchio
1105 * @package admin
1106 */
1107class admin_settingpage extends part_of_admin_tree {
1108
eef868d1 1109 /**
6e4dc10f 1110 * @var string An internal name for this external page. Must be unique amongst ALL part_of_admin_tree objects
1111 */
1112 var $name;
eef868d1 1113
6e4dc10f 1114 /**
1115 * @var string The displayed name for this external page. Usually obtained through get_string().
1116 */
1117 var $visiblename;
1118 /**
1119 * @var mixed An array of admin_setting objects that are part of this setting page.
1120 */
1121 var $settings;
eef868d1 1122
6e4dc10f 1123 /**
1124 * @var string The role capability/permission a user must have to access this external page.
1125 */
2ce38b70 1126 var $req_capability;
eef868d1 1127
6e4dc10f 1128 // see admin_category
1129 function path($name, $path = array()) {
1130 if ($name == $this->name) {
1131 array_push($path, $this->name);
1132 return $path;
1133 } else {
1134 return NULL;
1135 }
1136 }
eef868d1 1137
6e4dc10f 1138 // see admin_category
1139 function &locate($name) {
1140 $return = ($this->name == $name ? $this : NULL);
1141 return $return;
1142 }
4672d955 1143
1144 function prune($name) {
1145 return false;
1146 }
1147
6e4dc10f 1148 // see admin_externalpage
2ce38b70 1149 function admin_settingpage($name, $visiblename, $req_capability = 'moodle/site:config') {
6e4dc10f 1150 global $CFG;
1151 $this->settings = new stdClass();
1152 $this->name = $name;
1153 $this->visiblename = $visiblename;
38d2d43b 1154 if (is_array($req_capability)) {
1155 $this->req_capability = $req_capability;
1156 } else {
1157 $this->req_capability = array($req_capability);
1158 }
6e4dc10f 1159 }
eef868d1 1160
6e4dc10f 1161 // not the same as add for admin_category. adds an admin_setting to this admin_settingpage. settings appear (on the settingpage) in the order in which they're added
1162 // n.b. each admin_setting in an admin_settingpage must have a unique internal name
1163 // &$setting is the admin_setting object you want to add
1164 // returns true if successful, false if not (will fail if &$setting is an admin_setting or child thereof)
1165 function add(&$setting) {
1166 if (is_a($setting, 'admin_setting')) {
1167 $this->settings->{$setting->name} =& $setting;
1168 return true;
1169 }
1170 return false;
1171 }
eef868d1 1172
6e4dc10f 1173 // see admin_externalpage
1174 function check_access() {
1175 if (!get_site()) {
1176 return true; // no access check before site is fully set up
1177 }
eef868d1 1178 $context = get_context_instance(CONTEXT_SYSTEM, SITEID);
38d2d43b 1179 foreach($this->req_capability as $cap) {
1180 if (has_capability($cap, $context)) {
1181 return true;
1182 }
1183 }
1184 return false;
6e4dc10f 1185 }
eef868d1 1186
6e4dc10f 1187 // outputs this page as html in a table (suitable for inclusion in an admin pagetype)
1188 // returns a string of the html
1189 function output_html() {
1190 $return = '<table class="generaltable" width="100%" border="0" align="center" cellpadding="5" cellspacing="1">' . "\n";
1191 foreach($this->settings as $setting) {
1192 $return .= $setting->output_html();
1193 }
1194 $return .= '</table>';
1195 return $return;
1196 }
1197
1198 // writes settings (the ones that have been added to this admin_settingpage) to the database, or wherever else they're supposed to be written to
1199 // -- calls write_setting() to each child setting, sending it only the data that matches each setting's internal name
1200 // $data should be the result from data_submitted()
1201 // returns an empty string if everything went well, otherwise returns a printable error string (that's language-specific)
1202 function write_settings($data) {
1203 $return = '';
1204 foreach($this->settings as $setting) {
1205 if (isset($data['s_' . $setting->name])) {
1206 $return .= $setting->write_setting($data['s_' . $setting->name]);
1207 } else {
1208 $return .= $setting->write_setting('');
1209 }
1210 }
1211 return $return;
1212 }
1213
1214}
1215
1216
1217// read & write happens at this level; no authentication
1218class admin_setting {
1219
1220 var $name;
1221 var $visiblename;
1222 var $description;
1223 var $defaultsetting;
1224
1225 function admin_setting($name, $visiblename, $description, $defaultsetting) {
1226 $this->name = $name;
1227 $this->visiblename = $visiblename;
1228 $this->description = $description;
1229 $this->defaultsetting = $defaultsetting;
1230 }
eef868d1 1231
6e4dc10f 1232 function get_setting() {
1233 return NULL; // has to be overridden
1234 }
eef868d1 1235
6e4dc10f 1236 function write_setting($data) {
1237 return; // has to be overridden
1238 }
eef868d1 1239
6e4dc10f 1240 function output_html() {
1241 return; // has to be overridden
1242 }
eef868d1 1243
6e4dc10f 1244}
1245
1246
1247class admin_setting_configtext extends admin_setting {
1248
1249 var $paramtype;
1250
50999a0b 1251 function admin_setting_configtext($name, $visiblename, $description, $defaultsetting, $paramtype=PARAM_RAW) {
6e4dc10f 1252 $this->paramtype = $paramtype;
1253 parent::admin_setting($name, $visiblename, $description, $defaultsetting);
1254 }
1255
cc73de71 1256 // returns a string or NULL
6e4dc10f 1257 function get_setting() {
1258 global $CFG;
c8218a42 1259 return (isset($CFG->{$this->name}) ? $CFG->{$this->name} : NULL);
6e4dc10f 1260 }
eef868d1 1261
cc73de71 1262 // $data is a string
6e4dc10f 1263 function write_setting($data) {
c235598d 1264 if (is_string($this->paramtype)) {
1265 if (!$this->validate($data)) {
1266 return get_string('validateerror', 'admin') . $this->visiblename . '<br />';
1267 }
1268 } else {
cc73de71 1269 if ($data != clean_param($data, $this->paramtype)) {
1270 return get_string('validateerror', 'admin') . $this->visiblename . '<br />';
1271 }
c235598d 1272 }
6e4dc10f 1273 return (set_config($this->name,$data) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1274 }
1275
c235598d 1276 function validate($data) {
1277 return preg_match($this->paramtype, $data);
1278 }
1279
6e4dc10f 1280 function output_html() {
c8218a42 1281 if ($this->get_setting() === NULL) {
1282 $current = $this->defaultsetting;
1283 } else {
1284 $current = $this->get_setting();
1285 }
6e4dc10f 1286 return '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td>' .
c8218a42 1287 '<td align="left"><input type="text" size="50" name="s_'. $this->name .'" value="'. $current .'" /></td></tr>' .
6e4dc10f 1288 '<tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
1289 }
1290
1291}
1292
1293class admin_setting_configcheckbox extends admin_setting {
1294
1295 function admin_setting_configcheckbox($name, $visiblename, $description, $defaultsetting) {
1296 parent::admin_setting($name, $visiblename, $description, $defaultsetting);
1297 }
1298
1299 function get_setting() {
1300 global $CFG;
1301 return (isset($CFG->{$this->name}) ? $CFG->{$this->name} : NULL);
1302 }
eef868d1 1303
6e4dc10f 1304 function write_setting($data) {
1305 if ($data == '1') {
1306 return (set_config($this->name,1) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1307 } else {
1308 return (set_config($this->name,0) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1309 }
1310 }
1311
1312 function output_html() {
c8218a42 1313 if ($this->get_setting() === NULL) {
1314 $current = $this->defaultsetting;
1315 } else {
1316 $current = $this->get_setting();
1317 }
6e4dc10f 1318 return '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td>' .
c8218a42 1319 '<td align="left"><input type="checkbox" size="50" name="s_'. $this->name .'" value="1" ' . ($current == true ? 'checked="checked"' : '') . ' /></td></tr>' .
6e4dc10f 1320 '<tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
1321 }
1322
1323}
1324
1325class admin_setting_configselect extends admin_setting {
1326
1327 var $choices;
eef868d1 1328
6e4dc10f 1329 function admin_setting_configselect($name, $visiblename, $description, $defaultsetting, $choices) {
1330 $this->choices = $choices;
1331 parent::admin_setting($name, $visiblename, $description, $defaultsetting);
1332 }
1333
1334 function get_setting() {
1335 global $CFG;
1336 return (isset($CFG->{$this->name}) ? $CFG->{$this->name} : NULL);
1337 }
eef868d1 1338
6e4dc10f 1339 function write_setting($data) {
1340 // check that what we got was in the original choices
1341 // or that the data is the default setting - needed during install when choices can not be constructed yet
1342 if ($data != $this->defaultsetting and ! in_array($data, array_keys($this->choices))) {
1343 return 'Error setting ' . $this->visiblename . '<br />';
1344 }
eef868d1 1345
6e4dc10f 1346 return (set_config($this->name, $data) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1347 }
eef868d1 1348
6e4dc10f 1349 function output_html() {
c8218a42 1350 if ($this->get_setting() === NULL) {
1351 $current = $this->defaultsetting;
1352 } else {
1353 $current = $this->get_setting();
1354 }
6e4dc10f 1355 $return = '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td><td align="left"><select name="s_' . $this->name .'">';
1356 foreach ($this->choices as $key => $value) {
c8218a42 1357 $return .= '<option value="' . $key . '"' . ($key == $current ? ' selected="selected"' : '') . '>' . $value . '</option>';
6e4dc10f 1358 }
1359 $return .= '</select></td></tr><tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
1360 return $return;
1361 }
1362
1363}
1364
1365// this is a liiitle bit messy. we're using two selects, but we're returning them as an array named after $name (so we only use $name2
1366// internally for the setting)
1367class admin_setting_configtime extends admin_setting {
1368
1369 var $name2;
1370 var $choices;
1371 var $choices2;
6e4dc10f 1372
1373 function admin_setting_configtime($hoursname, $minutesname, $visiblename, $description, $defaultsetting) {
1374 $this->name2 = $minutesname;
1375 $this->choices = array();
1376 for ($i = 0; $i < 24; $i++) {
1377 $this->choices[$i] = $i;
1378 }
1379 $this->choices2 = array();
1380 for ($i = 0; $i < 60; $i += 5) {
1381 $this->choices2[$i] = $i;
1382 }
1383 parent::admin_setting($hoursname, $visiblename, $description, $defaultsetting);
1384 }
1385
1386 function get_setting() {
1387 global $CFG;
cc73de71 1388 return (isset($CFG->{$this->name}) && isset($CFG->{$this->name2}) ? array('h' => $CFG->{$this->name}, 'm' => $CFG->{$this->name2}) : NULL);
6e4dc10f 1389 }
eef868d1 1390
6e4dc10f 1391 function write_setting($data) {
1392 // check that what we got was in the original choices
1393 if (!(in_array($data['h'], array_keys($this->choices)) && in_array($data['m'], array_keys($this->choices2)))) {
1394 return get_string('errorsetting', 'admin') . $this->visiblename . '<br />';
1395 }
eef868d1 1396
6e4dc10f 1397 return (set_config($this->name, $data['h']) && set_config($this->name2, $data['m']) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1398 }
eef868d1 1399
6e4dc10f 1400 function output_html() {
cc73de71 1401 if ($this->get_setting() === NULL) {
1402 $currentsetting = $this->defaultsetting;
1403 } else {
1404 $currentsetting = $this->get_setting();
6e4dc10f 1405 }
1406 $return = '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td><td align="left"><select name="s_' . $this->name .'[h]">';
1407 foreach ($this->choices as $key => $value) {
cc73de71 1408 $return .= '<option value="' . $key . '"' . ($key == $currentsetting['h'] ? ' selected="selected"' : '') . '>' . $value . '</option>';
6e4dc10f 1409 }
1410 $return .= '</select>&nbsp;&nbsp;&nbsp;<select name="s_' . $this->name . '[m]">';
1411 foreach ($this->choices2 as $key => $value) {
cc73de71 1412 $return .= '<option value="' . $key . '"' . ($key == $currentsetting['m'] ? ' selected="selected"' : '') . '>' . $value . '</option>';
eef868d1 1413 }
6e4dc10f 1414 $return .= '</select></td></tr><tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
1415 return $return;
1416 }
1417
1418}
1419
1420class admin_setting_configmultiselect extends admin_setting_configselect {
1421
1422 function admin_setting_configmultiselect($name, $visiblename, $description, $defaultsetting, $choices) {
1423 parent::admin_setting_configselect($name, $visiblename, $description, $defaultsetting, $choices);
1424 }
1425
1426 function get_setting() {
1427 global $CFG;
1428 return (isset($CFG->{$this->name}) ? explode(',', $CFG->{$this->name}) : NULL);;
1429 }
eef868d1 1430
6e4dc10f 1431 function write_setting($data) {
1432 foreach ($data as $datum) {
1433 if (! in_array($datum, array_keys($this->choices))) {
1434 return get_string('errorsetting', 'admin') . $this->visiblename . '<br />';
1435 }
1436 }
eef868d1 1437
6e4dc10f 1438 return (set_config($this->name, implode(',',$data)) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1439 }
eef868d1 1440
6e4dc10f 1441 function output_html() {
cc73de71 1442 if ($this->get_setting() === NULL) {
1443 $currentsetting = $this->defaultsetting;
1444 } else {
1445 $currentsetting = $this->get_setting();
6e4dc10f 1446 }
1447 $return = '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td><td align="left"><select name="s_' . $this->name .'[]" size="10" multiple="multiple">';
1448 foreach ($this->choices as $key => $value) {
1449 $return .= '<option value="' . $key . '"' . (in_array($key,$currentsetting) ? ' selected="selected"' : '') . '>' . $value . '</option>';
1450 }
1451 $return .= '</select></td></tr><tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
1452 return $return;
1453 }
1454
1455}
1456
1457class admin_setting_special_adminseesall extends admin_setting_configcheckbox {
eef868d1 1458
6e4dc10f 1459 function admin_setting_special_adminseesall() {
1460 $name = 'calendar_adminseesall';
1461 $visiblename = get_string('adminseesall', 'admin');
1462 $description = get_string('helpadminseesall', 'admin');
1463 parent::admin_setting($name, $visiblename, $description, 0);
1464 }
1465
1466 function write_setting($data) {
1467 global $SESSION;
1468 unset($SESSION->cal_courses_shown);
1469 parent::write_setting($data);
1470 }
1471}
1472
1473class admin_setting_sitesetselect extends admin_setting_configselect {
1474
1475 var $id;
1476
1477 function admin_setting_sitesetselect($name, $visiblename, $description, $defaultsetting, $choices) {
1478
1479 $this->id = SITEID;
1480 parent::admin_setting_configselect($name, $visiblename, $description, $defaultsetting, $choices);
eef868d1 1481
6e4dc10f 1482 }
eef868d1 1483
6e4dc10f 1484 function get_setting() {
1485 $site = get_site();
1486 return (isset($site->{$this->name}) ? $site->{$this->name} : NULL);
1487 }
eef868d1 1488
6e4dc10f 1489 function write_setting($data) {
1490 if (!in_array($data, array_keys($this->choices))) {
1491 return get_string('errorsetting', 'admin') . $this->visiblename . '<br />';
1492 }
1493 $record = new stdClass();
1494 $record->id = $this->id;
1495 $temp = $this->name;
1496 $record->$temp = $data;
1497 $record->timemodified = time();
1498 return (update_record('course', $record) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1499 }
eef868d1 1500
6e4dc10f 1501}
1502
1503
e0f6e995 1504class admin_setting_courselist_frontpage extends admin_setting_configselect {
6e4dc10f 1505
e0f6e995 1506 function admin_setting_courselist_frontpage($loggedin) {
6e4dc10f 1507 global $CFG;
1508 require_once($CFG->dirroot . '/course/lib.php');
1509 $name = 'frontpage' . ($loggedin ? 'loggedin' : '');
1510 $visiblename = get_string('frontpage' . ($loggedin ? 'loggedin' : ''),'admin');
1511 $description = get_string('configfrontpage' . ($loggedin ? 'loggedin' : ''),'admin');
1512 $choices = array(FRONTPAGENEWS => get_string('frontpagenews'),
1513 FRONTPAGECOURSELIST => get_string('frontpagecourselist'),
1514 FRONTPAGECATEGORYNAMES => get_string('frontpagecategorynames'),
1515 FRONTPAGECATEGORYCOMBO => get_string('frontpagecategorycombo'),
1516 '' => get_string('none'));
1517 if (count_records("course") > FRONTPAGECOURSELIMIT) {
1518 unset($choices[FRONTPAGECOURSELIST]);
1519 }
4672d955 1520 $defaults = FRONTPAGECOURSELIST.',,,';
e0f6e995 1521 parent::admin_setting_configselect($name, $visiblename, $description, $defaults, $choices);
6e4dc10f 1522 }
eef868d1 1523
6e4dc10f 1524 function get_setting() {
1525 global $CFG;
1c1e7af4 1526 return (isset($CFG->{$this->name}) ? explode(',', $CFG->{$this->name}) : ',1,,');
6e4dc10f 1527 }
eef868d1 1528
6e4dc10f 1529 function write_setting($data) {
1530 if (empty($data)) {
1531 $data = array();
e0f6e995 1532 } if (!is_array($data)) {
1533 $data = explode(',', $data);
6e4dc10f 1534 }
1535 foreach($data as $datum) {
1536 if (! in_array($datum, array_keys($this->choices))) {
1537 return get_string('errorsetting', 'admin') . $this->visiblename . '<br />';
1538 }
1539 }
1540 return (set_config($this->name, implode(',', $data)) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1541 }
eef868d1 1542
6e4dc10f 1543 function output_html() {
cc73de71 1544 if ($this->get_setting() === NULL) {
1545 $currentsetting = $this->defaultsetting;
1546 } else {
1547 $currentsetting = $this->get_setting();
6e4dc10f 1548 }
1549 for ($i = 0; $i < count($this->choices) - 1; $i++) {
1550 if (!isset($currentsetting[$i])) {
1551 $currentsetting[$i] = 0;
1552 }
1553 }
1554 $return = '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td><td align="left">';
1555 for ($i = 0; $i < count($this->choices) - 1; $i++) {
eef868d1 1556 $return .='<select name="s_' . $this->name .'[]">';
6e4dc10f 1557 foreach ($this->choices as $key => $value) {
1558 $return .= '<option value="' . $key . '"' . ($key == $currentsetting[$i] ? ' selected="selected"' : '') . '>' . $value . '</option>';
1559 }
1560 $return .= '</select>';
1561 if ($i !== count($this->choices) - 2) {
975211bb 1562 $return .= '<br />';
6e4dc10f 1563 }
1564 }
1565 $return .= '</td></tr><tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
eef868d1 1566 return $return;
6e4dc10f 1567 }
1568}
1569
1570class admin_setting_sitesetcheckbox extends admin_setting_configcheckbox {
1571
1572 var $id;
1573
1574 function admin_setting_sitesetcheckbox($name, $visiblename, $description, $defaultsetting) {
1575
1576 $this->id = SITEID;
1577 parent::admin_setting_configcheckbox($name, $visiblename, $description, $defaultsetting);
eef868d1 1578
6e4dc10f 1579 }
eef868d1 1580
6e4dc10f 1581 function get_setting() {
1582 $site = get_site();
1583 return (isset($site->{$this->name}) ? $site->{$this->name} : NULL);
1584 }
eef868d1 1585
6e4dc10f 1586 function write_setting($data) {
1587 $record = new stdClass();
1588 $record->id = $this->id;
1589 $temp = $this->name;
1590 $record->$temp = ($data == '1' ? 1 : 0);
1591 $record->timemodified = time();
1592 return (update_record('course', $record) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1593 }
eef868d1 1594
6e4dc10f 1595}
1596
1597class admin_setting_sitesettext extends admin_setting_configtext {
1598
1599 var $id;
1600
50999a0b 1601 function admin_setting_sitesettext($name, $visiblename, $description, $defaultsetting, $paramtype=PARAM_RAW) {
6e4dc10f 1602
1603 $this->id = SITEID;
1604 parent::admin_setting_configtext($name, $visiblename, $description, $defaultsetting, $paramtype);
eef868d1 1605
6e4dc10f 1606 }
eef868d1 1607
6e4dc10f 1608 function get_setting() {
1609 $site = get_site();
1610 return (isset($site->{$this->name}) ? $site->{$this->name} : NULL);
1611 }
90cfbd0a 1612
6e4dc10f 1613 function write_setting($data) {
90cfbd0a 1614 if (is_string($this->paramtype)) {
1615 if (!$this->validate($data)) {
1616 return get_string('validateerror', 'admin') . $this->visiblename . '<br />';
1617 }
1618 } else {
1619 $data = clean_param($data, $this->paramtype);
1620 }
eef868d1 1621
6e4dc10f 1622 $record = new stdClass();
1623 $record->id = $this->id;
90cfbd0a 1624 $record->{$this->name} = $data;
6e4dc10f 1625 $record->timemodified = time();
1626 return (update_record('course', $record) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1627 }
90cfbd0a 1628
1629 function validate($data) {
1630 return preg_match($this->paramtype, $data);
1631 }
eef868d1 1632
6e4dc10f 1633}
1634
1635class admin_setting_special_frontpagedesc extends admin_setting {
1636
1637 var $id;
eef868d1 1638
6e4dc10f 1639 function admin_setting_special_frontpagedesc() {
1640 $this->id = SITEID;
1641 $name = 'summary';
1642 $visiblename = get_string('frontpagedescription');
1643 $description = get_string('frontpagedescriptionhelp');
1644 parent::admin_setting($name, $visiblename, $description, '');
1645 }
1646
1647 function output_html() {
eef868d1 1648
cc73de71 1649 if ($this->get_setting() === NULL) {
1650 $currentsetting = $this->defaultsetting;
1651 } else {
1652 $currentsetting = $this->get_setting();
1653 }
eef868d1 1654
6e4dc10f 1655 $usehtmleditor = can_use_html_editor();
eef868d1 1656
6e4dc10f 1657 $return = '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td>' .
1658 '<td>';
eef868d1 1659
6e4dc10f 1660 ob_start(); // double-check the number of columns below... might overrun some screen resolutions
1c1e7af4 1661 print_textarea($usehtmleditor, 15, 60, 0, 0, 's_' . $this->name, $currentsetting);
eef868d1 1662
6e4dc10f 1663 if ($usehtmleditor) {
1664 use_html_editor();
eef868d1 1665 }
6e4dc10f 1666 $return .= ob_get_contents();
eef868d1 1667 ob_end_clean();
6e4dc10f 1668 $return .= '</td></tr><tr><td>&nbsp;</td><td>' . $this->description . '</td></tr>';
1669 return $return;
eef868d1 1670
6e4dc10f 1671 }
eef868d1 1672
6e4dc10f 1673 function get_setting() {
eef868d1 1674
6e4dc10f 1675 $site = get_site();
1676 return (isset($site->{$this->name}) ? $site->{$this->name} : NULL);
eef868d1 1677
6e4dc10f 1678 }
eef868d1 1679
6e4dc10f 1680 function write_setting($data) {
eef868d1 1681
6e4dc10f 1682 $data = addslashes(clean_param($data, PARAM_CLEANHTML));
eef868d1 1683
6e4dc10f 1684 $record = new stdClass();
1685 $record->id = $this->id;
1686 $temp = $this->name;
1687 $record->$temp = $data;
1688 $record->timemodified = time();
eef868d1 1689
6e4dc10f 1690 return(update_record('course', $record) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
eef868d1 1691
6e4dc10f 1692 }
1693
1694}
1695
1696
1697class admin_setting_special_editorfontlist extends admin_setting {
1698
1699 var $items;
1700
1701 function admin_setting_special_editorfontlist() {
1702 global $CFG;
1703 $name = 'editorfontlist';
1704 $visiblename = get_string('editorfontlist', 'admin');
1705 $description = get_string('configeditorfontlist', 'admin');
6e4dc10f 1706 $defaults = array('k0' => 'Trebuchet',
1707 'v0' => 'Trebuchet MS,Verdana,Arial,Helvetica,sans-serif',
1708 'k1' => 'Arial',
1709 'v1' => 'arial,helvetica,sans-serif',
1710 'k2' => 'Courier New',
1711 'v2' => 'courier new,courier,monospace',
1712 'k3' => 'Georgia',
1713 'v3' => 'georgia,times new roman,times,serif',
1714 'k4' => 'Tahoma',
1715 'v4' => 'tahoma,arial,helvetica,sans-serif',
1716 'k5' => 'Times New Roman',
1717 'v5' => 'times new roman,times,serif',
1718 'k6' => 'Verdana',
1719 'v6' => 'verdana,arial,helvetica,sans-serif',
1720 'k7' => 'Impact',
1721 'v7' => 'impact',
1722 'k8' => 'Wingdings',
1723 'v8' => 'wingdings');
1724 parent::admin_setting($name, $visiblename, $description, $defaults);
1725 }
eef868d1 1726
6e4dc10f 1727 function get_setting() {
cc73de71 1728 global $CFG;
1729 if (isset($CFG->editorfontlist)) {
1730 $i = 0;
1731 $currentsetting = array();
1732 $items = explode(';', $CFG->editorfontlist);
1733 foreach ($items as $item) {
1734 $item = explode(':', $item);
1735 $currentsetting['k' . $i] = $item[0];
1736 $currentsetting['v' . $i] = $item[1];
1737 $i++;
1738 }
1739 return $currentsetting;
1740 } else {
1741 return NULL;
1742 }
6e4dc10f 1743 }
eef868d1 1744
6e4dc10f 1745 function write_setting($data) {
eef868d1 1746
6e4dc10f 1747 // there miiight be an easier way to do this :)
1748 // if this is changed, make sure the $defaults array above is modified so that this
1749 // function processes it correctly
eef868d1 1750
6e4dc10f 1751 $keys = array();
1752 $values = array();
eef868d1 1753
6e4dc10f 1754 foreach ($data as $key => $value) {
1755 if (substr($key,0,1) == 'k') {
1756 $keys[substr($key,1)] = $value;
1757 } elseif (substr($key,0,1) == 'v') {
1758 $values[substr($key,1)] = $value;
1759 }
1760 }
eef868d1 1761
6e4dc10f 1762 $result = '';
1763 for ($i = 0; $i < count($keys); $i++) {
1764 if (($keys[$i] !== '') && ($values[$i] !== '')) {
1765 $result .= clean_param($keys[$i],PARAM_NOTAGS) . ':' . clean_param($values[$i], PARAM_NOTAGS) . ';';
1766 }
1767 }
eef868d1 1768
6e4dc10f 1769 $result = substr($result, 0, -1); // trim the last semicolon
eef868d1 1770
6e4dc10f 1771 return (set_config($this->name, $result) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1772 }
eef868d1 1773
6e4dc10f 1774 function output_html() {
eef868d1 1775
cc73de71 1776 if ($this->get_setting() === NULL) {
1777 $currentsetting = $this->defaultsetting;
1778 } else {
1779 $currentsetting = $this->get_setting();
6e4dc10f 1780 }
eef868d1 1781
cc73de71 1782 $return = '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td><td align="left">';
1783 for ($i = 0; $i < count($currentsetting) / 2; $i++) {
1784 $return .= '<input type="text" name="s_editorfontlist[k' . $i . ']" value="' . $currentsetting['k' . $i] . '" size="20" />';
6e4dc10f 1785 $return .= '&nbsp;&nbsp;';
cc73de71 1786 $return .= '<input type="text" name="s_editorfontlist[v' . $i . ']" value="' . $currentsetting['v' . $i] . '" size="40" /><br />';
6e4dc10f 1787 }
cc73de71 1788 $return .= '<input type="text" name="s_editorfontlist[k' . $i . ']" value="" size="20" />';
6e4dc10f 1789 $return .= '&nbsp;&nbsp;';
cc73de71 1790 $return .= '<input type="text" name="s_editorfontlist[v' . $i . ']" value="" size="40" /><br />';
1791 $return .= '<input type="text" name="s_editorfontlist[k' . ($i + 1) . ']" value="" size="20" />';
6e4dc10f 1792 $return .= '&nbsp;&nbsp;';
cc73de71 1793 $return .= '<input type="text" name="s_editorfontlist[v' . ($i + 1) . ']" value="" size="40" />';
eef868d1 1794 $return .= '</td></tr><tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
6e4dc10f 1795 return $return;
1796 }
eef868d1 1797
6e4dc10f 1798}
1799
1800class admin_setting_special_editordictionary extends admin_setting_configselect {
1801
1802 function admin_setting_special_editordictionary() {
1803 $name = 'editordictionary';
1804 $visiblename = get_string('editordictionary','admin');
1805 $description = get_string('configeditordictionary', 'admin');
1806 $choices = $this->editor_get_dictionaries();
1807 if (! is_array($choices)) {
1808 $choices = array('');
1809 }
eef868d1 1810
6e4dc10f 1811 parent::admin_setting_configselect($name, $visiblename, $description, '', $choices);
1812 }
1813
1814 // function borrowed from the old moodle/admin/editor.php, slightly modified
1815 function editor_get_dictionaries () {
1816 /// Get all installed dictionaries in the system
1817
1818 global $CFG;
eef868d1 1819
6e4dc10f 1820// error_reporting(E_ALL); // for debug, final version shouldn't have this...
1821 clearstatcache();
1822
1823 // If aspellpath isn't set don't even bother ;-)
1824 if (empty($CFG->aspellpath)) {
1825 return 'Empty aspell path!';
1826 }
1827
1828 // Do we have access to popen function?
1829 if (!function_exists('popen')) {
1830 return 'Popen function disabled!';
1831 }
eef868d1 1832
6e4dc10f 1833 $cmd = $CFG->aspellpath;
1834 $output = '';
1835 $dictionaries = array();
1836 $dicts = array();
1837
1838 if(!($handle = @popen(escapeshellarg($cmd) .' dump dicts', 'r'))) {
1839 return 'Couldn\'t create handle!';
1840 }
1841
1842 while(!feof($handle)) {
1843 $output .= fread($handle, 1024);
1844 }
1845 @pclose($handle);
1846
1847 $dictionaries = explode(chr(10), $output);
1848
1849 // Get rid of possible empty values
1850 if (is_array($dictionaries)) {
1851
1852 $cnt = count($dictionaries);
1853
1854 for ($i = 0; $i < $cnt; $i++) {
1855 if (!empty($dictionaries[$i])) {
1856 $dicts[] = $dictionaries[$i];
1857 }
1858 }
1859 }
1860
1861 if (count($dicts) >= 1) {
1862 return $dicts;
1863 }
1864
1865 return 'Error! Check your aspell installation!';
1866 }
1867
eef868d1 1868
6e4dc10f 1869
1870}
1871
1872
1873class admin_setting_special_editorhidebuttons extends admin_setting {
1874
1875 var $name;
1876 var $visiblename;
1877 var $description;
1878 var $items;
1879
1880 function admin_setting_special_editorhidebuttons() {
1881 $this->name = 'editorhidebuttons';
1882 $this->visiblename = get_string('editorhidebuttons', 'admin');
1883 $this->description = get_string('confeditorhidebuttons', 'admin');
1884 $this->defaultsetting = array();
1885 // weird array... buttonname => buttonimage (assume proper path appended). if you leave buttomimage blank, text will be printed instead
1886 $this->items = array('fontname' => '',
1887 'fontsize' => '',
1888 'formatblock' => '',
1889 'bold' => 'ed_format_bold.gif',
1890 'italic' => 'ed_format_italic.gif',
1891 'underline' => 'ed_format_underline.gif',
1892 'strikethrough' => 'ed_format_strike.gif',
1893 'subscript' => 'ed_format_sub.gif',
1894 'superscript' => 'ed_format_sup.gif',
1895 'copy' => 'ed_copy.gif',
1896 'cut' => 'ed_cut.gif',
1897 'paste' => 'ed_paste.gif',
1898 'clean' => 'ed_wordclean.gif',
1899 'undo' => 'ed_undo.gif',
1900 'redo' => 'ed_redo.gif',
1901 'justifyleft' => 'ed_align_left.gif',
1902 'justifycenter' => 'ed_align_center.gif',
1903 'justifyright' => 'ed_align_right.gif',
1904 'justifyfull' => 'ed_align_justify.gif',
1905 'lefttoright' => 'ed_left_to_right.gif',
1906 'righttoleft' => 'ed_right_to_left.gif',
1907 'insertorderedlist' => 'ed_list_num.gif',
1908 'insertunorderedlist' => 'ed_list_bullet.gif',
1909 'outdent' => 'ed_indent_less.gif',
1910 'indent' => 'ed_indent_more.gif',
1911 'forecolor' => 'ed_color_fg.gif',
1912 'hilitecolor' => 'ed_color_bg.gif',
1913 'inserthorizontalrule' => 'ed_hr.gif',
1914 'createanchor' => 'ed_anchor.gif',
1915 'createlink' => 'ed_link.gif',
1916 'unlink' => 'ed_unlink.gif',
1917 'insertimage' => 'ed_image.gif',
1918 'inserttable' => 'insert_table.gif',
1919 'insertsmile' => 'em.icon.smile.gif',
1920 'insertchar' => 'icon_ins_char.gif',
1921 'spellcheck' => 'spell-check.gif',
1922 'htmlmode' => 'ed_html.gif',
1923 'popupeditor' => 'fullscreen_maximize.gif',
1924 'search_replace' => 'ed_replace.gif');
1925 }
1926
1927 function get_setting() {
1928 global $CFG;
1929 return (isset($CFG->{$this->name}) ? explode(' ', $CFG->{$this->name}) : NULL);
1930 }
1931
1932 function write_setting($data) {
1933 $result = array();
1934 if (empty($data)) { $data = array(); }
1935 foreach ($data as $key => $value) {
1936 if (!in_array($key, array_keys($this->items))) {
1937 return get_string('errorsetting', 'admin') . $this->visiblename . '<br />';
1938 }
1939 if ($value == '1') {
1940 $result[] = $key;
1941 }
1942 }
1943 return (set_config($this->name, implode(' ',$result)) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
1944 }
1945
1946 function output_html() {
eef868d1 1947
6e4dc10f 1948 global $CFG;
eef868d1 1949
6e4dc10f 1950 // checkboxes with input name="$this->name[$key]" value="1"
1951 // we do 15 fields per column
eef868d1 1952
cc73de71 1953 if ($this->get_setting() === NULL) {
1954 $currentsetting = $this->defaultsetting;
1955 } else {
1956 $currentsetting = $this->get_setting();
6e4dc10f 1957 }
eef868d1 1958
6e4dc10f 1959 $return = '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td><td align="left">';
eef868d1 1960
6e4dc10f 1961 $return .= '<table><tr><td valign="top" align="right">';
eef868d1 1962
6e4dc10f 1963 $count = 0;
eef868d1 1964
6e4dc10f 1965 foreach($this->items as $key => $value) {
1966 if ($count % 15 == 0) {
1967 $return .= '</div></td><td valign="top" align="right">';
1968 }
eef868d1 1969
6e4dc10f 1970 $return .= ($value == '' ? get_string($key,'editor') : '<img width="18" height="18" src="' . $CFG->wwwroot . '/lib/editor/htmlarea/images/' . $value . '" alt="' . get_string($key,'editor') . '" title="' . get_string($key,'editor') . '" />') . '&nbsp;';
1971 $return .= '<input type="checkbox" value="1" name="s_' . $this->name . '[' . $key . ']"' . (in_array($key,$currentsetting) ? ' checked="checked"' : '') . ' />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
1972 $count++;
1973 if ($count % 15 != 0) {
1974 $return .= '<br /><br />';
1975 }
1976 }
eef868d1 1977
1978 $return .= '</td></tr>';
6e4dc10f 1979 $return .= '</table>';
1980 $return .= '</td></tr><tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
1981
1982 return $return;
1983 }
1984
1985}
1986
1987class admin_setting_backupselect extends admin_setting_configselect {
1988
1989 function admin_setting_backupselect($name, $visiblename, $description, $default, $choices) {
1990 parent::admin_setting_configselect($name, $visiblename, $description, $default, $choices);
1991 }
1992
1993 function get_setting() {
1994 $backup_config = backup_get_config();
1995 return (isset($backup_config->{$this->name}) ? $backup_config->{$this->name} : NULL);
1996 }
eef868d1 1997
6e4dc10f 1998 function write_setting($data) {
1999 // check that what we got was in the original choices
2000 if (! in_array($data, array_keys($this->choices))) {
2001 return get_string('errorsetting', 'admin') . $this->visiblename . '<br />';
2002 }
eef868d1 2003
6e4dc10f 2004 return (backup_set_config($this->name, $data) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
2005 }
2006
2007}
2008
2009class admin_setting_special_backupsaveto extends admin_setting_configtext {
2010
2011 function admin_setting_special_backupsaveto() {
2012 $name = 'backup_sche_destination';
2013 $visiblename = get_string('saveto');
2014 $description = get_string('backupsavetohelp');
2015 parent::admin_setting_configtext($name, $visiblename, $description, '', PARAM_PATH);
2016 }
eef868d1 2017
6e4dc10f 2018 function get_setting() {
2019 $backup_config = backup_get_config();
2020 return (isset($backup_config->{$this->name}) ? $backup_config->{$this->name} : NULL);
2021 }
eef868d1 2022
6e4dc10f 2023 function write_setting($data) {
2024 $data = clean_param($data, PARAM_PATH);
2025 if (!empty($data) and (substr($data,-1) == '/' or substr($data,-1) == '\\')) {
2026 return get_string('pathslasherror') . '<br />';
2027 } else if (!empty($data) and !is_dir($data)) {
2028 return get_string('pathnotexists') . '<br />';
2029 }
2030 return (backup_set_config($this->name, $data) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
2031 }
2032
2033}
2034
2035class admin_setting_backupcheckbox extends admin_setting_configcheckbox {
2036
2037 function admin_setting_backupcheckbox($name, $visiblename, $description, $default) {
2038 parent::admin_setting_configcheckbox($name, $visiblename, $description, $default);
2039 }
2040
2041 function write_setting($data) {
2042 if ($data == '1') {
2043 return (backup_set_config($this->name, 1) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
2044 } else {
2045 return (backup_set_config($this->name, 0) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
2046 }
2047 }
eef868d1 2048
6e4dc10f 2049 function get_setting() {
2050 $backup_config = backup_get_config();
2051 return (isset($backup_config->{$this->name}) ? $backup_config->{$this->name} : NULL);
2052 }
2053
2054}
2055
2056class admin_setting_special_backuptime extends admin_setting_configtime {
2057
2058 function admin_setting_special_backuptime() {
2059 $name = 'backup_sche_hour';
2060 $name2 = 'backup_sche_minute';
2061 $visiblename = get_string('executeat');
2062 $description = get_string('backupexecuteathelp');
2063 $default = array('h' => 0, 'm' => 0);
2064 parent::admin_setting_configtime($name, $name2, $visiblename, $description, $default);
2065 }
eef868d1 2066
6e4dc10f 2067 function get_setting() {
2068 $backup_config = backup_get_config();
9fd9df20 2069 return (isset($backup_config->{$this->name}) && isset($backup_config->{$this->name}) ? array('h'=>$backup_config->{$this->name}, 'm'=>$backup_config->{$this->name2}) : NULL);
6e4dc10f 2070 }
eef868d1 2071
6e4dc10f 2072 function write_setting($data) {
2073 // check that what we got was in the original choices
2074 if (!(in_array($data['h'], array_keys($this->choices)) && in_array($data['m'], array_keys($this->choices2)))) {
2075 return get_string('errorsetting', 'admin') . $this->visiblename . '<br />';
2076 }
eef868d1 2077
2078 return (backup_set_config($this->name, $data['h']) && backup_set_config($this->name2, $data['m']) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
6e4dc10f 2079 }
eef868d1 2080
6e4dc10f 2081}
2082
2083class admin_setting_special_backupdays extends admin_setting {
2084
2085 function admin_setting_special_backupdays() {
2086 $name = 'backup_sche_weekdays';
2087 $visiblename = get_string('schedule');
2088 $description = get_string('backupschedulehelp');
2089 parent::admin_setting($name, $visiblename, $description, array());
2090 }
eef868d1 2091
6e4dc10f 2092 function get_setting() {
2093 $backup_config = backup_get_config();
cc73de71 2094 if (isset($backup_config->{$this->name})) {
2095 $currentsetting = $backup_config->{$this->name};
2096 return array('u' => substr($currentsetting, 0, 1),
2097 'm' => substr($currentsetting, 1, 1),
2098 't' => substr($currentsetting, 2, 1),
2099 'w' => substr($currentsetting, 3, 1),
2100 'r' => substr($currentsetting, 4, 1),
2101 'f' => substr($currentsetting, 5, 1),
2102 's' => substr($currentsetting, 6, 1));
2103 } else {
2104 return NULL;
2105 }
6e4dc10f 2106 }
eef868d1 2107
6e4dc10f 2108 function output_html() {
eef868d1 2109
cc73de71 2110 if ($this->get_setting() === NULL) {
2111 $currentsetting = $this->defaultsetting;
2112 } else {
2113 $currentsetting = $this->get_setting();
6e4dc10f 2114 }
eef868d1 2115
cc73de71 2116 // rewrite for simplicity
eef868d1 2117 $currentsetting = $currentsetting['u'] . $currentsetting['m'] . $currentsetting['t'] . $currentsetting['w'] .
cc73de71 2118 $currentsetting['r'] . $currentsetting['f'] . $currentsetting['s'];
eef868d1 2119
6e4dc10f 2120 return '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td><td align="left">' .
eef868d1 2121 '<table><tr><td><div align="center">&nbsp;&nbsp;' . get_string('sunday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' .
6e4dc10f 2122 get_string('monday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' . get_string('tuesday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' .
2123 get_string('wednesday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' . get_string('thursday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' .
2124 get_string('friday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' . get_string('saturday', 'calendar') . '&nbsp;&nbsp;</div></td></tr><tr>' .
eef868d1 2125 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[u]" value="1" ' . (substr($currentsetting,0,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' .
2126 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[m]" value="1" ' . (substr($currentsetting,1,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' .
2127 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[t]" value="1" ' . (substr($currentsetting,2,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' .
2128 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[w]" value="1" ' . (substr($currentsetting,3,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' .
2129 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[r]" value="1" ' . (substr($currentsetting,4,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' .
2130 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[f]" value="1" ' . (substr($currentsetting,5,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' .
2131 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[s]" value="1" ' . (substr($currentsetting,6,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' .
2132 '</tr></table>' .
6e4dc10f 2133 '</td></tr><tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
eef868d1 2134
6e4dc10f 2135 }
eef868d1 2136
6e4dc10f 2137 // we're using the array trick (see http://ca.php.net/manual/en/faq.html.php#faq.html.arrays) to get the data passed to use without having to modify
2138 // admin_settingpage (note that admin_settingpage only calls write_setting with the data that matches $this->name... so if we have multiple form fields,
2139 // they MUST go into an array named $this->name, or else we won't receive them here
2140 function write_setting($data) {
2141 $week = 'umtwrfs';
2142 $result = array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0);
9fd9df20 2143 if (!empty($data)) {
2144 foreach($data as $key => $value) {
2145 if ($value == '1') {
2146 $result[strpos($week, $key)] = 1;
2147 }
2148 }
6e4dc10f 2149 }
2150 return (backup_set_config($this->name, implode('',$result)) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
2151 }
2152}
2153
ee437bbc 2154class admin_setting_special_debug extends admin_setting_configselect {
6e4dc10f 2155
2156 function admin_setting_special_debug() {
2157 $name = 'debug';
2158 $visiblename = get_string('debug', 'admin');
2159 $description = get_string('configdebug', 'admin');
7eb0b60a 2160 $choices = array( DEBUG_NONE => get_string('debugnone', 'admin'),
2161 DEBUG_MINIMAL => get_string('debugminimal', 'admin'),
2162 DEBUG_NORMAL => get_string('debugnormal', 'admin'),
38d2d43b 2163 DEBUG_ALL => get_string('debugall', 'admin'),
2164 DEBUG_DEVELOPER => get_string('debugdeveloper', 'admin')
ee437bbc 2165 );
2166 parent::admin_setting_configselect($name, $visiblename, $description, '', $choices);
6e4dc10f 2167 }
2168
ee437bbc 2169 function get_setting() {
2170 global $CFG;
cc73de71 2171 if (isset($CFG->debug)) {
cc73de71 2172 return $CFG->debug;
2173 } else {
2174 return NULL;
ee437bbc 2175 }
6e4dc10f 2176 }
2177
ee437bbc 2178 function write_setting($data) {
2179 return (set_config($this->name,$data) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
6e4dc10f 2180 }
2181
2182}
2183
2184
2185class admin_setting_special_calendar_weekend extends admin_setting {
2186
2187 function admin_setting_special_calendar_weekend() {
2188 $name = 'calendar_weekend';
2189 $visiblename = get_string('calendar_weekend', 'admin');
2190 $description = get_string('helpweekenddays', 'admin');
2191 parent::admin_setting($name, $visiblename, $description, array('u' => 1, 's' => 1));
2192 }
2193
2194 function get_setting() {
2195 global $CFG;
2196 if (isset($CFG->{$this->name})) {
2197 $setting = intval($CFG->{$this->name});
2198 return array('u' => $setting & 1, 'm' => $setting & 2, 't' => $setting & 4, 'w' => $setting & 8, 'r' => $setting & 16, 'f' => $setting & 32, 's' => $setting & 64);
2199 } else {
2200 return NULL;
2201 }
2202 }
eef868d1 2203
6e4dc10f 2204 function write_setting($data) {
2205 $week = 'umtwrfs';
2206 $result = array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0);
2207 foreach($data as $key => $value) {
eef868d1 2208 if ($value == '1') {
6e4dc10f 2209 $result[strpos($week, $key)] = 1;
2210 }
2211 }
2212 return (set_config($this->name, bindec(implode('',$result))) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
2213 }
eef868d1 2214
6e4dc10f 2215 function output_html() {
2216
cc73de71 2217 if ($this->get_setting() === NULL) {
2218 $currentsetting = $this->defaultsetting;
2219 } else {
2220 $currentsetting = $this->get_setting();
6e4dc10f 2221 }
cc73de71 2222
6e4dc10f 2223 return '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td><td align="left">' .
eef868d1 2224 '<table><tr><td><div align="center">&nbsp;&nbsp;' . get_string('sunday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' .
6e4dc10f 2225 get_string('monday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' . get_string('tuesday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' .
2226 get_string('wednesday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' . get_string('thursday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' .
2227 get_string('friday', 'calendar') . '&nbsp;&nbsp;</div></td><td><div align="center">&nbsp;&nbsp;' . get_string('saturday', 'calendar') . '&nbsp;&nbsp;</div></td></tr><tr>' .
eef868d1 2228 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[u]" value="1" ' . ($currentsetting['u'] ? 'checked="checked"' : '') . ' /></div></td>' .
2229 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[m]" value="1" ' . ($currentsetting['m'] ? 'checked="checked"' : '') . ' /></div></td>' .
2230 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[t]" value="1" ' . ($currentsetting['t'] ? 'checked="checked"' : '') . ' /></div></td>' .
2231 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[w]" value="1" ' . ($currentsetting['w'] ? 'checked="checked"' : '') . ' /></div></td>' .
2232 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[r]" value="1" ' . ($currentsetting['r'] ? 'checked="checked"' : '') . ' /></div></td>' .
2233 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[f]" value="1" ' . ($currentsetting['f'] ? 'checked="checked"' : '') . ' /></div></td>' .
2234 '<td><div align="center"><input type="checkbox" name="s_'. $this->name .'[s]" value="1" ' . ($currentsetting['s'] ? 'checked="checked"' : '') . ' /></div></td>' .
2235 '</tr></table>' .
6e4dc10f 2236 '</td></tr><tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
eef868d1 2237
6e4dc10f 2238 }
2239
2240}
2241
2242
2243class admin_setting_special_perfdebug extends admin_setting_configcheckbox {
2244
2245 function admin_setting_special_perfdebug() {
2246 $name = 'perfdebug';
2247 $visiblename = get_string('perfdebug', 'admin');
2248 $description = get_string('configperfdebug', 'admin');
2249 parent::admin_setting_configcheckbox($name, $visiblename, $description, '');
2250 }
2251
2252 function write_setting($data) {
2253 if ($data == '1') {
2254 return (set_config($this->name,15) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
2255 } else {
2256 return (set_config($this->name,7) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />');
2257 }
2258 }
2259
2260 function output_html() {
cc73de71 2261 if ($this->get_setting() === NULL) {
2262 $currentsetting = $this->defaultsetting;
2263 } else {
2264 $currentsetting = $this->get_setting();
2265 }
eef868d1 2266
6e4dc10f 2267 return '<tr><td width="100" align="right" valign="top">' . $this->visiblename . '</td>' .
cc73de71 2268 '<td align="left"><input type="checkbox" size="50" name="s_'. $this->name .'" value="1" ' . ($currentsetting == 15 ? 'checked="checked"' : '') . ' /></td></tr>' .
6e4dc10f 2269 '<tr><td>&nbsp;</td><td align="left">' . $this->description . '</td></tr>';
2270 }
2271
2272}
2273
2274// Code for a function that helps externalpages print proper headers and footers
2275// N.B.: THIS FUNCTION HANDLES AUTHENTICATION
2276function admin_externalpage_setup($section, $adminroot) {
2277
2278 global $CFG, $PAGE, $USER;
eef868d1 2279
6e4dc10f 2280 require_once($CFG->libdir . '/blocklib.php');
02cc05a7 2281 require_once($CFG->dirroot . '/'.$CFG->admin.'/pagelib.php');
eef868d1 2282
02cc05a7 2283 page_map_class(PAGE_ADMIN, 'page_admin');
6e4dc10f 2284
e9a20759 2285 $PAGE = page_create_object(PAGE_ADMIN, 0); // there must be any constant id number
6e4dc10f 2286
02cc05a7 2287 $PAGE->init_extra($section); // hack alert!
6e4dc10f 2288
2289 $root = $adminroot->locate($PAGE->section);
2290
2291 if ($site = get_site()) {
2292 require_login();
2293 } else {
2294 redirect($CFG->wwwroot . '/admin/index.php');
2295 die;
2296 }
2297
2298 if (!is_a($root, 'admin_externalpage')) {
2299 error(get_string('sectionerror','admin'));
2300 die;
2301 }
2302
2303 // this eliminates our need to authenticate on the actual pages
2304 if (!($root->check_access())) {
2305 error(get_string('accessdenied', 'admin'));
2306 die;
2307 }
eef868d1 2308
6e4dc10f 2309 $adminediting = optional_param('adminedit', -1, PARAM_BOOL);
eef868d1 2310
6e4dc10f 2311 if (!isset($USER->adminediting)) {
2312 $USER->adminediting = false;
2313 }
eef868d1 2314
6e4dc10f 2315 if ($PAGE->user_allowed_editing()) {
2316 if ($adminediting == 1) {
2317 $USER->adminediting = true;
2318 } elseif ($adminediting == 0) {
2319 $USER->adminediting = false;
2320 }
2321 }
eef868d1 2322
6e4dc10f 2323}
2324
2325function admin_externalpage_print_header($adminroot) {
2326
b1ce7811 2327 global $CFG, $PAGE, $SITE;
eef868d1 2328
b1ce7811 2329 if (!empty($SITE->fullname)) {
2330 $pageblocks = blocks_setup($PAGE);
6e4dc10f 2331
eef868d1 2332 $preferred_width_left = bounded_number(BLOCK_L_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]),
b1ce7811 2333 BLOCK_L_MAX_WIDTH);
eef868d1 2334
b1ce7811 2335 $PAGE->print_header();
2336 echo '<table id="layout-table"><tr>';
2337 echo '<td style="width: ' . $preferred_width_left . 'px;" id="left-column">';
2338 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT);
2339 echo '</td>';
2340 echo '<td id="middle-column" width="*">';
2341 } else {
2342 print_header();
2343 }
6e4dc10f 2344
2345}
2346
2347function admin_externalpage_print_footer($adminroot) {
2348
b1ce7811 2349 global $CFG, $PAGE, $SITE;
2350
2351 if (!empty($SITE->fullname)) {
2352 $pageblocks = blocks_setup($PAGE);
2353 $preferred_width_right = bounded_number(BLOCK_R_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]),
2354 BLOCK_R_MAX_WIDTH);
2355 echo '</td>';
2356 echo '<td style="width: ' . $preferred_width_right . 'px;" id="right-column">';
2357 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT);
2358 echo '</td></tr></table>';
2359 }
2360
6e4dc10f 2361 print_footer();
6e4dc10f 2362}
2363
2364function admin_get_root() {
2365 global $CFG;
2366
2367 static $ADMIN;
2368
2369 if (!isset($ADMIN)) {
2370 // start the admin tree!
2371 $ADMIN = new admin_category('root','Administration');
2372 // we process this file first to get categories up and running
50999a0b 2373 include($CFG->dirroot . '/admin/settings/top.php');
6e4dc10f 2374
2375 // now we process all other files in admin/settings to build the
2376 // admin tree
2377 foreach (glob($CFG->dirroot . '/admin/settings/*.php') as $file) {
50999a0b 2378 if ($file != $CFG->dirroot . '/admin/settings/top.php') {
6e4dc10f 2379 include_once($file);
2380 }
2381 }
2382 }
eef868d1 2383
6e4dc10f 2384 return $ADMIN;
2385}
2386
2387/// settings utiliti functions
2388
2389// n.b. this function unconditionally applies default settings
2390function apply_default_settings(&$node) {
2391
2392 global $CFG;
2393
2394 if (is_a($node, 'admin_category')) {
2395 $entries = array_keys($node->children);
2396 foreach ($entries as $entry) {
2397 apply_default_settings($node->children[$entry]);
2398 }
2399 return;
eef868d1 2400 }
6e4dc10f 2401
eef868d1 2402 if (is_a($node, 'admin_settingpage')) {
6e4dc10f 2403 foreach ($node->settings as $setting) {
2404 $CFG->{$setting->name} = $setting->defaultsetting;
2405 $setting->write_setting($setting->defaultsetting);
2406 unset($setting); // needed to prevent odd (imho) reference behaviour
2407 // see http://www.php.net/manual/en/language.references.whatdo.php#AEN6399
2408 }
2409 return;
2410 }
2411
2412 return;
2413
2414}
2415
2416// n.b. this function unconditionally applies default settings
2417function apply_default_exception_settings($defaults) {
2418
2419 global $CFG;
2420
2421 foreach($defaults as $key => $value) {
2422 $CFG->$key = $value;
2423 set_config($key, $value);
2424 }
2425
2426}
2427
2c8766df 2428function format_admin_setting($name, $title='', $form='', $description='') {
2429 $output = '<div class="adminsetting">';
2430 $output .= 'etc';
2431 $output .= '</div>';
2432
2433 return $output;
2434}
2435
38d2d43b 2436?>