See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
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 * Data generator class for mod_data. 19 * 20 * @package mod_data 21 * @category test 22 * @copyright 2012 Petr Skoda {@link http://skodak.org} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 use mod_data\manager; 27 use mod_data\preset; 28 29 defined('MOODLE_INTERNAL') || die(); 30 31 32 /** 33 * Data generator class for mod_data. 34 * 35 * @package mod_data 36 * @category test 37 * @copyright 2012 Petr Skoda {@link http://skodak.org} 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class mod_data_generator extends testing_module_generator { 41 42 /** 43 * @var int keep track of how many database fields have been created. 44 */ 45 protected $databasefieldcount = 0; 46 47 /** 48 * @var int keep track of how many database records have been created. 49 */ 50 protected $databaserecordcount = 0; 51 52 /** 53 * To be called from data reset code only, 54 * do not use in tests. 55 * @return void 56 */ 57 public function reset() { 58 $this->databasefieldcount = 0; 59 $this->databaserecordcount = 0; 60 61 parent::reset(); 62 } 63 64 /** 65 * Creates a mod_data instance 66 * 67 * @param array $record 68 * @param array $options 69 * @return StdClass 70 */ 71 public function create_instance($record = null, array $options = null) { 72 // Note, the parent class does not type $record to cast to array and then to object. 73 $record = (object) (array) $record; 74 75 if (!isset($record->assessed)) { 76 $record->assessed = 0; 77 } 78 if (!isset($record->scale)) { 79 $record->scale = 0; 80 } 81 82 return parent::create_instance((array) $record, $options); 83 } 84 85 /** 86 * Creates a field for a mod_data instance. 87 * 88 * @param StdClass $record 89 * @param mod_data $data 90 * @return data_field_{type} 91 */ 92 public function create_field(stdClass $record = null, $data = null) { 93 $record = (array) $record; 94 95 $this->databasefieldcount++; 96 97 if (!isset($data->course)) { 98 throw new coding_exception('course must be present in phpunit_util::create_field() $data'); 99 } 100 101 if (!isset($data->id)) { 102 throw new coding_exception('dataid must be present in phpunit_util::create_field() $data'); 103 } else { 104 $record['dataid'] = $data->id; 105 } 106 107 if (!isset($record['type'])) { 108 throw new coding_exception('type must be present in phpunit_util::create_field() $record'); 109 } 110 111 if (!isset($record['required'])) { 112 $record['required'] = 0; 113 } 114 115 if (!isset($record['name'])) { 116 $record['name'] = "testField - " . $this->databasefieldcount; 117 } 118 119 if (!isset($record['description'])) { 120 $record['description'] = " This is testField - " . $this->databasefieldcount; 121 } 122 123 if (isset($record['param1']) && !empty($record['param1'])) { 124 // Some fields have multiline entries. 125 $record['param1'] = str_replace('\n', "\n", $record['param1']); 126 } 127 128 if (!isset($record['param1'])) { 129 if ($record['type'] == 'checkbox') { 130 $record['param1'] = implode("\n", array('opt1', 'opt2', 'opt3', 'opt4')); 131 } else if ($record['type'] == 'radiobutton') { 132 $record['param1'] = implode("\n", array('radioopt1', 'radioopt2', 'radioopt3', 'radioopt4')); 133 } else if ($record['type'] == 'menu') { 134 $record['param1'] = implode("\n", array('menu1', 'menu2', 'menu3', 'menu4')); 135 } else if ($record['type'] == 'multimenu') { 136 $record['param1'] = implode("\n", array('multimenu1', 'multimenu2', 'multimenu3', 'multimenu4')); 137 } else if (($record['type'] === 'text') || ($record['type'] === 'url')) { 138 $record['param1'] = 1; 139 } else if ($record['type'] == 'latlong') { 140 $record['param1'] = 'Google Maps'; 141 } else { 142 $record['param1'] = ''; 143 } 144 } 145 146 if (!isset($record['param2'])) { 147 148 if ($record['type'] === 'textarea') { 149 $record['param2'] = 60; 150 } else if ($record['type'] == 'latlong') { 151 $record['param2'] = -1; 152 } else { 153 $record['param2'] = ''; 154 } 155 } 156 157 if (!isset($record['param3'])) { 158 159 if (($record['type'] === 'textarea')) { 160 $record['param3'] = 35; 161 } else if ($record['type'] == 'picture' || $record['type'] == 'file') { 162 $record['param3'] = 0; 163 } else { 164 $record['param3'] = ''; 165 } 166 } 167 168 if (!isset($record['param4'])) { 169 170 if (($record['type'] === 'textarea')) { 171 $record['param4'] = 1; 172 } 173 } 174 175 if (!isset($record['param5'])) { 176 if (($record['type'] === 'textarea')) { 177 $record['param5'] = 0; 178 } 179 } 180 181 $record = (object) $record; 182 183 $field = data_get_field($record, $data); 184 $field->insert_field(); 185 186 return $field; 187 } 188 189 /** 190 * Creates a field for a mod_data instance. 191 * Keep in mind the default data field params created in create_field() function! 192 * ...if you haven't provided your own custom data field parameters there. 193 * The developers using the generator must adhere to the following format : 194 * 195 * Syntax : $contents[ fieldid ] = fieldvalue 196 * $contents['checkbox'] = array('val1', 'val2', 'val3' .....) 197 * $contents['data'] = 'dd-mm-yyyy' 198 * $contents['menu'] = 'value'; 199 * $contents['multimenu'] = array('val1', 'val2', 'val3' .....) 200 * $contents['number'] = 'numeric value' 201 * $contents['radiobuton'] = 'value' 202 * $contents['text'] = 'text' 203 * $contents['textarea'] = 'text' 204 * $contents['url'] = 'example.url' or array('example.url', 'urlname') 205 * $contents['latlong'] = array('value for lattitude', 'value for longitude') 206 * $contents['file'] = 'filename or draftitemid' 207 * $contents['picture'] = array('filename or draftitemid', 'alternative text') 208 * 209 * @param stdClass $data record from table {data} 210 * @param array $contents 211 * @param int $groupid 212 * @param array $tags 213 * @param array $options 214 * @param int $userid if defined, it will be the author of the entry 215 * @return int id of the generated record in table {data_records} 216 */ 217 public function create_entry($data, array $contents, $groupid = 0, $tags = [], array $options = null, int $userid = 0) { 218 global $DB, $USER, $CFG; 219 220 // Set current user if defined. 221 if (!empty($userid)) { 222 $currentuser = $USER; 223 $user = \core_user::get_user($userid); 224 $this->set_user($user); 225 } 226 227 $this->databaserecordcount++; 228 229 $recordid = data_add_record($data, $groupid); 230 231 if (isset($options['approved'])) { 232 data_approve_entry($recordid, !empty($options['approved'])); 233 } else { 234 $approved = null; 235 } 236 237 $fields = $DB->get_records('data_fields', array('dataid' => $data->id)); 238 239 // Validating whether required field are filled. 240 foreach ($fields as $field) { 241 $fieldhascontent = true; 242 243 $field = data_get_field($field, $data); 244 245 $fieldid = $field->field->id; 246 247 if ($field->type === 'date') { 248 $values = array(); 249 250 $temp = explode('-', $contents[$fieldid], 3); 251 252 $values['field_' . $fieldid . '_day'] = (int)trim($temp[0]); 253 $values['field_' . $fieldid . '_month'] = (int)trim($temp[1]); 254 $values['field_' . $fieldid . '_year'] = (int)trim($temp[2]); 255 256 // Year should be less than 2038, so it can be handled by 32 bit windows. 257 if ($values['field_' . $fieldid . '_year'] > 2038) { 258 throw new coding_exception('DateTime::getTimestamp resturns false on 32 bit win for year beyond ' . 259 '2038. Please use year less than 2038.'); 260 } 261 262 $contents[$fieldid] = $values; 263 264 foreach ($values as $fieldname => $value) { 265 if (!$field->notemptyfield($value, $fieldname)) { 266 $fieldhascontent = false; 267 } 268 } 269 } else if ($field->type === 'textarea') { 270 $values = array(); 271 272 $values['field_' . $fieldid] = $contents[$fieldid]; 273 $values['field_' . $fieldid . '_content1'] = 1; 274 275 $contents[$fieldid] = $values; 276 277 $fieldname = 'field_' . $fieldid; 278 if (!$field->notemptyfield($values[$fieldname], $fieldname)) { 279 $fieldhascontent = false; 280 } 281 282 } else if ($field->type === 'url') { 283 $values = array(); 284 285 if (is_array($contents[$fieldid])) { 286 foreach ($contents[$fieldid] as $key => $value) { 287 $values['field_' . $fieldid . '_' . $key] = $value; 288 } 289 } else { 290 $values['field_' . $fieldid . '_0'] = $contents[$fieldid]; 291 } 292 293 $contents[$fieldid] = $values; 294 $fieldname = 'field_' . $fieldid . '_0'; 295 if (!$field->notemptyfield($values[$fieldname], $fieldname)) { 296 $fieldhascontent = false; 297 } 298 299 } else if ($field->type === 'latlong') { 300 $values = array(); 301 302 foreach ($contents[$fieldid] as $key => $value) { 303 $values['field_' . $fieldid . '_' . $key] = $value; 304 } 305 306 $contents[$fieldid] = $values; 307 $fieldname = 'field_' . $fieldid . '_0'; 308 if (!$field->notemptyfield($values[$fieldname], $fieldname)) { 309 $fieldhascontent = false; 310 } 311 312 } else if ($field->type === 'file' || $field->type === 'picture') { 313 if (is_array($contents[$fieldid])) { 314 list($itemid, $alttext) = $contents[$fieldid]; 315 } else { 316 $itemid = $contents[$fieldid]; 317 $alttext = ''; 318 } 319 320 if (strlen($itemid) && !is_numeric($itemid)) { 321 // We expect draftarea item id here but it can also be a filename, in this case provider will generate file. 322 $filename = $itemid; 323 $usercontext = context_user::instance($USER->id); 324 $itemid = file_get_unused_draft_itemid(); 325 get_file_storage()->create_file_from_string(['component' => 'user', 'filearea' => 'draft', 326 'contextid' => $usercontext->id, 'itemid' => $itemid, 'filepath' => '/', 327 'filename' => $filename], 328 file_get_contents($CFG->dirroot.'/mod/data/pix/monologo.png')); 329 } 330 331 $fieldname = 'field_' . $fieldid . '_file'; 332 if ($field->type === 'file') { 333 $contents[$fieldid] = $itemid; 334 } else { 335 $contents[$fieldid] = [ 336 $fieldname => $itemid, 337 'field_' . $fieldid . '_alttext' => $alttext 338 ]; 339 } 340 341 if (!$field->notemptyfield($itemid, $fieldname)) { 342 $fieldhascontent = false; 343 } 344 345 } else { 346 if ($field->notemptyfield($contents[$fieldid], 'field_' . $fieldid . '_0')) { 347 continue; 348 } 349 } 350 351 if ($field->field->required && !$fieldhascontent) { 352 return false; 353 } 354 } 355 356 foreach ($contents as $fieldid => $content) { 357 $field = data_get_field_from_id($fieldid, $data); 358 359 if (is_array($content) and in_array($field->type, array('date', 'textarea', 'url', 'picture', 'latlong'))) { 360 361 foreach ($content as $fieldname => $value) { 362 $field->update_content($recordid, $value, $fieldname); 363 } 364 365 } else { 366 $field->update_content($recordid, $content); 367 } 368 } 369 370 if (!empty($tags)) { 371 $cm = get_coursemodule_from_instance('data', $data->id); 372 core_tag_tag::set_item_tags('mod_data', 'data_records', $recordid, 373 context_module::instance($cm->id), $tags); 374 } 375 376 if (isset($currentuser)) { 377 $this->set_user($currentuser); 378 } 379 380 return $recordid; 381 } 382 383 /** 384 * Creates a preset from a mod_data instance. 385 * 386 * @param stdClass $instance The mod_data instance. 387 * @param stdClass|null $record The preset information, like 'name'. 388 * @return preset The preset that has been created. 389 */ 390 public function create_preset(stdClass $instance, stdClass $record = null): preset { 391 global $USER; 392 393 if (is_null($record)) { 394 $record = new stdClass(); 395 } 396 397 // Set current user if defined. 398 if (isset($record->userid) && $record->userid != $USER->id) { 399 $currentuser = $USER; 400 $user = \core_user::get_user($record->userid); 401 $this->set_user($user); 402 } 403 404 // Fill in optional values if not specified. 405 $presetname = 'New preset ' . microtime(); 406 if (isset($record->name)) { 407 $presetname = $record->name; 408 } 409 $presetdescription = null; 410 if (isset($record->description)) { 411 $presetdescription = $record->description; 412 } 413 414 $manager = manager::create_from_instance($instance); 415 $preset = preset::create_from_instance($manager, $presetname, $presetdescription); 416 $preset->save(); 417 418 if (isset($currentuser)) { 419 $this->set_user($currentuser); 420 } 421 422 return $preset; 423 } 424 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body