diff --git a/group/autogroup.php b/group/autogroup.php index 6a74cc84591..19a27290af1 100644 --- a/group/autogroup.php +++ b/group/autogroup.php @@ -17,6 +17,7 @@ if (!defined('AUTOGROUP_MIN_RATIO')) { } $courseid = required_param('courseid', PARAM_INT); +$PAGE->set_url('/group/autogroup.php', array('courseid' => $courseid)); if (!$course = $DB->get_record('course', array('id'=>$courseid))) { print_error('invalidcourseid'); diff --git a/group/autogroup_form.php b/group/autogroup_form.php index 373901a2af1..06887e6b384 100644 --- a/group/autogroup_form.php +++ b/group/autogroup_form.php @@ -45,8 +45,7 @@ class autogroup_form extends moodleform { $mform->setAdvanced('allocateby'); $mform->addElement('text', 'namingscheme', get_string('namingscheme', 'group')); - $mform->setHelpButton('namingscheme', array(false, get_string('namingschemehelp', 'group'), - false, true, false, get_string('namingschemehelp', 'group'))); + $mform->setHelpButton('namingscheme', array('namingscheme', get_string('namingschemehelp', 'group'), 'group')); $mform->addRule('namingscheme', get_string('required'), 'required', null, 'client'); $mform->setType('namingscheme', PARAM_MULTILANG); // there must not be duplicate group names in course diff --git a/help.php b/help.php index 93779336f0c..655c8f54bfa 100644 --- a/help.php +++ b/help.php @@ -19,6 +19,7 @@ $text = optional_param('text', 'No text to display', PARAM_CLEAN); $module = optional_param('module', 'moodle', PARAM_ALPHAEXT); $forcelang = optional_param('forcelang', '', PARAM_SAFEDIR); $skiplocal = optional_param('skiplocal', 0, PARAM_INT); // shall _local help files be skipped? +$fortooltip = optional_param('fortooltip', 0, PARAM_INT); $PAGE->set_course($COURSE); @@ -62,8 +63,14 @@ if (!empty($file)) { // Finish buffer $output = ob_get_contents(); + ob_end_clean(); +if ($fortooltip) { + echo shorten_text($output, 400, false, '' . get_string('clickhelpiconformoreinfo') . ''); + die(); +} + // Determine title $title = get_string('help'); // Default is just 'Help' $matches = array(); diff --git a/index.php b/index.php index bad1b72d4e4..d92a85980d2 100644 --- a/index.php +++ b/index.php @@ -66,6 +66,9 @@ add_to_log(SITEID, 'course', 'view', 'view.php?id='.SITEID, SITEID); } + $PAGE->set_pagetype('site-index'); + $PAGE->set_course($SITE); + if (empty($CFG->langmenu)) { $langmenu = ''; } else { @@ -74,9 +77,6 @@ $langlabel = get_accesshide(get_string('language')); $langmenu = popup_form($CFG->wwwroot .'/index.php?lang=', $langs, 'chooselang', $currlang, '', '', '', true, 'self', $langlabel); } - - $PAGE->set_pagetype('site-index'); - $PAGE->set_course($SITE); $PAGE->set_other_editing_capability('moodle/course:manageactivities'); $PAGE->set_url(''); $PAGE->set_docs_path(''); diff --git a/lang/en_utf8/help/group/namingscheme.html b/lang/en_utf8/help/group/namingscheme.html new file mode 100644 index 00000000000..4ee5a1b73b3 --- /dev/null +++ b/lang/en_utf8/help/group/namingscheme.html @@ -0,0 +1,2 @@ +
Use @ character to represent the group letter (A-Z) or # to represent the group number.
diff --git a/lang/en_utf8/moodle.php b/lang/en_utf8/moodle.php index f4547f56bc3..5eb64a8aec4 100644 --- a/lang/en_utf8/moodle.php +++ b/lang/en_utf8/moodle.php @@ -242,6 +242,7 @@ $string['clamquarantinedirfailed'] = 'Could not move the file into your specifie $string['clamunknownerror'] = 'There was an unknown error with clam.'; $string['cleaningtempdata'] = 'Cleaning temp data'; $string['clear'] = 'Clear'; +$string['clickhelpiconformoreinfo'] = '... continues ... Click on the help icon to read the full article'; $string['clickhere'] = 'Click here ...'; $string['clicktochange'] = 'Click to change'; $string['clicktohideshow'] = 'Click to expand or collapse'; diff --git a/lib/ajax/ajaxlib.php b/lib/ajax/ajaxlib.php index 00d7f87b265..46a18051833 100644 --- a/lib/ajax/ajaxlib.php +++ b/lib/ajax/ajaxlib.php @@ -32,7 +32,7 @@ * @param page_requirements_manager $requires The page_requirements_manager to initialise. */ function setup_core_javascript(page_requirements_manager $requires) { - global $CFG; + global $CFG, $OUTPUT; // JavaScript should always work with $CFG->httpswwwroot rather than $CFG->wwwroot. // Otherwise, in some situations, users will get warnings about insecure content @@ -41,6 +41,7 @@ function setup_core_javascript(page_requirements_manager $requires) { $config = array( 'wwwroot' => $CFG->httpswwwroot, // Yes, really. See above. 'sesskey' => sesskey(), + 'loadingicon' => $OUTPUT->old_icon_url('i/loading_small') ); if (debugging('', DEBUG_DEVELOPER)) { $config['developerdebug'] = true; @@ -56,6 +57,12 @@ function setup_core_javascript(page_requirements_manager $requires) { // Note that, as a short-cut, the code // $js = "document.body.className += ' jsenabled';\n"; // is hard-coded in {@link page_requirements_manager::get_top_of_body_code) + $requires->yui_lib('container'); + $requires->yui_lib('connection'); + $requires->string_for_js('confirmation', 'moodle'); + $requires->string_for_js('cancel', 'moodle'); + $requires->string_for_js('yes', 'moodle'); + $requires->js_function_call('init_help_icons'); } @@ -364,8 +371,9 @@ class page_requirements_manager { * @return required_event_handler The event_handler object */ public function event_handler($id, $event, $function, $arguments=array()) { - $requirement = new required_event_handler($id, $event, $function, $arguments); + $requirement = new required_event_handler($this, $id, $event, $function, $arguments); $this->requiredjscode[] = $requirement; + $this->linkedrequirements[] = new required_yui_lib($this, 'event'); return $requirement; } @@ -1109,7 +1117,6 @@ class required_event_handler extends required_js_code { * @param array $arguments An optional array of argument parameters to pass to the function */ public function __construct(page_requirements_manager $manager, $id, $event, $function, $args=array()) { - $manager->requires->yui_lib('event'); parent::__construct($manager); $this->id = $id; $this->event = $event; @@ -1118,7 +1125,7 @@ class required_event_handler extends required_js_code { } public function get_js_code() { - $output = "YAHOO.util.Event.addListener($this->id, '$this->event', $this->function"; + $output = "YAHOO.util.Event.addListener('$this->id', '$this->event', $this->function"; if (!empty($this->args)) { $output .= ', ' . json_encode($this->args); } diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php index 44ed07e5291..94098918ad9 100644 --- a/lib/deprecatedlib.php +++ b/lib/deprecatedlib.php @@ -2379,3 +2379,599 @@ function print_table($table, $return=false) { return true; } } + +/** + * Creates and displays (or returns) a link to a popup window + * + * @deprecated since Moodle 2.0 + * + * @param string $url Web link. Either relative to $CFG->wwwroot, or a full URL. + * @param string $name Name to be assigned to the popup window (this is used by + * client-side scripts to "talk" to the popup window) + * @param string $linkname Text to be displayed as web link + * @param int $height Height to assign to popup window + * @param int $width Height to assign to popup window + * @param string $title Text to be displayed as popup page title + * @param string $options List of additional options for popup window + * @param bool $return If true, return as a string, otherwise print + * @param string $id id added to the element + * @param string $class class added to the element + * @return string html code to display a link to a popup window. + */ +function link_to_popup_window ($url, $name=null, $linkname=null, + $height=400, $width=500, $title=null, + $options=null, $return=false) { + global $OUTPUT; + + // debugging('link_to_popup_window() has been deprecated. Please change your code to use $OUTPUT->link_to_popup().'); + + if ($options == 'none') { + $options = null; + } + + if (empty($linkname)) { + throw new coding_exception('A link must have a descriptive text value! See $OUTPUT->link_to_popup() for usage.'); + } + + // Create a html_link object + $link = new html_link(); + $link->text = $linkname; + $link->url = $url; + $link->title = $title; + + // Parse the $options string + $popupparams = array(); + if (!empty($options)) { + $optionsarray = explode(',', $options); + foreach ($optionsarray as $option) { + if (strstr($option, '=')) { + $parts = explode('=', $option); + if ($parts[1] == '0') { + $popupparams[$parts[0]] = false; + } else { + $popupparams[$parts[0]] = $parts[1]; + } + } else { + $popupparams[$option] = true; + } + } + } + + $popupaction = new popup_action('click', $url, $name, $popupparams); + $link->add_action_object($popupaction); + + // Call the output method + $output = $OUTPUT->link_to_popup($link); + + if ($return) { + return $output; + } else { + echo $output; + } +} + +/** + * Creates and displays (or returns) a buttons to a popup window. + * + * @deprecated since Moodle 2.0 + * + * @param string $url Web link. Either relative to $CFG->wwwroot, or a full URL. + * @param string $name Name to be assigned to the popup window (this is used by + * client-side scripts to "talk" to the popup window) + * @param string $linkname Text to be displayed as web link + * @param int $height Height to assign to popup window + * @param int $width Height to assign to popup window + * @param string $title Text to be displayed as popup page title + * @param string $options List of additional options for popup window + * @param bool $return If true, return as a string, otherwise print + * @param string $id id added to the element + * @param string $class class added to the element + * @return string html code to display a link to a popup window. + */ +function button_to_popup_window ($url, $name=null, $linkname=null, + $height=400, $width=500, $title=null, $options=null, $return=false, + $id=null, $class=null) { + global $OUTPUT; + + // debugging('link_to_popup_window() has been deprecated. Please change your code to use $OUTPUT->link_to_popup().'); + + if ($options == 'none') { + $options = null; + } + + if (empty($linkname)) { + throw new coding_exception('A link must have a descriptive text value! See $OUTPUT->link_to_popup() for usage.'); + } + + // Create a html_button object + $button = new html_button(); + $button->value = $linkname; + $button->url = $url; + $button->id = $id; + $button->add_class($class); + $button->method = 'post'; + $button->title = $title; + + // Parse the $options string + $popupparams = array(); + if (!empty($options)) { + $optionsarray = explode(',', $options); + foreach ($optionsarray as $option) { + if (strstr($option, '=')) { + $parts = explode('=', $option); + if ($parts[1] == '0') { + $popupparams[$parts[0]] = false; + } else { + $popupparams[$parts[0]] = $parts[1]; + } + } else { + $popupparams[$option] = true; + } + } + } + + if (!empty($height)) { + $popupparams['height'] = $height; + } + if (!empty($width)) { + $popupparams['width'] = $width; + } + + $popupaction = new popup_action('click', $url, $name, $popupparams); + $button->add_action_object($popupaction); + $output = $OUTPUT->button($button); + + if ($return) { + return $output; + } else { + echo $output; + } +} + +/** + * Print a self contained form with a single submit button. + * + * @deprecated since Moodle 2.0 + * + * @param string $link used as the action attribute on the form, so the URL that will be hit if the button is clicked. + * @param array $options these become hidden form fields, so these options get passed to the script at $link. + * @param string $label the caption that appears on the button. + * @param string $method HTTP method used on the request of the button is clicked. 'get' or 'post'. + * @param string $notusedanymore no longer used. + * @param boolean $return if false, output the form directly, otherwise return the HTML as a string. + * @param string $tooltip a tooltip to add to the button as a title attribute. + * @param boolean $disabled if true, the button will be disabled. + * @param string $jsconfirmmessage if not empty then display a confirm dialogue with this string as the question. + * @param string $formid The id attribute to use for the form + * @return string|void Depending on the $return paramter. + */ +function print_single_button($link, $options, $label='OK', $method='get', $notusedanymore='', + $return=false, $tooltip='', $disabled = false, $jsconfirmmessage='', $formid = '') { + global $OUTPUT; + + // debugging('print_single_button() has been deprecated. Please change your code to use $OUTPUT->button().'); + + // Cast $options to array + $options = (array) $options; + $form = new html_form(); + $form->url = new moodle_url($link, $options); + $form->button->label = $label; + $form->button->disabled = $disabled; + $form->button->title = $tooltip; + $form->method = $method; + $form->id = $formid; + + if ($jsconfirmmessage) { + $confirmaction = new component_action('click', 'confirm_dialog', array($jsconfirmmessage)); + $form->button->add_action_object($confirmaction); + } + + $output = $OUTPUT->button($form); + + if ($return) { + return $output; + } else { + echo $output; + } +} + +/** + * Print a spacer image with the option of including a line break. + * + * @deprecated since Moodle 2.0 + * + * @global object + * @param int $height The height in pixels to make the spacer + * @param int $width The width in pixels to make the spacer + * @param boolean $br If set to true a BR is written after the spacer + */ +function print_spacer($height=1, $width=1, $br=true, $return=false) { + global $CFG, $OUTPUT; + + // debugging('print_spacer() has been deprecated. Please change your code to use $OUTPUT->spacer().'); + + $spacer = new html_spacer(); + $spacer->height = $height; + $spacer->width = $width; + + $output = $OUTPUT->spacer($spacer); + + $output .= '
';
+
+ if ($br) {
+ $output .= '$text
"); + } + + if (!empty($imagetext)) { + throw new coding_exception('The $imagetext parameter has been deprecated. Please update your code and use $OUTPUT->help_icon() instead.'); + } + + $helpicon = new help_icon(); + $helpicon->page = $page; + $helpicon->module = $module; + $helpicon->text = $title; + $helpicon->linktext = $linktext; + + // If image is true, the defaults are handled by the helpicon's prepare method + if (!$image) { + $helpicon->image = false; + } + + $output = $OUTPUT->help_icon($helpicon); + + if ($return) { + return $output; + } else { + echo $output; + } + +} + +/** + * Returns an image of an up or down arrow, used for column sorting. To avoid unnecessary DB accesses, please + * provide this function with the language strings for sortasc and sortdesc. + * + * @deprecated since Moodle 2.0 + * + * TODO migrate to outputlib + * If no sort string is associated with the direction, an arrow with no alt text will be printed/returned. + * + * @global object + * @param string $direction 'up' or 'down' + * @param string $strsort The language string used for the alt attribute of this image + * @param bool $return Whether to print directly or return the html string + * @return string|void depending on $return + * + */ +function print_arrow($direction='up', $strsort=null, $return=false) { + // debugging('print_arrow() has been deprecated. Please change your code to use $OUTPUT->arrow().'); + + global $OUTPUT; + + if (!in_array($direction, array('up', 'down', 'right', 'left', 'move'))) { + return null; + } + + $return = null; + + switch ($direction) { + case 'up': + $sortdir = 'asc'; + break; + case 'down': + $sortdir = 'desc'; + break; + case 'move': + $sortdir = 'asc'; + break; + default: + $sortdir = null; + break; + } + + // Prepare language string + $strsort = ''; + if (empty($strsort) && !empty($sortdir)) { + $strsort = get_string('sort' . $sortdir, 'grades'); + } + + $return = '+ * // Option 1: + * $userpic = new user_picture(); + * // Set properties of $userpic + * $OUTPUT->user_picture($userpic); + * + * // Option 2: (shortcut for simple cases) + * // $user has come from the DB and has fields id, picture, imagealt, firstname and lastname + * $OUTPUT->user_picture($user, $COURSE->id); + *+ * + * @param object $userpic Object with at least fields id, picture, imagealt, firstname, lastname + * If any of these are missing, or if a userid is passed, the database is queried. Avoid this + * if at all possible, particularly for reports. It is very bad for performance. + * A user_picture object is a better parameter. + * @param int $courseid courseid Used when constructing the link to the user's profile. Required if $userpic + * is not a user_picture object + * @return string HTML fragment + */ + public function user_picture($userpic, $courseid=null) { + // Instantiate a user_picture object if $user is not already one + if (!($userpic instanceof user_picture)) { + if (empty($courseid)) { + throw new coding_exception('Called $OUTPUT->user_picture with a $user object but no $courseid.'); + } + + $user = $userpic; + $userpic = new user_picture(); + $userpic->user = $user; + $userpic->courseid = $courseid; + } + + $userpic->prepare(); + + $output = $this->image($userpic->image); + + if (!empty($userpic->link) && !empty($userpic->url)) { + $actions = $userpic->get_actions(); + if (!empty($actions)) { + $link = new html_link(); + $link->url = $userpic->url; + $link->text = fullname($userpic->user); + $link->add_action_object($actions[0]); + $output = $this->link_to_popup($link); + } else { + $output = $this->link(prepare_url($userpic->url), $output); + } + } + + return $output; } public function close_window_button($buttontext = null, $reloadopener = false) { @@ -2506,8 +2847,55 @@ class moodle_core_renderer extends moodle_renderer_base { if (!is_a($link, 'moodle_url')) { $link = new moodle_url($link); } - return $this->output_tag('div', array('class' => 'continuebutton'), - print_single_button($link->out(true), $link->params(), get_string('continue'), 'get', '', true)); + $form = new html_form(); + $form->url = $link; + $form->values = $link->params(); + $form->button->label = get_string('continue'); + $form->method = 'get'; + + return $this->output_tag('div', array('class' => 'continuebutton') , $this->button($form)); + } + + /** + * Print a continue button that goes to a particular URL. + * + * @param string|moodle_url $link The url the button goes to. + * @return string the HTML to output. + */ + public function paging_bar($pagingbar) { + $output = ''; + + $pagingbar->prepare(); + + if ($pagingbar->totalcount > $pagingbar->perpage) { + $output .= get_string('page') . ':'; + + if (!empty($pagingbar->previouslink)) { + $output .= ' (' . $this->link($pagingbar->previouslink) . ') '; + } + + if (!empty($pagingbar->firstlink)) { + $output .= ' ' . $this->link($pagingbar->firstlink) . ' ...'; + } + + foreach ($pagingbar->pagelinks as $link) { + if ($link instanceof html_link) { + $output .= ' ' . $this->link($link); + } else { + $output .= " $link"; + } + } + + if (!empty($pagingbar->lastlink)) { + $output .= ' ...' . $this->link($pagingbar->lastlink) . ' '; + } + + if (!empty($pagingbar->nextlink)) { + $output .= ' (' . $this->link($pagingbar->nextlink) . ')'; + } + } + + return $this->output_tag('div', array('class' => 'paging'), $output); } /** @@ -2711,6 +3099,7 @@ class moodle_core_renderer extends moodle_renderer_base { } } +/// COMPONENTS /** * Base class for classes representing HTML elements, like moodle_select_menu. @@ -2730,6 +3119,20 @@ class moodle_html_component { * @var array class names to add to this HTML element. */ public $classes = array(); + /** + * @var string $title The title attributes applicable to any XHTML element + */ + public $title = ''; + /** + * An optional array of component_action objects handling the action part of this component. + * @var array $actions + */ + protected $actions = array(); + /** + * This array of generated ids is kept static to avoid id collisions + * @var array $generated_ids + */ + public static $generated_ids = array(); /** * Ensure some class names are an array. @@ -2807,6 +3210,59 @@ class moodle_html_component { } } + /** + * Adds a JS action to this component. + * Note: the JS function you write must have only two arguments: (string)event and (object|array)args + * If you want to add an instantiated component_action (or one of its subclasses), use $component->add_action_object($action) + * + * @param string $event a DOM event (click, mouseover etc.) + * @param string $jsfunction The name of the JS function to call + * @param array $jsfunctionargs An optional array of JS arguments to pass to the function + * @return void + */ + public function add_action($event, $jsfunction, $jsfunctionargs=array()) { + while (empty($this->id) || in_array($this->id, moodle_html_component::$generated_ids)) { + $this->generate_id(); + } + $this->actions[] = new component_action($event, $jsfunction, $jsfunctionargs); + } + + /** + * Adds an instantiated component_action to this component. + * Note: the JS function you write must have only two arguments: (string)event and (object|array)args + * + * @param component_action $action An instantiated component_action or one of its subclasses + * @return void + */ + public function add_action_object($action) { + if (!($action instanceof component_action)) { + throw new coding_exception('moodle_html_component::add_action_object($action) only takes an instance of component_action.'); + } + + while (empty($this->id) && !in_array($this->id, moodle_html_component::$generated_ids)) { + $this->generate_id(); + } + $this->actions[] = $action; + } + + /** + * Internal method for generating a unique ID for the purpose of event handlers. + * @return void; + */ + protected function generate_id() { + $this->id = get_class($this) . '-' . substr(sha1(microtime() * rand(0, 500)), 0, 5); + if (!in_array($this->id, moodle_html_component::$generated_ids)) { + moodle_html_component::$generated_ids[] = $this->id; + } + } + + /** + * Returns the array of component_actions. + * @return array Component actions + */ + public function get_actions() { + return $this->actions; + } } @@ -2815,6 +3271,10 @@ class moodle_html_component { * will be printed by {@link moodle_core_renderer::select_menu()}. (Or by an overridden * version of that method in a subclass.) * + * This component can also hold enough metadata to be used as a popup form. It just + * needs a bit more setting up than for a simple menu. See the shortcut methods for + * developer-friendly usage. + * * All the fields that are not set by the constructor have sensible defaults, so * you only need to set the properties where you want non-default behaviour. * @@ -3229,6 +3689,795 @@ class html_table extends moodle_html_component { } } +/** + * Component representing a XHTML link. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class html_link extends moodle_html_component { + /** + * URL can be simple text or a moodle_url object + * @var mixed $url + */ + public $url; + + /** + * @var string $text The text that will appear between the link tags + */ + public $text; + + /** + * @see lib/moodle_html_component#prepare() + * @return void + */ + public function prepare() { + // We can't accept an empty text value + if (empty($this->text)) { + throw new coding_exception('A html_link must have a descriptive text value!'); + } + + parent::prepare(); + } +} + +/** + * Component representing a help icon. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class help_icon extends moodle_html_component { + /** + * @var html_link $link A html_link object that will hold the URL info + */ + public $link; + /** + * @var string $text A descriptive text + */ + public $text; + /** + * @var string $page The keyword that defines a help page + */ + public $page; + /** + * @var string $module Which module is the page defined in + */ + public $module = 'moodle'; + /** + * @var boolean $linktext Whether or not to show text next to the icon + */ + public $linktext = false; + /** + * @var mixed $image The help icon. Can be set to true (will use default help icon), + * false (will not use any icon), the URL to an image, or a full + * html_image object. + */ + public $image; + + /** + * Constructor: sets up the other components in case they are needed + * @return void + */ + public function __construct() { + $this->link = new html_link(); + $this->image = new html_image(); + } + + /** + * @see lib/moodle_html_component#prepare() + * @return void + */ + public function prepare() { + global $COURSE, $OUTPUT; + + if (empty($this->page)) { + throw new coding_exception('A help_icon object requires a $page parameter'); + } + + if (empty($this->text)) { + throw new coding_exception('A help_icon object requires a $text parameter'); + } + + $this->link->text = $this->text; + + // fix for MDL-7734 + $this->link->url = new moodle_url('/help.php', array('module' => $this->module, 'file' => $this->page .'.html')); + + // fix for MDL-7734 + if (!empty($COURSE->lang)) { + $this->link->url->param('forcelang', $COURSE->lang); + } + + // Catch references to the old text.html and emoticons.html help files that + // were renamed in MDL-13233. + if (in_array($this->page, array('text', 'emoticons', 'richtext'))) { + $oldname = $this->page; + $this->page .= '2'; + debugging("You are referring to the old help file '$oldname'. " . + "This was renamed to '$this->page' because of MDL-13233. " . + "Please update your code.", DEBUG_DEVELOPER); + } + + if ($this->module == '') { + $this->module = 'moodle'; + } + + // Warn users about new window for Accessibility + $this->title = get_string('helpprefix2', '', trim($this->text, ". \t")) .' ('.get_string('newwindow').')'; + + // Prepare image and linktext + if ($this->image && !($this->image instanceof html_image)) { + $image = fullclone($this->image); + $this->image = new html_image(); + + if ($image instanceof moodle_url) { + $this->image->src = $image->out(); + } else if ($image === true) { + $this->image->src = $OUTPUT->old_icon_url('help'); + } else if (is_string($image)) { + $this->image->src = $image; + } + $this->image->alt = $this->text; + + if ($this->linktext) { + $this->image->alt = get_string('helpwiththis'); + } else { + $this->image->alt = $this->title; + } + $this->image->add_class('iconhelp'); + } else if (empty($this->image->src)) { + $this->image->src = $OUTPUT->old_icon_url('help'); + } + + parent::prepare(); + } +} + + +/** + * Component representing a XHTML button (input of type 'button'). + * The renderer will either output it as a button with an onclick event, + * or as a form with hidden inputs. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class html_button extends moodle_html_component { + /** + * @var string $label + */ + public $label; + + /** + * @var boolean $disabled Whether or not this button is disabled + */ + public $disabled = false; + + /** + * @see lib/moodle_html_component#prepare() + * @return void + */ + public function prepare() { + $this->add_class('singlebutton'); + + if (empty($this->label)) { + throw new coding_exception('A html_button must have a label value!'); + } + + if ($this->disabled) { + $this->disabled = 'disabled'; + } + + parent::prepare(); + } +} + +/** + * Component representing an icon linking to a Moodle page. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class action_icon extends moodle_html_component { + /** + * @var string $linktext Optional text to display next to the icon + */ + public $linktext; + /** + * @var html_image $image The icon + */ + public $image; + /** + * @var html_link $link The link + */ + public $link; + + /** + * Constructor: sets up the other components in case they are needed + * @return void + */ + public function __construct() { + $this->image = new html_image(); + $this->link = new html_link(); + } + + /** + * @see lib/moodle_html_component#prepare() + * @return void + */ + public function prepare() { + $this->image->add_class('action-icon'); + + parent::prepare(); + + if (empty($this->image->src)) { + throw new coding_exception('action_icon->image->src must not be empty'); + } + + if (empty($this->image->alt) && !empty($this->linktext)) { + $this->image->alt = $this->linktext; + } else if (empty($this->image->alt)) { + debugging('action_icon->image->alt should not be empty.', DEBUG_DEVELOPER); + } + } +} + +/** + * Component representing an image. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class html_image extends moodle_html_component { + /** + * @var string $alt A descriptive text + */ + public $alt = HTML_ATTR_EMPTY; + /** + * @var string $src The path to the image being used + */ + public $src; + + /** + * @see lib/moodle_html_component#prepare() + * @return void + */ + public function prepare() { + $this->add_class('image'); + parent::prepare(); + } +} + +/** + * Component representing a user picture. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class user_picture extends moodle_html_component { + /** + * @var mixed $user A userid or a user object with at least fields id, picture, imagealrt, firstname and lastname set. + */ + public $user; + /** + * @var int $courseid The course id. Used when constructing the link to the user's profile. + */ + public $courseid; + /** + * @var html_image $image A custom image used as the user picture. + */ + public $image; + /** + * @var mixed $url False: picture not enclosed in a link. True: default link. moodle_url: custom link. + */ + public $url; + /** + * @var int $size Size in pixels. Special values are (true/1 = 100px) and (false/0 = 35px) for backward compatibility + */ + public $size; + /** + * @var boolean $alttext add non-blank alt-text to the image. (Default true, set to false for purely + */ + public $alttext = true; + + /** + * Constructor: sets up the other components in case they are needed + * @return void + */ + public function __construct() { + $this->image = new html_image(); + } + + /** + * @see lib/moodle_html_component#prepare() + * @return void + */ + public function prepare() { + global $CFG, $DB, $OUTPUT; + + if (empty($this->user)) { + throw new coding_exception('A user_picture object must have a $user object before being rendered.'); + } + + if (empty($this->courseid)) { + throw new coding_exception('A user_picture object must have a courseid value before being rendered.'); + } + + if (!($this->image instanceof html_image)) { + debugging('user_picture::image must be an instance of html_image', DEBUG_DEVELOPER); + } + + $needrec = false; + // only touch the DB if we are missing data... + if (is_object($this->user)) { + // Note - both picture and imagealt _can_ be empty + // what we are trying to see here is if they have been fetched + // from the DB. We should use isset() _except_ that some installs + // have those fields as nullable, and isset() will return false + // on null. The only safe thing is to ask array_key_exists() + // which works on objects. property_exists() isn't quite + // what we want here... + if (! (array_key_exists('picture', $this->user) + && ($this->alttext && array_key_exists('imagealt', $this->user) + || (isset($this->user->firstname) && isset($this->user->lastname)))) ) { + $needrec = true; + $this->user = $this->user->id; + } + } else { + if ($this->alttext) { + // we need firstname, lastname, imagealt, can't escape... + $needrec = true; + } else { + $userobj = new StdClass; // fake it to save DB traffic + $userobj->id = $user; + $userobj->picture = $picture; + $this->user = clone($userobj); + unset($userobj); + } + } + if ($needrec) { + $this->user = $DB->get_record('user', array('id' => $this->user), 'id,firstname,lastname,imagealt'); + } + + if (!empty($this->link) && empty($this->url)) { + $this->url = new moodle_url('/user/view.php', array('id' => $this->user->id, 'course' => $this->courseid)); + } + + if (empty($this->size)) { + $file = 'f2'; + $this->size = 35; + } else if ($this->size === true or $this->size == 1) { + $file = 'f1'; + $this->size = 100; + } else if ($this->size >= 50) { + $file = 'f1'; + } else { + $file = 'f2'; + } + + $this->add_class('userpicture'); + + if (empty($this->image->src)) { + $this->image->src = $this->user->picture; + } + + if (!empty($this->image->src)) { + require_once($CFG->libdir.'/filelib.php'); + $this->image->src = new moodle_url(get_file_url($this->user->id.'/'.$file.'.jpg', null, 'user')); + } else { // Print default user pictures (use theme version if available) + $this->add_class('defaultuserpic'); + $this->image->src = $OUTPUT->old_icon_url('u/' . $file); + } + + if ($this->alttext) { + if (!empty($this->user->imagealt)) { + $this->image->alt = $this->user->imagealt; + } else { + $this->image->alt = get_string('pictureof','',fullname($this->user)); + } + } + + parent::prepare(); + } +} + +/** + * Component representing a textarea. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class html_textarea extends moodle_html_component { + /** + * @param string $name Name to use for the textarea element. + */ + public $name; + /** + * @param string $value Initial content to display in the textarea. + */ + public $value; + /** + * @param int $rows Number of rows to display (minimum of 10 when $height is non-null) + */ + public $rows; + /** + * @param int $cols Number of columns to display (minimum of 65 when $width is non-null) + */ + public $cols; + /** + * @param bool $usehtmleditor Enables the use of the htmleditor for this field. + */ + public $usehtmleditor; + + /** + * @see lib/moodle_html_component#prepare() + * @return void + */ + public function prepare() { + $this->add_class('form-textarea'); + + if (empty($this->id)) { + $this->id = "edit-$this->name"; + } + + if ($this->usehtmleditor) { + editors_head_setup(); + $editor = get_preferred_texteditor(FORMAT_HTML); + $editor->use_editor($this->id, array('legacy'=>true)); + $this->value = htmlspecialchars($value); + } + + parent::prepare(); + } +} + +/** + * Component representing a simple form wrapper. Its purpose is mainly to enclose + * a submit input with the appropriate action and hidden inputs. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class html_form extends moodle_html_component { + /** + * @var string $method post or get + */ + public $method = 'post'; + /** + * If a string is given, it will be converted to a moodle_url during prepare() + * @var mixed $url A moodle_url including params or a string + */ + public $url; + /** + * @var array $params Optional array of parameters. Ignored if $url instanceof moodle_url + */ + public $params = array(); + /** + * @var boolean $showbutton If true, the submit button will always be shown even if JavaScript is available + */ + public $showbutton = false; + /** + * @var string $targetwindow The name of the target page to open the linked page in. + */ + public $targetwindow = 'self'; + /** + * @var html_button $button A submit button + */ + public $button; + + /** + * Constructor: sets up the other components in case they are needed + * @return void + */ + public function __construct() { + static $go; + $this->button = new html_button(); + if (!isset($go)) { + $go = get_string('go'); + $this->button->label = $go; + } + } + + /** + * @see lib/moodle_html_component#prepare() + * @return void + */ + public function prepare() { + + if (empty($this->url)) { + throw new coding_exception('A html_form must have a $url value (string or moodle_url).'); + } + + if (!($this->url instanceof moodle_url)) { + $this->url = new moodle_url($this->url, $this->params); + } + + if ($this->method == 'post') { + $this->url->param('sesskey', sesskey()); + } + + parent::prepare(); + } +} + +/** + * Component representing a paging bar. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class moodle_paging_bar extends moodle_html_component { + /** + * @var int $maxdisplay The maximum number of pagelinks to display + */ + public $maxdisplay = 18; + /** + * @var int $totalcount post or get + */ + public $totalcount; + /** + * @var int $page The page you are currently viewing + */ + public $page; + /** + * @var int $perpage The number of entries that should be shown per page + */ + public $perpage; + /** + * @var string $baseurl If this is a string then it is the url which will be appended with $pagevar, an equals sign and the page number. + * If this is a moodle_url object then the pagevar param will be replaced by the page no, for each page. + */ + public $baseurl; + /** + * @var string $pagevar This is the variable name that you use for the page number in your code (ie. 'tablepage', 'blogpage', etc) + */ + public $pagevar = 'page'; + /** + * @var bool $nocurr do not display the current page as a link + */ + public $nocurr; + /** + * @var html_link $previouslink A HTML link representing the "previous" page + */ + public $previouslink = null; + /** + * @var html_link $nextlink A HTML link representing the "next" page + */ + public $nextlink = null; + /** + * @var html_link $firstlink A HTML link representing the first page + */ + public $firstlink = null; + /** + * @var html_link $lastlink A HTML link representing the last page + */ + public $lastlink = null; + /** + * @var array $pagelinks An array of html_links. One of them is just a string: the current page + */ + public $pagelinks = array(); + + /** + * @see lib/moodle_html_component#prepare() + * @return void + */ + public function prepare() { + if (!($this->baseurl instanceof moodle_url)) { + $this->baseurl = new moodle_url($this->baseurl); + } + + if ($this->totalcount > $this->perpage) { + $pagenum = $this->page - 1; + + if ($this->page > 0) { + $this->previouslink = new html_link(); + $this->previouslink->add_class('previous'); + $this->previouslink->url = $this->baseurl->out(false, array($this->pagevar => $pagenum)); + $this->previouslink->text = get_string('previous'); + } + + if ($this->perpage > 0) { + $lastpage = ceil($this->totalcount / $this->perpage); + } else { + $lastpage = 1; + } + + if ($this->page > 15) { + $startpage = $this->page - 10; + + $this->firstlink = new html_link(); + $this->firstlink->url = $this->baseurl->out(false, array($this->pagevar => 0)); + $this->firstlink->text = 1; + $this->firstlink->add_class('first'); + } else { + $startpage = 0; + } + + $currpage = $startpage; + $displaycount = $displaypage = 0; + + while ($displaycount < $this->maxdisplay and $currpage < $lastpage) { + $displaypage = $currpage + 1; + + if ($this->page == $currpage && empty($this->nocurr)) { + $this->pagelinks[] = $displaypage; + } else { + $pagelink = new html_link(); + $pagelink->url = $this->baseurl->out(false, array($this->pagevar => $currpage)); + $pagelink->text = $displaypage; + $this->pagelinks[] = $pagelink; + } + + $displaycount++; + $currpage++; + } + + if ($currpage < $lastpage) { + $lastpageactual = $lastpage - 1; + $this->lastlink = new html_link(); + $this->lastlink->url = $this->baseurl->out(false, array($this->pagevar => $lastpageactual)); + $this->lastlink->text = $lastpage; + $this->lastlink->add_class('last'); + } + + $pagenum = $this->page + 1; + + if ($pagenum != $displaypage) { + $this->nextlink = new html_link(); + $this->nextlink->url = $this->baseurl->out(false, array($this->pagevar => $pagenum)); + $this->nextlink->text = get_string('next'); + $this->nextlink->add_class('next'); + } + } + } + +} + +/// ACTIONS + +/** + * Helper class used by other components that involve an action on the page (URL or JS). + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class component_action { + + /** + * The DOM event that will trigger this action when caught + * @var string $event DOM event + */ + public $event; + + /** + * The JS function you create must have two arguments: + * 1. The event object + * 2. An object/array of arguments ($jsfunctionargs) + * @var string $jsfunction A function name to call when the button is clicked + */ + public $jsfunction = false; + + /** + * @var array $jsfunctionargs An array of arguments to pass to the JS function + */ + public $jsfunctionargs = array(); + + /** + * Constructor + * @param string $event DOM event + * @param moodle_url $url A moodle_url object, required if no jsfunction is given + * @param string $method 'post' or 'get' + * @param string $jsfunction An optional JS function. Required if jsfunctionargs is given + * @param array $jsfunctionargs An array of arguments to pass to the jsfunction + * @return void + */ + public function __construct($event, $jsfunction, $jsfunctionargs=array()) { + $this->event = $event; + + $this->jsfunction = $jsfunction; + $this->jsfunctionargs = $jsfunctionargs; + + if (!empty($this->jsfunctionargs)) { + if (empty($this->jsfunction)) { + throw new coding_exception('The component_action object needs a jsfunction value to pass the jsfunctionargs to.'); + } + } + } +} + +/** + * Component action for a popup window. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class popup_action extends component_action { + /** + * @var array $params An array of parameters that will be passed to the openpopup JS function + */ + public $params = array( + 'height' => 400, + 'width' => 500, + 'top' => 0, + 'left' => 0, + 'menubar' => false, + 'location' => false, + 'scrollbars' => true, + 'resizable' => true, + 'toolbar' => true, + 'status' => true, + 'directories' => false, + 'fullscreen' => false, + 'dependent' => true); + + /** + * Constructor + * @param string $event DOM event + * @param moodle_url $url A moodle_url object, required if no jsfunction is given + * @param string $method 'post' or 'get' + * @param array $params An array of popup parameters + * @return void + */ + public function __construct($event, $url, $name='popup', $params=array()) { + global $CFG; + $this->name = $name; + + $url = new moodle_url($url); + + if ($this->name) { + $_name = $this->name; + if (($_name = preg_replace("/\s/", '_', $_name)) != $this->name) { + throw new coding_exception('The $name of a popup window shouldn\'t contain spaces - string modified. '. $this->name .' changed to '. $_name); + $this->name = $_name; + } + } else { + $this->name = 'popup'; + } + + foreach ($this->params as $var => $val) { + if (array_key_exists($var, $params)) { + $this->params[$var] = $params[$var]; + } + } + parent::__construct($event, 'openpopup', array('url' => $url->out(false, array(), false), 'name' => $name, 'options' => $this->get_js_options($params))); + } + + /** + * Returns a string of concatenated option->value pairs used by JS to call the popup window, + * based on this object's variables + * + * @return string String of option->value pairs for JS popup function. + */ + public function get_js_options() { + $jsoptions = ''; + + foreach ($this->params as $var => $val) { + if (is_string($val) || is_int($val)) { + $jsoptions .= "$var=$val,"; + } elseif (is_bool($val)) { + $jsoptions .= ($val) ? "$var," : "$var=0,"; + } + } + + $jsoptions = substr($jsoptions, 0, strlen($jsoptions) - 1); + + return $jsoptions; + } +} + +/// RENDERERS /** * A renderer that generates output for command-line scripts. @@ -3423,3 +4672,23 @@ function output_css_for_css_edit($files, $toreplace) { echo "/* @end */\n\n"; } } + +/** + * Given a moodle_html_component with height and/or width set, translates them + * to appropriate CSS rules. + * + * @param moodle_html_component $component + * @return string CSS rules + */ +function prepare_legacy_width_and_height($component) { + $output = ''; + if (!empty($component->height)) { + debugging('Explicit height given to moodle_html_component leads to inline css. Use a proper CSS class instead.', DEBUG_DEVELOPER); + $output = "height: {$component->height}px;"; + } + if (!empty($component->width)) { + debugging('Explicit width given to moodle_html_component leads to inline css. Use a proper CSS class instead.', DEBUG_DEVELOPER); + $output .= "width: {$component->width}px;"; + } + return $output; +} diff --git a/lib/simpletest/testdeprecatedlib.php b/lib/simpletest/testdeprecatedlib.php new file mode 100644 index 00000000000..76257caf76d --- /dev/null +++ b/lib/simpletest/testdeprecatedlib.php @@ -0,0 +1,74 @@ +. + + +/** + * Unit tests for ../deprecatedlib.php. + * + * @package moodlecore + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later (5) + */ + +if (!defined('MOODLE_INTERNAL')) { + die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page +} +require_once($CFG->libdir . '/deprecatedlib.php'); + +class outputlib_methods_test extends UnitTestCase { + public function test_print_single_button() { + global $PAGE, $CFG; + + // Basic params, absolute URL + $link = 'http://www.test.com/index.php'; + $options = array('param1' => 'value1'); + $label = 'OK'; + $method = 'get'; + $return = true; + $tooltip = ''; + $disabled = false; + $jsconfirmmessage = ''; + $formid = ''; + + $html = print_single_button($link, $options, $label, $method, '', $return, $tooltip, $disabled, $jsconfirmmessage, $formid); + $this->assert(new ContainsTagWithAttributes('form', array('method' => $method, 'action' => $link)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'param1', 'value' => 'value1')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => 'OK')), $html); + + // URL with & params + $newlink = $link . '?param1=value1¶m2=value2'; + $html = print_single_button($newlink, $options, $label, $method, '', $return, $tooltip, $disabled, $jsconfirmmessage, $formid); + $this->assert(new ContainsTagWithAttributes('form', array('method' => $method, 'action' => $link)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'param1', 'value' => 'value1')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => 'OK')), $html); + + // URL with & params + $newlink = $link . '?param1=value1¶m2=value2'; + $html = print_single_button($newlink, $options, $label, $method, '', $return, $tooltip, $disabled, $jsconfirmmessage, $formid); + $this->assert(new ContainsTagWithAttributes('form', array('method' => $method, 'action' => $link)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'param1', 'value' => 'value1')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => 'OK')), $html); + + // relative URL with & params + $newlink = 'index.php?param1=value1¶m2=value2'; + $PAGE->set_url('index.php'); + $html = print_single_button($newlink, $options, $label, $method, '', $return, $tooltip, $disabled, $jsconfirmmessage, $formid); + $this->assert(new ContainsTagWithAttributes('form', array('method' => $method, 'action' => $CFG->wwwroot . '/index.php')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'param1', 'value' => 'value1')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => 'OK')), $html); + } +} diff --git a/lib/simpletest/testoutputlib.php b/lib/simpletest/testoutputlib.php index 28ff563ba73..3e659fc548e 100644 --- a/lib/simpletest/testoutputlib.php +++ b/lib/simpletest/testoutputlib.php @@ -578,7 +578,7 @@ class template_renderer_factory_test extends UnitTestCase { $this->make_theme_template_dir('mytheme'); $this->make_theme_template_dir('parenttheme'); $this->make_theme_template_dir('standardtemplate'); - + // Exercise SUT. $factory = new testable_template_renderer_factory($theme, $this->page); @@ -597,7 +597,7 @@ class template_renderer_factory_test extends UnitTestCase { $theme->parent = 'parenttheme'; $this->make_theme_template_dir('mytheme'); $this->make_theme_template_dir('standardtemplate'); - + // Exercise SUT. $factory = new testable_template_renderer_factory($theme, $this->page); $subfactory = new testable_template_renderer_factory($theme, $this->page, 'subtype'); @@ -905,4 +905,252 @@ class moodle_core_renderer_test extends UnitTestCase { $html = $this->renderer->error_text(''); $this->assertEqual('', $html); } + + public function test_link_to_popup_empty_link() { + // Empty link object: link MUST have a text value + $link = new html_link(); + $popupaction = new popup_action('click', 'http://test.com', 'my_popup'); + $link->add_action_object($popupaction); + $this->expectException(); + $html = $this->renderer->link_to_popup($link); + } + + public function test_link_to_popup() { + $link = new html_link(); + $link->text = 'Click here'; + $link->url = 'http://test.com'; + $link->title = 'Popup window'; + $popupaction = new popup_action('click', 'http://test.com', 'my_popup'); + $link->add_action_object($popupaction); + + $html = $this->renderer->link_to_popup($link); + $expectedattributes = array('title' => 'Popup window', 'href' => 'http://test.com'); + $this->assert(new ContainsTagWithAttributes('a', $expectedattributes), $html); + $this->assert(new ContainsTagWithContents('a', 'Click here'), $html); + + // Try a different url for the link than for the popup + $link->url = 'http://otheraddress.com'; + $html = $this->renderer->link_to_popup($link); + + $this->assert(new ContainsTagWithAttribute('a', 'title', 'Popup window'), $html); + $this->assert(new ContainsTagWithAttribute('a', 'href', 'http://otheraddress.com'), $html); + $this->assert(new ContainsTagWithContents('a', 'Click here'), $html); + + // Give it a moodle_url object instead of a string + $link->url = new moodle_url('http://otheraddress.com'); + $html = $this->renderer->link_to_popup($link); + $this->assert(new ContainsTagWithAttribute('a', 'title', 'Popup window'), $html); + $this->assert(new ContainsTagWithAttribute('a', 'href', 'http://otheraddress.com'), $html); + $this->assert(new ContainsTagWithContents('a', 'Click here'), $html); + + } + + public function test_button() { + global $CFG; + $originalform = new html_form(); + $originalform->button->label = 'Click Here'; + $originalform->url = '/index.php'; + + $form = clone($originalform); + + $html = $this->renderer->button($form); + $this->assert(new ContainsTagWithAttribute('div', 'class', 'singlebutton'), $html); + $this->assert(new ContainsTagWithAttributes('form', array('method' => 'post', 'action' => $CFG->wwwroot . '/index.php')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())), $html); + $this->assert(new ContainsTagWithAttributes('input', array('value' => 'Click Here', 'type' => 'submit')), $html); + + $form = clone($originalform); + $form->button->confirmmessage = 'Are you sure?'; + + $html = $this->renderer->button($form); + $this->assert(new ContainsTagWithAttribute('div', 'class', 'singlebutton'), $html); + $this->assert(new ContainsTagWithAttributes('form', array('method' => 'post', 'action' => $CFG->wwwroot . '/index.php')), $html); + $this->assert(new ContainsTagWithAttribute('input', 'type', 'submit'), $html); + + $form = clone($originalform); + $form->url = new moodle_url($form->url, array('var1' => 'value1', 'var2' => 'value2')); + $html = $this->renderer->button($form); + $this->assert(new ContainsTagWithAttributes('input', array('name' => 'var1', 'type' => 'hidden', 'value' => 'value1')), $html); + + } + + public function test_link() { + $link = new html_link(); + $link->url = 'http://test.com'; + $link->text = 'Resource 1'; + + $html = $this->renderer->link($link); + $this->assert(new ContainsTagWithAttribute('a', 'href', 'http://test.com'), $html); + $this->assert(new ContainsTagWithContents('a', 'Resource 1'), $html); + + // Add a title + $link->title = 'Link to resource 1'; + $html = $this->renderer->link($link); + $this->assert(new ContainsTagWithAttributes('a', array('title' => 'Link to resource 1', 'href' => 'http://test.com')), $html); + $this->assert(new ContainsTagWithContents('a', 'Resource 1'), $html); + + // Use a moodle_url object instead of string + $link->url = new moodle_url($link->url); + $html = $this->renderer->link($link); + $this->assert(new ContainsTagWithAttributes('a', array('title' => 'Link to resource 1', 'href' => 'http://test.com')), $html); + $this->assert(new ContainsTagWithContents('a', 'Resource 1'), $html); + + // Add a few classes to the link object + $link->add_classes('cool blue'); + $html = $this->renderer->link($link); + $this->assert(new ContainsTagWithAttributes('a', array('title' => 'Link to resource 1', 'class' => 'link cool blue', 'href' => 'http://test.com')), $html); + $this->assert(new ContainsTagWithContents('a', 'Resource 1'), $html); + + // Simple use of link() without a html_link object + $html = $this->renderer->link($link->url->out(), $link->text); + $expected_html = 'Resource 1'; + $this->assert(new ContainsTagWithAttribute('a', 'href', 'http://test.com'), $html); + $this->assert(new ContainsTagWithContents('a', 'Resource 1'), $html); + + // Missing second param when first is a string: exception + $this->expectException(); + $html = $this->renderer->link($link->url->out()); + } + + /** + * NOTE: consider the degree of detail in which we test HTML output, because + * the unit tests may be run under a different theme, with different HTML + * renderers. Maybe we should limit unit tests to standardwhite. + */ + public function test_confirm() { + // Basic test with string URLs + $continueurl = 'http://www.test.com/index.php?continue=1'; + $cancelurl = 'http://www.test.com/index.php?cancel=1'; + $message = 'Are you sure?'; + + $html = $this->renderer->confirm($message, $continueurl, $cancelurl); + $this->assert(new ContainsTagWithAttributes('div', array('id' => 'notice', 'class' => 'box generalbox')), $html); + $this->assert(new ContainsTagWithContents('p', $message), $html); + $this->assert(new ContainsTagWithAttribute('div', 'class', 'buttons'), $html); + $this->assert(new ContainsTagWithAttribute('div', 'class', 'singlebutton'), $html); + $this->assert(new ContainsTagWithAttributes('form', array('method' => 'post', 'action' => 'http://www.test.com/index.php')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'continue', 'value' => 1)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => get_string('yes'), 'class' => 'singlebutton')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'cancel', 'value' => 1)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => get_string('no'), 'class' => 'singlebutton')), $html); + + // Use html_forms with default values, should produce exactly the same output as above + $formcontinue = new html_form(); + $formcancel = new html_form(); + $formcontinue->url = new moodle_url($continueurl); + $formcancel->url = new moodle_url($cancelurl); + $html = $this->renderer->confirm($message, $formcontinue, $formcancel); + $this->assert(new ContainsTagWithAttributes('div', array('id' => 'notice', 'class' => 'box generalbox')), $html); + $this->assert(new ContainsTagWithContents('p', $message), $html); + $this->assert(new ContainsTagWithAttribute('div', 'class', 'buttons'), $html); + $this->assert(new ContainsTagWithAttribute('div', 'class', 'singlebutton'), $html); + $this->assert(new ContainsTagWithAttributes('form', array('method' => 'post', 'action' => 'http://www.test.com/index.php')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'continue', 'value' => 1)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => get_string('yes'), 'class' => 'singlebutton')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'cancel', 'value' => 1)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => get_string('no'), 'class' => 'singlebutton')), $html); + + // Give the buttons some different labels + $formcontinue = new html_form(); + $formcancel = new html_form(); + $formcontinue->url = new moodle_url($continueurl); + $formcancel->url = new moodle_url($cancelurl); + $formcontinue->button->label = 'Continue anyway'; + $formcancel->button->label = 'Wow OK, I get it, backing out!'; + $html = $this->renderer->confirm($message, $formcontinue, $formcancel); + $this->assert(new ContainsTagWithAttributes('form', array('method' => 'post', 'action' => 'http://www.test.com/index.php')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'continue', 'value' => 1)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => $formcontinue->button->label, 'class' => 'singlebutton')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'cancel', 'value' => 1)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => $formcancel->button->label, 'class' => 'singlebutton')), $html); + + // Change the method and add extra variables + $formcontinue = new html_form(); + $formcancel = new html_form(); + $formcontinue->url = new moodle_url($continueurl, array('var1' => 'val1', 'var2' => 'val2')); + $formcancel->url = new moodle_url($cancelurl, array('var3' => 'val3', 'var4' => 'val4')); + $html = $this->renderer->confirm($message, $formcontinue, $formcancel); + $this->assert(new ContainsTagWithAttributes('form', array('method' => 'post', 'action' => 'http://www.test.com/index.php')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'continue', 'value' => 1)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'var1', 'value' => 'val1')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'var2', 'value' => 'val2')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => get_string('yes'), 'class' => 'singlebutton')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'cancel', 'value' => 1)), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'submit', 'value' => get_string('no'), 'class' => 'singlebutton')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'var3', 'value' => 'val3')), $html); + $this->assert(new ContainsTagWithAttributes('input', array('type' => 'hidden', 'name' => 'var4', 'value' => 'val4')), $html); + + } + + public function test_spacer() { + global $CFG; + + $spacer = new html_image(); + + $html = $this->renderer->spacer($spacer); + $this->assert(new ContainsTagWithAttributes('img', array('class' => 'image spacer', + 'src' => $CFG->wwwroot . '/pix/spacer.gif', + 'alt' => '' + )), $html); + $spacer = new html_image(); + $spacer->src = $this->renderer->old_icon_url('myspacer'); + $spacer->alt = 'sometext'; + $spacer->add_class('my'); + + $html = $this->renderer->spacer($spacer); + + $this->assert(new ContainsTagWithAttributes('img', array( + 'class' => 'my image spacer', + 'src' => $this->renderer->old_icon_url('myspacer'), + 'alt' => 'sometext')), $html); + + } + + public function test_paging_bar() { + global $CFG, $OUTPUT; + + $totalcount = 5; + $perpage = 4; + $page = 1; + $baseurl = new moodle_url($CFG->wwwroot.'/index.php'); + $pagevar = 'mypage'; + + $pagingbar = new moodle_paging_bar(); + $pagingbar->totalcount = $totalcount; + $pagingbar->page = $page; + $pagingbar->perpage = $perpage; + $pagingbar->baseurl = $baseurl; + $pagingbar->pagevar = $pagevar; + $pagingbar->nocurr = true; + + $originalbar = clone($pagingbar); + + $html = $OUTPUT->paging_bar($pagingbar); + + $this->assert(new ContainsTagWithAttribute('div', 'class', 'paging'), $html); + $this->assert(new ContainsTagWithAttributes('a', array('class' => 'previous', 'href' => $baseurl->out().'?mypage=0')), $html); + // One of the links to the previous page must not have the 'previous' class + $this->assert(new ContainsTagWithAttributes('a', array('href' => $baseurl->out().'?mypage=0'), array('class' => 'previous')), $html); + // The link to the current page must not have the 'next' class: it's the last page + $this->assert(new ContainsTagWithAttributes('a', array('href' => $baseurl->out().'?mypage=1'), array('class' => 'next')), $html); + + $pagingbar = clone($originalbar); // clone the original bar before each output and set of assertions + $pagingbar->nocurr = false; + $html = $OUTPUT->paging_bar($pagingbar); + $this->assert(new ContainsTagWithAttribute('div', 'class', 'paging'), $html); + $this->assert(new ContainsTagWithAttributes('a', array('href' => $baseurl->out().'?mypage=0'), array('class' => 'previous')), $html); + $this->assert(new ContainsTagWithAttributes('a', array('class' => 'previous', 'href' => $baseurl->out().'?mypage=0')), $html); + $expectation = new ContainsTagWithAttributes('a', array('href' => $baseurl->out().'?mypage=1'), array('class' => 'next')); + $this->assertFalse($expectation->test($html)); + + // TODO test with more different parameters + } } diff --git a/lib/simpletest/testweblib.php b/lib/simpletest/testweblib.php index d75a943bb8a..24c41a8faf9 100644 --- a/lib/simpletest/testweblib.php +++ b/lib/simpletest/testweblib.php @@ -70,7 +70,7 @@ class web_test extends UnitTestCase { $this->assertEqual(highlight('good', 'This is goodness'), 'This is goodness'); } - function test_replace_ampersands() { + function test_replace_ampersands() { $this->assertEqual(replace_ampersands_not_followed_by_entity("This & that "), "This & that "); $this->assertEqual(replace_ampersands_not_followed_by_entity("This   that "), "This   that "); } @@ -92,10 +92,29 @@ class web_test extends UnitTestCase { $string = "visit http://www.moodle.org"; convert_urls_into_links($string); $this->assertEqual($string, 'visit http://www.moodle.org'); - + $string = "visit www.moodle.org"; convert_urls_into_links($string); $this->assertEqual($string, 'visit www.moodle.org'); } + + function test_prepare_url() { + global $CFG, $PAGE; + $fullexternalurl = 'http://www.externalsite.com/somepage.php'; + $fullmoodleurl = $CFG->wwwroot . '/mod/forum/view.php?id=5'; + $relativeurl1 = 'edit.php'; + $relativeurl2 = '/edit.php'; + + $this->assertEqual($fullmoodleurl, prepare_url($fullmoodleurl)); + $this->assertEqual($fullexternalurl, prepare_url($fullexternalurl)); + $this->assertEqual("$CFG->wwwroot/admin/report/unittest/$relativeurl1", prepare_url($relativeurl1)); + $this->assertEqual("$CFG->wwwroot$relativeurl2", prepare_url($relativeurl2)); + + // Use moodle_url object + $this->assertEqual($fullmoodleurl, prepare_url(new moodle_url('/mod/forum/view.php', array('id' => 5)))); + $this->assertEqual($fullexternalurl, prepare_url(new moodle_url($fullexternalurl))); + $this->assertEqual("$CFG->wwwroot/admin/report/unittest/$relativeurl1", prepare_url(new moodle_url($relativeurl1))); + $this->assertEqual("$CFG->wwwroot$relativeurl2", prepare_url(new moodle_url($relativeurl2))); + } } ?> diff --git a/lib/simpletestlib.php b/lib/simpletestlib.php index adefa18bf95..ae085d00fc5 100644 --- a/lib/simpletestlib.php +++ b/lib/simpletestlib.php @@ -229,59 +229,96 @@ class ContainsTagWithAttribute extends SimpleExpectation { /** * An Expectation that looks to see whether some HMTL contains a tag with an array of attributes. * All attributes must be present and their values must match the expected values. + * A third parameter can be used to specify attribute=>value pairs which must not be present in a positive match. * * @copyright 2009 Nicolas Connault * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class ContainsTagWithAttributes extends SimpleExpectation { + /** + * @var string $tag The name of the Tag to search + */ protected $tag; - protected $attributes = array(); + /** + * @var array $expectedvalues An associative array of parameters, all of which must be matched + */ + protected $expectedvalues = array(); + /** + * @var array $forbiddenvalues An associative array of parameters, none of which must be matched + */ + protected $forbiddenvalues = array(); + /** + * @var string $failurereason The reason why the test failed: nomatch or forbiddenmatch + */ + protected $failurereason = 'nomatch'; - function __construct($tag, $attributes, $message = '%s') { + function __construct($tag, $expectedvalues, $forbiddenvalues=array(), $message = '%s') { $this->SimpleExpectation($message); $this->tag = $tag; - $this->attributes = $attributes; + $this->expectedvalues = $expectedvalues; + $this->forbiddenvalues = $forbiddenvalues; } - + function test($html) { $parser = new DOMDocument(); $parser->validateOnParse = true; $parser->loadHTML($html); $list = $parser->getElementsByTagName($this->tag); - + + $foundamatch = false; + // Iterating through inputs foreach ($list as $node) { if (empty($node->attributes) || !is_a($node->attributes, 'DOMNamedNodeMap')) { continue; } - $result = true; + // For the current expected attribute under consideration, check that values match + $allattributesmatch = true; - foreach ($this->attributes as $attribute => $expectedvalue) { - if (!$node->attributes->getNamedItem($attribute)) { - break 2; + foreach ($this->expectedvalues as $expectedattribute => $expectedvalue) { + if (!$node->getAttribute($expectedattribute)) { + $this->failurereason = 'nomatch'; + continue 2; // Skip this tag, it doesn't have all the expected attributes } - - if ($node->attributes->getNamedItem($attribute)->value != $expectedvalue) { - $result = false; + if ($node->getAttribute($expectedattribute) != $expectedvalue) { + $allattributesmatch = false; + $this->failurereason = 'nomatch'; } } - if ($result) { - return true; + if ($allattributesmatch) { + $foundamatch = true; + + // Now make sure this node doesn't have any of the forbidden attributes either + $nodeattrlist = $node->attributes; + + foreach ($nodeattrlist as $domattrname => $domattr) { + if (array_key_exists($domattrname, $this->forbiddenvalues) && $node->getAttribute($domattrname) == $this->forbiddenvalues[$domattrname]) { + $this->failurereason = "forbiddenmatch:$domattrname:" . $node->getAttribute($domattrname); + $foundamatch = false; + } + } } - } - return false; + + return $foundamatch; } - + function testMessage($html) { - $output = 'Content [' . $html . '] does not contain the tag [' . $this->tag . '] with attributes ['; - foreach ($this->attributes as $var => $val) { - $output .= "$var=\"$val\" "; + $output = 'Content [' . $html . '] '; + + if (preg_match('/forbiddenmatch:(.*):(.*)/', $this->failurereason, $matches)) { + $output .= "contains the tag $this->tag with the forbidden attribute=>value pair: [$matches[1]=>$matches[2]]"; + } else if ($this->failurereason == 'nomatch') { + $output .= 'does not contain the tag [' . $this->tag . '] with attributes ['; + foreach ($this->expectedvalues as $var => $val) { + $output .= "$var=\"$val\" "; + } + $output = rtrim($output); + $output .= '].'; } - $output = rtrim($output); - $output .= ']'; + return $output; } } diff --git a/lib/weblib.php b/lib/weblib.php index e4d57b34db5..50b910ac173 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -318,7 +318,7 @@ class moodle_url { * * The added params override existing ones if they have the same name. * - * @param array $params Defaults to null. If null then return value of param 'name'. + * @param array $params Defaults to null. If null then returns all params. * @return array Array of Params for url. */ public function params($params = null) { @@ -483,6 +483,41 @@ class moodle_url { } } +/** + * Given an unknown $url type (string or moodle_url), returns a string URL. + * A relative URL is handled with $PAGE->url but gives a debugging error. + * + * @param mixed $url The URL (moodle_url or string) + * @param bool $stripformparams Whether or not to strip the query params from the URL + * @return string + */ +function prepare_url($url, $stripformparams=false) { + global $CFG, $PAGE; + + $output = $url; + + if ($url instanceof moodle_url) { + $output = $url->out($stripformparams); + } + + // Handle relative URLs + if (substr($output, 0, 4) != 'http' && substr($output, 0, 1) != '/') { + if (preg_match('/(.*)\/([A-Za-z0-9-_]*\.php)$/', $PAGE->url->out(true), $matches)) { + debugging('Relative URLs are deprecated, please use an absolute URL in your code', DEBUG_DEVELOPER); + return $matches[1] . "/$output"; + } else { + throw new coding_exception('Your page uses bizarre relative URLs which Moodle cannot handle. Please use absolute URLs.'); + } + } + + // Add wwwroot only if the URL does not already start with http:// or https:// + if (!preg_match('|https?://|', $output) ) { + $output = $CFG->wwwroot . $output; + } + + return $output; +} + /** * Determine if there is data waiting to be processed from a form * @@ -552,157 +587,6 @@ function break_up_long_words($string, $maxsize=20, $cutchar=' ') { return $output; } -/** - * This function will print a button/link/etc. form element - * that will work on both Javascript and non-javascript browsers. - * - * Relies on the Javascript function openpopup in javascript.php - * All parameters default to null, only $type and $url are mandatory. - * - * $url must be relative to home page eg /mod/survey/stuff.php - * - * @global object - * @param string $type Can be 'button' or 'link' - * @param string $url Web link. Either relative to $CFG->wwwroot, or a full URL. - * @param string $name Name to be assigned to the popup window (this is used by - * client-side scripts to "talk" to the popup window) - * @param string $linkname Text to be displayed as web link - * @param int $height Height to assign to popup window - * @param int $width Height to assign to popup window - * @param string $title Text to be displayed as popup page title - * @param string $options List of additional options for popup window - * @param bool $return If true, return as a string, otherwise print - * @param string $id id added to the element - * @param string $class class added to the element - * @return string - */ -function element_to_popup_window ($type=null, $url=null, $name=null, $linkname=null, - $height=400, $width=500, $title=null, - $options=null, $return=false, $id=null, $class=null) { - - if (is_null($url)) { - debugging('You must give the url to display in the popup. URL is missing - can\'t create popup window.', DEBUG_DEVELOPER); - } - - global $CFG; - - if ($options == 'none') { // 'none' is legacy, should be removed in v2.0 - $options = null; - } - - // add some sane default options for popup windows - if (!$options) { - $options = 'menubar=0,location=0,scrollbars,resizable'; - } - if ($width) { - $options .= ',width='. $width; - } - if ($height) { - $options .= ',height='. $height; - } - if ($id) { - $id = ' id="'.$id.'" '; - } - if ($class) { - $class = ' class="'.$class.'" '; - } - if ($name) { - $_name = $name; - if (($name = preg_replace("/\s/", '_', $name)) != $_name) { - debugging('The $name of a popup window shouldn\'t contain spaces - string modified. '. $_name .' changed to '. $name, DEBUG_DEVELOPER); - } - } else { - $name = 'popup'; - } - - // get some default string, using the localized version of legacy defaults - if (is_null($linkname) || $linkname === '') { - $linkname = get_string('clickhere'); - } - if (!$title) { - $title = get_string('popupwindowname'); - } - - $fullscreen = 0; // must be passed to openpopup - $element = ''; - - switch ($type) { - case 'button': - $element = '\n"; - break; - case 'link': - // Add wwwroot only if the URL does not already start with http:// or https:// - if (!preg_match('|https?://|', $url)) { - $url = $CFG->wwwroot . $url; - } - $element = '$linkname"; - break; - default : - print_error('cannotcreatepopupwin'); - break; - } - - if ($return) { - return $element; - } else { - echo $element; - } -} - -/** - * Creates and displays (or returns) a link to a popup window, using element_to_popup_window function. - * - * Simply calls {@link element_to_popup_window()} with type set to 'link' - * @see element_to_popup_window() - * - * @param string $url Web link. Either relative to $CFG->wwwroot, or a full URL. - * @param string $name Name to be assigned to the popup window (this is used by - * client-side scripts to "talk" to the popup window) - * @param string $linkname Text to be displayed as web link - * @param int $height Height to assign to popup window - * @param int $width Height to assign to popup window - * @param string $title Text to be displayed as popup page title - * @param string $options List of additional options for popup window - * @param bool $return If true, return as a string, otherwise print - * @param string $id id added to the element - * @param string $class class added to the element - * @return string html code to display a link to a popup window. - */ -function link_to_popup_window ($url, $name=null, $linkname=null, - $height=400, $width=500, $title=null, - $options=null, $return=false) { - - return element_to_popup_window('link', $url, $name, $linkname, $height, $width, $title, $options, $return, null, null); -} - -/** - * Creates and displays (or returns) a buttons to a popup window, using element_to_popup_window function. - * - * Simply calls {@link element_to_popup_window()} with type set to 'button' - * @see element_to_popup_window() - * - * @param string $url Web link. Either relative to $CFG->wwwroot, or a full URL. - * @param string $name Name to be assigned to the popup window (this is used by - * client-side scripts to "talk" to the popup window) - * @param string $linkname Text to be displayed as web link - * @param int $height Height to assign to popup window - * @param int $width Height to assign to popup window - * @param string $title Text to be displayed as popup page title - * @param string $options List of additional options for popup window - * @param bool $return If true, return as a string, otherwise print - * @param string $id id added to the element - * @param string $class class added to the element - * @return string html code to display a link to a popup window. - */ -function button_to_popup_window ($url, $name=null, $linkname=null, - $height=400, $width=500, $title=null, $options=null, $return=false, - $id=null, $class=null) { - - return element_to_popup_window('button', $url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class); -} - /** * Prints a simple button to close a window @@ -3164,240 +3048,6 @@ function _print_custom_corners_end($idbase) { } -/** - * Print a self contained form with a single submit button. - * - * @param string $link used as the action attribute on the form, so the URL that will be hit if the button is clicked. - * @param array $options these become hidden form fields, so these options get passed to the script at $link. - * @param string $label the caption that appears on the button. - * @param string $method HTTP method used on the request of the button is clicked. 'get' or 'post'. - * @param string $notusedanymore no longer used. - * @param boolean $return if false, output the form directly, otherwise return the HTML as a string. - * @param string $tooltip a tooltip to add to the button as a title attribute. - * @param boolean $disabled if true, the button will be disabled. - * @param string $jsconfirmmessage if not empty then display a confirm dialogue with this string as the question. - * @param string $formid The id attribute to use for the form - * @return string|void Depending on the $return paramter. - */ -function print_single_button($link, $options, $label='OK', $method='get', $notusedanymore='', - $return=false, $tooltip='', $disabled = false, $jsconfirmmessage='', $formid = '') { - $output = ''; - if ($formid) { - $formid = ' id="' . s($formid) . '"'; - } - $link = str_replace('"', '"', $link); //basic XSS protection - $output .= '"; - - if ($return) { - return $output; - } else { - echo $output; - } -} - - -/** - * Print a spacer image with the option of including a line break. - * - * @global object - * @param int $height The height in pixels to make the spacer - * @param int $width The width in pixels to make the spacer - * @param boolean $br If set to true a BR is written after the spacer - */ -function print_spacer($height=1, $width=1, $br=true, $return=false) { - global $CFG; - $output = ''; - - $output .= '
';
- if ($br) {
- $output .= ''. $message .'
'; - echo ''; - print_box_end(); -} - /** * Redirects the user to another page, after printing a notice * @@ -4856,93 +4259,6 @@ function obfuscate_mailto($email, $label='', $dimmed=false) { obfuscate_text($label)); } -/** - * Prints a single paging bar to provide access to other pages (usually in a search) - * - * @param int $totalcount Thetotal number of entries available to be paged through - * @param int $page The page you are currently viewing - * @param int $perpage The number of entries that should be shown per page - * @param mixed $baseurl If this is a string then it is the url which will be appended with $pagevar, an equals sign and the page number. - * If this is a moodle_url object then the pagevar param will be replaced by the page no, for each page. - * @param string $pagevar This is the variable name that you use for the page number in your code (ie. 'tablepage', 'blogpage', etc) - * @param bool $nocurr do not display the current page as a link - * @param bool $return whether to return an output string or echo now - * @return bool|string depending on $result - */ -function print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar='page',$nocurr=false, $return=false) { - $maxdisplay = 18; - $output = ''; - - if ($totalcount > $perpage) { - $output .= '