MDL-69863 tool_brickfield: Adding the Brickfield toolkit.

This commit is contained in:
Mike Churchward 2021-04-23 16:40:34 -04:00 committed by Eloy Lafuente (stronk7)
parent 49c74619f7
commit 43d29ccbed
279 changed files with 24982 additions and 0 deletions

2
blocks/accessreview/amd/build/module.min.js vendored Executable file
View file

@ -0,0 +1,2 @@
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("block_accessreview/module",["exports","core/ajax","core/templates","core/notification"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;c=f(c);function e(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;e=function(){return a};return a}function f(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=e();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var f in a){if(Object.prototype.hasOwnProperty.call(a,f)){var g=d?Object.getOwnPropertyDescriptor(a,f):null;if(g&&(g.get||g.set)){Object.defineProperty(c,f,g)}else{c[f]=a[f]}}}c.default=a;if(b){b.set(a,c)}return c}function g(a,b){return m(a)||l(a,b)||j(a,b)||h()}function h(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function j(a,b){if(!a)return;if("string"==typeof a)return k(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return k(a,b)}function k(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);c<b;c++){d[c]=a[c]}return d}function l(a,b){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(a)))return;var c=[],d=!0,e=!1,f=void 0;try{for(var g=a[Symbol.iterator](),h;!(d=(h=g.next()).done);d=!0){c.push(h.value);if(b&&c.length===b)break}}catch(a){e=!0;f=a}finally{try{if(!d&&null!=g["return"])g["return"]()}finally{if(e)throw f}}return c}function m(a){if(Array.isArray(a))return a}var n=!0,o=function(a,b,d,e,f,g){var h=parseInt((b-f)/g*2),i={resultPassed:!b,classList:"",passRate:{errorCount:b,checkCount:d,failureRate:Math.round(100*(b/d))}};if(!a){return Promise.resolve()}var j=["block_accessreview"];if(i.resultPassed){j.push("block_accessreview_success")}else if(h){j.push("block_accessreview_danger")}else{j.push("block_accessreview_warning")}var k="showicons"==e||"showboth"==e,l="showbackground"==e||"showboth"==e;if(l&&!k){var m;(m=a.classList).add.apply(m,j.concat(["alert"]));return Promise.resolve()}if(k&&!l){i.classList=j.join(" ")}return c.renderForPromise("block_accessreview/status",i).then(function(b){var d=b.html,e=b.js;c.appendNodeContents(a,d,e);if(l){var f;(f=a.classList).add.apply(f,j.concat(["alert"]))}}).catch()},p=function(a,b){var c=2<arguments.length&&arguments[2]!==void 0?arguments[2]:!1;return Promise.all(w(a,c)).then(function(a){var c=g(a,2),d=c[0],e=c[1],f=s(d,e),h=f.minViews,i=f.viewDelta;d.forEach(function(a){var c=document.querySelector("#section-".concat(a.section," .summary"));if(!c){return}o(c,a.numerrors,a.numchecks,b,h,i)});e.forEach(function(a){var c=document.getElementById("module-".concat(a.cmid));if(!c){return}o(c,a.numerrors,a.numchecks,b,h,i)});return{sectionData:d,moduleData:e}}).catch(d.exception)},q=function(){var a=0<arguments.length&&arguments[0]!==void 0?arguments[0]:!1;document.querySelectorAll(".block_accessreview_view").forEach(function(a){return a.remove()});var b=["block_accessreview","block_accessreview_success","block_accessreview_warning","block_accessreview_danger","block_accessreview_view"];document.querySelectorAll(".block_accessreview").forEach(function(a){var c;return(c=a.classList).remove.apply(c,b)});if(a){v(!1)}},r=function(a,b){n=!n;if(!n){q(!0)}else{p(a,b,!0)}},s=function(a,b){var c={totalErrors:0,totalUsers:0,minViews:0,maxViews:0,viewDelta:0};[].concat(a,b).forEach(function(a){c.totalErrors+=a.numerrors;if(a.numerrors<c.minViews){c.minViews=a.numerrors}if(a.numerrors>c.maxViews){c.maxViews=a.numerrors}c.totalUsers+=a.numchecks});c.viewDelta=c.maxViews-c.minViews+1;return c},t=function(a,b){document.addEventListener("click",function(c){if(c.target.closest("#toggle-accessmap")){c.preventDefault();r(a,b)}})},u=function(a){return{methodname:"core_user_update_user_preferences",args:{preferences:[{type:"block_accessreviewtogglestate",value:a}]}}},v=function(a){return(0,b.call)([u(a)])},w=function(a){var c=1<arguments.length&&arguments[1]!==void 0?arguments[1]:!1,d=[{methodname:"block_accessreview_get_section_data",args:{courseid:a}},{methodname:"block_accessreview_get_module_data",args:{courseid:a}}];if(c){d.push(u(!0))}return(0,b.call)(d)},x=function(a,b,c){n=1==a;if(n){p(c,b)}t(c,b)};a.init=x});
//# sourceMappingURL=module.min.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,294 @@
// 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/>.
/**
*
* @package block_accessreview
* @author Max Larkin <max@brickfieldlabs.ie>
* @copyright 2020 Brickfield Education Labs <max@brickfieldlabs.ie>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import {call as fetchMany} from 'core/ajax';
import * as Templates from 'core/templates';
import {exception as displayError} from 'core/notification';
/**
* The number of colours used to represent the heatmap. (Indexed on 0.)
* @type {number}
*/
const numColours = 2;
/**
* The toggle state of the heatmap.
* @type {boolean}
*/
let toggleState = true;
/**
* Renders the HTML template onto a particular HTML element.
* @param {HTMLElement} element The element to attach the HTML to.
* @param {number} errorCount The number of errors on this module/section.
* @param {number} checkCount The number of checks triggered on this module/section.
* @param {String} displayFormat
* @param {Number} minViews
* @param {Number} viewDelta
* @returns {Promise}
*/
const renderTemplate = (element, errorCount, checkCount, displayFormat, minViews, viewDelta) => {
// Calculate a weight?
const weight = parseInt((errorCount - minViews) / viewDelta * numColours);
const context = {
resultPassed: !errorCount,
classList: '',
passRate: {
errorCount,
checkCount,
failureRate: Math.round(errorCount / checkCount * 100),
},
};
if (!element) {
return Promise.resolve();
}
const elementClassList = ['block_accessreview'];
if (context.resultPassed) {
elementClassList.push('block_accessreview_success');
} else if (weight) {
elementClassList.push('block_accessreview_danger');
} else {
elementClassList.push('block_accessreview_warning');
}
const showIcons = (displayFormat == 'showicons') || (displayFormat == 'showboth');
const showBackground = (displayFormat == 'showbackground') || (displayFormat == 'showboth');
if (showBackground && !showIcons) {
// Only the background is displayed.
// No need to display the template.
// Note: The case where both the background and icons are shown is handled later to avoid jankiness.
element.classList.add(...elementClassList, 'alert');
return Promise.resolve();
}
if (showIcons && !showBackground) {
context.classList = elementClassList.join(' ');
}
// The icons are displayed either with, or without, the background.
return Templates.renderForPromise('block_accessreview/status', context)
.then(({html, js}) => {
Templates.appendNodeContents(element, html, js);
if (showBackground) {
element.classList.add(...elementClassList, 'alert');
}
return;
})
.catch();
};
/**
* Applies the template to all sections and modules on the course page.
*
* @param {Number} courseId
* @param {String} displayFormat
* @param {Boolean} updatePreference
* @returns {Promise}
*/
const showAccessMap = (courseId, displayFormat, updatePreference = false) => {
// Get error data.
return Promise.all(fetchReviewData(courseId, updatePreference))
.then(([sectionData, moduleData]) => {
// Get total data.
const {minViews, viewDelta} = getErrorTotals(sectionData, moduleData);
sectionData.forEach(section => {
const element = document.querySelector(`#section-${section.section} .summary`);
if (!element) {
return;
}
renderTemplate(element, section.numerrors, section.numchecks, displayFormat, minViews, viewDelta);
});
moduleData.forEach(module => {
const element = document.getElementById(`module-${module.cmid}`);
if (!element) {
return;
}
renderTemplate(element, module.numerrors, module.numchecks, displayFormat, minViews, viewDelta);
});
return {
sectionData,
moduleData,
};
})
.catch(displayError);
};
/**
* Hides or removes the templates from the HTML of the current page.
*
* @param {Boolean} updatePreference
*/
const hideAccessMap = (updatePreference = false) => {
// Removes the added elements.
document.querySelectorAll('.block_accessreview_view').forEach(node => node.remove());
const classList = [
'block_accessreview',
'block_accessreview_success',
'block_accessreview_warning',
'block_accessreview_danger',
'block_accessreview_view',
];
// Removes the added classes.
document.querySelectorAll('.block_accessreview').forEach(node => node.classList.remove(...classList));
if (updatePreference) {
setToggleStatePreference(false);
}
};
/**
* Toggles the heatmap on/off.
*
* @param {Number} courseId
* @param {String} displayFormat
*/
const toggleAccessMap = (courseId, displayFormat) => {
toggleState = !toggleState;
if (!toggleState) {
hideAccessMap(true);
} else {
showAccessMap(courseId, displayFormat, true);
}
};
/**
* Parses information on the errors, generating the min, max and totals.
*
* @param {Object[]} sectionData The error data for course sections.
* @param {Object[]} moduleData The error data for course modules.
* @returns {Object} An object representing the extra error information.
*/
const getErrorTotals = (sectionData, moduleData) => {
const totals = {
totalErrors: 0,
totalUsers: 0,
minViews: 0,
maxViews: 0,
viewDelta: 0,
};
[].concat(sectionData, moduleData).forEach(item => {
totals.totalErrors += item.numerrors;
if (item.numerrors < totals.minViews) {
totals.minViews = item.numerrors;
}
if (item.numerrors > totals.maxViews) {
totals.maxViews = item.numerrors;
}
totals.totalUsers += item.numchecks;
});
totals.viewDelta = totals.maxViews - totals.minViews + 1;
return totals;
};
const registerEventListeners = (courseId, displayFormat) => {
document.addEventListener('click', e => {
if (e.target.closest('#toggle-accessmap')) {
e.preventDefault();
toggleAccessMap(courseId, displayFormat);
}
});
};
/**
* Set the user preference for the toggle value.
*
* @param {Boolean} toggleState
* @returns {Promise}
*/
const getTogglePreferenceParams = toggleState => {
return {
methodname: 'core_user_update_user_preferences',
args: {
preferences: [{
type: 'block_accessreviewtogglestate',
value: toggleState,
}],
}
};
};
const setToggleStatePreference = toggleState => fetchMany([getTogglePreferenceParams(toggleState)]);
/**
* Fetch the review data.
*
* @param {Number} courseid
* @param {Boolean} updatePreference
* @returns {Promise[]}
*/
const fetchReviewData = (courseid, updatePreference = false) => {
const calls = [
{
methodname: 'block_accessreview_get_section_data',
args: {courseid}
},
{
methodname: 'block_accessreview_get_module_data',
args: {courseid}
},
];
if (updatePreference) {
calls.push(getTogglePreferenceParams(true));
}
return fetchMany(calls);
};
/**
* Setting up the access review module.
* @param {number} toggled A number represnting the state of the review toggle.
* @param {string} displayFormat A string representing the display format for icons.
* @param {number} courseId The course ID.
* @param {number} userId The id of the currently logged-in user.
*/
export const init = (toggled, displayFormat, courseId) => {
// Settings consts.
toggleState = toggled == 1;
if (toggleState) {
showAccessMap(courseId, displayFormat);
}
registerEventListeners(courseId, displayFormat);
};

