[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 * Persistent form abstract. 19 * 20 * @package tool_lp 21 * @copyright 2015 Frédéric Massart - FMCorz.net 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace tool_lp\form; 26 defined('MOODLE_INTERNAL') || die(); 27 28 use coding_exception; 29 use moodleform; 30 use stdClass; 31 32 require_once($CFG->libdir.'/formslib.php'); 33 34 /** 35 * Persistent form abstract class. 36 * 37 * This provides some shortcuts to validate objects based on the persistent model. 38 * 39 * Note that all mandatory fields (non-optional) of your model should be included in the 40 * form definition. Mandatory fields which are not editable by the user should be 41 * as hidden and constant. 42 * 43 * $mform->addElement('hidden', 'userid'); 44 * $mform->setType('userid', PARAM_INT); 45 * $mform->setConstant('userid', $this->_customdata['userid']); 46 * 47 * You may exclude some fields from the validation should your form include other 48 * properties such as files. To do so use the $foreignfields property. 49 * 50 * @package tool_lp 51 * @copyright 2015 Frédéric Massart - FMCorz.net 52 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 53 */ 54 abstract class persistent extends moodleform { 55 56 /** @var string The fully qualified classname. */ 57 protected static $persistentclass = null; 58 59 /** @var array Fields to remove when getting the final data. */ 60 protected static $fieldstoremove = array('submitbutton'); 61 62 /** @var array Fields to remove from the persistent validation. */ 63 protected static $foreignfields = array(); 64 65 /** @var \tool_lp\peristent Reference to the persistent. */ 66 private $persistent = null; 67 68 /** 69 * Constructor. 70 * 71 * The 'persistent' has to be passed as custom data when 'editing'. 72 * 73 * Note that in order for your persistent to be reloaded after form submission you should 74 * either override the URL to include the ID to your resource, or add the ID to the form 75 * fields. 76 * 77 * @param mixed $action 78 * @param mixed $customdata 79 * @param string $method 80 * @param string $target 81 * @param mixed $attributes 82 * @param bool $editable 83 */ 84 public function __construct($action = null, $customdata = null, $method = 'post', $target = '', 85 $attributes = null, $editable = true) { 86 if (empty(static::$persistentclass)) { 87 throw new coding_exception('Static property $persistentclass must be set.'); 88 } else if (!is_subclass_of(static::$persistentclass, 'core_competency\\persistent')) { 89 throw new coding_exception('Static property $persistentclass is not valid.'); 90 } else if (!array_key_exists('persistent', $customdata)) { 91 throw new coding_exception('The custom data \'persistent\' key must be set, even if it is null.'); 92 } 93 94 // Make a copy of the persistent passed, this ensures validation and object reference issues. 95 $persistendata = new stdClass(); 96 $persistent = isset($customdata['persistent']) ? $customdata['persistent'] : null; 97 if ($persistent) { 98 if (!($persistent instanceof static::$persistentclass)) { 99 throw new coding_exception('Invalid persistent'); 100 } 101 $persistendata = $persistent->to_record(); 102 unset($persistent); 103 } 104 105 $this->persistent = new static::$persistentclass(); 106 $this->persistent->from_record($persistendata); 107 108 unset($customdata['persistent']); 109 parent::__construct($action, $customdata, $method, $target, $attributes, $editable); 110 111 // Load the defaults. 112 $this->set_data($this->get_default_data()); 113 } 114 115 /** 116 * Convert some fields. 117 * 118 * @param stdClass $data The whole data set. 119 * @return stdClass The amended data set. 120 */ 121 protected static function convert_fields(stdClass $data) { 122 $class = static::$persistentclass; 123 $properties = $class::get_formatted_properties(); 124 125 foreach ($data as $field => $value) { 126 // Replace formatted properties. 127 if (isset($properties[$field])) { 128 $formatfield = $properties[$field]; 129 $data->$formatfield = $data->{$field}['format']; 130 $data->$field = $data->{$field}['text']; 131 } 132 } 133 134 return $data; 135 } 136 137 /** 138 * Define extra validation mechanims. 139 * 140 * The data here: 141 * - does not include {@link self::$fieldstoremove}. 142 * - does include {@link self::$foreignfields}. 143 * - was converted to map persistent-like data, e.g. array $description to string $description + int $descriptionformat. 144 * 145 * You can modify the $errors parameter in order to remove some validation errors should you 146 * need to. However, the best practice is to return new or overriden errors. Only modify the 147 * errors passed by reference when you have no other option. 148 * 149 * Do not add any logic here, it is only intended to be used by child classes. 150 * 151 * @param stdClass $data Data to validate. 152 * @param array $files Array of files. 153 * @param array $errors Currently reported errors. 154 * @return array of additional errors, or overridden errors. 155 */ 156 protected function extra_validation($data, $files, array &$errors) { 157 return array(); 158 } 159 160 /** 161 * Filter out the foreign fields of the persistent. 162 * 163 * This can be overridden to filter out more complex fields. 164 * 165 * @param stdClass $data The data to filter the fields out of. 166 * @return stdClass. 167 */ 168 protected function filter_data_for_persistent($data) { 169 return (object) array_diff_key((array) $data, array_flip((array) static::$foreignfields)); 170 } 171 172 /** 173 * Get the default data. 174 * 175 * This is the data that is prepopulated in the form at it loads, we automatically 176 * fetch all the properties of the persistent however some needs to be converted 177 * to map the form structure. 178 * 179 * Extend this class if you need to add more conversion. 180 * 181 * @return stdClass 182 */ 183 protected function get_default_data() { 184 $data = $this->get_persistent()->to_record(); 185 $class = static::$persistentclass; 186 $properties = $class::get_formatted_properties(); 187 188 foreach ($data as $field => $value) { 189 // Convert formatted properties. 190 if (isset($properties[$field])) { 191 $data->$field = array( 192 'text' => $data->$field, 193 'format' => $data->{$properties[$field]} 194 ); 195 unset($data->{$properties[$field]}); 196 } 197 } 198 199 return $data; 200 } 201 202 /** 203 * Get form data. 204 * 205 * Conveniently removes non-desired properties and add the ID property. 206 * 207 * @return object|null 208 */ 209 public function get_data() { 210 $data = parent::get_data(); 211 if (is_object($data)) { 212 foreach (static::$fieldstoremove as $field) { 213 unset($data->{$field}); 214 } 215 $data = static::convert_fields($data); 216 217 // Ensure that the ID is set. 218 $data->id = $this->persistent->get_id(); 219 } 220 return $data; 221 } 222 223 /** 224 * Return the persistent object associated with this form instance. 225 * 226 * @return tool_lp\persistent 227 */ 228 final protected function get_persistent() { 229 return $this->persistent; 230 } 231 232 /** 233 * Get the submitted form data. 234 * 235 * Conveniently removes non-desired properties. 236 * 237 * @return object|null 238 */ 239 public function get_submitted_data() { 240 $data = parent::get_submitted_data(); 241 if (is_object($data)) { 242 foreach (static::$fieldstoremove as $field) { 243 unset($data->{$field}); 244 } 245 $data = static::convert_fields($data); 246 } 247 return $data; 248 } 249 250 /** 251 * Form validation. 252 * 253 * If you need extra validation, use {@link self::extra_validation()}. 254 * 255 * @param array $data 256 * @param array $files 257 * @return array 258 */ 259 public final function validation($data, $files) { 260 $errors = parent::validation($data, $files); 261 $data = $this->get_submitted_data(); 262 263 // Only validate compatible fields. 264 $persistentdata = $this->filter_data_for_persistent($data); 265 $persistent = $this->get_persistent(); 266 $persistent->from_record((object) $persistentdata); 267 $errors = array_merge($errors, $persistent->get_errors()); 268 269 // Apply extra validation. 270 $extraerrors = $this->extra_validation($data, $files, $errors); 271 $errors = array_merge($errors, (array) $extraerrors); 272 273 return $errors; 274 } 275 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |