MDL-71636 qbank_columnsortorder: Add a columnsortorder settings page

This implementation will introduce a feature "columnsortorder"
which will add the column sort order feature in an external page.
Having this feature will give users the flexibility of sorting plugin
columns in the question bank view.
This commit is contained in:
Marc-Alexandre Ghaly 2021-06-15 09:54:56 -04:00 committed by Tim Hunt
parent 7c016b3451
commit 6dc1084c47
22 changed files with 1059 additions and 15 deletions

View File

@ -27,6 +27,8 @@
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
use qbank_columnsortorder\column_manager;
$action = required_param('action', PARAM_ALPHANUMEXT);
$name = required_param('name', PARAM_PLUGIN);
@ -46,15 +48,21 @@ if (!isset($plugins[$name])) {
throw new moodle_exception('qbanknotfound', 'question', $return, $name);
}
$plugintypename = $plugins[$name]->type . '_' . $plugins[$name]->name;
$columnsortordermanager = new column_manager();
switch ($action) {
case 'disable':
if ($plugins[$name]->is_enabled()) {
$columnsortordermanager->disable_columns($plugintypename);
$class = \core_plugin_manager::resolve_plugininfo_class('qbank');
$class::enable_plugin($name, false);
set_config('disabled', 1, 'qbank_'. $name);
}
break;
case 'enable':
if (!$plugins[$name]->is_enabled()) {
$columnsortordermanager->enable_columns($plugintypename);
$class = \core_plugin_manager::resolve_plugininfo_class('qbank');
$class::enable_plugin($name, true);
}

View File

@ -431,6 +431,7 @@ if ($hassiteconfig || has_capability('moodle/question:config', $systemcontext))
$temp->add(new \core_question\admin\manage_qbank_plugins_page());
$ADMIN->add('qbanksettings', $temp);
$plugins = core_plugin_manager::instance()->get_plugins_of_type('qbank');
foreach ($plugins as $plugin) {
/** @var \core\plugininfo\qbank $plugin */
$plugin->load_settings($ADMIN, 'qbanksettings', $hassiteconfig);

View File

@ -25,6 +25,8 @@
namespace core\plugininfo;
use qbank_columnsortorder\column_manager;
/**
* Base class for qbank plugins.
*
@ -150,8 +152,10 @@ class qbank extends base {
$settings = null;
if (file_exists($this->full_path('settings.php'))) {
$settings = new \admin_settingpage($section, $this->displayname,
'moodle/site:config', $this->is_enabled() === false);
if ($this->name !== 'columnsortorder') {
$settings = new \admin_settingpage($section, $this->displayname,
'moodle/site:config', $this->is_enabled() === false);
}
include($this->full_path('settings.php')); // This may also set $settings to null.
}
if ($settings) {

View File

@ -0,0 +1,10 @@
define("qbank_columnsortorder/sort_columns",["exports","core/ajax","core/notification","core/sortable_list","jquery"],(function(_exports,_ajax,_notification,_sortable_list,_jquery){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* Javascript for sorting columns in question bank view.
*
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_sortable_list=_interopRequireDefault(_sortable_list),_jquery=_interopRequireDefault(_jquery);const setOrder=columns=>(0,_ajax.call)([{methodname:"qbank_columnsortorder_set_columnbank_order",args:{columns:columns}}])[0],getColumnOrder=listRoot=>{const columns=Array.from(listRoot.querySelectorAll("[data-pluginname]")).map((column=>column.dataset.pluginname));return columns.filter(((value,index)=>columns.indexOf(value)===index))};_exports.init=id=>{(listRoot=>{new _sortable_list.default(".list",{moveHandlerSelector:".item"}),(0,_jquery.default)(".item").on(_sortable_list.default.EVENTS.DROP,(()=>{const columns=getColumnOrder(listRoot);setOrder(columns).catch(_notification.exception),listRoot.querySelectorAll(".item").forEach((item=>item.classList.remove("active")))})),(0,_jquery.default)(".item").on(_sortable_list.default.EVENTS.DRAGSTART,(event=>{event.currentTarget.classList.add("active")}))})(document.querySelector("#".concat(id)))}}));
//# sourceMappingURL=sort_columns.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"sort_columns.min.js","sources":["../src/sort_columns.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript for sorting columns in question bank view.\n *\n * @copyright 2021 Catalyst IT Australia Pty Ltd\n * @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {call as fetchMany} from 'core/ajax';\nimport {exception as displayException} from 'core/notification';\nimport SortableList from 'core/sortable_list';\nimport jQuery from 'jquery';\n\n/**\n * Sets up sortable list in the column sort order page.\n * @param {Element} listRoot\n */\nconst setupSortableLists = (listRoot) => {\n new SortableList(\n '.list',\n {\n moveHandlerSelector: '.item',\n }\n );\n\n jQuery('.item').on(SortableList.EVENTS.DROP, () => {\n const columns = getColumnOrder(listRoot);\n setOrder(columns).catch(displayException);\n listRoot.querySelectorAll('.item').forEach(item => item.classList.remove('active'));\n });\n\n jQuery('.item').on(SortableList.EVENTS.DRAGSTART, (event) => {\n event.currentTarget.classList.add('active');\n });\n};\n\n/**\n * Call external function set_order - inserts the updated column in the config_plugins table.\n *\n * @param {String} columns String that contains column order.\n * @returns {Promise}\n */\nconst setOrder = columns => fetchMany([{\n methodname: 'qbank_columnsortorder_set_columnbank_order',\n args: {columns: columns},\n }])[0];\n\n/**\n * Gets the newly reordered columns to display in the question bank view.\n * @param {Element} listRoot\n * @returns {Array}\n */\nconst getColumnOrder = (listRoot) => {\n const columns = Array.from(listRoot.querySelectorAll('[data-pluginname]')).map(column => column.dataset.pluginname);\n\n return columns.filter((value, index) => columns.indexOf(value) === index);\n};\n\n/**\n * Initialize module\n * @param {int} id unique id for columns.\n */\nexport const init = (id) => {\n const listRoot = document.querySelector(`#${id}`);\n setupSortableLists(listRoot);\n};\n"],"names":["setOrder","columns","methodname","args","getColumnOrder","listRoot","Array","from","querySelectorAll","map","column","dataset","pluginname","filter","value","index","indexOf","id","SortableList","moveHandlerSelector","on","EVENTS","DROP","catch","displayException","forEach","item","classList","remove","DRAGSTART","event","currentTarget","add","setupSortableLists","document","querySelector"],"mappings":";;;;;;;sLAyDMA,SAAWC,UAAW,cAAU,CAAC,CAC/BC,WAAY,6CACZC,KAAM,CAACF,QAASA,YAChB,GAOFG,eAAkBC,iBACdJ,QAAUK,MAAMC,KAAKF,SAASG,iBAAiB,sBAAsBC,KAAIC,QAAUA,OAAOC,QAAQC,oBAEjGX,QAAQY,QAAO,CAACC,MAAOC,QAAUd,QAAQe,QAAQF,SAAWC,uBAOlDE,KA7COZ,CAAAA,eACpBa,uBACA,QACA,CACIC,oBAAqB,8BAItB,SAASC,GAAGF,uBAAaG,OAAOC,MAAM,WACnCrB,QAAUG,eAAeC,UAC/BL,SAASC,SAASsB,MAAMC,yBACxBnB,SAASG,iBAAiB,SAASiB,SAAQC,MAAQA,KAAKC,UAAUC,OAAO,mCAGtE,SAASR,GAAGF,uBAAaG,OAAOQ,WAAYC,QAC/CA,MAAMC,cAAcJ,UAAUK,IAAI,cAgCtCC,CADiBC,SAASC,yBAAkBlB"}

View File

@ -0,0 +1,81 @@
// 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/>.
/**
* Javascript for sorting columns in question bank view.
*
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import {call as fetchMany} from 'core/ajax';
import {exception as displayException} from 'core/notification';
import SortableList from 'core/sortable_list';
import jQuery from 'jquery';
/**
* Sets up sortable list in the column sort order page.
* @param {Element} listRoot
*/
const setupSortableLists = (listRoot) => {
new SortableList(
'.list',
{
moveHandlerSelector: '.item',
}
);
jQuery('.item').on(SortableList.EVENTS.DROP, () => {
const columns = getColumnOrder(listRoot);
setOrder(columns).catch(displayException);
listRoot.querySelectorAll('.item').forEach(item => item.classList.remove('active'));
});
jQuery('.item').on(SortableList.EVENTS.DRAGSTART, (event) => {
event.currentTarget.classList.add('active');
});
};
/**
* Call external function set_order - inserts the updated column in the config_plugins table.
*
* @param {String} columns String that contains column order.
* @returns {Promise}
*/
const setOrder = columns => fetchMany([{
methodname: 'qbank_columnsortorder_set_columnbank_order',
args: {columns: columns},
}])[0];
/**
* Gets the newly reordered columns to display in the question bank view.
* @param {Element} listRoot
* @returns {Array}
*/
const getColumnOrder = (listRoot) => {
const columns = Array.from(listRoot.querySelectorAll('[data-pluginname]')).map(column => column.dataset.pluginname);
return columns.filter((value, index) => columns.indexOf(value) === index);
};
/**
* Initialize module
* @param {int} id unique id for columns.
*/
export const init = (id) => {
const listRoot = document.querySelector(`#${id}`);
setupSortableLists(listRoot);
};

View File

@ -0,0 +1,253 @@
<?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/>.
namespace qbank_columnsortorder;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/questionlib.php');
use context_system;
use core_question\local\bank\question_edit_contexts;
use core_question\local\bank\view;
use moodle_url;
/**
* Class column_manager responsible for loading and saving order to the config setting.
*
* @package qbank_columnsortorder
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class column_manager {
/**
* @var array|bool Column order as set in config_plugins 'class' => 'position', ie: question_type_column => 3.
*/
public $columnorder;
/**
* @var array|bool Disabled columns in config_plugins table.
*/
public $disabledcolumns;
/**
* Constructor for column_manager class.
*
*/
public function __construct() {
$this->columnorder = get_config('qbank_columnsortorder', 'enabledcol');
$this->disabledcolumns = get_config('qbank_columnsortorder', 'disabledcol');
if ($this->columnorder) {
$this->columnorder = array_flip(explode(',', $this->columnorder));
}
if ($this->disabledcolumns) {
$this->disabledcolumns = array_flip(explode(',', $this->disabledcolumns));
}
}
/**
* Sets column order in the qbank_columnsortorder plugin config.
*
* @param array $columns Column order to set.
*/
public static function set_column_order(array $columns) : void {
$columns = implode(',', $columns);
set_config('enabledcol', $columns, 'qbank_columnsortorder');
}
/**
* Get qbank.
*
* @return view
*/
protected function get_questionbank(): view {
$course = (object) ['id' => 0];
$context = context_system::instance();
$contexts = new question_edit_contexts($context);
// Dummy call to get the objects without error.
$questionbank = new view($contexts, new moodle_url('/question/dummyurl.php'), $course, null);
return $questionbank;
}
/**
* Get enabled columns.
*
* @return array
*/
public function get_columns(): array {
$columns = [];
foreach ($this->get_questionbank()->get_visiblecolumns() as $key => $column) {
if ($column->get_name() === 'checkbox') {
continue;
}
$classelements = explode('\\', $key);
$columns[] = (object) [
'class' => get_class($column),
'name' => $column->get_title(),
'colname' => end($classelements),
];
}
return $columns;
}
/**
* Get disabled columns.
*
* @return array
*/
public function get_disabled_columns(): array {
$disabled = [];
if ($this->disabledcolumns) {
foreach ($this->disabledcolumns as $class => $value) {
if (strpos($class, 'qbank_customfields\custom_field_column') !== false) {
$class = explode('\\', $class);
$disabledname = array_pop($class);
$class = implode('\\', $class);
$disabled[] = (object) [
'disabledname' => $disabledname,
];
} else {
$columnobject = new $class($this->get_questionbank());
$disabled[] = (object) [
'disabledname' => $columnobject->get_title(),
];
}
}
}
return $disabled;
}
/**
* Updates enabled and disabled config for 'qbank_columnsortorder' plugin.
*
* @param array $enabledcolumns Enabled columns to set.
* @param array $disabledcolumns Disabled columns to set.
*/
protected function update_config($enabledcolumns, $disabledcolumns): void {
if (!empty($enabledcolumns)) {
$configenabled = implode(',', array_flip($enabledcolumns));
set_config('enabledcol', $configenabled, 'qbank_columnsortorder');
}
if (!empty($disabledcolumns)) {
$configdisabled = implode(',', array_flip($disabledcolumns));
set_config('disabledcol', $configdisabled, 'qbank_columnsortorder');
} else {
set_config('disabledcol', null, 'qbank_columnsortorder');
}
}
/**
* Enables columns.
*
* @param string $plugin Plugin type and name ie: qbank_viewcreator.
*/
public function enable_columns(string $plugin): void {
$enabledcolumns = [];
$disabledcolumns = [];
if ($this->columnorder) {
$enabledcolumns = $this->columnorder;
}
if ($this->disabledcolumns) {
$disabledcolumns = $this->disabledcolumns;
foreach ($disabledcolumns as $class => $column) {
if (strpos($class, $plugin) !== false) {
$enabledcolumns[$class] = $class;
if (isset($disabledcolumns[$class])) {
unset($disabledcolumns[$class]);
}
}
}
}
$this->update_config($enabledcolumns, $disabledcolumns);
}
/**
* Disables columns.
*
* @param string $plugin Plugin type and name ie: qbank_viewcreator.
*/
public function disable_columns(string $plugin): void {
$disabledcolumns = [];
$enabledcolumns = [];
$allcolumns = $this->get_columns();
if ($this->disabledcolumns) {
$disabledcolumns = $this->disabledcolumns;
}
if ($this->columnorder) {
$enabledcolumns = $this->columnorder;
}
foreach ($allcolumns as $column) {
if (strpos($column->class, $plugin) !== false) {
if ($column->class === 'qbank_customfields\custom_field_column') {
$disabledcolumns[$column->class . '\\' . $column->colname] = $column->class . '\\' . $column->colname;
if (isset($enabledcolumns[$column->class . '\\' . $column->colname])) {
unset($enabledcolumns[$column->class. '\\' . $column->colname]);
}
} else {
$disabledcolumns[$column->class] = $column->class;
if (isset($enabledcolumns[$column->class])) {
unset($enabledcolumns[$column->class]);
}
}
}
}
$this->update_config($enabledcolumns, $disabledcolumns);
}
/**
* Orders columns in the question bank view according to config_plugins table 'qbank_columnsortorder' config.
*
* @param array $ordertosort Unordered array of columns
* @return array $properorder|$ordertosort Returns array ordered if 'qbank_columnsortorder' config exists.
*/
public function get_sorted_columns($ordertosort): array {
// Check if db has order set.
if (!empty($this->columnorder)) {
// Merge new order with old one.
$columnsortorder = $this->columnorder;
asort($columnsortorder);
$columnorder = [];
foreach ($columnsortorder as $classname => $colposition) {
$colname = explode('\\', $classname);
if (strpos($classname, 'qbank_customfields\custom_field_column') !== false) {
unset($colname[0]);
$classname = implode('\\', $colname);
// Checks if custom column still exists.
if (array_key_exists($classname, $ordertosort)) {
$columnorder[$classname] = $colposition;
} else {
$configtounset = str_replace('\\', '\\\\', $classname);
// Cleans config db.
unset_config($configtounset, 'column_sortorder');
}
} else {
$columnorder[end($colname)] = $colposition;
}
}
$properorder = array_merge($columnorder, $ordertosort);
// Always have the checkbox at first column position.
if (isset($properorder['checkbox_column'])) {
$checkboxfirstelement = $properorder['checkbox_column'];
unset($properorder['checkbox_column']);
$properorder = array_merge(['checkbox_column' => $checkboxfirstelement], $properorder);
}
return $properorder;
}
return $ordertosort;
}
}

View File

@ -0,0 +1,71 @@
<?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/>.
namespace qbank_columnsortorder\external;
use context_system;
use Exception;
use external_api;
use external_function_parameters;
use external_multiple_structure;
use external_value;
use qbank_columnsortorder\column_manager;
use stdClass;
/**
* External qbank_columnsortorder_set_columnbank_order API
*
* @package qbank_columnsortorder
* @category external
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author 2021, Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class set_columnbank_order extends external_api {
/**
* Returns description of method parameters.
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'columns' => new external_multiple_structure(
new external_value(PARAM_TEXT, 'Plugin name for the column', VALUE_REQUIRED)
)
]);
}
/**
* Returns description of method result value.
*
*/
public static function execute_returns(): void {
}
/**
* Returns the columns plugin order.
*
* @param array $columns json string representing new column order.
*/
public static function execute(array $columns): void {
['columns' => $columns] = self::validate_parameters(self::execute_parameters(), ['columns' => $columns]);
$context = context_system::instance();
self::validate_context($context);
require_capability('moodle/category:manage', $context);
column_manager::set_column_order($columns);
}
}