View file

@ -0,0 +1,309 @@
<?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/>.
use tool_brickfield\accessibility;
use tool_brickfield\analysis;
use tool_brickfield\area_base;
use tool_brickfield\local\tool\filter;
use tool_brickfield\manager;
use tool_brickfield\registration;
use tool_brickfield\scheduler;
use tool_brickfield\sitedata;
/**
* Definition of the accessreview block.
*
* @package block_accessreview
* @copyright 2019 Karen Holland LTS.ie
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_accessreview extends block_base {
/**
* Sets the block title.
*/
public function init(): void {
$this->title = get_string('errorssummary', 'block_accessreview');
}
/**
* Defines where the block can be added.
*
* @return array
*/
public function applicable_formats(): array {
// If Brickfield accessibility toolkit has been disabled, do nothing.
if (accessibility::is_accessibility_enabled()) {
return [
'course-view' => true,
'site' => true,
'mod' => false,
'my' => false,
];
} else {
return [];
}
}
/**
* Controls global configurability of block.
*
* @return bool
*/
public function has_config(): bool {
return true;
}
/**
* Controls whether multiple block instances are allowed.
*
* @return bool
*/
public function instance_allow_multiple(): bool {
return false;
}
/**
* Creates the block's main content
*
* @return string|stdClass
*/
public function get_content() {
global $COURSE, $OUTPUT;
// If Brickfield accessibility toolkit has been disabled, do nothing.
if (!accessibility::is_accessibility_enabled()) {
return '';
}
if (isset($this->content)) {
return $this->content;
}
$this->content = new stdClass;
$this->content->text = '';
// Check to see user can view/use the accessmap.
$context = context_course::instance($COURSE->id);
if (!isloggedin() || isguestuser() || !has_capability('block/accessreview:view', $context)) {
return $this->content;
}
// Check for valid registration.
if (!(new registration())->toolkit_is_active()) {
$this->content->text = manager::registration_message();
} else if (scheduler::is_course_analyzed($COURSE->id)) {
// Build error data table.
$table = new html_table();
$table->head = [
get_string('checktypes', 'block_accessreview'), get_string('errors', 'block_accessreview')
];
$table->align = ['left', 'center'];
$tabledata = $this->get_table_data($COURSE->id);
// Handling no data.
if ($tabledata === null) {
$this->content->text = get_string('nodata', 'block_accessreview');
return $this->content;
}
$table->data = $tabledata;
$table->attributes['class'] = 'generaltable table-sm block_accessreview_table';
$this->content->text .= html_writer::table($table, true);
// Check for compatible course formats for highlighting.
$showhighlighting = false;
switch ($COURSE->format) {
case accessibility::TOOL_BRICKFIELD_FORMAT_TOPIC:
case accessibility::TOOL_BRICKFIELD_FORMAT_WEEKLY:
$showhighlighting = true;
break;
}
// Toggle overlay link.
$toggle = ($showhighlighting) ? $this->get_toggle_link() : '';
// Report download link.
$download = $this->get_download_link($context);
// Report view link.
$view = $this->get_report_link($context);
$this->content->text .= html_writer::tag('div', $toggle . $view . $download, [
'class' => 'block_accessreview_links'
]
);
if ($showhighlighting) {
// Setting up AMD module.
$whattoshow = get_config('block_accessreview', 'whattoshow');
$toggled = get_user_preferences('block_accessreviewtogglestate', true);
$arguments = [$toggled, $whattoshow, $COURSE->id];
$this->page->requires->js_call_amd('block_accessreview/module', 'init', $arguments);
}
} else if (scheduler::is_course_in_schedule($COURSE->id)) {
// Display a message that the course is awaiting analysis.
$this->content->text = get_string('schedule:scheduled', manager::PLUGINNAME);
} else if (!analysis::is_enabled()) {
$this->content->text = get_string('analysistypedisabled', manager::PLUGINNAME);
} else {
// Display a button to request analysis.
$this->content->text = get_string('schedule:blocknotscheduled', manager::PLUGINNAME, manager::get_helpurl());
$button = new single_button(
new moodle_url(accessibility::get_plugin_url(), ['action' => 'requestanalysis', 'courseid' => $COURSE->id]),
get_string('schedule:requestanalysis', manager::PLUGINNAME), 'post', true,
['class' => 'block_accessreview_analysisbutton']);
$this->content->text .= html_writer::tag('div', $OUTPUT->render($button),
['class' => 'block_accessreview_analysisbutton']);
}
return $this->content;
}
/**
* Fetches and groups the relevent error data for the table to display.
* @param int $courseid The ID of the course.
* @return array The data required by the table.
* @throws coding_exception
* @throws moodle_exception
*/
protected function get_table_data($courseid): array {
global $OUTPUT;
$datafilters = new filter($courseid, 0);
$errordisplay = get_config('block_accessreview', 'errordisplay');
$summarydata = (new sitedata())->get_checkgroup_data($datafilters);
$data = [];
$count = 0;
for ($i = 1; $count < $summarydata[0]->groupcount; $i++) {
if (isset($summarydata[0]->{'componentlabel' . $i})) {
$data[$i] = $summarydata[0]->{'errorsvalue' . $i};
$count++;
}
}
$files = [
'form' => '',
'image' => '231/',
'layout' => '234/',
'link' => '237/',
'media' => '240/',
'table' => '243/',
'text' => '246/',
];
// Populating table data.
$tabledata = [];
foreach ($data as $key => $total) {
// If the total is empty it means there is no results yet in the table.
if ($total === null) {
continue;
}
$type = area_base::checkgroup_name($key);
// Error display data.
$display = $total;
// Icons.
$typeicon = $OUTPUT->pix_icon('f/' . $type, '', 'block_accessreview');
if ($errordisplay == 'showicon') {
$thistype = $total == 0 ? 'smile' : 'frown';
$display = $OUTPUT->pix_icon($thistype,
get_string($thistype, 'block_accessreview'), 'block_accessreview'
);
} else if ($errordisplay == 'showpercent') {
$display = round(($total), 1) . '%';
}
$tabledata[] = [$typeicon . get_string('checktype:' . $type, manager::PLUGINNAME), $display];
}
return $tabledata;
}
/**
* Get the link to toggle the heatmap.
*
* @return string
* @throws coding_exception
*/
protected function get_toggle_link(): string {
global $OUTPUT;
// Toggle overlay link.
return html_writer::link(
'#',
$OUTPUT->pix_icon('t/hide', get_string('togglealt', 'block_accessreview')),
[
'title' => get_string('togglealt', 'block_accessreview'),
'style' => 'cursor: pointer;',
'id' => 'toggle-accessmap',
'class' => 'block_accessreview_link',
]
);
}
/**
* Get the link to download a report for the specified context.
*
* @param context $context
* @return string
* @throws coding_exception
* @throws moodle_exception
*/
protected function get_download_link(context $context): string {
global $OUTPUT, $COURSE;
if (has_capability(accessibility::get_capability_name('viewcoursetools'), $context)) {
return html_writer::link(
new moodle_url(accessibility::get_plugin_url(),
[
'courseid' => $COURSE->id,
'tab' => 'printable',
'target' => 'pdf',
]
),
$OUTPUT->pix_icon('a/download_all', get_string('downloadreportalt', 'block_accessreview')),
[
'title' => get_string('downloadreportalt', 'block_accessreview'),
'class' => 'block_accessreview_link download-accessmap',
]
);
} else {
return '';
}
}
/**
* Get the report link for the specified context.
*
* @param context $context
* @return string
* @throws coding_exception
* @throws dml_exception
* @throws moodle_exception
*/
protected function get_report_link(context $context): string {
global $OUTPUT, $COURSE;
if (has_capability(accessibility::get_capability_name('viewcoursetools'), $context)) {
return html_writer::link(
new moodle_url(accessibility::get_plugin_url(),
[
'courseid' => $COURSE->id,
'tab' => get_config('block_accessreview', 'toolpage'),
]
),
$OUTPUT->pix_icon('f/find', get_string('viewreportalt', 'block_accessreview'), 'block_accessreview'),
[
'title' => get_string('viewreportalt', 'block_accessreview'),
'class' => 'block_accessreview_link report-accessmap',
]
);
} else {
return '';
}
}
}

