2009-05-26 03:57:03 +00:00
< ? php
// 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 .
2009-10-31 14:17:44 +00:00
*
2010-07-25 13:35:05 +00:00
* @ package core
* @ subpackage lib
* @ copyright 1999 onwards Martin Dougiamas { @ link http :// moodle . com }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2009-05-26 03:57:03 +00:00
*/
2006-01-05 07:08:10 +00:00
2010-07-25 13:35:05 +00:00
defined ( 'MOODLE_INTERNAL' ) || die ();
2012-03-28 16:39:42 +02:00
// Debug levels - always keep the values in ascending order!
/** No warnings and errors at all */
2010-10-19 09:23:08 +00:00
define ( 'DEBUG_NONE' , 0 );
2012-03-28 16:39:42 +02:00
/** Fatal errors only */
define ( 'DEBUG_MINIMAL' , E_ERROR | E_PARSE );
/** Errors, warnings and notices */
define ( 'DEBUG_NORMAL' , E_ERROR | E_PARSE | E_WARNING | E_NOTICE );
/** All problems except strict PHP warnings */
define ( 'DEBUG_ALL' , E_ALL & ~ E_STRICT );
/** DEBUG_ALL with all debug messages and strict warnings */
define ( 'DEBUG_DEVELOPER' , E_ALL | E_STRICT );
2010-10-19 09:23:08 +00:00
/** Remove any memory limits */
define ( 'MEMORY_UNLIMITED' , - 1 );
/** Standard memory limit for given platform */
define ( 'MEMORY_STANDARD' , - 2 );
/**
* Large memory limit for given platform - used in cron , upgrade , and other places that need a lot of memory .
* Can be overridden with $CFG -> extramemorylimit setting .
*/
define ( 'MEMORY_EXTRA' , - 3 );
/** Extremely large memory limit - not recommended for standard scripts */
define ( 'MEMORY_HUGE' , - 4 );
2009-06-29 05:00:45 +00:00
2011-02-25 23:39:42 +01:00
/**
* Software maturity levels used by the core and plugins
*/
define ( 'MATURITY_ALPHA' , 50 ); // internals can be tested using white box techniques
define ( 'MATURITY_BETA' , 100 ); // feature complete, ready for preview and testing
define ( 'MATURITY_RC' , 150 ); // tested, will be released unless there are fatal bugs
define ( 'MATURITY_STABLE' , 200 ); // ready for production deployment
2011-10-17 16:07:40 +01:00
/**
* Special value that can be used in $plugin -> dependencies in version . php files .
*/
define ( 'ANY_VERSION' , 'any' );
2008-01-20 17:59:26 +00:00
/**
2009-09-08 07:09:01 +00:00
* Simple class . It is usually used instead of stdClass because it looks
2009-11-01 10:05:07 +00:00
* more familiar to Java developers ; - ) Do not use for type checking of
2010-09-21 08:57:31 +00:00
* function parameters . Please use stdClass instead .
2009-05-26 03:57:03 +00:00
*
2010-09-06 11:41:43 +00:00
* @ package core
* @ subpackage lib
* @ copyright 2009 Petr Skoda { @ link http :// skodak . org }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2010-09-21 08:57:31 +00:00
* @ deprecated since 2.0
2008-01-20 17:59:26 +00:00
*/
2009-09-08 07:09:01 +00:00
class object extends stdClass {};
2008-01-20 17:59:26 +00:00
2008-06-13 17:51:34 +00:00
/**
* Base Moodle Exception class
2009-05-26 03:57:03 +00:00
*
2009-06-29 05:00:45 +00:00
* Although this class is defined here , you cannot throw a moodle_exception until
* after moodlelib . php has been included ( which will happen very soon ) .
*
2010-09-06 11:41:43 +00:00
* @ package core
* @ subpackage lib
* @ copyright 2008 Petr Skoda { @ link http :// skodak . org }
* @ 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 {
2012-02-21 11:48:33 +13:00
/**
* @ var string The name of the string from error . php to print
*/
2008-06-13 17:51:34 +00:00
public $errorcode ;
2012-02-21 11:48:33 +13:00
/**
* @ var string The name of module
*/
2008-06-13 17:51:34 +00:00
public $module ;
2012-02-21 11:48:33 +13:00
/**
* @ var mixed Extra words and phrases that might be required in the error string
*/
2008-06-13 17:51:34 +00:00
public $a ;
2012-02-21 11:48:33 +13:00
/**
* @ var string 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 .
*/
2008-06-13 17:51:34 +00:00
public $link ;
2012-02-21 11:48:33 +13:00
/**
* @ var string Optional information to aid the debugging process
*/
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 .
2012-02-21 11:48:33 +13:00
* @ param mixed $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 ;
2012-06-06 19:57:47 +01:00
$this -> debuginfo = is_null ( $debuginfo ) ? null : ( string ) $debuginfo ;
2008-06-13 17:51:34 +00:00
2010-05-18 11:58:53 +00:00
if ( get_string_manager () -> string_exists ( $errorcode , $module )) {
$message = get_string ( $errorcode , $module , $a );
} else {
$message = $module . '/' . $errorcode ;
}
2008-06-13 17:51:34 +00:00
2012-04-07 17:16:08 +02:00
if ( defined ( 'PHPUNIT_TEST' ) and PHPUNIT_TEST and $debuginfo ) {
2012-03-31 23:51:02 +02:00
$message = " $message ( $debuginfo ) " ;
}
2008-06-13 17:51:34 +00:00
parent :: __construct ( $message , 0 );
}
}
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
/**
* Course / activity access exception .
*
* This exception is thrown from require_login ()
2010-09-06 11:41:43 +00:00
*
2012-01-14 19:12:43 +01:00
* @ package core_access
2010-09-06 11:41:43 +00:00
* @ copyright 2010 Petr Skoda { @ link http :// skodak . org }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
*/
class require_login_exception extends moodle_exception {
2012-02-21 11:48:33 +13:00
/**
* Constructor
* @ param string $debuginfo Information to aid the debugging process
*/
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
function __construct ( $debuginfo ) {
parent :: __construct ( 'requireloginerror' , 'error' , '' , NULL , $debuginfo );
}
}
2010-02-05 04:10:36 +00:00
/**
* Web service parameter exception class
2011-10-17 13:18:30 +13:00
* @ deprecated since Moodle 2.2 - use moodle exception instead
2010-02-05 04:10:36 +00:00
* This exception must be thrown to the web service client when a web service parameter is invalid
* The error string is gotten from webservice . php
*/
class webservice_parameter_exception extends moodle_exception {
/**
* Constructor
* @ param string $errorcode The name of the string from webservice . php to print
* @ param string $a The name of the parameter
2012-02-21 11:48:33 +13:00
* @ param string $debuginfo Optional information to aid debugging
2010-02-05 04:10:36 +00:00
*/
2011-10-07 16:06:19 +08:00
function __construct ( $errorcode = null , $a = '' , $debuginfo = null ) {
parent :: __construct ( $errorcode , 'webservice' , '' , $a , $debuginfo );
2010-02-05 04:10:36 +00:00
}
}
2009-09-14 23:52:08 +00:00
/**
* Exceptions indicating user does not have permissions to do something
* and the execution can not continue .
2010-09-06 11:41:43 +00:00
*
2012-01-14 19:12:43 +01:00
* @ package core_access
2010-09-06 11:41:43 +00:00
* @ copyright 2009 Petr Skoda { @ link http :// skodak . org }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2009-09-14 23:52:08 +00:00
*/
class required_capability_exception extends moodle_exception {
2012-02-21 11:48:33 +13:00
/**
* Constructor
* @ param context $context The context used for the capability check
* @ param string $capability The required capability
* @ param string $errormessage The error message to show the user
* @ param string $stringfile
*/
2009-09-14 23:52:08 +00:00
function __construct ( $context , $capability , $errormessage , $stringfile ) {
$capabilityname = get_capability_string ( $capability );
2010-10-14 18:18:31 +00:00
if ( $context -> contextlevel == CONTEXT_MODULE and preg_match ( '/:view$/' , $capability )) {
// we can not go to mod/xx/view.php because we most probably do not have cap to view it, let's go to course instead
2012-08-21 14:20:30 +08:00
$paranetcontext = context :: instance_by_id ( get_parent_contextid ( $context ));
2010-10-14 18:18:31 +00:00
$link = get_context_url ( $paranetcontext );
} else {
$link = get_context_url ( $context );
}
parent :: __construct ( $errormessage , $stringfile , $link , $capabilityname );
2009-09-14 23:52:08 +00:00
}
}
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
*
2010-09-06 11:41:43 +00:00
* @ package core
* @ subpackage lib
* @ copyright 2008 Petr Skoda { @ link http :// skodak . org }
* @ 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-09-15 20:08:47 +00:00
}
}
/**
* Exception indicating malformed parameter problem .
* This exception is not supposed to be thrown when processing
* user submitted data in forms . It is more suitable
* for WS and other low level stuff .
2010-09-06 11:41:43 +00:00
*
* @ package core
* @ subpackage lib
* @ copyright 2009 Petr Skoda { @ link http :// skodak . org }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2009-09-15 20:08:47 +00:00
*/
class invalid_parameter_exception extends moodle_exception {
/**
* Constructor
* @ param string $debuginfo some detailed information
*/
function __construct ( $debuginfo = null ) {
parent :: __construct ( 'invalidparameter' , 'debug' , '' , null , $debuginfo );
2008-10-28 15:11:10 +00:00
}
}
2010-02-22 07:07:44 +00:00
/**
* Exception indicating malformed response problem .
* This exception is not supposed to be thrown when processing
* user submitted data in forms . It is more suitable
* for WS and other low level stuff .
*/
class invalid_response_exception extends moodle_exception {
/**
* Constructor
* @ param string $debuginfo some detailed information
*/
function __construct ( $debuginfo = null ) {
parent :: __construct ( 'invalidresponse' , 'debug' , '' , null , $debuginfo );
}
}
2009-05-08 07:47:02 +00:00
/**
2009-11-01 10:05:07 +00:00
* An exception that indicates something really weird happened . For example ,
2009-05-08 07:47:02 +00:00
* 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
*
2010-09-06 11:41:43 +00:00
* @ package core
* @ subpackage lib
* @ copyright 2009 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 );
}
}
2010-08-29 14:33:39 +00:00
/**
* An exception that indicates incorrect permissions in $CFG -> dataroot
*
* @ package core
* @ subpackage lib
* @ copyright 2010 Petr Skoda { @ link http :// skodak . org }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
class invalid_dataroot_permissions extends moodle_exception {
/**
* Constructor
* @ param string $debuginfo optional more detailed information
*/
function __construct ( $debuginfo = NULL ) {
parent :: __construct ( 'invaliddatarootpermissions' , 'error' , '' , NULL , $debuginfo );
}
}
2010-11-19 03:40:43 +00:00
/**
* An exception that indicates that file can not be served
*
* @ package core
* @ subpackage lib
* @ copyright 2010 Petr Skoda { @ link http :// skodak . org }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
class file_serving_exception extends moodle_exception {
/**
* Constructor
* @ param string $debuginfo optional more detailed information
*/
function __construct ( $debuginfo = NULL ) {
parent :: __construct ( 'cannotservefile' , 'error' , '' , NULL , $debuginfo );
}
}
2008-06-13 17:51:34 +00:00
/**
2009-11-01 10:05:07 +00:00
* Default exception handler , uncaught exceptions are equivalent to error () in 1.9 and earlier
2009-06-29 00:34:49 +00:00
*
2009-10-31 14:17:44 +00:00
* @ param Exception $ex
2009-10-31 13:52:39 +00:00
* @ return void - does not return . Terminates execution !
2008-06-13 17:51:34 +00:00
*/
2009-10-31 13:52:39 +00:00
function default_exception_handler ( $ex ) {
2012-04-22 17:17:27 +02:00
global $CFG , $DB , $OUTPUT , $USER , $FULLME , $SESSION , $PAGE ;
2009-06-12 10:59:28 +00:00
// detect active db transactions, rollback and log as error
2009-11-01 09:58:04 +00:00
abort_all_db_transactions ();
2008-10-28 15:21:01 +00:00
2010-11-12 07:53:55 +00:00
if (( $ex instanceof required_capability_exception ) && ! CLI_SCRIPT && ! AJAX_SCRIPT && ! empty ( $CFG -> autologinguests ) && ! empty ( $USER -> autologinguest )) {
2012-04-22 17:17:27 +02:00
$SESSION -> wantsurl = qualified_me ();
2010-11-12 07:53:55 +00:00
redirect ( get_login_url ());
}
2009-10-31 13:52:39 +00:00
$info = get_exception_info ( $ex );
2009-06-26 09:06:16 +00:00
2009-10-31 13:52:39 +00:00
if ( debugging ( '' , DEBUG_MINIMAL )) {
2009-10-31 22:02:05 +00:00
$logerrmsg = " Default exception handler: " . $info -> message . ' Debug: ' . $info -> debuginfo . " \n " . format_backtrace ( $info -> backtrace , true );
2009-11-01 09:58:04 +00:00
error_log ( $logerrmsg );
2009-06-29 00:34:49 +00:00
}
2009-10-31 13:52:39 +00:00
if ( is_early_init ( $info -> backtrace )) {
echo bootstrap_renderer :: early_error ( $info -> message , $info -> moreinfourl , $info -> link , $info -> backtrace , $info -> debuginfo );
2009-07-01 05:54:26 +00:00
} else {
2009-10-31 15:01:25 +00:00
try {
2009-11-01 10:00:30 +00:00
if ( $DB ) {
// If you enable db debugging and exception is thrown, the print footer prints a lot of rubbish
$DB -> set_debug ( 0 );
}
2009-10-31 15:01:25 +00:00
echo $OUTPUT -> fatal_error ( $info -> message , $info -> moreinfourl , $info -> link , $info -> backtrace , $info -> debuginfo );
} catch ( Exception $out_ex ) {
// default exception handler MUST not throw any exceptions!!
2009-10-31 22:02:05 +00:00
// the problem here is we do not know if page already started or not, we only know that somebody messed up in outputlib or theme
2009-10-31 15:01:25 +00:00
// so we just print at least something instead of "Exception thrown without a stack frame in Unknown on line 0":-(
2010-03-28 09:05:47 +00:00
if ( CLI_SCRIPT or AJAX_SCRIPT ) {
// just ignore the error and send something back using the safest method
echo bootstrap_renderer :: early_error ( $info -> message , $info -> moreinfourl , $info -> link , $info -> backtrace , $info -> debuginfo );
} else {
echo bootstrap_renderer :: early_error_content ( $info -> message , $info -> moreinfourl , $info -> link , $info -> backtrace , $info -> debuginfo );
$outinfo = get_exception_info ( $out_ex );
echo bootstrap_renderer :: early_error_content ( $outinfo -> message , $outinfo -> moreinfourl , $outinfo -> link , $outinfo -> backtrace , $outinfo -> debuginfo );
}
2009-10-31 15:01:25 +00:00
}
2009-06-30 05:34:50 +00:00
}
2009-06-26 09:06:16 +00:00
exit ( 1 ); // General error code
}
2010-08-20 09:05:15 +00:00
/**
* Default error handler , prevents some white screens .
* @ param int $errno
* @ param string $errstr
* @ param string $errfile
* @ param int $errline
* @ param array $errcontext
* @ return bool false means use default error handler
*/
function default_error_handler ( $errno , $errstr , $errfile , $errline , $errcontext ) {
if ( $errno == 4096 ) {
//fatal catchable error
throw new coding_exception ( 'PHP catchable fatal error' , $errstr );
}
return false ;
}
2009-11-01 09:58:04 +00:00
/**
* Unconditionally abort all database transactions , this function
* should be called from exception handlers only .
* @ return void
*/
function abort_all_db_transactions () {
global $CFG , $DB , $SCRIPT ;
2009-11-07 08:52:56 +00:00
// default exception handler MUST not throw any exceptions!!
2009-11-09 11:33:14 +00:00
2009-11-01 09:58:04 +00:00
if ( $DB && $DB -> is_transaction_started ()) {
error_log ( 'Database transaction aborted automatically in ' . $CFG -> dirroot . $SCRIPT );
2009-11-07 08:52:56 +00:00
// note: transaction blocks should never change current $_SESSION
$DB -> force_transaction_rollback ();
2009-11-01 09:58:04 +00:00
}
}
2009-07-01 05:54:26 +00:00
/**
2009-10-30 13:44:07 +00:00
* This function encapsulates the tests for whether an exception was thrown in
* early init -- either during setup . php or during init of $OUTPUT .
2009-07-01 05:54:26 +00:00
*
* If another exception is thrown then , and if we do not take special measures ,
* we would just get a very cryptic message " Exception thrown without a stack
* frame in Unknown on line 0 " . That makes debugging very hard, so we do take
* special measures in default_exception_handler , with the help of this function .
*
* @ param array $backtrace the stack trace to analyse .
* @ return boolean whether the stack trace is somewhere in output initialisation .
*/
2009-10-30 13:44:07 +00:00
function is_early_init ( $backtrace ) {
2009-07-01 05:54:26 +00:00
$dangerouscode = array (
array ( 'function' => 'header' , 'type' => '->' ),
array ( 'class' => 'bootstrap_renderer' ),
2009-10-30 13:44:07 +00:00
array ( 'file' => dirname ( __FILE__ ) . '/setup.php' ),
2009-07-01 05:54:26 +00:00
);
foreach ( $backtrace as $stackframe ) {
foreach ( $dangerouscode as $pattern ) {
$matches = true ;
foreach ( $pattern as $property => $value ) {
if ( ! isset ( $stackframe [ $property ]) || $stackframe [ $property ] != $value ) {
$matches = false ;
}
}
if ( $matches ) {
return true ;
}
}
}
return false ;
}
2009-06-26 09:06:16 +00:00
/**
2009-10-31 13:23:29 +00:00
* Abort execution by throwing of a general exception ,
* default exception handler displays the error message in most cases .
2009-06-26 09:06:16 +00:00
*
* @ param string $errorcode The name of the language string containing the error message .
* Normally this should be in the error . php lang file .
* @ param string $module The language file to get the error message from .
* @ 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
2009-10-31 13:23:29 +00:00
* @ param string $debuginfo optional debugging information
* @ return void , always throws exception !
2009-06-26 09:06:16 +00:00
*/
2009-10-31 13:23:29 +00:00
function print_error ( $errorcode , $module = 'error' , $link = '' , $a = null , $debuginfo = null ) {
throw new moodle_exception ( $errorcode , $module , $link , $a , $debuginfo );
2009-06-26 09:06:16 +00:00
}
/**
2009-10-31 13:52:39 +00:00
* Returns detailed information about specified exception .
* @ param exception $ex
* @ return object
2009-06-26 09:06:16 +00:00
*/
2009-10-31 13:52:39 +00:00
function get_exception_info ( $ex ) {
2009-06-26 09:06:16 +00:00
global $CFG , $DB , $SESSION ;
2009-10-31 13:52:39 +00:00
if ( $ex instanceof moodle_exception ) {
$errorcode = $ex -> errorcode ;
$module = $ex -> module ;
$a = $ex -> a ;
$link = $ex -> link ;
$debuginfo = $ex -> debuginfo ;
} else {
$errorcode = 'generalexceptionmessage' ;
$module = 'error' ;
$a = $ex -> getMessage ();
$link = '' ;
2012-06-06 19:57:47 +01:00
$debuginfo = '' ;
2009-06-26 09:06:16 +00:00
}
2012-03-06 12:46:23 +07:00
// Append the error code to the debug info to make grepping and googling easier
$debuginfo .= PHP_EOL . " Error code: $errorcode " ;
2009-10-31 13:52:39 +00:00
$backtrace = $ex -> getTrace ();
$place = array ( 'file' => $ex -> getFile (), 'line' => $ex -> getLine (), 'exception' => get_class ( $ex ));
array_unshift ( $backtrace , $place );
2009-06-29 05:00:45 +00:00
// Be careful, no guarantee moodlelib.php is loaded.
2009-06-26 09:06:16 +00:00
if ( empty ( $module ) || $module == 'moodle' || $module == 'core' ) {
$module = 'error' ;
}
2012-03-06 12:46:23 +07:00
// Search for the $errorcode's associated string
// If not found, append the contents of $a to $debuginfo so helpful information isn't lost
2010-05-18 11:58:53 +00:00
if ( function_exists ( 'get_string_manager' )) {
if ( get_string_manager () -> string_exists ( $errorcode , $module )) {
$message = get_string ( $errorcode , $module , $a );
} elseif ( $module == 'error' && get_string_manager () -> string_exists ( $errorcode , 'moodle' )) {
2009-06-29 05:00:45 +00:00
// Search in moodle file if error specified - needed for backwards compatibility
$message = get_string ( $errorcode , 'moodle' , $a );
2010-05-18 11:58:53 +00:00
} else {
$message = $module . '/' . $errorcode ;
2012-03-06 12:46:23 +07:00
$debuginfo .= PHP_EOL . '$a contents: ' . print_r ( $a , true );
2009-06-29 05:00:45 +00:00
}
} else {
$message = $module . '/' . $errorcode ;
2012-03-06 12:46:23 +07:00
$debuginfo .= PHP_EOL . '$a contents: ' . print_r ( $a , true );
2009-06-29 05:00:45 +00:00
}
// Be careful, no guarantee weblib.php is loaded.
if ( function_exists ( 'clean_text' )) {
$message = clean_text ( $message );
} else {
$message = htmlspecialchars ( $message );
2009-06-26 09:06:16 +00:00
}
if ( ! empty ( $CFG -> errordocroot )) {
2011-06-28 18:53:04 +08:00
$errordoclink = $CFG -> errordocroot . '/en/' ;
2009-06-26 09:06:16 +00:00
} else {
2011-06-28 18:53:04 +08:00
$errordoclink = get_docs_url ();
2009-06-26 09:06:16 +00:00
}
2011-06-28 18:53:04 +08:00
2009-06-26 09:06:16 +00:00
if ( $module === 'error' ) {
$modulelink = 'moodle' ;
2009-05-07 05:38:35 +00:00
} else {
2009-06-26 09:06:16 +00:00
$modulelink = $module ;
2008-06-13 17:51:34 +00:00
}
2011-06-28 18:53:04 +08:00
$moreinfourl = $errordoclink . 'error/' . $modulelink . '/' . $errorcode ;
2009-06-26 09:06:16 +00:00
2009-07-09 07:35:03 +00:00
if ( empty ( $link )) {
2009-06-26 09:06:16 +00:00
if ( ! empty ( $SESSION -> fromurl )) {
$link = $SESSION -> fromurl ;
unset ( $SESSION -> fromurl );
} else {
$link = $CFG -> wwwroot . '/' ;
}
}
2011-07-23 13:25:39 +02:00
// when printing an error the continue button should never link offsite
if ( stripos ( $link , $CFG -> wwwroot ) === false &&
stripos ( $link , $CFG -> httpswwwroot ) === false ) {
$link = $CFG -> wwwroot . '/' ;
}
2010-09-21 08:07:44 +00:00
$info = new stdClass ();
2009-10-31 13:52:39 +00:00
$info -> message = $message ;
$info -> errorcode = $errorcode ;
$info -> backtrace = $backtrace ;
$info -> link = $link ;
$info -> moreinfourl = $moreinfourl ;
$info -> a = $a ;
$info -> debuginfo = $debuginfo ;
2009-10-31 14:17:44 +00:00
2009-10-31 13:52:39 +00:00
return $info ;
2009-06-26 09:06:16 +00:00
}
2011-06-28 18:53:04 +08:00
/**
2012-06-26 18:15:44 +01:00
* Returns the Moodle Docs URL in the users language for a given 'More help' link .
2011-06-28 18:53:04 +08:00
*
2012-06-26 18:15:44 +01:00
* There are three cases :
*
* 1. In the normal case , $path will be a short relative path 'component/thing' ,
* like 'mod/folder/view' 'group/import' . This gets turned into an link to
* MoodleDocs in the user ' s language , and for the appropriate Moodle version .
* E . g . 'group/import' may become 'http://docs.moodle.org/2x/en/group/import' .
* The 'http://docs.moodle.org' bit comes from $CFG -> docroot .
*
* This is the only option that should be used in standard Moodle code . The other
* two options have been implemented because they are useful for third - party plugins .
*
2012-07-04 10:37:47 +08:00
* 2. $path may be an absolute URL , starting http :// or https ://. In this case ,
2012-06-26 18:15:44 +01:00
* the link is used as is .
*
* 3. $path may start %% WWWROOT %% , in which case that is replaced by
* $CFG -> wwwroot to make the link .
*
* @ param string $path the place to link to . See above for details .
* @ return string The MoodleDocs URL in the user ' s language . for example @ link http :// docs . moodle . org / 2 x / en / $path }
2011-06-28 18:53:04 +08:00
*/
2012-06-26 18:15:44 +01:00
function get_docs_url ( $path = null ) {
2011-06-28 18:53:04 +08:00
global $CFG ;
2012-06-26 18:15:44 +01:00
// Absolute URLs are used unmodified.
if ( substr ( $path , 0 , 7 ) === 'http://' || substr ( $path , 0 , 8 ) === 'https://' ) {
return $path ;
}
// Paths starting %%WWWROOT%% have that replaced by $CFG->wwwroot.
if ( substr ( $path , 0 , 11 ) === '%%WWWROOT%%' ) {
return $CFG -> wwwroot . substr ( $path , 11 );
}
// Otherwise we do the normal case, and construct a MoodleDocs URL relative to $CFG->docroot.
2012-05-03 14:05:40 +08:00
// Check that $CFG->branch has been set up, during installation it won't be.
if ( empty ( $CFG -> branch )) {
2012-06-26 18:15:44 +01:00
// It's not there yet so look at version.php.
2011-06-28 18:53:04 +08:00
include ( $CFG -> dirroot . '/version.php' );
} else {
2012-06-26 18:15:44 +01:00
// We can use $CFG->branch and avoid having to include version.php.
2012-05-03 14:05:40 +08:00
$branch = $CFG -> branch ;
2011-06-28 18:53:04 +08:00
}
2012-05-03 14:05:40 +08:00
// ensure branch is valid.
if ( ! $branch ) {
2011-06-28 18:53:04 +08:00
// We should never get here but in case we do lets set $branch to .
// the smart one's will know that this is the current directory
// and the smarter ones will know that there is some smart matching
// that will ensure people end up at the latest version of the docs.
$branch = '.' ;
}
if ( ! empty ( $CFG -> docroot )) {
return $CFG -> docroot . '/' . $branch . '/' . current_language () . '/' . $path ;
} else {
2012-06-26 18:15:44 +01:00
return 'http://docs.moodle.org/' . $branch . '/' . current_language () . '/' . $path ;
2011-06-28 18:53:04 +08:00
}
}
2009-06-26 09:06:16 +00:00
/**
* Formats a backtrace ready for output .
*
* @ param array $callers backtrace array , as returned by debug_backtrace () .
* @ param boolean $plaintext if false , generates HTML , if true generates plain text .
* @ return string formatted backtrace , ready for output .
*/
function format_backtrace ( $callers , $plaintext = false ) {
2009-10-15 22:34:34 +00:00
// do not use $CFG->dirroot because it might not be available in destructors
2009-06-26 09:06:16 +00:00
$dirroot = dirname ( dirname ( __FILE__ ));
2009-10-31 14:17:44 +00:00
2009-06-26 09:06:16 +00:00
if ( empty ( $callers )) {
return '' ;
}
$from = $plaintext ? '' : '<ul style="text-align: left">' ;
foreach ( $callers as $caller ) {
if ( ! isset ( $caller [ 'line' ])) {
$caller [ 'line' ] = '?' ; // probably call_user_func()
}
if ( ! isset ( $caller [ 'file' ])) {
$caller [ 'file' ] = 'unknownfile' ; // probably call_user_func()
}
$from .= $plaintext ? '* ' : '<li>' ;
$from .= 'line ' . $caller [ 'line' ] . ' of ' . str_replace ( $dirroot , '' , $caller [ 'file' ]);
if ( isset ( $caller [ 'function' ])) {
$from .= ': call to ' ;
if ( isset ( $caller [ 'class' ])) {
$from .= $caller [ 'class' ] . $caller [ 'type' ];
}
$from .= $caller [ 'function' ] . '()' ;
} else if ( isset ( $caller [ 'exception' ])) {
$from .= ': ' . $caller [ 'exception' ] . ' thrown' ;
}
$from .= $plaintext ? " \n " : '</li>' ;
}
$from .= $plaintext ? '' : '</ul>' ;
return $from ;
2008-06-13 17:51:34 +00:00
}
2008-01-20 17:59:26 +00:00
2010-11-19 03:40:43 +00:00
/**
* This function makes the return value of ini_get consistent if you are
* setting server directives through the . htaccess file in apache .
*
* Current behavior for value set from php . ini On = 1 , Off = [ blank ]
* Current behavior for value set from . htaccess On = On , Off = Off
* Contributed by jdell @ unr . edu
*
* @ param string $ini_get_arg The argument to get
* @ return bool True for on false for not
*/
function ini_get_bool ( $ini_get_arg ) {
$temp = ini_get ( $ini_get_arg );
if ( $temp == '1' or strtolower ( $temp ) == 'on' ) {
return true ;
}
return false ;
}
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' );
}
}
2010-05-19 13:30:13 +00:00
/**
* Initialise global $CFG variable
* @ return void
*/
function initialise_cfg () {
global $CFG , $DB ;
2010-06-08 07:21:43 +00:00
2010-05-19 13:30:13 +00:00
try {
if ( $DB ) {
$localcfg = $DB -> get_records_menu ( 'config' , array (), '' , 'name,value' );
foreach ( $localcfg as $name => $value ) {
if ( property_exists ( $CFG , $name )) {
// config.php settings always take precedence
continue ;
}
$CFG -> { $name } = $value ;
}
}
2011-11-12 17:39:19 +01:00
} catch ( dml_exception $e ) {
2010-05-19 13:30:13 +00:00
// most probably empty db, going to install soon
}
}
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 () {
2011-10-21 16:35:19 +02:00
global $CFG , $FULLME , $ME , $SCRIPT , $FULLSCRIPT ;
2009-01-05 21:37:20 +00:00
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
$rurl = setup_get_remote_url ();
2011-10-21 16:35:19 +02:00
$wwwroot = parse_url ( $CFG -> wwwroot . '/' );
if ( empty ( $rurl [ 'host' ])) {
// missing host in request header, probably not a real browser, let's ignore them
} else if ( ! empty ( $CFG -> reverseproxy )) {
// $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!!!!!
} else {
if (( $rurl [ 'host' ] !== $wwwroot [ 'host' ]) or ( ! empty ( $wwwroot [ 'port' ]) and $rurl [ 'port' ] != $wwwroot [ 'port' ])) {
// Explain the problem and redirect them to the right URL
if ( ! defined ( 'NO_MOODLE_COOKIES' )) {
define ( 'NO_MOODLE_COOKIES' , true );
}
redirect ( $CFG -> wwwroot , get_string ( 'wwwrootmismatch' , 'error' , $CFG -> wwwroot ), 3 );
}
}
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 )) {
2010-09-27 10:16:28 +00:00
if ( $rurl [ 'scheme' ] === 'http' and $wwwroot [ 'scheme' ] === 'https' ) {
2009-05-06 08:50:32 +00:00
print_error ( 'sslonlyaccess' , 'error' );
}
2010-09-27 10:16:28 +00:00
} else {
if ( $wwwroot [ 'scheme' ] !== 'https' ) {
throw new coding_exception ( 'Must use https address in wwwroot when ssl proxy enabled!' );
}
2010-10-15 19:18:45 +00:00
$rurl [ 'scheme' ] = 'https' ; // make moodle believe it runs on https, squid or something else it doing it
2009-05-06 08:50:32 +00:00
}
// hopefully this will stop all those "clever" admins trying to set up moodle
// with two different addresses in intranet and Internet
2011-07-22 23:17:09 +02:00
if ( ! empty ( $CFG -> reverseproxy ) && $rurl [ 'host' ] === $wwwroot [ 'host' ]) {
2009-05-06 08:50:32 +00:00
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' ];
}
/**
* 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 ();
2011-07-22 23:17:09 +02:00
if ( isset ( $_SERVER [ 'HTTP_HOST' ])) {
list ( $rurl [ 'host' ]) = explode ( ':' , $_SERVER [ 'HTTP_HOST' ]);
} else {
$rurl [ 'host' ] = null ;
}
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
2011-02-15 15:33:29 +01:00
$rurl [ 'scheme' ] = ( empty ( $_SERVER [ 'HTTPS' ]) or $_SERVER [ 'HTTPS' ] === 'off' or $_SERVER [ 'HTTPS' ] === 'Off' or $_SERVER [ 'HTTPS' ] === 'OFF' ) ? 'http' : 'https' ;
2009-01-05 21:37:20 +00:00
if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'apache' ) !== false ) {
//Apache server
2010-09-13 10:29:05 +00:00
$rurl [ 'fullpath' ] = $_SERVER [ 'REQUEST_URI' ];
2009-08-27 07:52:11 +00:00
2009-01-05 21:37:20 +00:00
} else if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'iis' ) !== false ) {
2010-04-06 19:23:47 +00:00
//IIS - needs a lot of tweaking to make it work
2009-01-05 21:37:20 +00:00
$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
2010-09-13 10:29:05 +00:00
/* NOTE: following servers are not fully tested! */
} else if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'lighttpd' ) !== false ) {
//lighttpd - not officially supported
$rurl [ 'fullpath' ] = $_SERVER [ 'REQUEST_URI' ]; // TODO: verify this is always properly encoded
} else if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'nginx' ) !== false ) {
//nginx - not officially supported
2011-01-30 11:38:16 +01:00
if ( ! isset ( $_SERVER [ 'SCRIPT_NAME' ])) {
die ( 'Invalid server configuration detected, please try to add "fastcgi_param SCRIPT_NAME $fastcgi_script_name;" to the nginx server configuration.' );
}
2010-09-13 10:29:05 +00:00
$rurl [ 'fullpath' ] = $_SERVER [ 'REQUEST_URI' ]; // TODO: verify this is always properly encoded
2010-04-06 19:23:47 +00:00
} else if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'cherokee' ) !== false ) {
//cherokee - not officially supported
$rurl [ 'fullpath' ] = $_SERVER [ 'REQUEST_URI' ]; // TODO: verify this is always properly encoded
2010-06-08 07:21:43 +00:00
} else if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'zeus' ) !== false ) {
//zeus - not officially supported
$rurl [ 'fullpath' ] = $_SERVER [ 'REQUEST_URI' ]; // TODO: verify this is always properly encoded
2010-09-13 10:29:05 +00:00
} else if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'LiteSpeed' ) !== false ) {
//LiteSpeed - not officially supported
$rurl [ 'fullpath' ] = $_SERVER [ 'REQUEST_URI' ]; // TODO: verify this is always properly encoded
2011-04-10 13:59:17 +02:00
} else if ( $_SERVER [ 'SERVER_SOFTWARE' ] === 'HTTPD' ) {
//obscure name found on some servers - this is definitely not supported
$rurl [ 'fullpath' ] = $_SERVER [ 'REQUEST_URI' ]; // TODO: verify this is always properly encoded
2012-03-14 10:21:55 +01:00
} else if ( strpos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'PHP' ) === 0 ) {
// built-in PHP Development Server
$rurl [ 'fullpath' ] = $_SERVER [ 'REQUEST_URI' ];
} 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
}
2011-03-27 12:29:36 +02:00
// sanitize the url a bit more, the encoding style may be different in vars above
$rurl [ 'fullpath' ] = str_replace ( '"' , '%22' , $rurl [ 'fullpath' ]);
$rurl [ 'fullpath' ] = str_replace ( '\'' , '%27' , $rurl [ 'fullpath' ]);
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
2010-09-21 08:07:44 +00:00
$PERF = new stdClass ();
2006-01-05 07:08:10 +00:00
$PERF -> logwrites = 0 ;
if ( function_exists ( 'microtime' )) {
$PERF -> starttime = microtime ();
2009-06-29 05:00:45 +00:00
}
2006-01-05 07:08:10 +00:00
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
}
}
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
2010-10-19 09:23:08 +00:00
* to override it .
2006-12-26 22:48:36 +00:00
*
2010-10-19 09:23:08 +00:00
* The memory limit should be expressed with a constant
* MEMORY_STANDARD , MEMORY_EXTRA or MEMORY_HUGE .
* It is possible to use strings or integers too ( eg : '128M' ) .
2006-12-26 22:48:36 +00:00
*
2010-10-19 09:23:08 +00:00
* @ param mixed $newlimit the new memory limit
* @ return bool success
2006-12-26 22:48:36 +00:00
*/
2009-01-05 21:37:20 +00:00
function raise_memory_limit ( $newlimit ) {
2010-10-19 09:23:08 +00:00
global $CFG ;
2006-12-26 22:48:36 +00:00
2010-10-19 09:23:08 +00:00
if ( $newlimit == MEMORY_UNLIMITED ) {
ini_set ( 'memory_limit' , - 1 );
return true ;
} else if ( $newlimit == MEMORY_STANDARD ) {
2010-10-23 10:57:15 +00:00
if ( PHP_INT_SIZE > 4 ) {
$newlimit = get_real_size ( '128M' ); // 64bit needs more memory
} else {
$newlimit = get_real_size ( '96M' );
}
2010-10-19 09:23:08 +00:00
} else if ( $newlimit == MEMORY_EXTRA ) {
2010-10-23 10:57:15 +00:00
if ( PHP_INT_SIZE > 4 ) {
$newlimit = get_real_size ( '384M' ); // 64bit needs more memory
} else {
$newlimit = get_real_size ( '256M' );
}
2010-10-26 08:02:51 +00:00
if ( ! empty ( $CFG -> extramemorylimit )) {
2010-10-19 09:23:08 +00:00
$extra = get_real_size ( $CFG -> extramemorylimit );
if ( $extra > $newlimit ) {
$newlimit = $extra ;
}
}
} else if ( $newlimit == MEMORY_HUGE ) {
$newlimit = get_real_size ( '2G' );
} else {
$newlimit = get_real_size ( $newlimit );
}
if ( $newlimit <= 0 ) {
debugging ( 'Invalid memory limit specified.' );
2006-12-26 22:48:36 +00:00
return false ;
}
2010-11-19 03:40:43 +00:00
$cur = ini_get ( 'memory_limit' );
2006-12-26 22:48:36 +00:00
if ( empty ( $cur )) {
// if php is compiled without --enable-memory-limits
// apparently memory_limit is set to ''
2010-10-19 09:23:08 +00:00
$cur = 0 ;
2006-12-26 22:48:36 +00:00
} else {
if ( $cur == - 1 ){
return true ; // unlimited mem!
}
2010-10-19 09:23:08 +00:00
$cur = get_real_size ( $cur );
2006-12-26 22:48:36 +00:00
}
2010-10-19 09:23:08 +00:00
if ( $newlimit > $cur ) {
2006-12-26 22:48:36 +00:00
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 ;
}
2010-11-19 03:40:43 +00:00
$cur = ini_get ( 'memory_limit' );
2009-03-26 02:09:28 +00:00
if ( empty ( $cur )) {
// if php is compiled without --enable-memory-limits
// apparently memory_limit is set to ''
2010-10-19 09:23:08 +00:00
$cur = 0 ;
2009-03-26 02:09:28 +00:00
} 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 .
*
2010-10-19 09:23:08 +00:00
* @ param string $size The size to be converted
* @ return int
2006-12-26 22:48:36 +00:00
*/
2010-10-19 09:23:08 +00:00
function get_real_size ( $size = 0 ) {
2006-12-26 22:48:36 +00:00
if ( ! $size ) {
return 0 ;
}
2009-01-05 21:37:20 +00:00
$scan = array ();
2010-10-19 09:23:08 +00:00
$scan [ 'GB' ] = 1073741824 ;
$scan [ 'Gb' ] = 1073741824 ;
$scan [ 'G' ] = 1073741824 ;
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 ;
}
2010-11-19 03:40:43 +00:00
/**
2010-11-20 03:49:20 +00:00
* Try to disable all output buffering and purge
* all headers .
*
2012-02-21 11:48:33 +13:00
* @ access private to be called only from lib / setup . php !
2010-11-19 03:40:43 +00:00
* @ return void
*/
function disable_output_buffering () {
$olddebug = error_reporting ( 0 );
// disable compression, it would prevent closing of buffers
if ( ini_get_bool ( 'zlib.output_compression' )) {
ini_set ( 'zlib.output_compression' , 'Off' );
}
// try to flush everything all the time
ob_implicit_flush ( true );
// close all buffers if possible and discard any existing output
// this can actually work around some whitespace problems in config.php
while ( ob_get_level ()) {
if ( ! ob_end_clean ()) {
// prevent infinite loop when buffer can not be closed
break ;
}
}
2012-04-28 18:00:06 +02:00
// disable any other output handlers
ini_set ( 'output_handler' , '' );
2010-11-19 03:40:43 +00:00
error_reporting ( $olddebug );
}
2009-07-10 08:44:01 +00:00
/**
* Check whether a major upgrade is needed . That is defined as an upgrade that
* changes something really fundamental in the database , so nothing can possibly
* work until the database has been updated , and that is defined by the hard - coded
* version number in this function .
*/
function redirect_if_major_upgrade_required () {
global $CFG ;
2012-11-05 14:25:24 +08:00
$lastmajordbchanges = 2012110201 ;
2009-07-10 08:44:01 +00:00
if ( empty ( $CFG -> version ) or ( int ) $CFG -> version < $lastmajordbchanges or
during_initial_install () or ! empty ( $CFG -> adminsetuppending )) {
try {
@ session_get_instance () -> terminate_current ();
} catch ( Exception $e ) {
// Ignore any errors, redirect to upgrade anyway.
}
2009-11-08 22:10:45 +00:00
$url = $CFG -> wwwroot . '/' . $CFG -> admin . '/index.php' ;
2009-07-10 08:44:01 +00:00
@ header ( $_SERVER [ 'SERVER_PROTOCOL' ] . ' 303 See Other' );
2009-11-08 22:10:45 +00:00
@ header ( 'Location: ' . $url );
echo bootstrap_renderer :: plain_redirect_message ( htmlspecialchars ( $url ));
2009-07-10 08:44:01 +00:00
exit ;
}
}
2006-01-05 07:08:10 +00:00
/**
2010-08-29 14:33:39 +00:00
* Function to check if a directory exists and by default create it if not exists .
*
* Previously this was accepting paths only from dataroot , but we now allow
* files outside of dataroot if you supply custom paths for some settings in config . php .
* This function does not verify that the directory is writable .
2006-01-05 07:08:10 +00:00
*
2011-11-19 10:36:37 +01:00
* NOTE : this function uses current file stat cache ,
* please use clearstatcache () before this if you expect that the
* directories may have been removed recently from a different request .
*
2010-08-29 14:33:39 +00:00
* @ param string $dir absolute directory path
* @ param boolean $create directory if does not exist
* @ param boolean $recursive create directory recursively
* @ return boolean true if directory exists or created , false otherwise
2006-01-05 07:08:10 +00:00
*/
2010-08-29 14:33:39 +00:00
function check_dir_exists ( $dir , $create = true , $recursive = true ) {
2006-01-05 07:08:10 +00:00
global $CFG ;
2010-08-29 14:33:39 +00:00
umask ( 0000 ); // just in case some evil code changed it
2006-01-05 07:08:10 +00:00
2010-08-29 14:33:39 +00:00
if ( is_dir ( $dir )) {
return true ;
}
2006-01-05 07:08:10 +00:00
2010-08-29 14:33:39 +00:00
if ( ! $create ) {
return false ;
2006-08-18 09:54:09 +00:00
}
2010-08-29 14:33:39 +00:00
return mkdir ( $dir , $CFG -> directorypermissions , $recursive );
}
/**
2011-08-23 11:26:46 +09:30
* Create a directory and make sure it is writable .
2010-08-29 14:33:39 +00:00
*
2011-09-10 11:22:57 +02:00
* @ private
2011-08-23 11:26:46 +09:30
* @ param string $dir the full path of the directory to be created
2010-08-29 14:33:39 +00:00
* @ param bool $exceptiononerror throw exception if error encountered
* @ return string | false Returns full path to directory if successful , false if not ; may throw exception
*/
2011-08-23 11:26:46 +09:30
function make_writable_directory ( $dir , $exceptiononerror = true ) {
2010-08-29 14:33:39 +00:00
global $CFG ;
if ( file_exists ( $dir ) and ! is_dir ( $dir )) {
if ( $exceptiononerror ) {
throw new coding_exception ( $dir . ' directory can not be created, file with the same name already exists.' );
} else {
return false ;
}
}
umask ( 0000 ); // just in case some evil code changed it
if ( ! file_exists ( $dir )) {
if ( ! mkdir ( $dir , $CFG -> directorypermissions , true )) {
if ( $exceptiononerror ) {
throw new invalid_dataroot_permissions ( $dir . ' can not be created, check permissions.' );
} else {
2006-01-05 07:08:10 +00:00
return false ;
}
}
}
2010-08-29 14:33:39 +00:00
if ( ! is_writable ( $dir )) {
if ( $exceptiononerror ) {
throw new invalid_dataroot_permissions ( $dir . ' is not writable, check permissions.' );
} else {
return false ;
}
}
return $dir ;
2006-01-05 07:08:10 +00:00
}
2011-08-23 11:26:46 +09:30
/**
* Protect a directory from web access .
* Could be extended in the future to support other mechanisms ( e . g . other webservers ) .
*
2011-09-10 11:22:57 +02:00
* @ private
2011-08-23 11:26:46 +09:30
* @ param string $dir the full path of the directory to be protected
*/
function protect_directory ( $dir ) {
// Make sure a .htaccess file is here, JUST IN CASE the files area is in the open and .htaccess is supported
if ( ! file_exists ( " $dir /.htaccess " )) {
if ( $handle = fopen ( " $dir /.htaccess " , 'w' )) { // For safety
@ 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 " );
@ fclose ( $handle );
}
}
}
/**
* Create a directory under dataroot and make sure it is writable .
2011-09-10 11:22:57 +02:00
* Do not use for temporary and cache files - see make_temp_directory () and make_cache_directory () .
2011-08-23 11:26:46 +09:30
*
* @ param string $directory the full path of the directory to be created under $CFG -> dataroot
* @ param bool $exceptiononerror throw exception if error encountered
* @ return string | false Returns full path to directory if successful , false if not ; may throw exception
*/
function make_upload_directory ( $directory , $exceptiononerror = true ) {
global $CFG ;
2011-09-10 11:22:57 +02:00
if ( strpos ( $directory , 'temp/' ) === 0 or $directory === 'temp' ) {
debugging ( 'Use make_temp_directory() for creation of temporary directory and $CFG->tempdir to get the location.' );
} else if ( strpos ( $directory , 'cache/' ) === 0 or $directory === 'cache' ) {
debugging ( 'Use make_cache_directory() for creation of chache directory and $CFG->cachedir to get the location.' );
}
2011-08-23 11:26:46 +09:30
protect_directory ( $CFG -> dataroot );
return make_writable_directory ( " $CFG->dataroot / $directory " , $exceptiononerror );
}
/**
* Create a directory under tempdir and make sure it is writable .
2011-09-10 11:22:57 +02:00
* Temporary files should be used during the current request only !
2011-08-23 11:26:46 +09:30
*
* @ param string $directory the full path of the directory to be created under $CFG -> tempdir
* @ param bool $exceptiononerror throw exception if error encountered
* @ return string | false Returns full path to directory if successful , false if not ; may throw exception
*/
function make_temp_directory ( $directory , $exceptiononerror = true ) {
global $CFG ;
2011-12-10 17:35:22 +01:00
if ( $CFG -> tempdir !== " $CFG->dataroot /temp " ) {
check_dir_exists ( $CFG -> tempdir , true , true );
protect_directory ( $CFG -> tempdir );
2011-12-12 15:06:47 +01:00
} else {
protect_directory ( $CFG -> dataroot );
2011-12-10 17:35:22 +01:00
}
2011-08-23 11:26:46 +09:30
return make_writable_directory ( " $CFG->tempdir / $directory " , $exceptiononerror );
}
/**
* Create a directory under cachedir and make sure it is writable .
*
* @ param string $directory the full path of the directory to be created under $CFG -> cachedir
* @ param bool $exceptiononerror throw exception if error encountered
* @ return string | false Returns full path to directory if successful , false if not ; may throw exception
*/
function make_cache_directory ( $directory , $exceptiononerror = true ) {
global $CFG ;
2011-12-10 17:35:22 +01:00
if ( $CFG -> cachedir !== " $CFG->dataroot /cache " ) {
check_dir_exists ( $CFG -> cachedir , true , true );
protect_directory ( $CFG -> cachedir );
2011-12-12 15:06:47 +01:00
} else {
protect_directory ( $CFG -> dataroot );
2011-12-10 17:35:22 +01:00
}
2011-08-23 11:26:46 +09:30
return make_writable_directory ( " $CFG->cachedir / $directory " , $exceptiononerror );
}
2011-02-14 15:42:26 +01:00
/**
* Checks if current user is a web crawler .
*
* This list can not be made complete , this is not a security
* restriction , we make the list only to help these sites
* especially when automatic guest login is disabled .
*
* If admin needs security they should enable forcelogin
* and disable guest access !!
*
* @ return bool
*/
function is_web_crawler () {
if ( ! empty ( $_SERVER [ 'HTTP_USER_AGENT' ])) {
if ( strpos ( $_SERVER [ 'HTTP_USER_AGENT' ], 'Googlebot' ) !== false ) {
return true ;
} else if ( strpos ( $_SERVER [ 'HTTP_USER_AGENT' ], 'google.com' ) !== false ) { // Google
return true ;
} else if ( strpos ( $_SERVER [ 'HTTP_USER_AGENT' ], 'Yahoo! Slurp' ) !== false ) { // Yahoo
return true ;
} else if ( strpos ( $_SERVER [ 'HTTP_USER_AGENT' ], '[ZSEBOT]' ) !== false ) { // Zoomspider
return true ;
2012-11-10 19:07:08 +01:00
} else if ( stripos ( $_SERVER [ 'HTTP_USER_AGENT' ], 'msnbot' ) !== false ) { // MSN Search
return true ;
} else if ( strpos ( $_SERVER [ 'HTTP_USER_AGENT' ], 'bingbot' ) !== false ) { // Bing
2011-02-14 15:42:26 +01:00
return true ;
} else if ( strpos ( $_SERVER [ 'HTTP_USER_AGENT' ], 'Yandex' ) !== false ) {
return true ;
} else if ( strpos ( $_SERVER [ 'HTTP_USER_AGENT' ], 'AltaVista' ) !== false ) {
return true ;
2012-11-10 19:07:08 +01:00
} else if ( stripos ( $_SERVER [ 'HTTP_USER_AGENT' ], 'baiduspider' ) !== false ) { // Baidu
return true ;
} else if ( strpos ( $_SERVER [ 'HTTP_USER_AGENT' ], 'Teoma' ) !== false ) { // Ask.com
return true ;
2011-02-14 15:42:26 +01:00
}
}
return false ;
}
2006-12-27 22:47:14 +00:00
2009-06-29 05:00:45 +00:00
/**
* This class solves the problem of how to initialise $OUTPUT .
*
* The problem is caused be two factors
* < ol >
* < li > On the one hand , we cannot be sure when output will start . In particular ,
2009-10-31 14:17:44 +00:00
* an error , which needs to be displayed , could be thrown at any time .</ li >
2009-06-29 05:00:45 +00:00
* < li > On the other hand , we cannot be sure when we will have all the information
* necessary to correctly initialise $OUTPUT . $OUTPUT depends on the theme , which
* ( potentially ) depends on the current course , course categories , and logged in user .
* It also depends on whether the current page requires HTTPS .</ li >
* </ ol >
*
* So , it is hard to find a single natural place during Moodle script execution ,
* which we can guarantee is the right time to initialise $OUTPUT . Instead we
* adopt the following strategy
* < ol >
* < li > We will initialise $OUTPUT the first time it is used .</ li >
* < li > If , after $OUTPUT has been initialised , the script tries to change something
2009-08-06 14:21:34 +00:00
* that $OUTPUT depends on , we throw an exception making it clear that the script
2009-06-29 05:00:45 +00:00
* did something wrong .
* </ ol >
*
* The only problem with that is , how do we initialise $OUTPUT on first use if ,
* it is going to be used like $OUTPUT -> somthing ( ... ) ? Well that is where this
* class comes in . Initially , we set up $OUTPUT = new bootstrap_renderer () . Then ,
* when any method is called on that object , we initialise $OUTPUT , and pass the call on .
*
* Note that this class is used before lib / outputlib . php has been loaded , so we
2009-11-01 10:05:07 +00:00
* must be careful referring to classes / functions from there , they may not be
2009-06-29 05:00:45 +00:00
* defined yet , and we must avoid fatal errors .
*
* @ copyright 2009 Tim Hunt
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.0
*/
class bootstrap_renderer {
/**
* Handles re - entrancy . Without this , errors or debugging output that occur
* during the initialisation of $OUTPUT , cause infinite recursion .
* @ var boolean
*/
protected $initialising = false ;
2009-07-01 05:54:26 +00:00
/**
* Have we started output yet ?
* @ return boolean true if the header has been printed .
*/
public function has_started () {
return false ;
}
2011-10-25 08:54:30 +02:00
/**
* Constructor - to be used by core code only .
2012-02-21 11:48:33 +13:00
* @ param string $method The method to call
* @ param array $arguments Arguments to pass to the method being called
2011-10-25 08:54:30 +02:00
* @ return string
*/
2009-06-29 05:00:45 +00:00
public function __call ( $method , $arguments ) {
2009-07-01 05:54:26 +00:00
global $OUTPUT , $PAGE ;
2009-06-29 05:00:45 +00:00
2009-07-07 04:37:12 +00:00
$recursing = false ;
if ( $method == 'notification' ) {
2009-11-01 10:05:07 +00:00
// Catch infinite recursion caused by debugging output during print_header.
2009-07-07 04:37:12 +00:00
$backtrace = debug_backtrace ();
array_shift ( $backtrace );
array_shift ( $backtrace );
2009-10-30 13:44:07 +00:00
$recursing = is_early_init ( $backtrace );
2009-07-07 04:37:12 +00:00
}
2010-08-16 19:11:21 +00:00
$earlymethods = array (
'fatal_error' => 'early_error' ,
'notification' => 'early_notification' ,
);
2009-06-29 05:00:45 +00:00
// If lib/outputlib.php has been loaded, call it.
2009-07-07 04:37:12 +00:00
if ( ! empty ( $PAGE ) && ! $recursing ) {
2010-08-16 19:11:21 +00:00
if ( array_key_exists ( $method , $earlymethods )) {
//prevent PAGE->context warnings - exceptions might appear before we set any context
$PAGE -> set_context ( null );
}
2009-07-01 05:54:26 +00:00
$PAGE -> initialise_theme_and_output ();
return call_user_func_array ( array ( $OUTPUT , $method ), $arguments );
2009-06-29 05:00:45 +00:00
}
2006-12-27 22:47:14 +00:00
2009-06-29 05:00:45 +00:00
$this -> initialising = true ;
2010-08-16 19:11:21 +00:00
2009-06-29 05:00:45 +00:00
// Too soon to initialise $OUTPUT, provide a couple of key methods.
if ( array_key_exists ( $method , $earlymethods )) {
return call_user_func_array ( array ( 'bootstrap_renderer' , $earlymethods [ $method ]), $arguments );
}
throw new coding_exception ( 'Attempt to start output before enough information is known to initialise the theme.' );
}
/**
2009-11-01 10:05:07 +00:00
* Returns nicely formatted error message in a div box .
2011-10-21 16:35:19 +02:00
* @ static
* @ param string $message error message
2011-10-25 08:54:30 +02:00
* @ param string $moreinfourl ( ignored in early errors )
* @ param string $link ( ignored in early errors )
2011-10-21 16:35:19 +02:00
* @ param array $backtrace
* @ param string $debuginfo
2009-10-31 14:17:44 +00:00
* @ return string
2009-06-29 05:00:45 +00:00
*/
2009-10-31 15:01:25 +00:00
public static function early_error_content ( $message , $moreinfourl , $link , $backtrace , $debuginfo = null ) {
2009-07-01 05:54:26 +00:00
global $CFG ;
2009-10-31 15:01:25 +00:00
$content = ' < div style = " margin-top: 6em; margin-left:auto; margin-right:auto; color:#990000; text-align:center; font-size:large; border-width:1px;
border - color : black ; background - color : #ffffee; border-style:solid; border-radius: 20px; border-collapse: collapse;
width : 80 % ; - moz - border - radius : 20 px ; padding : 15 px " >
' . $message . '
</ div > ' ;
2012-11-13 09:26:07 +13:00
// Check whether debug is set.
$debug = ( ! empty ( $CFG -> debug ) && $CFG -> debug >= DEBUG_DEVELOPER );
// Also check we have it set in the config file. This occurs if the method to read the config table from the
// database fails, reading from the config table is the first database interaction we have.
$debug = $debug || ( ! empty ( $CFG -> config_php_settings [ 'debug' ]) && $CFG -> config_php_settings [ 'debug' ] >= DEBUG_DEVELOPER );
if ( $debug ) {
2009-10-31 15:01:25 +00:00
if ( ! empty ( $debuginfo )) {
2010-03-20 13:46:15 +00:00
$debuginfo = s ( $debuginfo ); // removes all nasty JS
$debuginfo = str_replace ( " \n " , '<br />' , $debuginfo ); // keep newlines
$content .= '<div class="notifytiny">Debug info: ' . $debuginfo . '</div>' ;
2009-10-31 15:01:25 +00:00
}
if ( ! empty ( $backtrace )) {
$content .= '<div class="notifytiny">Stack trace: ' . format_backtrace ( $backtrace , false ) . '</div>' ;
}
}
return $content ;
}
/**
* This function should only be called by this class , or from exception handlers
2011-10-21 16:35:19 +02:00
* @ static
* @ param string $message error message
2011-10-25 08:54:30 +02:00
* @ param string $moreinfourl ( ignored in early errors )
* @ param string $link ( ignored in early errors )
2011-10-21 16:35:19 +02:00
* @ param array $backtrace
2011-10-25 08:54:30 +02:00
* @ param string $debuginfo extra information for developers
2009-10-31 15:01:25 +00:00
* @ return string
*/
public static function early_error ( $message , $moreinfourl , $link , $backtrace , $debuginfo = null ) {
2010-03-28 09:05:47 +00:00
global $CFG ;
if ( CLI_SCRIPT ) {
echo " !!! $message !!! \n " ;
if ( ! empty ( $CFG -> debug ) and $CFG -> debug >= DEBUG_DEVELOPER ) {
if ( ! empty ( $debuginfo )) {
echo " \n Debug info: $debuginfo " ;
}
if ( ! empty ( $backtrace )) {
echo " \n Stack trace: " . format_backtrace ( $backtrace , true );
}
}
return ;
} else if ( AJAX_SCRIPT ) {
$e = new stdClass ();
$e -> error = $message ;
$e -> stacktrace = NULL ;
$e -> debuginfo = NULL ;
if ( ! empty ( $CFG -> debug ) and $CFG -> debug >= DEBUG_DEVELOPER ) {
if ( ! empty ( $debuginfo )) {
$e -> debuginfo = $debuginfo ;
}
if ( ! empty ( $backtrace )) {
$e -> stacktrace = format_backtrace ( $backtrace , true );
}
}
2011-01-14 09:32:17 +01:00
@ header ( 'Content-Type: application/json; charset=utf-8' );
2010-03-28 09:05:47 +00:00
echo json_encode ( $e );
return ;
}
2009-06-29 05:00:45 +00:00
// In the name of protocol correctness, monitoring and performance
2009-11-01 10:05:07 +00:00
// profiling, set the appropriate error headers for machine consumption
2009-06-29 05:00:45 +00:00
if ( isset ( $_SERVER [ 'SERVER_PROTOCOL' ])) {
// Avoid it with cron.php. Note that we assume it's HTTP/1.x
2009-11-01 10:05:07 +00:00
// The 503 ode here means our Moodle does not work at all, the error happened too early
2009-06-29 05:00:45 +00:00
@ header ( $_SERVER [ 'SERVER_PROTOCOL' ] . ' 503 Service Unavailable' );
}
// better disable any caching
@ header ( 'Content-Type: text/html; charset=utf-8' );
2012-11-09 17:27:29 +01:00
@ header ( 'X-UA-Compatible: IE=edge' );
2009-06-29 05:00:45 +00:00
@ header ( 'Cache-Control: no-store, no-cache, must-revalidate' );
@ header ( 'Cache-Control: post-check=0, pre-check=0' , false );
@ header ( 'Pragma: no-cache' );
@ header ( 'Expires: Mon, 20 Aug 1969 09:23:00 GMT' );
@ header ( 'Last-Modified: ' . gmdate ( 'D, d M Y H:i:s' ) . ' GMT' );
2009-07-10 08:44:01 +00:00
if ( function_exists ( 'get_string' )) {
2009-06-29 05:00:45 +00:00
$strerror = get_string ( 'error' );
} else {
$strerror = 'Error' ;
}
2009-10-31 15:01:25 +00:00
$content = self :: early_error_content ( $message , $moreinfourl , $link , $backtrace , $debuginfo );
2009-07-10 08:44:01 +00:00
return self :: plain_page ( $strerror , $content );
2009-06-29 05:00:45 +00:00
}
2011-10-21 16:35:19 +02:00
/**
* Early notification message
* @ static
2012-02-21 11:48:33 +13:00
* @ param string $message
2011-10-25 08:54:30 +02:00
* @ param string $classes usually notifyproblem or notifysuccess
2011-10-21 16:35:19 +02:00
* @ return string
*/
2009-06-29 05:00:45 +00:00
public static function early_notification ( $message , $classes = 'notifyproblem' ) {
return '<div class="' . $classes . '">' . $message . '</div>' ;
}
2009-07-10 08:44:01 +00:00
2011-10-21 16:35:19 +02:00
/**
* Page should redirect message .
* @ static
2012-02-21 11:48:33 +13:00
* @ param string $encodedurl redirect url
2011-10-21 16:35:19 +02:00
* @ return string
*/
2009-07-10 08:44:01 +00:00
public static function plain_redirect_message ( $encodedurl ) {
2011-10-25 08:54:30 +02:00
$message = '<div style="margin-top: 3em; margin-left:auto; margin-right:auto; text-align:center;">' . get_string ( 'pageshouldredirect' ) . '<br /><a href="' .
2011-10-21 16:35:19 +02:00
$encodedurl . '">' . get_string ( 'continue' ) . '</a></div>' ;
2009-08-31 07:13:41 +00:00
return self :: plain_page ( get_string ( 'redirect' ), $message );
2009-07-10 08:44:01 +00:00
}
2011-10-21 16:35:19 +02:00
/**
* Early redirection page , used before full init of $PAGE global
* @ static
2012-02-21 11:48:33 +13:00
* @ param string $encodedurl redirect url
* @ param string $message redirect message
* @ param int $delay time in seconds
2011-10-25 08:54:30 +02:00
* @ return string redirect page
2011-10-21 16:35:19 +02:00
*/
public static function early_redirect_message ( $encodedurl , $message , $delay ) {
$meta = '<meta http-equiv="refresh" content="' . $delay . '; url=' . $encodedurl . '" />' ;
$content = self :: early_error_content ( $message , null , null , null );
$content .= self :: plain_redirect_message ( $encodedurl );
return self :: plain_page ( get_string ( 'redirect' ), $content , $meta );
}
/**
* Output basic html page .
* @ static
2012-02-21 11:48:33 +13:00
* @ param string $title page title
* @ param string $content page content
2011-10-25 08:54:30 +02:00
* @ param string $meta meta tag
* @ return string html page
2011-10-21 16:35:19 +02:00
*/
protected static function plain_page ( $title , $content , $meta = '' ) {
2009-07-10 08:44:01 +00:00
if ( function_exists ( 'get_string' ) && function_exists ( 'get_html_lang' )) {
$htmllang = get_html_lang ();
} else {
$htmllang = '' ;
}
return ' <! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Strict//EN " " http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd " >
< html xmlns = " http://www.w3.org/1999/xhtml " ' . $htmllang . ' >
< head >
< meta http - equiv = " Content-Type " content = " text/html; charset=utf-8 " />
2011-10-21 16:35:19 +02:00
'.$meta.'
2009-07-10 08:44:01 +00:00
< title > ' . $title . ' </ title >
</ head >< body > ' . $content . ' </ body ></ html > ' ;
}
2009-06-29 05:00:45 +00:00
}