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