View file

@ -0,0 +1,95 @@
<?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/>.
/**
* Web service to fetch module data.
*
* @package block_accessreview
* @copyright 2020 onward Brickfield Education Labs Ltd, https://www.brickfield.ie
* @author 2020 Max Larkin <max@brickfieldlabs.ie>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_accessreview\external;
use external_api;
use external_function_parameters;
use external_multiple_structure;
use external_single_structure;
use external_value;
use tool_brickfield\manager;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/externallib.php');
/**
* Web service to fetch module data.
*
* @package block_accessreview
* @copyright 2020 onward Brickfield Education Labs Ltd, https://www.brickfield.ie
* @author 2020 Max Larkin <max@brickfieldlabs.ie>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class get_module_data extends external_api {
/**
* Describes the parameters.
*
* @return external_function_parameters
*/
public static function execute_parameters() {
return new external_function_parameters([
'courseid' => new external_value(PARAM_INT, 'The course id to obtain results for.', VALUE_REQUIRED),
]);
}
/**
* Execute the service.
*
* @param int $courseid
* @return array
*/
public static function execute(int $courseid) {
[
'courseid' => $courseid,
] = self::validate_parameters(self::execute_parameters(), [
'courseid' => $courseid,
]);
$context = \context_course::instance($courseid);
self::validate_context($context);
require_capability('block/accessreview:view', $context);
return array_values(manager::get_cm_summary_for_course($courseid));
}
/**
* Describes the return structure of the service..
*
* @return external_multiple_structure
*/
public static function execute_returns() {
return new external_multiple_structure(
new external_single_structure(
[
'cmid' => new external_value(PARAM_INT, 'ID'),
'numerrors' => new external_value(PARAM_INT, 'Number of errors.'),
'numchecks' => new external_value(PARAM_INT, 'Number of checks.'),
]
)
);
}
}

