MDL-19690 - fix mailyes|no icon
[moodle.git] / lib / outputcomponents.php
CommitLineData
d9c8f425 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * Classes representing HTML elements, used by $OUTPUT methods
20 *
21 * Please see http://docs.moodle.org/en/Developement:How_Moodle_outputs_HTML
22 * for an overview.
23 *
24 * @package moodlecore
25 * @copyright 2009 Tim Hunt
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 */
28
29/**
30 * Base class for classes representing HTML elements, like moodle_select.
31 *
32 * Handles the id and class attributes.
33 *
34 * @copyright 2009 Tim Hunt
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 * @since Moodle 2.0
37 */
38class moodle_html_component {
39 /**
40 * @var string value to use for the id attribute of this HTML tag.
41 */
42 public $id = '';
43 /**
44 * @var string $alt value to use for the alt attribute of this HTML tag.
45 */
46 public $alt = '';
47 /**
48 * @var string $style value to use for the style attribute of this HTML tag.
49 */
50 public $style = '';
51 /**
52 * @var array class names to add to this HTML element.
53 */
54 public $classes = array();
55 /**
56 * @var string $title The title attributes applicable to any XHTML element
57 */
58 public $title = '';
59 /**
60 * An optional array of component_action objects handling the action part of this component.
61 * @var array $actions
62 */
63 protected $actions = array();
64 /**
65 * This array of generated ids is kept static to avoid id collisions
66 * @var array $generated_ids
67 */
68 public static $generated_ids = array();
69
70 /**
71 * Ensure some class names are an array.
72 * @param mixed $classes either an array of class names or a space-separated
73 * string containing class names.
74 * @return array the class names as an array.
75 */
76 public static function clean_classes($classes) {
77 if (is_array($classes)) {
78 return $classes;
79 } else {
80 return explode(' ', trim($classes));
81 }
82 }
83
84 /**
85 * Set the class name array.
86 * @param mixed $classes either an array of class names or a space-separated
87 * string containing class names.
88 * @return void
89 */
90 public function set_classes($classes) {
91 $this->classes = self::clean_classes($classes);
92 }
93
94 /**
95 * Add a class name to the class names array.
96 * @param string $class the new class name to add.
97 * @return void
98 */
99 public function add_class($class) {
100 $this->classes[] = $class;
101 }
102
103 /**
104 * Add a whole lot of class names to the class names array.
105 * @param mixed $classes either an array of class names or a space-separated
106 * string containing class names.
107 * @return void
108 */
109 public function add_classes($classes) {
110 $this->classes += self::clean_classes($classes);
111 }
112
113 /**
114 * Get the class names as a string.
115 * @return string the class names as a space-separated string. Ready to be put in the class="" attribute.
116 */
117 public function get_classes_string() {
118 return implode(' ', $this->classes);
119 }
120
121 /**
122 * Perform any cleanup or final processing that should be done before an
123 * instance of this class is output.
124 * @return void
125 */
126 public function prepare() {
127 $this->classes = array_unique(self::clean_classes($this->classes));
128 }
129
130 /**
131 * This checks developer do not try to assign a property directly
132 * if we have a setter for it. Otherwise, the property is set as expected.
133 * @param string $name The name of the variable to set
134 * @param mixed $value The value to assign to the variable
135 * @return void
136 */
137 public function __set($name, $value) {
138 if ($name == 'class') {
139 debugging('this way of setting css class has been deprecated. use set_classes() method instead.');
140 $this->set_classes($value);
141 } else {
142 $this->{$name} = $value;
143 }
144 }
145
146 /**
147 * Adds a JS action to this component.
148 * Note: the JS function you write must have only two arguments: (string)event and (object|array)args
149 * If you want to add an instantiated component_action (or one of its subclasses), give the object as the only parameter
150 *
151 * @param mixed $event a DOM event (click, mouseover etc.) or a component_action object
152 * @param string $jsfunction The name of the JS function to call. required if argument 1 is a string (event)
153 * @param array $jsfunctionargs An optional array of JS arguments to pass to the function
154 */
155 public function add_action($event, $jsfunction=null, $jsfunctionargs=array()) {
156 if (empty($this->id)) {
157 $this->generate_id();
158 }
159
160 if ($event instanceof component_action) {
161 $this->actions[] = $event;
162 } else {
163 if (empty($jsfunction)) {
164 throw new coding_exception('moodle_html_component::add_action requires a JS function argument if the first argument is a string event');
165 }
166 $this->actions[] = new component_action($event, $jsfunction, $jsfunctionargs);
167 }
168 }
169
170 /**
171 * Internal method for generating a unique ID for the purpose of event handlers.
172 */
173 protected function generate_id() {
174 // Generate an id that is not already used.
175 do {
176 $newid = get_class($this) . '-' . substr(sha1(microtime() * rand(0, 500)), 0, 6);
177 } while (in_array($this->id, moodle_html_component::$generated_ids));
178 $this->id = $newid;
179 moodle_html_component::$generated_ids[] = $newid;
180 }
181
182 /**
183 * Returns the array of component_actions.
184 * @return array Component actions
185 */
186 public function get_actions() {
187 return $this->actions;
188 }
189
190 /**
191 * Adds a descriptive label to the component.
192 *
193 * This can be used in two ways:
194 *
195 * <pre>
196 * $component->set_label($elementlabel, $elementid);
197 * // OR
198 * $label = new html_label();
199 * $label->for = $elementid;
200 * $label->text = $elementlabel;
201 * $component->set_label($label);
202 * </pre>
203 *
204 * Use the second form when you need to add additional HTML attributes
205 * to the label and/or JS actions.
206 *
207 * @param mixed $text Either the text of the label or a html_label object
208 * @param text $for The value of the "for" attribute (the associated element's id)
209 * @return void
210 */
211 public function set_label($text, $for=null) {
212 if ($text instanceof html_label) {
213 $this->label = $text;
214 } else if (!empty($text)) {
215 $this->label = new html_label();
216 $this->label->for = $for;
217 if (empty($for) && !empty($this->id)) {
218 $this->label->for = $this->id;
219 }
220 $this->label->text = $text;
221 }
222 }
e6fcbe27 223
224 /**
225 * Shortcut for adding a JS confirm dialog when the component is clicked.
226 * The message must be a yes/no question.
227 * @param string $message The yes/no confirmation question. If "Yes" is clicked, the original action will occur.
228 * @return void
229 */
230 public function add_confirm_action($message) {
231 $this->add_action(new component_action('click', 'confirm_dialog', array('message' => $message)));
232 }
d9c8f425 233}
234
beb56299 235/// Components representing HTML elements
d9c8f425 236
237/**
beb56299 238 * This class represents a label element
d9c8f425 239 *
beb56299 240 * @copyright 2009 Nicolas Connault
d9c8f425 241 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
242 * @since Moodle 2.0
243 */
beb56299 244class html_label extends moodle_html_component {
d9c8f425 245 /**
beb56299 246 * @var string $text The text to display in the label
d9c8f425 247 */
beb56299 248 public $text;
d9c8f425 249 /**
beb56299 250 * @var string $for The name of the form field this label is associated with
d9c8f425 251 */
beb56299 252 public $for;
253
d9c8f425 254 /**
beb56299 255 * @see moodle_html_component::prepare()
256 * @return void
d9c8f425 257 */
beb56299 258 public function prepare() {
259 if (empty($this->text)) {
260 throw new coding_exception('html_label must have a $text value.');
261 }
262 parent::prepare();
263 }
264}
265
266/**
267 * This class represents a select option element
268 *
269 * @copyright 2009 Nicolas Connault
270 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
271 * @since Moodle 2.0
272 */
273class html_select_option extends moodle_html_component {
d9c8f425 274 /**
beb56299 275 * @var string $value The value of this option (will be sent with form)
d9c8f425 276 */
beb56299 277 public $value;
d9c8f425 278 /**
beb56299 279 * @var string $text The display value of the option
d9c8f425 280 */
beb56299 281 public $text;
d9c8f425 282 /**
beb56299 283 * @var boolean $selected Whether or not this option is selected
d9c8f425 284 */
beb56299 285 public $selected = false;
d9c8f425 286 /**
beb56299 287 * @var mixed $label The label for that component. String or html_label object
d9c8f425 288 */
beb56299 289 public $label;
290
291 public function __construct() {
292 $this->label = new html_label();
293 }
294
d9c8f425 295 /**
beb56299 296 * @see moodle_html_component::prepare()
297 * @return void
d9c8f425 298 */
beb56299 299 public function prepare() {
300 if (empty($this->text)) {
301 throw new coding_exception('html_select_option requires a $text value.');
302 }
303
304 if (empty($this->label->text)) {
305 $this->set_label($this->text);
306 } else if (!($this->label instanceof html_label)) {
307 $this->set_label($this->label);
308 }
309 if (empty($this->id)) {
310 $this->generate_id();
311 }
312
313 parent::prepare();
314 }
315
d9c8f425 316 /**
beb56299 317 * Shortcut for making a checkbox-ready option
318 * @param string $value The value of the checkbox
319 * @param boolean $checked
320 * @param string $label
321 * @param string $alt
322 * @return html_select_option A component ready for $OUTPUT->checkbox()
d9c8f425 323 */
beb56299 324 public function make_checkbox($value, $checked, $label='', $alt='') {
325 $checkbox = new html_select_option();
326 $checkbox->value = $value;
327 $checkbox->selected = $checked;
328 $checkbox->text = $label;
329 $checkbox->label->text = $label;
330 $checkbox->alt = $alt;
331 return $checkbox;
332 }
333}
334
335/**
336 * This class represents a select optgroup element
337 *
338 * @copyright 2009 Nicolas Connault
339 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
340 * @since Moodle 2.0
341 */
342class html_select_optgroup extends moodle_html_component {
d9c8f425 343 /**
beb56299 344 * @var string $text The display value of the optgroup
d9c8f425 345 */
beb56299 346 public $text;
d9c8f425 347 /**
beb56299 348 * @var array $options An array of html_select_option objects
d9c8f425 349 */
beb56299 350 public $options = array();
351
352 public function prepare() {
353 if (empty($this->text)) {
354 throw new coding_exception('html_select_optgroup requires a $text value.');
355 }
356 if (empty($this->options)) {
357 throw new coding_exception('html_select_optgroup requires at least one html_select_option object');
358 }
359 parent::prepare();
360 }
361}
362
363/**
364 * This class represents an input field
365 *
366 * @copyright 2009 Nicolas Connault
367 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
368 * @since Moodle 2.0
369 */
370class html_field extends moodle_html_component {
d9c8f425 371 /**
beb56299 372 * @var string $name The name attribute of the field
d9c8f425 373 */
beb56299 374 public $name;
d9c8f425 375 /**
beb56299 376 * @var string $value The value attribute of the field
d9c8f425 377 */
beb56299 378 public $value;
d9c8f425 379 /**
beb56299 380 * @var string $type The type attribute of the field (text, submit, checkbox etc)
d9c8f425 381 */
beb56299 382 public $type;
d9c8f425 383 /**
beb56299 384 * @var string $maxlength The maxlength attribute of the field (only applies to text type)
d9c8f425 385 */
beb56299 386 public $maxlength;
387 /**
388 * @var mixed $label The label for that component. String or html_label object
389 */
390 public $label;
391
392 public function __construct() {
393 $this->label = new html_label();
394 }
d9c8f425 395
396 /**
397 * @see moodle_html_component::prepare()
398 * @return void
399 */
400 public function prepare() {
beb56299 401 if (empty($this->style)) {
402 $this->style = 'width: 4em;';
d9c8f425 403 }
beb56299 404 if (empty($this->id)) {
405 $this->generate_id();
d9c8f425 406 }
d9c8f425 407 parent::prepare();
408 }
409
410 /**
beb56299 411 * Shortcut for creating a text input component.
412 * @param string $name The name of the text field
413 * @param string $value The value of the text field
414 * @param string $alt The info to be inserted in the alt tag
415 * @param int $maxlength Sets the maxlength attribute of the field. Not set by default
416 * @return html_field The field component
d9c8f425 417 */
beb56299 418 public static function make_text($name='unnamed', $value, $alt, $maxlength=0) {
419 $field = new html_field();
420 if (empty($alt)) {
421 $alt = get_string('textfield');
422 }
423 $field->type = 'text';
424 $field->name = $name;
425 $field->value = $value;
426 $field->alt = $alt;
427 $field->maxlength = $maxlength;
428 return $field;
d9c8f425 429 }
beb56299 430}
d9c8f425 431
beb56299 432/**
433 * Holds all the information required to render a <table> by
434 * {@see moodle_core_renderer::table()} or by an overridden version of that
435 * method in a subclass.
436 *
437 * Example of usage:
438 * $t = new html_table();
439 * ... // set various properties of the object $t as described below
440 * echo $OUTPUT->table($t);
441 *
442 * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
443 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
444 * @since Moodle 2.0
445 */
446class html_table extends moodle_html_component {
d9c8f425 447 /**
beb56299 448 * @var array of headings. The n-th array item is used as a heading of the n-th column.
449 *
450 * Example of usage:
451 * $t->head = array('Student', 'Grade');
452 */
453 public $head;
d9c8f425 454 /**
beb56299 455 * @var array can be used to make a heading span multiple columns
456 *
457 * Example of usage:
458 * $t->headspan = array(2,1);
459 *
460 * In this example, {@see html_table:$data} is supposed to have three columns. For the first two columns,
461 * the same heading is used. Therefore, {@see html_table::$head} should consist of two items.
d9c8f425 462 */
beb56299 463 public $headspan;
d9c8f425 464 /**
beb56299 465 * @var array of column alignments. The value is used as CSS 'text-align' property. Therefore, possible
466 * values are 'left', 'right', 'center' and 'justify'. Specify 'right' or 'left' from the perspective
467 * of a left-to-right (LTR) language. For RTL, the values are flipped automatically.
468 *
469 * Examples of usage:
470 * $t->align = array(null, 'right');
471 * or
472 * $t->align[1] = 'right';
473 *
d9c8f425 474 */
beb56299 475 public $align;
d9c8f425 476 /**
beb56299 477 * @var array of column sizes. The value is used as CSS 'size' property.
478 *
479 * Examples of usage:
480 * $t->size = array('50%', '50%');
481 * or
482 * $t->size[1] = '120px';
d9c8f425 483 */
beb56299 484 public $size;
d9c8f425 485 /**
beb56299 486 * @var array of wrapping information. The only possible value is 'nowrap' that sets the
487 * CSS property 'white-space' to the value 'nowrap' in the given column.
488 *
489 * Example of usage:
490 * $t->wrap = array(null, 'nowrap');
d9c8f425 491 */
beb56299 492 public $wrap;
d9c8f425 493 /**
beb56299 494 * @var array of arrays or html_table_row objects containing the data. Alternatively, if you have
495 * $head specified, the string 'hr' (for horizontal ruler) can be used
496 * instead of an array of cells data resulting in a divider rendered.
d9c8f425 497 *
beb56299 498 * Example of usage with array of arrays:
499 * $row1 = array('Harry Potter', '76 %');
500 * $row2 = array('Hermione Granger', '100 %');
501 * $t->data = array($row1, $row2);
d9c8f425 502 *
beb56299 503 * Example with array of html_table_row objects: (used for more fine-grained control)
504 * $cell1 = new html_table_cell();
505 * $cell1->text = 'Harry Potter';
506 * $cell1->colspan = 2;
507 * $row1 = new html_table_row();
508 * $row1->cells[] = $cell1;
509 * $cell2 = new html_table_cell();
510 * $cell2->text = 'Hermione Granger';
511 * $cell3 = new html_table_cell();
512 * $cell3->text = '100 %';
513 * $row2 = new html_table_row();
514 * $row2->cells = array($cell2, $cell3);
515 * $t->data = array($row1, $row2);
516 */
517 public $data;
518 /**
519 * @var string width of the table, percentage of the page preferred. Defaults to 80% of the page width.
520 * @deprecated since Moodle 2.0. Styling should be in the CSS.
521 */
522 public $width = null;
523 /**
524 * @var string alignment the whole table. Can be 'right', 'left' or 'center' (default).
525 * @deprecated since Moodle 2.0. Styling should be in the CSS.
526 */
527 public $tablealign = null;
528 /**
529 * @var int padding on each cell, in pixels
530 * @deprecated since Moodle 2.0. Styling should be in the CSS.
531 */
532 public $cellpadding = null;
533 /**
534 * @var int spacing between cells, in pixels
535 * @deprecated since Moodle 2.0. Styling should be in the CSS.
536 */
537 public $cellspacing = null;
538 /**
539 * @var array classes to add to particular rows, space-separated string.
540 * Classes 'r0' or 'r1' are added automatically for every odd or even row,
541 * respectively. Class 'lastrow' is added automatically for the last row
542 * in the table.
d9c8f425 543 *
beb56299 544 * Example of usage:
545 * $t->rowclasses[9] = 'tenth'
546 */
547 public $rowclasses;
548 /**
549 * @var array classes to add to every cell in a particular column,
550 * space-separated string. Class 'cell' is added automatically by the renderer.
551 * Classes 'c0' or 'c1' are added automatically for every odd or even column,
552 * respectively. Class 'lastcol' is added automatically for all last cells
553 * in a row.
d9c8f425 554 *
beb56299 555 * Example of usage:
556 * $t->colclasses = array(null, 'grade');
d9c8f425 557 */
beb56299 558 public $colclasses;
559 /**
560 * @var string description of the contents for screen readers.
561 */
562 public $summary;
563 /**
564 * @var bool true causes the contents of the heading cells to be rotated 90 degrees.
565 */
566 public $rotateheaders = false;
d9c8f425 567
568 /**
beb56299 569 * @see moodle_html_component::prepare()
570 * @return void
d9c8f425 571 */
beb56299 572 public function prepare() {
573 if (!empty($this->align)) {
574 foreach ($this->align as $key => $aa) {
575 if ($aa) {
576 $this->align[$key] = 'text-align:'. fix_align_rtl($aa) .';'; // Fix for RTL languages
577 } else {
578 $this->align[$key] = '';
579 }
580 }
d9c8f425 581 }
beb56299 582 if (!empty($this->size)) {
583 foreach ($this->size as $key => $ss) {
584 if ($ss) {
585 $this->size[$key] = 'width:'. $ss .';';
586 } else {
587 $this->size[$key] = '';
588 }
589 }
d9c8f425 590 }
beb56299 591 if (!empty($this->wrap)) {
592 foreach ($this->wrap as $key => $ww) {
593 if ($ww) {
594 $this->wrap[$key] = 'white-space:nowrap;';
595 } else {
596 $this->wrap[$key] = '';
597 }
598 }
d9c8f425 599 }
beb56299 600 if (!empty($this->head)) {
601 foreach ($this->head as $key => $val) {
602 if (!isset($this->align[$key])) {
603 $this->align[$key] = '';
604 }
605 if (!isset($this->size[$key])) {
606 $this->size[$key] = '';
607 }
608 if (!isset($this->wrap[$key])) {
609 $this->wrap[$key] = '';
d9c8f425 610 }
611
d9c8f425 612 }
beb56299 613 }
614 if (empty($this->classes)) { // must be done before align
615 $this->set_classes(array('generaltable'));
616 }
617 if (!empty($this->tablealign)) {
618 $this->add_class('boxalign' . $this->tablealign);
619 }
620 if (!empty($this->rotateheaders)) {
621 $this->add_class('rotateheaders');
d9c8f425 622 } else {
beb56299 623 $this->rotateheaders = false; // Makes life easier later.
624 }
625 parent::prepare();
626 }
627 /**
628 * @param string $name The name of the variable to set
629 * @param mixed $value The value to assign to the variable
630 * @return void
631 */
632 public function __set($name, $value) {
633 if ($name == 'rowclass') {
634 debugging('rowclass[] has been deprecated for html_table ' .
635 'and should be replaced with rowclasses[]. please fix the code.');
636 $this->rowclasses = $value;
637 } else {
638 parent::__set($name, $value);
639 }
640 }
641}
d9c8f425 642
beb56299 643/**
644 * Component representing a table row.
645 *
646 * @copyright 2009 Nicolas Connault
647 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
648 * @since Moodle 2.0
649 */
650class html_table_row extends moodle_html_component {
651 /**
652 * @var array $cells Array of html_table_cell objects
653 */
654 public $cells = array();
d9c8f425 655
beb56299 656 /**
657 * @see lib/moodle_html_component#prepare()
658 * @return void
659 */
660 public function prepare() {
661 parent::prepare();
662 }
663}
d9c8f425 664
beb56299 665/**
666 * Component representing a table cell.
667 *
668 * @copyright 2009 Nicolas Connault
669 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
670 * @since Moodle 2.0
671 */
672class html_table_cell extends moodle_html_component {
673 /**
674 * @var string $text The contents of the cell
675 */
676 public $text;
677 /**
678 * @var string $abbr Abbreviated version of the contents of the cell
679 */
680 public $abbr = '';
681 /**
682 * @var int $colspan Number of columns this cell should span
683 */
684 public $colspan = '';
685 /**
686 * @var int $rowspan Number of rows this cell should span
687 */
688 public $rowspan = '';
689 /**
690 * @var string $scope Defines a way to associate header cells and data cells in a table
691 */
692 public $scope = '';
d9c8f425 693
beb56299 694 /**
695 * @see lib/moodle_html_component#prepare()
696 * @return void
697 */
698 public function prepare() {
699 parent::prepare();
d9c8f425 700 }
701}
702
703/**
beb56299 704 * Component representing a XHTML link.
d9c8f425 705 *
706 * @copyright 2009 Nicolas Connault
707 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
708 * @since Moodle 2.0
709 */
beb56299 710class html_link extends moodle_html_component {
711 /**
712 * URL can be simple text or a moodle_url object
713 * @var mixed $url
714 */
715 public $url;
716
d9c8f425 717 /**
beb56299 718 * @var string $text The text that will appear between the link tags
d9c8f425 719 */
720 public $text;
d9c8f425 721
722 /**
beb56299 723 * @see lib/moodle_html_component#prepare()
d9c8f425 724 * @return void
725 */
726 public function prepare() {
beb56299 727 // We can't accept an empty text value
d9c8f425 728 if (empty($this->text)) {
beb56299 729 throw new coding_exception('A html_link must have a descriptive text value!');
d9c8f425 730 }
beb56299 731
d9c8f425 732 parent::prepare();
733 }
beb56299 734
735 /**
736 * Shortcut for creating a link component.
737 * @param mixed $url String or moodle_url
738 * @param string $text The text of the link
739 * @return html_link The link component
740 */
741 public function make($url, $text) {
742 $link = new html_link();
743 $link->url = $url;
744 $link->text = $text;
745 return $link;
746 }
d9c8f425 747}
748
749/**
beb56299 750 * Component representing a XHTML button (input of type 'button').
751 * The renderer will either output it as a button with an onclick event,
752 * or as a form with hidden inputs.
d9c8f425 753 *
754 * @copyright 2009 Nicolas Connault
755 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
756 * @since Moodle 2.0
757 */
beb56299 758class html_button extends moodle_html_component {
d9c8f425 759 /**
beb56299 760 * @var string $text
d9c8f425 761 */
762 public $text;
beb56299 763
d9c8f425 764 /**
beb56299 765 * @var boolean $disabled Whether or not this button is disabled
d9c8f425 766 */
beb56299 767 public $disabled = false;
d9c8f425 768
769 /**
beb56299 770 * @see lib/moodle_html_component#prepare()
d9c8f425 771 * @return void
772 */
773 public function prepare() {
beb56299 774 $this->add_class('singlebutton');
775
d9c8f425 776 if (empty($this->text)) {
beb56299 777 throw new coding_exception('A html_button must have a text value!');
d9c8f425 778 }
779
beb56299 780 if ($this->disabled) {
781 $this->disabled = 'disabled';
d9c8f425 782 }
783
784 parent::prepare();
785 }
d9c8f425 786}
787
788/**
beb56299 789 * Component representing an image.
d9c8f425 790 *
791 * @copyright 2009 Nicolas Connault
792 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
793 * @since Moodle 2.0
794 */
beb56299 795class html_image extends moodle_html_component {
d9c8f425 796 /**
beb56299 797 * @var string $alt A descriptive text
d9c8f425 798 */
beb56299 799 public $alt = HTML_ATTR_EMPTY;
d9c8f425 800 /**
beb56299 801 * @var string $src The path to the image being used
d9c8f425 802 */
beb56299 803 public $src;
d9c8f425 804
beb56299 805 /**
806 * @see lib/moodle_html_component#prepare()
807 * @return void
808 */
d9c8f425 809 public function prepare() {
beb56299 810 $this->add_class('image');
d9c8f425 811 parent::prepare();
812 }
813}
814
815/**
beb56299 816 * Component representing a textarea.
d9c8f425 817 *
818 * @copyright 2009 Nicolas Connault
819 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
820 * @since Moodle 2.0
821 */
beb56299 822class html_textarea extends moodle_html_component {
d9c8f425 823 /**
beb56299 824 * @param string $name Name to use for the textarea element.
d9c8f425 825 */
826 public $name;
827 /**
beb56299 828 * @param string $value Initial content to display in the textarea.
d9c8f425 829 */
830 public $value;
831 /**
beb56299 832 * @param int $rows Number of rows to display (minimum of 10 when $height is non-null)
d9c8f425 833 */
beb56299 834 public $rows;
d9c8f425 835 /**
beb56299 836 * @param int $cols Number of columns to display (minimum of 65 when $width is non-null)
d9c8f425 837 */
beb56299 838 public $cols;
d9c8f425 839 /**
beb56299 840 * @param bool $usehtmleditor Enables the use of the htmleditor for this field.
d9c8f425 841 */
beb56299 842 public $usehtmleditor;
d9c8f425 843
844 /**
beb56299 845 * @see lib/moodle_html_component#prepare()
d9c8f425 846 * @return void
847 */
848 public function prepare() {
beb56299 849 $this->add_class('form-textarea');
850
d9c8f425 851 if (empty($this->id)) {
beb56299 852 $this->id = "edit-$this->name";
d9c8f425 853 }
d9c8f425 854
beb56299 855 if ($this->usehtmleditor) {
856 editors_head_setup();
857 $editor = get_preferred_texteditor(FORMAT_HTML);
858 $editor->use_editor($this->id, array('legacy'=>true));
859 $this->value = htmlspecialchars($value);
d9c8f425 860 }
beb56299 861
862 parent::prepare();
d9c8f425 863 }
864}
865
866/**
beb56299 867 * Component representing a simple form wrapper. Its purpose is mainly to enclose
868 * a submit input with the appropriate action and hidden inputs.
d9c8f425 869 *
beb56299 870 * @copyright 2009 Nicolas Connault
d9c8f425 871 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
872 * @since Moodle 2.0
873 */
beb56299 874class html_form extends moodle_html_component {
d9c8f425 875 /**
beb56299 876 * @var string $method post or get
d9c8f425 877 */
beb56299 878 public $method = 'post';
d9c8f425 879 /**
beb56299 880 * If a string is given, it will be converted to a moodle_url during prepare()
881 * @var mixed $url A moodle_url including params or a string
d9c8f425 882 */
beb56299 883 public $url;
884 /**
885 * @var array $params Optional array of parameters. Ignored if $url instanceof moodle_url
886 */
887 public $params = array();
888 /**
889 * @var boolean $showbutton If true, the submit button will always be shown even if JavaScript is available
890 */
891 public $showbutton = false;
892 /**
893 * @var string $targetwindow The name of the target page to open the linked page in.
894 */
895 public $targetwindow = 'self';
896 /**
897 * @var html_button $button A submit button
898 */
899 public $button;
d9c8f425 900
901 /**
beb56299 902 * Constructor: sets up the other components in case they are needed
903 * @return void
d9c8f425 904 */
beb56299 905 public function __construct() {
906 static $yes;
907 $this->button = new html_button();
908 if (!isset($yes)) {
909 $yes = get_string('yes');
910 $this->button->text = $yes;
911 }
912 }
d9c8f425 913
914 /**
beb56299 915 * @see lib/moodle_html_component#prepare()
916 * @return void
d9c8f425 917 */
beb56299 918 public function prepare() {
919
920 if (empty($this->url)) {
921 throw new coding_exception('A html_form must have a $url value (string or moodle_url).');
922 }
923
924 if (!($this->url instanceof moodle_url)) {
925 $this->url = new moodle_url($this->url, $this->params);
926 }
927
928 if ($this->method == 'post') {
929 $this->url->param('sesskey', sesskey());
930 }
931
932 parent::prepare();
933 }
934}
935
936/**
937 * Component representing a list.
938 *
939 * The advantage of using this object instead of a flat array is that you can load it
940 * with metadata (CSS classes, event handlers etc.) which can be used by the renderers.
941 *
942 * @copyright 2009 Nicolas Connault
943 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
944 * @since Moodle 2.0
945 */
946class html_list extends moodle_html_component {
d9c8f425 947
948 /**
beb56299 949 * @var array $items An array of html_list_item or html_list objects
d9c8f425 950 */
beb56299 951 public $items = array();
d9c8f425 952
953 /**
beb56299 954 * @var string $type The type of list (ordered|unordered), definition type not yet supported
d9c8f425 955 */
beb56299 956 public $type = 'unordered';
d9c8f425 957
958 /**
beb56299 959 * @see lib/moodle_html_component#prepare()
960 * @return void
d9c8f425 961 */
beb56299 962 public function prepare() {
963 parent::prepare();
964 }
d9c8f425 965
966 /**
beb56299 967 * This function takes a nested array of data and maps it into this list's $items array
968 * as proper html_list_item and html_list objects, with appropriate metadata.
969 *
970 * @param array $tree A nested array (array keys are ignored);
971 * @param int $row Used in identifying the iteration level and in ul classes
972 * @return void
d9c8f425 973 */
beb56299 974 public function load_data($tree, $level=0) {
d9c8f425 975
beb56299 976 $this->add_class("list-$level");
d9c8f425 977
beb56299 978 foreach ($tree as $key => $element) {
979 if (is_array($element)) {
980 $newhtmllist = new html_list();
981 $newhtmllist->load_data($element, $level + 1);
982 $this->items[] = $newhtmllist;
983 } else {
984 $listitem = new html_list_item();
985 $listitem->value = $element;
986 $listitem->add_class("list-item-$level-$key");
987 $this->items[] = $listitem;
988 }
989 }
990 }
d9c8f425 991
992 /**
beb56299 993 * Adds a html_list_item or html_list to this list.
994 * If the param is a string, a html_list_item will be added.
995 * @param mixed $item String, html_list or html_list_item object
d9c8f425 996 * @return void
997 */
beb56299 998 public function add_item($item) {
999 if ($item instanceof html_list_item || $item instanceof html_list) {
1000 $this->items[] = $item;
1001 } else {
1002 $listitem = new html_list_item();
1003 $listitem->value = $item;
1004 $this->items[] = $item;
d9c8f425 1005 }
d9c8f425 1006 }
1007}
1008
d9c8f425 1009/**
beb56299 1010 * Component representing a list item.
d9c8f425 1011 *
beb56299 1012 * @copyright 2009 Nicolas Connault
d9c8f425 1013 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1014 * @since Moodle 2.0
1015 */
beb56299 1016class html_list_item extends moodle_html_component {
d9c8f425 1017 /**
beb56299 1018 * @var string $value The value of the list item
d9c8f425 1019 */
beb56299 1020 public $value;
1021
d9c8f425 1022 /**
beb56299 1023 * @see lib/moodle_html_component#prepare()
1024 * @return void
d9c8f425 1025 */
beb56299 1026 public function prepare() {
1027 parent::prepare();
1028 }
d9c8f425 1029}
1030
beb56299 1031/// Complex components aggregating simpler components
d9c8f425 1032
1033/**
beb56299 1034 * This class hold all the information required to describe a <select> menu that
1035 * will be printed by {@link moodle_core_renderer::select()}. (Or by an overridden
1036 * version of that method in a subclass.)
d9c8f425 1037 *
beb56299 1038 * This component can also hold enough metadata to be used as a popup form. It just
1039 * needs a bit more setting up than for a simple menu. See the shortcut methods for
1040 * developer-friendly usage.
d9c8f425 1041 *
beb56299 1042 * All the fields that are not set by the constructor have sensible defaults, so
1043 * you only need to set the properties where you want non-default behaviour.
1044 *
1045 * @copyright 2009 Tim Hunt
d9c8f425 1046 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1047 * @since Moodle 2.0
1048 */
beb56299 1049class moodle_select extends moodle_html_component {
d9c8f425 1050 /**
beb56299 1051 * The moodle_select object parses an array of options into component objects
1052 * @see nested attribute
1053 * @var mixed $options the choices to show in the menu. An array $value => $display, of html_select_option or of html_select_optgroup objects.
d9c8f425 1054 */
beb56299 1055 public $options;
d9c8f425 1056 /**
beb56299 1057 * @var string $name the name of this form control. That is, the name of the GET/POST
1058 * variable that will be set if this select is submitted as part of a form.
d9c8f425 1059 */
beb56299 1060 public $name;
d9c8f425 1061 /**
beb56299 1062 * @var mixed $label The label for that component. String or html_label object
d9c8f425 1063 */
beb56299 1064 public $label;
d9c8f425 1065 /**
beb56299 1066 * @var string $selectedvalue the option to select initially. Should match one
1067 * of the $options array keys. Default none.
d9c8f425 1068 */
beb56299 1069 public $selectedvalue;
d9c8f425 1070 /**
beb56299 1071 * Defaults to get_string('choosedots').
1072 * Set this to '' if you do not want a 'nothing is selected' option.
1073 * This is ignored if the rendertype is 'radio' or 'checkbox'
1074 * @var string The label for the 'nothing is selected' option.
d9c8f425 1075 */
beb56299 1076 public $nothinglabel = null;
d9c8f425 1077 /**
beb56299 1078 * @var string The value returned by the 'nothing is selected' option. Defaults to 0.
d9c8f425 1079 */
beb56299 1080 public $nothingvalue = 0;
d9c8f425 1081 /**
beb56299 1082 * @var boolean set this to true if you want the control to appear disabled.
d9c8f425 1083 */
beb56299 1084 public $disabled = false;
d9c8f425 1085 /**
beb56299 1086 * @var integer if non-zero, sets the tabindex attribute on the <select> element. Default 0.
d9c8f425 1087 */
beb56299 1088 public $tabindex = 0;
d9c8f425 1089 /**
beb56299 1090 * @var mixed Defaults to false, which means display the select as a dropdown menu.
1091 * If true, display this select as a list box whose size is chosen automatically.
1092 * If an integer, display as list box of that size.
d9c8f425 1093 */
beb56299 1094 public $listbox = false;
d9c8f425 1095 /**
beb56299 1096 * @var integer if you are using $listbox === true to get an automatically
1097 * sized list box, the size of the list box will be the number of options,
1098 * or this number, whichever is smaller.
d9c8f425 1099 */
beb56299 1100 public $maxautosize = 10;
d9c8f425 1101 /**
beb56299 1102 * @var boolean if true, allow multiple selection. Only used if $listbox is true, or if
1103 * the select is to be output as checkboxes.
d9c8f425 1104 */
beb56299 1105 public $multiple = false;
d9c8f425 1106 /**
beb56299 1107 * Another way to use nested menu is to prefix optgroup labels with -- and end the optgroup with --
1108 * Leave this setting to false if you are using the latter method.
1109 * @var boolean $nested if true, uses $options' keys as option headings (optgroup)
d9c8f425 1110 */
beb56299 1111 public $nested = false;
d9c8f425 1112 /**
beb56299 1113 * @var html_form $form An optional html_form component
d9c8f425 1114 */
beb56299 1115 public $form;
d9c8f425 1116 /**
beb56299 1117 * @var moodle_help_icon $form An optional moodle_help_icon component
d9c8f425 1118 */
beb56299 1119 public $helpicon;
1120 /**
1121 * @var boolean $rendertype How the select element should be rendered: menu or radio (checkbox is just radio + multiple)
1122 */
1123 public $rendertype = 'menu';
d9c8f425 1124
1125 /**
1126 * @see moodle_html_component::prepare()
1127 * @return void
1128 */
1129 public function prepare() {
beb56299 1130 global $CFG;
d9c8f425 1131
beb56299 1132 // name may contain [], which would make an invalid id. e.g. numeric question type editing form, assignment quickgrading
1133 if (empty($this->id)) {
1134 $this->id = 'menu' . str_replace(array('[', ']'), '', $this->name);
d9c8f425 1135 }
beb56299 1136
1137 if (empty($this->classes)) {
1138 $this->set_classes(array('menu' . str_replace(array('[', ']'), '', $this->name)));
d9c8f425 1139 }
beb56299 1140
1141 if (is_null($this->nothinglabel)) {
1142 $this->nothinglabel = get_string('choosedots');
d9c8f425 1143 }
beb56299 1144
1145 if (!empty($this->label) && !($this->label instanceof html_label)) {
1146 $label = new html_label();
1147 $label->text = $this->label;
1148 $label->for = $this->name;
1149 $this->label = $label;
d9c8f425 1150 }
beb56299 1151
1152 $this->add_class('select');
1153
1154 $this->initialise_options();
d9c8f425 1155 parent::prepare();
1156 }
beb56299 1157
d9c8f425 1158 /**
beb56299 1159 * This is a shortcut for making a simple select menu. It lets you specify
1160 * the options, name and selected option in one line of code.
1161 * @param array $options used to initialise {@link $options}.
1162 * @param string $name used to initialise {@link $name}.
1163 * @param string $selected used to initialise {@link $selected}.
1164 * @return moodle_select A moodle_select object with the three common fields initialised.
d9c8f425 1165 */
beb56299 1166 public static function make($options, $name, $selected = '') {
1167 $menu = new moodle_select();
1168 $menu->options = $options;
1169 $menu->name = $name;
1170 $menu->selectedvalue = $selected;
1171 return $menu;
d9c8f425 1172 }
d9c8f425 1173
d9c8f425 1174 /**
beb56299 1175 * This is a shortcut for making a yes/no select menu.
1176 * @param string $name used to initialise {@link $name}.
1177 * @param string $selected used to initialise {@link $selected}.
1178 * @return moodle_select A menu initialised with yes/no options.
d9c8f425 1179 */
beb56299 1180 public static function make_yes_no($name, $selected) {
1181 return self::make(array(0 => get_string('no'), 1 => get_string('yes')), $name, $selected);
1182 }
d9c8f425 1183
1184 /**
beb56299 1185 * This is a shortcut for making an hour selector menu.
1186 * @param string $type The type of selector (years, months, days, hours, minutes)
1187 * @param string $name fieldname
1188 * @param int $currenttime A default timestamp in GMT
1189 * @param int $step minute spacing
1190 * @return moodle_select A menu initialised with hour options.
d9c8f425 1191 */
beb56299 1192 public static function make_time_selector($type, $name, $currenttime=0, $step=5) {
1193
1194 if (!$currenttime) {
1195 $currenttime = time();
1196 }
1197 $currentdate = usergetdate($currenttime);
1198 $userdatetype = $type;
1199
1200 switch ($type) {
1201 case 'years':
1202 for ($i=1970; $i<=2020; $i++) {
1203 $timeunits[$i] = $i;
1204 }
1205 $userdatetype = 'year';
1206 break;
1207 case 'months':
1208 for ($i=1; $i<=12; $i++) {
1209 $timeunits[$i] = userdate(gmmktime(12,0,0,$i,15,2000), "%B");
1210 }
1211 $userdatetype = 'month';
1212 break;
1213 case 'days':
1214 for ($i=1; $i<=31; $i++) {
1215 $timeunits[$i] = $i;
1216 }
1217 $userdatetype = 'mday';
1218 break;
1219 case 'hours':
1220 for ($i=0; $i<=23; $i++) {
1221 $timeunits[$i] = sprintf("%02d",$i);
1222 }
1223 break;
1224 case 'minutes':
1225 if ($step != 1) {
1226 $currentdate['minutes'] = ceil($currentdate['minutes']/$step)*$step;
1227 }
1228
1229 for ($i=0; $i<=59; $i+=$step) {
1230 $timeunits[$i] = sprintf("%02d",$i);
1231 }
1232 break;
1233 default:
1234 throw new coding_exception("Time type $type is not supported by moodle_select::make_time_selector().");
1235 }
1236
1237 $timerselector = self::make($timeunits, $name, $currentdate[$userdatetype]);
1238 $timerselector->label = new html_label();
1239 $timerselector->label->text = get_string(substr($type, -1), 'form');
1240 $timerselector->label->for = "menu$timerselector->name";
1241 $timerselector->label->add_class('accesshide');
1242 $timerselector->nothinglabel = '';
1243
1244 return $timerselector;
d9c8f425 1245 }
d9c8f425 1246
d9c8f425 1247 /**
beb56299 1248 * Given an associative array of type => fieldname and an optional timestamp,
1249 * returns an array of moodle_select components representing date/time selectors.
1250 * @param array $selectors Arrays of type => fieldname. Selectors will be returned in the order of the types given
1251 * @param int $currenttime A UNIX timestamp
1252 * @param int $step minute spacing
1253 * @return array Instantiated date/time selectors
d9c8f425 1254 */
beb56299 1255 public function make_time_selectors($selectors, $currenttime=0, $step=5) {
1256 $selects = array();
1257 foreach ($selectors as $type => $name) {
1258 $selects[] = moodle_select::make_time_selector($type, $name, $currenttime, $step);
1259 }
1260 return $selects;
1261 }
1262
d9c8f425 1263 /**
beb56299 1264 * This is a shortcut for making a select popup form.
1265 * @param mixed $baseurl The target URL, string or moodle_url
1266 * @param string $name The variable which this select's options are changing in the URL
1267 * @param array $options A list of value-label pairs for the popup list
1268 * @param string $formid id for the control. Must be unique on the page. Used in the HTML.
1269 * @param string $selected The option that is initially selected
1270 * @return moodle_select A menu initialised as a popup form.
d9c8f425 1271 */
beb56299 1272 public function make_popup_form($baseurl, $name, $options, $formid, $selected=null) {
1273 global $CFG;
1274
1275 $selectedurl = null;
1276
1277 if (!($baseurl instanceof moodle_url)) {
1278 $baseurl = new moodle_url($baseurl);
1279 }
1280
1281 if (!empty($selected)) {
1282 $selectedurl = $baseurl->out(false, array($name => $selected), false);
1283 }
1284
1285 if (!($baseurl instanceof moodle_url)) {
1286 $baseurl = new moodle_url($baseurl);
1287 }
1288
1289 // Replace real value by formatted URLs
1290 foreach ($options as $value => $label) {
1291 $options[$baseurl->out(false, array($name => $value), false)] = $label;
1292 unset($options[$value]);
1293 }
d9c8f425 1294
beb56299 1295 $select = self::make($options, 'jump', $selectedurl);
d9c8f425 1296
beb56299 1297 $select->form = new html_form();
1298 $select->form->id = $formid;
1299 $select->form->method = 'get';
1300 $select->form->add_class('popupform');
1301 $select->form->url = new moodle_url($CFG->wwwroot . '/course/jumpto.php', array('sesskey' => sesskey()));
1302 $select->form->button->text = get_string('go');
d9c8f425 1303
beb56299 1304 $select->id = $formid . '_jump';
d9c8f425 1305
beb56299 1306 $select->add_action('change', 'submit_form_by_id', array('id' => $formid, 'selectid' => $select->id));
d9c8f425 1307
beb56299 1308 return $select;
d9c8f425 1309 }
1310
1311 /**
beb56299 1312 * Override the URLs of the default popup_form, which only supports one base URL
1313 * @param array $options value=>label pairs representing select options
1314 * @return void
d9c8f425 1315 */
beb56299 1316 public function override_option_values($options) {
1317 global $PAGE;
d9c8f425 1318
beb56299 1319 $this->initialise_options();
1320
1321 reset($options);
1322
1323 foreach ($this->options as $optkey => $optgroup) {
1324 if ($optgroup instanceof html_select_optgroup) {
1325 foreach ($optgroup->options as $key => $option) {
1326 next($options);
1327 $this->options[$optkey]->options[$key]->value = key($options);
1328
1329 $optionurl = new moodle_url(key($options));
1330
1331 if ($optionurl->compare($PAGE->url, URL_MATCH_PARAMS)) {
1332 $this->options[$optkey]->options[$key]->selected = 'selected';
1333 }
1334 }
1335 next($options);
1336 } else if ($optgroup instanceof html_select_option) {
1337 next($options);
1338 $this->options[$optkey]->value = key($options);
1339 $optionurl = new moodle_url(key($options));
1340
1341 if ($optionurl->compare($PAGE->url, URL_MATCH_PARAMS)) {
1342 $this->options[$optkey]->selected = 'selected';
1343 }
1344 }
1345 }
1346 }
d9c8f425 1347
1348 /**
beb56299 1349 * Adds a help icon next to the select menu.
1350 *
1351 * This can be used in two ways:
1352 *
1353 * <pre>
1354 * $select->set_help_icon($page, $text, $linktext);
1355 * // OR
1356 * $helpicon = new moodle_help_icon();
1357 * $helpicon->page = $page;
1358 * $helpicon->text = $text;
1359 * $helpicon->linktext = $linktext;
1360 * $select->set_help_icon($helpicon);
1361 * </pre>
1362 *
1363 * Use the second form when you need to add additional HTML attributes
1364 * to the label and/or JS actions.
1365 *
1366 * @param mixed $page Either the keyword that defines a help page or a moodle_help_icon object
1367 * @param text $text The text of the help icon
1368 * @param boolean $linktext Whether or not to show text next to the icon
d9c8f425 1369 * @return void
1370 */
beb56299 1371 public function set_help_icon($page, $text, $linktext=false) {
1372 if ($page instanceof moodle_help_icon) {
1373 $this->helpicon = $page;
1374 } else if (!empty($page)) {
1375 $this->helpicon = new moodle_help_icon();
1376 $this->helpicon->page = $page;
1377 $this->helpicon->text = $text;
1378 $this->helpicon->linktext = $linktext;
1379 }
d9c8f425 1380 }
1381
1382 /**
beb56299 1383 * Parses the $options array and instantiates html_select_option objects in
1384 * the place of the original value => label pairs. This is useful for when you
1385 * need to setup extra html attributes and actions on individual options before
1386 * the component is sent to the renderer
1387 * @return void;
d9c8f425 1388 */
beb56299 1389 public function initialise_options() {
1390 // If options are already instantiated objects, stop here
1391 $firstoption = reset($this->options);
1392 if ($firstoption instanceof html_select_option || $firstoption instanceof html_select_optgroup) {
1393 return;
1394 }
d9c8f425 1395
beb56299 1396 if ($this->rendertype == 'radio' && $this->multiple) {
1397 $this->rendertype = 'checkbox';
d9c8f425 1398 }
1399
beb56299 1400 // If nested is on, or if radio/checkbox rendertype is set, remove the default Choose option
1401 if ($this->nested || $this->rendertype == 'radio' || $this->rendertype == 'checkbox') {
1402 $this->nothinglabel = '';
d9c8f425 1403 }
1404
beb56299 1405 $options = $this->options;
d9c8f425 1406
beb56299 1407 $this->options = array();
d9c8f425 1408
beb56299 1409 if ($this->nested && $this->rendertype != 'menu') {
1410 throw new coding_exception('moodle_select cannot render nested options as radio buttons or checkboxes.');
1411 } else if ($this->nested) {
1412 foreach ($options as $section => $values) {
1413 $optgroup = new html_select_optgroup();
1414 $optgroup->text = $section;
d9c8f425 1415
beb56299 1416 foreach ($values as $value => $display) {
1417 $option = new html_select_option();
1418 $option->value = s($value);
1419 $option->text = $display;
1420 if ($display === '') {
1421 $option->text = $value;
1422 }
1423
1424 if ((string) $value == (string) $this->selectedvalue ||
1425 (is_array($this->selectedvalue) && in_array($value, $this->selectedvalue))) {
1426 $option->selected = 'selected';
1427 }
1428
1429 $optgroup->options[] = $option;
1430 }
1431
1432 $this->options[] = $optgroup;
1433 }
1434 } else {
1435 $inoptgroup = false;
1436 $optgroup = false;
1437
1438 foreach ($options as $value => $display) {
1439 if ($display == '--') { /// we are ending previous optgroup
1440 // $this->options[] = $optgroup;
1441 $inoptgroup = false;
1442 continue;
1443 } else if (substr($display,0,2) == '--') { /// we are starting a new optgroup
1444 if (!empty($optgroup->options)) {
1445 $this->options[] = $optgroup;
1446 }
1447
1448 $optgroup = new html_select_optgroup();
1449 $optgroup->text = substr($display,2); // stripping the --
1450
1451 $inoptgroup = true; /// everything following will be in an optgroup
1452 continue;
1453
1454 } else {
1455 // Add $nothing option if there are not optgroups
1456 if ($this->nothinglabel && empty($this->options[0]) && !$inoptgroup) {
1457 $nothingoption = new html_select_option();
1458 $nothingoption->value = 0;
1459 if (!empty($this->nothingvalue)) {
1460 $nothingoption->value = $this->nothingvalue;
1461 }
1462 $nothingoption->text = $this->nothinglabel;
1463 $this->options = array($nothingoption) + $this->options;
1464 }
1465
1466 $option = new html_select_option();
1467 $option->text = $display;
d9c8f425 1468
beb56299 1469 if ($display === '') {
1470 $option->text = $value;
1471 }
d9c8f425 1472
beb56299 1473 if ((string) $value == (string) $this->selectedvalue ||
1474 (is_array($this->selectedvalue) && in_array($value, $this->selectedvalue))) {
1475 $option->selected = 'selected';
1476 }
d9c8f425 1477
beb56299 1478 $option->value = s($value);
d9c8f425 1479
beb56299 1480 if ($inoptgroup) {
1481 $optgroup->options[] = $option;
1482 } else {
1483 $this->options[] = $option;
1484 }
1485 }
d9c8f425 1486 }
d9c8f425 1487
beb56299 1488 if ($optgroup) {
1489 $this->options[] = $optgroup;
d9c8f425 1490 }
d9c8f425 1491 }
d9c8f425 1492 }
1493}
1494
d9c8f425 1495/**
beb56299 1496 * Component representing a paging bar.
d9c8f425 1497 *
1498 * @copyright 2009 Nicolas Connault
1499 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1500 * @since Moodle 2.0
1501 */
beb56299 1502class moodle_paging_bar extends moodle_html_component {
d9c8f425 1503 /**
beb56299 1504 * @var int $maxdisplay The maximum number of pagelinks to display
d9c8f425 1505 */
beb56299 1506 public $maxdisplay = 18;
d9c8f425 1507 /**
beb56299 1508 * @var int $totalcount post or get
d9c8f425 1509 */
beb56299 1510 public $totalcount;
d9c8f425 1511 /**
beb56299 1512 * @var int $page The page you are currently viewing
d9c8f425 1513 */
beb56299 1514 public $page = 0;
d9c8f425 1515 /**
beb56299 1516 * @var int $perpage The number of entries that should be shown per page
d9c8f425 1517 */
beb56299 1518 public $perpage;
d9c8f425 1519 /**
beb56299 1520 * @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.
1521 * If this is a moodle_url object then the pagevar param will be replaced by the page no, for each page.
d9c8f425 1522 */
beb56299 1523 public $baseurl;
d9c8f425 1524 /**
beb56299 1525 * @var string $pagevar This is the variable name that you use for the page number in your code (ie. 'tablepage', 'blogpage', etc)
d9c8f425 1526 */
beb56299 1527 public $pagevar = 'page';
d9c8f425 1528 /**
beb56299 1529 * @var bool $nocurr do not display the current page as a link
d9c8f425 1530 */
beb56299 1531 public $nocurr;
1532 /**
1533 * @var html_link $previouslink A HTML link representing the "previous" page
1534 */
1535 public $previouslink = null;
1536 /**
1537 * @var html_link $nextlink A HTML link representing the "next" page
1538 */
1539 public $nextlink = null;
1540 /**
1541 * @var html_link $firstlink A HTML link representing the first page
1542 */
1543 public $firstlink = null;
1544 /**
1545 * @var html_link $lastlink A HTML link representing the last page
1546 */
1547 public $lastlink = null;
1548 /**
1549 * @var array $pagelinks An array of html_links. One of them is just a string: the current page
1550 */
1551 public $pagelinks = array();
d9c8f425 1552
1553 /**
1554 * @see lib/moodle_html_component#prepare()
1555 * @return void
1556 */
1557 public function prepare() {
beb56299 1558 if (empty($this->totalcount)) {
1559 throw new coding_exception('moodle_paging_bar requires a totalcount value.');
1560 }
1561 if (!isset($this->page) || is_null($this->page)) {
1562 throw new coding_exception('moodle_paging_bar requires a page value.');
1563 }
1564 if (empty($this->perpage)) {
1565 throw new coding_exception('moodle_paging_bar requires a perpage value.');
1566 }
1567 if (empty($this->baseurl)) {
1568 throw new coding_exception('moodle_paging_bar requires a baseurl value.');
1569 }
1570 if (!($this->baseurl instanceof moodle_url)) {
1571 $this->baseurl = new moodle_url($this->baseurl);
1572 }
d9c8f425 1573
beb56299 1574 if ($this->totalcount > $this->perpage) {
1575 $pagenum = $this->page - 1;
d9c8f425 1576
beb56299 1577 if ($this->page > 0) {
1578 $this->previouslink = new html_link();
1579 $this->previouslink->add_class('previous');
1580 $this->previouslink->url = clone($this->baseurl);
1581 $this->previouslink->url->param($this->pagevar, $pagenum);
1582 $this->previouslink->text = get_string('previous');
1583 }
d9c8f425 1584
beb56299 1585 if ($this->perpage > 0) {
1586 $lastpage = ceil($this->totalcount / $this->perpage);
1587 } else {
1588 $lastpage = 1;
1589 }
1590
1591 if ($this->page > 15) {
1592 $startpage = $this->page - 10;
1593
1594 $this->firstlink = new html_link();
1595 $this->firstlink->url = clone($this->baseurl);
1596 $this->firstlink->url->param($this->pagevar, 0);
1597 $this->firstlink->text = 1;
1598 $this->firstlink->add_class('first');
1599 } else {
1600 $startpage = 0;
1601 }
1602
1603 $currpage = $startpage;
1604 $displaycount = $displaypage = 0;
1605
1606 while ($displaycount < $this->maxdisplay and $currpage < $lastpage) {
1607 $displaypage = $currpage + 1;
1608
1609 if ($this->page == $currpage && empty($this->nocurr)) {
1610 $this->pagelinks[] = $displaypage;
1611 } else {
1612 $pagelink = new html_link();
1613 $pagelink->url = clone($this->baseurl);
1614 $pagelink->url->param($this->pagevar, $currpage);
1615 $pagelink->text = $displaypage;
1616 $this->pagelinks[] = $pagelink;
1617 }
1618
1619 $displaycount++;
1620 $currpage++;
1621 }
1622
1623 if ($currpage < $lastpage) {
1624 $lastpageactual = $lastpage - 1;
1625 $this->lastlink = new html_link();
1626 $this->lastlink->url = clone($this->baseurl);
1627 $this->lastlink->url->param($this->pagevar, $lastpageactual);
1628 $this->lastlink->text = $lastpage;
1629 $this->lastlink->add_class('last');
1630 }
1631
1632 $pagenum = $this->page + 1;
1633
1634 if ($pagenum != $displaypage) {
1635 $this->nextlink = new html_link();
1636 $this->nextlink->url = clone($this->baseurl);
1637 $this->nextlink->url->param($this->pagevar, $pagenum);
1638 $this->nextlink->text = get_string('next');
1639 $this->nextlink->add_class('next');
1640 }
d9c8f425 1641 }
1642 }
d9c8f425 1643
1644 /**
beb56299 1645 * Shortcut for initialising a moodle_paging_bar with only the required params.
1646 *
1647 * @param int $totalcount Thetotal number of entries available to be paged through
1648 * @param int $page The page you are currently viewing
1649 * @param int $perpage The number of entries that should be shown per page
1650 * @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.
1651 * If this is a moodle_url object then the pagevar param will be replaced by the page no, for each page.
d9c8f425 1652 */
beb56299 1653 public function make($totalcount, $page, $perpage, $baseurl) {
1654 $pagingbar = new moodle_paging_bar();
1655 $pagingbar->totalcount = $totalcount;
1656 $pagingbar->page = $page;
1657 $pagingbar->perpage = $perpage;
1658 $pagingbar->baseurl = $baseurl;
1659 return $pagingbar;
d9c8f425 1660 }
1661}
1662
1663/**
1664 * Component representing a user picture.
1665 *
1666 * @copyright 2009 Nicolas Connault
1667 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1668 * @since Moodle 2.0
1669 */
beb56299 1670class moodle_user_picture extends moodle_html_component {
d9c8f425 1671 /**
1672 * @var mixed $user A userid or a user object with at least fields id, picture, imagealrt, firstname and lastname set.
1673 */
1674 public $user;
1675 /**
1676 * @var int $courseid The course id. Used when constructing the link to the user's profile.
1677 */
1678 public $courseid;
1679 /**
1680 * @var html_image $image A custom image used as the user picture.
1681 */
1682 public $image;
1683 /**
1684 * @var mixed $url False: picture not enclosed in a link. True: default link. moodle_url: custom link.
1685 */
1686 public $url;
1687 /**
1688 * @var int $size Size in pixels. Special values are (true/1 = 100px) and (false/0 = 35px) for backward compatibility
1689 */
1690 public $size;
1691 /**
1692 * @var boolean $alttext add non-blank alt-text to the image. (Default true, set to false for purely
1693 */
1694 public $alttext = true;
1695 /**
1696 * @var boolean $popup Whether or not to open the link in a popup window
1697 */
1698 public $popup = false;
1699
1700 /**
1701 * Constructor: sets up the other components in case they are needed
1702 * @return void
1703 */
1704 public function __construct() {
1705 $this->image = new html_image();
1706 }
1707
1708 /**
1709 * @see lib/moodle_html_component#prepare()
1710 * @return void
1711 */
1712 public function prepare() {
1713 global $CFG, $DB, $OUTPUT;
1714
1715 if (empty($this->user)) {
beb56299 1716 throw new coding_exception('A moodle_user_picture object must have a $user object before being rendered.');
d9c8f425 1717 }
1718
1719 if (empty($this->courseid)) {
beb56299 1720 throw new coding_exception('A moodle_user_picture object must have a courseid value before being rendered.');
d9c8f425 1721 }
1722
1723 if (!($this->image instanceof html_image)) {
beb56299 1724 debugging('moodle_user_picture::image must be an instance of html_image', DEBUG_DEVELOPER);
d9c8f425 1725 }
1726
1727 $needrec = false;
1728 // only touch the DB if we are missing data...
1729 if (is_object($this->user)) {
1730 // Note - both picture and imagealt _can_ be empty
1731 // what we are trying to see here is if they have been fetched
1732 // from the DB. We should use isset() _except_ that some installs
1733 // have those fields as nullable, and isset() will return false
1734 // on null. The only safe thing is to ask array_key_exists()
1735 // which works on objects. property_exists() isn't quite
1736 // what we want here...
1737 if (! (array_key_exists('picture', $this->user)
1738 && ($this->alttext && array_key_exists('imagealt', $this->user)
1739 || (isset($this->user->firstname) && isset($this->user->lastname)))) ) {
1740 $needrec = true;
1741 $this->user = $this->user->id;
1742 }
1743 } else {
1744 if ($this->alttext) {
1745 // we need firstname, lastname, imagealt, can't escape...
1746 $needrec = true;
1747 } else {
1748 $userobj = new StdClass; // fake it to save DB traffic
1749 $userobj->id = $this->user;
1750 $userobj->picture = $this->image->src;
1751 $this->user = clone($userobj);
1752 unset($userobj);
1753 }
1754 }
1755 if ($needrec) {
1756 $this->user = $DB->get_record('user', array('id' => $this->user), 'id,firstname,lastname,imagealt');
1757 }
1758
1759 if ($this->url === true) {
1760 $this->url = new moodle_url('/user/view.php', array('id' => $this->user->id, 'course' => $this->courseid));
1761 }
1762
1763 if (!empty($this->url) && $this->popup) {
1764 $this->add_action(new popup_action('click', $this->url));
1765 }
1766
1767 if (empty($this->size)) {
1768 $file = 'f2';
1769 $this->size = 35;
1770 } else if ($this->size === true or $this->size == 1) {
1771 $file = 'f1';
1772 $this->size = 100;
1773 } else if ($this->size >= 50) {
1774 $file = 'f1';
1775 } else {
1776 $file = 'f2';
1777 }
1778
1779 if (!empty($this->size)) {
1780 $this->image->width = $this->size;
1781 $this->image->height = $this->size;
1782 }
1783
1784 $this->add_class('userpicture');
1785
1786 if (empty($this->image->src) && !empty($this->user->picture)) {
1787 $this->image->src = $this->user->picture;
1788 }
1789
1790 if (!empty($this->image->src)) {
1791 require_once($CFG->libdir.'/filelib.php');
1792 $this->image->src = new moodle_url(get_file_url($this->user->id.'/'.$file.'.jpg', null, 'user'));
1793 } else { // Print default user pictures (use theme version if available)
1794 $this->add_class('defaultuserpic');
1795 $this->image->src = $OUTPUT->old_icon_url('u/' . $file);
1796 }
1797
1798 if ($this->alttext) {
1799 if (!empty($this->user->imagealt)) {
1800 $this->image->alt = $this->user->imagealt;
1801 } else {
1802 $this->image->alt = get_string('pictureof','',fullname($this->user));
1803 }
1804 }
1805
1806 parent::prepare();
1807 }
1808}
1809
1810/**
beb56299 1811 * Component representing a help icon.
d9c8f425 1812 *
1813 * @copyright 2009 Nicolas Connault
1814 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1815 * @since Moodle 2.0
1816 */
beb56299 1817class moodle_help_icon extends moodle_html_component {
d9c8f425 1818 /**
beb56299 1819 * @var html_link $link A html_link object that will hold the URL info
d9c8f425 1820 */
beb56299 1821 public $link;
d9c8f425 1822 /**
beb56299 1823 * @var string $text A descriptive text
d9c8f425 1824 */
beb56299 1825 public $text;
d9c8f425 1826 /**
beb56299 1827 * @var string $page The keyword that defines a help page
d9c8f425 1828 */
beb56299 1829 public $page;
d9c8f425 1830 /**
beb56299 1831 * @var string $module Which module is the page defined in
d9c8f425 1832 */
beb56299 1833 public $module = 'moodle';
d9c8f425 1834 /**
beb56299 1835 * @var boolean $linktext Whether or not to show text next to the icon
d9c8f425 1836 */
beb56299 1837 public $linktext = false;
d9c8f425 1838 /**
beb56299 1839 * @var mixed $image The help icon. Can be set to true (will use default help icon),
1840 * false (will not use any icon), the URL to an image, or a full
1841 * html_image object.
d9c8f425 1842 */
beb56299 1843 public $image;
d9c8f425 1844
1845 /**
1846 * Constructor: sets up the other components in case they are needed
1847 * @return void
1848 */
1849 public function __construct() {
beb56299 1850 $this->link = new html_link();
1851 $this->image = new html_image();
d9c8f425 1852 }
1853
1854 /**
1855 * @see lib/moodle_html_component#prepare()
1856 * @return void
1857 */
1858 public function prepare() {
beb56299 1859 global $COURSE, $OUTPUT;
d9c8f425 1860
beb56299 1861 if (empty($this->page)) {
1862 throw new coding_exception('A moodle_help_icon object requires a $page parameter');
d9c8f425 1863 }
1864
beb56299 1865 if (empty($this->text)) {
1866 throw new coding_exception('A moodle_help_icon object requires a $text parameter');
d9c8f425 1867 }
1868
beb56299 1869 $this->link->text = $this->text;
d9c8f425 1870
beb56299 1871 // fix for MDL-7734
1872 $this->link->url = new moodle_url('/help.php', array('module' => $this->module, 'file' => $this->page .'.html'));
d9c8f425 1873
beb56299 1874 // fix for MDL-7734
1875 if (!empty($COURSE->lang)) {
1876 $this->link->url->param('forcelang', $COURSE->lang);
d9c8f425 1877 }
1878
beb56299 1879 // Catch references to the old text.html and emoticons.html help files that
1880 // were renamed in MDL-13233.
1881 if (in_array($this->page, array('text', 'emoticons', 'richtext'))) {
1882 $oldname = $this->page;
1883 $this->page .= '2';
1884 debugging("You are referring to the old help file '$oldname'. " .
1885 "This was renamed to '$this->page' because of MDL-13233. " .
1886 "Please update your code.", DEBUG_DEVELOPER);
1887 }
d9c8f425 1888
beb56299 1889 if ($this->module == '') {
1890 $this->module = 'moodle';
1891 }
d9c8f425 1892
beb56299 1893 // Warn users about new window for Accessibility
1894 $this->title = get_string('helpprefix2', '', trim($this->text, ". \t")) .' ('.get_string('newwindow').')';
d9c8f425 1895
beb56299 1896 // Prepare image and linktext
1897 if ($this->image && !($this->image instanceof html_image)) {
1898 $image = fullclone($this->image);
1899 $this->image = new html_image();
d9c8f425 1900
beb56299 1901 if ($image instanceof moodle_url) {
1902 $this->image->src = $image->out();
1903 } else if ($image === true) {
1904 $this->image->src = $OUTPUT->old_icon_url('help');
1905 } else if (is_string($image)) {
1906 $this->image->src = $image;
d9c8f425 1907 }
beb56299 1908 $this->image->alt = $this->text;
d9c8f425 1909
beb56299 1910 if ($this->linktext) {
1911 $this->image->alt = get_string('helpwiththis');
1912 } else {
1913 $this->image->alt = $this->title;
d9c8f425 1914 }
beb56299 1915 $this->image->add_class('iconhelp');
1916 } else if (empty($this->image->src)) {
1917 if (!($this->image instanceof html_image)) {
1918 $this->image = new html_image();
d9c8f425 1919 }
beb56299 1920 $this->image->src = $OUTPUT->old_icon_url('help');
d9c8f425 1921 }
beb56299 1922
1923 parent::prepare();
d9c8f425 1924 }
1925
beb56299 1926 public static function make_scale_menu($courseid, $scale) {
1927 $helpbutton = new moodle_help_icon();
1928 $strscales = get_string('scales');
1929 $helpbutton->image->alt = $scale->name;
1930 $helpbutton->link->url = new moodle_url('/course/scales.php', array('id' => $courseid, 'list' => true, 'scaleid' => $scale->id));
1931 $popupaction = new popup_action('click', $helpbutton->url, 'ratingscale', $popupparams);
1932 $popupaction->width = 500;
1933 $popupaction->height = 400;
1934 $helpbutton->link->add_action($popupaction);
1935 $helpbutton->link->title = $scale->name;
1936 return $helpbutton;
d9c8f425 1937 }
1938}
1939
1940/**
beb56299 1941 * Component representing an icon linking to a Moodle page.
d9c8f425 1942 *
1943 * @copyright 2009 Nicolas Connault
1944 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1945 * @since Moodle 2.0
1946 */
beb56299 1947class moodle_action_icon extends moodle_html_component {
d9c8f425 1948 /**
beb56299 1949 * @var string $linktext Optional text to display next to the icon
d9c8f425 1950 */
beb56299 1951 public $linktext;
d9c8f425 1952 /**
beb56299 1953 * @var html_image $image The icon
d9c8f425 1954 */
beb56299 1955 public $image;
1956 /**
1957 * @var html_link $link The link
1958 */
1959 public $link;
d9c8f425 1960
1961 /**
beb56299 1962 * Constructor: sets up the other components in case they are needed
d9c8f425 1963 * @return void
1964 */
beb56299 1965 public function __construct() {
1966 $this->image = new html_image();
1967 $this->link = new html_link();
d9c8f425 1968 }
1969
1970 /**
beb56299 1971 * @see lib/moodle_html_component#prepare()
d9c8f425 1972 * @return void
1973 */
beb56299 1974 public function prepare() {
1975 $this->image->add_class('action-icon');
d9c8f425 1976
beb56299 1977 parent::prepare();
d9c8f425 1978
beb56299 1979 if (empty($this->image->src)) {
1980 throw new coding_exception('moodle_action_icon->image->src must not be empty');
d9c8f425 1981 }
d9c8f425 1982
beb56299 1983 if (empty($this->image->alt) && !empty($this->linktext)) {
1984 $this->image->alt = $this->linktext;
1985 } else if (empty($this->image->alt)) {
1986 debugging('moodle_action_icon->image->alt should not be empty.', DEBUG_DEVELOPER);
d9c8f425 1987 }
1988 }
1989}
1990
1991/**
beb56299 1992 * This class represents how a block appears on a page.
d9c8f425 1993 *
beb56299 1994 * During output, each block instance is asked to return a block_contents object,
1995 * those are then passed to the $OUTPUT->block function for display.
1996 *
1997 * {@link $contents} should probably be generated using a moodle_block_..._renderer.
1998 *
1999 * Other block-like things that need to appear on the page, for example the
2000 * add new block UI, are also represented as block_contents objects.
2001 *
2002 * @copyright 2009 Tim Hunt
d9c8f425 2003 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2004 * @since Moodle 2.0
2005 */
beb56299 2006class block_contents extends moodle_html_component {
2007 /** @var int used to set $skipid. */
2008 protected static $idcounter = 1;
2009
2010 const NOT_HIDEABLE = 0;
2011 const VISIBLE = 1;
2012 const HIDDEN = 2;
2013
d9c8f425 2014 /**
beb56299 2015 * @param integer $skipid All the blocks (or things that look like blocks)
2016 * printed on a page are given a unique number that can be used to construct
2017 * id="" attributes. This is set automatically be the {@link prepare()} method.
2018 * Do not try to set it manually.
d9c8f425 2019 */
beb56299 2020 public $skipid;
d9c8f425 2021
2022 /**
beb56299 2023 * @var integer If this is the contents of a real block, this should be set to
2024 * the block_instance.id. Otherwise this should be set to 0.
2025 */
2026 public $blockinstanceid = 0;
2027
2028 /**
2029 * @var integer if this is a real block instance, and there is a corresponding
2030 * block_position.id for the block on this page, this should be set to that id.
2031 * Otherwise it should be 0.
2032 */
2033 public $blockpositionid = 0;
2034
2035 /**
2036 * @param array $attributes an array of attribute => value pairs that are put on the
2037 * outer div of this block. {@link $id} and {@link $classes} attributes should be set separately.
2038 */
2039 public $attributes = array();
2040
2041 /**
2042 * @param string $title The title of this block. If this came from user input,
2043 * it should already have had format_string() processing done on it. This will
2044 * be output inside <h2> tags. Please do not cause invalid XHTML.
2045 */
2046 public $title = '';
2047
2048 /**
2049 * @param string $content HTML for the content
2050 */
2051 public $content = '';
2052
2053 /**
2054 * @param array $list an alternative to $content, it you want a list of things with optional icons.
2055 */
2056 public $footer = '';
2057
2058 /**
2059 * Any small print that should appear under the block to explain to the
2060 * teacher about the block, for example 'This is a sticky block that was
2061 * added in the system context.'
2062 * @var string
2063 */
2064 public $annotation = '';
2065
2066 /**
2067 * @var integer one of the constants NOT_HIDEABLE, VISIBLE, HIDDEN. Whether
2068 * the user can toggle whether this block is visible.
2069 */
2070 public $collapsible = self::NOT_HIDEABLE;
2071
2072 /**
2073 * A (possibly empty) array of editing controls. Each element of this array
2074 * should be an array('url' => $url, 'icon' => $icon, 'caption' => $caption).
2075 * $icon is the icon name. Fed to $OUTPUT->old_icon_url.
2076 * @var array
2077 */
2078 public $controls = array();
2079
2080 /**
2081 * @see moodle_html_component::prepare()
d9c8f425 2082 * @return void
2083 */
2084 public function prepare() {
beb56299 2085 $this->skipid = self::$idcounter;
2086 self::$idcounter += 1;
2087 $this->add_class('sideblock');
2088 if (empty($this->blockinstanceid) || !strip_tags($this->title)) {
2089 $this->collapsible = self::NOT_HIDEABLE;
2090 }
2091 if ($this->collapsible == self::HIDDEN) {
2092 $this->add_class('hidden');
2093 }
2094 if (!empty($this->controls)) {
2095 $this->add_class('block_with_controls');
2096 }
d9c8f425 2097 parent::prepare();
2098 }
2099}
beb56299 2100
2101/**
2102 * This class represents a target for where a block can go when it is being moved.
2103 *
2104 * This needs to be rendered as a form with the given hidden from fields, and
2105 * clicking anywhere in the form should submit it. The form action should be
2106 * $PAGE->url.
2107 *
2108 * @copyright 2009 Tim Hunt
2109 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2110 * @since Moodle 2.0
2111 */
2112class block_move_target extends moodle_html_component {
2113 /**
2114 * List of hidden form fields.
2115 * @var array
2116 */
2117 public $url = array();
2118 /**
2119 * List of hidden form fields.
2120 * @var array
2121 */
2122 public $text = '';
2123}