View File

@ -0,0 +1,58 @@
<?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/>.
namespace qbank_columnsortorder\output;
use qbank_columnsortorder\column_manager;
use html_writer;
use moodle_url;
use plugin_renderer_base;
/**
* Class renderer.
* @package qbank_columnsortorder
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends plugin_renderer_base {
/**
* Render list of question bank plugin columns.
*
* @return string The rendered HTML.
*/
public function render_column_sort_ui() {
$columnsortorder = new column_manager();
$enabledcolumns = $columnsortorder->get_columns();
$disabledcolumns = $columnsortorder->get_disabled_columns();
$params = [];
foreach ($enabledcolumns as $columnname) {
$name = $columnname->name;
$colname = get_string('qbankcolumnname', 'qbank_columnsortorder', $columnname->colname);
if ($columnname->class === 'qbank_customfields\custom_field_column') {
$columnname->class .= "\\$columnname->colname";
}
$params['names'][] = ['name' => $name, 'colname' => $colname, 'class' => $columnname->class];
}
$params['disabled'] = $disabledcolumns;
$params['columnsdisabled'] = (!empty($params['disabled'])) ? true : false;
$urltoredirect = new moodle_url('/admin/settings.php', ['section' => 'manageqbanks']);
$params['urltomanageqbanks'] = get_string('qbankgotomanageqbanks', 'qbank_columnsortorder', $urltoredirect->out());
return $this->render_from_template('qbank_columnsortorder/columnsortorder', $params);
}
}