View file

@ -0,0 +1,94 @@
<?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/>.
/**
* Web service to fetch section data.
*
* @package block_accessreview
* @copyright 2020 onward Brickfield Education Labs Ltd, https://www.brickfield.ie
* @author 2020 Max Larkin <max@brickfieldlabs.ie>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_accessreview\external;
use external_api;
use external_function_parameters;
use external_multiple_structure;
use external_single_structure;
use external_value;
use tool_brickfield\manager;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/externallib.php');
/**
* Web service to fetch section data.
*
* @package block_accessreview
* @copyright 2020 onward Brickfield Education Labs Ltd, https://www.brickfield.ie
* @author 2020 Max Larkin <max@brickfieldlabs.ie>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class get_section_data extends external_api {
/**
* Describes the parameters.
*
* @return external_function_parameters
*/
public static function execute_parameters() {
return new external_function_parameters([
'courseid' => new external_value(PARAM_INT, 'The course id to obtain results for.', VALUE_REQUIRED),
]);
}
/**
* Execute the service.
*
* @param int $courseid
* @return array
*/
public static function execute($courseid) {
[
'courseid' => $courseid,
] = self::validate_parameters(self::execute_parameters(), [
'courseid' => $courseid,
]);
$context = \context_course::instance($courseid);
self::validate_context($context);
require_capability('block/accessreview:view', $context);
return array_values(manager::get_section_summary_for_course($courseid));
}
/**
* Describes the return structure of the service..
*
* @return external_multiple_structure
*/
public static function execute_returns() {
return new external_multiple_structure(
new external_single_structure(
[
'section' => new external_value(PARAM_INT, 'ID'),
'numerrors' => new external_value(PARAM_INT, 'Number of errors.'),
'numchecks' => new external_value(PARAM_INT, 'Number of checks.'),
]
)
);
}
}

