first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
define("block_accessreview/module",["exports","core/ajax","core/templates","core/notification"],(function(_exports,_ajax,Templates,_notification){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,Templates=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}
/**
* Manager for the accessreview block.
*
* @module block_accessreview/module
* @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
*/(Templates);let toggleState=!0;const renderTemplate=(element,errorCount,checkCount,displayFormat,minViews,viewDelta)=>{const weight=parseInt((errorCount-minViews)/viewDelta*2),context={resultPassed:!errorCount,classList:"",passRate:{errorCount:errorCount,checkCount:checkCount,failureRate:Math.round(errorCount/checkCount*100)}};if(!element)return Promise.resolve();const elementClassList=["block_accessreview"];context.resultPassed?elementClassList.push("block_accessreview_success"):weight?elementClassList.push("block_accessreview_danger"):elementClassList.push("block_accessreview_warning");const showIcons="showicons"==displayFormat||"showboth"==displayFormat,showBackground="showbackground"==displayFormat||"showboth"==displayFormat;return showBackground&&!showIcons?(element.classList.add(...elementClassList,"alert"),Promise.resolve()):(showIcons&&!showBackground&&(context.classList=elementClassList.join(" ")),Templates.renderForPromise("block_accessreview/status",context).then((_ref=>{let{html:html,js:js}=_ref;Templates.appendNodeContents(element,html,js),showBackground&&element.classList.add(...elementClassList,"alert")})).catch())},showAccessMap=function(courseId,displayFormat){let updatePreference=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return Promise.all(fetchReviewData(courseId,updatePreference)).then((_ref2=>{let[sectionData,moduleData]=_ref2;const{minViews:minViews,viewDelta:viewDelta}=getErrorTotals(sectionData,moduleData);return sectionData.forEach((section=>{const element=document.querySelector("#section-".concat(section.section," .summary"));element&&renderTemplate(element,section.numerrors,section.numchecks,displayFormat,minViews,viewDelta)})),moduleData.forEach((module=>{const element=document.getElementById("module-".concat(module.cmid));element&&renderTemplate(element,module.numerrors,module.numchecks,displayFormat,minViews,viewDelta)})),document.querySelector(".icon-accessmap").classList.remove("fa-eye-slash"),document.querySelector(".icon-accessmap").classList.add("fa-eye"),{sectionData:sectionData,moduleData:moduleData}})).catch(_notification.exception)},toggleAccessMap=(courseId,displayFormat)=>{toggleState=!toggleState,toggleState?showAccessMap(courseId,displayFormat,!0):function(){let updatePreference=arguments.length>0&&void 0!==arguments[0]&&arguments[0];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","alert"];document.querySelectorAll(".block_accessreview").forEach((node=>node.classList.remove(...classList))),updatePreference&&setToggleStatePreference(!1),document.querySelector(".icon-accessmap").classList.remove("fa-eye"),document.querySelector(".icon-accessmap").classList.add("fa-eye-slash")}(!0)},getErrorTotals=(sectionData,moduleData)=>{const totals={totalErrors:0,totalUsers:0,minViews:0,maxViews:0,viewDelta:0};return[].concat(sectionData,moduleData).forEach((item=>{totals.totalErrors+=item.numerrors,item.numerrors<totals.minViews&&(totals.minViews=item.numerrors),item.numerrors>totals.maxViews&&(totals.maxViews=item.numerrors),totals.totalUsers+=item.numchecks})),totals.viewDelta=totals.maxViews-totals.minViews+1,totals},getTogglePreferenceParams=toggleState=>({methodname:"core_user_update_user_preferences",args:{preferences:[{type:"block_accessreviewtogglestate",value:toggleState}]}}),setToggleStatePreference=toggleState=>(0,_ajax.call)([getTogglePreferenceParams(toggleState)]),fetchReviewData=function(courseid){let updatePreference=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const calls=[{methodname:"block_accessreview_get_section_data",args:{courseid:courseid}},{methodname:"block_accessreview_get_module_data",args:{courseid:courseid}}];return updatePreference&&calls.push(getTogglePreferenceParams(!0)),(0,_ajax.call)(calls)};_exports.init=(toggled,displayFormat,courseId)=>{toggleState=1==toggled,toggleState&&showAccessMap(courseId,displayFormat),((courseId,displayFormat)=>{document.addEventListener("click",(e=>{e.target.closest("#toggle-accessmap")&&(e.preventDefault(),toggleAccessMap(courseId,displayFormat))}))})(courseId,displayFormat)}}));
//# sourceMappingURL=module.min.js.map
File diff suppressed because one or more lines are too long
+303
View File
@@ -0,0 +1,303 @@
// 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/>.
/**
* Manager for the accessreview block.
*
* @module block_accessreview/module
* @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);
});
// Change the icon display.
document.querySelector('.icon-accessmap').classList.remove(...['fa-eye-slash']);
document.querySelector('.icon-accessmap').classList.add(...['fa-eye']);
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',
'alert',
];
// Removes the added classes.
document.querySelectorAll('.block_accessreview').forEach(node => node.classList.remove(...classList));
if (updatePreference) {
setToggleStatePreference(false);
}
// Change the icon display.
document.querySelector('.icon-accessmap').classList.remove(...['fa-eye']);
document.querySelector('.icon-accessmap').classList.add(...['fa-eye-slash']);
};
/**
* 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.
*/
export const init = (toggled, displayFormat, courseId) => {
// Settings consts.
toggleState = toggled == 1;
if (toggleState) {
showAccessMap(courseId, displayFormat);
}
registerEventListeners(courseId, displayFormat);
};
+320
View File
@@ -0,0 +1,320 @@
<?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 {
return [
'course-view' => true,
'site' => true,
'mod' => false,
'my' => false,
];
}
/**
* 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', single_button::BUTTON_PRIMARY,
['class' => 'block_accessreview_analysisbutton']);
$this->content->text .= html_writer::tag('div', $OUTPUT->render($button),
['class' => 'block_accessreview_analysisbutton']);
}
return $this->content;
}
/**
* This block shouldn't be added to a page if the accessibility tools setting is disabled.
*
* @param moodle_page $page
* @return bool
*/
public function can_block_be_added(moodle_page $page): bool {
return accessibility::is_accessibility_enabled();
}
/**
* 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;
if (get_user_preferences('block_accessreviewtogglestate')) {
$icon = 't/hide';
} else {
$icon = 't/show';
}
// Toggle overlay link.
return html_writer::link(
'#',
$OUTPUT->pix_icon($icon, get_string('togglealt', 'block_accessreview'), 'moodle', ['class' => 'icon-accessmap']),
[
'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 '';
}
}
}
@@ -0,0 +1,83 @@
<?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\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use tool_brickfield\manager;
/**
* 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.'),
]
)
);
}
}
@@ -0,0 +1,83 @@
<?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\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use tool_brickfield\manager;
/**
* 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.'),
]
)
);
}
}
@@ -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
);
}
}
}
+49
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
),
),
);
+45
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',
]
];
@@ -0,0 +1,60 @@
<?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';
$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['nodata'] = 'No accessibility results data was found.';
$string['pluginname'] = 'Accessibility review';
$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 - error count: {$a->errorCount}';
$string['status:errorsalt'] = 'Errors';
$string['toggleaccessreview'] = 'Toggle highlighting';
$string['toolpage'] = 'Toolkit page to show';
$string['totalerrors'] = '<em>Total errors:</em> {$a} <br>(total excludes course settings)';
$string['viewreportalt'] = 'View accessibility toolkit';
$string['viewreport'] = 'View';
$string['downloadreportalt'] = 'Download accessibility summary report';
$string['downloadreport'] = 'Download';
$string['togglealt'] = 'Toggle accessibility heatmap';
$string['toggle'] = 'Toggle highlighting';
$string['whattoshow'] = 'What to show on course page';
+68
View File
@@ -0,0 +1,68 @@
<?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.
*
* @uses core_user::is_current_user
*
* @return array[]
*/
function block_accessreview_user_preferences(): array {
return [
'block_accessreviewtogglestate' => [
'type' => PARAM_INT,
'null' => NULL_NOT_ALLOWED,
'default' => 0,
'choices' => [0, 1],
'permissioncallback' => [core_user::class, 'is_current_user'],
],
];
}
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M367.2 412.5L99.5 144.8C77.1 176.1 64 214.5 64 256c0 106 86 192 192 192c41.5 0 79.9-13.1 111.2-35.5zm45.3-45.3C434.9 335.9 448 297.5 448 256c0-106-86-192-192-192c-41.5 0-79.9 13.1-111.2 35.5L412.5 367.2zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256z"/></svg>

After

Width:  |  Height:  |  Size: 549 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M32 32c17.7 0 32 14.3 32 32V400c0 8.8 7.2 16 16 16H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H80c-44.2 0-80-35.8-80-80V64C0 46.3 14.3 32 32 32zM160 224c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V256c0-17.7 14.3-32 32-32zm128-64V320c0 17.7-14.3 32-32 32s-32-14.3-32-32V160c0-17.7 14.3-32 32-32s32 14.3 32 32zm64 32c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V224c0-17.7 14.3-32 32-32zM480 96V320c0 17.7-14.3 32-32 32s-32-14.3-32-32V96c0-17.7 14.3-32 32-32s32 14.3 32 32z"/></svg>

After

Width:  |  Height:  |  Size: 798 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M441 58.9L453.1 71c9.4 9.4 9.4 24.6 0 33.9L424 134.1 377.9 88 407 58.9c9.4-9.4 24.6-9.4 33.9 0zM209.8 256.2L344 121.9 390.1 168 255.8 302.2c-2.9 2.9-6.5 5-10.4 6.1l-58.5 16.7 16.7-58.5c1.1-3.9 3.2-7.5 6.1-10.4zM373.1 25L175.8 222.2c-8.7 8.7-15 19.4-18.3 31.1l-28.6 100c-2.4 8.4-.1 17.4 6.1 23.6s15.2 8.5 23.6 6.1l100-28.6c11.8-3.4 22.5-9.7 31.1-18.3L487 138.9c28.1-28.1 28.1-73.7 0-101.8L474.9 25C446.8-3.1 401.2-3.1 373.1 25zM88 64C39.4 64 0 103.4 0 152V424c0 48.6 39.4 88 88 88H360c48.6 0 88-39.4 88-88V312c0-13.3-10.7-24-24-24s-24 10.7-24 24V424c0 22.1-17.9 40-40 40H88c-22.1 0-40-17.9-40-40V152c0-22.1 17.9-40 40-40H200c13.3 0 24-10.7 24-24s-10.7-24-24-24H88z"/></svg>

After

Width:  |  Height:  |  Size: 962 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M448 80c8.8 0 16 7.2 16 16V415.8l-5-6.5-136-176c-4.5-5.9-11.6-9.3-19-9.3s-14.4 3.4-19 9.3L202 340.7l-30.5-42.7C167 291.7 159.8 288 152 288s-15 3.7-19.5 10.1l-80 112L48 416.3l0-.3V96c0-8.8 7.2-16 16-16H448zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm80 192a48 48 0 1 0 0-96 48 48 0 1 0 0 96z"/></svg>

After

Width:  |  Height:  |  Size: 650 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M448 96V224H288V96H448zm0 192V416H288V288H448zM224 224H64V96H224V224zM64 288H224V416H64V288zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64z"/></svg>

After

Width:  |  Height:  |  Size: 495 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 640 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M579.8 267.7c56.5-56.5 56.5-148 0-204.5c-50-50-128.8-56.5-186.3-15.4l-1.6 1.1c-14.4 10.3-17.7 30.3-7.4 44.6s30.3 17.7 44.6 7.4l1.6-1.1c32.1-22.9 76-19.3 103.8 8.6c31.5 31.5 31.5 82.5 0 114L422.3 334.8c-31.5 31.5-82.5 31.5-114 0c-27.9-27.9-31.5-71.8-8.6-103.8l1.1-1.6c10.3-14.4 6.9-34.4-7.4-44.6s-34.4-6.9-44.6 7.4l-1.1 1.6C206.5 251.2 213 330 263 380c56.5 56.5 148 56.5 204.5 0L579.8 267.7zM60.2 244.3c-56.5 56.5-56.5 148 0 204.5c50 50 128.8 56.5 186.3 15.4l1.6-1.1c14.4-10.3 17.7-30.3 7.4-44.6s-30.3-17.7-44.6-7.4l-1.6 1.1c-32.1 22.9-76 19.3-103.8-8.6C74 372 74 321 105.5 289.5L217.7 177.2c31.5-31.5 82.5-31.5 114 0c27.9 27.9 31.5 71.8 8.6 103.9l-1.1 1.6c-10.3 14.4-6.9 34.4 7.4 44.6s34.4 6.9 44.6-7.4l1.1-1.6C433.5 260.8 427 182 377 132c-56.5-56.5-148-56.5-204.5 0L60.2 244.3z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM188.3 147.1c7.6-4.2 16.8-4.1 24.3 .5l144 88c7.1 4.4 11.5 12.1 11.5 20.5s-4.4 16.1-11.5 20.5l-144 88c-7.4 4.5-16.7 4.7-24.3 .5s-12.3-12.2-12.3-20.9V168c0-8.7 4.7-16.7 12.3-20.9z"/></svg>

After

Width:  |  Height:  |  Size: 573 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M64 464H96v48H64c-35.3 0-64-28.7-64-64V64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V288H336V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16zM176 352h32c30.9 0 56 25.1 56 56s-25.1 56-56 56H192v32c0 8.8-7.2 16-16 16s-16-7.2-16-16V448 368c0-8.8 7.2-16 16-16zm32 80c13.3 0 24-10.7 24-24s-10.7-24-24-24H192v48h16zm96-80h32c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48H304c-8.8 0-16-7.2-16-16V368c0-8.8 7.2-16 16-16zm32 128c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H320v96h16zm80-112c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16s-7.2 16-16 16H448v32h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H448v48c0 8.8-7.2 16-16 16s-16-7.2-16-16V432 368z"/></svg>

After

Width:  |  Height:  |  Size: 997 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M64 256V160H224v96H64zm0 64H224v96H64V320zm224 96V320H448v96H288zM448 256H288V160H448v96zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64z"/></svg>

After

Width:  |  Height:  |  Size: 492 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M254 52.8C249.3 40.3 237.3 32 224 32s-25.3 8.3-30 20.8L57.8 416H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32h-1.8l18-48H303.8l18 48H320c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H390.2L254 52.8zM279.8 304H168.2L224 155.1 279.8 304z"/></svg>

After

Width:  |  Height:  |  Size: 595 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 384 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M320 464c8.8 0 16-7.2 16-16V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320zM0 64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM80 288c0-17.7 14.3-32 32-32h96c17.7 0 32 14.3 32 32v16l44.9-29.9c2-1.3 4.4-2.1 6.8-2.1c6.8 0 12.3 5.5 12.3 12.3V387.7c0 6.8-5.5 12.3-12.3 12.3c-2.4 0-4.8-.7-6.8-2.1L240 368v16c0 17.7-14.3 32-32 32H112c-17.7 0-32-14.3-32-32V288z"/></svg>

After

Width:  |  Height:  |  Size: 782 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM174.6 384.1c-4.5 12.5-18.2 18.9-30.7 14.4s-18.9-18.2-14.4-30.7C146.9 319.4 198.9 288 256 288s109.1 31.4 126.6 79.9c4.5 12.5-2 26.2-14.4 30.7s-26.2-2-30.7-14.4C328.2 358.5 297.2 336 256 336s-72.2 22.5-81.4 48.1zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>

After

Width:  |  Height:  |  Size: 695 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm177.6 62.1C192.8 334.5 218.8 352 256 352s63.2-17.5 78.4-33.9c9-9.7 24.2-10.4 33.9-1.4s10.4 24.2 1.4 33.9c-22 23.8-60 49.4-113.6 49.4s-91.7-25.5-113.6-49.4c-9-9.7-8.4-24.9 1.4-33.9s24.9-8.4 33.9 1.4zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

+3
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="#888"/></svg>

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

+3
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="#888"/></svg>

After

Width:  |  Height:  |  Size: 473 B

+66
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
View File
@@ -0,0 +1,41 @@
.block_accessreview_success,
.block_accessreview.block_accessreview_success.hasinfo {
color: #1e451e;
background: #eff5ef;
box-shadow: 0 0 2px 2px #619a61;
}
.block_accessreview_danger,
.block_accessreview.block_accessreview_danger.hasinfo {
color: #6e211e;
background: #fdf7f7;
box-shadow: 0 0 2px 2px #da6960;
}
.block_accessreview_warning,
.block_accessreview.block_accessreview_warning.hasinfo {
color: #694b21;
background: #fdf2e3;
box-shadow: 0 0 2px 2px #c97a0e;
}
.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;
}
@@ -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>
@@ -0,0 +1,123 @@
<?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;
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
* @coversDefaultClass \block_accessreview
*/
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(): void {
$rc = new ReflectionClass(block_accessreview::class);
$rm = $rc->getMethod('get_toggle_link');
$block = new block_accessreview();
$output = $rm->invoke($block);
$this->assertNotEmpty($output);
}
public function test_get_download_link(): void {
$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');
$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(): void {
$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');
$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);
}
/**
* Test the behaviour of can_block_be_added() method.
*
* @covers ::can_block_be_added
*/
public function test_can_block_be_added(): void {
$this->resetAfterTest();
$this->setAdminUser();
// Create a course and prepare the page where the block will be added.
$course = $this->getDataGenerator()->create_course();
$page = new \moodle_page();
$page->set_context(context_course::instance($course->id));
$page->set_pagelayout('course');
$block = new block_accessreview();
// If the accessibility tools is enabled, the method should return true.
set_config('enableaccessibilitytools', true);
$this->assertTrue($block->can_block_be_added($page));
// However, if the accessibility tools is disabled, the method should return false.
set_config('enableaccessibilitytools', false);
$this->assertFalse($block->can_block_be_added($page));
}
}
@@ -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 "Your accessibility toolkit needs to be registered."
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 "Your accessibility toolkit needs to be registered."
And I click on "Actions menu" "icon" in the "Accessibility Review" "block"
And I follow "Hide Accessibility Review block"
And I should not see "Your accessibility toolkit needs to be registered."
And I click on "Actions menu" "icon" in the "Accessibility Review" "block"
And I follow "Show Accessibility Review block"
And I should see "Your accessibility toolkit needs to be registered."
@@ -0,0 +1,68 @@
@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 |
| label | Label two | <a href="modle.org">Click here</a> | C1 | id002 |
And I run the scheduled task "\tool_brickfield\task\process_analysis_requests"
And I run the scheduled task "\tool_brickfield\task\bulk_process_courses"
And I run the scheduled task "\tool_brickfield\task\bulk_process_caches"
Scenario: View accessreview block results on a course
Given I log in as "admin"
And I navigate to "Plugins > Admin tools > Accessibility > Brickfield registration" in site administration
And I set the field "id_key" to "123456789012345678901234567890ab"
And I set the field "id_hash" to "ab123456789012345678901234567890"
And I press "Activate"
Then I should see "Your accessibility toolkit is still being validated."
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 press "Submit for analysis"
Then I should see "This course has been scheduled for analysis."
And I run the scheduled task "\tool_brickfield\task\process_analysis_requests"
And I run the scheduled task "\tool_brickfield\task\bulk_process_courses"
And I run the scheduled task "\tool_brickfield\task\bulk_process_caches"
And I reload the page
And I should see "Image" in the "Accessibility Review" "block"
And I should see "Layout" in the "Accessibility Review" "block"
And I should see "Link" in the "Accessibility Review" "block"
And I should see "Media" in the "Accessibility Review" "block"
And I should see "Table" in the "Accessibility Review" "block"
And I should see "Text" in the "Accessibility Review" "block"
# We created one link error above.
And I should see "1" in the "Link" "table_row"
# We created one text issue, and the standard Behat course generator creates another (too much content).
And I should see "2" in the "Text" "table_row"
And "View Brickfield Accessibility Report" "icon" should exist in the "Accessibility Review" "block"
And "Toggle Brickfield Accessibility Heatmap" "icon" should exist in the "Accessibility Review" "block"
And "Download Brickfield Accessibility Report" "icon" should exist in the "Accessibility Review" "block"
Scenario: Toggle highlighting on/off
Given I log in as "admin"
Given the following "user preferences" exist:
| user | preference | value |
| admin | block_accessreviewtogglestate | 0 |
And I navigate to "Plugins > Admin tools > Accessibility > Brickfield registration" in site administration
And I set the field "id_key" to "123456789012345678901234567890ab"
And I set the field "id_hash" to "ab123456789012345678901234567890"
And I press "Activate"
And I am on "Course 1" course homepage with editing mode on
When I add the "Accessibility Review" block
And I press "Submit for analysis"
And I run the scheduled task "\tool_brickfield\task\process_analysis_requests"
And I run the scheduled task "\tool_brickfield\task\bulk_process_courses"
And I run the scheduled task "\tool_brickfield\task\bulk_process_caches"
And I reload the page
And I click on "Toggle Brickfield Accessibility Heatmap" "icon"
And ".block_accessreview_view" "css_element" should be visible
And I click on "Toggle Brickfield Accessibility Heatmap" "icon"
And ".block_accessreview_view" "css_element" should not be visible
@@ -0,0 +1,32 @@
@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 |
And the following config values are set as admin:
| analysistype | 1 | tool_brickfield |
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 "Your accessibility toolkit needs to be registered."
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 "Your accessibility toolkit needs to be registered."
And I click on "Actions menu" "icon" in the "Accessibility review" "block"
And I follow "Hide Accessibility review block"
And I should not see "Your accessibility toolkit needs to be registered."
And I click on "Actions menu" "icon" in the "Accessibility review" "block"
And I follow "Show Accessibility review block"
And I should see "Your accessibility toolkit needs to be registered."
@@ -0,0 +1,67 @@
@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 |
| label | Label two | <a href="modle.org">Click here</a> | C1 | id002 |
And the following config values are set as admin:
| analysistype | 1 | tool_brickfield |
Scenario: View accessreview block results on a course
Given I log in as "admin"
And I navigate to "Plugins > Admin tools > Accessibility > Brickfield registration" in site administration
And I set the field "id_key" to "123456789012345678901234567890ab"
And I set the field "id_hash" to "ab123456789012345678901234567890"
And I press "Activate"
Then I should see "Your accessibility toolkit is functional while being validated."
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 press "Submit for analysis"
Then I should see "This course has been scheduled for analysis."
And I run the scheduled task "\tool_brickfield\task\process_analysis_requests"
And I run the scheduled task "\tool_brickfield\task\bulk_process_courses"
And I run the scheduled task "\tool_brickfield\task\bulk_process_caches"
And I reload the page
And I should see "Image" in the "Accessibility review" "block"
And I should see "Layout" in the "Accessibility review" "block"
And I should see "Link" in the "Accessibility review" "block"
And I should see "Media" in the "Accessibility review" "block"
And I should see "Table" in the "Accessibility review" "block"
And I should see "Text" in the "Accessibility review" "block"
# We created one link error above.
And I should see "1" in the "Link" "table_row"
# We created one text issue, and the standard Behat course generator creates another (too much content).
And I should see "2" in the "Text" "table_row"
And "View accessibility toolkit" "icon" should exist in the "Accessibility review" "block"
And "Toggle accessibility heatmap" "icon" should exist in the "Accessibility review" "block"
And "Download accessibility summary report" "icon" should exist in the "Accessibility review" "block"
Scenario: Toggle highlighting on/off
Given I log in as "admin"
Given the following "user preferences" exist:
| user | preference | value |
| admin | block_accessreviewtogglestate | 0 |
And I navigate to "Plugins > Admin tools > Accessibility > Brickfield registration" in site administration
And I set the field "id_key" to "123456789012345678901234567890ab"
And I set the field "id_hash" to "ab123456789012345678901234567890"
And I press "Activate"
And I am on "Course 1" course homepage with editing mode on
When I add the "Accessibility review" block
And I press "Submit for analysis"
And I run the scheduled task "\tool_brickfield\task\process_analysis_requests"
And I run the scheduled task "\tool_brickfield\task\bulk_process_courses"
And I run the scheduled task "\tool_brickfield\task\bulk_process_caches"
And I reload the page
And I click on "Toggle accessibility heatmap" "icon"
And ".block_accessreview_view" "css_element" should be visible
And I click on "Toggle accessibility heatmap" "icon"
And ".block_accessreview_view" "css_element" should not be visible
+33
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/>.
/**
* 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->version = 2024042200;
$plugin->requires = 2024041600;
$plugin->dependencies = [
'tool_brickfield' => ANY_VERSION,
];