Skip to content

Commit 72677b8

Browse files
MDL-81407 qbank_columnsortorder: Fix error displaying hiddencols
When the question custom fields were deleted, if there were any hidden columns in qbank Column sort order referring those fields they were throwing 'Custom field does not exist' exception. Changes done to ignore such fields and display valid hiddencols, as these references were breaking the qbank Column sort order and Question bank pages.
1 parent 477aa7c commit 72677b8

File tree

6 files changed

+114
-17
lines changed

6 files changed

+114
-17
lines changed

question/bank/columnsortorder/classes/column_manager.php

+31-13
Original file line numberDiff line numberDiff line change
@@ -214,15 +214,12 @@ public function get_columns(): array {
214214
* @return array
215215
*/
216216
public function get_disabled_columns(): array {
217+
$result = $this->create_column_objects(array_keys($this->disabledcolumns));
217218
$disabled = [];
218-
if ($this->disabledcolumns) {
219-
foreach (array_keys($this->disabledcolumns) as $column) {
220-
[$classname, $columnname] = explode(column_base::ID_SEPARATOR, $column, 2);
221-
$columnobject = $classname::from_column_name($this->get_questionbank(), $columnname);
222-
$disabled[$column] = (object) [
223-
'disabledname' => $columnobject->get_title(),
224-
];
225-
}
219+
foreach ($result as $column => $columnobject) {
220+
$disabled[$column] = (object) [
221+
'disabledname' => $columnobject->get_title(),
222+
];
226223
}
227224
return $disabled;
228225
}
@@ -368,11 +365,32 @@ public function get_colsize_map(): array {
368365
* @return array
369366
*/
370367
public function get_hidden_columns(): array {
371-
return array_reduce($this->hiddencolumns, function($result, $hiddencolumn) {
372-
[$columnclass, $columnname] = explode(column_base::ID_SEPARATOR, $hiddencolumn, 2);
373-
$result[$hiddencolumn] = $columnclass::from_column_name($this->get_questionbank(), $columnname)->get_title();
374-
return $result;
375-
}, []);
368+
$result = $this->create_column_objects($this->hiddencolumns);
369+
$hidden = [];
370+
foreach ($result as $column => $columnobject) {
371+
$hidden[$column] = $columnobject->get_title();
372+
}
373+
return $hidden;
374+
}
375+
376+
/**
377+
* Returns an array of column objects.
378+
*
379+
* @param array $columnsnames Array of columns.
380+
* @return column_base[] Array of $columnsname => $columnobject
381+
*/
382+
public function create_column_objects(array $columnsnames): array {
383+
$result = [];
384+
foreach ($columnsnames as $column) {
385+
[$columnclass, $columnname] = explode(column_base::ID_SEPARATOR, $column, 2);
386+
if (class_exists($columnclass)) {
387+
$columnobject = $columnclass::from_column_name($this->get_questionbank(), $columnname, true);
388+
if ($columnobject != null) {
389+
$result[$column] = $columnobject;
390+
}
391+
}
392+
}
393+
return $result;
376394
}
377395

378396
public function get_column_width(column_base $column): string {

question/bank/columnsortorder/tests/behat/admin_settings.feature

+34
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,37 @@ Feature: Set default question bank column order and size
116116
Then "Last used" "table_row" should exist
117117
And "Question" "table_row" should appear before "Comments" "table_row"
118118
And the field "Width of 'Question' in pixels" matches value ""
119+
120+
Scenario: Deleting a custom field which is removed from the Column sort order
121+
Given the following "custom field categories" exist:
122+
| name | component | area | itemid |
123+
| Category for test | qbank_customfields | question | 0 |
124+
And the following "custom fields" exist:
125+
| name | category | type | shortname | configdata |
126+
| Field 1 | Category for test | text | f1 | {"visibility":"2"} |
127+
| Field 2 | Category for test | text | f2 | {"visibility":"2"} |
128+
And I change the window size to "large"
129+
When I log in as "admin"
130+
And I navigate to "Plugins > Question bank plugins > Column sort order" in site administration
131+
And "Field 1" "table_row" should exist
132+
And "Field 2" "table_row" should exist
133+
And I click on "Actions menu" "link" in the "Field 1" "table_row"
134+
And I choose "Remove" in the open action menu
135+
136+
# Delete a question custom field.
137+
And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
138+
And I click on "Delete" "link" in the "Field 1" "table_row"
139+
And I click on "Yes" "button" in the "Confirm" "dialogue"
140+
And I navigate to "Plugins > Question bank plugins > Column sort order" in site administration
141+
Then I should see "Column sort order"
142+
And "Field 2" "table_row" should exist
143+
And I click on "Actions menu" "link" in the "Field 2" "table_row"
144+
And I choose "Remove" in the open action menu
145+
146+
# Delete the question custom category.
147+
And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
148+
And I click on "[data-role='deletecategory']" "css_element"
149+
And I click on "Yes" "button" in the "Confirm" "dialogue"
150+
And I should not see "Category for test" in the "#customfield_catlist" "css_element"
151+
And I navigate to "Plugins > Question bank plugins > Column sort order" in site administration
152+
And I should see "Column sort order"

question/bank/columnsortorder/tests/behat/question_bank.feature

+35
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,38 @@ Feature: Set question bank column order and size
141141
Then I should see "Question bank"
142142
And "Create a new question" "button" should exist
143143
# Really, we are just checking the question bank displayed without errors.
144+
145+
Scenario: Deleting a custom field which a user had removed from his preferences
146+
Given the following "custom field categories" exist:
147+
| name | component | area | itemid |
148+
| Category for test | qbank_customfields | question | 0 |
149+
And the following "custom fields" exist:
150+
| name | category | type | shortname | configdata |
151+
| Field 1 | Category for test | text | f1 | {"visibility":"2"} |
152+
| Field 2 | Category for test | text | f2 | {"visibility":"2"} |
153+
And I am on the "Test quiz Q001" "mod_quiz > question bank" page logged in as "teacher1"
154+
And I apply question bank filter "Category" with value "Question category 1"
155+
And I click on "Actions menu" "link" in the "Field 1" "qbank_columnsortorder > column header"
156+
And I choose "Remove" in the open action menu
157+
And I click on "Actions menu" "link" in the "Field 2" "qbank_columnsortorder > column header"
158+
And I choose "Remove" in the open action menu
159+
And "Field 2" "qbank_columnsortorder > column header" should not exist
160+
161+
# Delete a question custom field.
162+
And I log in as "admin"
163+
And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
164+
And I click on "Delete" "link" in the "Field 1" "table_row"
165+
And I click on "Yes" "button" in the "Confirm" "dialogue"
166+
And I am on the "Test quiz Q001" "mod_quiz > question bank" page logged in as "teacher1"
167+
And I apply question bank filter "Category" with value "Question category 1"
168+
Then I should see "Question bank"
169+
170+
# Delete the question custom category.
171+
And I log in as "admin"
172+
And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
173+
And I click on "[data-role='deletecategory']" "css_element"
174+
And I click on "Yes" "button" in the "Confirm" "dialogue"
175+
And I should not see "Category for test" in the "#customfield_catlist" "css_element"
176+
And I am on the "Test quiz Q001" "mod_quiz > question bank" page logged in as "teacher1"
177+
And I apply question bank filter "Category" with value "Question category 1"
178+
And I should see "Question bank"

question/bank/customfields/classes/custom_field_column.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,18 @@ public function __construct(\core_question\local\bank\view $qbank, \core_customf
4444
$this->field = $field;
4545
}
4646

47-
public static function from_column_name(view $view, string $columnname): custom_field_column {
47+
public static function from_column_name(view $view, string $columnname, bool $ingoremissing = false): ?custom_field_column {
4848
$handler = question_handler::create();
4949
foreach ($handler->get_fields() as $field) {
5050
if ($field->get('shortname') == $columnname) {
5151
return new static($view, $field);
5252
}
5353
}
54-
throw new \coding_exception('Custom field ' . $columnname . ' does not exist.');
54+
if ($ingoremissing) {
55+
return null;
56+
} else {
57+
throw new \coding_exception('Custom field ' . $columnname . ' does not exist.');
58+
}
5559
}
5660

5761
/**

question/bank/upgrade.txt

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
This file describes core qbank plugin changes in /question/bank/*,
22
information provided here is intended especially for developers.
33

4+
=== 4.4.1 ===
5+
6+
* column_base::from_column_name now has an ignoremissing field, which can be used to ignore
7+
if the class does not exist, instead of throwing an exception.
8+
49
=== 4.4 ===
510

611
* Question bank actions (anything that subclasses question_action_base) should implement the

question/classes/local/bank/column_base.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ abstract class column_base extends view_component {
5757
*
5858
* @param view $view Question bank view
5959
* @param string $columnname The column name for this instance, as returned by {@see get_column_name()}
60-
* @return column_base An instance of this class.
60+
* @param bool $ingoremissing Whether to ignore if the class does not exist.
61+
* @return column_base|null An instance of this class.
6162
*/
62-
public static function from_column_name(view $view, string $columnname): column_base {
63+
public static function from_column_name(view $view, string $columnname, bool $ingoremissing = false): ?column_base {
6364
return new static($view);
6465
}
6566

0 commit comments

Comments
 (0)