View File

@ -0,0 +1,39 @@
<?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/>.
namespace qbank_columnsortorder\privacy;
use \core_privacy\local\metadata\null_provider;
/**
* Privacy provider for columnsortorder.
*
* @package qbank_columnsortorder
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View File

@ -0,0 +1,36 @@
<?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/>.
/**
* qbank_columnsortorder external functions and service definitions.
* @package qbank_columnsortorder
* @category webservice
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author 2021, Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$functions = [
'qbank_columnsortorder_set_columnbank_order' => [
'classname' => 'qbank_columnsortorder\external\set_columnbank_order',
'description' => 'Sets question columns order in database',
'type' => 'write',
'ajax' => true,
],
];

View File

@ -0,0 +1,33 @@
<?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/>.
/**
* Strings for component qbank_columnsortorder, language 'en'.
*
* @package qbank_columnsortorder
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Column sort order';
$string['privacy:metadata'] = 'Column sort order does not store any personal data.';
$string['qbankcolumnsortorder'] = 'Column sort order';
$string['qbankgotocolumnsort'] = 'You can reorder column order in the question bank view on the {$a} page';
$string['qbankcolumnsdisabled'] = 'Columns below are currently disabled.';
$string['qbankgotomanageqbanks'] = 'Enable and disable column plugins via <a href=\'{$a}\'>Manage question bank plugins</a>';
$string['qbankcolumnname'] = '({$a})';
$string['qbanksortdescription'] = 'Column order modification in this page will reorder column display in question bank view';

View File

@ -0,0 +1,44 @@
<?php
// This file is part of Moodle - https://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/>.
/**
* Adds admin settings for the plugin.
*
* @package qbank_columnsortorder
* @category admin
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
// Column sort order link in manageqbanks page.
$url = new moodle_url('/question/bank/columnsortorder/sortcolumns.php', ['section' => 'columnsortorder']);
if ($ADMIN->fulltree) {
$page = $adminroot->locate('manageqbanks');
if (isset($page)) {
$page->add(new admin_setting_description(
'manageqbanksgotocolumnsort',
'',
new lang_string('qbankgotocolumnsort', 'qbank_columnsortorder',
html_writer::link($url, get_string('qbankcolumnsortorder', 'qbank_columnsortorder')))
));
}
}
// Column sort order link in admin page.
$settings = new admin_externalpage('qbank_columnsortorder', get_string('qbankcolumnsortorder', 'qbank_columnsortorder'), $url);

View File

@ -0,0 +1,37 @@
<?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/>.
/**
* Question bank settings page class.
*
* @package qbank_columnsortorder
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('qbank_columnsortorder', '', ['section' => 'columnsortorder'],
'/question/bank/columnsortorder/sortcolumns.php');
$renderer = $PAGE->get_renderer('qbank_columnsortorder');
echo $OUTPUT->header();
echo $OUTPUT->heading(new lang_string('qbankcolumnsortorder', 'qbank_columnsortorder'));
echo $renderer->render_column_sort_ui();
echo $OUTPUT->footer();

View File

@ -0,0 +1,65 @@
{{!
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/>.
}}
{{!
@template qbank_columnsortorder/columnsortorder.mustache
Admin question bank setting template.
Context variables required for this template:
* name - plugin name
* hiddenname - class/columname
Example context (json):
{
"name": "Creatorname (creator_name_column)",
"hiddenname": "creator_name_column"
}
}}
<div>
{{#str}}qbanksortdescription, qbank_columnsortorder{{/str}}
</div>
<br>
<div class="list list-group" id="qbank_columnsortorder-{{uniqid}}">
{{#names}}
<div class="column item list-group-item list-group-item-action" data-pluginname={{class}}>
{{>core/drag_handle}}
{{name}} {{colname}}
</div>
{{/names}}
</div>
<br>
<div>
{{#columnsdisabled}}
{{#str}}qbankcolumnsdisabled, qbank_columnsortorder{{/str}}
<br>
{{/columnsdisabled}}
{{#disabled}}
<div class="list-group-item disabled">
{{disabledname}}
</div>
{{/disabled}}
</div>
{{#js}}
require(['qbank_columnsortorder/sort_columns'], function(SortColumns) {
SortColumns.init("qbank_columnsortorder-{{uniqid}}");
});
{{/js}}
<br>
<div>
{{{urltomanageqbanks}}}
</div>

View File

@ -0,0 +1,88 @@
@core @qbank_columnsortorder @javascript
Feature: An plugin column can be reordered and displayed in the question bank view.
In order to reorganise the question bank view columns
As an admin
I need to be able to reorder them
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | weeks |
And the following "activity" exists:
| activity | quiz |
| course | C1 |
| name | Test quiz Q001 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "question category" exist:
| contextlevel | reference | name |
| Activity module | Test quiz Q001 | Question category 1 |
And the following "questions" exist:
| questioncategory | qtype | name | user | questiontext | idnumber |
| Question category 1 | essay | Test question to be seen | teacher1 | Write about whatever you want | idnumber1 |
@javascript
Scenario: Teacher can see proper view
Given I am on the "Test quiz Q001" "quiz activity" page logged in as "teacher1"
When I navigate to "Question bank > Questions" in current page administration
And I click on "category" "select"
And I click on "Question category 1" "option"
And I should see "Test question to be seen"
Then I should see "Teacher 1"
@javascript
Scenario: Reordering question bank columns
Given I log in as "admin"
When I navigate to "Plugins > Question bank plugins > Column sort order" in site administration
And I drag "Created by (creator_name_column)" "text" and I drop it in "T (question_type_column)" "text"
And I am on the "Test quiz Q001" "quiz activity" page logged in as "teacher1"
And I navigate to "Question bank > Questions" in current page administration
And I click on "category" "select"
And I click on "Question category 1" "option"
Then ".creatorname" "css_element" should appear before ".qtype" "css_element"
@javascript
Scenario: Disabling and enabling column display is proper
Given I log in as "admin"
When I navigate to "Plugins > Question bank plugins > Column sort order" in site administration
And I should see "Created by (creator_name_column)"
And I click on "Manage question bank plugins" "link"
And I click on "Disable" "link" in the "View creator" "table_row"
And I click on "Column sort order" "link"
Then "Columns below are currently disabled." "text" should appear before "Created by" "text"
And I should not see "Created by (creator_name_column)"
And I click on "Manage question bank plugins" "link"
And I click on "Enable" "link" in the "View creator" "table_row"
And I click on "Column sort order" "link"
Then I should not see "Columns below are currently disabled."
And I should see "Created by (creator_name_column)"
@javascript
Scenario: Custom fields are reorderable
Given I log in as "admin"
When I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
And I press "Add a new category"
And I click on "Add a new custom field" "link"
And I follow "Checkbox"
And I set the following fields to these values:
| Name | checkboxcustomcolumn |
| Short name | chckcust |
And I press "Save changes"
Then I should see "checkboxcustomcolumn"
And I navigate to "Plugins > Question bank plugins > Column sort order" in site administration
And I should see "checkboxcustomcolumn"
And I drag "checkboxcustomcolumn" "text" and I drop it in "T (question_type_column)" "text"
Then "checkboxcustomcolumn" "text" should appear before "T (question_type_column)" "text"
And I click on "Manage question bank plugins" "link"
And I click on "Disable" "link" in the "Question custom fields" "table_row"
And I click on "Column sort order" "link"
Then "Columns below are currently disabled." "text" should appear before "chckcust" "text"
And I click on "Manage question bank plugins" "link"
And I click on "Enable" "link" in the "Question custom fields" "table_row"
And I click on "Column sort order" "link"
Then I should not see "Columns below are currently disabled."
And I should see "checkboxcustomcolumn"

View File

@ -0,0 +1,121 @@
<?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/>.
namespace qbank_columnsortorder;
defined('MOODLE_INTERNAL') || die();
use advanced_testcase;
use context_course;
use core_question\local\bank\question_edit_contexts;
use core_question\local\bank\view;
use moodle_url;
use qbank_columnsortorder\external\set_columnbank_order;
global $CFG;
require_once($CFG->dirroot . '/question/tests/fixtures/testable_core_question_column.php');
require_once($CFG->dirroot . '/question/classes/external.php');
/**
* Test class for columnsortorder feature.
*
* @package qbank_columnsortorder
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @coversDefaultClass \qbank_columnsortorder\column_manager
*/
class column_manager_test extends advanced_testcase {
/**
* Setup testcase.
*/
public function setUp(): void {
$this->resetAfterTest(true);
$this->setAdminUser();
$this->course = $this->getDataGenerator()->create_course();
// Creates question bank view.
$this->questionbank = new view(
new question_edit_contexts(context_course::instance($this->course->id)),
new moodle_url('/'),
$this->course
);
// Get current view columns.
$this->columns = [];
foreach ($this->questionbank->get_visiblecolumns() as $columnn) {
$this->columns[] = get_class($columnn);
}
$this->columnmanager = new column_manager();
}
/**
* Test function get_columns in helper class, that proper data is returned.
*
* @covers ::get_columns
*/
public function test_getcolumns_function(): void {
$questionlistcolumns = $this->columnmanager->get_columns();
$this->assertIsArray($questionlistcolumns);
foreach ($questionlistcolumns as $columnnobject) {
$this->assertObjectHasAttribute('class', $columnnobject);
$this->assertObjectHasAttribute('name', $columnnobject);
$this->assertObjectHasAttribute('colname', $columnnobject);
}
}
/**
* Test function sort columns method.
*
* @covers ::get_sorted_columns
*/
public function test_get_sorted_columns(): void {
$neworder = $this->columnmanager->get_sorted_columns($this->columns);
shuffle($neworder);
set_columnbank_order::execute($neworder);
$currentconfig = get_config('qbank_columnsortorder', 'enabledcol');
$currentconfig = explode(',', $currentconfig);
ksort($currentconfig);
$this->assertSame($neworder, $currentconfig);
}
/**
* Test function enabing and disablingcolumns.
*
* @covers ::enable_columns
* @covers ::disable_columns
*/
public function test_enable_disable_columns(): void {
$neworder = $this->columnmanager->get_sorted_columns($this->columns);
shuffle($neworder);
set_columnbank_order::execute($neworder);
$currentconfig = get_config('qbank_columnsortorder', 'enabledcol');
$currentconfig = explode(',', $currentconfig);
$class = $currentconfig[array_rand($currentconfig, 1)];
$randomplugintodisable = explode('\\', $class)[0];
$olddisabledconfig = get_config('qbank_columnsortorder', 'disabledcol');
$this->columnmanager->disable_columns($randomplugintodisable);
$newdisabledconfig = get_config('qbank_columnsortorder', 'disabledcol');
$this->assertNotEquals($olddisabledconfig, $newdisabledconfig);
$this->columnmanager->enable_columns($randomplugintodisable);
$newdisabledconfig = get_config('qbank_columnsortorder', 'disabledcol');
$this->assertEmpty($newdisabledconfig);
$enabledconfig = get_config('qbank_columnsortorder', 'enabledcol');
$contains = strpos($enabledconfig, $randomplugintodisable);
$this->assertNotFalse($contains);
$this->assertIsInt($contains);
}
}

