Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 21... Línea 21...
21
 * @copyright  2013 The Open University
21
 * @copyright  2013 The Open University
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
23
 */
Línea 24... Línea 24...
24
 
24
 
-
 
25
use core_question\local\bank\question_version_status;
Línea 25... Línea 26...
25
use core_question\local\bank\question_version_status;
26
use core\exception\coding_exception;
26
 
27
 
27
/**
28
/**
28
 * Class core_question_generator for generating question data.
29
 * Class core_question_generator for generating question data.
Línea 60... Línea 61...
60
        $defaults = [
61
        $defaults = [
61
            'name'       => 'Test question category ' . $this->categorycount,
62
            'name'       => 'Test question category ' . $this->categorycount,
62
            'info'       => '',
63
            'info'       => '',
63
            'infoformat' => FORMAT_HTML,
64
            'infoformat' => FORMAT_HTML,
64
            'stamp'      => make_unique_id_code(),
65
            'stamp'      => make_unique_id_code(),
65
            'sortorder'  => 999,
-
 
66
            'idnumber'   => null
66
            'idnumber'   => null,
67
        ];
67
        ];
Línea 68... Línea 68...
68
 
68
 
Línea 69... Línea 69...
69
        $record = $this->datagenerator->combine_defaults_and_record($defaults, $record);
69
        $record = $this->datagenerator->combine_defaults_and_record($defaults, $record);
70
 
70
 
71
        if (!isset($record['contextid'])) {
71
        if (!isset($record['contextid'])) {
72
            if (isset($record['parent'])) {
72
            if (isset($record['parent'])) {
-
 
73
                $record['contextid'] = $DB->get_field('question_categories', 'contextid', ['id' => $record['parent']]);
73
                $record['contextid'] = $DB->get_field('question_categories', 'contextid', ['id' => $record['parent']]);
74
            } else {
74
            } else {
75
                $qbank = $this->datagenerator->create_module('qbank', ['course' => SITEID]);
-
 
76
                $record['contextid'] = context_module::instance($qbank->cmid)->id;
-
 
77
            }
-
 
78
        } else {
-
 
79
            // Any requests for a question category in a contextlevel that is no longer supported
-
 
80
            // will have a qbank instance created on the associated context and then the category
-
 
81
            // will be made for that context instead.
-
 
82
            $context = context::instance_by_id($record['contextid']);
-
 
83
            if ($context->contextlevel !== CONTEXT_MODULE) {
-
 
84
                $course = match ($context->contextlevel) {
-
 
85
                    CONTEXT_COURSE => get_course($context->instanceid),
-
 
86
                    CONTEXT_SYSTEM => get_site(),
-
 
87
                    CONTEXT_COURSECAT => $this->datagenerator->create_course(['category' => $context->instanceid]),
-
 
88
                    default => throw new \Exception('Invalid context to infer a question bank from.'),
-
 
89
                };
-
 
90
                $qbank = \core_question\local\bank\question_bank_helper::get_default_open_instance_system_type($course, true);
-
 
91
                $bankcontext = context_module::instance($qbank->id);
-
 
92
            } else {
-
 
93
                $bankcontext = $context;
75
                $record['contextid'] = context_system::instance()->id;
94
            }
-
 
95
            $record['contextid'] = $bankcontext->id;
76
            }
96
        }
77
        }
97
 
78
        if (!isset($record['parent'])) {
98
        if (!isset($record['parent'])) {
-
 
99
            $record['parent'] = question_get_top_category($record['contextid'], true)->id;
-
 
100
        }
-
 
101
        if (!isset($record['sortorder'])) {
-
 
102
            $manager = new \core_question\category_manager();
79
            $record['parent'] = question_get_top_category($record['contextid'], true)->id;
103
            $record['sortorder'] = $manager->get_max_sortorder($record['parent']) + 1;
80
        }
104
        }
81
        $record['id'] = $DB->insert_record('question_categories', $record);
105
        $record['id'] = $DB->insert_record('question_categories', $record);
Línea 82... Línea 106...
82
        return (object) $record;
106
        return (object) $record;
Línea 136... Línea 160...
136
        $fromform = (object) $this->datagenerator->combine_defaults_and_record((array) $fromform, $overrides);
160
        $fromform = (object) $this->datagenerator->combine_defaults_and_record((array) $fromform, $overrides);
137
        $fromform->status = $fromform->status ?? $question->status;
161
        $fromform->status = $fromform->status ?? $question->status;
Línea 138... Línea 162...
138
 
162
 
Línea -... Línea 163...
-
 
163
        $question = question_bank::get_qtype($qtype)->save_question($question, $fromform);
139
        $question = question_bank::get_qtype($qtype)->save_question($question, $fromform);
164
 
140
 
165
        $validoverrides = ['createdby', 'modifiedby', 'timemodified'];
141
        if ($overrides && (array_key_exists('createdby', $overrides) || array_key_exists('modifiedby', $overrides))) {
166
        if ($overrides && !empty(array_intersect($validoverrides, array_keys($overrides)))) {
-
 
167
            // Manually update the createdby, modifiedby and timemodified because questiontypebase forces
142
            // Manually update the createdby and modifiedby because questiontypebase forces
168
            // current user and time and some tests require a specific user or time.
143
            // current user and some tests require a specific user.
169
            foreach ($validoverrides as $validoverride) {
144
            if (array_key_exists('createdby', $overrides)) {
170
                if (array_key_exists($validoverride, $overrides)) {
145
                $question->createdby = $overrides['createdby'];
-
 
146
            }
-
 
147
            if (array_key_exists('modifiedby', $overrides)) {
171
                    $question->{$validoverride} = $overrides[$validoverride];
148
                $question->modifiedby = $overrides['modifiedby'];
172
                }
149
            }
173
            }
150
            $DB->update_record('question', $question);
174
            $DB->update_record('question', $question);
151
        }
175
        }
Línea 157... Línea 181...
157
 
181
 
158
        return $question;
182
        return $question;
Línea 159... Línea 183...
159
    }
183
    }
160
 
184
 
161
    /**
185
    /**
162
     * Setup a course category, course, a question category, and 2 questions
186
     * Set up a course category, a course, a mod_qbank instance, a question category for the mod_qbank instance,
163
     * for testing.
-
 
164
     *
187
     * and 2 questions for testing.
165
     * @param string $type The type of question category to create.
188
     *
166
     * @return array The created data objects
189
     * @return array of the data objects mentioned above
167
     */
