Commit | Line | Data |
---|---|---|
5076b961 MG |
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 | * A form for cohort upload. | |
19 | * | |
20 | * @package core_cohort | |
21 | * @copyright 2014 Marina Glancy | |
22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
23 | */ | |
24 | ||
25 | defined('MOODLE_INTERNAL') || die(); | |
26 | ||
27 | require_once($CFG->libdir.'/formslib.php'); | |
28 | ||
29 | /** | |
30 | * Cohort upload form class | |
31 | * | |
32 | * @package core_cohort | |
33 | * @copyright 2014 Marina Glancy | |
34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
35 | */ | |
36 | class cohort_upload_form extends moodleform { | |
37 | /** @var array new cohorts that need to be created */ | |
38 | public $processeddata = null; | |
39 | /** @var array cached list of available contexts */ | |
40 | protected $contextoptions = null; | |
41 | /** @var array temporary cache for retrieved categories */ | |
42 | protected $categoriescache = array(); | |
43 | ||
44 | /** | |
45 | * Form definition | |
46 | */ | |
47 | public function definition() { | |
48 | $mform = $this->_form; | |
49 | $data = (object)$this->_customdata; | |
50 | ||
51 | $mform->addElement('hidden', 'returnurl'); | |
52 | $mform->setType('returnurl', PARAM_URL); | |
53 | ||
54 | $mform->addElement('header', 'cohortfileuploadform', get_string('uploadafile')); | |
55 | ||
56 | $filepickeroptions = array(); | |
57 | $filepickeroptions['filetypes'] = '*'; | |
58 | $filepickeroptions['maxbytes'] = get_max_upload_file_size(); | |
59 | $mform->addElement('filepicker', 'cohortfile', get_string('file'), null, $filepickeroptions); | |
60 | ||
61 | $choices = csv_import_reader::get_delimiter_list(); | |
62 | $mform->addElement('select', 'delimiter', get_string('csvdelimiter', 'tool_uploadcourse'), $choices); | |
63 | if (array_key_exists('cfg', $choices)) { | |
64 | $mform->setDefault('delimiter', 'cfg'); | |
65 | } else if (get_string('listsep', 'langconfig') == ';') { | |
66 | $mform->setDefault('delimiter', 'semicolon'); | |
67 | } else { | |
68 | $mform->setDefault('delimiter', 'comma'); | |
69 | } | |
70 | $mform->addHelpButton('delimiter', 'csvdelimiter', 'tool_uploadcourse'); | |
71 | ||
72 | $choices = core_text::get_encodings(); | |
73 | $mform->addElement('select', 'encoding', get_string('encoding', 'tool_uploadcourse'), $choices); | |
74 | $mform->setDefault('encoding', 'UTF-8'); | |
75 | $mform->addHelpButton('encoding', 'encoding', 'tool_uploadcourse'); | |
76 | ||
77 | $options = $this->get_context_options(); | |
78 | $mform->addElement('select', 'contextid', get_string('defaultcontext', 'cohort'), $options); | |
79 | ||
80 | $this->add_cohort_upload_buttons(true); | |
81 | $this->set_data($data); | |
82 | } | |
83 | ||
84 | /** | |
85 | * Add buttons to the form ("Upload cohorts", "Preview", "Cancel") | |
86 | */ | |
87 | protected function add_cohort_upload_buttons() { | |
88 | $mform = $this->_form; | |
89 | ||
90 | $buttonarray = array(); | |
91 | ||
92 | $submitlabel = get_string('uploadcohorts', 'cohort'); | |
93 | $buttonarray[] = $mform->createElement('submit', 'submitbutton', $submitlabel); | |
94 | ||
95 | $previewlabel = get_string('preview', 'cohort'); | |
96 | $buttonarray[] = $mform->createElement('submit', 'previewbutton', $previewlabel); | |
97 | $mform->registerNoSubmitButton('previewbutton'); | |
98 | ||
99 | $buttonarray[] = $mform->createElement('cancel'); | |
100 | ||
101 | $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); | |
102 | $mform->closeHeaderBefore('buttonar'); | |
103 | } | |
104 | ||
105 | /** | |
106 | * Process the uploaded file and allow the submit button only if it doest not have errors. | |
107 | */ | |
108 | public function definition_after_data() { | |
109 | $mform = $this->_form; | |
110 | $cohortfile = $mform->getElementValue('cohortfile'); | |
111 | $allowsubmitform = false; | |
112 | if ($cohortfile && ($file = $this->get_cohort_file($cohortfile))) { | |
113 | // File was uploaded. Parse it. | |
114 | $encoding = $mform->getElementValue('encoding')[0]; | |
115 | $delimiter = $mform->getElementValue('delimiter')[0]; | |
116 | $contextid = $mform->getElementValue('contextid')[0]; | |
117 | if (!empty($contextid) && ($context = context::instance_by_id($contextid, IGNORE_MISSING))) { | |
118 | $this->processeddata = $this->process_upload_file($file, $encoding, $delimiter, $context); | |
119 | if ($this->processeddata && count($this->processeddata) > 1 && !$this->processeddata[0]['errors']) { | |
120 | $allowsubmitform = true; | |
121 | } | |
122 | } | |
123 | } | |
124 | if (!$allowsubmitform) { | |
125 | // Hide submit button. | |
126 | $el = $mform->getElement('buttonar')->getElements()[0]; | |
127 | $el->setValue(''); | |
128 | $el->freeze(); | |
129 | } else { | |
130 | $mform->setExpanded('cohortfileuploadform', false); | |
131 | } | |
132 | ||
133 | } | |
134 | ||
135 | /** | |
136 | * Returns the list of contexts where current user can create cohorts. | |
137 | * | |
138 | * @return array | |
139 | */ | |
140 | protected function get_context_options() { | |
141 | global $CFG; | |
142 | require_once($CFG->libdir. '/coursecatlib.php'); | |
143 | if ($this->contextoptions === null) { | |
144 | $this->contextoptions = array(); | |
145 | $displaylist = coursecat::make_categories_list('moodle/cohort:manage'); | |
146 | // We need to index the options array by context id instead of category id and add option for system context. | |
147 | $syscontext = context_system::instance(); | |
148 | if (has_capability('moodle/cohort:manage', $syscontext)) { | |
149 | $this->contextoptions[$syscontext->id] = $syscontext->get_context_name(); | |
150 | } | |
151 | foreach ($displaylist as $cid => $name) { | |
152 | $context = context_coursecat::instance($cid); | |
153 | $this->contextoptions[$context->id] = $name; | |
154 | } | |
155 | } | |
156 | return $this->contextoptions; | |
157 | } | |
158 | ||
159 | public function validation($data, $files) { | |
160 | $errors = parent::validation($data, $files); | |
161 | if (empty($errors)) { | |
162 | if (empty($data['cohortfile']) || !($file = $this->get_cohort_file($data['cohortfile']))) { | |
163 | $errors['cohortfile'] = get_string('required'); | |
164 | } else { | |
165 | if (!empty($this->processeddata[0]['errors'])) { | |
166 | // Any value in $errors will notify that validation did not pass. The detailed errors will be shown in preview. | |
167 | $errors['dummy'] = ''; | |
168 | } | |
169 | } | |
170 | } | |
171 | return $errors; | |
172 | } | |
173 | ||
174 | /** | |
175 | * Returns the uploaded file if it is present. | |
176 | * | |
177 | * @param int $draftid | |
178 | * @return stored_file|null | |
179 | */ | |
180 | protected function get_cohort_file($draftid) { | |
181 | global $USER; | |
182 | // We can not use moodleform::get_file_content() method because we need the content before the form is validated. | |
183 | if (!$draftid) { | |
184 | return null; | |
185 | } | |
186 | $fs = get_file_storage(); | |
187 | $context = context_user::instance($USER->id); | |
188 | if (!$files = $fs->get_area_files($context->id, 'user', 'draft', $draftid, 'id DESC', false)) { | |
189 | return null; | |
190 | } | |
191 | $file = reset($files); | |
192 | ||
193 | return $file; | |
194 | ||
195 | } | |
196 | ||
197 | /** | |
198 | * Returns the list of prepared objects to be added as cohorts | |
199 | * | |
200 | * @return array of stdClass objects, each can be passed to {@link cohort_add_cohort()} | |
201 | */ | |
202 | public function get_cohorts_data() { | |
203 | $cohorts = array(); | |
204 | if ($this->processeddata) { | |
205 | foreach ($this->processeddata as $idx => $line) { | |
206 | if ($idx && !empty($line['data'])) { | |
207 | $cohorts[] = (object)$line['data']; | |
208 | } | |
209 | } | |
210 | } | |
211 | return $cohorts; | |
212 | } | |
213 | ||
214 | /** | |
215 | * Displays the preview of the uploaded file | |
216 | */ | |
217 | protected function preview_uploaded_cohorts() { | |
218 | global $OUTPUT; | |
219 | if (empty($this->processeddata)) { | |
220 | return; | |
221 | } | |
222 | foreach ($this->processeddata[0]['errors'] as $error) { | |
223 | echo $OUTPUT->notification($error); | |
224 | } | |
225 | foreach ($this->processeddata[0]['warnings'] as $warning) { | |
226 | echo $OUTPUT->notification($warning, 'notifymessage'); | |
227 | } | |
228 | $table = new html_table(); | |
229 | $table->id = 'previewuploadedcohorts'; | |
230 | $columns = $this->processeddata[0]['data']; | |
231 | $columns['contextid'] = get_string('context', 'role'); | |
232 | ||
233 | // Add column names to the preview table. | |
234 | $table->head = array(''); | |
235 | foreach ($columns as $key => $value) { | |
236 | $table->head[] = $value; | |
237 | } | |
238 | $table->head[] = get_string('status'); | |
239 | ||
240 | // Add (some) rows to the preview table. | |
241 | $previewdrows = $this->get_previewed_rows(); | |
242 | foreach ($previewdrows as $idx) { | |
243 | $line = $this->processeddata[$idx]; | |
244 | $cells = array(new html_table_cell($idx)); | |
245 | $context = context::instance_by_id($line['data']['contextid']); | |
246 | foreach ($columns as $key => $value) { | |
247 | if ($key === 'contextid') { | |
248 | $text = html_writer::link(new moodle_url('/cohort/index.php', array('contextid' => $context->id)), | |
249 | $context->get_context_name(false)); | |
250 | } else { | |
251 | $text = s($line['data'][$key]); | |
252 | } | |
253 | $cells[] = new html_table_cell($text); | |
254 | } | |
255 | $text = ''; | |
256 | if ($line['errors']) { | |
257 | $text .= html_writer::div(join('<br>', $line['errors']), 'notifyproblem'); | |
258 | } | |
259 | if ($line['warnings']) { | |
260 | $text .= html_writer::div(join('<br>', $line['warnings'])); | |
261 | } | |
262 | $cells[] = new html_table_cell($text); | |
263 | $table->data[] = new html_table_row($cells); | |
264 | } | |
265 | if ($notdisplayed = count($this->processeddata) - count($previewdrows) - 1) { | |
266 | $cell = new html_table_cell(get_string('displayedrows', 'cohort', | |
267 | (object)array('displayed' => count($previewdrows), 'total' => count($this->processeddata) - 1))); | |
268 | $cell->colspan = count($columns) + 2; | |
269 | $table->data[] = new html_table_row(array($cell)); | |
270 | } | |
271 | echo html_writer::table($table); | |
272 | } | |
273 | ||
274 | /** | |
275 | * Find up rows to show in preview | |
276 | * | |
277 | * Number of previewed rows is limited but rows with errors and warnings have priority. | |
278 | * | |
279 | * @return array | |
280 | */ | |
281 | protected function get_previewed_rows() { | |
282 | $previewlimit = 10; | |
283 | if (count($this->processeddata) <= 1) { | |
284 | $rows = array(); | |
285 | } else if (count($this->processeddata) < $previewlimit + 1) { | |
286 | // Return all rows. | |
287 | $rows = range(1, count($this->processeddata) - 1); | |
288 | } else { | |
289 | // First find rows with errors and warnings (no more than 10 of each). | |
290 | $errorrows = $warningrows = array(); | |
291 | foreach ($this->processeddata as $rownum => $line) { | |
292 | if ($rownum && $line['errors']) { | |
293 | $errorrows[] = $rownum; | |
294 | if (count($errorrows) >= $previewlimit) { | |
295 | return $errorrows; | |
296 | } | |
297 | } else if ($rownum && $line['warnings']) { | |
298 | if (count($warningrows) + count($errorrows) < $previewlimit) { | |
299 | $warningrows[] = $rownum; | |
300 | } | |
301 | } | |
302 | } | |
303 | // Include as many error rows as possible and top them up with warning rows. | |
304 | $rows = array_merge($errorrows, array_slice($warningrows, 0, $previewlimit - count($errorrows))); | |
305 | // Keep adding good rows until we reach limit. | |
306 | for ($rownum = 1; count($rows) < $previewlimit; $rownum++) { | |
307 | if (!in_array($rownum, $rows)) { | |
308 | $rows[] = $rownum; | |
309 | } | |
310 | } | |
311 | asort($rows); | |
312 | } | |
313 | return $rows; | |
314 | } | |
315 | ||
316 | public function display() { | |
317 | // Finalize the form definition if not yet done. | |
318 | if (!$this->_definition_finalized) { | |
319 | $this->_definition_finalized = true; | |
320 | $this->definition_after_data(); | |
321 | } | |
322 | ||
323 | // Difference from the parent display() method is that we want to show preview above the form if applicable. | |
324 | $this->preview_uploaded_cohorts(); | |
325 | ||
326 | $this->_form->display(); | |
327 | } | |
328 | ||
329 | /** | |
330 | * @param stored_file $file | |
331 | * @param string $encoding | |
332 | * @param string $delimiter | |
333 | * @param context $defaultcontext | |
334 | * @return array | |
335 | */ | |
336 | protected function process_upload_file($file, $encoding, $delimiter, $defaultcontext) { | |
337 | global $CFG, $DB; | |
338 | require_once($CFG->libdir . '/csvlib.class.php'); | |
339 | ||
340 | $cohorts = array( | |
341 | 0 => array('errors' => array(), 'warnings' => array(), 'data' => array()) | |
342 | ); | |
343 | ||
344 | // Read and parse the CSV file using csv library. | |
345 | $content = $file->get_content(); | |
346 | if (!$content) { | |
347 | $cohorts[0]['errors'][] = new lang_string('csvemptyfile', 'error'); | |
348 | return $cohorts; | |
349 | } | |
350 | ||
351 | $uploadid = csv_import_reader::get_new_iid('uploadcohort'); | |
352 | $cir = new csv_import_reader($uploadid, 'uploadcohort'); | |
353 | $readcount = $cir->load_csv_content($content, $encoding, $delimiter); | |
354 | unset($content); | |
355 | if (!$readcount) { | |
356 | $cohorts[0]['errors'][] = get_string('csvloaderror', 'error', $cir->get_error()); | |
357 | return $cohorts; | |
358 | } | |
359 | $columns = $cir->get_columns(); | |
360 | ||
361 | // Check that columns include 'name' and warn about extra columns. | |
fbb250f8 | 362 | $allowedcolumns = array('contextid', 'name', 'idnumber', 'description', 'descriptionformat', 'visible'); |
5076b961 MG |
363 | $additionalcolumns = array('context', 'category', 'category_id', 'category_idnumber', 'category_path'); |
364 | $displaycolumns = array(); | |
365 | $extracolumns = array(); | |
366 | $columnsmapping = array(); | |
367 | foreach ($columns as $i => $columnname) { | |
368 | $columnnamelower = preg_replace('/ /', '', core_text::strtolower($columnname)); | |
369 | $columnsmapping[$i] = null; | |
370 | if (in_array($columnnamelower, $allowedcolumns)) { | |
371 | $displaycolumns[$columnnamelower] = $columnname; | |
372 | $columnsmapping[$i] = $columnnamelower; | |
373 | } else if (in_array($columnnamelower, $additionalcolumns)) { | |
374 | $columnsmapping[$i] = $columnnamelower; | |
375 | } else { | |
376 | $extracolumns[] = $columnname; | |
377 | } | |
378 | } | |
379 | if (!in_array('name', $columnsmapping)) { | |
380 | $cohorts[0]['errors'][] = new lang_string('namecolumnmissing', 'cohort'); | |
381 | return $cohorts; | |
382 | } | |
383 | if ($extracolumns) { | |
384 | $cohorts[0]['warnings'][] = new lang_string('csvextracolumns', 'cohort', s(join(', ', $extracolumns))); | |
385 | } | |
386 | ||
387 | if (!isset($displaycolumns['contextid'])) { | |
388 | $displaycolumns['contextid'] = 'contextid'; | |
389 | } | |
390 | $cohorts[0]['data'] = $displaycolumns; | |
391 | ||
392 | // Parse data rows. | |
393 | $cir->init(); | |
394 | $rownum = 0; | |
395 | $idnumbers = array(); | |
396 | $haserrors = false; | |
397 | $haswarnings = false; | |
398 | while ($row = $cir->next()) { | |
399 | $rownum++; | |
400 | $cohorts[$rownum] = array( | |
401 | 'errors' => array(), | |
402 | 'warnings' => array(), | |
403 | 'data' => array(), | |
404 | ); | |
405 | $hash = array(); | |
406 | foreach ($row as $i => $value) { | |
407 | if ($columnsmapping[$i]) { | |
408 | $hash[$columnsmapping[$i]] = $value; | |
409 | } | |
410 | } | |
411 | $this->clean_cohort_data($hash); | |
412 | ||
413 | $warnings = $this->resolve_context($hash, $defaultcontext); | |
414 | $cohorts[$rownum]['warnings'] = array_merge($cohorts[$rownum]['warnings'], $warnings); | |
415 | ||
416 | if (!empty($hash['idnumber'])) { | |
417 | if (isset($idnumbers[$hash['idnumber']]) || $DB->record_exists('cohort', array('idnumber' => $hash['idnumber']))) { | |
418 | $cohorts[$rownum]['errors'][] = new lang_string('duplicateidnumber', 'cohort'); | |
419 | } | |
420 | $idnumbers[$hash['idnumber']] = true; | |
421 | } | |
422 | ||
423 | if (empty($hash['name'])) { | |
424 | $cohorts[$rownum]['errors'][] = new lang_string('namefieldempty', 'cohort'); | |
425 | } | |
426 | ||
427 | $cohorts[$rownum]['data'] = array_intersect_key($hash, $cohorts[0]['data']); | |
428 | $haserrors = $haserrors || !empty($cohorts[$rownum]['errors']); | |
429 | $haswarnings = $haswarnings || !empty($cohorts[$rownum]['warnings']); | |
430 | } | |
431 | ||
432 | if ($haserrors) { | |
433 | $cohorts[0]['errors'][] = new lang_string('csvcontainserrors', 'cohort'); | |
434 | } | |
435 | ||
436 | if ($haswarnings) { | |
437 | $cohorts[0]['warnings'][] = new lang_string('csvcontainswarnings', 'cohort'); | |
438 | } | |
439 | ||
440 | return $cohorts; | |
441 | } | |
442 | ||
443 | /** | |
444 | * Cleans input data about one cohort. | |
445 | * | |
446 | * @param array $hash | |
447 | */ | |
448 | protected function clean_cohort_data(&$hash) { | |
449 | foreach ($hash as $key => $value) { | |
450 | switch ($key) { | |
451 | case 'contextid': $hash[$key] = clean_param($value, PARAM_INT); break; | |
452 | case 'name': $hash[$key] = core_text::substr(clean_param($value, PARAM_TEXT), 0, 254); break; | |
453 | case 'idnumber': $hash[$key] = core_text::substr(clean_param($value, PARAM_RAW), 0, 254); break; | |
454 | case 'description': $hash[$key] = clean_param($value, PARAM_RAW); break; | |
455 | case 'descriptionformat': $hash[$key] = clean_param($value, PARAM_INT); break; | |
fbb250f8 MG |
456 | case 'visible': |
457 | $tempstr = trim(core_text::strtolower($value)); | |
458 | if ($tempstr === '') { | |
459 | // Empty string is treated as "YES" (the default value for cohort visibility). | |
460 | $hash[$key] = 1; | |
461 | } else { | |
462 | if ($tempstr === core_text::strtolower(get_string('no')) || $tempstr === 'n') { | |
463 | // Special treatment for 'no' string that is not included in clean_param(). | |
464 | $value = 0; | |
465 | } | |
466 | $hash[$key] = clean_param($value, PARAM_BOOL) ? 1 : 0; | |
467 | } | |
468 | break; | |
5076b961 MG |
469 | } |
470 | } | |
471 | } | |
472 | ||
473 | /** | |
474 | * Determines in which context the particular cohort will be created | |
475 | * | |
476 | * @param array $hash | |
477 | * @param context $defaultcontext | |
478 | * @return array array of warning strings | |
479 | */ | |
480 | protected function resolve_context(&$hash, $defaultcontext) { | |
481 | global $DB; | |
482 | ||
483 | $warnings = array(); | |
484 | ||
485 | if (!empty($hash['contextid'])) { | |
486 | // Contextid was specified, verify we can post there. | |
487 | $contextoptions = $this->get_context_options(); | |
488 | if (!isset($contextoptions[$hash['contextid']])) { | |
489 | $warnings[] = new lang_string('contextnotfound', 'cohort', $hash['contextid']); | |
490 | $hash['contextid'] = $defaultcontext->id; | |
491 | } | |
492 | return $warnings; | |
493 | } | |
494 | ||
495 | if (!empty($hash['context'])) { | |
496 | $systemcontext = context_system::instance(); | |
497 | if ((core_text::strtolower(trim($hash['context'])) === | |
498 | core_text::strtolower($systemcontext->get_context_name())) || | |
499 | ('' . $hash['context'] === '' . $systemcontext->id)) { | |
500 | // User meant system context. | |
501 | $hash['contextid'] = $systemcontext->id; | |
502 | $contextoptions = $this->get_context_options(); | |
503 | if (!isset($contextoptions[$hash['contextid']])) { | |
504 | $warnings[] = new lang_string('contextnotfound', 'cohort', $hash['context']); | |
505 | $hash['contextid'] = $defaultcontext->id; | |
506 | } | |
507 | } else { | |
508 | // Assume it is a category. | |
509 | $hash['category'] = trim($hash['context']); | |
510 | } | |
511 | } | |
512 | ||
513 | if (!empty($hash['category_path'])) { | |
514 | // We already have array with available categories, look up the value. | |
515 | $contextoptions = $this->get_context_options(); | |
516 | if (!$hash['contextid'] = array_search($hash['category_path'], $contextoptions)) { | |
517 | $warnings[] = new lang_string('categorynotfound', 'cohort', s($hash['category_path'])); | |
518 | $hash['contextid'] = $defaultcontext->id; | |
519 | } | |
520 | return $warnings; | |
521 | } | |
522 | ||
523 | if (!empty($hash['category'])) { | |
524 | // Quick search by category path first. | |
525 | // Do not issue warnings or return here, further we'll try to search by id or idnumber. | |
526 | $contextoptions = $this->get_context_options(); | |
527 | if ($hash['contextid'] = array_search($hash['category'], $contextoptions)) { | |
528 | return $warnings; | |
529 | } | |
530 | } | |
531 | ||
532 | // Now search by category id or category idnumber. | |
533 | if (!empty($hash['category_id'])) { | |
534 | $field = 'id'; | |
535 | $value = clean_param($hash['category_id'], PARAM_INT); | |
536 | } else if (!empty($hash['category_idnumber'])) { | |
537 | $field = 'idnumber'; | |
538 | $value = $hash['category_idnumber']; | |
539 | } else if (!empty($hash['category'])) { | |
540 | $field = is_numeric($hash['category']) ? 'id' : 'idnumber'; | |
541 | $value = $hash['category']; | |
542 | } else { | |
543 | // No category field was specified, assume default category. | |
544 | $hash['contextid'] = $defaultcontext->id; | |
545 | return $warnings; | |
546 | } | |
547 | ||
548 | if (empty($this->categoriescache[$field][$value])) { | |
549 | $record = $DB->get_record_sql("SELECT c.id, ctx.id contextid | |
550 | FROM {context} ctx JOIN {course_categories} c ON ctx.contextlevel = ? AND ctx.instanceid = c.id | |
551 | WHERE c.$field = ?", array(CONTEXT_COURSECAT, $value)); | |
552 | if ($record && ($contextoptions = $this->get_context_options()) && isset($contextoptions[$record->contextid])) { | |
553 | $contextid = $record->contextid; | |
554 | } else { | |
555 | $warnings[] = new lang_string('categorynotfound', 'cohort', s($value)); | |
556 | $contextid = $defaultcontext->id; | |
557 | } | |
558 | // Next time when we can look up and don't search by this value again. | |
559 | $this->categoriescache[$field][$value] = $contextid; | |
560 | } | |
561 | $hash['contextid'] = $this->categoriescache[$field][$value]; | |
562 | ||
563 | return $warnings; | |
564 | } | |
565 | } |