2009-05-26 03:57:03 +00:00
< ? php
2006-01-05 07:08:10 +00:00
2009-05-26 03:57:03 +00:00
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* These functions are required very early in the Moodle
* setup process , before any of the main libraries are
* loaded .
*
* @ package moodlecore
* @ copyright 1999 onwards Martin Dougiamas { @ link http :// moodle . com }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
2006-01-05 07:08:10 +00:00
2008-01-20 17:59:26 +00:00
/**
* Simple class
2009-05-26 03:57:03 +00:00
*
* @ package moodlecore
* @ copyright 1999 onwards Martin Dougiamas { @ link http :// moodle . com }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2008-01-20 17:59:26 +00:00
*/
class object {};
2008-06-13 17:51:34 +00:00
/**
* Base Moodle Exception class
2009-05-26 03:57:03 +00:00
*
* @ package moodlecore
* @ copyright 1999 onwards Martin Dougiamas { @ link http :// moodle . com }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2008-06-13 17:51:34 +00:00
*/
class moodle_exception extends Exception {
public $errorcode ;
public $module ;
public $a ;
public $link ;
2008-06-22 16:51:55 +00:00
public $debuginfo ;
2008-06-13 17:51:34 +00:00
/**
* Constructor
* @ param string $errorcode The name of the string from error . php to print
* @ param string $module name of module
* @ param string $link The url where the user will be prompted to continue . If no url is provided the user will be directed to the site index page .
* @ param object $a Extra words and phrases that might be required in the error string
2008-06-22 16:51:55 +00:00
* @ param string $debuginfo optional debugging information
2008-06-13 17:51:34 +00:00
*/
2008-09-02 06:03:37 +00:00
function __construct ( $errorcode , $module = '' , $link = '' , $a = NULL , $debuginfo = null ) {
if ( empty ( $module ) || $module == 'moodle' || $module == 'core' ) {
2008-06-13 17:51:34 +00:00
$module = 'error' ;
}
2008-09-02 06:03:37 +00:00
$this -> errorcode = $errorcode ;
$this -> module = $module ;
$this -> link = $link ;
$this -> a = $a ;
$this -> debuginfo = $debuginfo ;
2008-06-13 17:51:34 +00:00
2008-09-02 06:03:37 +00:00
$message = get_string ( $errorcode , $module , $a );
2008-06-13 17:51:34 +00:00
parent :: __construct ( $message , 0 );
}
}
2008-10-28 15:11:10 +00:00
/**
2009-05-08 07:47:02 +00:00
* Exception indicating programming error , must be fixed by a programer . For example
* a core API might throw this type of exception if a plugin calls it incorrectly .
2009-05-26 03:57:03 +00:00
*
* @ package moodlecore
* @ copyright 1999 onwards Martin Dougiamas { @ link http :// moodle . com }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2008-10-28 15:11:10 +00:00
*/
class coding_exception extends moodle_exception {
/**
* Constructor
* @ param string $hint short description of problem
* @ param string $debuginfo detailed information how to fix problem
*/
function __construct ( $hint , $debuginfo = null ) {
parent :: __construct ( 'codingerror' , 'debug' , '' , $hint , $debuginfo );
}
}
2009-05-08 07:47:02 +00:00
/**
* An exception that indicates something really weird happended . For example ,
* if you do switch ( $context -> contextlevel ), and have one case for each
* CONTEXT_ ... constant . You might throw an invalid_state_exception in the
2009-05-11 17:13:45 +00:00
* default case , to just in case something really weird is going on , and
2009-05-11 17:11:29 +00:00
* $context -> contextlevel is invalid - rather than ignoring this possibility .
2009-05-26 03:57:03 +00:00
*
* @ package moodlecore
* @ copyright 1999 onwards Martin Dougiamas { @ link http :// moodle . com }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2009-05-08 07:47:02 +00:00
*/
class invalid_state_exception extends moodle_exception {
/**
* Constructor
* @ param string $hint short description of problem
* @ param string $debuginfo optional more detailed information
*/
function __construct ( $hint , $debuginfo = null ) {
parent :: __construct ( 'invalidstatedetected' , 'debug' , '' , $hint , $debuginfo );
}
}
2008-06-13 17:51:34 +00:00
/**
* Default exception handler , uncought exceptions are equivalent to using print_error ()
*/
function default_exception_handler ( $ex ) {
2009-06-12 10:59:28 +00:00
global $CFG , $DB , $SCRIPT ;
// detect active db transactions, rollback and log as error
if ( $DB -> is_transaction_started ()) {
error_log ( 'Database transaction aborted by exception in ' . $CFG -> dirroot . $SCRIPT );
try {
// note: transaction blocks should never change current $_SESSION
$DB -> rollback_sql ();
} catch ( Exception $ignored ) {
}
}
2008-10-28 15:21:01 +00:00
2008-06-13 17:51:34 +00:00
$backtrace = $ex -> getTrace ();
$place = array ( 'file' => $ex -> getFile (), 'line' => $ex -> getLine (), 'exception' => get_class ( $ex ));
array_unshift ( $backtrace , $place );
2009-05-07 05:38:35 +00:00
$earlyerror = ! isset ( $CFG -> theme ) || ! isset ( $CFG -> stylesheets );
foreach ( $backtrace as $stackframe ) {
if ( isset ( $stackframe [ 'function' ]) && $stackframe [ 'function' ] == 'print_header' ) {
$earlyerror = true ;
break ;
2008-10-28 15:21:01 +00:00
}
2009-05-07 05:38:35 +00:00
}
if ( $ex instanceof moodle_exception ) {
$errorcode = $ex -> errorcode ;
$module = $ex -> module ;
$a = $ex -> a ;
$link = $ex -> link ;
$debuginfo = $ex -> debuginfo ;
2008-06-13 17:51:34 +00:00
} else {
2009-05-07 05:38:35 +00:00
$errorcode = 'generalexceptionmessage' ;
$module = 'error' ;
$a = $ex -> getMessage ();
$link = '' ;
$debuginfo = null ;
}
if ( $earlyerror ) {
_print_early_error ( $errorcode , $module , $a , $backtrace , $debuginfo );
} else {
_print_normal_error ( $errorcode , $module , $a , $link , $backtrace , $debuginfo );
2008-06-13 17:51:34 +00:00
}
}
2008-01-20 17:59:26 +00:00
2009-02-01 13:37:42 +00:00
/**
* This function verifies the sanity of PHP configuration
* and stops execution if anything critical found .
*/
function setup_validate_php_configuration () {
// this must be very fast - no slow checks here!!!
if ( ini_get_bool ( 'register_globals' )) {
print_error ( 'globalswarning' , 'admin' );
}
if ( ini_get_bool ( 'session.auto_start' )) {
print_error ( 'sessionautostartwarning' , 'admin' );
}
if ( ini_get_bool ( 'magic_quotes_runtime' )) {
print_error ( 'fatalmagicquotesruntime' , 'admin' );
}
}
2009-01-05 21:37:20 +00:00
/**
2009-05-06 08:50:32 +00:00
* Initialises $FULLME and friends . Private function . Should only be called from
* setup . php .
2009-01-05 21:37:20 +00:00
*/
function initialise_fullme () {
global $CFG , $FULLME , $ME , $SCRIPT , $FULLSCRIPT ;
2009-05-06 08:50:32 +00:00
// Detect common config error.
2009-01-07 15:31:54 +00:00
if ( substr ( $CFG -> wwwroot , - 1 ) == '/' ) {
print_error ( 'wwwrootslash' , 'error' );
}
2009-05-06 08:50:32 +00:00
if ( CLI_SCRIPT ) {
initialise_fullme_cli ();
return ;
2009-01-07 09:54:09 +00:00
}
2009-01-05 21:37:20 +00:00
2009-05-06 08:50:32 +00:00
$wwwroot = parse_url ( $CFG -> wwwroot );
if ( ! isset ( $wwwroot [ 'path' ])) {
$wwwroot [ 'path' ] = '' ;
}
$wwwroot [ 'path' ] .= '/' ;
$rurl = setup_get_remote_url ();
2009-01-05 21:37:20 +00:00
2009-05-06 08:50:32 +00:00
// Check that URL is under $CFG->wwwroot.
if ( strpos ( $rurl [ 'path' ], $wwwroot [ 'path' ]) === 0 ) {
$SCRIPT = substr ( $rurl [ 'path' ], strlen ( $wwwroot [ 'path' ]) - 1 );
} else {
// Probably some weird external script
$SCRIPT = $FULLSCRIPT = $FULLME = $ME = null ;
2009-01-05 21:37:20 +00:00
return ;
}
2009-05-06 08:50:32 +00:00
// $CFG->sslproxy specifies if external SSL appliance is used
// (That is, the Moodle server uses http, with an external box translating everything to https).
if ( empty ( $CFG -> sslproxy )) {
if ( $rurl [ 'scheme' ] == 'http' and $wwwroot [ 'scheme' ] == 'https' ) {
print_error ( 'sslonlyaccess' , 'error' );
}
}
// $CFG->reverseproxy specifies if reverse proxy server used.
// Used in load balancing scenarios.
// Do not abuse this to try to solve lan/wan access problems!!!!!
if ( empty ( $CFG -> reverseproxy )) {
if (( $rurl [ 'host' ] != $wwwroot [ 'host' ]) or
( ! empty ( $wwwroot [ 'port' ]) and $rurl [ 'port' ] != $wwwroot [ 'port' ])) {
print_error ( 'wwwrootmismatch' , 'error' , '' , $CFG -> wwwroot );
}
}
// hopefully this will stop all those "clever" admins trying to set up moodle
// with two different addresses in intranet and Internet
if ( ! empty ( $CFG -> reverseproxy ) && $rurl [ 'host' ] == $wwwroot [ 'host' ]) {
print_error ( 'reverseproxyabused' , 'error' );
}
$hostandport = $rurl [ 'scheme' ] . '://' . $wwwroot [ 'host' ];
if ( ! empty ( $wwwroot [ 'port' ])) {
$hostandport .= ':' . $wwwroot [ 'port' ];
}
$FULLSCRIPT = $hostandport . $rurl [ 'path' ];
$FULLME = $hostandport . $rurl [ 'fullpath' ];
$ME = $rurl [ 'fullpath' ];
$rurl [ 'path' ] = $rurl [ 'fullpath' ];
}
/**
* Initialises $FULLME and friends for command line scripts .
* This is a private method for use by initialise_fullme .
*/
function initialise_fullme_cli () {
2009-05-17 17:07:54 +00:00
global $CFG , $FULLME , $ME , $SCRIPT , $FULLSCRIPT ;
2009-05-06 08:50:32 +00:00
// Urls do not make much sense in CLI scripts
$backtrace = debug_backtrace ();
$topfile = array_pop ( $backtrace );
$topfile = realpath ( $topfile [ 'file' ]);
$dirroot = realpath ( $CFG -> dirroot );
if ( strpos ( $topfile , $dirroot ) !== 0 ) {
// Probably some weird external script
$SCRIPT = $FULLSCRIPT = $FULLME = $ME = null ;
} else {
$relativefile = substr ( $topfile , strlen ( $dirroot ));
$relativefile = str_replace ( '\\' , '/' , $relativefile ); // Win fix
$SCRIPT = $FULLSCRIPT = $relativefile ;
$FULLME = $ME = null ;
}
}
/**
* Get the URL that PHP / the web server thinks it is serving . Private function
* used by initialise_fullme . In your code , use $PAGE -> url , $SCRIPT , etc .
* @ return array in the same format that parse_url returns , with the addition of
* a 'fullpath' element , which includes any slasharguments path .
*/
function setup_get_remote_url () {
2009-01-05 21:37:20 +00:00
$rurl = array ();
2009-05-06 08:50:32 +00:00
list ( $rurl [ 'host' ]) = explode ( ':' , $_SERVER [ 'HTTP_HOST' ]);
2009-01-05 21:37:20 +00:00
$rurl [ 'port' ] = $_SERVER [ 'SERVER_PORT' ];
2009-05-06 08:50:32 +00:00
$rurl [ 'path' ] = $_SERVER [ 'SCRIPT_NAME' ]; // Script path without slash arguments
2009-01-05 21:37:20 +00:00
if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'apache' ) !== false ) {
//Apache server
$rurl [ 'scheme' ] = empty ( $_SERVER [ 'HTTPS' ]) ? 'http' : 'https' ;
$rurl [ 'fullpath' ] = $_SERVER [ 'REQUEST_URI' ]; // TODO: verify this is always properly encoded
} else if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'lighttpd' ) !== false ) {
//lighttpd
$rurl [ 'scheme' ] = empty ( $_SERVER [ 'HTTPS' ]) ? 'http' : 'https' ;
$rurl [ 'fullpath' ] = $_SERVER [ 'REQUEST_URI' ]; // TODO: verify this is always properly encoded
} else if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'iis' ) !== false ) {
//IIS
$rurl [ 'scheme' ] = ( $_SERVER [ 'HTTPS' ] == 'off' ) ? 'http' : 'https' ;
$rurl [ 'fullpath' ] = $_SERVER [ 'SCRIPT_NAME' ];
// NOTE: ignore PATH_INFO because it is incorrectly encoded using 8bit filesystem legacy encoding in IIS
// since 2.0 we rely on iis rewrite extenssion like Helicon ISAPI_rewrite
2009-01-05 22:32:15 +00:00
// example rule: RewriteRule ^([^\?]+?\.php)(\/.+)$ $1\?file=$2 [QSA]
2009-01-05 21:37:20 +00:00
if ( $_SERVER [ 'QUERY_STRING' ] != '' ) {
2009-01-06 12:33:32 +00:00
$rurl [ 'fullpath' ] .= '?' . $_SERVER [ 'QUERY_STRING' ];
2009-01-05 21:37:20 +00:00
}
$_SERVER [ 'REQUEST_URI' ] = $rurl [ 'fullpath' ]; // extra IIS compatibility
} else {
2009-05-06 08:50:32 +00:00
throw new moodle_exception ( 'unsupportedwebserver' , 'error' , '' , $_SERVER [ 'SERVER_SOFTWARE' ]);
2009-01-05 21:37:20 +00:00
}
2009-05-06 08:50:32 +00:00
return $rurl ;
2009-01-05 21:37:20 +00:00
}
2006-01-05 07:08:10 +00:00
/**
* Initializes our performance info early .
*
* Pairs up with get_performance_info () which is actually
2008-06-13 17:51:34 +00:00
* in moodlelib . php . This function is here so that we can
* call it before all the libs are pulled in .
2006-01-05 07:08:10 +00:00
*
* @ uses $PERF
*/
function init_performance_info () {
2007-03-20 02:59:34 +00:00
global $PERF , $CFG , $USER ;
2008-06-13 17:51:34 +00:00
2008-06-16 21:01:54 +00:00
$PERF = new object ();
2006-01-05 07:08:10 +00:00
$PERF -> logwrites = 0 ;
if ( function_exists ( 'microtime' )) {
$PERF -> starttime = microtime ();
}
if ( function_exists ( 'memory_get_usage' )) {
$PERF -> startmemory = memory_get_usage ();
}
if ( function_exists ( 'posix_times' )) {
2008-06-13 17:51:34 +00:00
$PERF -> startposixtimes = posix_times ();
2006-01-05 07:08:10 +00:00
}
2007-03-20 00:34:05 +00:00
if ( function_exists ( 'apd_set_pprof_trace' )) {
// APD profiling
2007-03-20 02:59:34 +00:00
if ( $USER -> id > 0 && $CFG -> perfdebug >= 15 ) {
2008-06-13 17:51:34 +00:00
$tempdir = $CFG -> dataroot . '/temp/profile/' . $USER -> id ;
2007-03-20 02:59:34 +00:00
mkdir ( $tempdir );
apd_set_pprof_trace ( $tempdir );
$PERF -> profiling = true ;
}
2007-03-20 00:34:05 +00:00
}
2006-01-05 07:08:10 +00:00
}
2009-06-24 09:17:56 +00:00
/**
* Indicates whether we are in the middle of the initial Moodle install .
*
* Very occasionally it is necessary avoid running certain bits of code before the
* Moodle installation has completed . The installed flag is set in admin / index . php
* after Moodle core and all the plugins have been installed , but just before
* the person doing the initial install is asked to choose the admin password .
*
* @ return boolean true if the initial install is not complete .
*/
function during_initial_install () {
global $CFG ;
return empty ( $CFG -> rolesactive );
}
2006-12-26 22:48:36 +00:00
/**
* Function to raise the memory limit to a new value .
* Will respect the memory limit if it is higher , thus allowing
* settings in php . ini , apache conf or command line switches
* to override it
*
* The memory limit should be expressed with a string ( eg : '64M' )
*
* @ param string $newlimit the new memory limit
* @ return bool
*/
2009-01-05 21:37:20 +00:00
function raise_memory_limit ( $newlimit ) {
2006-12-26 22:48:36 +00:00
if ( empty ( $newlimit )) {
return false ;
}
$cur = @ ini_get ( 'memory_limit' );
if ( empty ( $cur )) {
// if php is compiled without --enable-memory-limits
// apparently memory_limit is set to ''
$cur = 0 ;
} else {
if ( $cur == - 1 ){
return true ; // unlimited mem!
}
$cur = get_real_size ( $cur );
}
$new = get_real_size ( $newlimit );
if ( $new > $cur ) {
ini_set ( 'memory_limit' , $newlimit );
2009-03-26 02:09:28 +00:00
return true ;
}
return false ;
}
/**
* Function to reduce the memory limit to a new value .
* Will respect the memory limit if it is lower , thus allowing
* settings in php . ini , apache conf or command line switches
* to override it
*
* The memory limit should be expressed with a string ( eg : '64M' )
*
* @ param string $newlimit the new memory limit
* @ return bool
*/
2009-05-11 17:13:45 +00:00
function reduce_memory_limit ( $newlimit ) {
2009-03-26 02:09:28 +00:00
if ( empty ( $newlimit )) {
return false ;
}
$cur = @ ini_get ( 'memory_limit' );
if ( empty ( $cur )) {
// if php is compiled without --enable-memory-limits
// apparently memory_limit is set to ''
$cur = 0 ;
} else {
if ( $cur == - 1 ){
return true ; // unlimited mem!
}
$cur = get_real_size ( $cur );
}
$new = get_real_size ( $newlimit );
// -1 is smaller, but it means unlimited
if ( $new < $cur && $new != - 1 ) {
ini_set ( 'memory_limit' , $newlimit );
2006-12-26 22:48:36 +00:00
return true ;
}
return false ;
}
/**
* Converts numbers like 10 M into bytes .
*
* @ param mixed $size The size to be converted
* @ return mixed
*/
function get_real_size ( $size = 0 ) {
if ( ! $size ) {
return 0 ;
}
2009-01-05 21:37:20 +00:00
$scan = array ();
2006-12-26 22:48:36 +00:00
$scan [ 'MB' ] = 1048576 ;
$scan [ 'Mb' ] = 1048576 ;
$scan [ 'M' ] = 1048576 ;
$scan [ 'm' ] = 1048576 ;
$scan [ 'KB' ] = 1024 ;
$scan [ 'Kb' ] = 1024 ;
$scan [ 'K' ] = 1024 ;
$scan [ 'k' ] = 1024 ;
while ( list ( $key ) = each ( $scan )) {
if (( strlen ( $size ) > strlen ( $key )) && ( substr ( $size , strlen ( $size ) - strlen ( $key )) == $key )) {
$size = substr ( $size , 0 , strlen ( $size ) - strlen ( $key )) * $scan [ $key ];
break ;
}
}
return $size ;
}
2006-01-05 07:08:10 +00:00
/**
* Create a directory .
*
* @ uses $CFG
* @ param string $directory a string of directory names under $CFG -> dataroot eg stuff / assignment / 1
* param bool $shownotices If true then notification messages will be printed out on error .
* @ return string | false Returns full path to directory if successful , false if not
*/
function make_upload_directory ( $directory , $shownotices = true ) {
global $CFG ;
$currdir = $CFG -> dataroot ;
umask ( 0000 );
if ( ! file_exists ( $currdir )) {
2009-02-11 15:26:29 +00:00
if ( ! mkdir ( $currdir , $CFG -> directorypermissions ) or ! is_writable ( $currdir )) {
2006-01-05 07:08:10 +00:00
if ( $shownotices ) {
2008-06-13 17:51:34 +00:00
echo '<div class="notifyproblem" align="center">ERROR: You need to create the directory ' .
2006-01-05 07:08:10 +00:00
$currdir . ' with web server write access</div>' . " <br /> \n " ;
}
return false ;
}
2006-08-18 09:54:09 +00:00
}
// Make sure a .htaccess file is here, JUST IN CASE the files area is in the open
if ( ! file_exists ( $currdir . '/.htaccess' )) {
2006-01-05 07:08:10 +00:00
if ( $handle = fopen ( $currdir . '/.htaccess' , 'w' )) { // For safety
2009-05-08 21:30:56 +00:00
@ fwrite ( $handle , " deny from all \r \n AllowOverride None \r \n Note: this file is broken intentionally, we do not want anybody to undo it in subdirectory! \r \n " );
2006-01-05 07:08:10 +00:00
@ fclose ( $handle );
}
}
$dirarray = explode ( '/' , $directory );
foreach ( $dirarray as $dir ) {
$currdir = $currdir . '/' . $dir ;
if ( ! file_exists ( $currdir )) {
if ( ! mkdir ( $currdir , $CFG -> directorypermissions )) {
if ( $shownotices ) {
2008-06-13 17:51:34 +00:00
echo '<div class="notifyproblem" align="center">ERROR: Could not find or create a directory (' .
2006-01-05 07:08:10 +00:00
$currdir . ')</div>' . " <br /> \n " ;
}
return false ;
}
//@chmod($currdir, $CFG->directorypermissions); // Just in case mkdir didn't do it
}
}
return $currdir ;
}
2006-12-27 22:44:39 +00:00
function init_memcached () {
global $CFG , $MCACHE ;
2006-12-27 22:47:51 +00:00
include_once ( $CFG -> libdir . '/memcached.class.php' );
$MCACHE = new memcached ;
if ( $MCACHE -> status ()) {
return true ;
2008-06-13 17:51:34 +00:00
}
2006-12-27 22:47:51 +00:00
unset ( $MCACHE );
2008-06-13 17:51:34 +00:00
return false ;
2006-12-27 22:44:39 +00:00
}
2006-12-27 22:47:14 +00:00
function init_eaccelerator () {
global $CFG , $MCACHE ;
include_once ( $CFG -> libdir . '/eaccelerator.class.php' );
$MCACHE = new eaccelerator ;
2006-12-27 22:47:51 +00:00
if ( $MCACHE -> status ()) {
2006-12-27 22:47:14 +00:00
return true ;
2008-06-13 17:51:34 +00:00
}
2006-12-27 22:47:14 +00:00
unset ( $MCACHE );
return false ;
}
2006-01-05 07:08:10 +00:00
?>