diff --git a/lib/classes/plugin_manager.php b/lib/classes/plugin_manager.php index 3d50eb33317..3774b8a03f4 100644 --- a/lib/classes/plugin_manager.php +++ b/lib/classes/plugin_manager.php @@ -1939,7 +1939,9 @@ class core_plugin_manager { ), 'qbank' => [ - 'deletequestion', 'importquestions', + 'deletequestion', + 'exportquestions', + 'importquestions', ], 'qbehaviour' => array( diff --git a/lib/questionlib.php b/lib/questionlib.php index 1bf8900da84..f9dcf74e3fc 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -2336,9 +2336,13 @@ function core_question_question_preview_pluginfile($previewcontext, $questionid, * @param string $withcategories * @param string $ithcontexts * @param moodle_url export file url + * @deprecated since Moodle 4.0 MDL-71573 + * @see qbank_exportquestions\exportquestions_helper */ function question_make_export_url($contextid, $categoryid, $format, $withcategories, $withcontexts, $filename) { + debugging('Function question_make_export_url() has been deprecated and moved to qbank_exportquestions plugin, + Please use qbank_exportquestions\exportquestions_helper::question_make_export_url() instead.', DEBUG_DEVELOPER); global $CFG; $urlbase = "$CFG->wwwroot/pluginfile.php"; return moodle_url::make_file_url($urlbase, diff --git a/question/bank/exportquestions/classes/exportquestions_helper.php b/question/bank/exportquestions/classes/exportquestions_helper.php new file mode 100644 index 00000000000..a9832f37098 --- /dev/null +++ b/question/bank/exportquestions/classes/exportquestions_helper.php @@ -0,0 +1,58 @@ +. + +/** + * Library functions used by qbank_exportquestions/export.php. + * + * This code is based on lib/questionlib.php by Martin Dougiamas. + * + * @package qbank_exportquestions + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Guillermo Gomez Arias + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace qbank_exportquestions; + +use moodle_url; + +/** + * Class exportquestions_helper contains all the library functions. + * + * @package qbank_exportquestions + */ +class exportquestions_helper { + + /** + * Create url for question export. + * + * @param int $contextid Current context. + * @param int $categoryid Category id. + * @param string $format Format. + * @param string $withcategories nocategories or withcategories text. + * @param string $withcontexts nocontexts or withcontexts text. + * @param string $filename File name. + * @return moodle_url Return an URL. + */ + public static function question_make_export_url($contextid, $categoryid, $format, $withcategories, + $withcontexts, $filename): moodle_url { + global $CFG; + $urlbase = "$CFG->wwwroot/pluginfile.php"; + return moodle_url::make_file_url($urlbase, + "/$contextid/question/export/{$categoryid}/{$format}/{$withcategories}" . + "/{$withcontexts}/{$filename}", true); + } +} diff --git a/question/bank/exportquestions/classes/form/export_form.php b/question/bank/exportquestions/classes/form/export_form.php new file mode 100644 index 00000000000..bd35f32645b --- /dev/null +++ b/question/bank/exportquestions/classes/form/export_form.php @@ -0,0 +1,100 @@ +. + +/** + * Defines the export questions form. + * + * @package qbank_exportquestions + * @copyright 2007 Jamie Pratt me@jamiep.org + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace qbank_exportquestions\form; + +use moodleform; + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->libdir . '/formslib.php'); + + +/** + * Form to export questions from the question bank. + * + * @copyright 2007 Jamie Pratt me@jamiep.org + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class export_form extends moodleform { + + /** + * Build the form definition. + * + * This adds all the form fields that the export questions feature needs. + */ + protected function definition() { + global $OUTPUT; + + $mform = $this->_form; + + $defaultcategory = $this->_customdata['defaultcategory']; + $contexts = $this->_customdata['contexts']; + + // Choice of format, with help. + $mform->addElement('header', 'fileformat', get_string('fileformat', 'question')); + + $fileformatnames = get_import_export_formats('export'); + $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 .= '
'; + $separators[] = $separator; + } + + $radioarray[] = $mform->createElement('static', 'makelasthelpiconshowup', ''); + $mform->addGroup($radioarray, "formatchoices", '', $separators, false); + $mform->addRule("formatchoices", null, 'required', null, 'client'); + + // Export options. + $mform->addElement('header', 'general', get_string('general', 'form')); + + $mform->addElement('questioncategory', 'category', get_string('exportcategory', 'question'), + ['contexts' => $contexts, 'top' => true]); + $mform->setDefault('category', $defaultcategory); + $mform->addHelpButton('category', 'exportcategory', 'question'); + + $categorygroup = []; + $categorygroup[] = $mform->createElement('checkbox', 'cattofile', '', get_string('tofilecategory', 'question')); + $categorygroup[] = $mform->createElement('checkbox', 'contexttofile', '', get_string('tofilecontext', 'question')); + $mform->addGroup($categorygroup, 'categorygroup', '', '', false); + $mform->disabledIf('categorygroup', 'cattofile', 'notchecked'); + $mform->setDefault('cattofile', 1); + $mform->setDefault('contexttofile', 1); + + // Set a template for the format select elements. + $renderer = $mform->defaultRenderer(); + $template = "{help} {element}\n"; + $renderer->setGroupElementTemplate($template, 'format'); + + // Submit buttons. + $this->add_action_buttons(false, get_string('exportquestions', 'question')); + } +} diff --git a/question/bank/exportquestions/classes/navigation.php b/question/bank/exportquestions/classes/navigation.php new file mode 100644 index 00000000000..4d0491591ee --- /dev/null +++ b/question/bank/exportquestions/classes/navigation.php @@ -0,0 +1,49 @@ +. + +/** + * Plugin entrypoint for navigation. + * + * @package qbank_exportquestions + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Guillermo Gomez Arias + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace qbank_exportquestions; + +/** + * Class navigation. + * + * @package qbank_exportquestions + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Guillermo Gomez Arias + * @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('export', 'question'); + } + + public function get_navigation_key(): string { + return 'export'; + } + + public function get_navigation_url(): \moodle_url { + return new \moodle_url('/question/bank/exportquestions/export.php'); + } +} diff --git a/question/bank/exportquestions/classes/plugin_feature.php b/question/bank/exportquestions/classes/plugin_feature.php new file mode 100644 index 00000000000..e2f245dc23d --- /dev/null +++ b/question/bank/exportquestions/classes/plugin_feature.php @@ -0,0 +1,43 @@ +. + +/** + * Entry point for plugin. + * + * Every qbank plugin must extent this class. + * + * @package qbank_exportquestions + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Safat Shahin + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace qbank_exportquestions; + +/** + * Class plugin_feature. + * + * @package qbank_exportquestions + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Safat Shahin + * @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(); + } +} diff --git a/question/bank/exportquestions/classes/privacy/provider.php b/question/bank/exportquestions/classes/privacy/provider.php new file mode 100644 index 00000000000..2843e29b2e5 --- /dev/null +++ b/question/bank/exportquestions/classes/privacy/provider.php @@ -0,0 +1,37 @@ +. + +/** + * Privacy Subsystem for qbank_exportquestions implementing null_provider. + * + * @package qbank_exportquestions + * @category privacy + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Guillermo Gomez Arias + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace qbank_exportquestions\privacy; + +/** + * Class provider. + */ +class provider implements \core_privacy\local\metadata\null_provider { + + public static function get_reason(): string { + return 'privacy:metadata'; + } +} diff --git a/question/export.php b/question/bank/exportquestions/export.php similarity index 59% rename from question/export.php rename to question/bank/exportquestions/export.php index 07d48dc0af1..d7f260ed4cb 100644 --- a/question/export.php +++ b/question/bank/exportquestions/export.php @@ -17,28 +17,32 @@ /** * Script for importing questions into the question bank. * - * @package moodlecore - * @subpackage questionbank + * @package qbank_exportquestions * @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(__DIR__ . '/../../../config.php'); require_once($CFG->dirroot . '/question/editlib.php'); -require_once($CFG->dirroot . '/question/export_form.php'); require_once($CFG->dirroot . '/question/format.php'); +require_once($CFG->dirroot . '/question/renderer.php'); + +use qbank_exportquestions\exportquestions_helper; +use qbank_exportquestions\form\export_form; + +require_login(); +core_question\local\bank\helper::require_plugin_enabled('qbank_exportquestions'); list($thispageurl, $contexts, $cmid, $cm, $module, $pagevars) = - question_edit_setup('export', '/question/export.php'); + question_edit_setup('export', '/question/bank/exportquestions/export.php'); -// get display strings +// Get display strings. $strexportquestions = get_string('exportquestions', 'question'); list($catid, $catcontext) = explode(',', $pagevars['cat']); -$category = $DB->get_record('question_categories', array("id" => $catid, 'contextid' => $catcontext), '*', MUST_EXIST); +$category = $DB->get_record('question_categories', ["id" => $catid, 'contextid' => $catcontext], '*', MUST_EXIST); -/// Header +// Header. $PAGE->set_url($thispageurl); $PAGE->set_title($strexportquestions); $PAGE->set_heading($COURSE->fullname); @@ -48,56 +52,57 @@ echo $OUTPUT->header(); $renderer = $PAGE->get_renderer('core_question', 'bank'); echo $renderer->extra_horizontal_navigation(); -$export_form = new question_export_form($thispageurl, - array('contexts' => $contexts->having_one_edit_tab_cap('export'), 'defaultcategory' => $pagevars['cat'])); +$exportform = new export_form($thispageurl, + ['contexts' => $contexts->having_one_edit_tab_cap('export'), 'defaultcategory' => $pagevars['cat']]); - -if ($from_form = $export_form->get_data()) { +if ($fromform = $exportform->get_data()) { $thiscontext = $contexts->lowest(); - if (!is_readable("format/{$from_form->format}/format.php")) { - print_error('unknowformat', '', '', $from_form->format); + if (!is_readable($CFG->dirroot . "/question/format/{$fromform->format}/format.php")) { + throw new moodle_exception('unknowformat', '', '', $fromform->format); } $withcategories = 'nocategories'; - if (!empty($from_form->cattofile)) { + if (!empty($fromform->cattofile)) { $withcategories = 'withcategories'; } $withcontexts = 'nocontexts'; - if (!empty($from_form->contexttofile)) { + if (!empty($fromform->contexttofile)) { $withcontexts = 'withcontexts'; } - $classname = 'qformat_' . $from_form->format; + $classname = 'qformat_' . $fromform->format; $qformat = new $classname(); $filename = question_default_export_filename($COURSE, $category) . $qformat->export_file_extension(); - $export_url = question_make_export_url($thiscontext->id, $category->id, - $from_form->format, $withcategories, $withcontexts, $filename); + $exporturl = exportquestions_helper::question_make_export_url($thiscontext->id, $category->id, + $fromform->format, $withcategories, $withcontexts, $filename); echo $OUTPUT->box_start(); - echo get_string('yourfileshoulddownload', 'question', $export_url->out()); + echo get_string('yourfileshoulddownload', 'question', $exporturl->out()); echo $OUTPUT->box_end(); // Log the export of these questions. $eventparams = [ 'contextid' => $category->contextid, - 'other' => ['format' => $from_form->format, 'categoryid' => $category->id], + 'other' => ['format' => $fromform->format, 'categoryid' => $category->id], ]; $event = \core\event\questions_exported::create($eventparams); $event->trigger(); // Don't allow force download for behat site, as pop-up can't be handled by selenium. if (!defined('BEHAT_SITE_RUNNING')) { - $PAGE->requires->js_function_call('document.location.replace', array($export_url->out(false)), false, 1); + $PAGE->requires->js_function_call('document.location.replace', [$exporturl->out(false)], false, 1); } - echo $OUTPUT->continue_button(new moodle_url('edit.php', $thispageurl->params())); + echo $OUTPUT->continue_button(new moodle_url($PAGE->settingsnav->find( + 'questionbank', + \navigation_node::TYPE_CONTAINER)->action->get_path(), $thispageurl->params())); echo $OUTPUT->footer(); exit; } -/// Display export form +// Display export form. echo $OUTPUT->heading_with_help($strexportquestions, 'exportquestions', 'question'); -$export_form->display(); +$exportform->display(); echo $OUTPUT->footer(); diff --git a/question/bank/exportquestions/lang/en/qbank_exportquestions.php b/question/bank/exportquestions/lang/en/qbank_exportquestions.php new file mode 100644 index 00000000000..1e8974ca15d --- /dev/null +++ b/question/bank/exportquestions/lang/en/qbank_exportquestions.php @@ -0,0 +1,27 @@ +. + +/** + * Strings for component 'qbank_exportquestions', language 'en' + * + * @package qbank_exportquestions + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Guillermo Gomez Arias + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$string['pluginname'] = 'Export question bank feature'; +$string['privacy:metadata'] = 'The Export Questions plugin does not store any personal data.'; diff --git a/question/bank/exportquestions/version.php b/question/bank/exportquestions/version.php new file mode 100644 index 00000000000..adb5946f38f --- /dev/null +++ b/question/bank/exportquestions/version.php @@ -0,0 +1,31 @@ +. + +/** + * Plugin version and other meta-data are defined here. + * + * @package qbank_exportquestions + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Guillermo Gomez Arias + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$plugin->component = 'qbank_exportquestions'; +$plugin->version = 2021070700; +$plugin->requires = 2021052500; +$plugin->maturity = MATURITY_STABLE; diff --git a/question/export_form.php b/question/export_form.php index 0d5ade3d4da..b23e459b227 100644 --- a/question/export_form.php +++ b/question/export_form.php @@ -34,10 +34,15 @@ require_once($CFG->libdir . '/formslib.php'); * * @copyright 2007 Jamie Pratt me@jamiep.org * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @deprecated since Moodle 4.0 MDL-71573 + * @see qbank_exportquestions\form\export_form */ class question_export_form extends moodleform { protected function definition() { + debugging('Class question_export_form in \core_question\export_form is deprecated, + please use core_question\bank\exportquestions\export_form instead.', DEBUG_DEVELOPER); + global $OUTPUT; $mform = $this->_form; diff --git a/question/format.php b/question/format.php index 0177abf03e4..878dd9500ae 100644 --- a/question/format.php +++ b/question/format.php @@ -972,7 +972,7 @@ class qformat_default { // continue path for following error checks $course = $this->course; - $continuepath = "{$CFG->wwwroot}/question/export.php?courseid={$course->id}"; + $continuepath = "{$CFG->wwwroot}/question/bank/exportquestions/export.php?courseid={$course->id}"; // did we actually process anything if ($count==0) {