View File

@ -0,0 +1,63 @@
<?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/>.
namespace qbank_columnsortorder;
use advanced_testcase;
use qbank_columnsortorder\column_manager;
use qbank_columnsortorder\external\set_columnbank_order;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/question/classes/external.php');
/**
* Unit tests for qbank_columnsortorder external API.
*
* @package qbank_columnsortorder
* @author 2021, Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class columnsortorder_external_test extends advanced_testcase {
/**
* Test that external call core_question_external::set_columnbank_order($oldorder) sets proper
* data in config_plugins table.
*/
public function test_columnorder_external(): void {
$this->resetAfterTest(true);
$this->setAdminUser();
$columnsortorder = new column_manager();
$questionlistcolumns = $columnsortorder->get_columns();
$columnclasses = [];
foreach ($questionlistcolumns as $columnnobject) {
$columnclasses[] = $columnnobject->class;
}
shuffle($columnclasses);
$columnclasses = implode(',', $columnclasses);
set_columnbank_order::execute($columnclasses);
$currentconfig = (array)get_config('qbank_columnsortorder');
unset($currentconfig['version']);
asort($currentconfig);
$currentconfig = array_flip($currentconfig);
$columnclasses = explode(',', $columnclasses);
$this->assertSame($columnclasses, $currentconfig);
}
}

