Submit buttons (ccsubmit, echecksubmit) are no longer used. Hidden field paymentmetho...
[moodle.git] / lib / adminlib.php
CommitLineData
88a7228a 1<?php //
2 //
3
4/**
5 * adminlib.php - Contains functions that only administrators will ever need to use
6 *
7 * @author Martin Dougiamas
8 * @version $Id$
9 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
10 * @package moodlecore
11 */
12
13/**
ead29342 14 * Upgrade plugins
88a7228a 15 *
16 * @uses $db
17 * @uses $CFG
ead29342 18 * @param string $type The type of plugins that should be updated (e.g. 'enrol', 'qtype')
19 * @param string $dir The directory where the plugins are located (e.g. 'question/questiontypes')
20 * @param string $return The url to prompt the user to continue to
88a7228a 21 */
ead29342 22function upgrade_plugins($type, $dir, $return) {
e69ef14b 23 global $CFG, $db;
173cc1c3 24
ead29342 25 if (!$plugs = get_list_of_plugins($dir) ) {
26 error('No '.$type.' plugins installed!');
173cc1c3 27 }
28
583fad99 29 $updated_plugins = false;
30 $strpluginsetup = get_string('pluginsetup');
31
ead29342 32 foreach ($plugs as $plug) {
173cc1c3 33
ead29342 34 $fullplug = $CFG->dirroot .'/'.$dir.'/'. $plug;
173cc1c3 35
ead29342 36 unset($plugin);
173cc1c3 37
bbbf2d40 38 if (is_readable($fullplug .'/version.php')) {
ead29342 39 include_once($fullplug .'/version.php'); // defines $plugin with version etc
173cc1c3 40 } else {
41 continue; // Nothing to do.
42 }
43
e79a09a2 44 $oldupgrade = false;
45 $newupgrade = false;
7c006e34 46 if (is_readable($fullplug . '/db/'. $CFG->dbtype . '.php')) {
47 include_once($fullplug . '/db/'. $CFG->dbtype . '.php'); // defines old upgrading function
e79a09a2 48 $oldupgrade = true;
49 }
7c006e34 50 if (is_readable($fullplug . '/db/upgrade.php') && $CFG->xmldb_enabled) {
51 include_once($fullplug . '/db/upgrade.php'); // defines new upgrading function
e79a09a2 52 $newupgrade = true;
53 }
54
ead29342 55 if (!isset($plugin)) {
173cc1c3 56 continue;
57 }
58
ead29342 59 if (!empty($plugin->requires)) {
60 if ($plugin->requires > $CFG->version) {
61 $info->pluginname = $plug;
62 $info->pluginversion = $plugin->version;
173cc1c3 63 $info->currentmoodle = $CFG->version;
ead29342 64 $info->requiremoodle = $plugin->requires;
583fad99 65 if (!$updated_plugins) {
66 print_header($strpluginsetup, $strpluginsetup, $strpluginsetup, '',
67 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
68 false, '&nbsp;', '&nbsp;');
69 }
70 upgrade_log_start();
ead29342 71 notify(get_string('pluginrequirementsnotmet', 'error', $info));
583fad99 72 $updated_plugins = true;
173cc1c3 73 unset($info);
74 continue;
75 }
76 }
77
ead29342 78 $plugin->name = $plug; // The name MUST match the directory
173cc1c3 79
ead29342 80 $pluginversion = $type.'_'.$plug.'_version';
173cc1c3 81
ead29342 82 if (!isset($CFG->$pluginversion)) {
83 set_config($pluginversion, 0);
173cc1c3 84 }
85
ead29342 86 if ($CFG->$pluginversion == $plugin->version) {
173cc1c3 87 // do nothing
ead29342 88 } else if ($CFG->$pluginversion < $plugin->version) {
583fad99 89 if (!$updated_plugins) {
a36f058e 90 print_header($strpluginsetup, $strpluginsetup, $strpluginsetup, '',
91 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
92 false, '&nbsp;', '&nbsp;');
173cc1c3 93 }
e79a09a2 94 $updated_plugins = true;
583fad99 95 upgrade_log_start();
ead29342 96 print_heading($plugin->name .' plugin needs upgrading');
e79a09a2 97 $db->debug = true;
98 @set_time_limit(0); // To allow slow databases to complete the long SQL
99
d87a9d73 100 if ($CFG->$pluginversion == 0) { // It's a new install of this plugin
e79a09a2 101 /// Both old .sql files and new install.xml are supported
102 /// but we priorize install.xml (XMLDB) if present
103 $status = false;
450cf307 104 if (file_exists($fullplug . '/db/install.xml') && $CFG->xmldb_enabled) {
105 $status = install_from_xmldb_file($fullplug . '/db/install.xml'); //New method
e79a09a2 106 } else if (file_exists($fullplug .'/db/'. $CFG->dbtype .'.sql')) {
107 $status = modify_database($fullplug .'/db/'. $CFG->dbtype .'.sql'); //Old method
7c006e34 108 } else {
109 $status = true;
d87a9d73 110 }
e79a09a2 111
112 $db->debug = false;
113 /// Continue with the instalation, roles and other stuff
114 if ($status) {
115 // OK so far, now update the plugins record
116 set_config($pluginversion, $plugin->version);
117 if (!update_capabilities($dir.'/'.$plug)) {
118 error('Could not set up the capabilities for '.$module->name.'!');
119 }
120 notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess');
121 } else {
122 notify('Installing '. $plugin->name .' FAILED!');
123 }
d87a9d73 124 } else { // Upgrade existing install
e79a09a2 125 /// Run de old and new upgrade functions for the module
126 $oldupgrade_function = $type.'_'.$plugin->name .'_upgrade';
127 $newupgrade_function = 'xmldb_' . $type.'_'.$plugin->name .'_upgrade';
128
129 /// First, the old function if exists
130 $oldupgrade_status = true;
131 if ($oldupgrade && function_exists($oldupgrade_function)) {
132 $db->debug = true;
133 $oldupgrade_status = $oldupgrade_function($CFG->$pluginversion);
134 } else if ($oldupgrade) {
135 notify ('Upgrade function ' . $oldupgrade_function . ' was not available in ' .
136 $fullplug . '/db/' . $CFG->dbtype . '.php');
137 }
138
139 /// Then, the new function if exists and the old one was ok
140 $newupgrade_status = true;
141 if ($newupgrade && function_exists($newupgrade_function) && $oldupgrade_status) {
142 $db->debug = true;
143 $newupgrade_status = $newupgrade_function($CFG->$pluginversion);
144 } else if ($newupgrade) {
145 notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' .
146 $fullplug . '/db/upgrade.php');
147 }
148
149 $db->debug=false;
150 /// Now analyze upgrade results
151 if ($oldupgrade_status && $newupgrade_status) { // No upgrading failed
152 // OK so far, now update the plugins record
153 set_config($pluginversion, $plugin->version);
154 if (!update_capabilities($dir.'/'.$plug)) {
155 error('Could not update '.$plugin->name.' capabilities!');
d87a9d73 156 }
e79a09a2 157 notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess');
158 } else {
159 notify('Upgrading '. $plugin->name .' from '. $CFG->$pluginversion .' to '. $plugin->version .' FAILED!');
173cc1c3 160 }
161 }
d87a9d73 162 echo '<hr />';
173cc1c3 163 } else {
583fad99 164 upgrade_log_start();
ead29342 165 error('Version mismatch: '. $plugin->name .' can\'t downgrade '. $CFG->$pluginversion .' -> '. $plugin->version .' !');
173cc1c3 166 }
167 }
168
583fad99 169 upgrade_log_finish();
170
171 if ($updated_plugins) {
173cc1c3 172 print_continue($return);
173 die;
174 }
175}
176
88a7228a 177/**
178 * Find and check all modules and load them up or upgrade them if necessary
179 *
180 * @uses $db
181 * @uses $CFG
182 * @param string $return The url to prompt the user to continue to
183 * @todo Finish documenting this function
184 */
173cc1c3 185function upgrade_activity_modules($return) {
173cc1c3 186
e69ef14b 187 global $CFG, $db;
173cc1c3 188
88a7228a 189 if (!$mods = get_list_of_plugins('mod') ) {
190 error('No modules installed!');
173cc1c3 191 }
192
583fad99 193 $updated_modules = false;
194 $strmodulesetup = get_string('modulesetup');
195
173cc1c3 196 foreach ($mods as $mod) {
197
88a7228a 198 if ($mod == 'NEWMODULE') { // Someone has unzipped the template, ignore it
173cc1c3 199 continue;
200 }
201
88a7228a 202 $fullmod = $CFG->dirroot .'/mod/'. $mod;
173cc1c3 203
204 unset($module);
205
88a7228a 206 if ( is_readable($fullmod .'/version.php')) {
207 include_once($fullmod .'/version.php'); // defines $module with version etc
173cc1c3 208 } else {
88a7228a 209 notify('Module '. $mod .': '. $fullmod .'/version.php was not readable');
173cc1c3 210 continue;
211 }
212
d6eb06b6 213 $oldupgrade = false;
214 $newupgrade = false;
7c006e34 215 if ( is_readable($fullmod .'/db/' . $CFG->dbtype . '.php')) {
216 include_once($fullmod .'/db/' . $CFG->dbtype . '.php'); // defines old upgrading function
d6eb06b6 217 $oldupgrade = true;
218 }
7c006e34 219 if ( is_readable($fullmod . '/db/upgrade.php') && $CFG->xmldb_enabled) {
220 include_once($fullmod . '/db/upgrade.php'); // defines new upgrading function
d6eb06b6 221 $newupgrade = true;
173cc1c3 222 }
223
224 if (!isset($module)) {
225 continue;
226 }
227
228 if (!empty($module->requires)) {
229 if ($module->requires > $CFG->version) {
230 $info->modulename = $mod;
231 $info->moduleversion = $module->version;
232 $info->currentmoodle = $CFG->version;
233 $info->requiremoodle = $module->requires;
583fad99 234 if (!$updated_modules) {
235 print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '',
236 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
237 false, '&nbsp;', '&nbsp;');
238 }
239 upgrade_log_start();
173cc1c3 240 notify(get_string('modulerequirementsnotmet', 'error', $info));
583fad99 241 $updated_modules = true;
173cc1c3 242 unset($info);
243 continue;
244 }
245 }
246
247 $module->name = $mod; // The name MUST match the directory
248
88a7228a 249 if ($currmodule = get_record('modules', 'name', $module->name)) {
173cc1c3 250 if ($currmodule->version == $module->version) {
251 // do nothing
252 } else if ($currmodule->version < $module->version) {
d6eb06b6 253 /// If versions say that we need to upgrade but no upgrade files are available, notify and continue
254 if (!$oldupgrade && !$newupgrade) {
255 notify('Upgrade files ' . $mod . ': ' . $fullmod . '/db/' . $CFG->dbtype . '.php or ' .
256 $fullmod . '/db/upgrade.php were not readable');
257 continue;
258 }
583fad99 259 if (!$updated_modules) {
a36f058e 260 print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '',
261 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
262 false, '&nbsp;', '&nbsp;');
173cc1c3 263 }
583fad99 264 upgrade_log_start();
88a7228a 265 print_heading($module->name .' module needs upgrading');
d6eb06b6 266
267 /// Run de old and new upgrade functions for the module
268 $oldupgrade_function = $module->name . '_upgrade';
269 $newupgrade_function = 'xmldb_' . $module->name . '_upgrade';
270
271 /// First, the old function if exists
272 $oldupgrade_status = true;
273 if ($oldupgrade && function_exists($oldupgrade_function)) {
274 $db->debug = true;
275 $oldupgrade_status = $oldupgrade_function($currmodule->version, $module);
ba05965e 276 } else if ($oldupgrade) {
d6eb06b6 277 notify ('Upgrade function ' . $oldupgrade_function . ' was not available in ' .
278 $mod . ': ' . $fullmod . '/db/' . $CFG->dbtype . '.php');
d6eb06b6 279 }
280
281 /// Then, the new function if exists and the old one was ok
282 $newupgrade_status = true;
ba05965e 283 if ($newupgrade && function_exists($newupgrade_function) && $oldupgrade_status) {
d6eb06b6 284 $db->debug = true;
285 $newupgrade_status = $newupgrade_function($currmodule->version, $module);
ba05965e 286 } else if ($newupgrade) {
d6eb06b6 287 notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' .
288 $mod . ': ' . $fullmod . '/db/upgrade.php');
d6eb06b6 289 }
290
e79a09a2 291 $db->debug=false;
d6eb06b6 292 /// Now analyze upgrade results
668896e5 293 if ($oldupgrade_status && $newupgrade_status) { // No upgrading failed
d6eb06b6 294 // OK so far, now update the modules record
295 $module->id = $currmodule->id;
296 if (! update_record('modules', $module)) {
297 error('Could not update '. $module->name .' record in modules table!');
173cc1c3 298 }
d6eb06b6 299 remove_dir($CFG->dataroot . '/cache', true); // flush cache
300 notify(get_string('modulesuccess', '', $module->name), 'notifysuccess');
301 echo '<hr />';
302 } else {
d6eb06b6 303 notify('Upgrading '. $module->name .' from '. $currmodule->version .' to '. $module->version .' FAILED!');
173cc1c3 304 }
bbbf2d40 305
d6eb06b6 306 /// Update the capabilities table?
bbbf2d40 307 if (!update_capabilities('mod/'.$module->name)) {
308 error('Could not update '.$module->name.' capabilities!');
309 }
310
173cc1c3 311 $updated_modules = true;
bbbf2d40 312
173cc1c3 313 } else {
583fad99 314 upgrade_log_start();
88a7228a 315 error('Version mismatch: '. $module->name .' can\'t downgrade '. $currmodule->version .' -> '. $module->version .' !');
173cc1c3 316 }
317
318 } else { // module not installed yet, so install it
583fad99 319 if (!$updated_modules) {
a36f058e 320 print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '',
321 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
322 false, '&nbsp;', '&nbsp;');
173cc1c3 323 }
583fad99 324 upgrade_log_start();
173cc1c3 325 print_heading($module->name);
326 $updated_modules = true;
327 $db->debug = true;
328 @set_time_limit(0); // To allow slow databases to complete the long SQL
d6eb06b6 329
330 /// Both old .sql files and new install.xml are supported
331 /// but we priorize install.xml (XMLDB) if present
332 if (file_exists($fullmod . '/db/install.xml') && $CFG->xmldb_enabled) {
333 $status = install_from_xmldb_file($fullmod . '/db/install.xml'); //New method
334 } else {
335 $status = modify_database($fullmod .'/db/'. $CFG->dbtype .'.sql'); //Old method
336 }
337
e79a09a2 338 $db->debug = false;
d6eb06b6 339 /// Continue with the instalation, roles and other stuff
340 if ($status) {
88a7228a 341 if ($module->id = insert_record('modules', $module)) {
bbbf2d40 342 if (!update_capabilities('mod/'.$module->name)) {
343 error('Could not set up the capabilities for '.$module->name.'!');
344 }
a8f68426 345 notify(get_string('modulesuccess', '', $module->name), 'notifysuccess');
88a7228a 346 echo '<hr />';
173cc1c3 347 } else {
88a7228a 348 error($module->name .' module could not be added to the module list!');
173cc1c3 349 }
350 } else {
88a7228a 351 error($module->name .' tables could NOT be set up successfully!');
173cc1c3 352 }
353 }
e5bd4e58 354
355 /// Check submodules of this module if necessary
356
357 include_once($fullmod.'/lib.php'); // defines upgrading function
358
359 $submoduleupgrade = $module->name.'_upgrade_submodules';
360 if (function_exists($submoduleupgrade)) {
361 $submoduleupgrade();
362 }
363
364
365 /// Run any defaults or final code that is necessary for this module
366
a5c0990e 367 if ( is_readable($fullmod .'/defaults.php')) {
368 // Insert default values for any important configuration variables
9e6e7502 369 unset($defaults);
a5c0990e 370 include_once($fullmod .'/defaults.php');
f9a2e515 371 if (!empty($defaults)) {
372 foreach ($defaults as $name => $value) {
373 if (!isset($CFG->$name)) {
374 set_config($name, $value);
375 }
a5c0990e 376 }
377 }
378 }
173cc1c3 379 }
380
583fad99 381 upgrade_log_finish(); // finish logging if started
382
383 if ($updated_modules) {
173cc1c3 384 print_continue($return);
136f43dc 385 print_footer();
173cc1c3 386 die;
387 }
388}
389
f3221af9 390/**
391 * This function will return FALSE if the lock fails to be set (ie, if it's already locked)
80be7ee3 392 *
393 * @param string $name ?
394 * @param bool $value ?
395 * @param int $staleafter ?
396 * @param bool $clobberstale ?
397 * @todo Finish documenting this function
f3221af9 398 */
399function set_cron_lock($name,$value=true,$staleafter=7200,$clobberstale=false) {
400
401 if (empty($name)) {
402 mtrace("Tried to get a cron lock for a null fieldname");
403 return false;
404 }
405
406 if (empty($value)) {
407 set_config($name,0);
408 return true;
409 }
410
411 if ($config = get_record('config','name',$name)) {
412 if (empty($config->value)) {
413 set_config($name,time());
414 } else {
415 // check for stale.
416 if ((time() - $staleafter) > $config->value) {
417 mtrace("STALE LOCKFILE FOR $name - was $config->value");
418 if (!empty($clobberstale)) {
419 set_config($name,time());
420 return true;
421 }
422 } else {
423 return false; // was not stale - ie, we're ok to still be running.
424 }
425 }
426 }
427 else {
428 set_config($name,time());
429 }
430 return true;
431}
a597f8a8 432
fb06b255 433function print_progress($done, $total, $updatetime=5, $sleeptime=1, $donetext='') {
a597f8a8 434 static $starttime;
435 static $lasttime;
436
437 if (empty($starttime)) {
438 $starttime = $lasttime = time();
439 $lasttime = $starttime - $updatetime;
440 echo '<table width="500" cellpadding="0" cellspacing="0" align="center"><tr><td width="500">';
441 echo '<div id="bar" style="border-style:solid;border-width:1px;width:500px;height:50px;">';
442 echo '<div id="slider" style="border-style:solid;border-width:1px;height:48px;width:10px;background-color:green;"></div>';
443 echo '</div>';
444 echo '<div id="text" align="center" style="width:500px;"></div>';
445 echo '</td></tr></table>';
446 echo '</div>';
447 }
448
a597f8a8 449 $now = time();
450
451 if ($done && (($now - $lasttime) >= $updatetime)) {
452 $elapsedtime = $now - $starttime;
453 $projectedtime = (int)(((float)$total / (float)$done) * $elapsedtime) - $elapsedtime;
454 $percentage = format_float((float)$done / (float)$total, 2);
455 $width = (int)(500 * $percentage);
456
fb06b255 457 if ($projectedtime > 10) {
458 $projectedtext = ' Ending: '.format_time($projectedtime);
459 } else {
460 $projectedtext = '';
461 }
462
a597f8a8 463 echo '<script>';
fb06b255 464 echo 'document.getElementById("text").innerHTML = "'.addslashes($donetext).' '.$done.' done.'.$projectedtext.'";'."\n";
a597f8a8 465 echo 'document.getElementById("slider").style.width = \''.$width.'px\';'."\n";
466 echo '</script>';
467
468 $lasttime = $now;
469 sleep($sleeptime);
470 }
471}
583fad99 472
473////////////////////////////////////////////////
474/// upgrade logging functions
475////////////////////////////////////////////////
476
477$upgradeloghandle = false;
26c91c73 478$upgradelogbuffer = '';
479// I did not find out how to use static variable in callback function,
480// the problem was that I could not flush the static buffer :-(
481global $upgradeloghandle, $upgradelogbuffer;
583fad99 482
483/**
484 * Check if upgrade is already running.
485 *
486 * If anything goes wrong due to missing call to upgrade_log_finish()
487 * just restart the browser.
488 *
489 * @param string warning message indicating upgrade is already running
490 * @param int page reload timeout
491 */
492function upgrade_check_running($message, $timeout) {
493 if (!empty($_SESSION['upgraderunning'])) {
494 print_header();
495 redirect(me(), $message, $timeout);
496 }
497}
498
499/**
500 * Start logging of output into file (if not disabled) and
501 * prevent aborting and concurrent execution of upgrade script.
502 *
503 * Please note that you can not write into session variables after calling this function!
504 *
505 * This function may be called repeatedly.
506 */
507function upgrade_log_start() {
426a369b 508 global $CFG, $upgradeloghandle;
583fad99 509
510 if (!empty($_SESSION['upgraderunning'])) {
511 return; // logging already started
512 }
513
514 @ignore_user_abort(true); // ignore if user stops or otherwise aborts page loading
515 $_SESSION['upgraderunning'] = 1; // set upgrade indicator
426a369b 516 if (empty($CFG->dbsessions)) { // workaround for bug in adodb, db session can not be restarted
517 session_write_close(); // from now on user can reload page - will be displayed warning
518 }
583fad99 519 make_upload_directory('upgradelogs');
520 ob_start('upgrade_log_callback', 2); // function for logging to disk; flush each line of text ASAP
dedb2304 521 register_shutdown_function('upgrade_log_finish'); // in case somebody forgets to stop logging
583fad99 522}
523
524/**
525 * Terminate logging of output, flush all data, allow script aborting
526 * and reopen session for writing. Function error() does terminate the logging too.
527 *
528 * Please make sure that each upgrade_log_start() is properly terminated by
529 * this function or error().
530 *
531 * This function may be called repeatedly.
532 */
533function upgrade_log_finish() {
426a369b 534 global $CFG, $upgradeloghandle, $upgradelogbuffer;
583fad99 535
536 if (empty($_SESSION['upgraderunning'])) {
537 return; // logging already terminated
538 }
539
540 @ob_end_flush();
26c91c73 541 if ($upgradelogbuffer !== '') {
542 @fwrite($upgradeloghandle, $upgradelogbuffer);
40896537 543 $upgradelogbuffer = '';
26c91c73 544 }
545 if ($upgradeloghandle and ($upgradeloghandle !== 'error')) {
546 @fclose($upgradeloghandle);
40896537 547 $upgradeloghandle = false;
26c91c73 548 }
426a369b 549 if (empty($CFG->dbsessions)) {
550 @session_start(); // ignore header errors, we only need to reopen session
551 }
583fad99 552 $_SESSION['upgraderunning'] = 0; // clear upgrade indicator
553 if (connection_aborted()) {
554 die;
555 }
556 @ignore_user_abort(false);
557}
558
559/**
560 * Callback function for logging into files. Not more than one file is created per minute,
561 * upgrade session (terminated by upgrade_log_finish()) is always stored in one file.
562 *
563 * This function must not output any characters or throw warnigns and errors!
564 */
565function upgrade_log_callback($string) {
26c91c73 566 global $CFG, $upgradeloghandle, $upgradelogbuffer;
583fad99 567
568 if (empty($CFG->disableupgradelogging) and ($string != '') and ($upgradeloghandle !== 'error')) {
569 if ($upgradeloghandle or ($upgradeloghandle = @fopen($CFG->dataroot.'/upgradelogs/upg_'.date('Ymd-Hi').'.html', 'a'))) {
26c91c73 570 $upgradelogbuffer .= $string;
571 if (strlen($upgradelogbuffer) > 2048) { // 2kB write buffer
572 @fwrite($upgradeloghandle, $upgradelogbuffer);
573 $upgradelogbuffer = '';
574 }
583fad99 575 } else {
576 $upgradeloghandle = 'error';
577 }
578 }
579 return $string;
580}
581
57e35f32 582/**
583 * Try to verify that dataroot is not accessible from web.
584 * It is not 100% correct but might help to reduce number of vulnerable sites.
585 *
586 * Protection from httpd.conf and .htaccess is not detected properly.
587 */
588function is_dataroot_insecure() {
589 global $CFG;
590
591 $siteroot = str_replace('\\', '/', strrev($CFG->dirroot.'/')); // win32 backslash workaround
592
593 $rp = preg_replace('|https?://[^/]+|i', '', $CFG->wwwroot, 1);
594 $rp = strrev(trim($rp, '/'));
595 $rp = explode('/', $rp);
596 foreach($rp as $r) {
597 if (strpos($siteroot, '/'.$r.'/') === 0) {
598 $siteroot = substr($siteroot, strlen($r)+1); // moodle web in subdirectory
599 } else {
600 break; // probably alias root
601 }
602 }
603
604 $siteroot = strrev($siteroot);
605 $dataroot = str_replace('\\', '/', $CFG->dataroot.'/');
606
607 if (strpos($dataroot, $siteroot) === 0) {
608 return true;
609 }
610 return false;
611}
9e6e7502 612?>