View file

@ -0,0 +1,78 @@
<?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/>.
/**
* Privacy Subsystem implementation for block_accessreview.
*
* @package block_accessreview
* @copyright 2020 Brickfield Education Labs, www.brickfield.ie
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_accessreview\privacy;
use \core_privacy\local\metadata\collection;
defined('MOODLE_INTERNAL') || die();
/**
* The accessreview block stores a user preference data.
*
* @copyright 2020 Brickfield Education Labs, www.brickfield.ie
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
// This plugin has data.
\core_privacy\local\metadata\provider,
// This plugin has some sitewide user preferences to export.
\core_privacy\local\request\user_preference_provider {
/** The user preference for the toggle state. */
const TOGGLE_STATE = 'block_accessreviewtogglestate';
/**
* Returns meta data about this system.
*
* @param collection $items The initialised item collection to add items to.
* @return collection A listing of user data stored through this system.
*/
public static function get_metadata(collection $items) : collection {
$items->add_user_preference(self::TOGGLE_STATE, 'privacy:metadata:preference:block_accessreviewtogglestate');
return $items;
}
/**
* Store all user preferences for the plugin.
*
* @param int $userid The userid of the user whose data is to be exported.
*/
public static function export_user_preferences(int $userid) {
$togglestate = get_user_preferences(self::TOGGLE_STATE, null, $userid);
if (isset($togglestate)) {
$preferencestring = get_string('privacy:togglestateoff', 'block_accessreview');
if ($togglestate == true) {
$preferencestring = get_string('privacy:togglestateon', 'block_accessreview');
}
\core_privacy\local\request\writer::export_user_preference(
'block_accessreview',
self::TOGGLE_STATE,
($togglestate) ? 'On' : 'Off',
$preferencestring
);
}
}
}

