]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-19786 Renamed user_picture and action_icon component classes to moodle_user_pictu...
authornicolasconnault <nicolasconnault>
Mon, 10 Aug 2009 06:37:29 +0000 (06:37 +0000)
committernicolasconnault <nicolasconnault>
Mon, 10 Aug 2009 06:37:29 +0000 (06:37 +0000)
blocks/rss_client/managefeeds.php
lib/commentlib.php
lib/deprecatedlib.php
lib/outputcomponents.php
lib/outputrenderers.php
lib/simpletest/testoutputlib.php
repository/filepicker.php

index 4825f2b406f5d62f0aeb37ee4eae90d1a125cdcc..5790d53afb720275bcf195ba43ad00e69f9258f3 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
-// This file is part of Moodle - http://moodle.org/ 
-// 
+// 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
@@ -11,7 +11,7 @@
 // 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/>.
 
@@ -121,13 +121,13 @@ foreach($feeds as $feed) {
         '<div class="url">' . $OUTPUT->link($feed->url, $feed->url) .'</div>' .
         '<div class="description">' . $feed->description . '</div>';
 
-    $editaction = new action_icon();
+    $editaction = new moodle_action_icon();
     $editaction->link->url = $CFG->wwwroot .'/blocks/rss_client/editfeed.php?rssid=' . $feed->id . $extraparams;
     $editaction->link->title = get_string('edit');
     $editaction->image->src = $OUTPUT->old_icon_url('t/edit');
     $editaction->image->alt = get_string('edit');
 
-    $deleteaction = new action_icon();
+    $deleteaction = new moodle_action_icon();
     $deleteaction->link->url = $CFG->wwwroot .'/blocks/rss_client/managefeeds.php?deleterssid=' . $feed->id .
             '&sesskey=' . sesskey() . $extraparams;
     $deleteaction->link->title = get_string('delete');
index 38c9e1535ff54fb1cbeaef5ea7cea3c28962b6d2..bac55742966f03f95f2b6fc659c219dfe1c7fcdf 100644 (file)
@@ -388,7 +388,7 @@ EOD;
                 $user->lastname  = $c->lastname;
                 $user->imagealt  = $c->imagealt;
                 $c->content = format_text($c->content, $c->format);
-                $userpic = new user_picture();
+                $userpic = new moodle_user_picture();
                 $userpic->user = $user;
                 $userpic->courseid = $this->course->id;
                 $userpic->link = true;
index 072e74da4889da5ee2d78cbf85c55c665db2bcab..9f1b50ade5f36ed332ad540fcec524360ff652ac 100644 (file)
@@ -2675,7 +2675,7 @@ function print_user_picture($user, $courseid, $picture=NULL, $size=0, $return=fa
 
     // debugging('print_user_picture() has been deprecated. Please change your code to use $OUTPUT->user_picture($user, $courseid).');
 
-    $userpic = new user_picture();
+    $userpic = new moodle_user_picture();
     $userpic->user = $user;
     $userpic->courseid = $courseid;
     $userpic->size = $size;
@@ -3287,7 +3287,7 @@ function popup_form($baseurl, $options, $formid, $selected='', $nothing='choose'
     $baseurl = new moodle_url($baseurl);
     $select = moodle_select::make_popup_form($baseurl, $name, $options, $formid, $selected);
     $select->disabled = $disabled;
-    
+
     if (!empty($submitvalue)) {
         $select->form->button->text = $submitvalue;
     }
index edd47e437de7a221c30c90448163b8cd2a151d5c..933f3e80ae8c61e1a2e575155d21229407cdbee9 100644 (file)
@@ -222,1362 +222,1431 @@ class moodle_html_component {
     }
 }
 
+/// Components representing HTML elements
 
 /**
- * This class hold all the information required to describe a <select> menu that
- * will be printed by {@link moodle_core_renderer::select()}. (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.
+ * This class represents a label element
  *
- * @copyright 2009 Tim Hunt
+ * @copyright 2009 Nicolas Connault
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @since     Moodle 2.0
  */
-class moodle_select extends moodle_html_component {
+class html_label extends moodle_html_component {
     /**
-     * The moodle_select object parses an array of options into component objects
-     * @see nested attribute
-     * @var mixed $options the choices to show in the menu. An array $value => $display, of html_select_option or of html_select_optgroup objects.
+     * @var string $text The text to display in the label
      */
-    public $options;
+    public $text;
     /**
-     * @var string $name the name of this form control. That is, the name of the GET/POST
-     * variable that will be set if this select is submitted as part of a form.
+     * @var string $for The name of the form field this label is associated with
      */
-    public $name;
+    public $for;
+
     /**
-     * @var mixed $label The label for that component. String or html_label object
+     * @see moodle_html_component::prepare()
+     * @return void
      */
-    public $label;
+    public function prepare() {
+        if (empty($this->text)) {
+            throw new coding_exception('html_label must have a $text value.');
+        }
+        parent::prepare();
+    }
+}
+
+/**
+ * This class represents a select option element
+ *
+ * @copyright 2009 Nicolas Connault
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+class html_select_option extends moodle_html_component {
     /**
-     * @var string $selectedvalue the option to select initially. Should match one
-     * of the $options array keys. Default none.
+     * @var string $value The value of this option (will be sent with form)
      */
-    public $selectedvalue;
+    public $value;
     /**
-     * Defaults to get_string('choosedots').
-     * Set this to '' if you do not want a 'nothing is selected' option.
-     * This is ignored if the rendertype is 'radio' or 'checkbox'
-     * @var string The label for the 'nothing is selected' option.
+     * @var string $text The display value of the option
      */
-    public $nothinglabel = null;
+    public $text;
     /**
-     * @var string The value returned by the 'nothing is selected' option. Defaults to 0.
+     * @var boolean $selected Whether or not this option is selected
      */
-    public $nothingvalue = 0;
+    public $selected = false;
     /**
-     * @var boolean set this to true if you want the control to appear disabled.
+     * @var mixed $label The label for that component. String or html_label object
      */
-    public $disabled = false;
+    public $label;
+
+    public function __construct() {
+        $this->label = new html_label();
+    }
+
     /**
-     * @var integer if non-zero, sets the tabindex attribute on the <select> element. Default 0.
+     * @see moodle_html_component::prepare()
+     * @return void
      */
-    public $tabindex = 0;
+    public function prepare() {
+        if (empty($this->text)) {
+            throw new coding_exception('html_select_option requires a $text value.');
+        }
+
+        if (empty($this->label->text)) {
+            $this->set_label($this->text);
+        } else if (!($this->label instanceof html_label)) {
+            $this->set_label($this->label);
+        }
+        if (empty($this->id)) {
+            $this->generate_id();
+        }
+
+        parent::prepare();
+    }
+
     /**
-     * @var mixed Defaults to false, which means display the select as a dropdown menu.
-     * If true, display this select as a list box whose size is chosen automatically.
-     * If an integer, display as list box of that size.
+     * Shortcut for making a checkbox-ready option
+     * @param string $value The value of the checkbox
+     * @param boolean $checked
+     * @param string $label
+     * @param string $alt
+     * @return html_select_option A component ready for $OUTPUT->checkbox()
      */
-    public $listbox = false;
+    public function make_checkbox($value, $checked, $label='', $alt='') {
+        $checkbox = new html_select_option();
+        $checkbox->value = $value;
+        $checkbox->selected = $checked;
+        $checkbox->text = $label;
+        $checkbox->label->text = $label;
+        $checkbox->alt = $alt;
+        return $checkbox;
+    }
+}
+
+/**
+ * This class represents a select optgroup element
+ *
+ * @copyright 2009 Nicolas Connault
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+class html_select_optgroup extends moodle_html_component {
     /**
-     * @var integer if you are using $listbox === true to get an automatically
-     * sized list box, the size of the list box will be the number of options,
-     * or this number, whichever is smaller.
+     * @var string $text The display value of the optgroup
      */
-    public $maxautosize = 10;
+    public $text;
     /**
-     * @var boolean if true, allow multiple selection. Only used if $listbox is true, or if
-     *      the select is to be output as checkboxes.
+     * @var array $options An array of html_select_option objects
      */
-    public $multiple = false;
+    public $options = array();
+
+    public function prepare() {
+        if (empty($this->text)) {
+            throw new coding_exception('html_select_optgroup requires a $text value.');
+        }
+        if (empty($this->options)) {
+            throw new coding_exception('html_select_optgroup requires at least one html_select_option object');
+        }
+        parent::prepare();
+    }
+}
+
+/**
+ * This class represents an input field
+ *
+ * @copyright 2009 Nicolas Connault
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+class html_field extends moodle_html_component {
     /**
-     * Another way to use nested menu is to prefix optgroup labels with -- and end the optgroup with --
-     * Leave this setting to false if you are using the latter method.
-     * @var boolean $nested if true, uses $options' keys as option headings (optgroup)
+     * @var string $name The name attribute of the field
      */
-    public $nested = false;
+    public $name;
     /**
-     * @var html_form $form An optional html_form component
+     * @var string $value The value attribute of the field
      */
-    public $form;
+    public $value;
     /**
-     * @var moodle_help_icon $form An optional moodle_help_icon component
+     * @var string $type The type attribute of the field (text, submit, checkbox etc)
      */
-    public $helpicon;
+    public $type;
     /**
-     * @var boolean $rendertype How the select element should be rendered: menu or radio (checkbox is just radio + multiple)
+     * @var string $maxlength The maxlength attribute of the field (only applies to text type)
      */
-    public $rendertype = 'menu';
+    public $maxlength;
+    /**
+     * @var mixed $label The label for that component. String or html_label object
+     */
+    public $label;
+
+    public function __construct() {
+        $this->label = new html_label();
+    }
 
     /**
      * @see moodle_html_component::prepare()
      * @return void
      */
     public function prepare() {
-        global $CFG;
-
-        // name may contain [], which would make an invalid id. e.g. numeric question type editing form, assignment quickgrading
-        if (empty($this->id)) {
-            $this->id = 'menu' . str_replace(array('[', ']'), '', $this->name);
-        }
-
-        if (empty($this->classes)) {
-            $this->set_classes(array('menu' . str_replace(array('[', ']'), '', $this->name)));
-        }
-
-        if (is_null($this->nothinglabel)) {
-            $this->nothinglabel = get_string('choosedots');
+        if (empty($this->style)) {
+            $this->style = 'width: 4em;';
         }
-
-        if (!empty($this->label) && !($this->label instanceof html_label)) {
-            $label = new html_label();
-            $label->text = $this->label;
-            $label->for = $this->name;
-            $this->label = $label;
+        if (empty($this->id)) {
+            $this->generate_id();
         }
-
-        $this->add_class('select');
-
-        $this->initialise_options();
         parent::prepare();
     }
 
     /**
-     * This is a shortcut for making a simple select menu. It lets you specify
-     * the options, name and selected option in one line of code.
-     * @param array $options used to initialise {@link $options}.
-     * @param string $name used to initialise {@link $name}.
-     * @param string $selected  used to initialise {@link $selected}.
-     * @return moodle_select A moodle_select object with the three common fields initialised.
+     * Shortcut for creating a text input component.
+     * @param string $name    The name of the text field
+     * @param string $value   The value of the text field
+     * @param string $alt     The info to be inserted in the alt tag
+     * @param int $maxlength Sets the maxlength attribute of the field. Not set by default
+     * @return html_field The field component
      */
-    public static function make($options, $name, $selected = '') {
-        $menu = new moodle_select();
-        $menu->options = $options;
-        $menu->name = $name;
-        $menu->selectedvalue = $selected;
-        return $menu;
+    public static function make_text($name='unnamed', $value, $alt, $maxlength=0) {
+        $field = new html_field();
+        if (empty($alt)) {
+            $alt = get_string('textfield');
+        }
+        $field->type = 'text';
+        $field->name = $name;
+        $field->value = $value;
+        $field->alt = $alt;
+        $field->maxlength = $maxlength;
+        return $field;
     }
+}
 
+/**
+ * Holds all the information required to render a <table> by
+ * {@see moodle_core_renderer::table()} or by an overridden version of that
+ * method in a subclass.
+ *
+ * Example of usage:
+ * $t = new html_table();
+ * ... // set various properties of the object $t as described below
+ * echo $OUTPUT->table($t);
+ *
+ * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+class html_table extends moodle_html_component {
     /**
-     * This is a shortcut for making a yes/no select menu.
-     * @param string $name used to initialise {@link $name}.
-     * @param string $selected  used to initialise {@link $selected}.
-     * @return moodle_select A menu initialised with yes/no options.
-     */
-    public static function make_yes_no($name, $selected) {
-        return self::make(array(0 => get_string('no'), 1 => get_string('yes')), $name, $selected);
-    }
-
+     * @var array of headings. The n-th array item is used as a heading of the n-th column.
+     *
+     * Example of usage:
+     * $t->head = array('Student', 'Grade');
+     */
+    public $head;
     /**
-     * This is a shortcut for making an hour selector menu.
-     * @param string $type The type of selector (years, months, days, hours, minutes)
-     * @param string $name fieldname
-     * @param int $currenttime A default timestamp in GMT
-     * @param int $step minute spacing
-     * @return moodle_select A menu initialised with hour options.
+     * @var array can be used to make a heading span multiple columns
+     *
+     * Example of usage:
+     * $t->headspan = array(2,1);
+     *
+     * In this example, {@see html_table:$data} is supposed to have three columns. For the first two columns,
+     * the same heading is used. Therefore, {@see html_table::$head} should consist of two items.
      */
-    public static function make_time_selector($type, $name, $currenttime=0, $step=5) {
-
-        if (!$currenttime) {
-            $currenttime = time();
-        }
-        $currentdate = usergetdate($currenttime);
-        $userdatetype = $type;
-
-        switch ($type) {
-            case 'years':
-                for ($i=1970; $i<=2020; $i++) {
-                    $timeunits[$i] = $i;
-                }
-                $userdatetype = 'year';
-                break;
-            case 'months':
-                for ($i=1; $i<=12; $i++) {
-                    $timeunits[$i] = userdate(gmmktime(12,0,0,$i,15,2000), "%B");
-                }
-                $userdatetype = 'month';
-                break;
-            case 'days':
-                for ($i=1; $i<=31; $i++) {
-                    $timeunits[$i] = $i;
-                }
-                $userdatetype = 'mday';
-                break;
-            case 'hours':
-                for ($i=0; $i<=23; $i++) {
-                    $timeunits[$i] = sprintf("%02d",$i);
-                }
-                break;
-            case 'minutes':
-                if ($step != 1) {
-                    $currentdate['minutes'] = ceil($currentdate['minutes']/$step)*$step;
-                }
-
-                for ($i=0; $i<=59; $i+=$step) {
-                    $timeunits[$i] = sprintf("%02d",$i);
-                }
-                break;
-            default:
-                throw new coding_exception("Time type $type is not supported by moodle_select::make_time_selector().");
-        }
-
-        $timerselector = self::make($timeunits, $name, $currentdate[$userdatetype]);
-        $timerselector->label = new html_label();
-        $timerselector->label->text = get_string(substr($type, -1), 'form');
-        $timerselector->label->for = "menu$timerselector->name";
-        $timerselector->label->add_class('accesshide');
-        $timerselector->nothinglabel = '';
-
-        return $timerselector;
-    }
-
+    public $headspan;
     /**
-     * Given an associative array of type => fieldname and an optional timestamp,
-     * returns an array of moodle_select components representing date/time selectors.
-     * @param array $selectors Arrays of type => fieldname. Selectors will be returned in the order of the types given
-     * @param int $currenttime A UNIX timestamp
-     * @param int $step minute spacing
-     * @return array Instantiated date/time selectors
+     * @var array of column alignments. The value is used as CSS 'text-align' property. Therefore, possible
+     * values are 'left', 'right', 'center' and 'justify'. Specify 'right' or 'left' from the perspective
+     * of a left-to-right (LTR) language. For RTL, the values are flipped automatically.
+     *
+     * Examples of usage:
+     * $t->align = array(null, 'right');
+     * or
+     * $t->align[1] = 'right';
+     *
      */
-    public function make_time_selectors($selectors, $currenttime=0, $step=5) {
-        $selects = array();
-        foreach ($selectors as $type => $name) {
-            $selects[] = moodle_select::make_time_selector($type, $name, $currenttime, $step);
-        }
-        return $selects;
-    }
-
+    public $align;
     /**
-     * This is a shortcut for making a select popup form.
-     * @param mixed $baseurl The target URL, string or moodle_url
-     * @param string $name The variable which this select's options are changing in the URL
-     * @param array $options A list of value-label pairs for the popup list
-     * @param string $formid id for the control. Must be unique on the page. Used in the HTML.
-     * @param string $selected The option that is initially selected
-     * @return moodle_select A menu initialised as a popup form.
+     * @var array of column sizes. The value is used as CSS 'size' property.
+     *
+     * Examples of usage:
+     * $t->size = array('50%', '50%');
+     * or
+     * $t->size[1] = '120px';
      */
-    public function make_popup_form($baseurl, $name, $options, $formid, $selected=null) {
-        global $CFG;
-
-        $selectedurl = null;
-
-        if (!($baseurl instanceof moodle_url)) {
-            $baseurl = new moodle_url($baseurl);
-        }
-
-        if (!empty($selected)) {
-            $selectedurl = $baseurl->out(false, array($name => $selected), false);
-        }
-
-        if (!($baseurl instanceof moodle_url)) {
-            $baseurl = new moodle_url($baseurl);
-        }
-
-        // Replace real value by formatted URLs
-        foreach ($options as $value => $label) {
-            $options[$baseurl->out(false, array($name => $value), false)] = $label;
-            unset($options[$value]);
-        }
-
-        $select = self::make($options, 'jump', $selectedurl);
-
-        $select->form = new html_form();
-        $select->form->id = $formid;
-        $select->form->method = 'get';
-        $select->form->add_class('popupform');
-        $select->form->url = new moodle_url($CFG->wwwroot . '/course/jumpto.php', array('sesskey' => sesskey()));
-        $select->form->button->text = get_string('go');
-
-        $select->id = $formid . '_jump';
-
-        $select->add_action('change', 'submit_form_by_id', array('id' => $formid, 'selectid' => $select->id));
-
-        return $select;
-    }
-
+    public $size;
     /**
-     * Override the URLs of the default popup_form, which only supports one base URL
-     * @param array $options value=>label pairs representing select options
-     * @return void
+     * @var array of wrapping information. The only possible value is 'nowrap' that sets the
+     * CSS property 'white-space' to the value 'nowrap' in the given column.
+     *
+     * Example of usage:
+     * $t->wrap = array(null, 'nowrap');
      */
-    public function override_option_values($options) {
-        global $PAGE;
-
-        $this->initialise_options();
-
-        reset($options);
-
-        foreach ($this->options as $optkey => $optgroup) {
-            if ($optgroup instanceof html_select_optgroup) {
-                foreach ($optgroup->options as $key => $option) {
-                    next($options);
-                    $this->options[$optkey]->options[$key]->value = key($options);
-
-                    $optionurl = new moodle_url(key($options));
-
-                    if ($optionurl->compare($PAGE->url, URL_MATCH_PARAMS)) {
-                        $this->options[$optkey]->options[$key]->selected = 'selected';
-                    }
-                }
-                next($options);
-            } else if ($optgroup instanceof html_select_option) {
-                next($options);
-                $this->options[$optkey]->value = key($options);
-                $optionurl = new moodle_url(key($options));
-
-                if ($optionurl->compare($PAGE->url, URL_MATCH_PARAMS)) {
-                    $this->options[$optkey]->selected = 'selected';
-                }
-            }
-        }
-    }
-
+    public $wrap;
     /**
-     * Adds a help icon next to the select menu.
+     * @var array of arrays or html_table_row objects containing the data. Alternatively, if you have
+     * $head specified, the string 'hr' (for horizontal ruler) can be used
+     * instead of an array of cells data resulting in a divider rendered.
      *
-     * This can be used in two ways:
+     * Example of usage with array of arrays:
+     * $row1 = array('Harry Potter', '76 %');
+     * $row2 = array('Hermione Granger', '100 %');
+     * $t->data = array($row1, $row2);
      *
-     * <pre>
-     * $select->set_help_icon($page, $text, $linktext);
-     * // OR
-     * $helpicon = new moodle_help_icon();
-     * $helpicon->page = $page;
-     * $helpicon->text = $text;
-     * $helpicon->linktext = $linktext;
-     * $select->set_help_icon($helpicon);
-     * </pre>
+     * Example with array of html_table_row objects: (used for more fine-grained control)
+     * $cell1 = new html_table_cell();
+     * $cell1->text = 'Harry Potter';
+     * $cell1->colspan = 2;
+     * $row1 = new html_table_row();
+     * $row1->cells[] = $cell1;
+     * $cell2 = new html_table_cell();
+     * $cell2->text = 'Hermione Granger';
+     * $cell3 = new html_table_cell();
+     * $cell3->text = '100 %';
+     * $row2 = new html_table_row();
+     * $row2->cells = array($cell2, $cell3);
+     * $t->data = array($row1, $row2);
+     */
+    public $data;
+    /**
+     * @var string width of the table, percentage of the page preferred. Defaults to 80% of the page width.
+     * @deprecated since Moodle 2.0. Styling should be in the CSS.
+     */
+    public $width = null;
+    /**
+     * @var string alignment the whole table. Can be 'right', 'left' or 'center' (default).
+     * @deprecated since Moodle 2.0. Styling should be in the CSS.
+     */
+    public $tablealign = null;
+    /**
+     * @var int padding on each cell, in pixels
+     * @deprecated since Moodle 2.0. Styling should be in the CSS.
+     */
+    public $cellpadding = null;
+    /**
+     * @var int spacing between cells, in pixels
+     * @deprecated since Moodle 2.0. Styling should be in the CSS.
+     */
+    public $cellspacing = null;
+    /**
+     * @var array classes to add to particular rows, space-separated string.
+     * Classes 'r0' or 'r1' are added automatically for every odd or even row,
+     * respectively. Class 'lastrow' is added automatically for the last row
+     * in the table.
      *
-     * Use the second form when you need to add additional HTML attributes
-     * to the label and/or JS actions.
+     * Example of usage:
+     * $t->rowclasses[9] = 'tenth'
+     */
+    public $rowclasses;
+    /**
+     * @var array classes to add to every cell in a particular column,
+     * space-separated string. Class 'cell' is added automatically by the renderer.
+     * Classes 'c0' or 'c1' are added automatically for every odd or even column,
+     * respectively. Class 'lastcol' is added automatically for all last cells
+     * in a row.
      *
-     * @param mixed $page Either the keyword that defines a help page or a moodle_help_icon object
-     * @param text  $text The text of the help icon
-     * @param boolean $linktext Whether or not to show text next to the icon
-     * @return void
+     * Example of usage:
+     * $t->colclasses = array(null, 'grade');
      */
-    public function set_help_icon($page, $text, $linktext=false) {
-        if ($page instanceof moodle_help_icon) {
-            $this->helpicon = $page;
-        } else if (!empty($page)) {
-            $this->helpicon = new moodle_help_icon();
-            $this->helpicon->page = $page;
-            $this->helpicon->text = $text;
-            $this->helpicon->linktext = $linktext;
-        }
-    }
+    public $colclasses;
+    /**
+     * @var string description of the contents for screen readers.
+     */
+    public $summary;
+    /**
+     * @var bool true causes the contents of the heading cells to be rotated 90 degrees.
+     */
+    public $rotateheaders = false;
 
     /**
-     * Parses the $options array and instantiates html_select_option objects in
-     * the place of the original value => label pairs. This is useful for when you
-     * need to setup extra html attributes and actions on individual options before
-     * the component is sent to the renderer
-     * @return void;
+     * @see moodle_html_component::prepare()
+     * @return void
      */
-    public function initialise_options() {
-        // If options are already instantiated objects, stop here
-        $firstoption = reset($this->options);
-        if ($firstoption instanceof html_select_option || $firstoption instanceof html_select_optgroup) {
-            return;
+    public function prepare() {
+        if (!empty($this->align)) {
+            foreach ($this->align as $key => $aa) {
+                if ($aa) {
+                    $this->align[$key] = 'text-align:'. fix_align_rtl($aa) .';';  // Fix for RTL languages
+                } else {
+                    $this->align[$key] = '';
+                }
+            }
         }
-
-        if ($this->rendertype == 'radio' && $this->multiple) {
-            $this->rendertype = 'checkbox';
+        if (!empty($this->size)) {
+            foreach ($this->size as $key => $ss) {
+                if ($ss) {
+                    $this->size[$key] = 'width:'. $ss .';';
+                } else {
+                    $this->size[$key] = '';
+                }
+            }
         }
-
-        // If nested is on, or if radio/checkbox rendertype is set, remove the default Choose option
-        if ($this->nested || $this->rendertype == 'radio' || $this->rendertype == 'checkbox') {
-            $this->nothinglabel = '';
+        if (!empty($this->wrap)) {
+            foreach ($this->wrap as $key => $ww) {
+                if ($ww) {
+                    $this->wrap[$key] = 'white-space:nowrap;';
+                } else {
+                    $this->wrap[$key] = '';
+                }
+            }
         }
-
-        $options = $this->options;
-
-        $this->options = array();
-
-        if ($this->nested && $this->rendertype != 'menu') {
-            throw new coding_exception('moodle_select cannot render nested options as radio buttons or checkboxes.');
-        } else if ($this->nested) {
-            foreach ($options as $section => $values) {
-                $optgroup = new html_select_optgroup();
-                $optgroup->text = $section;
-
-                foreach ($values as $value => $display) {
-                    $option = new html_select_option();
-                    $option->value = s($value);
-                    $option->text = $display;
-                    if ($display === '') {
-                        $option->text = $value;
-                    }
-
-                    if ((string) $value == (string) $this->selectedvalue ||
-                            (is_array($this->selectedvalue) && in_array($value, $this->selectedvalue))) {
-                        $option->selected = 'selected';
-                    }
-
-                    $optgroup->options[] = $option;
+        if (!empty($this->head)) {
+            foreach ($this->head as $key => $val) {
+                if (!isset($this->align[$key])) {
+                    $this->align[$key] = '';
+                }
+                if (!isset($this->size[$key])) {
+                    $this->size[$key] = '';
+                }
+                if (!isset($this->wrap[$key])) {
+                    $this->wrap[$key] = '';
                 }
 
-                $this->options[] = $optgroup;
             }
+        }
+        if (empty($this->classes)) { // must be done before align
+            $this->set_classes(array('generaltable'));
+        }
+        if (!empty($this->tablealign)) {
+            $this->add_class('boxalign' . $this->tablealign);
+        }
+        if (!empty($this->rotateheaders)) {
+            $this->add_class('rotateheaders');
         } else {
-            $inoptgroup = false;
-            $optgroup = false;
-
-            foreach ($options as $value => $display) {
-                if ($display == '--') { /// we are ending previous optgroup
-                    // $this->options[] = $optgroup;
-                    $inoptgroup = false;
-                    continue;
-                } else if (substr($display,0,2) == '--') { /// we are starting a new optgroup
-                    if (!empty($optgroup->options)) {
-                        $this->options[] = $optgroup;
-                    }
-
-                    $optgroup = new html_select_optgroup();
-                    $optgroup->text = substr($display,2); // stripping the --
-
-                    $inoptgroup = true; /// everything following will be in an optgroup
-                    continue;
-
-                } else {
-                    // Add $nothing option if there are not optgroups
-                    if ($this->nothinglabel && empty($this->options[0]) && !$inoptgroup) {
-                        $nothingoption = new html_select_option();
-                        $nothingoption->value = 0;
-                        if (!empty($this->nothingvalue)) {
-                            $nothingoption->value = $this->nothingvalue;
-                        }
-                        $nothingoption->text = $this->nothinglabel;
-                        $this->options = array($nothingoption) + $this->options;
-                    }
-
-                    $option = new html_select_option();
-                    $option->text = $display;
-
-                    if ($display === '') {
-                        $option->text = $value;
-                    }
+            $this->rotateheaders = false; // Makes life easier later.
+        }
+        parent::prepare();
+    }
+    /**
+     * @param string $name The name of the variable to set
+     * @param mixed $value The value to assign to the variable
+     * @return void
+     */
+    public function __set($name, $value) {
+        if ($name == 'rowclass') {
+            debugging('rowclass[] has been deprecated for html_table ' .
+                      'and should be replaced with rowclasses[]. please fix the code.');
+            $this->rowclasses = $value;
+        } else {
+            parent::__set($name, $value);
+        }
+    }
+}
 
-                    if ((string) $value == (string) $this->selectedvalue ||
-                            (is_array($this->selectedvalue) && in_array($value, $this->selectedvalue))) {
-                        $option->selected = 'selected';
-                    }
+/**
+ * Component representing a table row.
+ *
+ * @copyright 2009 Nicolas Connault
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+class html_table_row extends moodle_html_component {
+    /**
+     * @var array $cells Array of html_table_cell objects
+     */
+    public $cells = array();
 
-                    $option->value = s($value);
+    /**
+     * @see lib/moodle_html_component#prepare()
+     * @return void
+     */
+    public function prepare() {
+        parent::prepare();
+    }
+}
 
-                    if ($inoptgroup) {
-                        $optgroup->options[] = $option;
-                    } else {
-                        $this->options[] = $option;
-                    }
-                }
-            }
+/**
+ * Component representing a table cell.
+ *
+ * @copyright 2009 Nicolas Connault
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+class html_table_cell extends moodle_html_component {
+    /**
+     * @var string $text The contents of the cell
+     */
+    public $text;
+    /**
+     * @var string $abbr Abbreviated version of the contents of the cell
+     */
+    public $abbr = '';
+    /**
+     * @var int $colspan Number of columns this cell should span
+     */
+    public $colspan = '';
+    /**
+     * @var int $rowspan Number of rows this cell should span
+     */
+    public $rowspan = '';
+    /**
+     * @var string $scope Defines a way to associate header cells and data cells in a table
+     */
+    public $scope = '';
 
-            if ($optgroup) {
-                $this->options[] = $optgroup;
-            }
-        }
+    /**
+     * @see lib/moodle_html_component#prepare()
+     * @return void
+     */
+    public function prepare() {
+        parent::prepare();
     }
 }
 
 /**
- * This class represents a label element
+ * 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_label extends moodle_html_component {
+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 to display in the label
+     * @var string $text The text that will appear between the link tags
      */
     public $text;
-    /**
-     * @var string $for The name of the form field this label is associated with
-     */
-    public $for;
 
     /**
-     * @see moodle_html_component::prepare()
+     * @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('html_label must have a $text value.');
+            throw new coding_exception('A html_link must have a descriptive text value!');
         }
+
         parent::prepare();
     }
+
+    /**
+     * Shortcut for creating a link component.
+     * @param mixed  $url String or moodle_url
+     * @param string $text The text of the link
+     * @return html_link The link component
+     */
+    public function make($url, $text) {
+        $link = new html_link();
+        $link->url = $url;
+        $link->text = $text;
+        return $link;
+    }
 }
 
 /**
- * This class represents a select option element
+ * 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_select_option extends moodle_html_component {
-    /**
-     * @var string $value The value of this option (will be sent with form)
-     */
-    public $value;
+class html_button extends moodle_html_component {
     /**
-     * @var string $text The display value of the option
+     * @var string $text
      */
     public $text;
+
     /**
-     * @var boolean $selected Whether or not this option is selected
-     */
-    public $selected = false;
-    /**
-     * @var mixed $label The label for that component. String or html_label object
+     * @var boolean $disabled Whether or not this button is disabled
      */
-    public $label;
-
-    public function __construct() {
-        $this->label = new html_label();
-    }
+    public $disabled = false;
 
     /**
-     * @see moodle_html_component::prepare()
+     * @see lib/moodle_html_component#prepare()
      * @return void
      */
     public function prepare() {
+        $this->add_class('singlebutton');
+
         if (empty($this->text)) {
-            throw new coding_exception('html_select_option requires a $text value.');
+            throw new coding_exception('A html_button must have a text value!');
         }
 
-        if (empty($this->label->text)) {
-            $this->set_label($this->text);
-        } else if (!($this->label instanceof html_label)) {
-            $this->set_label($this->label);
-        }
-        if (empty($this->id)) {
-            $this->generate_id();
+        if ($this->disabled) {
+            $this->disabled = 'disabled';
         }
 
         parent::prepare();
     }
-
-    /**
-     * Shortcut for making a checkbox-ready option
-     * @param string $value The value of the checkbox
-     * @param boolean $checked
-     * @param string $label
-     * @param string $alt
-     * @return html_select_option A component ready for $OUTPUT->checkbox()
-     */
-    public function make_checkbox($value, $checked, $label='', $alt='') {
-        $checkbox = new html_select_option();
-        $checkbox->value = $value;
-        $checkbox->selected = $checked;
-        $checkbox->text = $label;
-        $checkbox->label->text = $label;
-        $checkbox->alt = $alt;
-        return $checkbox;
-    }
 }
 
 /**
- * This class represents a select optgroup element
+ * 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_select_optgroup extends moodle_html_component {
+class html_image extends moodle_html_component {
     /**
-     * @var string $text The display value of the optgroup
+     * @var string $alt A descriptive text
      */
-    public $text;
+    public $alt = HTML_ATTR_EMPTY;
     /**
-     * @var array $options An array of html_select_option objects
+     * @var string $src The path to the image being used
      */
-    public $options = array();
+    public $src;
 
+    /**
+     * @see lib/moodle_html_component#prepare()
+     * @return void
+     */
     public function prepare() {
-        if (empty($this->text)) {
-            throw new coding_exception('html_select_optgroup requires a $text value.');
-        }
-        if (empty($this->options)) {
-            throw new coding_exception('html_select_optgroup requires at least one html_select_option object');
-        }
+        $this->add_class('image');
         parent::prepare();
     }
 }
 
 /**
- * This class represents an input field
+ * 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_field extends moodle_html_component {
+class html_textarea extends moodle_html_component {
     /**
-     * @var string $name The name attribute of the field
+     * @param string $name Name to use for the textarea element.
      */
     public $name;
     /**
-     * @var string $value The value attribute of the field
+     * @param string $value Initial content to display in the textarea.
      */
     public $value;
     /**
-     * @var string $type The type attribute of the field (text, submit, checkbox etc)
+     * @param int $rows Number of rows to display  (minimum of 10 when $height is non-null)
      */
-    public $type;
+    public $rows;
     /**
-     * @var string $maxlength The maxlength attribute of the field (only applies to text type)
+     * @param int $cols Number of columns to display (minimum of 65 when $width is non-null)
      */
-    public $maxlength;
+    public $cols;
     /**
-     * @var mixed $label The label for that component. String or html_label object
+     * @param bool $usehtmleditor Enables the use of the htmleditor for this field.
      */
-    public $label;
-
-    public function __construct() {
-        $this->label = new html_label();
-    }
+    public $usehtmleditor;
 
     /**
-     * @see moodle_html_component::prepare()
+     * @see lib/moodle_html_component#prepare()
      * @return void
      */
     public function prepare() {
-        if (empty($this->style)) {
-            $this->style = 'width: 4em;';
-        }
+        $this->add_class('form-textarea');
+
         if (empty($this->id)) {
-            $this->generate_id();
+            $this->id = "edit-$this->name";
         }
-        parent::prepare();
-    }
 
-    /**
-     * Shortcut for creating a text input component.
-     * @param string $name    The name of the text field
-     * @param string $value   The value of the text field
-     * @param string $alt     The info to be inserted in the alt tag
-     * @param int $maxlength Sets the maxlength attribute of the field. Not set by default
-     * @return html_field The field component
-     */
-    public static function make_text($name='unnamed', $value, $alt, $maxlength=0) {
-        $field = new html_field();
-        if (empty($alt)) {
-            $alt = get_string('textfield');
+        if ($this->usehtmleditor) {
+            editors_head_setup();
+            $editor = get_preferred_texteditor(FORMAT_HTML);
+            $editor->use_editor($this->id, array('legacy'=>true));
+            $this->value = htmlspecialchars($value);
         }
-        $field->type = 'text';
-        $field->name = $name;
-        $field->value = $value;
-        $field->alt = $alt;
-        $field->maxlength = $maxlength;
-        return $field;
+
+        parent::prepare();
     }
 }
 
 /**
- * This class represents how a block appears on a page.
- *
- * During output, each block instance is asked to return a block_contents object,
- * those are then passed to the $OUTPUT->block function for display.
- *
- * {@link $contents} should probably be generated using a moodle_block_..._renderer.
- *
- * Other block-like things that need to appear on the page, for example the
- * add new block UI, are also represented as block_contents objects.
+ * Component representing a simple form wrapper. Its purpose is mainly to enclose
+ * a submit input with the appropriate action and hidden inputs.
  *
- * @copyright 2009 Tim Hunt
+ * @copyright 2009 Nicolas Connault
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @since     Moodle 2.0
  */
-class block_contents extends moodle_html_component {
-    /** @var int used to set $skipid. */
-    protected static $idcounter = 1;
-
-    const NOT_HIDEABLE = 0;
-    const VISIBLE = 1;
-    const HIDDEN = 2;
-
+class html_form extends moodle_html_component {
     /**
-     * @param integer $skipid All the blocks (or things that look like blocks)
-     * printed on a page are given a unique number that can be used to construct
-     * id="" attributes. This is set automatically be the {@link prepare()} method.
-     * Do not try to set it manually.
+     * @var string $method post or get
      */
-    public $skipid;
-
+    public $method = 'post';
     /**
-     * @var integer If this is the contents of a real block, this should be set to
-     * the block_instance.id. Otherwise this should be set to 0.
+     * 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 $blockinstanceid = 0;
+    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;
 
     /**
-     * @var integer if this is a real block instance, and there is a corresponding
-     * block_position.id for the block on this page, this should be set to that id.
-     * Otherwise it should be 0.
+     * Constructor: sets up the other components in case they are needed
+     * @return void
      */
-    public $blockpositionid = 0;
+    public function __construct() {
+        static $yes;
+        $this->button = new html_button();
+        if (!isset($yes)) {
+            $yes = get_string('yes');
+            $this->button->text = $yes;
+        }
+    }
 
     /**
-     * @param array $attributes an array of attribute => value pairs that are put on the
-     * outer div of this block. {@link $id} and {@link $classes} attributes should be set separately.
+     * @see lib/moodle_html_component#prepare()
+     * @return void
      */
-    public $attributes = array();
+    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 list.
+ *
+ * The advantage of using this object instead of a flat array is that you can load it
+ * with metadata (CSS classes, event handlers etc.) which can be used by the renderers.
+ *
+ * @copyright 2009 Nicolas Connault
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+class html_list extends moodle_html_component {
 
     /**
-     * @param string $title The title of this block. If this came from user input,
-     * it should already have had format_string() processing done on it. This will
-     * be output inside <h2> tags. Please do not cause invalid XHTML.
+     * @var array $items An array of html_list_item or html_list objects
      */
-    public $title = '';
+    public $items = array();
 
     /**
-     * @param string $content HTML for the content
+     * @var string $type The type of list (ordered|unordered), definition type not yet supported
      */
-    public $content = '';
+    public $type = 'unordered';
 
     /**
-     * @param array $list an alternative to $content, it you want a list of things with optional icons.
+     * @see lib/moodle_html_component#prepare()
+     * @return void
      */
-    public $footer = '';
+    public function prepare() {
+        parent::prepare();
+    }
 
     /**
-     * Any small print that should appear under the block to explain to the
-     * teacher about the block, for example 'This is a sticky block that was
-     * added in the system context.'
-     * @var string
+     * This function takes a nested array of data and maps it into this list's $items array
+     * as proper html_list_item and html_list objects, with appropriate metadata.
+     *
+     * @param array $tree A nested array (array keys are ignored);
+     * @param int $row Used in identifying the iteration level and in ul classes
+     * @return void
      */
-    public $annotation = '';
+    public function load_data($tree, $level=0) {
 
-    /**
-     * @var integer one of the constants NOT_HIDEABLE, VISIBLE, HIDDEN. Whether
-     * the user can toggle whether this block is visible.
-     */
-    public $collapsible = self::NOT_HIDEABLE;
+        $this->add_class("list-$level");
 
-    /**
-     * A (possibly empty) array of editing controls. Each element of this array
-     * should be an array('url' => $url, 'icon' => $icon, 'caption' => $caption).
-     * $icon is the icon name. Fed to $OUTPUT->old_icon_url.
-     * @var array
-     */
-    public $controls = array();
+        foreach ($tree as $key => $element) {
+            if (is_array($element)) {
+                $newhtmllist = new html_list();
+                $newhtmllist->load_data($element, $level + 1);
+                $this->items[] = $newhtmllist;
+            } else {
+                $listitem = new html_list_item();
+                $listitem->value = $element;
+                $listitem->add_class("list-item-$level-$key");
+                $this->items[] = $listitem;
+            }
+        }
+    }
 
     /**
-     * @see moodle_html_component::prepare()
+     * Adds a html_list_item or html_list to this list.
+     * If the param is a string, a html_list_item will be added.
+     * @param mixed $item String, html_list or html_list_item object
      * @return void
      */
-    public function prepare() {
-        $this->skipid = self::$idcounter;
-        self::$idcounter += 1;
-        $this->add_class('sideblock');
-        if (empty($this->blockinstanceid) || !strip_tags($this->title)) {
-            $this->collapsible = self::NOT_HIDEABLE;
-        }
-        if ($this->collapsible == self::HIDDEN) {
-            $this->add_class('hidden');
-        }
-        if (!empty($this->controls)) {
-            $this->add_class('block_with_controls');
+    public function add_item($item) {
+        if ($item instanceof html_list_item || $item instanceof html_list) {
+            $this->items[] = $item;
+        } else {
+            $listitem = new html_list_item();
+            $listitem->value = $item;
+            $this->items[] = $item;
         }
-        parent::prepare();
     }
 }
 
-
 /**
- * This class represents a target for where a block can go when it is being moved.
- *
- * This needs to be rendered as a form with the given hidden from fields, and
- * clicking anywhere in the form should submit it. The form action should be
- * $PAGE->url.
+ * Component representing a list item.
  *
- * @copyright 2009 Tim Hunt
+ * @copyright 2009 Nicolas Connault
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @since     Moodle 2.0
  */
-class block_move_target extends moodle_html_component {
+class html_list_item extends moodle_html_component {
     /**
-     * List of hidden form fields.
-     * @var array
+     * @var string $value The value of the list item
      */
-    public $url = array();
+    public $value;
+
     /**
-     * List of hidden form fields.
-     * @var array
+     * @see lib/moodle_html_component#prepare()
+     * @return void
      */
-    public $text = '';
+    public function prepare() {
+        parent::prepare();
+    }
 }
 
+/// Complex components aggregating simpler components
 
 /**
- * Holds all the information required to render a <table> by
- * {@see moodle_core_renderer::table()} or by an overridden version of that
- * method in a subclass.
+ * This class hold all the information required to describe a <select> menu that
+ * will be printed by {@link moodle_core_renderer::select()}. (Or by an overridden
+ * version of that method in a subclass.)
  *
- * Example of usage:
- * $t = new html_table();
- * ... // set various properties of the object $t as described below
- * echo $OUTPUT->table($t);
+ * 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.
  *
- * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
+ * 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.
+ *
+ * @copyright 2009 Tim Hunt
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @since     Moodle 2.0
  */
-class html_table extends moodle_html_component {
+class moodle_select extends moodle_html_component {
     /**
-     * @var array of headings. The n-th array item is used as a heading of the n-th column.
-     *
-     * Example of usage:
-     * $t->head = array('Student', 'Grade');
+     * The moodle_select object parses an array of options into component objects
+     * @see nested attribute
+     * @var mixed $options the choices to show in the menu. An array $value => $display, of html_select_option or of html_select_optgroup objects.
      */
-    public $head;
+    public $options;
     /**
-     * @var array can be used to make a heading span multiple columns
-     *
-     * Example of usage:
-     * $t->headspan = array(2,1);
-     *
-     * In this example, {@see html_table:$data} is supposed to have three columns. For the first two columns,
-     * the same heading is used. Therefore, {@see html_table::$head} should consist of two items.
+     * @var string $name the name of this form control. That is, the name of the GET/POST
+     * variable that will be set if this select is submitted as part of a form.
      */
-    public $headspan;
+    public $name;
     /**
-     * @var array of column alignments. The value is used as CSS 'text-align' property. Therefore, possible
-     * values are 'left', 'right', 'center' and 'justify'. Specify 'right' or 'left' from the perspective
-     * of a left-to-right (LTR) language. For RTL, the values are flipped automatically.
-     *
-     * Examples of usage:
-     * $t->align = array(null, 'right');
-     * or
-     * $t->align[1] = 'right';
-     *
+     * @var mixed $label The label for that component. String or html_label object
      */
-    public $align;
+    public $label;
     /**
-     * @var array of column sizes. The value is used as CSS 'size' property.
-     *
-     * Examples of usage:
-     * $t->size = array('50%', '50%');
-     * or
-     * $t->size[1] = '120px';
+     * @var string $selectedvalue the option to select initially. Should match one
+     * of the $options array keys. Default none.
      */
-    public $size;
+    public $selectedvalue;
     /**
-     * @var array of wrapping information. The only possible value is 'nowrap' that sets the
-     * CSS property 'white-space' to the value 'nowrap' in the given column.
-     *
-     * Example of usage:
-     * $t->wrap = array(null, 'nowrap');
+     * Defaults to get_string('choosedots').
+     * Set this to '' if you do not want a 'nothing is selected' option.
+     * This is ignored if the rendertype is 'radio' or 'checkbox'
+     * @var string The label for the 'nothing is selected' option.
      */
-    public $wrap;
+    public $nothinglabel = null;
     /**
-     * @var array of arrays or html_table_row objects containing the data. Alternatively, if you have
-     * $head specified, the string 'hr' (for horizontal ruler) can be used
-     * instead of an array of cells data resulting in a divider rendered.
-     *
-     * Example of usage with array of arrays:
-     * $row1 = array('Harry Potter', '76 %');
-     * $row2 = array('Hermione Granger', '100 %');
-     * $t->data = array($row1, $row2);
-     *
-     * Example with array of html_table_row objects: (used for more fine-grained control)
-     * $cell1 = new html_table_cell();
-     * $cell1->text = 'Harry Potter';
-     * $cell1->colspan = 2;
-     * $row1 = new html_table_row();
-     * $row1->cells[] = $cell1;
-     * $cell2 = new html_table_cell();
-     * $cell2->text = 'Hermione Granger';
-     * $cell3 = new html_table_cell();
-     * $cell3->text = '100 %';
-     * $row2 = new html_table_row();
-     * $row2->cells = array($cell2, $cell3);
-     * $t->data = array($row1, $row2);
+     * @var string The value returned by the 'nothing is selected' option. Defaults to 0.
      */
-    public $data;
+    public $nothingvalue = 0;
     /**
-     * @var string width of the table, percentage of the page preferred. Defaults to 80% of the page width.
-     * @deprecated since Moodle 2.0. Styling should be in the CSS.
+     * @var boolean set this to true if you want the control to appear disabled.
      */
-    public $width = null;
+    public $disabled = false;
     /**
-     * @var string alignment the whole table. Can be 'right', 'left' or 'center' (default).
-     * @deprecated since Moodle 2.0. Styling should be in the CSS.
+     * @var integer if non-zero, sets the tabindex attribute on the <select> element. Default 0.
      */
-    public $tablealign = null;
+    public $tabindex = 0;
     /**
-     * @var int padding on each cell, in pixels
-     * @deprecated since Moodle 2.0. Styling should be in the CSS.
+     * @var mixed Defaults to false, which means display the select as a dropdown menu.
+     * If true, display this select as a list box whose size is chosen automatically.
+     * If an integer, display as list box of that size.
      */
-    public $cellpadding = null;
+    public $listbox = false;
     /**
-     * @var int spacing between cells, in pixels
-     * @deprecated since Moodle 2.0. Styling should be in the CSS.
+     * @var integer if you are using $listbox === true to get an automatically
+     * sized list box, the size of the list box will be the number of options,
+     * or this number, whichever is smaller.
      */
-    public $cellspacing = null;
+    public $maxautosize = 10;
     /**
-     * @var array classes to add to particular rows, space-separated string.
-     * Classes 'r0' or 'r1' are added automatically for every odd or even row,
-     * respectively. Class 'lastrow' is added automatically for the last row
-     * in the table.
-     *
-     * Example of usage:
-     * $t->rowclasses[9] = 'tenth'
+     * @var boolean if true, allow multiple selection. Only used if $listbox is true, or if
+     *      the select is to be output as checkboxes.
      */
-    public $rowclasses;
+    public $multiple = false;
     /**
-     * @var array classes to add to every cell in a particular column,
-     * space-separated string. Class 'cell' is added automatically by the renderer.
-     * Classes 'c0' or 'c1' are added automatically for every odd or even column,
-     * respectively. Class 'lastcol' is added automatically for all last cells
-     * in a row.
-     *
-     * Example of usage:
-     * $t->colclasses = array(null, 'grade');
+     * Another way to use nested menu is to prefix optgroup labels with -- and end the optgroup with --
+     * Leave this setting to false if you are using the latter method.
+     * @var boolean $nested if true, uses $options' keys as option headings (optgroup)
      */
-    public $colclasses;
+    public $nested = false;
     /**
-     * @var string description of the contents for screen readers.
+     * @var html_form $form An optional html_form component
      */
-    public $summary;
+    public $form;
     /**
-     * @var bool true causes the contents of the heading cells to be rotated 90 degrees.
+     * @var moodle_help_icon $form An optional moodle_help_icon component
      */
-    public $rotateheaders = false;
+    public $helpicon;
+    /**
+     * @var boolean $rendertype How the select element should be rendered: menu or radio (checkbox is just radio + multiple)
+     */
+    public $rendertype = 'menu';
 
     /**
      * @see moodle_html_component::prepare()
      * @return void
      */
     public function prepare() {
-        if (!empty($this->align)) {
-            foreach ($this->align as $key => $aa) {
-                if ($aa) {
-                    $this->align[$key] = 'text-align:'. fix_align_rtl($aa) .';';  // Fix for RTL languages
-                } else {
-                    $this->align[$key] = '';
-                }
-            }
-        }
-        if (!empty($this->size)) {
-            foreach ($this->size as $key => $ss) {
-                if ($ss) {
-                    $this->size[$key] = 'width:'. $ss .';';
-                } else {
-                    $this->size[$key] = '';
-                }
-            }
-        }
-        if (!empty($this->wrap)) {
-            foreach ($this->wrap as $key => $ww) {
-                if ($ww) {
-                    $this->wrap[$key] = 'white-space:nowrap;';
-                } else {
-                    $this->wrap[$key] = '';
-                }
-            }
-        }
-        if (!empty($this->head)) {
-            foreach ($this->head as $key => $val) {
-                if (!isset($this->align[$key])) {
-                    $this->align[$key] = '';
-                }
-                if (!isset($this->size[$key])) {
-                    $this->size[$key] = '';
-                }
-                if (!isset($this->wrap[$key])) {
-                    $this->wrap[$key] = '';
-                }
+        global $CFG;
 
-            }
+        // name may contain [], which would make an invalid id. e.g. numeric question type editing form, assignment quickgrading
+        if (empty($this->id)) {
+            $this->id = 'menu' . str_replace(array('[', ']'), '', $this->name);
         }
-        if (empty($this->classes)) { // must be done before align
-            $this->set_classes(array('generaltable'));
+
+        if (empty($this->classes)) {
+            $this->set_classes(array('menu' . str_replace(array('[', ']'), '', $this->name)));
         }
-        if (!empty($this->tablealign)) {
-            $this->add_class('boxalign' . $this->tablealign);
+
+        if (is_null($this->nothinglabel)) {
+            $this->nothinglabel = get_string('choosedots');
         }
-        if (!empty($this->rotateheaders)) {
-            $this->add_class('rotateheaders');
-        } else {
-            $this->rotateheaders = false; // Makes life easier later.
+
+        if (!empty($this->label) && !($this->label instanceof html_label)) {
+            $label = new html_label();
+            $label->text = $this->label;
+            $label->for = $this->name;
+            $this->label = $label;
         }
+
+        $this->add_class('select');
+
+        $this->initialise_options();
         parent::prepare();
     }
+
     /**
-     * @param string $name The name of the variable to set
-     * @param mixed $value The value to assign to the variable
-     * @return void
+     * This is a shortcut for making a simple select menu. It lets you specify
+     * the options, name and selected option in one line of code.
+     * @param array $options used to initialise {@link $options}.
+     * @param string $name used to initialise {@link $name}.
+     * @param string $selected  used to initialise {@link $selected}.
+     * @return moodle_select A moodle_select object with the three common fields initialised.
      */
-    public function __set($name, $value) {
-        if ($name == 'rowclass') {
-            debugging('rowclass[] has been deprecated for html_table ' .
-                      'and should be replaced with rowclasses[]. please fix the code.');
-            $this->rowclasses = $value;
-        } else {
-            parent::__set($name, $value);
-        }
+    public static function make($options, $name, $selected = '') {
+        $menu = new moodle_select();
+        $menu->options = $options;
+        $menu->name = $name;
+        $menu->selectedvalue = $selected;
+        return $menu;
     }
-}
 
-/**
- * Component representing a table row.
- *
- * @copyright 2009 Nicolas Connault
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- * @since     Moodle 2.0
- */
-class html_table_row extends moodle_html_component {
     /**
-     * @var array $cells Array of html_table_cell objects
+     * This is a shortcut for making a yes/no select menu.
+     * @param string $name used to initialise {@link $name}.
+     * @param string $selected  used to initialise {@link $selected}.
+     * @return moodle_select A menu initialised with yes/no options.
      */
-    public $cells = array();
+    public static function make_yes_no($name, $selected) {
+        return self::make(array(0 => get_string('no'), 1 => get_string('yes')), $name, $selected);
+    }
 
     /**
-     * @see lib/moodle_html_component#prepare()
-     * @return void
+     * This is a shortcut for making an hour selector menu.
+     * @param string $type The type of selector (years, months, days, hours, minutes)
+     * @param string $name fieldname
+     * @param int $currenttime A default timestamp in GMT
+     * @param int $step minute spacing
+     * @return moodle_select A menu initialised with hour options.
      */
-    public function prepare() {
-        parent::prepare();
+    public static function make_time_selector($type, $name, $currenttime=0, $step=5) {
+
+        if (!$currenttime) {
+            $currenttime = time();
+        }
+        $currentdate = usergetdate($currenttime);
+        $userdatetype = $type;
+
+        switch ($type) {
+            case 'years':
+                for ($i=1970; $i<=2020; $i++) {
+                    $timeunits[$i] = $i;
+                }
+                $userdatetype = 'year';
+                break;
+            case 'months':
+                for ($i=1; $i<=12; $i++) {
+                    $timeunits[$i] = userdate(gmmktime(12,0,0,$i,15,2000), "%B");
+                }
+                $userdatetype = 'month';
+                break;
+            case 'days':
+                for ($i=1; $i<=31; $i++) {
+                    $timeunits[$i] = $i;
+                }
+                $userdatetype = 'mday';
+                break;
+            case 'hours':
+                for ($i=0; $i<=23; $i++) {
+                    $timeunits[$i] = sprintf("%02d",$i);
+                }
+                break;
+            case 'minutes':
+                if ($step != 1) {
+                    $currentdate['minutes'] = ceil($currentdate['minutes']/$step)*$step;
+                }
+
+                for ($i=0; $i<=59; $i+=$step) {
+                    $timeunits[$i] = sprintf("%02d",$i);
+                }
+                break;
+            default:
+                throw new coding_exception("Time type $type is not supported by moodle_select::make_time_selector().");
+        }
+
+        $timerselector = self::make($timeunits, $name, $currentdate[$userdatetype]);
+        $timerselector->label = new html_label();
+        $timerselector->label->text = get_string(substr($type, -1), 'form');
+        $timerselector->label->for = "menu$timerselector->name";
+        $timerselector->label->add_class('accesshide');
+        $timerselector->nothinglabel = '';
+
+        return $timerselector;
     }
-}
 
-/**
- * Component representing a table cell.
- *
- * @copyright 2009 Nicolas Connault
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- * @since     Moodle 2.0
- */
-class html_table_cell extends moodle_html_component {
-    /**
-     * @var string $text The contents of the cell
-     */
-    public $text;
-    /**
-     * @var string $abbr Abbreviated version of the contents of the cell
-     */
-    public $abbr = '';
-    /**
-     * @var int $colspan Number of columns this cell should span
-     */
-    public $colspan = '';
     /**
-     * @var int $rowspan Number of rows this cell should span
+     * Given an associative array of type => fieldname and an optional timestamp,
+     * returns an array of moodle_select components representing date/time selectors.
+     * @param array $selectors Arrays of type => fieldname. Selectors will be returned in the order of the types given
+     * @param int $currenttime A UNIX timestamp
+     * @param int $step minute spacing
+     * @return array Instantiated date/time selectors
      */
-    public $rowspan = '';
+    public function make_time_selectors($selectors, $currenttime=0, $step=5) {
+        $selects = array();
+        foreach ($selectors as $type => $name) {
+            $selects[] = moodle_select::make_time_selector($type, $name, $currenttime, $step);
+        }
+        return $selects;
+    }
+
     /**
-     * @var string $scope Defines a way to associate header cells and data cells in a table
+     * This is a shortcut for making a select popup form.
+     * @param mixed $baseurl The target URL, string or moodle_url
+     * @param string $name The variable which this select's options are changing in the URL
+     * @param array $options A list of value-label pairs for the popup list
+     * @param string $formid id for the control. Must be unique on the page. Used in the HTML.
+     * @param string $selected The option that is initially selected
+     * @return moodle_select A menu initialised as a popup form.
      */
-    public $scope = '';
+    public function make_popup_form($baseurl, $name, $options, $formid, $selected=null) {
+        global $CFG;
+
+        $selectedurl = null;
+
+        if (!($baseurl instanceof moodle_url)) {
+            $baseurl = new moodle_url($baseurl);
+        }
+
+        if (!empty($selected)) {
+            $selectedurl = $baseurl->out(false, array($name => $selected), false);
+        }
+
+        if (!($baseurl instanceof moodle_url)) {
+            $baseurl = new moodle_url($baseurl);
+        }
+
+        // Replace real value by formatted URLs
+        foreach ($options as $value => $label) {
+            $options[$baseurl->out(false, array($name => $value), false)] = $label;
+            unset($options[$value]);
+        }
 
-    /**
-     * @see lib/moodle_html_component#prepare()
-     * @return void
-     */
-    public function prepare() {
-        parent::prepare();
-    }
-}
+        $select = self::make($options, 'jump', $selectedurl);
 
-/**
- * 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;
+        $select->form = new html_form();
+        $select->form->id = $formid;
+        $select->form->method = 'get';
+        $select->form->add_class('popupform');
+        $select->form->url = new moodle_url($CFG->wwwroot . '/course/jumpto.php', array('sesskey' => sesskey()));
+        $select->form->button->text = get_string('go');
 
-    /**
-     * @var string $text The text that will appear between the link tags
-     */
-    public $text;
+        $select->id = $formid . '_jump';
 
-    /**
-     * @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!');
-        }
+        $select->add_action('change', 'submit_form_by_id', array('id' => $formid, 'selectid' => $select->id));
 
-        parent::prepare();
+        return $select;
     }
 
     /**
-     * Shortcut for creating a link component.
-     * @param mixed  $url String or moodle_url
-     * @param string $text The text of the link
-     * @return html_link The link component
+     * Override the URLs of the default popup_form, which only supports one base URL
+     * @param array $options value=>label pairs representing select options
+     * @return void
      */
-    public function make($url, $text) {
-        $link = new html_link();
-        $link->url = $url;
-        $link->text = $text;
-        return $link;
-    }
-}
+    public function override_option_values($options) {
+        global $PAGE;
 
-/**
- * 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 moodle_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;
+        $this->initialise_options();
+
+        reset($options);
+
+        foreach ($this->options as $optkey => $optgroup) {
+            if ($optgroup instanceof html_select_optgroup) {
+                foreach ($optgroup->options as $key => $option) {
+                    next($options);
+                    $this->options[$optkey]->options[$key]->value = key($options);
+
+                    $optionurl = new moodle_url(key($options));
+
+                    if ($optionurl->compare($PAGE->url, URL_MATCH_PARAMS)) {
+                        $this->options[$optkey]->options[$key]->selected = 'selected';
+                    }
+                }
+                next($options);
+            } else if ($optgroup instanceof html_select_option) {
+                next($options);
+                $this->options[$optkey]->value = key($options);
+                $optionurl = new moodle_url(key($options));
+
+                if ($optionurl->compare($PAGE->url, URL_MATCH_PARAMS)) {
+                    $this->options[$optkey]->selected = 'selected';
+                }
+            }
+        }
+    }
 
     /**
-     * Constructor: sets up the other components in case they are needed
+     * Adds a help icon next to the select menu.
+     *
+     * This can be used in two ways:
+     *
+     * <pre>
+     * $select->set_help_icon($page, $text, $linktext);
+     * // OR
+     * $helpicon = new moodle_help_icon();
+     * $helpicon->page = $page;
+     * $helpicon->text = $text;
+     * $helpicon->linktext = $linktext;
+     * $select->set_help_icon($helpicon);
+     * </pre>
+     *
+     * Use the second form when you need to add additional HTML attributes
+     * to the label and/or JS actions.
+     *
+     * @param mixed $page Either the keyword that defines a help page or a moodle_help_icon object
+     * @param text  $text The text of the help icon
+     * @param boolean $linktext Whether or not to show text next to the icon
      * @return void
      */
-    public function __construct() {
-        $this->link = new html_link();
-        $this->image = new html_image();
+    public function set_help_icon($page, $text, $linktext=false) {
+        if ($page instanceof moodle_help_icon) {
+            $this->helpicon = $page;
+        } else if (!empty($page)) {
+            $this->helpicon = new moodle_help_icon();
+            $this->helpicon->page = $page;
+            $this->helpicon->text = $text;
+            $this->helpicon->linktext = $linktext;
+        }
     }
 
     /**
-     * @see lib/moodle_html_component#prepare()
-     * @return void
+     * Parses the $options array and instantiates html_select_option objects in
+     * the place of the original value => label pairs. This is useful for when you
+     * need to setup extra html attributes and actions on individual options before
+     * the component is sent to the renderer
+     * @return void;
      */
-    public function prepare() {
-        global $COURSE, $OUTPUT;
+    public function initialise_options() {
+        // If options are already instantiated objects, stop here
+        $firstoption = reset($this->options);
+        if ($firstoption instanceof html_select_option || $firstoption instanceof html_select_optgroup) {
+            return;
+        }
 
-        if (empty($this->page)) {
-            throw new coding_exception('A moodle_help_icon object requires a $page parameter');
+        if ($this->rendertype == 'radio' && $this->multiple) {
+            $this->rendertype = 'checkbox';
         }
 
-        if (empty($this->text)) {
-            throw new coding_exception('A moodle_help_icon object requires a $text parameter');
+        // If nested is on, or if radio/checkbox rendertype is set, remove the default Choose option
+        if ($this->nested || $this->rendertype == 'radio' || $this->rendertype == 'checkbox') {
+            $this->nothinglabel = '';
         }
 
-        $this->link->text = $this->text;
+        $options = $this->options;
 
-        // fix for MDL-7734
-        $this->link->url = new moodle_url('/help.php', array('module' => $this->module, 'file' => $this->page .'.html'));
+        $this->options = array();
 
-        // fix for MDL-7734
-        if (!empty($COURSE->lang)) {
-            $this->link->url->param('forcelang', $COURSE->lang);
-        }
+        if ($this->nested && $this->rendertype != 'menu') {
+            throw new coding_exception('moodle_select cannot render nested options as radio buttons or checkboxes.');
+        } else if ($this->nested) {
+            foreach ($options as $section => $values) {
+                $optgroup = new html_select_optgroup();
+                $optgroup->text = $section;
 
-        // 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);
-        }
+                foreach ($values as $value => $display) {
+                    $option = new html_select_option();
+                    $option->value = s($value);
+                    $option->text = $display;
+                    if ($display === '') {
+                        $option->text = $value;
+                    }
+
+                    if ((string) $value == (string) $this->selectedvalue ||
+                            (is_array($this->selectedvalue) && in_array($value, $this->selectedvalue))) {
+                        $option->selected = 'selected';
+                    }
+
+                    $optgroup->options[] = $option;
+                }
+
+                $this->options[] = $optgroup;
+            }
+        } else {
+            $inoptgroup = false;
+            $optgroup = false;
+
+            foreach ($options as $value => $display) {
+                if ($display == '--') { /// we are ending previous optgroup
+                    // $this->options[] = $optgroup;
+                    $inoptgroup = false;
+                    continue;
+                } else if (substr($display,0,2) == '--') { /// we are starting a new optgroup
+                    if (!empty($optgroup->options)) {
+                        $this->options[] = $optgroup;
+                    }
+
+                    $optgroup = new html_select_optgroup();
+                    $optgroup->text = substr($display,2); // stripping the --
+
+                    $inoptgroup = true; /// everything following will be in an optgroup
+                    continue;
+
+                } else {
+                    // Add $nothing option if there are not optgroups
+                    if ($this->nothinglabel && empty($this->options[0]) && !$inoptgroup) {
+                        $nothingoption = new html_select_option();
+                        $nothingoption->value = 0;
+                        if (!empty($this->nothingvalue)) {
+                            $nothingoption->value = $this->nothingvalue;
+                        }
+                        $nothingoption->text = $this->nothinglabel;
+                        $this->options = array($nothingoption) + $this->options;
+                    }
+
+                    $option = new html_select_option();
+                    $option->text = $display;
 
-        if ($this->module == '') {
-            $this->module = 'moodle';
-        }
+                    if ($display === '') {
+                        $option->text = $value;
+                    }
 
-        // Warn users about new window for Accessibility
-        $this->title = get_string('helpprefix2', '', trim($this->text, ". \t")) .' ('.get_string('newwindow').')';
+                    if ((string) $value == (string) $this->selectedvalue ||
+                            (is_array($this->selectedvalue) && in_array($value, $this->selectedvalue))) {
+                        $option->selected = 'selected';
+                    }
 
-        // Prepare image and linktext
-        if ($this->image && !($this->image instanceof html_image)) {
-            $image = fullclone($this->image);
-            $this->image = new html_image();
+                    $option->value = s($value);
 
-            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;
+                    if ($inoptgroup) {
+                        $optgroup->options[] = $option;
+                    } else {
+                        $this->options[] = $option;
+                    }
+                }
             }
-            $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)) {
-            if (!($this->image instanceof html_image)) {
-                $this->image = new html_image();
+            if ($optgroup) {
+                $this->options[] = $optgroup;
             }
-            $this->image->src = $OUTPUT->old_icon_url('help');
         }
-
-        parent::prepare();
-    }
-
-    public static function make_scale_menu($courseid, $scale) {
-        $helpbutton = new moodle_help_icon();
-        $strscales = get_string('scales');
-        $helpbutton->image->alt = $scale->name;
-        $helpbutton->link->url = new moodle_url('/course/scales.php', array('id' => $courseid, 'list' => true, 'scaleid' => $scale->id));
-        $popupaction = new popup_action('click', $helpbutton->url, 'ratingscale', $popupparams);
-        $popupaction->width = 500;
-        $popupaction->height = 400;
-        $helpbutton->link->add_action($popupaction);
-        $helpbutton->link->title = $scale->name;
-        return $helpbutton;
     }
 }
 
-
 /**
- * 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.
+ * 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 html_button extends moodle_html_component {
+class moodle_paging_bar extends moodle_html_component {
     /**
-     * @var string $text
+     * @var int $maxdisplay The maximum number of pagelinks to display
      */
-    public $text;
-
+    public $maxdisplay = 18;
     /**
-     * @var boolean $disabled Whether or not this button is disabled
+     * @var int $totalcount post or get
      */
-    public $disabled = false;
-
+    public $totalcount;
     /**
-     * @see lib/moodle_html_component#prepare()
-     * @return void
+     * @var int $page The page you are currently viewing
      */
-    public function prepare() {
-        $this->add_class('singlebutton');
-
-        if (empty($this->text)) {
-            throw new coding_exception('A html_button must have a text 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 {
+    public $page = 0;
     /**
-     * @var string $linktext Optional text to display next to the icon
+     * @var int $perpage The number of entries that should be shown per page
      */
-    public $linktext;
+    public $perpage;
     /**
-     * @var html_image $image The icon
+     * @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 $image;
+    public $baseurl;
     /**
-     * @var html_link $link The link
+     * @var string $pagevar This is the variable name that you use for the page number in your code (ie. 'tablepage', 'blogpage', etc)
      */
-    public $link;
-
+    public $pagevar = 'page';
     /**
-     * Constructor: sets up the other components in case they are needed
-     * @return void
+     * @var bool $nocurr do not display the current page as a link
      */
-    public function __construct() {
-        $this->image = new html_image();
-        $this->link = new html_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() {
-        $this->image->add_class('action-icon');
+        if (empty($this->totalcount)) {
+            throw new coding_exception('moodle_paging_bar requires a totalcount value.');
+        }
+        if (!isset($this->page) || is_null($this->page)) {
+            throw new coding_exception('moodle_paging_bar requires a page value.');
+        }
+        if (empty($this->perpage)) {
+            throw new coding_exception('moodle_paging_bar requires a perpage value.');
+        }
+        if (empty($this->baseurl)) {
+            throw new coding_exception('moodle_paging_bar requires a baseurl value.');
+        }
+        if (!($this->baseurl instanceof moodle_url)) {
+            $this->baseurl = new moodle_url($this->baseurl);
+        }
 
-        parent::prepare();
+        if ($this->totalcount > $this->perpage) {
+            $pagenum = $this->page - 1;
 
-        if (empty($this->image->src)) {
-            throw new coding_exception('action_icon->image->src must not be empty');
-        }
+            if ($this->page > 0) {
+                $this->previouslink = new html_link();
+                $this->previouslink->add_class('previous');
+                $this->previouslink->url = clone($this->baseurl);
+                $this->previouslink->url->param($this->pagevar, $pagenum);
+                $this->previouslink->text = get_string('previous');
+            }
 
-        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);
+            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 = clone($this->baseurl);
+                $this->firstlink->url->param($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 = clone($this->baseurl);
+                    $pagelink->url->param($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 = clone($this->baseurl);
+                $this->lastlink->url->param($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 = clone($this->baseurl);
+                $this->nextlink->url->param($this->pagevar, $pagenum);
+                $this->nextlink->text = get_string('next');
+                $this->nextlink->add_class('next');
+            }
         }
     }
-}
-
-/**
- * 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
+     * Shortcut for initialising a moodle_paging_bar with only the required params.
+     *
+     * @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.
      */
-    public function prepare() {
-        $this->add_class('image');
-        parent::prepare();
+    public function make($totalcount, $page, $perpage, $baseurl) {
+        $pagingbar = new moodle_paging_bar();
+        $pagingbar->totalcount = $totalcount;
+        $pagingbar->page = $page;
+        $pagingbar->perpage = $perpage;
+        $pagingbar->baseurl = $baseurl;
+        return $pagingbar;
     }
 }
 
@@ -1588,7 +1657,7 @@ class html_image extends moodle_html_component {
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @since     Moodle 2.0
  */
-class user_picture extends moodle_html_component {
+class moodle_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.
      */
@@ -1634,15 +1703,15 @@ class user_picture extends moodle_html_component {
         global $CFG, $DB, $OUTPUT;
 
         if (empty($this->user)) {
-            throw new coding_exception('A user_picture object must have a $user object before being rendered.');
+            throw new coding_exception('A moodle_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.');
+            throw new coding_exception('A moodle_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);
+            debugging('moodle_user_picture::image must be an instance of html_image', DEBUG_DEVELOPER);
         }
 
         $needrec = false;
@@ -1729,102 +1798,47 @@ class user_picture extends moodle_html_component {
 }
 
 /**
- * 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.
+ * 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 html_form extends moodle_html_component {
+class moodle_help_icon extends moodle_html_component {
     /**
-     * @var string $method post or get
+     * @var html_link $link A html_link object that will hold the URL info
      */
-    public $method = 'post';
+    public $link;
     /**
-     * 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
+     * @var string $text A descriptive text
      */
-    public $url;
+    public $text;
     /**
-     * @var array $params Optional array of parameters. Ignored if $url instanceof moodle_url
+     * @var string $page  The keyword that defines a help page
      */
-    public $params = array();
+    public $page;
     /**
-     * @var boolean $showbutton If true, the submit button will always be shown even if JavaScript is available
+     * @var string $module Which module is the page defined in
      */
-    public $showbutton = false;
+    public $module = 'moodle';
     /**
-     * @var string $targetwindow The name of the target page to open the linked page in.
+     * @var boolean $linktext Whether or not to show text next to the icon
      */
-    public $targetwindow = 'self';
+    public $linktext = false;
     /**
-     * @var html_button $button A submit button
+     * @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 $button;
+    public $image;
 
     /**
      * Constructor: sets up the other components in case they are needed
      * @return void
      */
     public function __construct() {
-        static $yes;
-        $this->button = new html_button();
-        if (!isset($yes)) {
-            $yes = get_string('yes');
-            $this->button->text = $yes;
-        }
+        $this->link = new html_link();
+        $this->image = new html_image();
     }
 
     /**
@@ -1832,282 +1846,268 @@ class html_form extends moodle_html_component {
      * @return void
      */
     public function prepare() {
+        global $COURSE, $OUTPUT;
 
-        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 (empty($this->page)) {
+            throw new coding_exception('A moodle_help_icon object requires a $page parameter');
         }
 
-        if ($this->method == 'post') {
-            $this->url->param('sesskey', sesskey());
+        if (empty($this->text)) {
+            throw new coding_exception('A moodle_help_icon object requires a $text parameter');
         }
 
-        parent::prepare();
-    }
-}
+        $this->link->text = $this->text;
 
-/**
- * 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 = 0;
-    /**
-     * @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();
+        // fix for MDL-7734
+        $this->link->url = new moodle_url('/help.php', array('module' => $this->module, 'file' => $this->page .'.html'));
 
-    /**
-     * @see lib/moodle_html_component#prepare()
-     * @return void
-     */
-    public function prepare() {
-        if (empty($this->totalcount)) {
-            throw new coding_exception('moodle_paging_bar requires a totalcount value.');
-        }
-        if (!isset($this->page) || is_null($this->page)) {
-            throw new coding_exception('moodle_paging_bar requires a page value.');
-        }
-        if (empty($this->perpage)) {
-            throw new coding_exception('moodle_paging_bar requires a perpage value.');
-        }
-        if (empty($this->baseurl)) {
-            throw new coding_exception('moodle_paging_bar requires a baseurl value.');
-        }
-        if (!($this->baseurl instanceof moodle_url)) {
-            $this->baseurl = new moodle_url($this->baseurl);
+        // fix for MDL-7734
+        if (!empty($COURSE->lang)) {
+            $this->link->url->param('forcelang', $COURSE->lang);
         }
 
-        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 = clone($this->baseurl);
-                $this->previouslink->url->param($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 = clone($this->baseurl);
-                $this->firstlink->url->param($this->pagevar, 0);
-                $this->firstlink->text = 1;
-                $this->firstlink->add_class('first');
-            } else {
-                $startpage = 0;
-            }
+        // 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);
+        }
 
-            $currpage = $startpage;
-            $displaycount = $displaypage = 0;
+        if ($this->module == '') {
+            $this->module = 'moodle';
+        }
 
-            while ($displaycount < $this->maxdisplay and $currpage < $lastpage) {
-                $displaypage = $currpage + 1;
+        // Warn users about new window for Accessibility
+        $this->title = get_string('helpprefix2', '', trim($this->text, ". \t")) .' ('.get_string('newwindow').')';
 
-                if ($this->page == $currpage && empty($this->nocurr)) {
-                    $this->pagelinks[] = $displaypage;
-                } else {
-                    $pagelink = new html_link();
-                    $pagelink->url = clone($this->baseurl);
-                    $pagelink->url->param($this->pagevar, $currpage);
-                    $pagelink->text = $displaypage;
-                    $this->pagelinks[] = $pagelink;
-                }
+        // Prepare image and linktext
+        if ($this->image && !($this->image instanceof html_image)) {
+            $image = fullclone($this->image);
+            $this->image = new html_image();
 
-                $displaycount++;
-                $currpage++;
+            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 ($currpage < $lastpage) {
-                $lastpageactual = $lastpage - 1;
-                $this->lastlink = new html_link();
-                $this->lastlink->url = clone($this->baseurl);
-                $this->lastlink->url->param($this->pagevar, $lastpageactual);
-                $this->lastlink->text = $lastpage;
-                $this->lastlink->add_class('last');
+            if ($this->linktext) {
+                $this->image->alt = get_string('helpwiththis');
+            } else {
+                $this->image->alt = $this->title;
             }
-
-            $pagenum = $this->page + 1;
-
-            if ($pagenum != $displaypage) {
-                $this->nextlink = new html_link();
-                $this->nextlink->url = clone($this->baseurl);
-                $this->nextlink->url->param($this->pagevar, $pagenum);
-                $this->nextlink->text = get_string('next');
-                $this->nextlink->add_class('next');
+            $this->image->add_class('iconhelp');
+        } else if (empty($this->image->src)) {
+            if (!($this->image instanceof html_image)) {
+                $this->image = new html_image();
             }
+            $this->image->src = $OUTPUT->old_icon_url('help');
         }
+
+        parent::prepare();
     }
 
-    /**
-     * Shortcut for initialising a moodle_paging_bar with only the required params.
-     *
-     * @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.
-     */
-    public function make($totalcount, $page, $perpage, $baseurl) {
-        $pagingbar = new moodle_paging_bar();
-        $pagingbar->totalcount = $totalcount;
-        $pagingbar->page = $page;
-        $pagingbar->perpage = $perpage;
-        $pagingbar->baseurl = $baseurl;
-        return $pagingbar;
+    public static function make_scale_menu($courseid, $scale) {
+        $helpbutton = new moodle_help_icon();
+        $strscales = get_string('scales');
+        $helpbutton->image->alt = $scale->name;
+        $helpbutton->link->url = new moodle_url('/course/scales.php', array('id' => $courseid, 'list' => true, 'scaleid' => $scale->id));
+        $popupaction = new popup_action('click', $helpbutton->url, 'ratingscale', $popupparams);
+        $popupaction->width = 500;
+        $popupaction->height = 400;
+        $helpbutton->link->add_action($popupaction);
+        $helpbutton->link->title = $scale->name;
+        return $helpbutton;
     }
 }
 
 /**
- * Component representing a list.
- *
- * The advantage of using this object instead of a flat array is that you can load it
- * with metadata (CSS classes, event handlers etc.) which can be used by the renderers.
+ * 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 html_list extends moodle_html_component {
-
+class moodle_action_icon extends moodle_html_component {
     /**
-     * @var array $items An array of html_list_item or html_list objects
+     * @var string $linktext Optional text to display next to the icon
      */
-    public $items = array();
-
+    public $linktext;
     /**
-     * @var string $type The type of list (ordered|unordered), definition type not yet supported
+     * @var html_image $image The icon
      */
-    public $type = 'unordered';
+    public $image;
+    /**
+     * @var html_link $link The link
+     */
+    public $link;
 
     /**
-     * @see lib/moodle_html_component#prepare()
+     * Constructor: sets up the other components in case they are needed
      * @return void
      */
-    public function prepare() {
-        parent::prepare();
+    public function __construct() {
+        $this->image = new html_image();
+        $this->link = new html_link();
     }
 
     /**
-     * This function takes a nested array of data and maps it into this list's $items array
-     * as proper html_list_item and html_list objects, with appropriate metadata.
-     *
-     * @param array $tree A nested array (array keys are ignored);
-     * @param int $row Used in identifying the iteration level and in ul classes
+     * @see lib/moodle_html_component#prepare()
      * @return void
      */
-    public function load_data($tree, $level=0) {
+    public function prepare() {
+        $this->image->add_class('action-icon');
 
-        $this->add_class("list-$level");
+        parent::prepare();
 
-        foreach ($tree as $key => $element) {
-            if (is_array($element)) {
-                $newhtmllist = new html_list();
-                $newhtmllist->load_data($element, $level + 1);
-                $this->items[] = $newhtmllist;
-            } else {
-                $listitem = new html_list_item();
-                $listitem->value = $element;
-                $listitem->add_class("list-item-$level-$key");
-                $this->items[] = $listitem;
-            }
+        if (empty($this->image->src)) {
+            throw new coding_exception('moodle_action_icon->image->src must not be empty');
         }
-    }
 
-    /**
-     * Adds a html_list_item or html_list to this list.
-     * If the param is a string, a html_list_item will be added.
-     * @param mixed $item String, html_list or html_list_item object
-     * @return void
-     */
-    public function add_item($item) {
-        if ($item instanceof html_list_item || $item instanceof html_list) {
-            $this->items[] = $item;
-        } else {
-            $listitem = new html_list_item();
-            $listitem->value = $item;
-            $this->items[] = $item;
+        if (empty($this->image->alt) && !empty($this->linktext)) {
+            $this->image->alt = $this->linktext;
+        } else if (empty($this->image->alt)) {
+            debugging('moodle_action_icon->image->alt should not be empty.', DEBUG_DEVELOPER);
         }
     }
 }
 
 /**
- * Component representing a list item.
+ * This class represents how a block appears on a page.
  *
- * @copyright 2009 Nicolas Connault
+ * During output, each block instance is asked to return a block_contents object,
+ * those are then passed to the $OUTPUT->block function for display.
+ *
+ * {@link $contents} should probably be generated using a moodle_block_..._renderer.
+ *
+ * Other block-like things that need to appear on the page, for example the
+ * add new block UI, are also represented as block_contents objects.
+ *
+ * @copyright 2009 Tim Hunt
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @since     Moodle 2.0
  */
-class html_list_item extends moodle_html_component {
+class block_contents extends moodle_html_component {
+    /** @var int used to set $skipid. */
+    protected static $idcounter = 1;
+
+    const NOT_HIDEABLE = 0;
+    const VISIBLE = 1;
+    const HIDDEN = 2;
+
     /**
-     * @var string $value The value of the list item
+     * @param integer $skipid All the blocks (or things that look like blocks)
+     * printed on a page are given a unique number that can be used to construct
+     * id="" attributes. This is set automatically be the {@link prepare()} method.
+     * Do not try to set it manually.
      */
-    public $value;
+    public $skipid;
 
     /**
-     * @see lib/moodle_html_component#prepare()
+     * @var integer If this is the contents of a real block, this should be set to
+     * the block_instance.id. Otherwise this should be set to 0.
+     */
+    public $blockinstanceid = 0;
+
+    /**
+     * @var integer if this is a real block instance, and there is a corresponding
+     * block_position.id for the block on this page, this should be set to that id.
+     * Otherwise it should be 0.
+     */
+    public $blockpositionid = 0;
+
+    /**
+     * @param array $attributes an array of attribute => value pairs that are put on the
+     * outer div of this block. {@link $id} and {@link $classes} attributes should be set separately.
+     */
+    public $attributes = array();
+
+    /**
+     * @param string $title The title of this block. If this came from user input,
+     * it should already have had format_string() processing done on it. This will
+     * be output inside <h2> tags. Please do not cause invalid XHTML.
+     */
+    public $title = '';
+
+    /**
+     * @param string $content HTML for the content
+     */
+    public $content = '';
+
+    /**
+     * @param array $list an alternative to $content, it you want a list of things with optional icons.
+     */
+    public $footer = '';
+
+    /**
+     * Any small print that should appear under the block to explain to the
+     * teacher about the block, for example 'This is a sticky block that was
+     * added in the system context.'
+     * @var string
+     */
+    public $annotation = '';
+
+    /**
+     * @var integer one of the constants NOT_HIDEABLE, VISIBLE, HIDDEN. Whether
+     * the user can toggle whether this block is visible.
+     */
+    public $collapsible = self::NOT_HIDEABLE;
+
+    /**
+     * A (possibly empty) array of editing controls. Each element of this array
+     * should be an array('url' => $url, 'icon' => $icon, 'caption' => $caption).
+     * $icon is the icon name. Fed to $OUTPUT->old_icon_url.
+     * @var array
+     */
+    public $controls = array();
+
+    /**
+     * @see moodle_html_component::prepare()
      * @return void
      */
     public function prepare() {
+        $this->skipid = self::$idcounter;
+        self::$idcounter += 1;
+        $this->add_class('sideblock');
+        if (empty($this->blockinstanceid) || !strip_tags($this->title)) {
+            $this->collapsible = self::NOT_HIDEABLE;
+        }
+        if ($this->collapsible == self::HIDDEN) {
+            $this->add_class('hidden');
+        }
+        if (!empty($this->controls)) {
+            $this->add_class('block_with_controls');
+        }
         parent::prepare();
     }
 }
+
+/**
+ * This class represents a target for where a block can go when it is being moved.
+ *
+ * This needs to be rendered as a form with the given hidden from fields, and
+ * clicking anywhere in the form should submit it. The form action should be
+ * $PAGE->url.
+ *
+ * @copyright 2009 Tim Hunt
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+class block_move_target extends moodle_html_component {
+    /**
+     * List of hidden form fields.
+     * @var array
+     */
+    public $url = array();
+    /**
+     * List of hidden form fields.
+     * @var array
+     */
+    public $text = '';
+}
index a0615c2ad534bcf3efaa37c808c5453eb204a45f..f16adeec72f8d11df54d2ab8507288e053c74f60 100644 (file)
@@ -1221,7 +1221,7 @@ class moodle_core_renderer extends moodle_renderer_base {
      */
     public function doc_link($path, $text=false, $iconpath=false) {
         global $CFG, $OUTPUT;
-        $icon = new action_icon();
+        $icon = new moodle_action_icon();
         $icon->linktext = $text;
         $icon->image->alt = $text;
         $icon->image->add_class('iconhelp');
@@ -1242,9 +1242,9 @@ class moodle_core_renderer extends moodle_renderer_base {
     }
 
     /**
-     * Given a action_icon object, outputs an image linking to an action (URL or AJAX).
+     * Given a moodle_action_icon object, outputs an image linking to an action (URL or AJAX).
      *
-     * @param action_icon $icon An action_icon object
+     * @param moodle_action_icon $icon A moodle_action_icon object
      * @return string HTML fragment
      */
     public function action_icon($icon) {
@@ -1402,7 +1402,7 @@ class moodle_core_renderer extends moodle_renderer_base {
      * This method can be used in two ways:
      * <pre>
      * // Option 1:
-     * $userpic = new user_picture();
+     * $userpic = new moodle_user_picture();
      * // Set properties of $userpic
      * $OUTPUT->user_picture($userpic);
      *
@@ -1414,20 +1414,20 @@ class moodle_core_renderer extends moodle_renderer_base {
      * @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.
+     *     A moodle_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
+     *     is not a moodle_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)) {
+        // Instantiate a moodle_user_picture object if $user is not already one
+        if (!($userpic instanceof moodle_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 = new moodle_user_picture();
             $userpic->user = $user;
             $userpic->courseid = $courseid;
         } else {
index 80a26ca42de2ce383ac25804444b470c007b208c..851dd5bf3db5cbb00fedae5b726394bf2fe54264 100644 (file)
@@ -1187,7 +1187,7 @@ class moodle_core_renderer_test extends UnitTestCase {
         $this->assert(new ContainsTagWithContents('option', 'value3'), $html);
         $this->assert(new ContainsTagWithContents('option', 'value4'), $html);
     }
-    
+
     public function test_userpicture() {
         global $CFG;
         // Set up the user with the required fields
@@ -1197,7 +1197,7 @@ class moodle_core_renderer_test extends UnitTestCase {
         $user->picture = false;
         $user->imagealt = false;
         $user->id = 1;
-        $userpic = new user_picture();
+        $userpic = new moodle_user_picture();
         $userpic->user = $user;
         $userpic->courseid = 1;
         $userpic->url = true;
index 07a3f9579e49a2a094add78357afd816bd17feed..ba9788d075fd5cea765111ef571b0d95ba908ee6 100755 (executable)
@@ -233,7 +233,7 @@ case 'plugins':
     echo '<div><ul>';
     foreach($repos as $repo) {
         $info = $repo->get_meta();
-        $icon = new action_icon();
+        $icon = new moodle_action_icon();
         $icon->image->src = $info->icon;
         $icon->image->style = 'height: 16px; width: 16px;';
         $icon->link->url = clone($url);