mirror of
https://github.com/moodle/moodle.git
synced 2025-03-19 15:10:05 +01:00
Merge branch 'master_MDL-71608-importquestions' of https://github.com/catalyst/moodle-MDL-70329
This commit is contained in:
commit
61e4c8ddaa
@ -1939,7 +1939,7 @@ class core_plugin_manager {
|
||||
),
|
||||
|
||||
'qbank' => [
|
||||
'deletequestion',
|
||||
'deletequestion', 'importquestions',
|
||||
],
|
||||
|
||||
'qbehaviour' => array(
|
||||
|
179
question/bank/importquestions/classes/form/import_form.php
Normal file
179
question/bank/importquestions/classes/form/import_form.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Defines the export questions form.
|
||||
*
|
||||
* @package qbank_importquestions
|
||||
* @copyright 2007 Jamie Pratt me@jamiep.org
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace qbank_importquestions\form;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use moodle_exception;
|
||||
use moodleform;
|
||||
use stdClass;
|
||||
|
||||
require_once($CFG->libdir . '/formslib.php');
|
||||
|
||||
/**
|
||||
* Form to import questions into the question bank.
|
||||
*
|
||||
* @copyright 2007 Jamie Pratt me@jamiep.org
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class question_import_form extends moodleform {
|
||||
|
||||
/**
|
||||
* Build the form definition.
|
||||
*
|
||||
* This adds all the form fields that the manage categories feature needs.
|
||||
* @throws \coding_exception
|
||||
*/
|
||||
protected function definition() {
|
||||
global $OUTPUT;
|
||||
|
||||
$mform = $this->_form;
|
||||
|
||||
$defaultcategory = $this->_customdata['defaultcategory'];
|
||||
$contexts = $this->_customdata['contexts'];
|
||||
|
||||
// Choice of import format, with help icons.
|
||||
$mform->addElement('header', 'fileformat', get_string('fileformat', 'question'));
|
||||
|
||||
$fileformatnames = get_import_export_formats('import');
|
||||
$radioarray = [];
|
||||
$separators = [];
|
||||
foreach ($fileformatnames as $shortname => $fileformatname) {
|
||||
$radioarray[] = $mform->createElement('radio', 'format', '', $fileformatname, $shortname);
|
||||
|
||||
$separator = '';
|
||||
if (get_string_manager()->string_exists('pluginname_help', 'qformat_' . $shortname)) {
|
||||
$separator .= $OUTPUT->help_icon('pluginname', 'qformat_' . $shortname);
|
||||
}
|
||||
$separator .= '<div class="w-100"></div>';
|
||||
$separators[] = $separator;
|
||||
}
|
||||
|
||||
$radioarray[] = $mform->createElement('static', 'makelasthelpiconshowup', '');
|
||||
$mform->addGroup($radioarray, "formatchoices", '', $separators, false);
|
||||
$mform->addRule("formatchoices", null, 'required', null, 'client');
|
||||
|
||||
// Import options.
|
||||
$mform->addElement('header', 'general', get_string('general', 'form'));
|
||||
|
||||
$mform->addElement('questioncategory', 'category', get_string('importcategory', 'question'), compact('contexts'));
|
||||
$mform->setDefault('category', $defaultcategory);
|
||||
$mform->addHelpButton('category', 'importcategory', 'question');
|
||||
|
||||
$categorygroup = [];
|
||||
$categorygroup[] = $mform->createElement('checkbox', 'catfromfile', '', get_string('getcategoryfromfile', 'question'));
|
||||
$categorygroup[] = $mform->createElement('checkbox', 'contextfromfile', '', get_string('getcontextfromfile', 'question'));
|
||||
$mform->addGroup($categorygroup, 'categorygroup', '', '', false);
|
||||
$mform->disabledIf('categorygroup', 'catfromfile', 'notchecked');
|
||||
$mform->setDefault('catfromfile', 1);
|
||||
$mform->setDefault('contextfromfile', 1);
|
||||
|
||||
$matchgrades = [];
|
||||
$matchgrades['error'] = get_string('matchgradeserror', 'question');
|
||||
$matchgrades['nearest'] = get_string('matchgradesnearest', 'question');
|
||||
$mform->addElement('select', 'matchgrades', get_string('matchgrades', 'question'), $matchgrades);
|
||||
$mform->addHelpButton('matchgrades', 'matchgrades', 'question');
|
||||
$mform->setDefault('matchgrades', 'error');
|
||||
|
||||
$mform->addElement('selectyesno', 'stoponerror', get_string('stoponerror', 'question'));
|
||||
$mform->setDefault('stoponerror', 1);
|
||||
$mform->addHelpButton('stoponerror', 'stoponerror', 'question');
|
||||
|
||||
// The file to import.
|
||||
$mform->addElement('header', 'importfileupload', get_string('importquestions', 'question'));
|
||||
|
||||
$mform->addElement('filepicker', 'newfile', get_string('import'));
|
||||
$mform->addRule('newfile', null, 'required', null, 'client');
|
||||
|
||||
// Submit button.
|
||||
$mform->addElement('submit', 'submitbutton', get_string('import'));
|
||||
|
||||
// Set a template for the format select elements.
|
||||
$renderer = $mform->defaultRenderer();
|
||||
$template = "{help} {element}\n";
|
||||
$renderer->setGroupElementTemplate($template, 'format');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a file has been uploaded, and that it is of a plausible type.
|
||||
* @param array $data the submitted data.
|
||||
* @param array $errors the errors so far.
|
||||
* @return array the updated errors.
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
protected function validate_uploaded_file($data, $errors) {
|
||||
global $CFG;
|
||||
|
||||
if (empty($data['newfile'])) {
|
||||
$errors['newfile'] = get_string('required');
|
||||
return $errors;
|
||||
}
|
||||
|
||||
$files = $this->get_draft_files('newfile');
|
||||
if (!is_array($files) || count($files) < 1) {
|
||||
$errors['newfile'] = get_string('required');
|
||||
return $errors;
|
||||
}
|
||||
|
||||
if (empty($data['format'])) {
|
||||
$errors['format'] = get_string('required');
|
||||
return $errors;
|
||||
}
|
||||
|
||||
$formatfile = $CFG->dirroot . '/question/format/' . $data['format'] . '/format.php';
|
||||
if (!is_readable($formatfile)) {
|
||||
throw new moodle_exception('formatnotfound', 'question', '', $data['format']);
|
||||
}
|
||||
|
||||
require_once($formatfile);
|
||||
|
||||
$classname = 'qformat_' . $data['format'];
|
||||
$qformat = new $classname();
|
||||
|
||||
$file = reset($files);
|
||||
if (!$qformat->can_import_file($file)) {
|
||||
$a = new stdClass();
|
||||
$a->actualtype = $file->get_mimetype();
|
||||
$a->expectedtype = $qformat->mime_type();
|
||||
$errors['newfile'] = get_string('importwrongfiletype', 'question', $a);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation.
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $files
|
||||
* @return array the errors that were found
|
||||
* @throws \dml_exception|\coding_exception|moodle_exception
|
||||
*/
|
||||
public function validation($data, $files) {
|
||||
$errors = parent::validation($data, $files);
|
||||
$errors = $this->validate_uploaded_file($data, $errors);
|
||||
return $errors;
|
||||
}
|
||||
}
|
50
question/bank/importquestions/classes/navigation.php
Normal file
50
question/bank/importquestions/classes/navigation.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin entrypoint for navigation.
|
||||
*
|
||||
* @package qbank_importquestions
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace qbank_importquestions;
|
||||
|
||||
/**
|
||||
* Class navigation.
|
||||
*
|
||||
* @package qbank_importquestions
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class navigation extends \core_question\local\bank\navigation_node_base {
|
||||
|
||||
public function get_navigation_title(): string {
|
||||
return get_string('import', 'question');
|
||||
}
|
||||
|
||||
public function get_navigation_key(): string {
|
||||
return 'import';
|
||||
}
|
||||
|
||||
public function get_navigation_url(): \moodle_url {
|
||||
return new \moodle_url('/question/bank/importquestions/import.php');
|
||||
}
|
||||
|
||||
}
|
41
question/bank/importquestions/classes/plugin_feature.php
Normal file
41
question/bank/importquestions/classes/plugin_feature.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin entrypoint for qbank.
|
||||
*
|
||||
* @package qbank_importquestions
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace qbank_importquestions;
|
||||
|
||||
/**
|
||||
* Class plugin_feature.
|
||||
*
|
||||
* @package qbank_importquestions
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Safat Shahin <safatshahin@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class plugin_feature extends \core_question\local\bank\plugin_features_base {
|
||||
|
||||
public function get_navigation_node(): ?object {
|
||||
return new navigation();
|
||||
}
|
||||
}
|
38
question/bank/importquestions/classes/privacy/provider.php
Normal file
38
question/bank/importquestions/classes/privacy/provider.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace qbank_importquestions\privacy;
|
||||
|
||||
/**
|
||||
* Privacy Subsystem implementation for qbank_importquestions.
|
||||
*
|
||||
* @package qbank_importquestions
|
||||
* @category privacy
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Marc-Alexandre Ghaly <marc-alexandreghaly@catalyst-ca.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements \core_privacy\local\metadata\null_provider {
|
||||
/**
|
||||
* Get the language string identifier with the component's language
|
||||
* file to explain why this plugin stores no data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_reason(): string {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
150
question/bank/importquestions/import.php
Normal file
150
question/bank/importquestions/import.php
Normal file
@ -0,0 +1,150 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Defines the import questions form.
|
||||
*
|
||||
* @package qbank_importquestions
|
||||
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
require_once(__DIR__ . '/../../../config.php');
|
||||
require_once($CFG->dirroot . '/question/editlib.php');
|
||||
require_once($CFG->dirroot . '/question/bank/importquestions/classes/form/import_form.php');
|
||||
require_once($CFG->dirroot . '/question/format.php');
|
||||
require_once($CFG->dirroot . '/question/renderer.php');
|
||||
|
||||
use qbank_importquestions\form\question_import_form;
|
||||
|
||||
require_login();
|
||||
core_question\local\bank\helper::require_plugin_enabled('qbank_importquestions');
|
||||
list($thispageurl, $contexts, $cmid, $cm, $module, $pagevars) =
|
||||
question_edit_setup('import', '/question/bank/importquestions/import.php');
|
||||
|
||||
// Get display strings.
|
||||
$txt = new stdClass();
|
||||
$txt->importerror = get_string('importerror', 'question');
|
||||
$txt->importquestions = get_string('importquestions', 'question');
|
||||
|
||||
list($catid, $catcontext) = explode(',', $pagevars['cat']);
|
||||
if (!$category = $DB->get_record("question_categories", ['id' => $catid])) {
|
||||
throw new moodle_exception('nocategory', 'question');
|
||||
}
|
||||
|
||||
$categorycontext = context::instance_by_id($category->contextid);
|
||||
$category->context = $categorycontext;
|
||||
// This page can be called without courseid or cmid in which case.
|
||||
// We get the context from the category object.
|
||||
if ($contexts === null) { // Need to get the course from the chosen category.
|
||||
$contexts = new question_edit_contexts($categorycontext);
|
||||
$thiscontext = $contexts->lowest();
|
||||
if ($thiscontext->contextlevel == CONTEXT_COURSE) {
|
||||
require_login($thiscontext->instanceid, false);
|
||||
} else if ($thiscontext->contextlevel == CONTEXT_MODULE) {
|
||||
list($module, $cm) = get_module_from_cmid($thiscontext->instanceid);
|
||||
require_login($cm->course, false, $cm);
|
||||
}
|
||||
$contexts->require_one_edit_tab_cap($edittab);
|
||||
}
|
||||
|
||||
$PAGE->set_url($thispageurl);
|
||||
|
||||
$importform = new question_import_form($thispageurl, ['contexts' => $contexts->having_one_edit_tab_cap('import'),
|
||||
'defaultcategory' => $pagevars['cat']]);
|
||||
|
||||
if ($importform->is_cancelled()) {
|
||||
redirect($thispageurl);
|
||||
}
|
||||
// Page header.
|
||||
$PAGE->set_title($txt->importquestions);
|
||||
$PAGE->set_heading($COURSE->fullname);
|
||||
echo $OUTPUT->header();
|
||||
|
||||
// Print horizontal nav if needed.
|
||||
$renderer = $PAGE->get_renderer('core_question', 'bank');
|
||||
echo $renderer->extra_horizontal_navigation();
|
||||
|
||||
// File upload form submitted.
|
||||
if ($form = $importform->get_data()) {
|
||||
|
||||
// File checks out ok.
|
||||
$fileisgood = false;
|
||||
|
||||
// Work out if this is an uploaded file.
|
||||
// Or one from the filesarea.
|
||||
$realfilename = $importform->get_new_filename('newfile');
|
||||
$importfile = make_request_directory() . "/{$realfilename}";
|
||||
if (!$result = $importform->save_file('newfile', $importfile, true)) {
|
||||
throw new moodle_exception('uploadproblem');
|
||||
}
|
||||
|
||||
$formatfile = $CFG->dirroot . '/question/format/' . $form->format . '/format.php';
|
||||
if (!is_readable($formatfile)) {
|
||||
throw new moodle_exception('formatnotfound', 'question', '', $form->format);
|
||||
}
|
||||
|
||||
require_once($formatfile);
|
||||
|
||||
$classname = 'qformat_' . $form->format;
|
||||
$qformat = new $classname();
|
||||
|
||||
// Load data into class.
|
||||
$qformat->setCategory($category);
|
||||
$qformat->setContexts($contexts->having_one_edit_tab_cap('import'));
|
||||
$qformat->setCourse($COURSE);
|
||||
$qformat->setFilename($importfile);
|
||||
$qformat->setRealfilename($realfilename);
|
||||
$qformat->setMatchgrades($form->matchgrades);
|
||||
$qformat->setCatfromfile(!empty($form->catfromfile));
|
||||
$qformat->setContextfromfile(!empty($form->contextfromfile));
|
||||
$qformat->setStoponerror($form->stoponerror);
|
||||
|
||||
// Do anything before that we need to.
|
||||
if (!$qformat->importpreprocess()) {
|
||||
throw new moodle_exception('cannotimport', '', $thispageurl->out());
|
||||
}
|
||||
|
||||
// Process the uploaded file.
|
||||
if (!$qformat->importprocess()) {
|
||||
throw new moodle_exception('cannotimport', '', $thispageurl->out());
|
||||
}
|
||||
|
||||
// In case anything needs to be done after.
|
||||
if (!$qformat->importpostprocess()) {
|
||||
throw new moodle_exception('cannotimport', '', $thispageurl->out());
|
||||
}
|
||||
|
||||
// Log the import into this category.
|
||||
$eventparams = [
|
||||
'contextid' => $qformat->category->contextid,
|
||||
'other' => ['format' => $form->format, 'categoryid' => $qformat->category->id],
|
||||
];
|
||||
$event = \core\event\questions_imported::create($eventparams);
|
||||
$event->trigger();
|
||||
|
||||
$params = $thispageurl->params() + ['category' => $qformat->category->id . ',' . $qformat->category->contextid];
|
||||
echo $OUTPUT->continue_button(new moodle_url('/question/edit.php', $params));
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
}
|
||||
|
||||
echo $OUTPUT->heading_with_help($txt->importquestions, 'importquestions', 'question');
|
||||
|
||||
// Print upload form.
|
||||
$importform->display();
|
||||
echo $OUTPUT->footer();
|
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Strings for component 'qbank_importquestions', language 'en'
|
||||
*
|
||||
* @package qbank_importquestions
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Marc-Alexandre Ghaly <marc-alexandreghaly@catalyst-ca.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['pluginname'] = 'Import question bank feature';
|
||||
$string['privacy:metadata'] = 'The import question bank will import questions from a file according to the selected file format.';
|
31
question/bank/importquestions/version.php
Normal file
31
question/bank/importquestions/version.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin version and other meta-data are defined here.
|
||||
*
|
||||
* @package qbank_importquestions
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author Marc-Alexandre Ghaly <marc-alexandreghaly@catalyst-ca.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->component = 'qbank_importquestions';
|
||||
$plugin->version = 2021070700;
|
||||
$plugin->requires = 2021052500;
|
||||
$plugin->maturity = MATURITY_STABLE;
|
Loading…
x
Reference in New Issue
Block a user