View file

@ -0,0 +1,49 @@
<?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/>.
/**
* accessreview capabilities definition
*
* @package block_accessreview
* @copyright 2019 Karen Holland LTS.ie
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'block/accessreview:addinstance' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
'block/accessreview:view' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
),
);

View file

@ -0,0 +1,45 @@
<?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/>.
/**
* External service definitions for the accessreview block.
*
* @package block_accessreview
* @author Max Larkin <max@brickfieldlabs.ie>
* @copyright 2020 Brickfield Education Labs <max@brickfieldlabs.ie>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$functions = [
'block_accessreview_get_module_data' => [
'classname' => 'block_accessreview\external\get_module_data',
'methodname' => 'execute',
'description' => 'Gets error data for course modules.',
'type' => 'read',
'ajax' => true,
'capabilities' => 'block/accessreview:view',
],
'block_accessreview_get_section_data' => [
'classname' => 'block_accessreview\external\get_section_data',
'methodname' => 'execute',
'description' => 'Gets error data for course sections.',
'type' => 'read',
'ajax' => true,
'capabilities' => 'block/accessreview:view',
]
];

View file

@ -0,0 +1,64 @@
<?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/>.
/**
* Simple block language strings
*
* @package block_accessreview
* @copyright 2019 Karen Holland LTS.ie
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$string['accessreview:addinstance'] = 'Add an Accessibility Review block to a course';
$string['accessreview:view'] = 'View the Accessibility Review';
$string['checktypes'] = 'Types';
$string['errors'] = 'Errors';
$string['errordisplay'] = 'Display errors in this format';
$string['errorssummary'] = 'Accessibility Review';
$string['frown'] = 'Errors found, sorry!';
$string['guides'] = 'Guides';
$string['link:pdf'] = 'Link to PDF resource on {$a} - opens in new window';
$string['link:video'] = 'Link to Video resource on {$a} - opens in new window';
$string['nodata'] = 'No accessibility results data was found.';
$string['pluginname'] = 'Accessibility Review';
$string['privacy:metadata'] = 'The Accessibility Review plugin does not store any personal data.';
$string['privacy:metadata:preference:block_accessreviewtogglestate'] = 'The user\'s preference for hiding or showing the course accessibility highlighting.';
$string['privacy:togglestateoff'] = 'The current preference for the course accessibility highlighting is off.';
$string['privacy:togglestateon'] = 'The current preference for the course accessibility highlighting is on.';
$string['showbackground'] = 'Show background colouring only';
$string['showboth'] = 'Show both background colour and status icons';
$string['showicon'] = 'Display smiley';
$string['showicons'] = 'Show count icons only';
$string['showint'] = 'Display amount';
$string['showpercent'] = 'Display percentage';
$string['smile'] = '0 errors, congratulations!';
$string['status:successalt'] = 'Passed';
$string['status:success'] = 'Passed';
$string['status:errors'] = 'Failed {$a->errorCount} errors ({$a->failureRate}% of all checks)';
$string['status:errorsalt'] = 'Errors';
$string['toggleaccessreview'] = 'Toggle highlighting';
$string['toolpage'] = 'Report page to show';
$string['totalerrors'] = '<em>Total errors:</em> {$a} <br>(total excludes course settings)';
$string['viewreportalt'] = 'View Brickfield Accessibility Report';
$string['viewreport'] = 'View';
$string['downloadreportalt'] = 'Download Brickfield Accessibility Report';
$string['downloadreport'] = 'Download';
$string['togglealt'] = 'Toggle Brickfield Accessibility Heatmap';
$string['toggle'] = 'Toggle highlighting';
$string['whattoshow'] = 'What to show on course page';

View file

@ -0,0 +1,65 @@
<?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/>.
/**
* Lib library of functions.
*
* @package block_accessreview
* @copyright 2019 Karen Holland LTS.ie
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Get icon mapping for font-awesome.
*/
function block_accessreview_get_fontawesome_icon_map() {
return [
'block_accessreview:smile' => 'fa-smile-o',
'block_accessreview:frown' => 'fa-frown-o',
'block_accessreview:errorsfound' => 'fa-ban',
'block_accessreview:f/pdf' => 'fa-file-pdf-o',
'block_accessreview:f/video' => 'fa-file-video-o',
'block_accessreview:f/find' => 'fa-bar-chart',
'block_accessreview:f/form' => 'fa-pencil-square-o',
'block_accessreview:f/image' => 'fa-image',
'block_accessreview:f/layout' => 'fa-th-large',
'block_accessreview:f/link' => 'fa-link',
'block_accessreview:f/media' => 'fa-play-circle-o',
'block_accessreview:f/table' => 'fa-table',
'block_accessreview:f/text' => 'fa-font',
'block_accessreview:t/fail' => 'fa-ban',
'block_accessreview:t/pass' => 'fa-check',
];
}
/**
* Define preferences which may be set via the core_user_set_user_preferences external function.
*
* @return array
*/
function block_accessreview_user_preferences(): array {
return [
'block_accessreviewtogglestate' => [
'type' => PARAM_INT,
'null' => NULL_NOT_ALLOWED,
'default' => 0,
'choices' => [0, 1],
],
];
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

View file

@ -0,0 +1,3 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
]><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M6 0C2.7 0 0 2.7 0 6s2.7 6 6 6 6-2.7 6-6-2.7-6-6-6zm0 2.5c.5 0 1 .1 1.4.3L2.8 7.4c-.2-.4-.3-.9-.3-1.4 0-1.9 1.6-3.5 3.5-3.5zm0 7c-.5 0-1-.1-1.4-.3l4.6-4.6c.2.4.3.9.3 1.4 0 1.9-1.6 3.5-3.5 3.5z" fill="#999"/></svg>

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

