weekly release 2.6dev
[moodle.git] / lib / testing / generator / data_generator.php
CommitLineData
7e7cfe7a
PS
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.
19 *
20 * @package core
6b219869 21 * @category test
7e7cfe7a
PS
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
c29e3e24 26defined('MOODLE_INTERNAL') || die();
7e7cfe7a
PS
27
28/**
6b219869 29 * Data generator class for unit tests and other tools that need to create fake test sites.
7e7cfe7a
PS
30 *
31 * @package core
6b219869 32 * @category test
7e7cfe7a
PS
33 * @copyright 2012 Petr Skoda {@link http://skodak.org}
34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35 */
5c3c2c81 36class testing_data_generator {
7e7cfe7a
PS
37 protected $usercounter = 0;
38 protected $categorycount = 0;
4729332b 39 protected $cohortcount = 0;
7e7cfe7a
PS
40 protected $coursecount = 0;
41 protected $scalecount = 0;
42 protected $groupcount = 0;
43 protected $groupingcount = 0;
44
45 /** @var array list of plugin generators */
46 protected $generators = array();
47
48 /** @var array lis of common last names */
49 public $lastnames = array(
50 'Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Miller', 'Davis', 'García', 'Rodríguez', 'Wilson',
51 'Müller', 'Schmidt', 'Schneider', 'Fischer', 'Meyer', 'Weber', 'Schulz', 'Wagner', 'Becker', 'Hoffmann',
52 'Novák', 'Svoboda', 'Novotný', 'Dvořák', 'Černý', 'Procházková', 'Kučerová', 'Veselá', 'Horáková', 'Němcová',
53 'Смирнов', 'Иванов', 'Кузнецов', 'Соколов', 'Попов', 'Лебедева', 'Козлова', 'Новикова', 'Морозова', 'Петрова',
54 '王', '李', '张', '刘', '陈', '楊', '黃', '趙', '吳', '周',
55 '佐藤', '鈴木', '高橋', '田中', '渡辺', '伊藤', '山本', '中村', '小林', '斎藤',
56 );
57
58 /** @var array lis of common first names */
59 public $firstnames = array(
60 'Jacob', 'Ethan', 'Michael', 'Jayden', 'William', 'Isabella', 'Sophia', 'Emma', 'Olivia', 'Ava',
61 'Lukas', 'Leon', 'Luca', 'Timm', 'Paul', 'Leonie', 'Leah', 'Lena', 'Hanna', 'Laura',
62 'Jakub', 'Jan', 'Tomáš', 'Lukáš', 'Matěj', 'Tereza', 'Eliška', 'Anna', 'Adéla', 'Karolína',
63 'Даниил', 'Максим', 'Артем', 'Иван', 'Александр', 'София', 'Анастасия', 'Дарья', 'Мария', 'Полина',
64 '伟', '伟', '芳', '伟', '秀英', '秀英', '娜', '秀英', '伟', '敏',
65 '翔', '大翔', '拓海', '翔太', '颯太', '陽菜', 'さくら', '美咲', '葵', '美羽',
66 );
67
68 public $loremipsum = <<<EOD
69Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla non arcu lacinia neque faucibus fringilla. Vivamus porttitor turpis ac leo. Integer in sapien. Nullam eget nisl. Aliquam erat volutpat. Cras elementum. Mauris suscipit, ligula sit amet pharetra semper, nibh ante cursus purus, vel sagittis velit mauris vel metus. Integer malesuada. Nullam lectus justo, vulputate eget mollis sed, tempor sed magna. Mauris elementum mauris vitae tortor. Aliquam erat volutpat.
70Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Pellentesque ipsum. Cras pede libero, dapibus nec, pretium sit amet, tempor quis. Aliquam ante. Proin in tellus sit amet nibh dignissim sagittis. Vivamus porttitor turpis ac leo. Duis bibendum, lectus ut viverra rhoncus, dolor nunc faucibus libero, eget facilisis enim ipsum id lacus. In sem justo, commodo ut, suscipit at, pharetra vitae, orci. Aliquam erat volutpat. Nulla est.
71Vivamus luctus egestas leo. Aenean fermentum risus id tortor. Mauris dictum facilisis augue. Aliquam erat volutpat. Aliquam ornare wisi eu metus. Aliquam id dolor. Duis condimentum augue id magna semper rutrum. Donec iaculis gravida nulla. Pellentesque ipsum. Etiam dictum tincidunt diam. Quisque tincidunt scelerisque libero. Etiam egestas wisi a erat.
72Integer lacinia. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris tincidunt sem sed arcu. Nullam feugiat, turpis at pulvinar vulputate, erat libero tristique tellus, nec bibendum odio risus sit amet ante. Aliquam id dolor. Maecenas sollicitudin. Et harum quidem rerum facilis est et expedita distinctio. Mauris suscipit, ligula sit amet pharetra semper, nibh ante cursus purus, vel sagittis velit mauris vel metus. Nullam dapibus fermentum ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Pellentesque sapien. Duis risus. Mauris elementum mauris vitae tortor. Suspendisse nisl. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim.
73In laoreet, magna id viverra tincidunt, sem odio bibendum justo, vel imperdiet sapien wisi sed libero. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Nullam justo enim, consectetuer nec, ullamcorper ac, vestibulum in, elit. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Maecenas lorem. Etiam posuere lacus quis dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Curabitur ligula sapien, pulvinar a vestibulum quis, facilisis vel sapien. Nam sed tellus id magna elementum tincidunt. Suspendisse nisl. Vivamus luctus egestas leo. Nulla non arcu lacinia neque faucibus fringilla. Etiam dui sem, fermentum vitae, sagittis id, malesuada in, quam. Etiam dictum tincidunt diam. Etiam commodo dui eget wisi. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Duis ante orci, molestie vitae vehicula venenatis, tincidunt ac pede. Pellentesque sapien.
74EOD;
75
76 /**
77 * To be called from data reset code only,
78 * do not use in tests.
79 * @return void
80 */
81 public function reset() {
82 $this->usercounter = 0;
83 $this->categorycount = 0;
84 $this->coursecount = 0;
85 $this->scalecount = 0;
86
5c3c2c81 87 foreach ($this->generators as $generator) {
7e7cfe7a
PS
88 $generator->reset();
89 }
90 }
91
92 /**
ba203de1
TH
93 * Return generator for given plugin or component.
94 * @param string $component the component name, e.g. 'mod_forum' or 'core_question'.
95 * @return component_generator_base or rather an instance of the appropriate subclass.
7e7cfe7a
PS
96 */
97 public function get_plugin_generator($component) {
56da374e 98 list($type, $plugin) = core_component::normalize_component($component);
ba203de1
TH
99 $cleancomponent = $type . '_' . $plugin;
100 if ($cleancomponent != $component) {
101 debugging("Please specify the component you want a generator for as " .
102 "{$cleancomponent}, not {$component}.", DEBUG_DEVELOPER);
103 $component = $cleancomponent;
104 }
7e7cfe7a 105
ba203de1
TH
106 if (isset($this->generators[$component])) {
107 return $this->generators[$component];
7e7cfe7a
PS
108 }
109
b0d1d941 110 $dir = core_component::get_component_directory($component);
ba203de1
TH
111 $lib = $dir . '/tests/generator/lib.php';
112 if (!$dir || !is_readable($lib)) {
113 throw new coding_exception("Component {$component} does not support " .
114 "generators yet. Missing tests/generator/lib.php.");
115 }
7e7cfe7a 116
ba203de1
TH
117 include_once($lib);
118 $classname = $component . '_generator';
119
120 if (!class_exists($classname)) {
121 throw new coding_exception("Component {$component} does not support " .
122 "data generators yet. Class {$classname} not found.");
7e7cfe7a
PS
123 }
124
ba203de1
TH
125 $this->generators[$component] = new $classname($this);
126 return $this->generators[$component];
7e7cfe7a
PS
127 }
128
129 /**
130 * Create a test user
131 * @param array|stdClass $record
132 * @param array $options
133 * @return stdClass user record
134 */
135 public function create_user($record=null, array $options=null) {
136 global $DB, $CFG;
137
138 $this->usercounter++;
139 $i = $this->usercounter;
140
141 $record = (array)$record;
142
143 if (!isset($record['auth'])) {
144 $record['auth'] = 'manual';
145 }
146
147 if (!isset($record['firstname']) and !isset($record['lastname'])) {
148 $country = rand(0, 5);
149 $firstname = rand(0, 4);
150 $lastname = rand(0, 4);
151 $female = rand(0, 1);
152 $record['firstname'] = $this->firstnames[($country*10) + $firstname + ($female*5)];
153 $record['lastname'] = $this->lastnames[($country*10) + $lastname + ($female*5)];
154
155 } else if (!isset($record['firstname'])) {
156 $record['firstname'] = 'Firstname'.$i;
157
158 } else if (!isset($record['lastname'])) {
159 $record['lastname'] = 'Lastname'.$i;
160 }
161
a327f25e
AG
162 if (!isset($record['firstnamephonetic'])) {
163 $firstnamephonetic = rand(0, 59);
164 $record['firstnamephonetic'] = $this->firstnames[$firstnamephonetic];
165 }
166
167 if (!isset($record['lasttnamephonetic'])) {
168 $lastnamephonetic = rand(0, 59);
169 $record['lastnamephonetic'] = $this->lastnames[$lastnamephonetic];
170 }
171
172 if (!isset($record['middlename'])) {
173 $middlename = rand(0, 59);
174 $record['middlename'] = $this->firstnames[$middlename];
175 }
176
177 if (!isset($record['alternatename'])) {
178 $alternatename = rand(0, 59);
179 $record['alternatename'] = $this->firstnames[$alternatename];
180 }
181
7e7cfe7a
PS
182 if (!isset($record['idnumber'])) {
183 $record['idnumber'] = '';
184 }
185
186 if (!isset($record['mnethostid'])) {
187 $record['mnethostid'] = $CFG->mnet_localhost_id;
188 }
189
190 if (!isset($record['username'])) {
fe67134e
PS
191 $record['username'] = 'username'.$i;
192 $j = 2;
7e7cfe7a 193 while ($DB->record_exists('user', array('username'=>$record['username'], 'mnethostid'=>$record['mnethostid']))) {
fe67134e
PS
194 $record['username'] = 'username'.$i.'_'.$j;
195 $j++;
7e7cfe7a
PS
196 }
197 }
198
dbf60a04
PS
199 if (isset($record['password'])) {
200 $record['password'] = hash_internal_user_password($record['password']);
201 } else {
202 // The auth plugin may not fully support this,
203 // but it is still better/faster than hashing random stuff.
204 $record['password'] = AUTH_PASSWORD_NOT_CACHED;
7e7cfe7a
PS
205 }
206
207 if (!isset($record['email'])) {
208 $record['email'] = $record['username'].'@example.com';
209 }
210
211 if (!isset($record['confirmed'])) {
212 $record['confirmed'] = 1;
213 }
214
215 if (!isset($record['lang'])) {
216 $record['lang'] = 'en';
217 }
218
219 if (!isset($record['maildisplay'])) {
220 $record['maildisplay'] = 1;
221 }
222
223 if (!isset($record['deleted'])) {
224 $record['deleted'] = 0;
225 }
226
227 $record['timecreated'] = time();
228 $record['timemodified'] = $record['timecreated'];
229 $record['lastip'] = '0.0.0.0';
230
7e7cfe7a
PS
231 if ($record['deleted']) {
232 $delname = $record['email'].'.'.time();
233 while ($DB->record_exists('user', array('username'=>$delname))) {
234 $delname++;
235 }
236 $record['idnumber'] = '';
237 $record['email'] = md5($record['username']);
238 $record['username'] = $delname;
239 $record['picture'] = 0;
240 }
241
242 $userid = $DB->insert_record('user', $record);
243
244 if (!$record['deleted']) {
245 context_user::instance($userid);
246 }
247
248 return $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
249 }
250
251 /**
252 * Create a test course category
253 * @param array|stdClass $record
254 * @param array $options
b28bb7e8 255 * @return coursecat course category record
7e7cfe7a 256 */
4729332b 257 public function create_category($record=null, array $options=null) {
7e7cfe7a 258 global $DB, $CFG;
b28bb7e8 259 require_once("$CFG->libdir/coursecatlib.php");
7e7cfe7a
PS
260
261 $this->categorycount++;
262 $i = $this->categorycount;
263
264 $record = (array)$record;
265
266 if (!isset($record['name'])) {
267 $record['name'] = 'Course category '.$i;
268 }
269
7e7cfe7a
PS
270 if (!isset($record['description'])) {
271 $record['description'] = "Test course category $i\n$this->loremipsum";
272 }
273
b28bb7e8
MG
274 if (!isset($record['idnumber'])) {
275 $record['idnumber'] = '';
7e7cfe7a 276 }
7e7cfe7a 277
b28bb7e8 278 return coursecat::create($record);
7e7cfe7a
PS
279 }
280
4729332b
PS
281 /**
282 * Create test cohort.
283 * @param array|stdClass $record
284 * @param array $options
285 * @return stdClass cohort record
286 */
287 public function create_cohort($record=null, array $options=null) {
288 global $DB, $CFG;
289 require_once("$CFG->dirroot/cohort/lib.php");
290
291 $this->cohortcount++;
292 $i = $this->cohortcount;
293
294 $record = (array)$record;
295
296 if (!isset($record['contextid'])) {
297 $record['contextid'] = context_system::instance()->id;
298 }
299
300 if (!isset($record['name'])) {
301 $record['name'] = 'Cohort '.$i;
302 }
303
304 if (!isset($record['idnumber'])) {
305 $record['idnumber'] = '';
306 }
307
308 if (!isset($record['description'])) {
309 $record['description'] = "Test cohort $i\n$this->loremipsum";
310 }
311
312 if (!isset($record['descriptionformat'])) {
313 $record['descriptionformat'] = FORMAT_MOODLE;
314 }
315
316 if (!isset($record['component'])) {
317 $record['component'] = '';
318 }
319
320 $id = cohort_add_cohort((object)$record);
321
322 return $DB->get_record('cohort', array('id'=>$id), '*', MUST_EXIST);
323 }
324
7e7cfe7a
PS
325 /**
326 * Create a test course
327 * @param array|stdClass $record
328 * @param array $options with keys:
329 * 'createsections'=>bool precreate all sections
330 * @return stdClass course record
331 */
4729332b 332 public function create_course($record=null, array $options=null) {
7e7cfe7a
PS
333 global $DB, $CFG;
334 require_once("$CFG->dirroot/course/lib.php");
335
336 $this->coursecount++;
337 $i = $this->coursecount;
338
339 $record = (array)$record;
340
341 if (!isset($record['fullname'])) {
342 $record['fullname'] = 'Test course '.$i;
343 }
344
345 if (!isset($record['shortname'])) {
346 $record['shortname'] = 'tc_'.$i;
347 }
348
349 if (!isset($record['idnumber'])) {
350 $record['idnumber'] = '';
351 }
352
353 if (!isset($record['format'])) {
354 $record['format'] = 'topics';
355 }
356
357 if (!isset($record['newsitems'])) {
358 $record['newsitems'] = 0;
359 }
360
361 if (!isset($record['numsections'])) {
362 $record['numsections'] = 5;
363 }
364
4a38e659
PS
365 if (!isset($record['summary'])) {
366 $record['summary'] = "Test course $i\n$this->loremipsum";
7e7cfe7a
PS
367 }
368
4a38e659
PS
369 if (!isset($record['summaryformat'])) {
370 $record['summaryformat'] = FORMAT_MOODLE;
7e7cfe7a
PS
371 }
372
373 if (!isset($record['category'])) {
374 $record['category'] = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
375 }
376
377 $course = create_course((object)$record);
378 context_course::instance($course->id);
7e7cfe7a 379 if (!empty($options['createsections'])) {
384c3510
MG
380 if (isset($course->numsections)) {
381 course_create_sections_if_missing($course, range(0, $course->numsections));
382 } else {
383 course_create_sections_if_missing($course, 0);
7e7cfe7a
PS
384 }
385 }
386
387 return $course;
388 }
389
390 /**
391 * Create course section if does not exist yet
384c3510 392 * @param array|stdClass $record must contain 'course' and 'section' attributes
7e7cfe7a
PS
393 * @param array|null $options
394 * @return stdClass
395 * @throws coding_exception
396 */
397 public function create_course_section($record = null, array $options = null) {
398 global $DB;
399
400 $record = (array)$record;
401
402 if (empty($record['course'])) {
5c3c2c81 403 throw new coding_exception('course must be present in testing_data_generator::create_course_section() $record');
7e7cfe7a
PS
404 }
405
406 if (!isset($record['section'])) {
5c3c2c81 407 throw new coding_exception('section must be present in testing_data_generator::create_course_section() $record');
7e7cfe7a
PS
408 }
409
b46be6ad
MG
410 course_create_sections_if_missing($record['course'], $record['section']);
411 return get_fast_modinfo($record['course'])->get_section_info($record['section']);
7e7cfe7a
PS
412 }
413
414 /**
415 * Create a test block
416 * @param string $blockname
417 * @param array|stdClass $record
418 * @param array $options
419 * @return stdClass block instance record
420 */
421 public function create_block($blockname, $record=null, array $options=null) {
422 $generator = $this->get_plugin_generator('block_'.$blockname);
423 return $generator->create_instance($record, $options);
424 }
425
426 /**
427 * Create a test module
428 * @param string $modulename
429 * @param array|stdClass $record
430 * @param array $options
431 * @return stdClass activity record
432 */
433 public function create_module($modulename, $record=null, array $options=null) {
434 $generator = $this->get_plugin_generator('mod_'.$modulename);
435 return $generator->create_instance($record, $options);
436 }
437
438 /**
439 * Create a test group for the specified course
440 *
441 * $record should be either an array or a stdClass containing infomation about the group to create.
442 * At the very least it needs to contain courseid.
443 * Default values are added for name, description, and descriptionformat if they are not present.
444 *
6b219869
DM
445 * This function calls groups_create_group() to create the group within the database.
446 * @see groups_create_group
7e7cfe7a
PS
447 * @param array|stdClass $record
448 * @return stdClass group record
449 */
450 public function create_group($record) {
451 global $DB, $CFG;
452
453 require_once($CFG->dirroot . '/group/lib.php');
454
455 $this->groupcount++;
456 $i = $this->groupcount;
457
458 $record = (array)$record;
459
460 if (empty($record['courseid'])) {
5c3c2c81 461 throw new coding_exception('courseid must be present in testing_data_generator::create_group() $record');
7e7cfe7a
PS
462 }
463
464 if (!isset($record['name'])) {
465 $record['name'] = 'group-' . $i;
466 }
467
468 if (!isset($record['description'])) {
469 $record['description'] = "Test Group $i\n{$this->loremipsum}";
470 }
471
472 if (!isset($record['descriptionformat'])) {
473 $record['descriptionformat'] = FORMAT_MOODLE;
474 }
475
476 $id = groups_create_group((object)$record);
477
478 return $DB->get_record('groups', array('id'=>$id));
479 }
480
87bb583c
DM
481 /**
482 * Create a test group member
483 * @param array|stdClass $record
484 * @throws coding_exception
485 * @return boolean
486 */
487 public function create_group_member($record) {
488 global $DB, $CFG;
489
490 require_once($CFG->dirroot . '/group/lib.php');
491
492 $record = (array)$record;
493
494 if (empty($record['userid'])) {
495 throw new coding_exception('user must be present in testing_util::create_group_member() $record');
496 }
497
498 if (!isset($record['groupid'])) {
499 throw new coding_exception('group must be present in testing_util::create_group_member() $record');
500 }
501
502 if (!isset($record['component'])) {
503 $record['component'] = null;
504 }
505 if (!isset($record['itemid'])) {
506 $record['itemid'] = 0;
507 }
508
509 return groups_add_member($record['groupid'], $record['userid'], $record['component'], $record['itemid']);
510 }
511
7e7cfe7a
PS
512 /**
513 * Create a test grouping for the specified course
514 *
515 * $record should be either an array or a stdClass containing infomation about the grouping to create.
516 * At the very least it needs to contain courseid.
517 * Default values are added for name, description, and descriptionformat if they are not present.
518 *
6b219869
DM
519 * This function calls groups_create_grouping() to create the grouping within the database.
520 * @see groups_create_grouping
7e7cfe7a
PS
521 * @param array|stdClass $record
522 * @return stdClass grouping record
523 */
524 public function create_grouping($record) {
525 global $DB, $CFG;
526
527 require_once($CFG->dirroot . '/group/lib.php');
528
529 $this->groupingcount++;
530 $i = $this->groupingcount;
531
532 $record = (array)$record;
533
534 if (empty($record['courseid'])) {
5c3c2c81 535 throw new coding_exception('courseid must be present in testing_data_generator::create_grouping() $record');
7e7cfe7a
PS
536 }
537
538 if (!isset($record['name'])) {
539 $record['name'] = 'grouping-' . $i;
540 }
541
542 if (!isset($record['description'])) {
543 $record['description'] = "Test Grouping $i\n{$this->loremipsum}";
544 }
545
546 if (!isset($record['descriptionformat'])) {
547 $record['descriptionformat'] = FORMAT_MOODLE;
548 }
549
550 $id = groups_create_grouping((object)$record);
551
552 return $DB->get_record('groupings', array('id'=>$id));
553 }
554
87bb583c
DM
555 /**
556 * Create a test grouping group
557 * @param array|stdClass $record
558 * @throws coding_exception
559 * @return boolean
560 */
561 public function create_grouping_group($record) {
562 global $DB, $CFG;
563
564 require_once($CFG->dirroot . '/group/lib.php');
565
566 $record = (array)$record;
567
568 if (empty($record['groupingid'])) {
569 throw new coding_exception('grouping must be present in testing::create_grouping_group() $record');
570 }
571
572 if (!isset($record['groupid'])) {
573 throw new coding_exception('group must be present in testing_util::create_grouping_group() $record');
574 }
575
576 return groups_assign_grouping($record['groupingid'], $record['groupid']);
577 }
578
0852bbae
FM
579 /**
580 * Create an instance of a repository.
581 *
582 * @param string type of repository to create an instance for.
583 * @param array|stdClass $record data to use to up set the instance.
584 * @param array $options options
585 * @return stdClass repository instance record
ba375bcb 586 * @since 2.5.1
0852bbae
FM
587 */
588 public function create_repository($type, $record=null, array $options = null) {
0852bbae
FM
589 $generator = $this->get_plugin_generator('repository_'.$type);
590 return $generator->create_instance($record, $options);
591 }
592
593 /**
594 * Create an instance of a repository.
595 *
596 * @param string type of repository to create an instance for.
597 * @param array|stdClass $record data to use to up set the instance.
598 * @param array $options options
599 * @return repository_type object
ba375bcb 600 * @since 2.5.1
0852bbae
FM
601 */
602 public function create_repository_type($type, $record=null, array $options = null) {
0852bbae
FM
603 $generator = $this->get_plugin_generator('repository_'.$type);
604 return $generator->create_type($record, $options);
605 }
606
607
7e7cfe7a
PS
608 /**
609 * Create a test scale
610 * @param array|stdClass $record
611 * @param array $options
612 * @return stdClass block instance record
613 */
614 public function create_scale($record=null, array $options=null) {
615 global $DB;
616
617 $this->scalecount++;
618 $i = $this->scalecount;
619
620 $record = (array)$record;
621
622 if (!isset($record['name'])) {
623 $record['name'] = 'Test scale '.$i;
624 }
625
626 if (!isset($record['scale'])) {
627 $record['scale'] = 'A,B,C,D,F';
628 }
629
630 if (!isset($record['courseid'])) {
631 $record['courseid'] = 0;
632 }
633
634 if (!isset($record['userid'])) {
635 $record['userid'] = 0;
636 }
637
638 if (!isset($record['description'])) {
639 $record['description'] = 'Test scale description '.$i;
640 }
641
642 if (!isset($record['descriptionformat'])) {
643 $record['descriptionformat'] = FORMAT_MOODLE;
644 }
645
646 $record['timemodified'] = time();
647
648 if (isset($record['id'])) {
649 $DB->import_record('scale', $record);
650 $DB->get_manager()->reset_sequence('scale');
651 $id = $record['id'];
652 } else {
653 $id = $DB->insert_record('scale', $record);
654 }
655
656 return $DB->get_record('scale', array('id'=>$id), '*', MUST_EXIST);
657 }
4f5789ea 658
ba203de1
TH
659 /**
660 * Helper method which combines $defaults with the values specified in $record.
661 * If $record is an object, it is converted to an array.
662 * Then, for each key that is in $defaults, but not in $record, the value
663 * from $defaults is copied.
664 * @param array $defaults the default value for each field with
665 * @param array|stdClass $record
666 * @return array updated $record.
667 */
668 public function combine_defaults_and_record(array $defaults, $record) {
669 $record = (array) $record;
670
671 foreach ($defaults as $key => $defaults) {
672 if (!array_key_exists($key, $record)) {
673 $record[$key] = $defaults;
674 }
675 }
676 return $record;
677 }
678
4f5789ea
PS
679 /**
680 * Simplified enrolment of user to course using default options.
681 *
682 * It is strongly recommended to use only this method for 'manual' and 'self' plugins only!!!
683 *
684 * @param int $userid
685 * @param int $courseid
686 * @param int $roleid optional role id, use only with manual plugin
687 * @param string $enrol name of enrol plugin,
688 * there must be exactly one instance in course,
689 * it must support enrol_user() method.
1ecb8044
RT
690 * @param int $timestart (optional) 0 means unknown
691 * @param int $timeend (optional) 0 means forever
692 * @param int $status (optional) default to ENROL_USER_ACTIVE for new enrolments
4f5789ea
PS
693 * @return bool success
694 */
e6cc5347 695 public function enrol_user($userid, $courseid, $roleid = null, $enrol = 'manual', $timestart = 0, $timeend = 0, $status = null) {
4f5789ea
PS
696 global $DB;
697
698 if (!$plugin = enrol_get_plugin($enrol)) {
699 return false;
700 }
701
702 $instances = $DB->get_records('enrol', array('courseid'=>$courseid, 'enrol'=>$enrol));
703 if (count($instances) != 1) {
704 return false;
705 }
706 $instance = reset($instances);
707
708 if (is_null($roleid) and $instance->roleid) {
709 $roleid = $instance->roleid;
710 }
711
e6cc5347 712 $plugin->enrol_user($instance, $userid, $roleid, $timestart, $timeend, $status);
4f5789ea
PS
713 return true;
714 }
7e7cfe7a 715}
6b219869
DM
716
717/**
718 * Deprecated in favour of testing_data_generator
719 *
720 * @deprecated since Moodle 2.5 MDL-37457 - please do not use this function any more.
721 * @todo MDL-37517 This will be deleted in Moodle 2.7
722 * @see testing_data_generator
723 * @package core
724 * @category test
725 * @copyright 2012 David Monllaó
726 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
727 */
728class phpunit_data_generator extends testing_data_generator {
729
730 /**
731 * Dumb constructor to throw the deprecated notification
732 */
733 public function __construct() {
734 debugging('Class phpunit_data_generator is deprecated, please use class testing_module_generator instead', DEBUG_DEVELOPER);
735 }
736}