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 /** 18 * Field controller abstract class 19 * 20 * @package core_customfield 21 * @copyright 2018 Toni Barbera <toni@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_customfield; 26 27 defined('MOODLE_INTERNAL') || die; 28 29 /** 30 * Base class for custom fields controllers 31 * 32 * This class is a wrapper around the persistent field class that allows to define the field 33 * configuration 34 * 35 * Custom field plugins must define a class 36 * \{pluginname}\field_controller extends \core_customfield\field_controller 37 * 38 * @package core_customfield 39 * @copyright 2018 Toni Barbera <toni@moodle.com> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 abstract class field_controller { 43 44 /** 45 * Field persistent class 46 * 47 * @var field 48 */ 49 protected $field; 50 51 /** 52 * Category of the field. 53 * 54 * @var category_controller 55 */ 56 protected $category; 57 58 /** 59 * Constructor. 60 * 61 * @param int $id 62 * @param \stdClass|null $record 63 */ 64 public function __construct(int $id = 0, \stdClass $record = null) { 65 $this->field = new field($id, $record); 66 } 67 68 /** 69 * Creates an instance of field_controller 70 * 71 * Parameters $id, $record and $category can complement each other but not conflict. 72 * If $id is not specified, categoryid must be present either in $record or in $category. 73 * If $id is not specified, type must be present in $record 74 * 75 * No DB queries are performed if both $record and $category are specified. 76 * 77 * @param int $id 78 * @param \stdClass|null $record 79 * @param category_controller|null $category 80 * @return field_controller will return the instance of the class from the customfield element plugin 81 * @throws \coding_exception 82 * @throws \moodle_exception 83 */ 84 public static function create(int $id, \stdClass $record = null, category_controller $category = null) : field_controller { 85 global $DB; 86 if ($id && $record) { 87 // This warning really should be in persistent as well. 88 debugging('Too many parameters, either id need to be specified or a record, but not both.', 89 DEBUG_DEVELOPER); 90 } 91 if ($id) { 92 if (!$record = $DB->get_record(field::TABLE, array('id' => $id), '*', IGNORE_MISSING)) { 93 throw new \moodle_exception('fieldnotfound', 'core_customfield'); 94 } 95 } 96 97 if (empty($record->categoryid)) { 98 if (!$category) { 99 throw new \coding_exception('Not enough parameters to initialise field_controller - unknown category'); 100 } else { 101 $record->categoryid = $category->get('id'); 102 } 103 } 104 if (empty($record->type)) { 105 throw new \coding_exception('Not enough parameters to initialise field_controller - unknown field type'); 106 } 107 108 $type = $record->type; 109 if (!$category) { 110 $category = category_controller::create($record->categoryid); 111 } 112 if ($category->get('id') != $record->categoryid) { 113 throw new \coding_exception('Category of the field does not match category from the parameter'); 114 } 115 116 $customfieldtype = "\\customfield_{$type}\\field_controller"; 117 if (!class_exists($customfieldtype) || !is_subclass_of($customfieldtype, self::class)) { 118 throw new \moodle_exception('errorfieldtypenotfound', 'core_customfield', '', s($type)); 119 } 120 $fieldcontroller = new $customfieldtype(0, $record); 121 $fieldcontroller->category = $category; 122 $category->add_field($fieldcontroller); 123 return $fieldcontroller; 124 } 125 126 /** 127 * Perform pre-processing of field values, for example those that originate from an external source (e.g. upload course tool) 128 * 129 * Override in plugin classes as necessary 130 * 131 * @param string $value 132 * @return mixed 133 */ 134 public function parse_value(string $value) { 135 return $value; 136 } 137 138 /** 139 * Validate the data on the field configuration form 140 * 141 * Plugins can override it 142 * 143 * @param array $data from the add/edit profile field form 144 * @param array $files 145 * @return array associative array of error messages 146 */ 147 public function config_form_validation(array $data, $files = array()) : array { 148 return array(); 149 } 150 151 152 /** 153 * Persistent getter parser. 154 * 155 * @param string $property 156 * @return mixed 157 */ 158 final public function get(string $property) { 159 return $this->field->get($property); 160 } 161 162 /** 163 * Persistent setter parser. 164 * 165 * @param string $property 166 * @param mixed $value 167 * @return field 168 */ 169 final public function set($property, $value) { 170 return $this->field->set($property, $value); 171 } 172 173 /** 174 * Delete a field and all associated data 175 * 176 * Plugins may override it if it is necessary to delete related data (such as files) 177 * 178 * Not that the delete() method from data_controller is not called here. 179 * 180 * @return bool 181 */ 182 public function delete() : bool { 183 global $DB; 184 $DB->delete_records('customfield_data', ['fieldid' => $this->get('id')]); 185 return $this->field->delete(); 186 } 187 188 /** 189 * Save or update the persistent class to database. 190 * 191 * @return void 192 */ 193 public function save() { 194 $this->field->save(); 195 } 196 197 /** 198 * Persistent to_record parser. 199 * 200 * @return \stdClass 201 */ 202 final public function to_record() { 203 return $this->field->to_record(); 204 } 205 206 /** 207 * Get the category associated with this field 208 * 209 * @return category_controller 210 */ 211 public final function get_category() : category_controller { 212 return $this->category; 213 } 214 215 /** 216 * Get configdata property. 217 * 218 * @param string $property name of the property 219 * @return mixed 220 */ 221 public function get_configdata_property(string $property) { 222 $configdata = $this->field->get('configdata'); 223 if (!isset($configdata[$property])) { 224 return null; 225 } 226 return $configdata[$property]; 227 } 228 229 /** 230 * Returns a handler for this field 231 * 232 * @return handler 233 */ 234 public final function get_handler() : handler { 235 return $this->get_category()->get_handler(); 236 } 237 238 /** 239 * Prepare the field data to set in the configuration form 240 * 241 * Plugin can override if some preprocessing required for editor or filemanager fields 242 * 243 * @param \stdClass $formdata 244 */ 245 public function prepare_for_config_form(\stdClass $formdata) { 246 } 247 248 /** 249 * Add specific settings to the field configuration form, for example "default value" 250 * 251 * @param \MoodleQuickForm $mform 252 */ 253 public abstract function config_form_definition(\MoodleQuickForm $mform); 254 255 /** 256 * Returns the field name formatted according to configuration context. 257 * 258 * @return string 259 */ 260 public function get_formatted_name() : string { 261 $context = $this->get_handler()->get_configuration_context(); 262 return format_string($this->get('name'), true, ['context' => $context]); 263 } 264 265 /** 266 * Does this custom field type support being used as part of the block_myoverview 267 * custom field grouping? 268 * @return bool 269 */ 270 public function supports_course_grouping(): bool { 271 return false; 272 } 273 274 /** 275 * If this field supports course filtering, then this function needs overriding to 276 * return the formatted values for this. 277 * @param array $values the used values that need grouping 278 * @return array 279 */ 280 public function course_grouping_format_values($values): array { 281 return []; 282 } 283 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body