View file

@ -0,0 +1,3 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
]><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M11.4.6l-.9-.5c-.4-.2-1-.1-1.3.4L4.7 8.2 2 6.6C1.5 6.3.9 6.5.6 7l-.5.8c-.2.5-.1 1.1.4 1.4L5 11.8c.1.1.3.1.4.1.4.1.8-.1 1-.5L11.8 2c.3-.5.1-1.1-.4-1.4z" fill="#999"/></svg>

After

Width:  |  Height:  |  Size: 475 B

View file

@ -0,0 +1,66 @@
<?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/>.
/**
* accessreview block settings
*
* @package block_accessreview
* @copyright 2019 Karen Holland LTS.ie
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
use tool_brickfield\local\tool\tool as base_tool;
if ($ADMIN->fulltree) {
// Control background display and icons.
$options = [
'showboth' => get_string('showboth', 'block_accessreview'),
'showbackground' => get_string('showbackground', 'block_accessreview'),
'showicons' => get_string('showicons', 'block_accessreview'),
];
$settings->add(new admin_setting_configselect('block_accessreview/whattoshow',
get_string('whattoshow', 'block_accessreview'),
'',
'showboth',
$options)
);
// Control display format for errors.
$erroroptions = [
'showint' => get_string('showint', 'block_accessreview'),
'showpercent' => get_string('showpercent', 'block_accessreview'),
'showicon' => get_string('showicon', 'block_accessreview'),
];
$settings->add(new admin_setting_configselect('block_accessreview/errordisplay',
get_string('errordisplay', 'block_accessreview'),
'',
'showint',
$erroroptions)
);
// Tool page to display by default.
$options = base_tool::get_tool_names();
$settings->add(new admin_setting_configselect(
'block_accessreview/toolpage',
get_string('toolpage', 'block_accessreview'),
'',
key($options),
$options
));
}

41
blocks/accessreview/styles.css Executable file
View file

@ -0,0 +1,41 @@
.block_accessreview_success,
.block_accessreview.block_accessreview_success.hasinfo {
color: #1e451e;
background: #d7e6d7;
border-color: #c8ddc8;
}
.block_accessreview_danger,
.block_accessreview.block_accessreview_danger.hasinfo {
color: #6e211e;
background: #f6d9d8;
border-color: #f3c9c8;
}
.block_accessreview_warning,
.block_accessreview.block_accessreview_warning.hasinfo {
color: #7d5a29;
background: #fcefdc;
border-color: #fbe8cd;
}
.block_accessreview_table {
border-bottom: 1px solid;
border-color: #eee8e8;
}
.block_accessreview_links {
display: flex;
flex-flow: row;
flex-wrap: wrap;
justify-content: center;
}
.block_accessreview_link {
padding-left: 10px;
padding-right: 10px;
}
.block_accessreview_analysisbutton {
text-align: center;
}

View file

@ -0,0 +1,63 @@
{{!
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 block_accessreview/status
Accessibility review result information.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* classList - array of block_accessreview classes
* resultPassed - boolean indicating that the item is correct
* passRate - object containing metrics
* errorCount - the number of failures
* checkCount - the number of items checked
* failureRate - the percentage of items failing
Example context (json):
{
"classList": "block_accessreview_danger",
"passRate": {
"checkCount": "60",
"errorCount": "12",
"failureRate": "20"
}
}
}}
<div class="block_accessreview block_accessreview_view {{classList}}">
{{#resultPassed}}
{{#pix}}t/pass, block_accessreview, {{#str}}status:successalt, block_accessreview{{/str}}{{/pix}}
{{#str}}status:success, block_accessreview, {
"errorCount": {{passRate.errorCount}},
"checkCount": {{passRate.checkCount}},
"failureRate": {{passRate.failureRate}}
}{{/str}}
{{/resultPassed}}
{{^resultPassed}}
{{#pix}}t/fail, block_accessreview, {{#str}}status:errorsalt, block_accessreview{{/str}}{{/pix}}
{{#str}}status:errors, block_accessreview, {
"errorCount": {{passRate.errorCount}},
"checkCount": {{passRate.checkCount}},
"failureRate": {{passRate.failureRate}}
}{{/str}}
{{/resultPassed}}
</div>

View file

@ -0,0 +1,99 @@
<?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 block_accessreview\tests;
use ReflectionClass;
use advanced_testcase;
use block_accessreview;
use context_course;
/**
* PHPUnit block_accessibility_review tests
*
* @package block_accessreview
* @copyright 2020 onward: Learning Technology Services, www.lts.ie
* @author Jay Churchward (jay.churchward@poetopensource.org)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class accessibility_review_test extends advanced_testcase {
public static function setUpBeforeClass(): void {
require_once(__DIR__ . '/../../moodleblock.class.php');
require_once(__DIR__ . '/../block_accessreview.php');
}
public function test_get_toggle_link() {
$rc = new ReflectionClass(block_accessreview::class);
$rm = $rc->getMethod('get_toggle_link');
$rm->setAccessible(true);
$block = new block_accessreview();
$output = $rm->invoke($block);
$this->assertNotEmpty($output);
}
public function test_get_download_link() {
$this->resetAfterTest();
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$course = $this->getDataGenerator()->create_course();
// Enrol users in the course.
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'teacher');
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
$rc = new ReflectionClass(block_accessreview::class);
$rm = $rc->getMethod('get_download_link');
$rm->setAccessible(true);
$block = new block_accessreview();
$this->setUser($user1);
$result = $rm->invoke($block, context_course::instance($course->id));
$this->assertNotEmpty($result);
$this->setUser($user2);
$result = $rm->invoke($block, context_course::instance($course->id));
$this->assertEmpty($result);
}
public function test_get_report_link() {
$this->resetAfterTest();
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$course = $this->getDataGenerator()->create_course();
// Enrol users in the course.
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'teacher');
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
$rc = new ReflectionClass(block_accessreview::class);
$rm = $rc->getMethod('get_report_link');
$rm->setAccessible(true);
$block = new block_accessreview();
$this->setUser($user1);
$result = $rm->invoke($block, context_course::instance($course->id));
$this->assertNotEmpty($result);
$this->setUser($user2);
$result = $rm->invoke($block, context_course::instance($course->id));
$this->assertEmpty($result);
}
}

View file

@ -0,0 +1,30 @@
@block @block_accessreview @javascript
Feature: Block accessreview
In order to overview accessibility information on my course
As a manager
I can add the accessreview block in a course
Background:
Given the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
Scenario: View accessreview block on a course
Given I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
When I add the "Accessibility Review" block
Then I should see "Accessibility Review"
And I should see "No accessibility results data was found."
Scenario: Hide/show accessreview view
Given I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
When I add the "Accessibility Review" block
Then I should see "Accessibility Review"
And I should see "No accessibility results data was found."
And I click on "Actions menu" "icon" in the "Accessibility Review" "block"
And I follow "Hide Accessibility Review block"
And I should not see "No accessibility results data was found."
And I click on "Actions menu" "icon" in the "Accessibility Review" "block"
And I follow "Show Accessibility Review block"
And I should see "No accessibility results data was found."

View file

@ -0,0 +1,38 @@
@block @block_accessreview @javascript
Feature: Block accessreview results
In order to overview accessibility information on my course
As a manager
I can add the accessreview block in a course after running the scheduled task
Background:
Given the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| label | Label one | <b>Bold text is bold.</b> | C1 | id001 |
And I run the scheduled task "\tool_brickfield\task\bulk_process_courses"
Scenario: View accessreview block results on a course
Given I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
When I add the "Accessibility Review" block
Then I should see "Accessibility Review"
And I should not see "No accessibility results data was found."
And I should see "Image"
And I should see "Layout"
And I should see "Link"
And I should see "Media"
And I should see "Table"
And I should see "Text"
And I should see "View"
And I should see "Toggle highlighting"
Scenario: Toggle highlighting on/off
Given I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
When I add the "Accessibility Review" block
Then I should see "Toggle highlighting"
And ".block_accessreview_view" "css_element" should be visible
And I click on "Toggle highlighting" "text"
And ".block_accessreview_view" "css_element" should not be visible

View file

@ -0,0 +1,35 @@
<?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/>.
/**
* Simple block version identification
*
* @package block_accessreview
* @copyright 2019 Karen Holland LTS.ie
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'block_accessreview';
$plugin->release = '1.1 (Build - 2021012500)';
$plugin->version = 2020101904;
$plugin->requires = 2018051700; // Moodle 3.5 and up.
$plugin->maturity = MATURITY_STABLE;
$plugin->dependencies = array(
'tool_brickfield' => ANY_VERSION,
);