View File

@ -0,0 +1,31 @@
<?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/>.
/**
* Version information for qbank_columnsortorder.
*
* @package qbank_columnsortorder
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'qbank_columnsortorder';
$plugin->version = 2021100100;
$plugin->requires = 2021052500;
$plugin->maturity = MATURITY_STABLE;

View File

@ -51,5 +51,4 @@ class helper {
throw new \moodle_exception('The following plugin is either disabled or missing from disk: ' . $pluginname);
}
}
}

View File

@ -24,7 +24,12 @@
namespace core_question\local\bank;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/question/editlib.php');
use core_plugin_manager;
use core_question\bank\search\condition;
use qbank_columnsortorder\column_manager;
use qbank_editquestion\editquestion_helper;
use qbank_managecategories\helper;
@ -298,9 +303,15 @@ class view {
$questionbankclasscolumns[$key] = $newpluginclasscolumn;
}
// Check if qbank_columnsortorder is enabled.
if (array_key_exists('columnsortorder', core_plugin_manager::instance()->get_enabled_plugins('qbank'))) {
$columnorder = new column_manager();
$questionbankclasscolumns = $columnorder->get_sorted_columns($questionbankclasscolumns);
}
// Mitigate the error in case of any regression.
foreach ($questionbankclasscolumns as $shortname => $questionbankclasscolumn) {
if (empty($questionbankclasscolumn)){
if (empty($questionbankclasscolumn)) {
unset($questionbankclasscolumns[$shortname]);
}
}
@ -1227,18 +1238,9 @@ class view {
/**
* Gets visible columns.
* @return array $this->visiblecolumns Visible columns.
* @return array Visible columns.
*/
public function get_visiblecolumns(): array {
return $this->visiblecolumns;
}
/**
* Get required columns.
*
* @return array Required columns.
*/
public function get_requiredcolumns(): array {
return $this->requiredcolumns;
}
}

View File

@ -23,7 +23,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once($CFG->dirroot . '/question/editlib.php');