190
     */
168
    public function setup_course_and_questions($type = 'course') {
191
    public function setup_course_and_questions() {
169
        $datagenerator = $this->datagenerator;
192
        $datagenerator = $this->datagenerator;
170
        $category = $datagenerator->create_category();
193
        $category = $datagenerator->create_category();
171
        $course = $datagenerator->create_course([
194
        $course = $datagenerator->create_course([
172
            'numsections' => 5,
195
            'numsections' => 5,
173
            'category' => $category->id
-
 
174
        ]);
-
 
175
 
-
 
176
        switch ($type) {
196
            'category' => $category->id
177
            case 'category':
-
 
178
                $context = context_coursecat::instance($category->id);
-
 
179
                break;
-
 
180
 
-
 
181
            case 'system':
-
 
182
                $context = context_system::instance();
-
 
183
                break;
-
 
184
 
197
        ]);
185
            default:
-
 
186
                $context = context_course::instance($course->id);
-
 
Línea 187... Línea 198...
187
                break;
198
        $qbank = $datagenerator->create_module('qbank', ['course' => $course->id]);
Línea 188... Línea 199...
188
        }
199
        $context = context_module::instance($qbank->cmid);
189
 
200
 
190
        $qcat = $this->create_question_category(['contextid' => $context->id]);
201
        $qcat = $this->create_question_category(['contextid' => $context->id]);
191
 
202
 
Línea 192... Línea 203...
192
        $questions = [
203
        $questions = [
193
                $this->create_question('shortanswer', null, ['category' => $qcat->id]),
204
                $this->create_question('shortanswer', null, ['category' => $qcat->id]),
Línea 194... Línea 205...
194
                $this->create_question('shortanswer', null, ['category' => $qcat->id]),
205
                $this->create_question('shortanswer', null, ['category' => $qcat->id]),
195
        ];
206
        ];
196
 
207
 
Línea 261... Línea 272...
261
            $postdata[$qa->get_behaviour_field_name('submit')] = 1;
272
            $postdata[$qa->get_behaviour_field_name('submit')] = 1;
262
        }
273
        }
Línea 263... Línea 274...
263
 
274
 
264
        return $postdata;
275
        return $postdata;
-
 
276
    }
-
 
277
 
-
 
278
    /**
-
 
279
     * Given a context and a structure of categories and questions, generate that structure.
-
 
280
     *
-
 
281
     * The $structure parameter takes a multi-dimensional array of categories and questions, like this:
-
 
282
     * [
-
 
283
     *    'categoryname' => [
-
 
284
     *        'question1name' => 'questiontype',
-
 
285
     *        'question2name' => 'questiontype',
-
 
286
     *        'subcategoryname' => [
-
 
287
     *            'subquestion1name' => 'questiontype',
-
 
288
     *        ],
-
 
289
     *    ],
-
 
290
     * ]
-
 
291
     * Arrays are treated as categories, strings are treated as questions. The key in each case is used for the name of the category
-
 
292
     * or question. For subcategories, the method is called recursively to create all descendants.
-
 
293
     * The 'questiontype' string is the type of question to be generated, and will be passed to create_question.
-
 
294
     *
-
 
295
     * @param context $context The context to create the structure in.
-
 
296
     * @param array $structure The array of categories and questions, see above.
-
 
297
     * @param ?int $parentid The category to create the category or question within.
-
 
298
     * @return array The input structure, with the generated questions in place of the question types.
-
 
299
     */
-
 
300
    public function create_categories_and_questions(context $context, array $structure, ?int $parentid = null) {
-
 
301
        $createdcategories = [];
-
 
302
        foreach ($structure as $name => $item) {
-
 
303
            if (is_array($item)) {
-
 
304
                $categorydata = [
-
 
305
                    'name' => $name,
-
 
306
                    'contextid' => $context->id,
-
 
307
                ];
-
 
308
                if ($parentid) {
-
 
309
                    $categorydata['parent'] = $parentid;
-
 
310
                }
-
 
311
                $category = $this->create_question_category($categorydata);
-
 
312
                $createdcategories[$name] = $this->create_categories_and_questions($context, $item, $category->id);
-
 
313
            } else if (is_string($item)) {
-
 
314
                if (!$parentid) {
-
 
315
                    throw new coding_exception('You cannot create questions in a top-level category.');
-
 
316
                }
-
 
317
                $createdcategories[$name] = $this->create_question($item, null, ['name' => $name, 'category' => $parentid]);
-
 
318
            } else {
-
 
319
                throw new coding_exception('Structure items must be arrays or strings, ' . gettype($item) . ' found.');
-
 
320
            }
-
 
321
        }
-
 
322
        return $createdcategories;
265
    }
323
    }