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 * mod_lesson data generator.
19 *
20 * @package    mod_lesson
21 * @category   test
22 * @copyright  2013 Marina Glancy
23 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28/**
29 * mod_lesson data generator class.
30 *
31 * @package    mod_lesson
32 * @category   test
33 * @copyright  2013 Marina Glancy
34 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35 */
36class mod_lesson_generator extends testing_module_generator {
37
38    /**
39     * @var int keep track of how many pages have been created.
40     */
41    protected $pagecount = 0;
42
43    /**
44     * To be called from data reset code only,
45     * do not use in tests.
46     * @return void
47     */
48    public function reset() {
49        $this->pagecount = 0;
50        parent::reset();
51    }
52
53    public function create_instance($record = null, array $options = null) {
54        global $CFG;
55
56        // Add default values for lesson.
57        $lessonconfig = get_config('mod_lesson');
58        $record = (array)$record + array(
59            'progressbar' => $lessonconfig->progressbar,
60            'ongoing' => $lessonconfig->ongoing,
61            'displayleft' => $lessonconfig->displayleftmenu,
62            'displayleftif' => $lessonconfig->displayleftif,
63            'slideshow' => $lessonconfig->slideshow,
64            'maxanswers' => $lessonconfig->maxanswers,
65            'feedback' => $lessonconfig->defaultfeedback,
66            'activitylink' => 0,
67            'available' => 0,
68            'deadline' => 0,
69            'usepassword' => 0,
70            'password' => '',
71            'dependency' => 0,
72            'timespent' => 0,
73            'completed' => 0,
74            'gradebetterthan' => 0,
75            'modattempts' => $lessonconfig->modattempts,
76            'review' => $lessonconfig->displayreview,
77            'maxattempts' => $lessonconfig->maximumnumberofattempts,
78            'nextpagedefault' => $lessonconfig->defaultnextpage,
79            'maxpages' => $lessonconfig->numberofpagestoshow,
80            'practice' => $lessonconfig->practice,
81            'custom' => $lessonconfig->customscoring,
82            'retake' => $lessonconfig->retakesallowed,
83            'usemaxgrade' => $lessonconfig->handlingofretakes,
84            'minquestions' => $lessonconfig->minimumnumberofquestions,
85            'grade' => 100,
86        );
87        if (!isset($record['mediafile'])) {
88            require_once($CFG->libdir.'/filelib.php');
89            $record['mediafile'] = file_get_unused_draft_itemid();
90        }
91
92        return parent::create_instance($record, (array)$options);
93    }
94
95    public function create_content($lesson, $record = array()) {
96        global $DB, $CFG;
97        require_once($CFG->dirroot.'/mod/lesson/locallib.php');
98        $now = time();
99        $this->pagecount++;
100        $record = (array)$record + array(
101            'lessonid' => $lesson->id,
102            'title' => 'Lesson page '.$this->pagecount,
103            'timecreated' => $now,
104            'qtype' => 20, // LESSON_PAGE_BRANCHTABLE
105            'pageid' => 0, // By default insert in the beginning.
106        );
107        if (!isset($record['contents_editor'])) {
108            $record['contents_editor'] = array(
109                'text' => 'Contents of lesson page '.$this->pagecount,
110                'format' => FORMAT_MOODLE,
111                'itemid' => 0,
112            );
113        }
114        $context = context_module::instance($lesson->cmid);
115        $page = lesson_page::create((object)$record, new lesson($lesson), $context, $CFG->maxbytes);
116        return $DB->get_record('lesson_pages', array('id' => $page->id), '*', MUST_EXIST);
117    }
118
119    /**
120     * Create True/false question pages.
121     * @param object $lesson
122     * @param array $record
123     * @return int
124     */
125    public function create_question_truefalse($lesson, $record = array()) {
126        global $DB, $CFG;
127        require_once($CFG->dirroot.'/mod/lesson/locallib.php');
128        $now = time();
129        $this->pagecount++;
130        $record = (array)$record + array(
131            'lessonid' => $lesson->id,
132            'title' => 'Lesson TF question '.$this->pagecount,
133            'timecreated' => $now,
134            'qtype' => 2,  // LESSON_PAGE_TRUEFALSE.
135            'pageid' => 0, // By default insert in the beginning.
136        );
137        if (!isset($record['contents_editor'])) {
138            $record['contents_editor'] = array(
139                'text' => 'The answer is TRUE '.$this->pagecount,
140                'format' => FORMAT_HTML,
141                'itemid' => 0
142            );
143        }
144
145        // First Answer (TRUE).
146        if (!isset($record['answer_editor'][0])) {
147            $record['answer_editor'][0] = array(
148                'text' => 'TRUE answer for '.$this->pagecount,
149                'format' => FORMAT_HTML
150            );
151        }
152        if (!isset($record['jumpto'][0])) {
153            $record['jumpto'][0] = LESSON_NEXTPAGE;
154        }
155
156        // Second Answer (FALSE).
157        if (!isset($record['answer_editor'][1])) {
158            $record['answer_editor'][1] = array(
159                'text' => 'FALSE answer for '.$this->pagecount,
160                'format' => FORMAT_HTML
161            );
162        }
163        if (!isset($record['jumpto'][1])) {
164            $record['jumpto'][1] = LESSON_THISPAGE;
165        }
166
167        $context = context_module::instance($lesson->cmid);
168        $page = lesson_page::create((object)$record, new lesson($lesson), $context, $CFG->maxbytes);
169        return $DB->get_record('lesson_pages', array('id' => $page->id), '*', MUST_EXIST);
170    }
171
172    /**
173     * Create multichoice question pages.
174     * @param object $lesson
175     * @param array $record
176     * @return int
177     */
178    public function create_question_multichoice($lesson, $record = array()) {
179        global $DB, $CFG;
180        require_once($CFG->dirroot.'/mod/lesson/locallib.php');
181        $now = time();
182        $this->pagecount++;
183        $record = (array)$record + array(
184            'lessonid' => $lesson->id,
185            'title' => 'Lesson multichoice question '.$this->pagecount,
186            'timecreated' => $now,
187            'qtype' => 3,  // LESSON_PAGE_MULTICHOICE.
188            'pageid' => 0, // By default insert in the beginning.
189        );
190        if (!isset($record['contents_editor'])) {
191            $record['contents_editor'] = array(
192                'text' => 'Pick the correct answer '.$this->pagecount,
193                'format' => FORMAT_HTML,
194                'itemid' => 0
195            );
196        }
197
198        // First Answer (correct).
199        if (!isset($record['answer_editor'][0])) {
200            $record['answer_editor'][0] = array(
201                'text' => 'correct answer for '.$this->pagecount,
202                'format' => FORMAT_HTML
203            );
204        }
205        if (!isset($record['jumpto'][0])) {
206            $record['jumpto'][0] = LESSON_NEXTPAGE;
207        }
208
209        // Second Answer (incorrect).
210        if (!isset($record['answer_editor'][1])) {
211            $record['answer_editor'][1] = array(
212                'text' => 'correct answer for '.$this->pagecount,
213                'format' => FORMAT_HTML
214            );
215        }
216        if (!isset($record['jumpto'][1])) {
217            $record['jumpto'][1] = LESSON_THISPAGE;
218        }
219
220        $context = context_module::instance($lesson->cmid);
221        $page = lesson_page::create((object)$record, new lesson($lesson), $context, $CFG->maxbytes);
222        return $DB->get_record('lesson_pages', array('id' => $page->id), '*', MUST_EXIST);
223    }
224
225    /**
226     * Create essay question pages.
227     * @param object $lesson
228     * @param array $record
229     * @return int
230     */
231    public function create_question_essay($lesson, $record = array()) {
232        global $DB, $CFG;
233        require_once($CFG->dirroot.'/mod/lesson/locallib.php');
234        $now = time();
235        $this->pagecount++;
236        $record = (array)$record + array(
237            'lessonid' => $lesson->id,
238            'title' => 'Lesson Essay question '.$this->pagecount,
239            'timecreated' => $now,
240            'qtype' => 10, // LESSON_PAGE_ESSAY.
241            'pageid' => 0, // By default insert in the beginning.
242        );
243        if (!isset($record['contents_editor'])) {
244            $record['contents_editor'] = array(
245                'text' => 'Write an Essay '.$this->pagecount,
246                'format' => FORMAT_HTML,
247                'itemid' => 0
248            );
249        }
250
251        // Essays have an answer of NULL.
252        if (!isset($record['answer_editor'][0])) {
253            $record['answer_editor'][0] = array(
254                'text' => null,
255                'format' => FORMAT_MOODLE
256            );
257        }
258        if (!isset($record['jumpto'][0])) {
259            $record['jumpto'][0] = LESSON_NEXTPAGE;
260        }
261
262        $context = context_module::instance($lesson->cmid);
263        $page = lesson_page::create((object)$record, new lesson($lesson), $context, $CFG->maxbytes);
264        return $DB->get_record('lesson_pages', array('id' => $page->id), '*', MUST_EXIST);
265    }
266
267    /**
268     * Create matching question pages.
269     * @param object $lesson
270     * @param array $record
271     * @return int
272     */
273    public function create_question_matching($lesson, $record = array()) {
274        global $DB, $CFG;
275        require_once($CFG->dirroot.'/mod/lesson/locallib.php');
276        $now = time();
277        $this->pagecount++;
278        $record = (array)$record + array(
279            'lessonid' => $lesson->id,
280            'title' => 'Lesson Matching question '.$this->pagecount,
281            'timecreated' => $now,
282            'qtype' => 5,  // LESSON_PAGE_MATCHING.
283            'pageid' => 0, // By default insert in the beginning.
284        );
285        if (!isset($record['contents_editor'])) {
286            $record['contents_editor'] = array(
287                'text' => 'Match the values '.$this->pagecount,
288                'format' => FORMAT_HTML,
289                'itemid' => 0
290            );
291        }
292        // Feedback for correct result.
293        if (!isset($record['answer_editor'][0])) {
294            $record['answer_editor'][0] = array(
295                'text' => '',
296                'format' => FORMAT_HTML
297            );
298        }
299        // Feedback for wrong result.
300        if (!isset($record['answer_editor'][1])) {
301            $record['answer_editor'][1] = array(
302                'text' => '',
303                'format' => FORMAT_HTML
304            );
305        }
306        // First answer value.
307        if (!isset($record['answer_editor'][2])) {
308            $record['answer_editor'][2] = array(
309                'text' => 'Match value 1',
310                'format' => FORMAT_HTML
311            );
312        }
313        // First response value.
314        if (!isset($record['response_editor'][2])) {
315            $record['response_editor'][2] = 'Match answer 1';
316        }
317        // Second Matching value.
318        if (!isset($record['answer_editor'][3])) {
319            $record['answer_editor'][3] = array(
320                'text' => 'Match value 2',
321                'format' => FORMAT_HTML
322            );
323        }
324        // Second Matching answer.
325        if (!isset($record['response_editor'][3])) {
326            $record['response_editor'][3] = 'Match answer 2';
327        }
328
329        // Jump Values.
330        if (!isset($record['jumpto'][0])) {
331            $record['jumpto'][0] = LESSON_NEXTPAGE;
332        }
333        if (!isset($record['jumpto'][1])) {
334            $record['jumpto'][1] = LESSON_THISPAGE;
335        }
336
337        // Mark the correct values.
338        if (!isset($record['score'][0])) {
339            $record['score'][0] = 1;
340        }
341        $context = context_module::instance($lesson->cmid);
342        $page = lesson_page::create((object)$record, new lesson($lesson), $context, $CFG->maxbytes);
343        return $DB->get_record('lesson_pages', array('id' => $page->id), '*', MUST_EXIST);
344    }
345
346    /**
347     * Create shortanswer question pages.
348     * @param object $lesson
349     * @param array $record
350     * @return int
351     */
352    public function create_question_shortanswer($lesson, $record = array()) {
353        global $DB, $CFG;
354        require_once($CFG->dirroot.'/mod/lesson/locallib.php');
355        $now = time();
356        $this->pagecount++;
357        $record = (array)$record + array(
358            'lessonid' => $lesson->id,
359            'title' => 'Lesson Shortanswer question '.$this->pagecount,
360            'timecreated' => $now,
361            'qtype' => 1,  // LESSON_PAGE_SHORTANSWER.
362            'pageid' => 0, // By default insert in the beginning.
363        );
364        if (!isset($record['contents_editor'])) {
365            $record['contents_editor'] = array(
366                'text' => 'Fill in the blank '.$this->pagecount,
367                'format' => FORMAT_HTML,
368                'itemid' => 0
369            );
370        }
371
372        // First Answer (correct).
373        if (!isset($record['answer_editor'][0])) {
374            $record['answer_editor'][0] = array(
375                'text' => 'answer'.$this->pagecount,
376                'format' => FORMAT_MOODLE
377            );
378        }
379        if (!isset($record['jumpto'][0])) {
380            $record['jumpto'][0] = LESSON_NEXTPAGE;
381        }
382
383        $context = context_module::instance($lesson->cmid);
384        $page = lesson_page::create((object)$record, new lesson($lesson), $context, $CFG->maxbytes);
385        return $DB->get_record('lesson_pages', array('id' => $page->id), '*', MUST_EXIST);
386    }
387
388    /**
389     * Create shortanswer question pages.
390     * @param object $lesson
391     * @param array $record
392     * @return int
393     */
394    public function create_question_numeric($lesson, $record = array()) {
395        global $DB, $CFG;
396        require_once($CFG->dirroot.'/mod/lesson/locallib.php');
397        $now = time();
398        $this->pagecount++;
399        $record = (array)$record + array(
400            'lessonid' => $lesson->id,
401            'title' => 'Lesson numerical question '.$this->pagecount,
402            'timecreated' => $now,
403            'qtype' => 8,  // LESSON_PAGE_NUMERICAL.
404            'pageid' => 0, // By default insert in the beginning.
405        );
406        if (!isset($record['contents_editor'])) {
407            $record['contents_editor'] = array(
408                'text' => 'Numerical question '.$this->pagecount,
409                'format' => FORMAT_HTML,
410                'itemid' => 0
411            );
412        }
413
414        // First Answer (correct).
415        if (!isset($record['answer_editor'][0])) {
416            $record['answer_editor'][0] = array(
417                'text' => $this->pagecount,
418                'format' => FORMAT_MOODLE
419            );
420        }
421        if (!isset($record['jumpto'][0])) {
422            $record['jumpto'][0] = LESSON_NEXTPAGE;
423        }
424
425        $context = context_module::instance($lesson->cmid);
426        $page = lesson_page::create((object)$record, new lesson($lesson), $context, $CFG->maxbytes);
427        return $DB->get_record('lesson_pages', array('id' => $page->id), '*', MUST_EXIST);
428    }
429
430    /**
431     * Create a lesson override (either user or group).
432     *
433     * @param array $data must specify lessonid, and one of userid or groupid.
434     */
435    public function create_override(array $data): void {
436        global $DB;
437
438        if (!isset($data['lessonid'])) {
439            throw new coding_exception('Must specify lessonid when creating a lesson override.');
440        }
441
442        if (!isset($data['userid']) && !isset($data['groupid'])) {
443            throw new coding_exception('Must specify one of userid or groupid when creating a lesson override.');
444        }
445
446        if (isset($data['userid']) && isset($data['groupid'])) {
447            throw new coding_exception('Cannot specify both userid and groupid when creating a lesson override.');
448        }
449
450        $DB->insert_record('lesson_overrides', (object) $data);
451    }
452}
453