MDL-66553 question bank: show tags and idnumbers in question list

This commit is contained in:
Tim Hunt
2019-10-11 13:59:26 +01:00
parent d4b47c5442
commit 61cc1e6494
10 changed files with 168 additions and 21 deletions
+1 -2
View File
@@ -968,8 +968,7 @@ table.quizreviewsummary td.cell {
border: 0 none;
}
#categoryquestions th.modifiername .sorters,
#categoryquestions th.creatorname .sorters {
#categoryquestions th .sorters {
font-weight: normal;
font-size: 0.8em;
}
@@ -35,7 +35,7 @@ Feature: Adding random questions to a quiz based on category and tags
| Tags | foo |
And I press "id_submitbutton"
And I click on "Manage tags" "link" in the "question 2 name" "table_row"
And I set the following fields to these values:
And I set the following fields in the "Question tags" "dialogue" to these values:
| Tags | bar |
And I press "Save changes"
And I am on "Course 1" course homepage
+37 -1
View File
@@ -257,6 +257,42 @@ abstract class column_base {
return array();
}
/**
* If this column needs extra data (e.g. tags) then load that here.
*
* The extra data should be added to the question object in the array.
* Probably a good idea to check that another column has not already
* loaded the data you want.
*
* @param \stdClass[] $questions the questions that will be displayed.
*/
public function load_additional_data(array $questions) {
}
/**
* Load the tags for each question.
*
* Helper that can be used from {@link load_additional_data()};
*
* @param array $questions
*/
public function load_question_tags(array $questions) {
$firstquestion = reset($questions);
if (isset($firstquestion->tags)) {
// Looks like tags are already loaded, so don't do it again.
return;
}
// Load the tags.
$tagdata = \core_tag_tag::get_items_tags('core_question', 'question',
array_keys($questions));
// Add them to the question objects.
foreach ($tagdata as $questionid => $tags) {
$questions[$questionid]->tags = $tags;
}
}
/**
* Can this column be sorted on? You can return either:
* + false for no (the default),
@@ -264,7 +300,7 @@ abstract class column_base {
* + an array of subnames to sort on as follows
* return array(
* 'firstname' => array('field' => 'uc.firstname', 'title' => get_string('firstname')),
* 'lastname' => array('field' => 'uc.lastname', 'field' => get_string('lastname')),
* 'lastname' => array('field' => 'uc.lastname', 'title' => get_string('lastname')),
* );
* As well as field, and field, you can also add 'revers' => 1 if you want the default sort
* order to be DESC.
@@ -0,0 +1,89 @@
<?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/>.
/**
* A question bank column showing the question name with idnumber and tags.
*
* @package core_question
* @copyright 2019 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
/**
* A question bank column showing the question name with idnumber and tags.
*
* @copyright 2019 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class question_name_idnumber_tags_column extends question_name_column {
public function get_name() {
return 'qnameidnumbertags';
}
protected function display_content($question, $rowclasses) {
global $OUTPUT;
$layoutclasses = 'd-inline-flex flex-nowrap overflow-hidden w-100';
$labelfor = $this->label_for($question);
if ($labelfor) {
echo '<label for="' . $labelfor . '" class="' . $layoutclasses . '">';
$closetag = '</label>';
} else {
echo '<span class="' . $layoutclasses . '">';
$closetag = '</span>';
}
// Question name.
echo \html_writer::span(format_string($question->name), 'questionname flex-grow-1 flex-shrink-1 text-truncate');
// Question idnumber.
if ($question->idnumber !== null && $question->idnumber !== '') {
echo ' ' . \html_writer::span(
\html_writer::span(get_string('idnumber', 'question'), 'accesshide') . ' ' .
\html_writer::span($question->idnumber, 'badge badge-primary'), 'ml-1');
}
// Question tags.
if (!empty($question->tags)) {
$tags = \core_tag_tag::get_item_tags('core_question', 'question', $question->id);
echo $OUTPUT->tag_list($tags, null, 'd-inline flex-shrink-1 text-truncate ml-1', 0, null, true);
}
echo $closetag; // Computed above to ensure it matches.
}
public function get_required_fields() {
$fields = parent::get_required_fields();
$fields[] = 'q.idnumber';
return $fields;
}
public function is_sortable() {
return [
'name' => ['field' => 'q.name', 'title' => get_string('questionname', 'question')],
'lastname' => ['field' => 'q.idnumber', 'title' => get_string('idnumber', 'question')],
];
}
public function load_additional_data(array $questions) {
parent::load_additional_data($questions);
parent::load_question_tags($questions);
}
}
+14 -7
View File
@@ -177,9 +177,9 @@ class view {
if (empty($CFG->questionbankcolumns)) {
$questionbankcolumns = array('checkbox_column', 'question_type_column',
'question_name_column', 'tags_action_column', 'edit_action_column',
'copy_action_column', 'preview_action_column', 'delete_action_column',
'creator_name_column', 'modifier_name_column');
'question_name_idnumber_tags_column', 'tags_action_column', 'edit_action_column',
'copy_action_column', 'preview_action_column', 'delete_action_column',
'creator_name_column', 'modifier_name_column');
} else {
$questionbankcolumns = explode(',', $CFG->questionbankcolumns);
}
@@ -467,9 +467,9 @@ class view {
protected function load_page_questions($page, $perpage) {
global $DB;
$questions = $DB->get_recordset_sql($this->loadsql, $this->sqlparams, $page * $perpage, $perpage);
if (!$questions->valid()) {
// No questions on this page. Reset to page 0.
if (empty($questions)) {
$questions->close();
// No questions on this page. Reset to page 0.
$questions = $DB->get_recordset_sql($this->loadsql, $this->sqlparams, 0, $perpage);
}
return $questions;
@@ -784,7 +784,15 @@ class view {
if ($totalnumber == 0) {
return;
}
$questions = $this->load_page_questions($page, $perpage);
$questionsrs = $this->load_page_questions($page, $perpage);
$questions = [];
foreach ($questionsrs as $question) {
$questions[$question->id] = $question;
}
$questionsrs->close();
foreach ($this->requiredcolumns as $name => $column) {
$column->load_additional_data($questions);
}
echo '<div class="categorypagingbarcontainer">';
$pageingurl = new \moodle_url('edit.php', $pageurl->params());
@@ -805,7 +813,6 @@ class view {
$this->print_table_row($question, $rowcount);
$rowcount += 1;
}
$questions->close();
$this->end_table();
echo "</div>\n";
+1 -1
View File
@@ -34,7 +34,7 @@ Feature: A teacher can duplicate questions in the question bank
Then I should see "Duplicated question name"
And I should see "Test question to be copied"
And "Duplicated question name" row "Last modified by" column of "categoryquestions" table should contain "Teacher 1"
And "Test question to be copied" row "Created by" column of "categoryquestions" table should contain "Admin User"
And "Test question to be copied ID number qid" row "Created by" column of "categoryquestions" table should contain "Admin User"
@javascript
Scenario: Duplicated questions automatically get a new name suggested
@@ -32,9 +32,11 @@ Feature: A teacher can put questions in categories in the question bank
| Name | New Category 1 |
| Parent category | Top |
| Category info | Created as a test |
| ID number | newcatidnumber |
And I press "submitbutton"
Then I should see "New Category 1 (0)"
Then I should see "New Category 1 ID number newcatidnumber (0)"
And I should see "Created as a test" in the "New Category 1" "list_item"
And "New Category 1 [newcatidnumber]" "option" should exist in the "Parent category" "select"
Scenario: A question category can be edited
When I navigate to "Question bank > Categories" in current page administration
@@ -35,7 +35,7 @@ Feature: A teacher can put questions with idnumbers in categories with idnumbers
# Correction to a unique idnumber for the context.
And I set the field "ID number" to "c1unused"
And I press "Add category"
Then I should see "Sub used category (0)"
Then I should see "Sub used category ID number c1unused (0)"
And I should see "Created as a test" in the "Sub used category" "list_item"
Scenario: A question category can be edited and saved without changing the idnumber
+13 -7
View File
@@ -18,10 +18,10 @@ Feature: The questions in the question bank can be sorted in various ways
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | user | questiontext |
| Test questions | essay | A question 1 name | admin | Question 1 text |
| Test questions | essay | B question 2 name | teacher1 | Question 2 text |
| Test questions | numerical | C question 3 name | teacher1 | Question 3 text |
| questioncategory | qtype | name | user | questiontext | idnumber |
| Test questions | essay | A question 1 name | admin | Question 1 text | |
| Test questions | essay | B question 2 name | teacher1 | Question 2 text | |
| Test questions | numerical | C question 3 name | teacher1 | Question 3 text | numidnum |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank > Questions" in current page administration
@@ -30,6 +30,12 @@ Feature: The questions in the question bank can be sorted in various ways
Scenario: The questions are sorted by type by default
Then "A question 1 name" "checkbox" should appear before "C question 3 name" "checkbox"
@javascript
Scenario: The questions can be sorted by idnumber
When I follow "Sort by ID number ascending"
Then "C question 3 name" "checkbox" should appear before "A question 1 name" "checkbox"
And I should see "numidnum" in the "C question 3 name" "table_row"
@javascript
Scenario: The questions can be sorted in reverse order by type
When I follow "Sort by Question type descending"
@@ -37,14 +43,14 @@ Feature: The questions in the question bank can be sorted in various ways
@javascript
Scenario: The questions can be sorted by name
When I follow "Sort by Question ascending"
When I follow "Sort by Question name ascending"
Then "A question 1 name" "checkbox" should appear before "B question 2 name" "checkbox"
And "B question 2 name" "checkbox" should appear before "C question 3 name" "checkbox"
@javascript
Scenario: The questions can be sorted in reverse order by name
When I follow "Sort by Question ascending"
And I follow "Sort by Question descending"
When I follow "Sort by Question name ascending"
And I follow "Sort by Question name descending"
Then "C question 3 name" "checkbox" should appear before "B question 2 name" "checkbox"
And "B question 2 name" "checkbox" should appear before "A question 1 name" "checkbox"
+8
View File
@@ -1,5 +1,13 @@
This files describes API changes for code that uses the question API.
=== 3.8 ===
If you have customised the display of the question bank (using $CFG->questionbankcolumns)
then be aware that the default configuration has changed, and you may wish to make
equivalent changes in your customised version. The old column question_name_column
has been replaced by question_name_idnumber_tags_column. The old question_name_column
still exists, so it is safe to continue using it.
=== 3.7 ===
The code for the is_valid_number function that was duplicated in the