1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace core\output; 18 19 use renderable; 20 use renderer_base; 21 use core\output\named_templatable; 22 23 /** 24 * A generic user choice output class. 25 * 26 * This class can be used as a generic user choice data structure for any dropdown, modal, or any 27 * other component that offers choices to the user. 28 * 29 * @package core 30 * @copyright 2023 Ferran Recio <ferran@moodle.com> 31 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 32 */ 33 class choicelist implements renderable, named_templatable { 34 35 /** @var object[] The user choices. */ 36 protected $options = []; 37 38 /** @var string the selected option. */ 39 protected $selected = null; 40 41 /** @var string the choice description. */ 42 protected $description = null; 43 44 /** 45 * Constructor. 46 * 47 * @param string $description the choice description. 48 */ 49 public function __construct(?string $description = null) { 50 $this->description = $description; 51 } 52 53 /** 54 * Add option to the user choice. 55 * 56 * The definition object could contain the following keys: 57 * - string description: the description of the option. 58 * - \moodle_url url: the URL to link to. 59 * - \pix_icon icon: the icon to display. 60 * - bool disabled: whether the option is disabled. 61 * - bool selected: whether the option is selected. 62 * - array extras: an array of HTML attributes to add to the option (attribute => value). 63 * 64 * @param string $value 65 * @param string $name 66 * @param array $definition an optional array of definition for the option. 67 */ 68 public function add_option(string $value, string $name, array $definition = []) { 69 $option = [ 70 'value' => $value, 71 'name' => $name, 72 'description' => $definition['description'] ?? null, 73 'url' => $definition['url'] ?? null, 74 'icon' => $definition['icon'] ?? null, 75 'disabled' => (!empty($definition['disabled'])) ? true : false, 76 ]; 77 if (!empty($definition['selected'])) { 78 $this->selected = $value; 79 } 80 $this->options[$value] = $option; 81 if (isset($definition['extras'])) { 82 $this->set_option_extras($value, $definition['extras']); 83 } 84 } 85 86 /** 87 * Get the number of options added to the choice list. 88 * @return int 89 */ 90 public function count_options(): int { 91 return count($this->options); 92 } 93 94 /** 95 * Set the selected option. 96 * 97 * @param string $value The value of the selected option. 98 */ 99 public function set_selected_value(string $value) { 100 $this->selected = $value; 101 } 102 103 /** 104 * Get the selected option. 105 * 106 * @return string|null The value of the selected option. 107 */ 108 public function get_selected_value(): ?string { 109 return $this->selected; 110 } 111 112 /** 113 * Set the general choice description option. 114 * 115 * @param string $value the new description. 116 */ 117 public function set_description(string $value) { 118 $this->description = $value; 119 } 120 121 /** 122 * Get the choice description option. 123 * 124 * @return string|null the current description. 125 */ 126 public function get_description(): ?string { 127 return $this->description; 128 } 129 130 /** 131 * Set the option disabled. 132 * 133 * @param string $value The value of the option. 134 * @param bool $disabled Whether the option is disabled. 135 */ 136 public function set_option_disabled(string $value, bool $disabled) { 137 if (isset($this->options[$value])) { 138 $this->options[$value]['disabled'] = $disabled; 139 } 140 } 141 142 /** 143 * Set the option disabled. 144 * 145 * @param string $value The value of the option. 146 * @param array $extras an array to add HTML attributes to the option (attribute => value). 147 */ 148 public function set_option_extras(string $value, array $extras) { 149 if (!isset($this->options[$value])) { 150 return; 151 } 152 $extrasattributes = []; 153 foreach ($extras as $attribute => $attributevalue) { 154 $extrasattributes[] = [ 155 'attribute' => $attribute, 156 'value' => $attributevalue, 157 ]; 158 } 159 $this->options[$value]['extras'] = $extrasattributes; 160 } 161 162 /** 163 * Export for template. 164 * 165 * @param renderer_base $output The renderer. 166 * @return array 167 */ 168 public function export_for_template(renderer_base $output): array { 169 $options = []; 170 foreach ($this->options as $option) { 171 if (!empty($option['icon'])) { 172 $option['icon'] = $option['icon']->export_for_pix($output); 173 } 174 $option['hasicon'] = !empty($option['icon']); 175 176 if (!empty($option['url'])) { 177 $option['url'] = $option['url']->out(true); 178 } 179 $option['hasurl'] = !empty($option['url']); 180 181 if ($option['value'] == $this->selected) { 182 $option['selected'] = true; 183 } 184 185 $option['optionnumber'] = count($options) + 1; 186 $option['first'] = count($options) === 0; 187 $option['optionuniqid'] = \html_writer::random_id('choice_option_'); 188 189 $options[] = $option; 190 } 191 return [ 192 'description' => $this->description, 193 'options' => $options, 194 'hasoptions' => !empty($options), 195 ]; 196 } 197 198 /** 199 * Get the name of the template to use for this templatable. 200 * 201 * @param renderer_base $renderer The renderer requesting the template name 202 * @return string 203 */ 204 public function get_template_name(renderer_base $renderer): string { 205 return 'core/local/choicelist'; 206 } 207 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body