From f17d5783e1cb9cda19ff191a7c5310a88476d2b1 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 13 Mar 2024 18:05:55 +0000 Subject: [PATCH] MDL-81227 question bank: improve the order of the action menu --- .../deletequestion/classes/delete_action.php | 4 +++ .../bank/editquestion/classes/copy_action.php | 4 +++ .../bank/editquestion/classes/edit_action.php | 4 +++ .../exporttoxml/classes/export_xml_action.php | 4 +++ .../bank/history/classes/history_action.php | 4 +++ .../classes/preview_action.php | 4 +++ .../bank/tagquestion/classes/tags_action.php | 4 +++ question/bank/upgrade.txt | 7 +++++ question/classes/local/bank/view.php | 14 ++++++++++ .../classes/local/bank/view_component.php | 27 +++++++++++++++++++ 10 files changed, 76 insertions(+) diff --git a/question/bank/deletequestion/classes/delete_action.php b/question/bank/deletequestion/classes/delete_action.php index 88dfca34243..b1fc73b5474 100644 --- a/question/bank/deletequestion/classes/delete_action.php +++ b/question/bank/deletequestion/classes/delete_action.php @@ -75,6 +75,10 @@ class delete_action extends question_action_base { } } + public function get_menu_position(): int { + return 400; + } + protected function get_url_icon_and_label(\stdClass $question): array { if (!question_has_capability_on($question, 'edit')) { return [null, null, null]; diff --git a/question/bank/editquestion/classes/copy_action.php b/question/bank/editquestion/classes/copy_action.php index c3fa8f597b3..514e91005b3 100644 --- a/question/bank/editquestion/classes/copy_action.php +++ b/question/bank/editquestion/classes/copy_action.php @@ -57,6 +57,10 @@ class copy_action extends question_action_base { } } + public function get_menu_position(): int { + return 250; + } + /** * Get the URL for duplicating a question as a moodle_url. * diff --git a/question/bank/editquestion/classes/edit_action.php b/question/bank/editquestion/classes/edit_action.php index e3a85b5c4f5..d642e37ce0a 100644 --- a/question/bank/editquestion/classes/edit_action.php +++ b/question/bank/editquestion/classes/edit_action.php @@ -67,6 +67,10 @@ class edit_action extends question_action_base { } } + public function get_menu_position(): int { + return 200; + } + /** * Get the URL for editing a question as a link. * diff --git a/question/bank/exporttoxml/classes/export_xml_action.php b/question/bank/exporttoxml/classes/export_xml_action.php index 2dea79e2a46..b1d6d7f1f6c 100644 --- a/question/bank/exporttoxml/classes/export_xml_action.php +++ b/question/bank/exporttoxml/classes/export_xml_action.php @@ -36,6 +36,10 @@ class export_xml_action extends question_action_base { $this->strexportasxml = get_string('exportasxml', 'question'); } + public function get_menu_position(): int { + return 600; + } + 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 diff --git a/question/bank/history/classes/history_action.php b/question/bank/history/classes/history_action.php index 057aa3ecdd5..7157cf806d6 100644 --- a/question/bank/history/classes/history_action.php +++ b/question/bank/history/classes/history_action.php @@ -36,6 +36,10 @@ class history_action extends question_action_base { $this->strpreview = get_string('history_action', 'qbank_history'); } + public function get_menu_position(): int { + return 500; + } + 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 diff --git a/question/bank/previewquestion/classes/preview_action.php b/question/bank/previewquestion/classes/preview_action.php index f7e3f2444f9..44218fe7b47 100644 --- a/question/bank/previewquestion/classes/preview_action.php +++ b/question/bank/previewquestion/classes/preview_action.php @@ -38,6 +38,10 @@ class preview_action extends question_action_base { $this->strpreview = get_string('preview'); } + public function get_menu_position(): int { + return 100; + } + 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 diff --git a/question/bank/tagquestion/classes/tags_action.php b/question/bank/tagquestion/classes/tags_action.php index 402be6a9b99..a2451f629ca 100644 --- a/question/bank/tagquestion/classes/tags_action.php +++ b/question/bank/tagquestion/classes/tags_action.php @@ -48,6 +48,10 @@ class tags_action extends question_action_base { $this->managetags = get_string('managetags', 'tag'); } + public function get_menu_position(): int { + return 300; + } + protected function check_tags_status(): void { global $CFG; if (!$CFG->usetags) { diff --git a/question/bank/upgrade.txt b/question/bank/upgrade.txt index fa9a68c086c..4ef4a3ae07b 100644 --- a/question/bank/upgrade.txt +++ b/question/bank/upgrade.txt @@ -1,6 +1,13 @@ This file describes core qbank plugin changes in /question/bank/*, information provided here is intended especially for developers. +=== 4.4 === + +* Question bank actions (anything that subclasses question_action_base) should implement the + method get_menu_position() to control what position in the action menu it appears it. + See the comment on the base class method for more details. If you don't do this, you will + get a debugging warning. + === 4.3 === * The helper class in qbank_statistics has had several of its methods deprecated. diff --git a/question/classes/local/bank/view.php b/question/classes/local/bank/view.php index e2b3b80ee01..878ad96756a 100644 --- a/question/classes/local/bank/view.php +++ b/question/classes/local/bank/view.php @@ -375,8 +375,22 @@ class view { $menuactions = $plugin->get_question_actions($this); foreach ($menuactions as $menuaction) { $this->questionactions[$menuaction::class] = $menuaction; + if ($menuaction->get_menu_position() === question_action_base::MENU_POSITION_NOT_SET) { + debugging('Question bank actions must define the get_menu_position method. ' . + $menuaction::class . ' does not.', DEBUG_DEVELOPER); + } } } + + // Sort according to each action's desired position. + // Note, we are relying on the sort to be stable for + // equal values of get_menu_position. + uasort( + $this->questionactions, + function (question_action_base $a, question_action_base $b) { + return $a->get_menu_position() <=> $b->get_menu_position(); + }, + ); } /** diff --git a/question/classes/local/bank/view_component.php b/question/classes/local/bank/view_component.php index a50397921e3..486c92c1641 100644 --- a/question/classes/local/bank/view_component.php +++ b/question/classes/local/bank/view_component.php @@ -25,6 +25,8 @@ namespace core_question\local\bank; * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ abstract class view_component { + /** @var int value we return from get_menu_position here. Subclasses should override this. */ + const MENU_POSITION_NOT_SET = 6666; /** @var view Question bank view. */ protected $qbank; @@ -45,6 +47,31 @@ abstract class view_component { protected function init(): void { } + /** + * Return an integer to indicate the desired position in the menu for this link, smaller at the top. + * + * The standard menu items in Moodle core return these numbers: + * 100 preview_action + * 200 edit_action + * 250 copy_action + * 300 tags_action + * 400 delete_action + * 500 history_action + * 600 export_xml_action + * (So, if you want your action at a particular place in the order, there should be space.) + * + * If two actions get the same order number, then the tie-break on the sort + * is plugin name, then the order returned by get_question_actions for that plugin. + * + * @return int desired position. Smallest at the top. + */ + public function get_menu_position(): int { + // We return a big number by default, which is after all the standard core links, + // so they go first. This should be overridden by all plugins, and not overriding will + // generate a debugging warning from {@see \core_question\local\bank\view::init_question_actions()}. + return self::MENU_POSITION_NOT_SET; + } + /** * Return an array 'table_alias' => 'JOIN clause' to bring in any data that * this feature requires.