diff --git a/lib/classes/plugin_manager.php b/lib/classes/plugin_manager.php index 3774b8a03f4..5587e60b900 100644 --- a/lib/classes/plugin_manager.php +++ b/lib/classes/plugin_manager.php @@ -1940,6 +1940,7 @@ class core_plugin_manager { 'qbank' => [ 'deletequestion', + 'editquestion', 'exportquestions', 'importquestions', ], diff --git a/question/bank/editquestion/addquestion.php b/question/bank/editquestion/addquestion.php new file mode 100644 index 00000000000..7b8502bab44 --- /dev/null +++ b/question/bank/editquestion/addquestion.php @@ -0,0 +1,94 @@ +. + +/** + * Shows a screen where the user can choose a question type, before being redirected to question.php + * + * @package qbank_editquestion + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once(__DIR__ . '/../../../config.php'); +require_once(__DIR__ . '/../../editlib.php'); + +use qbank_editquestion\editquestion_helper; + +// Read URL parameters. +$categoryid = required_param('category', PARAM_INT); +$cmid = optional_param('cmid', 0, PARAM_INT); +$courseid = optional_param('courseid', 0, PARAM_INT); +$returnurl = optional_param('returnurl', 0, PARAM_LOCALURL); +$appendqnumstring = optional_param('appendqnumstring', '', PARAM_ALPHA); +$validationerror = optional_param('validationerror', false, PARAM_BOOL); + +\core_question\local\bank\helper::require_plugin_enabled('qbank_editquestion'); + +// Place to accumulate hidden params for the form we will print. +$hiddenparams = array('category' => $categoryid); + +// Validate params. +if (!$category = $DB->get_record('question_categories', array('id' => $categoryid))) { + throw new moodle_exception('categorydoesnotexist', 'question', $returnurl); +} + +if ($cmid) { + list($module, $cm) = get_module_from_cmid($cmid); + require_login($cm->course, false, $cm); + $thiscontext = context_module::instance($cmid); + $hiddenparams['cmid'] = $cmid; +} else if ($courseid) { + require_login($courseid, false); + $thiscontext = context_course::instance($courseid); + $module = null; + $cm = null; + $hiddenparams['courseid'] = $courseid; +} else { + throw new moodle_exception('missingcourseorcmid', 'question'); +} + +// Check permissions. +$categorycontext = context::instance_by_id($category->contextid); +require_capability('moodle/question:add', $categorycontext); + +// Ensure other optional params get passed on to question.php. +if (!empty($returnurl)) { + $hiddenparams['returnurl'] = $returnurl; +} +if (!empty($appendqnumstring)) { + $hiddenparams['appendqnumstring'] = $appendqnumstring; +} + +$PAGE->set_url('/question/bank/editquestion/addquestion.php', $hiddenparams); +if ($cmid) { + $questionbankurl = new moodle_url('/question/edit.php', array('cmid' => $cmid)); +} else { + $questionbankurl = new moodle_url('/question/edit.php', array('courseid' => $courseid)); +} +navigation_node::override_active_url($questionbankurl); + +$chooseqtype = get_string('chooseqtypetoadd', 'question'); +$PAGE->set_heading($COURSE->fullname); +$PAGE->navbar->add($chooseqtype); +$PAGE->set_title($chooseqtype); + +// Display a form to choose the question type. +echo $OUTPUT->header(); +echo $OUTPUT->notification(get_string('youmustselectaqtype', 'question')); +echo $OUTPUT->box_start('generalbox boxwidthnormal boxaligncenter', 'chooseqtypebox'); +echo editquestion_helper::print_choose_qtype_to_add_form($hiddenparams, null, false); +echo $OUTPUT->box_end(); +echo $OUTPUT->footer(); diff --git a/question/bank/editquestion/classes/copy_action_column.php b/question/bank/editquestion/classes/copy_action_column.php new file mode 100644 index 00000000000..ff1b4df565c --- /dev/null +++ b/question/bank/editquestion/classes/copy_action_column.php @@ -0,0 +1,91 @@ +. + +/** + * Question bank column for the duplicate action icon. + * + * @package qbank_editquestion + * @copyright 2013 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace qbank_editquestion; + +use core_question\local\bank\menu_action_column_base; +use moodle_url; + +/** + * Question bank column for the duplicate action icon. + * + * @copyright 2013 The Open University + * @author 2021 Safat Shahin + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class copy_action_column extends menu_action_column_base { + + /** @var string avoids repeated calls to get_string('duplicate'). */ + protected $strcopy; + + /** + * Contains the url of the edit question page. + * @var moodle_url|string + */ + public $duplicatequestionurl; + + public function init(): void { + parent::init(); + $this->strcopy = get_string('duplicate'); + $this->duplicatequestionurl = new \moodle_url('/question/bank/editquestion/question.php', + array('returnurl' => $this->qbank->returnurl)); + if ($this->qbank->cm !== null) { + $this->duplicatequestionurl->param('cmid', $this->qbank->cm->id); + } else { + $this->duplicatequestionurl->param('courseid', $this->qbank->course->id); + } + } + + public function get_name() { + return 'copyaction'; + } + + /** + * Get the URL for duplicating a question as a moodle_url. + * + * @param int $questionid the question id. + * @return \moodle_url the URL. + */ + public function duplicate_question_moodle_url($questionid): moodle_url { + return new \moodle_url($this->duplicatequestionurl, ['id' => $questionid, 'makecopy' => 1]); + } + + protected function get_url_icon_and_label(\stdClass $question): array { + if (!\question_bank::is_qtype_installed($question->qtype)) { + // It sometimes happens that people end up with junk questions + // in their question bank of a type that is no longer installed. + // We cannot do most actions on them, because that leads to errors. + return [null, null, null]; + } + + // To copy a question, you need permission to add a question in the same + // category as the existing question, and ability to access the details of + // the question being copied. + if (question_has_capability_on($question, 'add') && + (question_has_capability_on($question, 'edit') || question_has_capability_on($question, 'view'))) { + return [$this->duplicate_question_moodle_url($question->id), 't/copy', $this->strcopy]; + } + return [null, null, null]; + } +} diff --git a/question/bank/editquestion/classes/edit_action_column.php b/question/bank/editquestion/classes/edit_action_column.php new file mode 100644 index 00000000000..db06b3f9366 --- /dev/null +++ b/question/bank/editquestion/classes/edit_action_column.php @@ -0,0 +1,100 @@ +. + +/** + * Class for question bank edit question column. + * + * @package qbank_editquestion + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace qbank_editquestion; + +use core_question\local\bank\menu_action_column_base; +use moodle_url; + +/** + * Class for question bank edit question column. + * + * @copyright 2009 Tim Hunt + * @author 2021 Safat Shahin + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class edit_action_column extends menu_action_column_base { + + /** + * Contains the string. + * @var string + */ + protected $stredit; + + /** + * Contains the string. + * @var string + */ + protected $strview; + + /** + * Contains the url of the edit question page. + * @var moodle_url|string + */ + public $editquestionurl; + + public function init(): void { + parent::init(); + $this->stredit = get_string('editquestion', 'question'); + $this->strview = get_string('view'); + $this->editquestionurl = new \moodle_url('/question/bank/editquestion/question.php', + array('returnurl' => $this->qbank->returnurl)); + if ($this->qbank->cm !== null) { + $this->editquestionurl->param('cmid', $this->qbank->cm->id); + } else { + $this->editquestionurl->param('courseid', $this->qbank->course->id); + } + } + + public function get_name() { + return 'editaction'; + } + + /** + * Get the URL for editing a question as a link. + * + * @param int $questionid the question id. + * @return moodle_url the URL, HTML-escaped. + */ + public function edit_question_moodle_url($questionid): moodle_url { + return new moodle_url($this->editquestionurl, ['id' => $questionid]); + } + + protected function get_url_icon_and_label(\stdClass $question): array { + if (!\question_bank::is_qtype_installed($question->qtype)) { + // It sometimes happens that people end up with junk questions + // in their question bank of a type that is no longer installed. + // We cannot do most actions on them, because that leads to errors. + return [null, null, null]; + } + + if (question_has_capability_on($question, 'edit')) { + return [$this->edit_question_moodle_url($question->id), 't/edit', $this->stredit]; + } else if (question_has_capability_on($question, 'view')) { + return [$this->edit_question_moodle_url($question->id), 'i/info', $this->strview]; + } else { + return [null, null, null]; + } + } +} diff --git a/question/bank/editquestion/classes/editquestion_helper.php b/question/bank/editquestion/classes/editquestion_helper.php new file mode 100644 index 00000000000..7430eece457 --- /dev/null +++ b/question/bank/editquestion/classes/editquestion_helper.php @@ -0,0 +1,86 @@ +. + +/** + * Helper class for adding/editing a question. + * + * This code is based on question/editlib.php by Martin Dougiamas. + * + * @package qbank_editquestion + * @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_editquestion; + +/** + * Class editquestion_helper for methods related to add/edit/copy + * + * @package qbank_editquestion + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Safat Shahin + */ +class editquestion_helper { + + /** + * Print a form to let the user choose which question type to add. + * When the form is submitted, it goes to the question.php script. + * + * @param array|null $hiddenparams hidden parameters to add to the form, in addition to + * the qtype radio buttons. + * @param array|null $allowedqtypes optional list of qtypes that are allowed. If given, only + * those qtypes will be shown. Example value array('description', 'multichoice'). + * @param bool $enablejs + * @return bool|string + */ + public static function print_choose_qtype_to_add_form(array $hiddenparams, array $allowedqtypes = null, $enablejs = true) { + global $PAGE; + + $chooser = \qbank_editquestion\qbank_chooser::get($PAGE->course, $hiddenparams, $allowedqtypes); + $renderer = $PAGE->get_renderer('qbank_editquestion'); + + return $renderer->render($chooser); + } + + /** + * Print a button for creating a new question. This will open question/addquestion.php, + * which in turn goes to question/question.php before getting back to $params['returnurl'] + * (by default the question bank screen). + * + * @param int $categoryid The id of the category that the new question should be added to. + * @param array $params Other paramters to add to the URL. You need either $params['cmid'] or + * $params['courseid'], and you should probably set $params['returnurl'] + * @param bool $canadd the text to display on the button. + * @param string $tooltip a tooltip to add to the button (optional). + * @param bool $disabled if true, the button will be disabled. + */ + public static function create_new_question_button($categoryid, $params, $canadd, $tooltip = '', $disabled = false) { + global $PAGE, $OUTPUT; + + $addquestiondisplay = array(); + $addquestiondisplay['canadd'] = $canadd; + if ($canadd) { + $params['category'] = $categoryid; + $url = new \moodle_url('/question/bank/editquestion/addquestion.php', $params); + $addquestiondisplay['buttonhtml'] = $OUTPUT->single_button($url, + get_string('createnewquestion', 'question'), + 'get', array('disabled' => $disabled, 'title' => $tooltip)); + $addquestiondisplay['qtypeform'] = self::print_choose_qtype_to_add_form(array()); + } + return $PAGE->get_renderer('qbank_editquestion')->render_create_new_question_button($addquestiondisplay); + } +} diff --git a/question/bank/editquestion/classes/output/renderer.php b/question/bank/editquestion/classes/output/renderer.php new file mode 100644 index 00000000000..c3ea82e536b --- /dev/null +++ b/question/bank/editquestion/classes/output/renderer.php @@ -0,0 +1,60 @@ +. + +/** + * Renderer for adding/editing a question. + * + * This code is based on question/renderer.php by The Open University. + * + * @package qbank_editquestion + * @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_editquestion\output; + +/** + * Renderer for add/edit/copy + * + * @package qbank_editquestion + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Safat Shahin + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class renderer extends \plugin_renderer_base { + + /** + * Render a qbank_chooser. + * + * @param \renderable $qbankchooser The chooser. + * @return string + */ + public function render_qbank_chooser (\renderable $qbankchooser) { + return $this->render_from_template('qbank_editquestion/qbank_chooser', $qbankchooser->export_for_template($this)); + } + + /** + * Render add question button. + * + * @param array $addquestiondata + * @return bool|string + */ + public function render_create_new_question_button ($addquestiondata) { + return $this->render_from_template('qbank_editquestion/add_new_question', $addquestiondata); + } + +} diff --git a/question/bank/editquestion/classes/plugin_feature.php b/question/bank/editquestion/classes/plugin_feature.php new file mode 100644 index 00000000000..1cd8bf9492e --- /dev/null +++ b/question/bank/editquestion/classes/plugin_feature.php @@ -0,0 +1,45 @@ +. + +/** + * Plugin entrypoint for columns. + * + * @package qbank_editquestion + * @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_editquestion; + +/** + * Class columns is the entrypoint for the columns. + * + * @package qbank_editquestion + * @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_question_columns($qbank): array { + return [ + new edit_action_column($qbank), + new copy_action_column($qbank) + ]; + } + +} diff --git a/question/bank/editquestion/classes/privacy/provider.php b/question/bank/editquestion/classes/privacy/provider.php new file mode 100644 index 00000000000..b4d4ea779e8 --- /dev/null +++ b/question/bank/editquestion/classes/privacy/provider.php @@ -0,0 +1,40 @@ +. + +/** + * Version information for qbank_editquestion. + * + * @package qbank_editquestion + * @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_editquestion\privacy; + +/** + * Privacy Subsystem for qbank_editquestion implementing null_provider. + * + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Safat Shahin + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class provider implements \core_privacy\local\metadata\null_provider { + + public static function get_reason(): string { + return 'privacy:metadata'; + } +} diff --git a/question/bank/editquestion/classes/qbank_chooser.php b/question/bank/editquestion/classes/qbank_chooser.php new file mode 100644 index 00000000000..099ea0cbd2f --- /dev/null +++ b/question/bank/editquestion/classes/qbank_chooser.php @@ -0,0 +1,105 @@ +. + +/** + * The qbank_chooser renderable. + * + * @package qbank_editquestion + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace qbank_editquestion; + +use context; +use context_course; +use core\output\chooser_section; +use lang_string; +use moodle_url; +use question_bank; +use stdClass; + +/** + * The qbank_chooser renderable class. + * + * @package qbank_editquestion + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qbank_chooser extends \core\output\chooser { + + /** + * Constructor. + * + * @param array $real The real question types. + * @param array $fake The fake question types. + * @param stdClass $course The course. + * @param array $hiddenparams Hidden parameters. + * @param context $context The relevant context. + */ + public function __construct($real, $fake, $course, $hiddenparams, $context) { + $sections = []; + $sections[] = new chooser_section('questions', new lang_string('questions', 'question'), + array_map(function($qtype) use ($context) { + return new qbank_chooser_item($qtype, $context); + }, $real)); + + if (!empty($fake)) { + $sections[] = new chooser_section('other', new lang_string('other'), + array_map(function ($qtype) use ($context) { + return new qbank_chooser_item($qtype, $context); + }, $fake)); + } + + parent::__construct(new moodle_url('/question/bank/editquestion/question.php'), + new lang_string('chooseqtypetoadd', 'question'), $sections, 'qtype'); + + $this->set_instructions(new lang_string('selectaqtypefordescription', 'question')); + + $this->set_method('get'); + $this->add_param('courseid', $course->id); + foreach ($hiddenparams as $k => $v) { + $this->add_param($k, $v); + } + } + + /** + * Get an instance of the question bank chooser. + * + * @param stdClass $course The course. + * @param array $hiddenparams Hidden parameters. + * @param array|null $allowedqtypes Allowed question types. + * @return qbank_chooser + */ + public static function get($course, $hiddenparams, array $allowedqtypes = null): qbank_chooser { + $realqtypes = array(); + $fakeqtypes = array(); + + foreach (question_bank::get_creatable_qtypes() as $qtypename => $qtype) { + if ($allowedqtypes && !in_array($qtypename, $allowedqtypes)) { + continue; + } + if ($qtype->is_real_question_type()) { + $realqtypes[] = $qtype; + } else { + $fakeqtypes[] = $qtype; + } + } + + return new static($realqtypes, $fakeqtypes, $course, $hiddenparams, context_course::instance($course->id)); + } + +} diff --git a/question/bank/editquestion/classes/qbank_chooser_item.php b/question/bank/editquestion/classes/qbank_chooser_item.php new file mode 100644 index 00000000000..b05f544c542 --- /dev/null +++ b/question/bank/editquestion/classes/qbank_chooser_item.php @@ -0,0 +1,55 @@ +. + +/** + * The qbank_chooser_item renderable. + * + * @package qbank_editquestion + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace qbank_editquestion; + +use context; +use lang_string; +use pix_icon; + +/** + * The qbank_chooser_item renderable class. + * + * @package qbank_editquestion + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qbank_chooser_item extends \core\output\chooser_item { + + /** + * Constructor. + * + * @param object $qtype The question type. + * @param context $context The relevant context. + */ + public function __construct($qtype, $context) { + $icon = new pix_icon('icon', $qtype->local_name(), $qtype->plugin_name(), [ + 'class' => 'icon', + 'title' => $qtype->local_name() + ]); + $help = new lang_string('pluginnamesummary', $qtype->plugin_name()); + parent::__construct($qtype->plugin_name(), $qtype->menu_name(), $qtype->name(), $icon, $help, $context); + } + +} diff --git a/question/bank/editquestion/lang/en/qbank_editquestion.php b/question/bank/editquestion/lang/en/qbank_editquestion.php new file mode 100644 index 00000000000..b4c670af91a --- /dev/null +++ b/question/bank/editquestion/lang/en/qbank_editquestion.php @@ -0,0 +1,27 @@ +. + +/** + * Strings for component qbank_editquestion, language 'en'. + * + * @package qbank_editquestion + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Safat Shahin + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$string['pluginname'] = 'Edit question bank feature'; +$string['privacy:metadata'] = 'Edit question plugin add/edit/copy a question, it does not store any user data.'; diff --git a/question/bank/editquestion/question.php b/question/bank/editquestion/question.php new file mode 100644 index 00000000000..3a5384e5dc4 --- /dev/null +++ b/question/bank/editquestion/question.php @@ -0,0 +1,339 @@ +. +/** + * Page for editing questions. + * + * @package qbank_editquestion + * @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__ . '/../../editlib.php'); +require_once($CFG->libdir . '/filelib.php'); +require_once($CFG->libdir . '/formslib.php'); + +// Read URL parameters telling us which question to edit. +$id = optional_param('id', 0, PARAM_INT); // Question id. +$makecopy = optional_param('makecopy', 0, PARAM_BOOL); +$qtype = optional_param('qtype', '', PARAM_COMPONENT); +$categoryid = optional_param('category', 0, PARAM_INT); +$cmid = optional_param('cmid', 0, PARAM_INT); +$courseid = optional_param('courseid', 0, PARAM_INT); +$wizardnow = optional_param('wizardnow', '', PARAM_ALPHA); +$originalreturnurl = optional_param('returnurl', 0, PARAM_LOCALURL); +$appendqnumstring = optional_param('appendqnumstring', '', PARAM_ALPHA); +$inpopup = optional_param('inpopup', 0, PARAM_BOOL); +$scrollpos = optional_param('scrollpos', 0, PARAM_INT); + +\core_question\local\bank\helper::require_plugin_enabled('qbank_editquestion'); + +$url = new moodle_url('/question/bank/editquestion/question.php'); +if ($id !== 0) { + $url->param('id', $id); +} +if ($makecopy) { + $url->param('makecopy', $makecopy); +} +if ($qtype !== '') { + $url->param('qtype', $qtype); +} +if ($categoryid !== 0) { + $url->param('category', $categoryid); +} +if ($cmid !== 0) { + $url->param('cmid', $cmid); +} +if ($courseid !== 0) { + $url->param('courseid', $courseid); +} +if ($wizardnow !== '') { + $url->param('wizardnow', $wizardnow); +} +if ($originalreturnurl !== 0) { + $url->param('returnurl', $originalreturnurl); +} +if ($appendqnumstring !== '') { + $url->param('appendqnumstring', $appendqnumstring); +} +if ($inpopup !== 0) { + $url->param('inpopup', $inpopup); +} +if ($scrollpos) { + $url->param('scrollpos', $scrollpos); +} +$PAGE->set_url($url); + +if ($cmid) { + $questionbankurl = new moodle_url('/question/edit.php', array('cmid' => $cmid)); +} else { + $questionbankurl = new moodle_url('/question/edit.php', array('courseid' => $courseid)); +} +navigation_node::override_active_url($questionbankurl); + +if ($originalreturnurl) { + if (strpos($originalreturnurl, '/') !== 0) { + throw new coding_exception("returnurl must be a local URL starting with '/'. $originalreturnurl was given."); + } + $returnurl = new moodle_url($originalreturnurl); +} else { + $returnurl = $questionbankurl; +} +if ($scrollpos) { + $returnurl->param('scrollpos', $scrollpos); +} + +if ($cmid) { + list($module, $cm) = get_module_from_cmid($cmid); + require_login($cm->course, false, $cm); + $thiscontext = context_module::instance($cmid); +} else if ($courseid) { + require_login($courseid, false); + $thiscontext = context_course::instance($courseid); + $module = null; + $cm = null; +} else { + throw new moodle_exception('missingcourseorcmid', 'question'); +} +$contexts = new question_edit_contexts($thiscontext); +$PAGE->set_pagelayout('admin'); + +if (optional_param('addcancel', false, PARAM_BOOL)) { + redirect($returnurl); +} + +if ($id) { + if (!$question = $DB->get_record('question', array('id' => $id))) { + throw new moodle_exception('questiondoesnotexist', 'question', $returnurl); + } + // We can use $COURSE here because it's been initialised as part of the + // require_login above. Passing it as the third parameter tells the function + // to filter the course tags by that course. + get_question_options($question, true, [$COURSE]); + +} else if ($categoryid && $qtype) { // Only for creating new questions. + $question = new stdClass(); + $question->category = $categoryid; + $question->qtype = $qtype; + $question->createdby = $USER->id; + + // Check that users are allowed to create this question type at the moment. + if (!question_bank::qtype_enabled($qtype)) { + throw new moodle_exception('cannotenable', 'question', $returnurl, $qtype); + } + +} else if ($categoryid) { + // Category, but no qtype. They probably came from the addquestion.php + // script without choosing a question type. Send them back. + $addurl = new moodle_url('/question/bank/editquestion/addquestion.php', $url->params()); + $addurl->param('validationerror', 1); + redirect($addurl); + +} else { + throw new moodle_exception('notenoughdatatoeditaquestion', 'question', $returnurl); +} + +$qtypeobj = question_bank::get_qtype($question->qtype); + +if (isset($question->categoryobject)) { + $category = $question->categoryobject; +} else { + // Validate the question category. + if (!$category = $DB->get_record('question_categories', array('id' => $question->category))) { + throw new moodle_exception('categorydoesnotexist', 'question', $returnurl); + } +} + +// Check permissions. +$question->formoptions = new stdClass(); + +$categorycontext = context::instance_by_id($category->contextid); +$question->contextid = $category->contextid; +$addpermission = has_capability('moodle/question:add', $categorycontext); + +if ($id) { + $question->formoptions->canedit = question_has_capability_on($question, 'edit'); + $question->formoptions->canmove = $addpermission && question_has_capability_on($question, 'move'); + $question->formoptions->cansaveasnew = $addpermission && + (question_has_capability_on($question, 'view') || $question->formoptions->canedit); + $question->formoptions->repeatelements = $question->formoptions->canedit || $question->formoptions->cansaveasnew; + $formeditable = $question->formoptions->canedit || $question->formoptions->cansaveasnew || $question->formoptions->canmove; + if (!$formeditable) { + question_require_capability_on($question, 'view'); + } + if ($makecopy) { + // If we are duplicating a question, add some indication to the question name. + $question->name = get_string('questionnamecopy', 'question', $question->name); + $question->idnumber = core_question_find_next_unused_idnumber($question->idnumber, $category->id); + $question->beingcopied = true; + } + +} else { // Creating a new question. + $question->formoptions->canedit = question_has_capability_on($question, 'edit'); + $question->formoptions->canmove = (question_has_capability_on($question, 'move') && $addpermission); + $question->formoptions->cansaveasnew = false; + $question->formoptions->repeatelements = true; + $formeditable = true; + require_capability('moodle/question:add', $categorycontext); +} +$question->formoptions->mustbeusable = (bool) $appendqnumstring; + +// Validate the question type. +$PAGE->set_pagetype('question-type-' . $question->qtype); + +// Create the question editing form. +if ($wizardnow !== '') { + $mform = $qtypeobj->next_wizard_form('question.php', $question, $wizardnow, $formeditable); +} else { + $mform = $qtypeobj->create_editing_form('question.php', $question, $category, $contexts, $formeditable); +} +$toform = fullclone($question); // Send the question object and a few more parameters to the form. +$toform->category = "{$category->id},{$category->contextid}"; +$toform->scrollpos = $scrollpos; +if ($formeditable && $id) { + $toform->categorymoveto = $toform->category; +} + +$toform->appendqnumstring = $appendqnumstring; +$toform->returnurl = $originalreturnurl; +$toform->makecopy = $makecopy; +if ($cm !== null) { + $toform->cmid = $cm->id; + $toform->courseid = $cm->course; +} else { + $toform->courseid = $COURSE->id; +} + +$toform->inpopup = $inpopup; + +$mform->set_data($toform); + +if ($mform->is_cancelled()) { + if ($inpopup) { + close_window(); + } else { + redirect($returnurl); + } + +} else if ($fromform = $mform->get_data()) { + // If we are saving as a copy, break the connection to the old question. + if ($makecopy) { + $question->id = 0; + $question->hidden = 0; // Copies should not be hidden. + } + + // Process the combination of usecurrentcat, categorymoveto and category form + // fields, so the save_question method only has to consider $fromform->category. + if (empty($fromform->usecurrentcat) && !empty($fromform->categorymoveto)) { + $fromform->category = $fromform->categorymoveto; + } + + // If we are moving a question, check we have permission to move it from + // whence it came (Where we are moving to is validated by the form). + list($newcatid, $newcontextid) = explode(',', $fromform->category); + if (!empty($question->id) && $newcatid != $question->category) { + $contextid = $newcontextid; + question_require_capability_on($question, 'move'); + } else { + $contextid = $category->contextid; + } + + // Ensure we redirect back to the category the question is being saved into. + $returnurl->param('category', $fromform->category); + + // We are actually saving the question. + if (!empty($question->id)) { + question_require_capability_on($question, 'edit'); + } else { + require_capability('moodle/question:add', context::instance_by_id($contextid)); + if (!empty($fromform->makecopy) && !$question->formoptions->cansaveasnew) { + throw new moodle_exception('nopermissions', '', '', 'edit'); + } + } + + // If this is a new question, save defaults for user in user_preferences table. + if (empty($question->id)) { + $qtypeobj->save_defaults_for_new_questions($fromform); + } + $question = $qtypeobj->save_question($question, $fromform); + if (isset($fromform->tags)) { + // If we have any question context level tags then set those tags now. + core_tag_tag::set_item_tags('core_question', 'question', $question->id, + context::instance_by_id($contextid), $fromform->tags, 0); + } + + if (isset($fromform->coursetags)) { + // If we have and course context level tags then set those now. + core_tag_tag::set_item_tags('core_question', 'question', $question->id, + context_course::instance($fromform->courseid), $fromform->coursetags, 0); + } + + // Purge this question from the cache. + question_bank::notify_question_edited($question->id); + + // If we are saving and continuing to edit the question. + if (!empty($fromform->updatebutton)) { + $url->param('id', $question->id); + $url->remove_params('makecopy'); + redirect($url); + } + + if ($qtypeobj->finished_edit_wizard($fromform)) { + if ($inpopup) { + echo $OUTPUT->notification(get_string('changessaved'), ''); + close_window(3); + } else { + $returnurl->param('lastchanged', $question->id); + if ($appendqnumstring) { + $returnurl->param($appendqnumstring, $question->id); + $returnurl->param('sesskey', sesskey()); + $returnurl->param('cmid', $cmid); + } + redirect($returnurl); + } + + } else { + $nexturlparams = array( + 'returnurl' => $originalreturnurl, + 'appendqnumstring' => $appendqnumstring, + 'scrollpos' => $scrollpos); + if (isset($fromform->nextpageparam) && is_array($fromform->nextpageparam)) { + // Useful for passing data to the next page which is not saved in the database. + $nexturlparams += $fromform->nextpageparam; + } + $nexturlparams['id'] = $question->id; + $nexturlparams['wizardnow'] = $fromform->wizard; + $nexturl = new moodle_url($url, $nexturlparams); + if ($cmid) { + $nexturl->param('cmid', $cmid); + } else { + $nexturl->param('courseid', $COURSE->id); + } + redirect($nexturl); + } + +} + +$streditingquestion = $qtypeobj->get_heading(); +$PAGE->set_title($streditingquestion); +$PAGE->set_heading($COURSE->fullname); +$PAGE->navbar->add($streditingquestion); + +// Display a heading, question editing form and possibly some extra content needed for +// for this question type. +echo $OUTPUT->header(); +$qtypeobj->display_question_editing_page($mform, $question, $wizardnow); +echo $OUTPUT->footer(); diff --git a/question/bank/editquestion/templates/add_new_question.mustache b/question/bank/editquestion/templates/add_new_question.mustache new file mode 100644 index 00000000000..d98ef264fb5 --- /dev/null +++ b/question/bank/editquestion/templates/add_new_question.mustache @@ -0,0 +1,41 @@ +{{! + 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 . +}} +{{! + @template qbank_editquestion/add_new_question + + Example context (json): + { + "addquestiondata": [ + { + "canadd": true, + "buttonhtml": "HTML for button", + "qtypeform": "html for qtype" + } + ] + } +}} +
+ {{^canadd}} + {{#str}} nopermissionadd, question{{/str}} + {{/canadd}} + {{#canadd}} + {{{buttonhtml}}} +
+ {{{qtypeform}}} +
+ {{/canadd}} +
diff --git a/question/bank/editquestion/templates/qbank_chooser.mustache b/question/bank/editquestion/templates/qbank_chooser.mustache new file mode 100644 index 00000000000..5a823b963e3 --- /dev/null +++ b/question/bank/editquestion/templates/qbank_chooser.mustache @@ -0,0 +1,29 @@ +{{! + 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 . +}} +{{! + @template qbank_editquestion/qbank_chooser +}} +{{> core/chooser }} +{{#js}} +require([ + 'core/yui' +], function(Y) { + Y.use('moodle-qbank_editquestion-chooser', function() { + M.question.init_chooser(); + }); +}); +{{/js}} diff --git a/question/bank/editquestion/version.php b/question/bank/editquestion/version.php new file mode 100644 index 00000000000..69614fede68 --- /dev/null +++ b/question/bank/editquestion/version.php @@ -0,0 +1,31 @@ +. + +/** + * Version information for qbank_editquestion. + * + * @package qbank_editquestion + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Safat Shahin + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$plugin->component = 'qbank_editquestion'; +$plugin->version = 2021062800; +$plugin->requires = 2021052500; +$plugin->maturity = MATURITY_STABLE; diff --git a/question/bank/editquestion/yui/build/moodle-qbank_editquestion-chooser/moodle-qbank_editquestion-chooser-debug.js b/question/bank/editquestion/yui/build/moodle-qbank_editquestion-chooser/moodle-qbank_editquestion-chooser-debug.js new file mode 100644 index 00000000000..f66e41aed8c --- /dev/null +++ b/question/bank/editquestion/yui/build/moodle-qbank_editquestion-chooser/moodle-qbank_editquestion-chooser-debug.js @@ -0,0 +1,78 @@ +YUI.add('moodle-qbank_editquestion-chooser', function (Y, NAME) { + +// 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 . + +/** + * JavaScript required by the add question pop-up. + * + * @module moodle-qbank_editquestion-chooser + */ + +var SELECTORS = { + CREATENEWQUESTION: 'div.createnewquestion', + CREATENEWQUESTIONFORM: 'div.createnewquestion form', + CHOOSERDIALOGUE: 'div.chooserdialoguebody', + CHOOSERHEADER: 'div.choosertitle' +}; + +function Chooser() { + Chooser.superclass.constructor.apply(this, arguments); +} + +Y.extend(Chooser, M.core.chooserdialogue, { + initializer: function() { + Y.all('form').each(function(node) { + if (/question\/bank\/editquestion\/addquestion\.php/.test(node.getAttribute('action'))) { + node.on('submit', this.displayQuestionChooser, this); + } + }, this); + }, + displayQuestionChooser: function(e) { + var dialogue = Y.one(SELECTORS.CREATENEWQUESTION + ' ' + SELECTORS.CHOOSERDIALOGUE), + header = Y.one(SELECTORS.CREATENEWQUESTION + ' ' + SELECTORS.CHOOSERHEADER); + + if (this.container === null) { + // Setup the dialogue, and then prepare the chooser if it's not already been set up. + this.setup_chooser_dialogue(dialogue, header, {}); + this.prepare_chooser(); + } + + // Update all of the hidden fields within the questionbank form. + var originForm = e.target.ancestor('form', true), + targetForm = this.container.one('form'), + hiddenElements = originForm.all('input[type="hidden"]'); + + targetForm.all('input.customfield').remove(); + hiddenElements.each(function(field) { + targetForm.appendChild(field.cloneNode()) + .removeAttribute('id') + .addClass('customfield'); + }); + + // Display the chooser dialogue. + this.display_chooser(e); + } +}, { + NAME: 'questionChooser' +}); + +M.question = M.question || {}; +M.question.init_chooser = function(config) { + return new Chooser(config); +}; + + +}, '@VERSION@', {"requires": ["moodle-core-chooserdialogue"]}); diff --git a/question/bank/editquestion/yui/build/moodle-qbank_editquestion-chooser/moodle-qbank_editquestion-chooser-min.js b/question/bank/editquestion/yui/build/moodle-qbank_editquestion-chooser/moodle-qbank_editquestion-chooser-min.js new file mode 100644 index 00000000000..adc2202662f --- /dev/null +++ b/question/bank/editquestion/yui/build/moodle-qbank_editquestion-chooser/moodle-qbank_editquestion-chooser-min.js @@ -0,0 +1 @@ +YUI.add("moodle-qbank_editquestion-chooser",function(r,e){var u="div.createnewquestion",a="div.chooserdialoguebody",c="div.choosertitle";function o(){o.superclass.constructor.apply(this,arguments)}r.extend(o,M.core.chooserdialogue,{initializer:function(){r.all("form").each(function(e){/question\/bank\/editquestion\/addquestion\.php/.test(e.getAttribute("action"))&&e.on("submit",this.displayQuestionChooser,this)},this)},displayQuestionChooser:function(e){var o,i,t,n=r.one(u+" "+a),s=r.one(u+" "+c);null===this.container&&(this.setup_chooser_dialogue(n,s,{}),this.prepare_chooser()),o=e.target.ancestor("form",!0),i=this.container.one("form"),t=o.all('input[type="hidden"]'),i.all("input.customfield").remove(),t.each(function(e){i.appendChild(e.cloneNode()).removeAttribute("id").addClass("customfield")}),this.display_chooser(e)}},{NAME:"questionChooser"}),M.question=M.question||{},M.question.init_chooser=function(e){return new o(e)}},"@VERSION@",{requires:["moodle-core-chooserdialogue"]}); \ No newline at end of file diff --git a/question/bank/editquestion/yui/build/moodle-qbank_editquestion-chooser/moodle-qbank_editquestion-chooser.js b/question/bank/editquestion/yui/build/moodle-qbank_editquestion-chooser/moodle-qbank_editquestion-chooser.js new file mode 100644 index 00000000000..f66e41aed8c --- /dev/null +++ b/question/bank/editquestion/yui/build/moodle-qbank_editquestion-chooser/moodle-qbank_editquestion-chooser.js @@ -0,0 +1,78 @@ +YUI.add('moodle-qbank_editquestion-chooser', function (Y, NAME) { + +// 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 . + +/** + * JavaScript required by the add question pop-up. + * + * @module moodle-qbank_editquestion-chooser + */ + +var SELECTORS = { + CREATENEWQUESTION: 'div.createnewquestion', + CREATENEWQUESTIONFORM: 'div.createnewquestion form', + CHOOSERDIALOGUE: 'div.chooserdialoguebody', + CHOOSERHEADER: 'div.choosertitle' +}; + +function Chooser() { + Chooser.superclass.constructor.apply(this, arguments); +} + +Y.extend(Chooser, M.core.chooserdialogue, { + initializer: function() { + Y.all('form').each(function(node) { + if (/question\/bank\/editquestion\/addquestion\.php/.test(node.getAttribute('action'))) { + node.on('submit', this.displayQuestionChooser, this); + } + }, this); + }, + displayQuestionChooser: function(e) { + var dialogue = Y.one(SELECTORS.CREATENEWQUESTION + ' ' + SELECTORS.CHOOSERDIALOGUE), + header = Y.one(SELECTORS.CREATENEWQUESTION + ' ' + SELECTORS.CHOOSERHEADER); + + if (this.container === null) { + // Setup the dialogue, and then prepare the chooser if it's not already been set up. + this.setup_chooser_dialogue(dialogue, header, {}); + this.prepare_chooser(); + } + + // Update all of the hidden fields within the questionbank form. + var originForm = e.target.ancestor('form', true), + targetForm = this.container.one('form'), + hiddenElements = originForm.all('input[type="hidden"]'); + + targetForm.all('input.customfield').remove(); + hiddenElements.each(function(field) { + targetForm.appendChild(field.cloneNode()) + .removeAttribute('id') + .addClass('customfield'); + }); + + // Display the chooser dialogue. + this.display_chooser(e); + } +}, { + NAME: 'questionChooser' +}); + +M.question = M.question || {}; +M.question.init_chooser = function(config) { + return new Chooser(config); +}; + + +}, '@VERSION@', {"requires": ["moodle-core-chooserdialogue"]}); diff --git a/question/bank/editquestion/yui/src/chooser/build.json b/question/bank/editquestion/yui/src/chooser/build.json new file mode 100644 index 00000000000..0a340c0a46d --- /dev/null +++ b/question/bank/editquestion/yui/src/chooser/build.json @@ -0,0 +1,10 @@ +{ + "name": "moodle-qbank_editquestion-chooser", + "builds": { + "moodle-qbank_editquestion-chooser": { + "jsfiles": [ + "chooser.js" + ] + } + } +} diff --git a/question/bank/editquestion/yui/src/chooser/js/chooser.js b/question/bank/editquestion/yui/src/chooser/js/chooser.js new file mode 100644 index 00000000000..9b4c03b75e0 --- /dev/null +++ b/question/bank/editquestion/yui/src/chooser/js/chooser.js @@ -0,0 +1,73 @@ +// 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 . + +/** + * JavaScript required by the add question pop-up. + * + * @module moodle-qbank_editquestion-chooser + */ + +var SELECTORS = { + CREATENEWQUESTION: 'div.createnewquestion', + CREATENEWQUESTIONFORM: 'div.createnewquestion form', + CHOOSERDIALOGUE: 'div.chooserdialoguebody', + CHOOSERHEADER: 'div.choosertitle' +}; + +function Chooser() { + Chooser.superclass.constructor.apply(this, arguments); +} + +Y.extend(Chooser, M.core.chooserdialogue, { + initializer: function() { + Y.all('form').each(function(node) { + if (/question\/bank\/editquestion\/addquestion\.php/.test(node.getAttribute('action'))) { + node.on('submit', this.displayQuestionChooser, this); + } + }, this); + }, + displayQuestionChooser: function(e) { + var dialogue = Y.one(SELECTORS.CREATENEWQUESTION + ' ' + SELECTORS.CHOOSERDIALOGUE), + header = Y.one(SELECTORS.CREATENEWQUESTION + ' ' + SELECTORS.CHOOSERHEADER); + + if (this.container === null) { + // Setup the dialogue, and then prepare the chooser if it's not already been set up. + this.setup_chooser_dialogue(dialogue, header, {}); + this.prepare_chooser(); + } + + // Update all of the hidden fields within the questionbank form. + var originForm = e.target.ancestor('form', true), + targetForm = this.container.one('form'), + hiddenElements = originForm.all('input[type="hidden"]'); + + targetForm.all('input.customfield').remove(); + hiddenElements.each(function(field) { + targetForm.appendChild(field.cloneNode()) + .removeAttribute('id') + .addClass('customfield'); + }); + + // Display the chooser dialogue. + this.display_chooser(e); + } +}, { + NAME: 'questionChooser' +}); + +M.question = M.question || {}; +M.question.init_chooser = function(config) { + return new Chooser(config); +}; diff --git a/question/bank/editquestion/yui/src/chooser/meta/chooser.json b/question/bank/editquestion/yui/src/chooser/meta/chooser.json new file mode 100644 index 00000000000..2e51762975d --- /dev/null +++ b/question/bank/editquestion/yui/src/chooser/meta/chooser.json @@ -0,0 +1,7 @@ +{ + "moodle-qbank_editquestion-chooser": { + "requires": [ + "moodle-core-chooserdialogue" + ] + } +} diff --git a/question/classes/local/bank/view.php b/question/classes/local/bank/view.php index 74ababaae01..36e8436b9f2 100644 --- a/question/classes/local/bank/view.php +++ b/question/classes/local/bank/view.php @@ -25,6 +25,7 @@ namespace core_question\local\bank; use core_question\bank\search\condition; +use qbank_editquestion\editquestion_helper; /** * This class prints a view of the question bank. @@ -163,8 +164,7 @@ class view { // Create the url of the new question page to forward to. $this->returnurl = $pageurl->out_as_local_url(false); - $this->editquestionurl = new \moodle_url('/question/question.php', - ['returnurl' => $this->returnurl]); + $this->editquestionurl = new \moodle_url('/question/bank/editquestion/question.php', ['returnurl' => $this->returnurl]); if ($this->cm !== null) { $this->editquestionurl->param('cmid', $this->cm->id); } else { @@ -892,14 +892,10 @@ class view { * @param bool $canadd */ protected function create_new_question_form($category, $canadd): void { - echo \html_writer::start_tag('div', ['class' => "createnewquestion"]); - if ($canadd) { - create_new_question_button($category->id, $this->editquestionurl->params(), - get_string('createnewquestion', 'question')); - } else { - print_string('nopermissionadd', 'question'); + if (\core\plugininfo\qbank::is_plugin_enabled('qbank_editquestion')) { + echo editquestion_helper::create_new_question_button($category->id, + $this->requiredcolumns['qbank_editquestion\edit_action_column']->editquestionurl->params(), $canadd); } - echo \html_writer::end_tag('div'); } /** diff --git a/question/classes/output/qbank_chooser.php b/question/classes/output/qbank_chooser.php index 348a2ecdb88..8f278291454 100644 --- a/question/classes/output/qbank_chooser.php +++ b/question/classes/output/qbank_chooser.php @@ -38,6 +38,9 @@ use question_bank; * @package core_question * @copyright 2016 Frédéric Massart - FMCorz.net * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @deprecated since Moodle 4.0 + * @see \qbank_editquestion\qbank_chooser + * @todo MDL-72004 delete the class and add it to lib/db/renameclasses.php pointing to the plugin */ class qbank_chooser extends \core\output\chooser { diff --git a/question/classes/output/qbank_chooser_item.php b/question/classes/output/qbank_chooser_item.php index da834d1adc1..137025e7f56 100644 --- a/question/classes/output/qbank_chooser_item.php +++ b/question/classes/output/qbank_chooser_item.php @@ -35,6 +35,9 @@ use pix_icon; * @package core_question * @copyright 2016 Frédéric Massart - FMCorz.net * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @deprecated since Moodle 4.0 + * @see \qbank_editquestion\qbank_chooser_item + * @todo MDL-72004 delete the class and add it to lib/db/renameclasses.php pointing to the plugin */ class qbank_chooser_item extends \core\output\chooser_item { diff --git a/question/editlib.php b/question/editlib.php index 8da8963cb4f..4a5e7aa9647 100644 --- a/question/editlib.php +++ b/question/editlib.php @@ -222,7 +222,7 @@ class_alias('core_question\local\bank\action_column_base', 'question_bank_action * @deprecated since Moodle 2.7 MDL-40457 * @todo MDl-72004 delete the class alias, not done in MDL-71516 for any potential error from other plugins. */ -class_alias('core_question\bank\edit_action_column', 'question_bank_edit_action_column', true); +class_alias('qbank_editquestion\edit_action_column', 'question_bank_edit_action_column', true); /** * Question bank column for the duplicate action icon. @@ -232,7 +232,7 @@ class_alias('core_question\bank\edit_action_column', 'question_bank_edit_action_ * @deprecated since Moodle 2.7 MDL-40457 * @todo MDl-72004 delete the class alias, not done in MDL-71516 for any potential error from other plugins. */ -class_alias('core_question\bank\copy_action_column', 'question_bank_copy_action_column', true); +class_alias('qbank_editquestion\copy_action_column', 'question_bank_copy_action_column', true); /** * Question bank columns for the preview action icon. @@ -633,6 +633,9 @@ function require_login_in_context($contextorid = null){ * the qtype radio buttons. * @param $allowedqtypes optional list of qtypes that are allowed. If given, only * those qtypes will be shown. Example value array('description', 'multichoice'). + * @deprecated since Moodle 4.0 + * @see \qbank_editquestion\editquestion_helper::print_choose_qtype_to_add_form() + * @todo MDL-72004 deprecate the function and add debugging message. */ function print_choose_qtype_to_add_form($hiddenparams, array $allowedqtypes = null, $enablejs = true) { global $CFG, $PAGE, $OUTPUT; @@ -654,8 +657,12 @@ function print_choose_qtype_to_add_form($hiddenparams, array $allowedqtypes = nu * @param string $caption the text to display on the button. * @param string $tooltip a tooltip to add to the button (optional). * @param bool $disabled if true, the button will be disabled. + * @deprecated since Moodle 4.0 + * @see \qbank_editquestion\editquestion_helper::create_new_question_button() */ function create_new_question_button($categoryid, $params, $caption, $tooltip = '', $disabled = false) { + debugging('Function create_new_question_button() has been deprecated and moved to bank/editquestion, + please use qbank_editquestion\editquestion_helper::create_new_question_button() instead.', DEBUG_DEVELOPER); global $CFG, $PAGE, $OUTPUT; static $choiceformprinted = false; $params['category'] = $categoryid; diff --git a/question/renderer.php b/question/renderer.php index e08831536ab..3ca2feb5e21 100644 --- a/question/renderer.php +++ b/question/renderer.php @@ -96,6 +96,9 @@ class core_question_bank_renderer extends plugin_renderer_base { * * @param renderable $qbankchooser The chooser. * @return string + * @deprecated since Moodle 4.0 + * @see \qbank_editquestion\output\renderer + * @todo MDL-72004 deprecate the function and add debugging message. */ public function render_qbank_chooser(renderable $qbankchooser) { return $this->render_from_template('core_question/qbank_chooser', $qbankchooser->export_for_template($this)); diff --git a/question/yui/build/moodle-question-chooser/moodle-question-chooser-debug.js b/question/yui/build/moodle-question-chooser/moodle-question-chooser-debug.js index 0c927881572..8ae50df8904 100644 --- a/question/yui/build/moodle-question-chooser/moodle-question-chooser-debug.js +++ b/question/yui/build/moodle-question-chooser/moodle-question-chooser-debug.js @@ -1,5 +1,29 @@ YUI.add('moodle-question-chooser', function (Y, NAME) { +// 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 . + +/** + * JavaScript required by the question type chooser pop-up. + * + * @module moodle-question-chooser + */ + +Y.log("The moodle-question-chooser module has been deprecated. " + + "Please use moodle-qbank_editquestion-chooser instead.", 'moodle-core-notification', 'warn'); + var SELECTORS = { CREATENEWQUESTION: 'div.createnewquestion', CREATENEWQUESTIONFORM: 'div.createnewquestion form', diff --git a/question/yui/build/moodle-question-chooser/moodle-question-chooser.js b/question/yui/build/moodle-question-chooser/moodle-question-chooser.js index 0c927881572..cfeecae9b4e 100644 --- a/question/yui/build/moodle-question-chooser/moodle-question-chooser.js +++ b/question/yui/build/moodle-question-chooser/moodle-question-chooser.js @@ -1,5 +1,27 @@ YUI.add('moodle-question-chooser', function (Y, NAME) { +// 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 . + +/** + * JavaScript required by the question type chooser pop-up. + * + * @module moodle-question-chooser + */ + + var SELECTORS = { CREATENEWQUESTION: 'div.createnewquestion', CREATENEWQUESTIONFORM: 'div.createnewquestion form', diff --git a/question/yui/src/chooser/js/chooser.js b/question/yui/src/chooser/js/chooser.js index 4ae91a652ae..e839a961ae7 100644 --- a/question/yui/src/chooser/js/chooser.js +++ b/question/yui/src/chooser/js/chooser.js @@ -1,3 +1,27 @@ +// 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 . + +/** + * JavaScript required by the question type chooser pop-up. + * + * @module moodle-question-chooser + */ + +Y.log("The moodle-question-chooser module has been deprecated. " + + "Please use moodle-qbank_editquestion-chooser instead.", 'moodle-core-notification', 'warn'); + var SELECTORS = { CREATENEWQUESTION: 'div.createnewquestion', CREATENEWQUESTIONFORM: 'div.createnewquestion form',