2009-08-10 06:22:04 +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/>.
/**
* Classes for rendering HTML output for Moodle .
*
* Please see http :// docs . moodle . org / en / Developement : How_Moodle_outputs_HTML
* for an overview .
*
* @ package moodlecore
* @ copyright 2009 Tim Hunt
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
/**
* Simple base class for Moodle renderers .
*
* Tracks the xhtml_container_stack to use , which is passed in in the constructor .
*
* Also has methods to facilitate generating HTML output .
*
* @ copyright 2009 Tim Hunt
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.0
*/
2009-12-16 18:00:58 +00:00
class renderer_base {
2009-08-10 06:22:04 +00:00
/** @var xhtml_container_stack the xhtml_container_stack to use. */
protected $opencontainers ;
/** @var moodle_page the page we are rendering for. */
protected $page ;
2010-05-22 14:43:46 +00:00
/** @var requested rendering target */
2009-12-17 22:43:27 +00:00
protected $target ;
2009-08-10 06:22:04 +00:00
/**
* Constructor
* @ param moodle_page $page the page we are doing output for .
2009-12-17 22:43:27 +00:00
* @ param string $target one of rendering target constants
2009-08-10 06:22:04 +00:00
*/
2009-12-17 22:43:27 +00:00
public function __construct ( moodle_page $page , $target ) {
2009-08-10 06:22:04 +00:00
$this -> opencontainers = $page -> opencontainers ;
$this -> page = $page ;
2009-12-17 22:43:27 +00:00
$this -> target = $target ;
2009-08-10 06:22:04 +00:00
}
/**
2010-01-13 17:13:52 +00:00
* Returns rendered widget .
2010-05-22 14:43:46 +00:00
* @ param renderable $widget instance with renderable interface
2010-01-13 17:13:52 +00:00
* @ return string
2009-08-10 06:22:04 +00:00
*/
2010-01-13 17:13:52 +00:00
public function render ( renderable $widget ) {
2010-05-04 08:29:05 +00:00
$rendermethod = 'render_' . get_class ( $widget );
2010-01-13 17:13:52 +00:00
if ( method_exists ( $this , $rendermethod )) {
return $this -> $rendermethod ( $widget );
}
throw new coding_exception ( 'Can not render widget, renderer method (' . $rendermethod . ') not found.' );
2009-08-10 06:22:04 +00:00
}
/**
2010-01-13 17:13:52 +00:00
* Adds JS handlers needed for event execution for one html element id
* @ param component_action $actions
2010-02-11 15:44:06 +00:00
* @ param string $id
* @ return string id of element , either original submitted or random new if not supplied
2009-08-10 06:22:04 +00:00
*/
2010-02-11 15:44:06 +00:00
public function add_action_handler ( component_action $action , $id = null ) {
if ( ! $id ) {
$id = html_writer :: random_id ( $action -> event );
}
2010-01-19 22:01:12 +00:00
$this -> page -> requires -> event_handler ( " # $id " , $action -> event , $action -> jsfunction , $action -> jsfunctionargs );
2010-02-11 15:44:06 +00:00
return $id ;
2009-08-10 06:22:04 +00:00
}
/**
2010-01-13 17:13:52 +00:00
* Have we started output yet ?
* @ return boolean true if the header has been printed .
2009-08-10 06:22:04 +00:00
*/
2010-01-13 17:13:52 +00:00
public function has_started () {
return $this -> page -> state >= moodle_page :: STATE_IN_BODY ;
2009-08-10 06:22:04 +00:00
}
/**
* Given an array or space - separated list of classes , prepares and returns the HTML class attribute value
* @ param mixed $classes Space - separated string or array of classes
* @ return string HTML class attribute value
*/
public static function prepare_classes ( $classes ) {
if ( is_array ( $classes )) {
return implode ( ' ' , array_unique ( $classes ));
}
return $classes ;
}
/**
2010-01-04 14:40:34 +00:00
* Return the moodle_url for an image .
* The exact image location and extension is determined
* automatically by searching for gif | png | jpg | jpeg , please
* note there can not be diferent images with the different
* extension . The imagename is for historical reasons
* a relative path name , it may be changed later for core
* images . It is recommended to not use subdirectories
* in plugin and theme pix directories .
2009-08-10 06:22:04 +00:00
*
2010-01-04 14:40:34 +00:00
* There are three types of images :
* 1 / theme images - stored in theme / mytheme / pix / ,
* use component 'theme'
* 2 / core images - stored in / pix / ,
* overridden via theme / mytheme / pix_core /
* 3 / plugin images - stored in mod / mymodule / pix ,
* overridden via theme / mytheme / pix_plugins / mod / mymodule / ,
* example : pix_url ( 'comment' , 'mod_glossary' )
*
* @ param string $imagename the pathname of the image
* @ param string $component full plugin name ( aka component ) or 'theme'
2009-12-16 18:00:58 +00:00
* @ return moodle_url
2009-08-10 06:22:04 +00:00
*/
2009-12-17 22:43:27 +00:00
public function pix_url ( $imagename , $component = 'moodle' ) {
2009-12-16 20:33:37 +00:00
return $this -> page -> theme -> pix_url ( $imagename , $component );
2009-08-10 06:22:04 +00:00
}
}
2009-12-17 22:43:27 +00:00
2009-12-17 14:51:36 +00:00
/**
* Basis for all plugin renderers .
*
2009-12-17 22:43:27 +00:00
* @ author Petr Skoda ( skodak )
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.0
2009-12-17 14:51:36 +00:00
*/
class plugin_renderer_base extends renderer_base {
/**
* A reference to the current general renderer probably { @ see core_renderer }
* @ var renderer_base
*/
protected $output ;
/**
2010-05-22 14:43:46 +00:00
* Constructor method , calls the parent constructor
2009-12-17 14:51:36 +00:00
* @ param moodle_page $page
2009-12-17 22:43:27 +00:00
* @ param string $target one of rendering target constants
2009-12-17 14:51:36 +00:00
*/
2009-12-17 22:43:27 +00:00
public function __construct ( moodle_page $page , $target ) {
$this -> output = $page -> get_renderer ( 'core' , null , $target );
parent :: __construct ( $page , $target );
2009-12-17 14:51:36 +00:00
}
2009-12-17 14:54:04 +00:00
2010-01-13 17:13:52 +00:00
/**
* Returns rendered widget .
2010-05-22 20:16:12 +00:00
* @ param renderable $widget instance with renderable interface
2010-01-13 17:13:52 +00:00
* @ return string
*/
public function render ( renderable $widget ) {
$rendermethod = 'render_' . get_class ( $widget );
if ( method_exists ( $this , $rendermethod )) {
return $this -> $rendermethod ( $widget );
}
// pass to core renderer if method not found here
$this -> output -> render ( $widget );
}
2009-12-17 14:54:04 +00:00
/**
* Magic method used to pass calls otherwise meant for the standard renderer
2010-05-22 14:43:46 +00:00
* to it to ensure we don ' t go causing unnecessary grief .
2009-12-17 14:54:04 +00:00
*
* @ param string $method
* @ param array $arguments
* @ return mixed
*/
public function __call ( $method , $arguments ) {
2009-12-20 16:34:18 +00:00
if ( method_exists ( 'renderer_base' , $method )) {
throw new coding_exception ( 'Protected method called against ' . __CLASS__ . ' :: ' . $method );
}
2009-12-17 14:54:04 +00:00
if ( method_exists ( $this -> output , $method )) {
return call_user_func_array ( array ( $this -> output , $method ), $arguments );
} else {
throw new coding_exception ( 'Unknown method called against ' . __CLASS__ . ' :: ' . $method );
}
}
2009-12-17 14:51:36 +00:00
}
2009-08-10 06:22:04 +00:00
2009-12-17 22:43:27 +00:00
2009-08-10 06:22:04 +00:00
/**
2009-12-16 18:00:58 +00:00
* The standard implementation of the core_renderer interface .
2009-08-10 06:22:04 +00:00
*
* @ copyright 2009 Tim Hunt
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.0
*/
2009-12-16 18:00:58 +00:00
class core_renderer extends renderer_base {
2009-08-10 06:22:04 +00:00
/** @var string used in {@link header()}. */
const PERFORMANCE_INFO_TOKEN = '%%PERFORMANCEINFO%%' ;
/** @var string used in {@link header()}. */
const END_HTML_TOKEN = '%%ENDHTML%%' ;
/** @var string used in {@link header()}. */
const MAIN_CONTENT_TOKEN = '[MAIN CONTENT GOES HERE]' ;
/** @var string used to pass information from {@link doctype()} to {@link standard_head_html()}. */
protected $contenttype ;
/** @var string used by {@link redirect_message()} method to communicate with {@link header()}. */
protected $metarefreshtag = '' ;
/**
* Get the DOCTYPE declaration that should be used with this page . Designed to
* be called in theme layout . php files .
* @ return string the DOCTYPE declaration ( and any XML prologue ) that should be used .
*/
public function doctype () {
global $CFG ;
$doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' . " \n " ;
$this -> contenttype = 'text/html; charset=utf-8' ;
if ( empty ( $CFG -> xmlstrictheaders )) {
return $doctype ;
}
// We want to serve the page with an XML content type, to force well-formedness errors to be reported.
$prolog = '<?xml version="1.0" encoding="utf-8"?>' . " \n " ;
if ( isset ( $_SERVER [ 'HTTP_ACCEPT' ]) && strpos ( $_SERVER [ 'HTTP_ACCEPT' ], 'application/xhtml+xml' ) !== false ) {
// Firefox and other browsers that can cope natively with XHTML.
$this -> contenttype = 'application/xhtml+xml; charset=utf-8' ;
} else if ( preg_match ( '/MSIE.*Windows NT/' , $_SERVER [ 'HTTP_USER_AGENT' ])) {
// IE can't cope with application/xhtml+xml, but it will cope if we send application/xml with an XSL stylesheet.
$this -> contenttype = 'application/xml; charset=utf-8' ;
$prolog .= '<?xml-stylesheet type="text/xsl" href="' . $CFG -> httpswwwroot . '/lib/xhtml.xsl"?>' . " \n " ;
} else {
$prolog = '' ;
}
return $prolog . $doctype ;
}
/**
* The attributes that should be added to the < html > tag . Designed to
* be called in theme layout . php files .
* @ return string HTML fragment .
*/
public function htmlattributes () {
return get_html_lang ( true ) . ' xmlns="http://www.w3.org/1999/xhtml"' ;
}
/**
* The standard tags ( meta tags , links to stylesheets and JavaScript , etc . )
* that should be included in the < head > tag . Designed to be called in theme
* layout . php files .
* @ return string HTML fragment .
*/
public function standard_head_html () {
2009-12-02 06:38:16 +00:00
global $CFG , $SESSION ;
2009-08-10 06:22:04 +00:00
$output = '' ;
$output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . " \n " ;
$output .= '<meta name="keywords" content="moodle, ' . $this -> page -> title . '" />' . " \n " ;
if ( ! $this -> page -> cacheable ) {
$output .= '<meta http-equiv="pragma" content="no-cache" />' . " \n " ;
$output .= '<meta http-equiv="expires" content="0" />' . " \n " ;
}
// This is only set by the {@link redirect()} method
$output .= $this -> metarefreshtag ;
// Check if a periodic refresh delay has been set and make sure we arn't
// already meta refreshing
if ( $this -> metarefreshtag == '' && $this -> page -> periodicrefreshdelay !== null ) {
$output .= '<meta http-equiv="refresh" content="' . $this -> page -> periodicrefreshdelay . ';url=' . $this -> page -> url -> out () . '" />' ;
}
2009-08-28 08:47:31 +00:00
$this -> page -> requires -> js_function_call ( 'setTimeout' , array ( 'fix_column_widths()' , 20 ));
2009-08-10 06:22:04 +00:00
$focus = $this -> page -> focuscontrol ;
if ( ! empty ( $focus )) {
if ( preg_match ( " #forms \ ['([a-zA-Z0-9]+)' \ ].elements \ ['([a-zA-Z0-9]+)' \ ]# " , $focus , $matches )) {
// This is a horrifically bad way to handle focus but it is passed in
// through messy formslib::moodleform
2009-08-28 08:47:31 +00:00
$this -> page -> requires -> js_function_call ( 'old_onload_focus' , array ( $matches [ 1 ], $matches [ 2 ]));
2009-08-10 06:22:04 +00:00
} else if ( strpos ( $focus , '.' ) !== false ) {
// Old style of focus, bad way to do it
debugging ( 'This code is using the old style focus event, Please update this code to focus on an element id or the moodleform focus method.' , DEBUG_DEVELOPER );
$this -> page -> requires -> js_function_call ( 'old_onload_focus' , explode ( '.' , $focus , 2 ));
} else {
// Focus element with given id
2009-08-28 08:47:31 +00:00
$this -> page -> requires -> js_function_call ( 'focuscontrol' , array ( $focus ));
2009-08-10 06:22:04 +00:00
}
}
2009-12-16 18:00:58 +00:00
// Get the theme stylesheet - this has to be always first CSS, this loads also styles.css from all plugins;
// any other custom CSS can not be overridden via themes and is highly discouraged
2010-01-05 00:33:15 +00:00
$urls = $this -> page -> theme -> css_urls ( $this -> page );
2009-12-16 18:00:58 +00:00
foreach ( $urls as $url ) {
2010-01-18 20:02:13 +00:00
$this -> page -> requires -> css_theme ( $url );
2009-12-16 18:00:58 +00:00
}
2010-01-05 23:22:16 +00:00
// Get the theme javascript head and footer
$jsurl = $this -> page -> theme -> javascript_url ( true );
2010-02-07 13:08:46 +00:00
$this -> page -> requires -> js ( $jsurl , true );
$jsurl = $this -> page -> theme -> javascript_url ( false );
2010-01-26 09:00:50 +00:00
$this -> page -> requires -> js ( $jsurl );
2010-01-13 17:13:52 +00:00
2009-12-16 18:00:58 +00:00
// Perform a browser environment check for the flash version. Should only run once per login session.
2010-02-15 19:05:33 +00:00
if ( ! NO_MOODLE_COOKIES && isloggedin () && ! empty ( $CFG -> excludeoldflashclients ) && empty ( $SESSION -> flashversion )) {
2010-02-06 12:58:19 +00:00
$this -> page -> requires -> js ( '/lib/swfobject/swfobject.js' );
$this -> page -> requires -> js_init_call ( 'M.core_flashdetect.init' );
2009-12-02 06:38:16 +00:00
}
2009-08-10 06:22:04 +00:00
// Get any HTML from the page_requirements_manager.
2009-12-28 23:08:55 +00:00
$output .= $this -> page -> requires -> get_head_code ( $this -> page , $this );
2009-08-10 06:22:04 +00:00
// List alternate versions.
foreach ( $this -> page -> alternateversions as $type => $alt ) {
2010-01-13 17:13:52 +00:00
$output .= html_writer :: empty_tag ( 'link' , array ( 'rel' => 'alternate' ,
2009-08-10 06:22:04 +00:00
'type' => $type , 'title' => $alt -> title , 'href' => $alt -> url ));
}
return $output ;
}
/**
* The standard tags ( typically skip links ) that should be output just inside
* the start of the < body > tag . Designed to be called in theme layout . php files .
* @ return string HTML fragment .
*/
public function standard_top_of_body_html () {
return $this -> page -> requires -> get_top_of_body_code ();
}
/**
* The standard tags ( typically performance information and validation links ,
* if we are in developer debug mode ) that should be output in the footer area
* of the page . Designed to be called in theme layout . php files .
* @ return string HTML fragment .
*/
public function standard_footer_html () {
global $CFG ;
// This function is normally called from a layout.php file in {@link header()}
// but some of the content won't be known until later, so we return a placeholder
// for now. This will be replaced with the real content in {@link footer()}.
$output = self :: PERFORMANCE_INFO_TOKEN ;
2010-04-21 04:21:53 +00:00
if ( $this -> page -> legacythemeinuse ) {
// The legacy theme is in use print the notification
$output .= html_writer :: tag ( 'div' , get_string ( 'legacythemeinuse' ), array ( 'class' => 'legacythemeinuse' ));
}
2009-08-10 06:22:04 +00:00
if ( ! empty ( $CFG -> debugpageinfo )) {
$output .= '<div class="performanceinfo">This page is: ' . $this -> page -> debug_summary () . '</div>' ;
}
if ( ! empty ( $CFG -> debugvalidators )) {
$output .= ' < div class = " validators " >< ul >
< li >< a href = " http://validator.w3.org/check?verbose=1&ss=1&uri=' . urlencode(qualified_me()) . ' " > Validate HTML </ a ></ li >
< li >< a href = " http://www.contentquality.com/mynewtester/cynthia.exe?rptmode=-1&url1=' . urlencode(qualified_me()) . ' " > Section 508 Check </ a ></ li >
< li >< a href = " http://www.contentquality.com/mynewtester/cynthia.exe?rptmode=0&warnp2n3e=1&url1=' . urlencode(qualified_me()) . ' " > WCAG 1 ( 2 , 3 ) Check </ a ></ li >
</ ul ></ div > ' ;
}
return $output ;
}
/**
* The standard tags ( typically script tags that are not needed earlier ) that
* should be output after everything else , . Designed to be called in theme layout . php files .
* @ return string HTML fragment .
*/
public function standard_end_of_body_html () {
// This function is normally called from a layout.php file in {@link header()}
// but some of the content won't be known until later, so we return a placeholder
// for now. This will be replaced with the real content in {@link footer()}.
echo self :: END_HTML_TOKEN ;
}
/**
* Return the standard string that says whether you are logged in ( and switched
* roles / logged in as another user ) .
* @ return string HTML fragment .
*/
public function login_info () {
2009-12-29 17:26:29 +00:00
global $USER , $CFG , $DB ;
2009-12-30 15:19:55 +00:00
2009-12-29 17:26:29 +00:00
if ( during_initial_install ()) {
return '' ;
}
2009-12-30 15:19:55 +00:00
2009-12-29 17:26:29 +00:00
$course = $this -> page -> course ;
2009-12-30 15:19:55 +00:00
2009-12-29 17:26:29 +00:00
if ( session_is_loggedinas ()) {
$realuser = session_get_realuser ();
$fullname = fullname ( $realuser , true );
2010-02-11 13:27:02 +00:00
$realuserinfo = " [<a href= \" $CFG->wwwroot /course/loginas.php?id= $course->id &return=1&sesskey= " . sesskey () . " \" > $fullname </a>] " ;
2009-12-29 17:26:29 +00:00
} else {
$realuserinfo = '' ;
}
2009-12-30 15:19:55 +00:00
2009-12-29 17:26:29 +00:00
$loginurl = get_login_url ();
2009-12-30 15:19:55 +00:00
2009-12-29 17:26:29 +00:00
if ( empty ( $course -> id )) {
// $course->id is not defined during installation
return '' ;
2010-03-31 07:41:31 +00:00
} else if ( isloggedin ()) {
2009-12-29 17:26:29 +00:00
$context = get_context_instance ( CONTEXT_COURSE , $course -> id );
2009-12-30 15:19:55 +00:00
2009-12-29 17:26:29 +00:00
$fullname = fullname ( $USER , true );
2010-05-04 13:04:35 +00:00
// Since Moodle 2.0 this link always goes to the public profile page (not the course profile page)
$username = " <a href= \" $CFG->wwwroot /user/profile.php?id= $USER->id\ " > $fullname </ a > " ;
2009-12-29 17:26:29 +00:00
if ( is_mnet_remote_user ( $USER ) and $idprovider = $DB -> get_record ( 'mnet_host' , array ( 'id' => $USER -> mnethostid ))) {
2010-02-11 13:27:02 +00:00
$username .= " from <a href= \" { $idprovider -> wwwroot } \" > { $idprovider -> name } </a> " ;
2009-12-29 17:26:29 +00:00
}
if ( isset ( $USER -> username ) && $USER -> username == 'guest' ) {
$loggedinas = $realuserinfo . get_string ( 'loggedinasguest' ) .
2010-02-11 13:27:02 +00:00
" (<a href= \" $loginurl\ " > " .get_string('login').'</a>)';
2009-12-29 17:26:29 +00:00
} else if ( ! empty ( $USER -> access [ 'rsw' ][ $context -> path ])) {
$rolename = '' ;
if ( $role = $DB -> get_record ( 'role' , array ( 'id' => $USER -> access [ 'rsw' ][ $context -> path ]))) {
$rolename = ': ' . format_string ( $role -> name );
}
$loggedinas = get_string ( 'loggedinas' , 'moodle' , $username ) . $rolename .
2010-02-11 13:27:02 +00:00
" (<a href= \" $CFG->wwwroot /course/view.php?id= $course->id &switchrole=0&sesskey= " . sesskey () . " \" > " . get_string ( 'switchrolereturn' ) . '</a>)' ;
2009-12-29 17:26:29 +00:00
} else {
$loggedinas = $realuserinfo . get_string ( 'loggedinas' , 'moodle' , $username ) . ' ' .
2010-02-11 13:27:02 +00:00
" (<a href= \" $CFG->wwwroot /login/logout.php?sesskey= " . sesskey () . " \" > " . get_string ( 'logout' ) . '</a>)' ;
2009-12-29 17:26:29 +00:00
}
} else {
$loggedinas = get_string ( 'loggedinnot' , 'moodle' ) .
2010-02-11 13:27:02 +00:00
" (<a href= \" $loginurl\ " > " .get_string('login').'</a>)';
2009-12-29 17:26:29 +00:00
}
2009-12-30 15:19:55 +00:00
2009-12-29 17:26:29 +00:00
$loggedinas = '<div class="logininfo">' . $loggedinas . '</div>' ;
2009-12-30 15:19:55 +00:00
2009-12-29 17:26:29 +00:00
if ( isset ( $SESSION -> justloggedin )) {
unset ( $SESSION -> justloggedin );
if ( ! empty ( $CFG -> displayloginfailures )) {
if ( ! empty ( $USER -> username ) and $USER -> username != 'guest' ) {
if ( $count = count_login_failures ( $CFG -> displayloginfailures , $USER -> username , $USER -> lastlogin )) {
$loggedinas .= ' <div class="loginfailures">' ;
if ( empty ( $count -> accounts )) {
$loggedinas .= get_string ( 'failedloginattempts' , '' , $count );
} else {
$loggedinas .= get_string ( 'failedloginattemptsall' , '' , $count );
}
if ( has_capability ( 'coursereport/log:view' , get_context_instance ( CONTEXT_SYSTEM ))) {
$loggedinas .= ' (<a href="' . $CFG -> wwwroot . '/course/report/log/index.php' .
'?chooselog=1&id=1&modid=site_errors">' . get_string ( 'logs' ) . '</a>)' ;
}
$loggedinas .= '</div>' ;
}
}
}
}
2009-12-30 15:19:55 +00:00
2009-12-29 17:26:29 +00:00
return $loggedinas ;
2009-08-10 06:22:04 +00:00
}
/**
* Return the 'back' link that normally appears in the footer .
* @ return string HTML fragment .
*/
public function home_link () {
global $CFG , $SITE ;
if ( $this -> page -> pagetype == 'site-index' ) {
// Special case for site home page - please do not remove
return '<div class="sitelink">' .
2009-11-17 03:06:39 +00:00
'<a title="Moodle" href="http://moodle.org/">' .
2010-01-04 23:55:09 +00:00
'<img style="width:100px;height:30px" src="' . $this -> pix_url ( 'moodlelogo' ) . '" alt="moodlelogo" /></a></div>' ;
2009-08-10 06:22:04 +00:00
} else if ( ! empty ( $CFG -> target_release ) && $CFG -> target_release != $CFG -> release ) {
// Special case for during install/upgrade.
return '<div class="sitelink">' .
2009-11-17 03:06:39 +00:00
'<a title="Moodle" href="http://docs.moodle.org/en/Administrator_documentation" onclick="this.target=\'_blank\'">' .
2010-01-04 23:55:09 +00:00
'<img style="width:100px;height:30px" src="' . $this -> pix_url ( 'moodlelogo' ) . '" alt="moodlelogo" /></a></div>' ;
2009-08-10 06:22:04 +00:00
} else if ( $this -> page -> course -> id == $SITE -> id || strpos ( $this -> page -> pagetype , 'course-view' ) === 0 ) {
return '<div class="homelink"><a href="' . $CFG -> wwwroot . '/">' .
get_string ( 'home' ) . '</a></div>' ;
} else {
return '<div class="homelink"><a href="' . $CFG -> wwwroot . '/course/view.php?id=' . $this -> page -> course -> id . '">' .
format_string ( $this -> page -> course -> shortname ) . '</a></div>' ;
}
}
/**
* Redirects the user by any means possible given the current state
*
* This function should not be called directly , it should always be called using
* the redirect function in lib / weblib . php
*
* The redirect function should really only be called before page output has started
* however it will allow itself to be called during the state STATE_IN_BODY
*
* @ param string $encodedurl The URL to send to encoded if required
* @ param string $message The message to display to the user if any
* @ param int $delay The delay before redirecting a user , if $message has been
* set this is a requirement and defaults to 3 , set to 0 no delay
* @ param boolean $debugdisableredirect this redirect has been disabled for
* debugging purposes . Display a message that explains , and don ' t
* trigger the redirect .
* @ return string The HTML to display to the user before dying , may contain
* meta refresh , javascript refresh , and may have set header redirects
*/
public function redirect_message ( $encodedurl , $message , $delay , $debugdisableredirect ) {
global $CFG ;
$url = str_replace ( '&' , '&' , $encodedurl );
switch ( $this -> page -> state ) {
case moodle_page :: STATE_BEFORE_HEADER :
// No output yet it is safe to delivery the full arsenal of redirect methods
if ( ! $debugdisableredirect ) {
// Don't use exactly the same time here, it can cause problems when both redirects fire at the same time.
$this -> metarefreshtag = '<meta http-equiv="refresh" content="' . $delay . '; url=' . $encodedurl . '" />' . " \n " ;
2010-02-06 14:45:17 +00:00
$this -> page -> requires -> js_function_call ( 'document.location.replace' , array ( $url ), false , ( $delay + 3 ));
2009-08-10 06:22:04 +00:00
}
$output = $this -> header ();
break ;
case moodle_page :: STATE_PRINTING_HEADER :
// We should hopefully never get here
throw new coding_exception ( 'You cannot redirect while printing the page header' );
break ;
case moodle_page :: STATE_IN_BODY :
// We really shouldn't be here but we can deal with this
debugging ( " You should really redirect before you start page output " );
if ( ! $debugdisableredirect ) {
2010-02-06 14:45:17 +00:00
$this -> page -> requires -> js_function_call ( 'document.location.replace' , array ( $url ), false , $delay );
2009-08-10 06:22:04 +00:00
}
$output = $this -> opencontainers -> pop_all_but_last ();
break ;
case moodle_page :: STATE_DONE :
// Too late to be calling redirect now
throw new coding_exception ( 'You cannot redirect after the entire page has been generated' );
break ;
}
$output .= $this -> notification ( $message , 'redirectmessage' );
2010-06-14 05:16:56 +00:00
$output .= '<div class="continuebutton">(<a href="' . $encodedurl . '">' . get_string ( 'continue' ) . '</a>)</div>' ;
2009-08-10 06:22:04 +00:00
if ( $debugdisableredirect ) {
$output .= '<p><strong>Error output, so disabling automatic redirect.</strong></p>' ;
}
$output .= $this -> footer ();
return $output ;
}
/**
* Start output by sending the HTTP headers , and printing the HTML < head >
* and the start of the < body >.
*
* To control what is printed , you should set properties on $PAGE . If you
* are familiar with the old { @ link print_header ()} function from Moodle 1.9
* you will find that there are properties on $PAGE that correspond to most
* of the old parameters to could be passed to print_header .
*
* Not that , in due course , the remaining $navigation , $menu parameters here
* will be replaced by more properties of $PAGE , but that is still to do .
*
* @ return string HTML that you must output this , preferably immediately .
*/
2009-09-01 03:47:07 +00:00
public function header () {
2009-08-10 06:22:04 +00:00
global $USER , $CFG ;
$this -> page -> set_state ( moodle_page :: STATE_PRINTING_HEADER );
2009-12-16 18:00:58 +00:00
// Find the appropriate page layout file, based on $this->page->pagelayout.
$layoutfile = $this -> page -> theme -> layout_file ( $this -> page -> pagelayout );
// Render the layout using the layout file.
$rendered = $this -> render_page_layout ( $layoutfile );
2009-10-03 08:54:30 +00:00
2009-12-16 18:00:58 +00:00
// Slice the rendered output into header and footer.
$cutpos = strpos ( $rendered , self :: MAIN_CONTENT_TOKEN );
2009-08-10 06:22:04 +00:00
if ( $cutpos === false ) {
2009-12-16 18:00:58 +00:00
throw new coding_exception ( 'page layout file ' . $layoutfile .
2009-08-10 06:22:04 +00:00
' does not contain the string "' . self :: MAIN_CONTENT_TOKEN . '".' );
}
2009-12-16 18:00:58 +00:00
$header = substr ( $rendered , 0 , $cutpos );
$footer = substr ( $rendered , $cutpos + strlen ( self :: MAIN_CONTENT_TOKEN ));
2009-08-10 06:22:04 +00:00
if ( empty ( $this -> contenttype )) {
2009-12-16 18:00:58 +00:00
debugging ( 'The page layout file did not call $OUTPUT->doctype()' );
2009-10-03 08:54:30 +00:00
$header = $this -> doctype () . $header ;
2009-08-10 06:22:04 +00:00
}
send_headers ( $this -> contenttype , $this -> page -> cacheable );
2009-10-03 08:54:30 +00:00
2009-08-10 06:22:04 +00:00
$this -> opencontainers -> push ( 'header/footer' , $footer );
$this -> page -> set_state ( moodle_page :: STATE_IN_BODY );
2009-10-03 08:54:30 +00:00
2010-06-23 09:10:53 +00:00
return $header . $this -> skip_link_target ( 'maincontent' );
2009-08-10 06:22:04 +00:00
}
/**
2009-12-16 18:00:58 +00:00
* Renders and outputs the page layout file .
* @ param string $layoutfile The name of the layout file
2009-08-10 06:22:04 +00:00
* @ return string HTML code
*/
2009-12-16 18:00:58 +00:00
protected function render_page_layout ( $layoutfile ) {
2009-12-23 17:44:17 +00:00
global $CFG , $SITE , $USER ;
2009-08-10 06:22:04 +00:00
// The next lines are a bit tricky. The point is, here we are in a method
// of a renderer class, and this object may, or may not, be the same as
2009-12-16 18:00:58 +00:00
// the global $OUTPUT object. When rendering the page layout file, we want to use
2009-08-10 06:22:04 +00:00
// this object. However, people writing Moodle code expect the current
// renderer to be called $OUTPUT, not $this, so define a variable called
// $OUTPUT pointing at $this. The same comment applies to $PAGE and $COURSE.
$OUTPUT = $this ;
$PAGE = $this -> page ;
$COURSE = $this -> page -> course ;
ob_start ();
2009-12-16 18:00:58 +00:00
include ( $layoutfile );
$rendered = ob_get_contents ();
2009-08-10 06:22:04 +00:00
ob_end_clean ();
2009-12-16 18:00:58 +00:00
return $rendered ;
2009-08-10 06:22:04 +00:00
}
/**
* Outputs the page ' s footer
* @ return string HTML fragment
*/
public function footer () {
2009-11-07 08:52:56 +00:00
global $CFG , $DB ;
2009-11-03 11:02:07 +00:00
2009-12-23 18:05:58 +00:00
$output = $this -> container_end_all ( true );
2010-05-19 08:05:36 +00:00
2009-08-10 06:22:04 +00:00
$footer = $this -> opencontainers -> pop ( 'header/footer' );
2009-11-07 08:52:56 +00:00
if ( debugging () and $DB and $DB -> is_transaction_started ()) {
2009-11-09 11:33:14 +00:00
// TODO: MDL-20625 print warning - transaction will be rolled back
2009-11-07 08:52:56 +00:00
}
2009-08-10 06:22:04 +00:00
// Provide some performance info if required
$performanceinfo = '' ;
if ( defined ( 'MDL_PERF' ) || ( ! empty ( $CFG -> perfdebug ) and $CFG -> perfdebug > 7 )) {
$perf = get_performance_info ();
if ( defined ( 'MDL_PERFTOLOG' ) && ! function_exists ( 'register_shutdown_function' )) {
error_log ( " PERF: " . $perf [ 'txt' ]);
}
if ( defined ( 'MDL_PERFTOFOOT' ) || debugging () || $CFG -> perfdebug > 7 ) {
$performanceinfo = $perf [ 'html' ];
}
}
$footer = str_replace ( self :: PERFORMANCE_INFO_TOKEN , $performanceinfo , $footer );
$footer = str_replace ( self :: END_HTML_TOKEN , $this -> page -> requires -> get_end_code (), $footer );
$this -> page -> set_state ( moodle_page :: STATE_DONE );
return $output . $footer ;
}
2009-12-23 18:05:58 +00:00
/**
* Close all but the last open container . This is useful in places like error
* handling , where you want to close all the open containers ( apart from < body > )
* before outputting the error message .
* @ param bool $shouldbenone assert that the stack should be empty now - causes a
* developer debug warning if it isn ' t .
* @ return string the HTML required to close any open containers inside < body >.
*/
public function container_end_all ( $shouldbenone = false ) {
return $this -> opencontainers -> pop_all_but_last ( $shouldbenone );
}
2009-12-29 17:26:29 +00:00
/**
* Returns lang menu or '' , this method also checks forcing of languages in courses .
* @ return string
*/
public function lang_menu () {
global $CFG ;
if ( empty ( $CFG -> langmenu )) {
return '' ;
}
if ( $this -> page -> course != SITEID and ! empty ( $this -> page -> course -> lang )) {
// do not show lang menu if language forced
return '' ;
}
$currlang = current_language ();
2010-04-14 09:45:49 +00:00
$langs = get_string_manager () -> get_list_of_translations ();
2009-12-30 15:19:55 +00:00
2009-12-29 17:26:29 +00:00
if ( count ( $langs ) < 2 ) {
return '' ;
}
2010-02-09 17:39:13 +00:00
$s = new single_select ( $this -> page -> url , 'lang' , $langs , $currlang , null );
$s -> label = get_accesshide ( get_string ( 'language' ));
$s -> class = 'langmenu' ;
return $this -> render ( $s );
2009-12-29 17:26:29 +00:00
}
2009-08-10 06:22:04 +00:00
/**
* Output the row of editing icons for a block , as defined by the controls array .
* @ param array $controls an array like { @ link block_contents :: $controls } .
* @ return HTML fragment .
*/
public function block_controls ( $controls ) {
if ( empty ( $controls )) {
return '' ;
}
$controlshtml = array ();
foreach ( $controls as $control ) {
2010-02-19 06:57:55 +00:00
$controlshtml [] = html_writer :: tag ( 'a' ,
2010-02-18 18:15:56 +00:00
html_writer :: empty_tag ( 'img' , array ( 'src' => $this -> pix_url ( $control [ 'icon' ]) -> out ( false ), 'alt' => $control [ 'caption' ])),
2010-02-19 06:57:55 +00:00
array ( 'class' => 'icon' , 'title' => $control [ 'caption' ], 'href' => $control [ 'url' ]));
2009-08-10 06:22:04 +00:00
}
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'div' , implode ( '' , $controlshtml ), array ( 'class' => 'commands' ));
2009-08-10 06:22:04 +00:00
}
/**
* Prints a nice side block with an optional header .
*
* The content is described
* by a { @ link block_contents } object .
*
* @ param block_contents $bc HTML for the content
* @ param string $region the region the block is appearing in .
* @ return string the HTML to be output .
*/
2010-02-17 18:36:26 +00:00
function block ( block_contents $bc , $region ) {
2009-08-10 06:22:04 +00:00
$bc = clone ( $bc ); // Avoid messing up the object passed in.
2010-02-17 18:36:26 +00:00
if ( empty ( $bc -> blockinstanceid ) || ! strip_tags ( $bc -> title )) {
$bc -> collapsible = block_contents :: NOT_HIDEABLE ;
}
if ( $bc -> collapsible == block_contents :: HIDDEN ) {
$bc -> add_class ( 'hidden' );
}
if ( ! empty ( $bc -> controls )) {
$bc -> add_class ( 'block_with_controls' );
}
2009-08-10 06:22:04 +00:00
$skiptitle = strip_tags ( $bc -> title );
if ( empty ( $skiptitle )) {
$output = '' ;
$skipdest = '' ;
} else {
2010-02-18 18:15:56 +00:00
$output = html_writer :: tag ( 'a' , get_string ( 'skipa' , 'access' , $skiptitle ), array ( 'href' => '#sb-' . $bc -> skipid , 'class' => 'skip-block' ));
$skipdest = html_writer :: tag ( 'span' , '' , array ( 'id' => 'sb-' . $bc -> skipid , 'class' => 'skip-block-to' ));
2009-08-10 06:22:04 +00:00
}
2010-05-19 08:05:36 +00:00
2010-01-13 17:13:52 +00:00
$output .= html_writer :: start_tag ( 'div' , $bc -> attributes );
2009-08-10 06:22:04 +00:00
$controlshtml = $this -> block_controls ( $bc -> controls );
$title = '' ;
if ( $bc -> title ) {
2010-02-18 18:15:56 +00:00
$title = html_writer :: tag ( 'h2' , $bc -> title , null );
2009-08-10 06:22:04 +00:00
}
if ( $title || $controlshtml ) {
2010-02-24 08:12:17 +00:00
$output .= html_writer :: tag ( 'div' , html_writer :: tag ( 'div' , html_writer :: tag ( 'div' , '' , array ( 'class' => 'block_action' )) . $title . $controlshtml , array ( 'class' => 'title' )), array ( 'class' => 'header' ));
2009-08-10 06:22:04 +00:00
}
2010-01-13 17:13:52 +00:00
$output .= html_writer :: start_tag ( 'div' , array ( 'class' => 'content' ));
2010-02-24 08:12:17 +00:00
if ( ! $title && ! $controlshtml ) {
$output .= html_writer :: tag ( 'div' , '' , array ( 'class' => 'block_action notitle' ));
}
2009-08-10 06:22:04 +00:00
$output .= $bc -> content ;
if ( $bc -> footer ) {
2010-02-18 18:15:56 +00:00
$output .= html_writer :: tag ( 'div' , $bc -> footer , array ( 'class' => 'footer' ));
2009-08-10 06:22:04 +00:00
}
2010-01-13 17:13:52 +00:00
$output .= html_writer :: end_tag ( 'div' );
$output .= html_writer :: end_tag ( 'div' );
2009-08-10 06:22:04 +00:00
if ( $bc -> annotation ) {
2010-02-18 18:15:56 +00:00
$output .= html_writer :: tag ( 'div' , $bc -> annotation , array ( 'class' => 'blockannotation' ));
2009-08-10 06:22:04 +00:00
}
$output .= $skipdest ;
$this -> init_block_hider_js ( $bc );
return $output ;
}
/**
* Calls the JS require function to hide a block .
* @ param block_contents $bc A block_contents object
* @ return void
*/
2010-02-17 18:36:26 +00:00
protected function init_block_hider_js ( block_contents $bc ) {
if ( ! empty ( $bc -> attributes [ 'id' ]) and $bc -> collapsible != block_contents :: NOT_HIDEABLE ) {
2009-08-10 06:22:04 +00:00
$userpref = 'block' . $bc -> blockinstanceid . 'hidden' ;
user_preference_allow_ajax_update ( $userpref , PARAM_BOOL );
2009-12-16 20:25:14 +00:00
$this -> page -> requires -> yui2_lib ( 'dom' );
$this -> page -> requires -> yui2_lib ( 'event' );
2009-08-10 06:22:04 +00:00
$plaintitle = strip_tags ( $bc -> title );
2010-02-17 18:36:26 +00:00
$this -> page -> requires -> js_function_call ( 'new block_hider' , array ( $bc -> attributes [ 'id' ], $userpref ,
2009-08-10 06:22:04 +00:00
get_string ( 'hideblocka' , 'access' , $plaintitle ), get_string ( 'showblocka' , 'access' , $plaintitle ),
2010-01-17 09:50:55 +00:00
$this -> pix_url ( 't/switch_minus' ) -> out ( false ), $this -> pix_url ( 't/switch_plus' ) -> out ( false )));
2009-08-10 06:22:04 +00:00
}
}
/**
* Render the contents of a block_list .
* @ param array $icons the icon for each item .
* @ param array $items the content of each item .
* @ return string HTML
*/
public function list_block_contents ( $icons , $items ) {
$row = 0 ;
$lis = array ();
foreach ( $items as $key => $string ) {
2010-01-13 17:13:52 +00:00
$item = html_writer :: start_tag ( 'li' , array ( 'class' => 'r' . $row ));
2009-08-25 19:09:04 +00:00
if ( ! empty ( $icons [ $key ])) { //test if the content has an assigned icon
2010-02-18 18:15:56 +00:00
$item .= html_writer :: tag ( 'div' , $icons [ $key ], array ( 'class' => 'icon column c0' ));
2009-08-10 06:22:04 +00:00
}
2010-02-18 18:15:56 +00:00
$item .= html_writer :: tag ( 'div' , $string , array ( 'class' => 'column c1' ));
2010-01-13 17:13:52 +00:00
$item .= html_writer :: end_tag ( 'li' );
2009-08-10 06:22:04 +00:00
$lis [] = $item ;
$row = 1 - $row ; // Flip even/odd.
}
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'ul' , implode ( " \n " , $lis ), array ( 'class' => 'list' ));
2009-08-10 06:22:04 +00:00
}
/**
* Output all the blocks in a particular region .
* @ param string $region the name of a region on this page .
* @ return string the HTML to be output .
*/
public function blocks_for_region ( $region ) {
$blockcontents = $this -> page -> blocks -> get_content_for_region ( $region , $this );
$output = '' ;
foreach ( $blockcontents as $bc ) {
if ( $bc instanceof block_contents ) {
$output .= $this -> block ( $bc , $region );
} else if ( $bc instanceof block_move_target ) {
$output .= $this -> block_move_target ( $bc );
} else {
throw new coding_exception ( 'Unexpected type of thing (' . get_class ( $bc ) . ') found in list of block contents.' );
}
}
return $output ;
}
/**
* Output a place where the block that is currently being moved can be dropped .
* @ param block_move_target $target with the necessary details .
* @ return string the HTML to be output .
*/
public function block_move_target ( $target ) {
2010-03-17 02:25:36 +00:00
return html_writer :: tag ( 'a' , html_writer :: tag ( 'span' , $target -> text , array ( 'class' => 'accesshide' )), array ( 'href' => $target -> url , 'class' => 'blockmovetarget' ));
2009-08-10 06:22:04 +00:00
}
2010-01-14 22:40:33 +00:00
/**
2010-05-22 14:43:46 +00:00
* Renders a special html link with attached action
2010-01-14 22:40:33 +00:00
*
* @ param string | moodle_url $url
* @ param string $text HTML fragment
* @ param component_action $action
2010-01-14 22:51:10 +00:00
* @ param array $attributes associative array of html link attributes + disabled
2010-01-14 22:40:33 +00:00
* @ return HTML fragment
*/
2010-02-16 16:24:49 +00:00
public function action_link ( $url , $text , component_action $action = null , array $attributes = null ) {
2010-01-14 22:40:33 +00:00
if ( ! ( $url instanceof moodle_url )) {
$url = new moodle_url ( $url );
}
$link = new action_link ( $url , $text , $action , $attributes );
2010-01-15 09:01:59 +00:00
return $this -> render ( $link );
2010-01-14 22:40:33 +00:00
}
/**
* Implementation of action_link rendering
* @ param action_link $link
* @ return string HTML fragment
*/
protected function render_action_link ( action_link $link ) {
global $CFG ;
// A disabled link is rendered as formatted text
if ( ! empty ( $link -> attributes [ 'disabled' ])) {
// do not use div here due to nesting restriction in xhtml strict
return html_writer :: tag ( 'span' , $link -> text , array ( 'class' => 'currentlink' ));
}
2010-01-14 22:51:10 +00:00
2010-01-14 22:40:33 +00:00
$attributes = $link -> attributes ;
unset ( $link -> attributes [ 'disabled' ]);
$attributes [ 'href' ] = $link -> url ;
if ( $link -> actions ) {
2010-01-15 09:01:59 +00:00
if ( empty ( $attributes [ 'id' ])) {
2010-01-14 22:40:33 +00:00
$id = html_writer :: random_id ( 'action_link' );
$attributes [ 'id' ] = $id ;
} else {
$id = $attributes [ 'id' ];
}
foreach ( $link -> actions as $action ) {
2010-02-11 15:44:06 +00:00
$this -> add_action_handler ( $action , $id );
2010-01-14 22:40:33 +00:00
}
}
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'a' , $link -> text , $attributes );
2010-01-14 22:40:33 +00:00
}
2010-02-16 16:24:49 +00:00
/**
* Similar to action_link , image is used instead of the text
*
* @ param string | moodle_url $url A string URL or moodel_url
* @ param pix_icon $pixicon
* @ param component_action $action
* @ param array $attributes associative array of html link attributes + disabled
* @ param bool $linktext show title next to image in link
* @ return string HTML fragment
*/
public function action_icon ( $url , pix_icon $pixicon , component_action $action = null , array $attributes = null , $linktext = false ) {
if ( ! ( $url instanceof moodle_url )) {
$url = new moodle_url ( $url );
}
$attributes = ( array ) $attributes ;
2010-02-24 06:08:52 +00:00
if ( empty ( $attributes [ 'class' ])) {
2010-02-16 16:24:49 +00:00
// let ppl override the class via $options
$attributes [ 'class' ] = 'action-icon' ;
}
$icon = $this -> render ( $pixicon );
if ( $linktext ) {
$text = $pixicon -> attributes [ 'alt' ];
} else {
$text = '' ;
}
return $this -> action_link ( $url , $text . $icon , $action , $attributes );
}
2009-08-10 06:22:04 +00:00
/**
2009-09-01 14:15:49 +00:00
* Print a message along with button choices for Continue / Cancel
*
2010-02-11 10:32:39 +00:00
* If a string or moodle_url is given instead of a single_button , method defaults to post .
2009-09-01 14:15:49 +00:00
*
2009-08-10 06:22:04 +00:00
* @ param string $message The question to ask the user
2010-01-14 19:18:04 +00:00
* @ param single_button | moodle_url | string $continue The single_button component representing the Continue answer . Can also be a moodle_url or string URL
* @ param single_button | moodle_url | string $cancel The single_button component representing the Cancel answer . Can also be a moodle_url or string URL
2009-08-10 06:22:04 +00:00
* @ return string HTML fragment
*/
public function confirm ( $message , $continue , $cancel ) {
2010-01-14 22:44:24 +00:00
if ( $continue instanceof single_button ) {
2010-01-14 22:51:10 +00:00
// ok
2010-01-14 22:44:24 +00:00
} else if ( is_string ( $continue )) {
$continue = new single_button ( new moodle_url ( $continue ), get_string ( 'continue' ), 'post' );
} else if ( $continue instanceof moodle_url ) {
2010-01-03 17:20:49 +00:00
$continue = new single_button ( $continue , get_string ( 'continue' ), 'post' );
2009-08-10 06:22:04 +00:00
} else {
2010-02-11 10:32:39 +00:00
throw new coding_exception ( 'The continue param to $OUTPUT->confirm() must be either a URL (string/moodle_url) or a single_button instance.' );
2009-08-10 06:22:04 +00:00
}
2010-01-14 22:44:24 +00:00
if ( $cancel instanceof single_button ) {
2010-01-14 22:51:10 +00:00
// ok
2010-01-14 22:44:24 +00:00
} else if ( is_string ( $cancel )) {
$cancel = new single_button ( new moodle_url ( $cancel ), get_string ( 'cancel' ), 'get' );
} else if ( $cancel instanceof moodle_url ) {
2010-01-03 17:20:49 +00:00
$cancel = new single_button ( $cancel , get_string ( 'cancel' ), 'get' );
2009-08-10 06:22:04 +00:00
} else {
2010-02-11 10:32:39 +00:00
throw new coding_exception ( 'The cancel param to $OUTPUT->confirm() must be either a URL (string/moodle_url) or a single_button instance.' );
2009-08-10 06:22:04 +00:00
}
$output = $this -> box_start ( 'generalbox' , 'notice' );
2010-02-18 18:15:56 +00:00
$output .= html_writer :: tag ( 'p' , $message );
$output .= html_writer :: tag ( 'div' , $this -> render ( $continue ) . $this -> render ( $cancel ), array ( 'class' => 'buttons' ));
2009-08-10 06:22:04 +00:00
$output .= $this -> box_end ();
return $output ;
}
2010-01-03 10:28:29 +00:00
/**
2010-01-14 19:18:04 +00:00
* Returns a form with a single button .
2010-01-03 10:28:29 +00:00
*
2010-01-14 19:18:04 +00:00
* @ param string | moodle_url $url
2010-01-03 10:28:29 +00:00
* @ param string $label button text
* @ param string $method get or post submit method
2010-01-14 19:18:04 +00:00
* @ param array $options associative array { disabled , title , etc . }
2010-01-03 10:28:29 +00:00
* @ return string HTML fragment
*/
2010-01-14 19:18:04 +00:00
public function single_button ( $url , $label , $method = 'post' , array $options = null ) {
2010-01-14 22:40:33 +00:00
if ( ! ( $url instanceof moodle_url )) {
$url = new moodle_url ( $url );
2010-01-14 19:18:04 +00:00
}
2010-01-14 22:40:33 +00:00
$button = new single_button ( $url , $label , $method );
2010-01-14 19:18:04 +00:00
foreach (( array ) $options as $key => $value ) {
if ( array_key_exists ( $key , $button )) {
$button -> $key = $value ;
}
2010-01-03 10:28:29 +00:00
}
2010-01-14 19:18:04 +00:00
return $this -> render ( $button );
2010-01-03 10:28:29 +00:00
}
2009-08-10 06:22:04 +00:00
/**
2010-01-14 19:18:04 +00:00
* Internal implementation of single_button rendering
* @ param single_button $button
2009-08-10 06:22:04 +00:00
* @ return string HTML fragment
*/
2010-01-14 19:18:04 +00:00
protected function render_single_button ( single_button $button ) {
$attributes = array ( 'type' => 'submit' ,
'value' => $button -> label ,
2010-02-03 17:20:01 +00:00
'disabled' => $button -> disabled ? 'disabled' : null ,
2010-01-14 19:18:04 +00:00
'title' => $button -> tooltip );
if ( $button -> actions ) {
$id = html_writer :: random_id ( 'single_button' );
$attributes [ 'id' ] = $id ;
foreach ( $button -> actions as $action ) {
2010-02-11 15:44:06 +00:00
$this -> add_action_handler ( $action , $id );
2010-01-14 19:18:04 +00:00
}
2009-08-10 06:22:04 +00:00
}
2010-01-14 19:18:04 +00:00
// first the input element
$output = html_writer :: empty_tag ( 'input' , $attributes );
2009-08-10 06:22:04 +00:00
2010-01-14 19:18:04 +00:00
// then hidden fields
$params = $button -> url -> params ();
if ( $button -> method === 'post' ) {
$params [ 'sesskey' ] = sesskey ();
}
foreach ( $params as $var => $val ) {
$output .= html_writer :: empty_tag ( 'input' , array ( 'type' => 'hidden' , 'name' => $var , 'value' => $val ));
}
2009-08-10 06:22:04 +00:00
2010-01-14 19:18:04 +00:00
// then div wrapper for xhtml strictness
2010-02-18 18:15:56 +00:00
$output = html_writer :: tag ( 'div' , $output );
2009-08-10 06:22:04 +00:00
2010-01-14 19:18:04 +00:00
// now the form itself around it
2010-01-17 09:37:30 +00:00
$url = $button -> url -> out_omit_querystring (); // url without params
2010-01-16 15:39:56 +00:00
if ( $url === '' ) {
$url = '#' ; // there has to be always some action
}
2010-01-14 19:18:04 +00:00
$attributes = array ( 'method' => $button -> method ,
2010-01-16 15:39:56 +00:00
'action' => $url ,
2010-01-14 19:18:04 +00:00
'id' => $button -> formid );
2010-02-18 18:15:56 +00:00
$output = html_writer :: tag ( 'form' , $output , $attributes );
2009-08-10 06:22:04 +00:00
2010-01-14 19:18:04 +00:00
// and finally one more wrapper with class
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'div' , $output , array ( 'class' => $button -> class ));
2009-08-10 06:22:04 +00:00
}
2010-02-09 17:39:13 +00:00
/**
2010-02-10 10:23:09 +00:00
* Returns a form with a single select widget .
2010-02-09 17:39:13 +00:00
* @ param moodle_url $url form action target , includes hidden fields
* @ param string $name name of selection field - the changing parameter in url
* @ param array $options list of options
* @ param string $selected selected element
* @ param array $nothing
2010-02-10 09:37:50 +00:00
* @ param string $formid
2010-02-09 17:39:13 +00:00
* @ return string HTML fragment
*/
2010-02-10 09:37:50 +00:00
public function single_select ( $url , $name , array $options , $selected = '' , $nothing = array ( '' => 'choosedots' ), $formid = null ) {
2010-02-09 17:39:13 +00:00
if ( ! ( $url instanceof moodle_url )) {
$url = new moodle_url ( $url );
}
2010-02-10 09:37:50 +00:00
$select = new single_select ( $url , $name , $options , $selected , $nothing , $formid );
2010-02-09 17:39:13 +00:00
return $this -> render ( $select );
}
/**
* Internal implementation of single_select rendering
* @ param single_select $select
* @ return string HTML fragment
*/
protected function render_single_select ( single_select $select ) {
$select = clone ( $select );
if ( empty ( $select -> formid )) {
$select -> formid = html_writer :: random_id ( 'single_select_f' );
}
$output = '' ;
$params = $select -> url -> params ();
if ( $select -> method === 'post' ) {
$params [ 'sesskey' ] = sesskey ();
}
foreach ( $params as $name => $value ) {
$output .= html_writer :: empty_tag ( 'input' , array ( 'type' => 'hidden' , 'name' => $name , 'value' => $value ));
}
if ( empty ( $select -> attributes [ 'id' ])) {
$select -> attributes [ 'id' ] = html_writer :: random_id ( 'single_select' );
}
2010-02-10 09:46:44 +00:00
if ( $select -> disabled ) {
$select -> attributes [ 'disabled' ] = 'disabled' ;
}
2010-02-10 10:22:25 +00:00
2010-02-09 17:39:13 +00:00
if ( $select -> tooltip ) {
$select -> attributes [ 'title' ] = $select -> tooltip ;
}
if ( $select -> label ) {
2010-07-02 12:15:36 +00:00
$output .= html_writer :: label ( $select -> label , $select -> attributes [ 'id' ]);
2010-02-09 17:39:13 +00:00
}
if ( $select -> helpicon instanceof help_icon ) {
$output .= $this -> render ( $select -> helpicon );
2010-04-13 21:51:49 +00:00
} else if ( $select -> helpicon instanceof old_help_icon ) {
$output .= $this -> render ( $select -> helpicon );
2010-02-09 17:39:13 +00:00
}
$output .= html_writer :: select ( $select -> options , $select -> name , $select -> selected , $select -> nothing , $select -> attributes );
$go = html_writer :: empty_tag ( 'input' , array ( 'type' => 'submit' , 'value' => get_string ( 'go' )));
2010-02-18 18:15:56 +00:00
$output .= html_writer :: tag ( 'noscript' , $go , array ( 'style' => 'inline' ));
2010-02-09 17:39:13 +00:00
$nothing = empty ( $select -> nothing ) ? false : key ( $select -> nothing );
2010-02-10 16:20:28 +00:00
$this -> page -> requires -> js_init_call ( 'M.util.init_select_autosubmit' , array ( $select -> formid , $select -> attributes [ 'id' ], $nothing ));
2010-02-09 17:39:13 +00:00
// then div wrapper for xhtml strictness
2010-02-18 18:15:56 +00:00
$output = html_writer :: tag ( 'div' , $output );
2010-02-09 17:39:13 +00:00
// now the form itself around it
$formattributes = array ( 'method' => $select -> method ,
'action' => $select -> url -> out_omit_querystring (),
'id' => $select -> formid );
2010-02-18 18:15:56 +00:00
$output = html_writer :: tag ( 'form' , $output , $formattributes );
2010-02-10 10:22:25 +00:00
// and finally one more wrapper with class
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'div' , $output , array ( 'class' => $select -> class ));
2010-02-10 10:22:25 +00:00
}
/**
2010-02-10 10:23:09 +00:00
* Returns a form with a url select widget .
2010-02-10 10:22:25 +00:00
* @ param array $urls list of urls - array ( '/course/view.php?id=1' => 'Frontpage' , .... )
* @ param string $selected selected element
* @ param array $nothing
* @ param string $formid
* @ return string HTML fragment
*/
public function url_select ( array $urls , $selected , $nothing = array ( '' => 'choosedots' ), $formid = null ) {
$select = new url_select ( $urls , $selected , $nothing , $formid );
return $this -> render ( $select );
}
/**
2010-02-10 10:23:09 +00:00
* Internal implementation of url_select rendering
2010-02-10 10:22:25 +00:00
* @ param single_select $select
* @ return string HTML fragment
*/
protected function render_url_select ( url_select $select ) {
2010-05-28 15:47:26 +00:00
global $CFG ;
2010-02-10 10:22:25 +00:00
$select = clone ( $select );
if ( empty ( $select -> formid )) {
$select -> formid = html_writer :: random_id ( 'url_select_f' );
}
if ( empty ( $select -> attributes [ 'id' ])) {
$select -> attributes [ 'id' ] = html_writer :: random_id ( 'url_select' );
}
if ( $select -> disabled ) {
$select -> attributes [ 'disabled' ] = 'disabled' ;
}
if ( $select -> tooltip ) {
$select -> attributes [ 'title' ] = $select -> tooltip ;
}
$output = '' ;
if ( $select -> label ) {
2010-07-02 12:15:36 +00:00
$output .= html_writer :: label ( $select -> label , $select -> attributes [ 'id' ]);
2010-02-10 10:22:25 +00:00
}
if ( $select -> helpicon instanceof help_icon ) {
$output .= $this -> render ( $select -> helpicon );
2010-04-13 21:51:49 +00:00
} else if ( $select -> helpicon instanceof old_help_icon ) {
$output .= $this -> render ( $select -> helpicon );
2010-02-10 10:22:25 +00:00
}
2010-05-31 15:30:45 +00:00
// For security reasons, the script course/jumpto.php requires URL starting with '/'. To keep
// backward compatibility, we are removing heading $CFG->wwwroot from URLs here.
2010-05-28 15:47:26 +00:00
$urls = array ();
foreach ( $select -> urls as $k => $v ) {
2010-05-31 15:30:45 +00:00
if ( is_array ( $v )) {
// optgroup structure
foreach ( $v as $optgrouptitle => $optgroupoptions ) {
foreach ( $optgroupoptions as $optionurl => $optiontitle ) {
if ( empty ( $optionurl )) {
$safeoptionurl = '' ;
} else if ( strpos ( $optionurl , $CFG -> wwwroot . '/' ) === 0 ) {
// debugging('URLs passed to url_select should be in local relative form - please fix the code.', DEBUG_DEVELOPER);
$safeoptionurl = str_replace ( $CFG -> wwwroot , '' , $optionurl );
} else if ( strpos ( $optionurl , '/' ) !== 0 ) {
debugging ( " Invalid url_select urls parameter inside optgroup: url ' $optionurl ' is not local relative url! " );
continue ;
} else {
$safeoptionurl = $optionurl ;
}
$urls [ $k ][ $optgrouptitle ][ $safeoptionurl ] = $optiontitle ;
}
}
} else {
// plain list structure
if ( empty ( $k )) {
// nothing selected option
} else if ( strpos ( $k , $CFG -> wwwroot . '/' ) === 0 ) {
$k = str_replace ( $CFG -> wwwroot , '' , $k );
} else if ( strpos ( $k , '/' ) !== 0 ) {
debugging ( " Invalid url_select urls parameter: url ' $k ' is not local relative url! " );
continue ;
}
$urls [ $k ] = $v ;
}
}
$selected = $select -> selected ;
if ( ! empty ( $selected )) {
if ( strpos ( $select -> selected , $CFG -> wwwroot . '/' ) === 0 ) {
$selected = str_replace ( $CFG -> wwwroot , '' , $selected );
} else if ( strpos ( $selected , '/' ) !== 0 ) {
debugging ( " Invalid value of parameter 'selected': url ' $selected ' is not local relative url! " );
2010-05-28 15:47:26 +00:00
}
}
2010-02-10 10:22:25 +00:00
$output .= html_writer :: empty_tag ( 'input' , array ( 'type' => 'hidden' , 'name' => 'sesskey' , 'value' => sesskey ()));
2010-05-31 15:30:45 +00:00
$output .= html_writer :: select ( $urls , 'jump' , $selected , $select -> nothing , $select -> attributes );
2010-02-10 10:22:25 +00:00
$go = html_writer :: empty_tag ( 'input' , array ( 'type' => 'submit' , 'value' => get_string ( 'go' )));
2010-02-18 18:15:56 +00:00
$output .= html_writer :: tag ( 'noscript' , $go , array ( 'style' => 'inline' ));
2010-02-10 10:22:25 +00:00
$nothing = empty ( $select -> nothing ) ? false : key ( $select -> nothing );
$output .= $this -> page -> requires -> js_init_call ( 'M.util.init_url_select' , array ( $select -> formid , $select -> attributes [ 'id' ], $nothing ));
// then div wrapper for xhtml strictness
2010-02-18 18:15:56 +00:00
$output = html_writer :: tag ( 'div' , $output );
2010-02-10 10:22:25 +00:00
// now the form itself around it
$formattributes = array ( 'method' => 'post' ,
'action' => new moodle_url ( '/course/jumpto.php' ),
'id' => $select -> formid );
2010-02-18 18:15:56 +00:00
$output = html_writer :: tag ( 'form' , $output , $formattributes );
2010-02-09 17:39:13 +00:00
// and finally one more wrapper with class
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'div' , $output , array ( 'class' => $select -> class ));
2010-02-09 17:39:13 +00:00
}
2009-08-10 06:22:04 +00:00
/**
* Returns a string containing a link to the user documentation .
* Also contains an icon by default . Shown to teachers and admin only .
* @ param string $path The page link after doc root and language , no leading slash .
* @ param string $text The text to be displayed for the link
2010-05-22 14:43:46 +00:00
* @ return string
2009-08-10 06:22:04 +00:00
*/
2010-01-02 13:17:54 +00:00
public function doc_link ( $path , $text ) {
global $CFG ;
2010-02-11 14:59:00 +00:00
$icon = $this -> pix_icon ( 'docs' , $text , 'moodle' , array ( 'class' => 'iconhelp' ));
2010-01-02 13:17:54 +00:00
2010-02-11 14:59:00 +00:00
$url = new moodle_url ( get_docs_url ( $path ));
2010-01-02 13:17:54 +00:00
2010-02-11 15:44:06 +00:00
$attributes = array ( 'href' => $url );
2009-08-10 06:22:04 +00:00
if ( ! empty ( $CFG -> doctonewwindow )) {
2010-02-11 15:44:06 +00:00
$attributes [ 'id' ] = $this -> add_action_handler ( new popup_action ( 'click' , $url ));
2009-08-10 06:22:04 +00:00
}
2010-03-28 09:05:47 +00:00
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'a' , $icon . $text , $attributes );
2009-08-10 06:22:04 +00:00
}
2010-02-11 14:59:00 +00:00
/**
* Render icon
* @ param string $pix short pix name
* @ param string $alt mandatory alt attribute
* @ param strin $component standard compoennt name like 'moodle' , 'mod_form' , etc .
* @ param array $attributes htm lattributes
* @ return string HTML fragment
*/
public function pix_icon ( $pix , $alt , $component = 'moodle' , array $attributes = null ) {
$icon = new pix_icon ( $pix , $alt , $component , $attributes );
return $this -> render ( $icon );
}
/**
* Render icon
* @ param pix_icon $icon
* @ return string HTML fragment
*/
2010-02-16 17:33:13 +00:00
protected function render_pix_icon ( pix_icon $icon ) {
2010-02-11 14:59:00 +00:00
$attributes = $icon -> attributes ;
$attributes [ 'src' ] = $this -> pix_url ( $icon -> pix , $icon -> component );
2010-02-11 15:44:06 +00:00
return html_writer :: empty_tag ( 'img' , $attributes );
2010-02-11 14:59:00 +00:00
}
2010-03-16 05:57:51 +00:00
/**
* Produces the html that represents this rating in the UI
* @ param $page the page object on which this rating will appear
*/
function render_rating ( rating $rating ) {
2010-03-17 09:12:13 +00:00
global $CFG , $USER ;
2010-03-16 05:57:51 +00:00
static $havesetupjavascript = false ;
2010-04-22 05:15:23 +00:00
if ( $rating -> settings -> aggregationmethod == RATING_AGGREGATE_NONE ){
return null ; //ratings are turned off
}
2010-03-19 06:55:47 +00:00
$useajax = ! empty ( $CFG -> enableajax );
//include required Javascript
if ( ! $havesetupjavascript && $useajax ) {
2010-04-01 20:33:15 +00:00
$this -> page -> requires -> js_init_call ( 'M.core_rating.init' );
2010-03-16 05:57:51 +00:00
$havesetupjavascript = true ;
}
2010-04-22 05:15:23 +00:00
//check the item we're rating was created in the assessable time window
$inassessablewindow = true ;
if ( $rating -> settings -> assesstimestart && $rating -> settings -> assesstimefinish ) {
if ( $rating -> itemtimecreated < $rating -> settings -> assesstimestart || $item -> itemtimecreated > $rating -> settings -> assesstimefinish ) {
$inassessablewindow = false ;
2010-03-16 05:57:51 +00:00
}
2010-04-22 05:15:23 +00:00
}
2010-03-16 05:57:51 +00:00
2010-04-22 05:15:23 +00:00
$strrate = get_string ( " rate " , " rating " );
$ratinghtml = '' ; //the string we'll return
2010-04-23 09:44:19 +00:00
//permissions check - can they view the aggregate?
2010-05-19 08:05:36 +00:00
if ( ( $rating -> itemuserid == $USER -> id
2010-04-23 09:44:19 +00:00
&& $rating -> settings -> permissions -> view && $rating -> settings -> pluginpermissions -> view )
2010-05-19 08:05:36 +00:00
|| ( $rating -> itemuserid != $USER -> id
2010-04-23 09:44:19 +00:00
&& $rating -> settings -> permissions -> viewany && $rating -> settings -> pluginpermissions -> viewany ) ) {
$aggregatelabel = '' ;
switch ( $rating -> settings -> aggregationmethod ) {
case RATING_AGGREGATE_AVERAGE :
$aggregatelabel .= get_string ( " aggregateavg " , " forum " );
break ;
case RATING_AGGREGATE_COUNT :
$aggregatelabel .= get_string ( " aggregatecount " , " forum " );
break ;
case RATING_AGGREGATE_MAXIMUM :
$aggregatelabel .= get_string ( " aggregatemax " , " forum " );
break ;
case RATING_AGGREGATE_MINIMUM :
$aggregatelabel .= get_string ( " aggregatemin " , " forum " );
break ;
case RATING_AGGREGATE_SUM :
$aggregatelabel .= get_string ( " aggregatesum " , " forum " );
break ;
}
2010-03-16 05:57:51 +00:00
2010-04-23 09:44:19 +00:00
//$scalemax = 0;//no longer displaying scale max
$aggregatestr = '' ;
2010-03-16 05:57:51 +00:00
2010-05-24 03:41:00 +00:00
//only display aggregate if aggregation method isn't COUNT
if ( $rating -> aggregate && $rating -> settings -> aggregationmethod != RATING_AGGREGATE_COUNT ) {
if ( $rating -> settings -> aggregationmethod != RATING_AGGREGATE_SUM && is_array ( $rating -> settings -> scale -> scaleitems )) {
2010-04-23 09:44:19 +00:00
$aggregatestr .= $rating -> settings -> scale -> scaleitems [ round ( $rating -> aggregate )]; //round aggregate as we're using it as an index
2010-04-22 05:15:23 +00:00
}
2010-05-24 03:41:00 +00:00
else { //aggregation is SUM or the scale is numeric
2010-04-23 09:44:19 +00:00
$aggregatestr .= round ( $rating -> aggregate , 1 );
2010-04-22 05:15:23 +00:00
}
2010-04-23 09:44:19 +00:00
} else {
$aggregatestr = ' - ' ;
}
2010-05-17 07:31:22 +00:00
$countstr = html_writer :: start_tag ( 'span' , array ( 'id' => " ratingcount { $rating -> itemid } " ));
2010-04-23 09:44:19 +00:00
if ( $rating -> count > 0 ) {
2010-05-17 07:31:22 +00:00
$countstr .= " ( { $rating -> count } ) " ;
2010-04-23 09:44:19 +00:00
}
2010-05-17 07:31:22 +00:00
$countstr .= html_writer :: end_tag ( 'span' );
2010-04-22 05:15:23 +00:00
2010-04-23 09:44:19 +00:00
//$aggregatehtml = "{$ratingstr} / $scalemax ({$rating->count}) ";
$aggregatehtml = " <span id='ratingaggregate { $rating -> itemid } '> { $aggregatestr } </span> $countstr " ;
2010-04-22 05:15:23 +00:00
2010-04-23 09:44:19 +00:00
if ( $rating -> settings -> permissions -> viewall && $rating -> settings -> pluginpermissions -> viewall ) {
$url = " /rating/index.php?contextid= { $rating -> context -> id } &itemid= { $rating -> itemid } &scaleid= { $rating -> settings -> scale -> id } " ;
$nonpopuplink = new moodle_url ( $url );
$popuplink = new moodle_url ( " $url &popup=1 " );
2010-03-16 05:57:51 +00:00
2010-04-23 09:44:19 +00:00
$action = new popup_action ( 'click' , $popuplink , 'ratings' , array ( 'height' => 400 , 'width' => 600 ));
2010-07-02 12:15:36 +00:00
$ratinghtml .= $aggregatelabel . get_string ( 'labelsep' , 'langconfig' ) . $this -> action_link ( $nonpopuplink , $aggregatehtml , $action );
2010-04-23 09:44:19 +00:00
} else {
2010-07-02 12:15:36 +00:00
$ratinghtml .= $aggregatelabel . get_string ( 'labelsep' , 'langconfig' ) . $aggregatehtml ;
2010-03-16 05:57:51 +00:00
}
2010-04-23 09:44:19 +00:00
}
2010-03-16 05:57:51 +00:00
2010-04-23 09:44:19 +00:00
$formstart = null ;
2010-05-22 20:16:12 +00:00
//if the item doesn't belong to the current user, the user has permission to rate
2010-04-23 09:44:19 +00:00
//and we're within the assessable period
if ( $rating -> itemuserid != $USER -> id
&& $rating -> settings -> permissions -> rate
&& $rating -> settings -> pluginpermissions -> rate
&& $inassessablewindow ) {
2010-05-19 08:05:36 +00:00
2010-05-17 07:31:22 +00:00
//start the rating form
$formstart = html_writer :: start_tag ( 'form' ,
array ( 'id' => " postrating { $rating -> itemid } " , 'class' => 'postratingform' , 'method' => 'post' , 'action' => " { $CFG -> wwwroot } /rating/rate.php " ));
$formstart .= html_writer :: start_tag ( 'div' , array ( 'class' => 'ratingform' ));
//add the hidden inputs
$attributes = array ( 'type' => 'hidden' , 'class' => 'ratinginput' , 'name' => 'contextid' , 'value' => $rating -> context -> id );
$formstart .= html_writer :: empty_tag ( 'input' , $attributes );
$attributes [ 'name' ] = 'itemid' ;
$attributes [ 'value' ] = $rating -> itemid ;
$formstart .= html_writer :: empty_tag ( 'input' , $attributes );
$attributes [ 'name' ] = 'scaleid' ;
$attributes [ 'value' ] = $rating -> settings -> scale -> id ;
$formstart .= html_writer :: empty_tag ( 'input' , $attributes );
$attributes [ 'name' ] = 'returnurl' ;
$attributes [ 'value' ] = $rating -> settings -> returnurl ;
$formstart .= html_writer :: empty_tag ( 'input' , $attributes );
$attributes [ 'name' ] = 'rateduserid' ;
$attributes [ 'value' ] = $rating -> itemuserid ;
$formstart .= html_writer :: empty_tag ( 'input' , $attributes );
$attributes [ 'name' ] = 'aggregation' ;
$attributes [ 'value' ] = $rating -> settings -> aggregationmethod ;
$formstart .= html_writer :: empty_tag ( 'input' , $attributes );
2010-05-21 03:43:45 +00:00
$attributes [ 'name' ] = 'sesskey' ;
$attributes [ 'value' ] = sesskey ();;
$formstart .= html_writer :: empty_tag ( 'input' , $attributes );
2010-04-23 09:44:19 +00:00
if ( empty ( $ratinghtml )) {
$ratinghtml .= $strrate . ': ' ;
}
2010-04-22 05:15:23 +00:00
2010-04-23 09:44:19 +00:00
$ratinghtml = $formstart . $ratinghtml ;
2010-04-22 05:15:23 +00:00
2010-04-23 09:44:19 +00:00
//generate an array of values for numeric scales
$scalearray = $rating -> settings -> scale -> scaleitems ;
if ( ! is_array ( $scalearray )) { //almost certainly a numerical scale
2010-05-22 14:43:46 +00:00
$intscalearray = intval ( $scalearray ); //just in case they've passed "5" instead of 5
2010-04-23 09:44:19 +00:00
if ( is_int ( $intscalearray ) && $intscalearray > 0 ){
$scalearray = array ();
for ( $i = 0 ; $i <= $rating -> settings -> scale -> scaleitems ; $i ++ ) {
$scalearray [ $i ] = $i ;
2010-03-16 09:37:31 +00:00
}
2010-03-16 05:57:51 +00:00
}
2010-04-23 09:44:19 +00:00
}
2010-03-16 09:37:31 +00:00
2010-04-23 09:44:19 +00:00
$scalearray = array ( RATING_UNSET_RATING => $strrate . '...' ) + $scalearray ;
$ratinghtml .= html_writer :: select ( $scalearray , 'rating' , $rating -> rating , false , array ( 'class' => 'postratingmenu ratinginput' , 'id' => 'menurating' . $rating -> itemid ));
2010-03-16 05:57:51 +00:00
2010-04-23 09:44:19 +00:00
//output submit button
2010-05-19 08:05:36 +00:00
2010-05-17 07:31:22 +00:00
$ratinghtml .= html_writer :: start_tag ( 'span' , array ( 'class' => " ratingsubmit " ));
$attributes = array ( 'type' => 'submit' , 'class' => 'postratingmenusubmit' , 'id' => 'postratingsubmit' . $rating -> itemid , 'value' => s ( get_string ( 'rate' , 'rating' )));
$ratinghtml .= html_writer :: empty_tag ( 'input' , $attributes );
2010-03-16 05:57:51 +00:00
2010-04-23 09:44:19 +00:00
if ( is_array ( $rating -> settings -> scale -> scaleitems )) {
$ratinghtml .= $this -> help_icon_scale ( $rating -> settings -> scale -> courseid , $rating -> settings -> scale );
2010-03-16 05:57:51 +00:00
}
2010-05-17 07:31:22 +00:00
$ratinghtml .= html_writer :: end_tag ( 'span' );
$ratinghtml .= html_writer :: end_tag ( 'div' );
$ratinghtml .= html_writer :: end_tag ( 'form' );
2010-03-16 05:57:51 +00:00
}
2010-04-22 05:15:23 +00:00
return $ratinghtml ;
2010-03-16 05:57:51 +00:00
}
2009-08-10 06:22:04 +00:00
/*
* Centered heading with attached help button ( same title text )
* and optional icon attached
2009-12-30 15:19:55 +00:00
* @ param string $text A heading text
2010-04-10 09:10:08 +00:00
* @ param string $helpidentifier The keyword that defines a help page
2009-12-30 15:19:55 +00:00
* @ param string $component component name
* @ param string | moodle_url $icon
* @ param string $iconalt icon alt text
2009-08-10 06:22:04 +00:00
* @ return string HTML fragment
*/
2010-04-10 09:10:08 +00:00
public function heading_with_help ( $text , $helpidentifier , $component = 'moodle' , $icon = '' , $iconalt = '' ) {
2009-12-30 15:19:55 +00:00
$image = '' ;
if ( $icon ) {
2010-02-16 17:31:35 +00:00
$image = $this -> pix_icon ( $icon , $iconalt , $component , array ( 'class' => 'icon' ));
2009-08-10 06:22:04 +00:00
}
2009-12-30 15:19:55 +00:00
2010-04-13 21:51:49 +00:00
$help = '' ;
if ( $helpidentifier ) {
$help = $this -> help_icon ( $helpidentifier , $component );
}
2009-12-30 15:19:55 +00:00
return $this -> heading ( $image . $text . $help , 2 , 'main help' );
2009-08-10 06:22:04 +00:00
}
/**
* Print a help icon .
*
2009-12-30 15:19:55 +00:00
* @ param string $page The keyword that defines a help page
2010-01-13 18:50:28 +00:00
* @ param string $title A descriptive text for accessibility only
2009-12-30 15:19:55 +00:00
* @ param string $component component name
2010-01-13 18:50:28 +00:00
* @ param string | bool $linktext true means use $title as link text , string means link text value
* @ return string HTML fragment
*/
2010-04-13 20:34:27 +00:00
public function old_help_icon ( $helpidentifier , $title , $component = 'moodle' , $linktext = '' ) {
$icon = new old_help_icon ( $helpidentifier , $title , $component );
2010-01-13 18:50:28 +00:00
if ( $linktext === true ) {
$icon -> linktext = $title ;
} else if ( ! empty ( $linktext )) {
$icon -> linktext = $linktext ;
}
return $this -> render ( $icon );
}
2009-12-30 15:19:55 +00:00
2010-01-13 18:50:28 +00:00
/**
* Implementation of user image rendering .
* @ param help_icon $helpicon
* @ return string HTML fragment
2009-08-10 06:22:04 +00:00
*/
2010-04-13 20:34:27 +00:00
protected function render_old_help_icon ( old_help_icon $helpicon ) {
2010-01-13 18:50:28 +00:00
global $CFG ;
2009-08-10 06:22:04 +00:00
2010-01-13 18:50:28 +00:00
// first get the help image icon
$src = $this -> pix_url ( 'help' );
2009-08-10 06:22:04 +00:00
2010-01-13 18:50:28 +00:00
if ( empty ( $helpicon -> linktext )) {
$alt = $helpicon -> title ;
} else {
$alt = get_string ( 'helpwiththis' );
}
$attributes = array ( 'src' => $src , 'alt' => $alt , 'class' => 'iconhelp' );
$output = html_writer :: empty_tag ( 'img' , $attributes );
// add the link text if given
if ( ! empty ( $helpicon -> linktext )) {
// the spacing has to be done through CSS
$output .= $helpicon -> linktext ;
2009-08-10 06:22:04 +00:00
}
2010-04-10 09:10:08 +00:00
// now create the link around it
$url = new moodle_url ( '/help.php' , array ( 'component' => $helpicon -> component , 'identifier' => $helpicon -> helpidentifier , 'lang' => current_language ()));
2010-01-13 18:50:28 +00:00
// note: this title is displayed only if JS is disabled, otherwise the link will have the new ajax tooltip
$title = get_string ( 'helpprefix2' , '' , trim ( $helpicon -> title , " . \t " ));
$attributes = array ( 'href' => $url , 'title' => $title );
$id = html_writer :: random_id ( 'helpicon' );
$attributes [ 'id' ] = $id ;
2010-02-18 18:15:56 +00:00
$output = html_writer :: tag ( 'a' , $output , $attributes );
2010-05-04 14:22:19 +00:00
$this -> page -> requires -> js_init_call ( 'M.util.help_icon.add' , array ( array ( 'id' => $id , 'url' => $url -> out ( false ))));
2010-01-13 18:50:28 +00:00
// and finally span
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'span' , $output , array ( 'class' => 'helplink' ));
2009-08-10 06:22:04 +00:00
}
2010-04-13 21:51:49 +00:00
/**
* Print a help icon .
*
* @ param string $identifier The keyword that defines a help page
* @ param string $component component name
* @ param string | bool $linktext true means use $title as link text , string means link text value
* @ return string HTML fragment
*/
public function help_icon ( $identifier , $component = 'moodle' , $linktext = '' ) {
2010-05-04 08:29:05 +00:00
$icon = new help_icon ( $identifier , $component );
2010-04-13 21:51:49 +00:00
$icon -> diag_strings ();
if ( $linktext === true ) {
$icon -> linktext = get_string ( $icon -> identifier , $icon -> component );
} else if ( ! empty ( $linktext )) {
$icon -> linktext = $linktext ;
}
return $this -> render ( $icon );
}
/**
* Implementation of user image rendering .
* @ param help_icon $helpicon
* @ return string HTML fragment
*/
protected function render_help_icon ( help_icon $helpicon ) {
global $CFG ;
// first get the help image icon
$src = $this -> pix_url ( 'help' );
$title = get_string ( $helpicon -> identifier , $helpicon -> component );
if ( empty ( $helpicon -> linktext )) {
$alt = $title ;
} else {
$alt = get_string ( 'helpwiththis' );
}
$attributes = array ( 'src' => $src , 'alt' => $alt , 'class' => 'iconhelp' );
$output = html_writer :: empty_tag ( 'img' , $attributes );
// add the link text if given
if ( ! empty ( $helpicon -> linktext )) {
// the spacing has to be done through CSS
$output .= $helpicon -> linktext ;
}
// now create the link around it
$url = new moodle_url ( '/help.php' , array ( 'component' => $helpicon -> component , 'identifier' => $helpicon -> identifier , 'lang' => current_language ()));
// note: this title is displayed only if JS is disabled, otherwise the link will have the new ajax tooltip
$title = get_string ( 'helpprefix2' , '' , trim ( $title , " . \t " ));
$attributes = array ( 'href' => $url , 'title' => $title );
$id = html_writer :: random_id ( 'helpicon' );
$attributes [ 'id' ] = $id ;
$output = html_writer :: tag ( 'a' , $output , $attributes );
2010-05-04 08:29:05 +00:00
$this -> page -> requires -> js_init_call ( 'M.util.help_icon.add' , array ( array ( 'id' => $id , 'url' => $url -> out ( false ))));
2010-04-13 21:51:49 +00:00
// and finally span
return html_writer :: tag ( 'span' , $output , array ( 'class' => 'helplink' ));
}
2009-08-10 06:22:04 +00:00
/**
2009-12-30 15:19:55 +00:00
* Print scale help icon .
2009-08-10 06:22:04 +00:00
*
2009-12-30 15:19:55 +00:00
* @ param int $courseid
* @ param object $scale instance
* @ return string HTML fragment
2009-08-10 06:22:04 +00:00
*/
2009-12-30 15:19:55 +00:00
public function help_icon_scale ( $courseid , stdClass $scale ) {
global $CFG ;
2009-10-23 18:49:00 +00:00
2009-12-30 15:19:55 +00:00
$title = get_string ( 'helpprefix2' , '' , $scale -> name ) . ' (' . get_string ( 'newwindow' ) . ')' ;
2009-10-23 18:49:00 +00:00
2010-02-16 17:31:35 +00:00
$icon = $this -> pix_icon ( 'help' , get_string ( 'scales' ), 'moodle' , array ( 'class' => 'iconhelp' ));
2009-10-23 18:49:00 +00:00
2010-02-11 16:56:00 +00:00
$link = new moodle_url ( '/course/scales.php' , array ( 'id' => $courseid , 'list' => true , 'scaleid' => $scale -> id ));
2010-03-24 02:35:16 +00:00
$action = new popup_action ( 'click' , $link , 'ratingscale' );
2009-10-23 18:49:00 +00:00
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'span' , $this -> action_link ( $link , $icon , $action ), array ( 'class' => 'helplink' ));
2009-08-10 06:22:04 +00:00
}
/**
* Creates and returns a spacer image with optional line break .
*
2010-02-16 17:31:35 +00:00
* @ param array $attributes
* @ param boo spacer
2009-08-10 06:22:04 +00:00
* @ return string HTML fragment
*/
2010-02-16 17:31:35 +00:00
public function spacer ( array $attributes = null , $br = false ) {
$attributes = ( array ) $attributes ;
if ( empty ( $attributes [ 'width' ])) {
$attributes [ 'width' ] = 1 ;
2009-12-27 23:31:46 +00:00
}
if ( empty ( $options [ 'height' ])) {
2010-02-16 17:31:35 +00:00
$attributes [ 'height' ] = 1 ;
2009-08-10 06:22:04 +00:00
}
2010-02-16 17:31:35 +00:00
$attributes [ 'class' ] = 'spacer' ;
2009-08-10 06:22:04 +00:00
2010-02-16 17:31:35 +00:00
$output = $this -> pix_icon ( 'spacer' , '' , 'moodle' , $attributes );
2009-08-14 03:16:23 +00:00
2010-02-16 17:31:35 +00:00
if ( ! empty ( $br )) {
2009-12-27 23:31:46 +00:00
$output .= '<br />' ;
}
2009-08-10 06:22:04 +00:00
return $output ;
}
/**
* Print the specified user ' s avatar .
*
2010-01-13 17:13:52 +00:00
* User avatar may be obtained in two ways :
2009-08-10 06:22:04 +00:00
* < pre >
2009-12-27 19:47:21 +00:00
* // Option 1: (shortcut for simple cases, preferred way)
* // $user has come from the DB and has fields id, picture, imagealt, firstname and lastname
* $OUTPUT -> user_picture ( $user , array ( 'popup' => true ));
*
2010-01-13 17:13:52 +00:00
* // Option 2:
* $userpic = new user_picture ( $user );
2009-08-10 06:22:04 +00:00
* // Set properties of $userpic
2009-12-27 19:47:21 +00:00
* $userpic -> popup = true ;
2010-01-13 17:13:52 +00:00
* $OUTPUT -> render ( $userpic );
2009-08-10 06:22:04 +00:00
* </ pre >
*
2010-01-13 17:13:52 +00:00
* @ param object Object with at least fields id , picture , imagealt , firstname , lastname
2009-12-27 19:47:21 +00:00
* If any of these are missing , the database is queried . Avoid this
2009-08-10 06:22:04 +00:00
* if at all possible , particularly for reports . It is very bad for performance .
2009-12-27 19:47:21 +00:00
* @ param array $options associative array with user picture options , used only if not a user_picture object ,
* options are :
* - courseid = $this -> page -> course -> id ( course id of user profile in link )
* - size = 35 ( size of image )
* - link = true ( make image clickable - the link leads to user profile )
* - popup = false ( open in popup )
* - alttext = true ( add image alt attribute )
2010-01-13 17:13:52 +00:00
* - class = image class attribute ( default 'userpicture' )
2009-08-10 06:22:04 +00:00
* @ return string HTML fragment
*/
2010-01-13 17:13:52 +00:00
public function user_picture ( stdClass $user , array $options = null ) {
$userpicture = new user_picture ( $user );
foreach (( array ) $options as $key => $value ) {
if ( array_key_exists ( $key , $userpicture )) {
$userpicture -> $key = $value ;
}
}
return $this -> render ( $userpicture );
}
/**
* Internal implementation of user image rendering .
* @ param user_picture $userpicture
* @ return string
*/
protected function render_user_picture ( user_picture $userpicture ) {
global $CFG , $DB ;
2009-12-27 19:47:21 +00:00
2010-01-13 17:13:52 +00:00
$user = $userpicture -> user ;
if ( $userpicture -> alttext ) {
if ( ! empty ( $user -> imagealt )) {
$alt = $user -> imagealt ;
} else {
$alt = get_string ( 'pictureof' , '' , fullname ( $user ));
}
2009-08-10 06:22:04 +00:00
} else {
2010-02-03 16:27:52 +00:00
$alt = '' ;
2010-01-13 17:13:52 +00:00
}
if ( empty ( $userpicture -> size )) {
$file = 'f2' ;
$size = 35 ;
} else if ( $userpicture -> size === true or $userpicture -> size == 1 ) {
$file = 'f1' ;
$size = 100 ;
} else if ( $userpicture -> size >= 50 ) {
$file = 'f1' ;
$size = $userpicture -> size ;
} else {
$file = 'f2' ;
$size = $userpicture -> size ;
2009-08-10 06:22:04 +00:00
}
2010-01-13 17:13:52 +00:00
$class = $userpicture -> class ;
2009-08-10 06:22:04 +00:00
2010-01-13 17:13:52 +00:00
if ( ! empty ( $user -> picture )) {
require_once ( $CFG -> libdir . '/filelib.php' );
$src = new moodle_url ( get_file_url ( $user -> id . '/' . $file . '.jpg' , null , 'user' ));
} else { // Print default user pictures (use theme version if available)
$class .= ' defaultuserpic' ;
$src = $this -> pix_url ( 'u/' . $file );
}
2009-08-10 06:22:04 +00:00
2010-01-13 17:13:52 +00:00
$attributes = array ( 'src' => $src , 'alt' => $alt , 'class' => $class , 'width' => $size , 'height' => $size );
// get the image html output fisrt
$output = html_writer :: empty_tag ( 'img' , $attributes );;
// then wrap it in link if needed
if ( ! $userpicture -> link ) {
return $output ;
2009-08-10 06:22:04 +00:00
}
2010-01-13 17:13:52 +00:00
if ( empty ( $userpicture -> courseid )) {
$courseid = $this -> page -> course -> id ;
} else {
$courseid = $userpicture -> courseid ;
}
2010-05-04 13:04:35 +00:00
if ( $courseid == SITEID ) {
$url = new moodle_url ( '/user/profile.php' , array ( 'id' => $user -> id ));
} else {
$url = new moodle_url ( '/user/view.php' , array ( 'id' => $user -> id , 'course' => $courseid ));
}
2010-01-13 17:13:52 +00:00
$attributes = array ( 'href' => $url );
if ( $userpicture -> popup ) {
$id = html_writer :: random_id ( 'userpicture' );
$attributes [ 'id' ] = $id ;
2010-02-11 15:44:06 +00:00
$this -> add_action_handler ( new popup_action ( 'click' , $url ), $id );
2010-01-13 17:13:52 +00:00
}
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'a' , $output , $attributes );
2009-08-10 06:22:04 +00:00
}
2010-05-26 08:32:31 +00:00
/**
* Internal implementation of file tree viewer items rendering .
* @ param array $dir
* @ return string
*/
public function htmllize_file_tree ( $dir ) {
if ( empty ( $dir [ 'subdirs' ]) and empty ( $dir [ 'files' ])) {
return '' ;
}
$result = '<ul>' ;
foreach ( $dir [ 'subdirs' ] as $subdir ) {
$result .= '<li>' . s ( $subdir [ 'dirname' ]) . ' ' . $this -> htmllize_file_tree ( $subdir ) . '</li>' ;
}
foreach ( $dir [ 'files' ] as $file ) {
$filename = $file -> get_filename ();
$result .= '<li><span>' . html_writer :: link ( $file -> fileurl , $filename ) . '</span></li>' ;
}
$result .= '</ul>' ;
return $result ;
}
2010-05-24 07:55:57 +00:00
/**
* Print the file picker
*
* < pre >
* $OUTPUT -> file_picker ( $options );
* </ pre >
*
* @ param array $options associative array with file manager options
* options are :
* maxbytes =>- 1 ,
* itemid => 0 ,
* client_id => uniqid (),
* acepted_types => '*' ,
* return_types => FILE_INTERNAL ,
* context => $PAGE -> context
* @ return string HTML fragment
*/
public function file_picker ( $options ) {
$fp = new file_picker ( $options );
return $this -> render ( $fp );
}
2010-05-26 08:32:31 +00:00
/**
* Internal implementation of file picker rendering .
* @ param file_picker $fp
* @ return string
*/
2010-05-24 07:55:57 +00:00
public function render_file_picker ( file_picker $fp ) {
global $CFG , $OUTPUT , $USER ;
$options = $fp -> options ;
$client_id = $options -> client_id ;
$strsaved = get_string ( 'filesaved' , 'repository' );
$straddfile = get_string ( 'openpicker' , 'repository' );
$strloading = get_string ( 'loading' , 'repository' );
$icon_progress = $OUTPUT -> pix_icon ( 'i/loading_small' , $strloading ) . '' ;
$currentfile = $options -> currentfile ;
if ( empty ( $currentfile )) {
$currentfile = get_string ( 'nofilesattached' , 'repository' );
}
$html = <<< EOD
< div class = " filemanager-loading mdl-align " id = 'filepicker-loading-{$client_id}' >
$icon_progress
</ div >
< div id = " filepicker-wrapper- { $client_id } " class = " mdl-left " style = " display:none " >
< div >
< button id = " filepicker-button- { $client_id } " > $straddfile </ button >
</ div >
EOD ;
if ( $options -> env != 'url' ) {
$html .= <<< EOD
< div id = " file_info_ { $client_id } " class = " mdl-left filepicker-filelist " > $currentfile </ div >
EOD ;
}
$html .= '</div>' ;
return $html ;
}
2009-08-10 06:22:04 +00:00
/**
* Prints the 'Update this Modulename' button that appears on module pages .
*
* @ param string $cmid the course_module id .
* @ param string $modulename the module name , eg . " forum " , " quiz " or " workshop "
* @ return string the HTML for the button , if this user has permission to edit it , else an empty string .
*/
public function update_module_button ( $cmid , $modulename ) {
global $CFG ;
if ( has_capability ( 'moodle/course:manageactivities' , get_context_instance ( CONTEXT_MODULE , $cmid ))) {
$modulename = get_string ( 'modulename' , $modulename );
$string = get_string ( 'updatethis' , '' , $modulename );
2010-01-14 19:18:04 +00:00
$url = new moodle_url ( " $CFG->wwwroot /course/mod.php " , array ( 'update' => $cmid , 'return' => true , 'sesskey' => sesskey ()));
return $this -> single_button ( $url , $string );
2009-08-10 06:22:04 +00:00
} else {
return '' ;
}
}
/**
* Prints a " Turn editing on/off " button in a form .
* @ param moodle_url $url The URL + params to send through when clicking the button
* @ return string HTML the button
*/
public function edit_button ( moodle_url $url ) {
global $USER ;
if ( ! empty ( $USER -> editing )) {
$string = get_string ( 'turneditingoff' );
$edit = '0' ;
} else {
$string = get_string ( 'turneditingon' );
$edit = '1' ;
}
2010-01-14 19:18:04 +00:00
$url = new moodle_url ( $url , array ( 'edit' => $edit ));
2009-08-10 06:22:04 +00:00
2010-01-14 19:18:04 +00:00
return $this -> single_button ( $url , $string );
2009-08-10 06:22:04 +00:00
}
/**
* Prints a simple button to close a window
*
* @ param string $text The lang string for the button ' s label ( already output from get_string ())
2010-01-14 19:18:04 +00:00
* @ return string html fragment
2009-08-10 06:22:04 +00:00
*/
2009-08-13 01:15:58 +00:00
public function close_window_button ( $text = '' ) {
2009-08-10 06:22:04 +00:00
if ( empty ( $text )) {
$text = get_string ( 'closewindow' );
}
2010-01-16 15:39:56 +00:00
$button = new single_button ( new moodle_url ( '#' ), $text , 'get' );
$button -> add_action ( new component_action ( 'click' , 'close_window' ));
2010-01-14 19:18:04 +00:00
return $this -> container ( $this -> render ( $button ), 'closewindow' );
2009-08-10 06:22:04 +00:00
}
/**
* Output an error message . By default wraps the error message in < span class = " error " >.
* If the error message is blank , nothing is output .
* @ param string $message the error message .
* @ return string the HTML to output .
*/
public function error_text ( $message ) {
if ( empty ( $message )) {
return '' ;
}
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'span' , $message , array ( 'class' => 'error' ));
2009-08-10 06:22:04 +00:00
}
/**
* Do not call this function directly .
*
* To terminate the current script with a fatal error , call the { @ link print_error }
* function , or throw an exception . Doing either of those things will then call this
* function to display the error , before terminating the execution .
*
* @ param string $message The message to output
* @ param string $moreinfourl URL where more info can be found about the error
* @ param string $link Link for the Continue button
* @ param array $backtrace The execution backtrace
* @ param string $debuginfo Debugging information
* @ return string the HTML to output .
*/
2009-10-30 13:29:14 +00:00
public function fatal_error ( $message , $moreinfourl , $link , $backtrace , $debuginfo = null ) {
2009-08-10 06:22:04 +00:00
$output = '' ;
2009-10-31 14:12:16 +00:00
$obbuffer = '' ;
2009-08-13 03:38:30 +00:00
2009-08-10 06:22:04 +00:00
if ( $this -> has_started ()) {
2009-10-30 13:44:07 +00:00
// we can not always recover properly here, we have problems with output buffering,
// html tables, etc.
2009-08-10 06:22:04 +00:00
$output .= $this -> opencontainers -> pop_all_but_last ();
2009-10-30 13:44:07 +00:00
2009-08-10 06:22:04 +00:00
} else {
2009-10-30 13:44:07 +00:00
// It is really bad if library code throws exception when output buffering is on,
// because the buffered text would be printed before our start of page.
// NOTE: this hack might be behave unexpectedly in case output buffering is enabled in PHP.ini
while ( ob_get_level () > 0 ) {
2009-10-31 14:12:16 +00:00
$obbuffer .= ob_get_clean ();
2009-10-30 13:44:07 +00:00
}
2009-10-31 14:12:16 +00:00
2009-08-10 06:22:04 +00:00
// Header not yet printed
2009-10-30 12:46:16 +00:00
if ( isset ( $_SERVER [ 'SERVER_PROTOCOL' ])) {
2009-12-16 18:00:58 +00:00
// server protocol should be always present, because this render
// can not be used from command line or when outputting custom XML
2009-10-30 12:46:16 +00:00
@ header ( $_SERVER [ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
}
2010-01-18 09:40:14 +00:00
$this -> page -> set_url ( '/' ); // no url
2009-12-27 12:02:04 +00:00
//$this->page->set_pagelayout('base'); //TODO: MDL-20676 blocks on error pages are weird, unfortunately it somehow detect the pagelayout from URL :-(
2010-06-23 09:13:23 +00:00
$this -> page -> set_title ( get_string ( 'error' ));
2010-06-23 09:16:53 +00:00
$this -> page -> set_heading ( $this -> page -> course -> fullname );
2009-08-10 06:22:04 +00:00
$output .= $this -> header ();
}
$message = '<p class="errormessage">' . $message . '</p>' .
'<p class="errorcode"><a href="' . $moreinfourl . '">' .
get_string ( 'moreinformation' ) . '</a></p>' ;
$output .= $this -> box ( $message , 'errorbox' );
2009-10-31 14:12:16 +00:00
if ( debugging ( '' , DEBUG_DEVELOPER )) {
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
$output .= $this -> notification ( '<strong>Debug info:</strong> ' . $debuginfo , 'notifytiny' );
2009-10-31 14:12:16 +00:00
}
if ( ! empty ( $backtrace )) {
$output .= $this -> notification ( '<strong>Stack trace:</strong> ' . format_backtrace ( $backtrace ), 'notifytiny' );
}
if ( $obbuffer !== '' ) {
$output .= $this -> notification ( '<strong>Output buffer:</strong> ' . s ( $obbuffer ), 'notifytiny' );
}
2009-08-10 06:22:04 +00:00
}
if ( ! empty ( $link )) {
$output .= $this -> continue_button ( $link );
}
$output .= $this -> footer ();
// Padding to encourage IE to display our error page, rather than its own.
$output .= str_repeat ( ' ' , 512 );
return $output ;
}
/**
* Output a notification ( that is , a status message about something that has
* just happened ) .
*
* @ param string $message the message to print out
* @ param string $classes normally 'notifyproblem' or 'notifysuccess' .
* @ return string the HTML to output .
*/
public function notification ( $message , $classes = 'notifyproblem' ) {
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'div' , clean_text ( $message ), array ( 'class' => renderer_base :: prepare_classes ( $classes )));
2009-08-10 06:22:04 +00:00
}
/**
* Print a continue button that goes to a particular URL .
*
2010-01-14 19:18:04 +00:00
* @ param string | moodle_url $url The url the button goes to .
2009-08-10 06:22:04 +00:00
* @ return string the HTML to output .
*/
2010-01-14 19:18:04 +00:00
public function continue_button ( $url ) {
if ( ! ( $url instanceof moodle_url )) {
$url = new moodle_url ( $url );
2009-08-10 06:22:04 +00:00
}
2010-01-14 19:18:04 +00:00
$button = new single_button ( $url , get_string ( 'continue' ), 'get' );
$button -> class = 'continuebutton' ;
2009-08-10 06:22:04 +00:00
2010-01-14 19:18:04 +00:00
return $this -> render ( $button );
2009-08-10 06:22:04 +00:00
}
/**
* Prints a single paging bar to provide access to other pages ( usually in a search )
*
2010-05-22 20:16:12 +00:00
* @ param int $totalcount The total number of entries available to be paged through
2010-02-17 16:59:41 +00:00
* @ param int $page The page you are currently viewing
* @ param int $perpage The number of entries that should be shown per page
* @ param string | moodle_url $baseurl url of the current page , the $pagevar parameter is added
* @ param string $pagevar name of page parameter that holds the page number
2009-08-10 06:22:04 +00:00
* @ return string the HTML to output .
*/
2010-02-17 16:59:41 +00:00
public function paging_bar ( $totalcount , $page , $perpage , $baseurl , $pagevar = 'page' ) {
$pb = new paging_bar ( $totalcount , $page , $perpage , $baseurl , $pagevar );
return $this -> render ( $pb );
}
/**
* Internal implementation of paging bar rendering .
* @ param paging_bar $pagingbar
* @ return string
*/
protected function render_paging_bar ( paging_bar $pagingbar ) {
2009-08-10 06:22:04 +00:00
$output = '' ;
$pagingbar = clone ( $pagingbar );
2009-12-27 12:58:29 +00:00
$pagingbar -> prepare ( $this , $this -> page , $this -> target );
2009-08-10 06:22:04 +00:00
if ( $pagingbar -> totalcount > $pagingbar -> perpage ) {
$output .= get_string ( 'page' ) . ':' ;
if ( ! empty ( $pagingbar -> previouslink )) {
2010-02-16 17:23:49 +00:00
$output .= ' (' . $pagingbar -> previouslink . ') ' ;
2009-08-10 06:22:04 +00:00
}
if ( ! empty ( $pagingbar -> firstlink )) {
2010-02-16 17:23:49 +00:00
$output .= ' ' . $pagingbar -> firstlink . ' ...' ;
2009-08-10 06:22:04 +00:00
}
foreach ( $pagingbar -> pagelinks as $link ) {
2010-02-16 17:23:49 +00:00
$output .= "    $link " ;
2009-08-10 06:22:04 +00:00
}
if ( ! empty ( $pagingbar -> lastlink )) {
2010-02-16 17:23:49 +00:00
$output .= ' ...' . $pagingbar -> lastlink . ' ' ;
2009-08-10 06:22:04 +00:00
}
if ( ! empty ( $pagingbar -> nextlink )) {
2010-02-16 17:23:49 +00:00
$output .= '  (' . $pagingbar -> nextlink . ')' ;
2009-08-10 06:22:04 +00:00
}
}
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'div' , $output , array ( 'class' => 'paging' ));
2009-08-10 06:22:04 +00:00
}
/**
* Output the place a skip link goes to .
* @ param string $id The target name from the corresponding $PAGE -> requires -> skip_link_to ( $target ) call .
* @ return string the HTML to output .
*/
2010-02-16 08:26:21 +00:00
public function skip_link_target ( $id = null ) {
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'span' , '' , array ( 'id' => $id ));
2009-08-10 06:22:04 +00:00
}
/**
* Outputs a heading
* @ param string $text The text of the heading
* @ param int $level The level of importance of the heading . Defaulting to 2
* @ param string $classes A space - separated list of CSS classes
* @ param string $id An optional ID
* @ return string the HTML to output .
*/
2010-02-16 08:26:21 +00:00
public function heading ( $text , $level = 2 , $classes = 'main' , $id = null ) {
2009-08-10 06:22:04 +00:00
$level = ( integer ) $level ;
if ( $level < 1 or $level > 6 ) {
throw new coding_exception ( 'Heading level must be an integer between 1 and 6.' );
}
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'h' . $level , $text , array ( 'id' => $id , 'class' => renderer_base :: prepare_classes ( $classes )));
2009-08-10 06:22:04 +00:00
}
/**
* Outputs a box .
* @ param string $contents The contents of the box
* @ param string $classes A space - separated list of CSS classes
* @ param string $id An optional ID
* @ return string the HTML to output .
*/
2010-02-16 08:26:21 +00:00
public function box ( $contents , $classes = 'generalbox' , $id = null ) {
2009-08-10 06:22:04 +00:00
return $this -> box_start ( $classes , $id ) . $contents . $this -> box_end ();
}
/**
* Outputs the opening section of a box .
* @ param string $classes A space - separated list of CSS classes
* @ param string $id An optional ID
* @ return string the HTML to output .
*/
2010-02-16 08:26:21 +00:00
public function box_start ( $classes = 'generalbox' , $id = null ) {
2010-01-13 17:13:52 +00:00
$this -> opencontainers -> push ( 'box' , html_writer :: end_tag ( 'div' ));
return html_writer :: start_tag ( 'div' , array ( 'id' => $id ,
2009-12-16 18:00:58 +00:00
'class' => 'box ' . renderer_base :: prepare_classes ( $classes )));
2009-08-10 06:22:04 +00:00
}
/**
* Outputs the closing section of a box .
* @ return string the HTML to output .
*/
public function box_end () {
return $this -> opencontainers -> pop ( 'box' );
}
/**
* Outputs a container .
* @ param string $contents The contents of the box
* @ param string $classes A space - separated list of CSS classes
* @ param string $id An optional ID
* @ return string the HTML to output .
*/
2010-02-16 08:26:21 +00:00
public function container ( $contents , $classes = null , $id = null ) {
2009-08-10 06:22:04 +00:00
return $this -> container_start ( $classes , $id ) . $contents . $this -> container_end ();
}
/**
* Outputs the opening section of a container .
* @ param string $classes A space - separated list of CSS classes
* @ param string $id An optional ID
* @ return string the HTML to output .
*/
2010-02-16 08:26:21 +00:00
public function container_start ( $classes = null , $id = null ) {
2010-01-13 17:13:52 +00:00
$this -> opencontainers -> push ( 'container' , html_writer :: end_tag ( 'div' ));
return html_writer :: start_tag ( 'div' , array ( 'id' => $id ,
2009-12-16 18:00:58 +00:00
'class' => renderer_base :: prepare_classes ( $classes )));
2009-08-10 06:22:04 +00:00
}
/**
* Outputs the closing section of a container .
* @ return string the HTML to output .
*/
public function container_end () {
return $this -> opencontainers -> pop ( 'container' );
}
2009-08-28 08:47:31 +00:00
2010-04-19 06:30:30 +00:00
/**
2009-08-28 08:47:31 +00:00
* Make nested HTML lists out of the items
*
* The resulting list will look something like this :
*
* < pre >
* << ul >>
* << li >>< div class = 'tree_item parent' > ( item contents ) </ div >
* << ul >
* << li >>< div class = 'tree_item' > ( item contents ) </ div ><</ li >>
* <</ ul >>
* <</ li >>
* <</ ul >>
* </ pre >
*
* @ param array [] tree_item $items
* @ param array [ string ] string $attrs html attributes passed to the top of
* the list
* @ return string HTML
*/
function tree_block_contents ( $items , $attrs = array ()) {
// exit if empty, we don't want an empty ul element
if ( empty ( $items )) {
return '' ;
}
// array of nested li elements
$lis = array ();
foreach ( $items as $item ) {
// this applies to the li item which contains all child lists too
$content = $item -> content ( $this );
$liclasses = array ( $item -> get_css_type ());
2010-04-19 06:30:30 +00:00
if ( ! $item -> forceopen || ( ! $item -> forceopen && $item -> collapse ) || ( $item -> children -> count () == 0 && $item -> nodetype == navigation_node :: NODETYPE_BRANCH )) {
2009-08-28 08:47:31 +00:00
$liclasses [] = 'collapsed' ;
}
if ( $item -> isactive === true ) {
$liclasses [] = 'current_branch' ;
}
$liattr = array ( 'class' => join ( ' ' , $liclasses ));
// class attribute on the div item which only contains the item content
$divclasses = array ( 'tree_item' );
2010-04-19 06:30:30 +00:00
if ( $item -> children -> count () > 0 || $item -> nodetype == navigation_node :: NODETYPE_BRANCH ) {
2009-08-28 08:47:31 +00:00
$divclasses [] = 'branch' ;
} else {
$divclasses [] = 'leaf' ;
}
if ( ! empty ( $item -> classes ) && count ( $item -> classes ) > 0 ) {
$divclasses [] = join ( ' ' , $item -> classes );
}
$divattr = array ( 'class' => join ( ' ' , $divclasses ));
if ( ! empty ( $item -> id )) {
$divattr [ 'id' ] = $item -> id ;
}
2010-02-18 18:15:56 +00:00
$content = html_writer :: tag ( 'p' , $content , $divattr ) . $this -> tree_block_contents ( $item -> children );
2009-08-28 08:47:31 +00:00
if ( ! empty ( $item -> preceedwithhr ) && $item -> preceedwithhr === true ) {
2010-02-18 18:15:56 +00:00
$content = html_writer :: empty_tag ( 'hr' ) . $content ;
2009-08-28 08:47:31 +00:00
}
2010-02-18 18:15:56 +00:00
$content = html_writer :: tag ( 'li' , $content , $liattr );
2009-08-28 08:47:31 +00:00
$lis [] = $content ;
}
2010-02-18 18:15:56 +00:00
return html_writer :: tag ( 'ul' , implode ( " \n " , $lis ), $attrs );
2009-08-28 08:47:31 +00:00
}
/**
* Return the navbar content so that it can be echoed out by the layout
* @ return string XHTML navbar
*/
public function navbar () {
2010-04-19 06:30:30 +00:00
//return $this->page->navbar->content();
$items = $this -> page -> navbar -> get_items ();
$count = 0 ;
$htmlblocks = array ();
// Iterate the navarray and display each node
2010-04-27 05:19:32 +00:00
$itemcount = count ( $items );
$separator = get_separator ();
for ( $i = 0 ; $i < $itemcount ; $i ++ ) {
$item = $items [ $i ];
2010-04-23 04:21:33 +00:00
$item -> hideicon = true ;
2010-04-27 05:19:32 +00:00
if ( $i === 0 ) {
$content = html_writer :: tag ( 'li' , $this -> render ( $item ));
} else {
$content = html_writer :: tag ( 'li' , $separator . $this -> render ( $item ));
}
$htmlblocks [] = $content ;
2010-04-19 06:30:30 +00:00
}
2010-06-23 09:13:23 +00:00
//accessibility: heading for navbar list (MDL-20446)
$navbarcontent = html_writer :: tag ( 'span' , get_string ( 'pagepath' ), array ( 'class' => 'accesshide' ));
$navbarcontent .= html_writer :: tag ( 'ul' , join ( '' , $htmlblocks ));
2010-04-19 06:30:30 +00:00
// XHTML
2010-06-23 09:13:23 +00:00
return $navbarcontent ;
2010-04-19 06:30:30 +00:00
}
protected function render_navigation_node ( navigation_node $item ) {
$content = $item -> get_content ();
$title = $item -> get_title ();
2010-04-23 04:21:33 +00:00
if ( $item -> icon instanceof renderable && ! $item -> hideicon ) {
2010-04-19 06:30:30 +00:00
$icon = $this -> render ( $item -> icon );
2010-06-03 08:27:03 +00:00
$content = $icon . $content ; // use CSS for spacing of icons
2010-04-19 06:30:30 +00:00
}
if ( $item -> helpbutton !== null ) {
$content = trim ( $item -> helpbutton ) . html_writer :: tag ( 'span' , $content , array ( 'class' => 'clearhelpbutton' ));
}
if ( $content === '' ) {
2010-05-11 15:47:12 +00:00
return '' ;
2010-04-19 06:30:30 +00:00
}
if ( $item -> action instanceof action_link ) {
//TODO: to be replaced with something else
$link = $item -> action ;
if ( $item -> hidden ) {
$link -> add_class ( 'dimmed' );
}
$content = $this -> output -> render ( $link );
} else if ( $item -> action instanceof moodle_url ) {
$attributes = array ();
if ( $title !== '' ) {
$attributes [ 'title' ] = $title ;
}
if ( $item -> hidden ) {
$attributes [ 'class' ] = 'dimmed_text' ;
}
$content = html_writer :: link ( $item -> action , $content , $attributes );
} else if ( is_string ( $item -> action ) || empty ( $item -> action )) {
$attributes = array ();
if ( $title !== '' ) {
$attributes [ 'title' ] = $title ;
}
if ( $item -> hidden ) {
$attributes [ 'class' ] = 'dimmed_text' ;
}
$content = html_writer :: tag ( 'span' , $content , $attributes );
}
return $content ;
2009-08-28 08:47:31 +00:00
}
2009-12-23 17:44:17 +00:00
/**
* Accessibility : Right arrow - like character is
* used in the breadcrumb trail , course navigation menu
* ( previous / next activity ), calendar , and search forum block .
* If the theme does not set characters , appropriate defaults
* are set automatically . Please DO NOT
* use & lt ; & gt ; & raquo ; - these are confusing for blind users .
* @ return string
*/
public function rarrow () {
return $this -> page -> theme -> rarrow ;
}
/**
* Accessibility : Right arrow - like character is
* used in the breadcrumb trail , course navigation menu
* ( previous / next activity ), calendar , and search forum block .
* If the theme does not set characters , appropriate defaults
* are set automatically . Please DO NOT
* use & lt ; & gt ; & raquo ; - these are confusing for blind users .
* @ return string
*/
public function larrow () {
return $this -> page -> theme -> larrow ;
}
2009-12-23 17:51:41 +00:00
/**
* Returns the colours of the small MP3 player
* @ return string
*/
public function filter_mediaplugin_colors () {
return $this -> page -> theme -> filter_mediaplugin_colors ;
}
/**
* Returns the colours of the big MP3 player
* @ return string
*/
public function resource_mp3player_colors () {
return $this -> page -> theme -> resource_mp3player_colors ;
}
2010-05-10 05:24:00 +00:00
/**
* Returns the custom menu if one has been set
*
2010-05-22 20:16:12 +00:00
* A custom menu can be configured by browsing to
2010-05-10 05:24:00 +00:00
* Settings : Administration > Appearance > Themes > Theme settings
* and then configuring the custommenu config setting as described .
2010-05-19 08:05:36 +00:00
*
2010-05-10 05:24:00 +00:00
* @ return string
*/
public function custom_menu () {
2010-05-11 07:30:04 +00:00
global $CFG ;
if ( empty ( $CFG -> custommenuitems )) {
return '' ;
}
2010-05-10 05:24:00 +00:00
$custommenu = new custom_menu ();
return $this -> render_custom_menu ( $custommenu );
}
/**
* Renders a custom menu object ( located in outputcomponents . php )
*
* The custom menu this method produces makes use of the YUI3 menunav widget
* and requires very specific html elements and classes .
*
* @ staticvar int $menucount
* @ param custom_menu $menu
* @ return string
*/
protected function render_custom_menu ( custom_menu $menu ) {
static $menucount = 0 ;
// If the menu has no children return an empty string
if ( ! $menu -> has_children ()) {
return '' ;
}
// Increment the menu count. This is used for ID's that get worked with
// in JavaScript as is essential
$menucount ++ ;
// Initialise this custom menu
2010-05-10 09:41:32 +00:00
$this -> page -> requires -> js_init_call ( 'M.core_custom_menu.init' , array ( 'custom_menu_' . $menucount ));
2010-05-10 05:24:00 +00:00
// Build the root nodes as required by YUI
$content = html_writer :: start_tag ( 'div' , array ( 'id' => 'custom_menu_' . $menucount , 'class' => 'yui3-menu yui3-menu-horizontal javascript-disabled' ));
$content .= html_writer :: start_tag ( 'div' , array ( 'class' => 'yui3-menu-content' ));
$content .= html_writer :: start_tag ( 'ul' );
// Render each child
foreach ( $menu -> get_children () as $item ) {
$content .= $this -> render_custom_menu_item ( $item );
}
// Close the open tags
$content .= html_writer :: end_tag ( 'ul' );
$content .= html_writer :: end_tag ( 'div' );
$content .= html_writer :: end_tag ( 'div' );
// Return the custom menu
return $content ;
}
/**
* Renders a custom menu node as part of a submenu
*
* The custom menu this method produces makes use of the YUI3 menunav widget
* and requires very specific html elements and classes .
*
* @ see render_custom_menu ()
*
* @ staticvar int $submenucount
* @ param custom_menu_item $menunode
* @ return string
*/
protected function render_custom_menu_item ( custom_menu_item $menunode ) {
// Required to ensure we get unique trackable id's
static $submenucount = 0 ;
if ( $menunode -> has_children ()) {
// If the child has menus render it as a sub menu
$submenucount ++ ;
$content = html_writer :: start_tag ( 'li' );
if ( $menunode -> get_url () !== null ) {
$url = $menunode -> get_url ();
} else {
$url = '#cm_submenu_' . $submenucount ;
}
$content .= html_writer :: link ( $url , $menunode -> get_text (), array ( 'class' => 'yui3-menu-label' , 'title' => $menunode -> get_title ()));
$content .= html_writer :: start_tag ( 'div' , array ( 'id' => 'cm_submenu_' . $submenucount , 'class' => 'yui3-menu custom_menu_submenu' ));
$content .= html_writer :: start_tag ( 'div' , array ( 'class' => 'yui3-menu-content' ));
$content .= html_writer :: start_tag ( 'ul' );
foreach ( $menunode -> get_children () as $menunode ) {
$content .= $this -> render_custom_menu_item ( $menunode );
}
$content .= html_writer :: end_tag ( 'ul' );
$content .= html_writer :: end_tag ( 'div' );
$content .= html_writer :: end_tag ( 'div' );
$content .= html_writer :: end_tag ( 'li' );
} else {
// The node doesn't have children so produce a final menuitem
$content = html_writer :: start_tag ( 'li' , array ( 'class' => 'yui3-menuitem' ));
if ( $menunode -> get_url () !== null ) {
$url = $menunode -> get_url ();
} else {
$url = '#' ;
}
$content .= html_writer :: link ( $url , $menunode -> get_text (), array ( 'class' => 'yui3-menuitem-content' , 'title' => $menunode -> get_title ()));
$content .= html_writer :: end_tag ( 'li' );
}
// Return the sub menu
return $content ;
}
2010-06-04 01:49:53 +00:00
/**
* Renders the image_gallery component and initialises its JavaScript
*
* @ param image_gallery $imagegallery
* @ return string
*/
protected function render_image_gallery ( image_gallery $imagegallery ) {
$this -> page -> requires -> js_gallery_module ( array ( 'gallery-lightbox' , 'gallery-lightbox-skin' ), '2010.04.08-12-35' , 'Y.Lightbox.init' );
if ( count ( $imagegallery -> images ) == 0 ) {
return '' ;
}
2010-06-04 02:46:25 +00:00
$classes = array ( 'image_gallery' );
if ( $imagegallery -> displayfirstimageonly ) {
$classes [] = 'oneimageonly' ;
}
$content = html_writer :: start_tag ( 'div' , array ( 'class' => join ( ' ' , $classes )));
2010-06-04 01:49:53 +00:00
foreach ( $imagegallery -> images as $image ) {
$content .= html_writer :: tag ( 'a' , html_writer :: empty_tag ( 'img' , $image -> thumb ), $image -> link );
}
$content .= html_writer :: end_tag ( 'div' );
return $content ;
}
2009-12-16 18:00:58 +00:00
}
2009-08-10 06:22:04 +00:00
/// RENDERERS
/**
* A renderer that generates output for command - line scripts .
*
* The implementation of this renderer is probably incomplete .
*
* @ copyright 2009 Tim Hunt
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.0
*/
2009-12-17 13:45:54 +00:00
class core_renderer_cli extends core_renderer {
2009-08-10 06:22:04 +00:00
/**
* Returns the page header .
* @ return string HTML fragment
*/
public function header () {
output_starting_hook ();
return $this -> page -> heading . " \n " ;
}
/**
* Returns a template fragment representing a Heading .
* @ param string $text The text of the heading
* @ param int $level The level of importance of the heading
* @ param string $classes A space - separated list of CSS classes
* @ param string $id An optional ID
* @ return string A template fragment for a heading
*/
2010-04-10 22:23:46 +00:00
public function heading ( $text , $level = 2 , $classes = 'main' , $id = null ) {
2009-08-10 06:22:04 +00:00
$text .= " \n " ;
switch ( $level ) {
case 1 :
return '=>' . $text ;
case 2 :
return '-->' . $text ;
default :
return $text ;
}
}
/**
* Returns a template fragment representing a fatal error .
* @ param string $message The message to output
* @ param string $moreinfourl URL where more info can be found about the error
* @ param string $link Link for the Continue button
* @ param array $backtrace The execution backtrace
* @ param string $debuginfo Debugging information
* @ return string A template fragment for a fatal error
*/
2009-10-30 13:29:14 +00:00
public function fatal_error ( $message , $moreinfourl , $link , $backtrace , $debuginfo = null ) {
2009-08-10 06:22:04 +00:00
$output = " !!! $message !!! \n " ;
if ( debugging ( '' , DEBUG_DEVELOPER )) {
if ( ! empty ( $debuginfo )) {
$this -> notification ( $debuginfo , 'notifytiny' );
}
if ( ! empty ( $backtrace )) {
$this -> notification ( 'Stack trace: ' . format_backtrace ( $backtrace , true ), 'notifytiny' );
}
}
}
/**
* Returns a template fragment representing a notification .
* @ param string $message The message to include
* @ param string $classes A space - separated list of CSS classes
* @ return string A template fragment for a notification
*/
public function notification ( $message , $classes = 'notifyproblem' ) {
$message = clean_text ( $message );
if ( $classes === 'notifysuccess' ) {
return " ++ $message ++ \n " ;
}
return " !! $message !! \n " ;
}
}
2010-03-28 09:05:47 +00:00
/**
* A renderer that generates output for ajax scripts .
*
* This renderer prevents accidental sends back only json
* encoded error messages , all other output is ignored .
*
* @ copyright 2010 Petr Skoda
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.0
*/
class core_renderer_ajax extends core_renderer {
/**
* Returns a template fragment representing a fatal error .
* @ param string $message The message to output
* @ param string $moreinfourl URL where more info can be found about the error
* @ param string $link Link for the Continue button
* @ param array $backtrace The execution backtrace
* @ param string $debuginfo Debugging information
* @ return string A template fragment for a fatal error
*/
public function fatal_error ( $message , $moreinfourl , $link , $backtrace , $debuginfo = null ) {
$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 );
}
}
return json_encode ( $e );
}
public function notification ( $message , $classes = 'notifyproblem' ) {
}
public function redirect_message ( $encodedurl , $message , $delay , $debugdisableredirect ) {
}
public function header () {
}
public function footer () {
}
2010-04-10 22:23:46 +00:00
public function heading ( $text , $level = 2 , $classes = 'main' , $id = null ) {
2010-03-28 09:05:47 +00:00
}
}