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,
];
@@ -0,0 +1,106 @@
<?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/>.
/**
* This file contains the Activity modules block.
*
* @package block_activity_modules
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/filelib.php');
class block_activity_modules extends block_list {
function init() {
$this->title = get_string('pluginname', 'block_activity_modules');
}
function get_content() {
global $CFG, $DB, $OUTPUT;
if($this->content !== NULL) {
return $this->content;
}
$this->content = new stdClass;
$this->content->items = array();
$this->content->icons = array();
$this->content->footer = '';
$course = $this->page->course;
require_once($CFG->dirroot.'/course/lib.php');
$modinfo = get_fast_modinfo($course);
$modfullnames = array();
$archetypes = array();
foreach($modinfo->cms as $cm) {
// Exclude activities that aren't visible or have no view link (e.g. label). Account for folder being displayed inline.
if (!$cm->uservisible || (!$cm->has_view() && strcmp($cm->modname, 'folder') !== 0)) {
continue;
}
if (array_key_exists($cm->modname, $modfullnames)) {
continue;
}
if (!array_key_exists($cm->modname, $archetypes)) {
$archetypes[$cm->modname] = plugin_supports('mod', $cm->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
}
if ($archetypes[$cm->modname] == MOD_ARCHETYPE_RESOURCE) {
if (!array_key_exists('resources', $modfullnames)) {
$modfullnames['resources'] = get_string('resources');
}
} else {
$modfullnames[$cm->modname] = $cm->modplural;
}
}
core_collator::asort($modfullnames);
foreach ($modfullnames as $modname => $modfullname) {
if ($modname === 'resources') {
$icon = $OUTPUT->pix_icon('monologo', '', 'mod_page', array('class' => 'icon'));
$this->content->items[] = '<a href="'.$CFG->wwwroot.'/course/resources.php?id='.$course->id.'">'.$icon.$modfullname.'</a>';
} else {
$icon = $OUTPUT->image_icon('monologo', get_string('pluginname', $modname), $modname);
$this->content->items[] = '<a href="'.$CFG->wwwroot.'/mod/'.$modname.'/index.php?id='.$course->id.'">'.$icon.$modfullname.'</a>';
}
}
return $this->content;
}
/**
* Returns the role that best describes this blocks contents.
*
* This returns 'navigation' as the blocks contents is a list of links to activities and resources.
*
* @return string 'navigation'
*/
public function get_aria_role() {
return 'navigation';
}
function applicable_formats() {
return array('all' => true, 'mod' => false, 'my' => false, 'admin' => false,
'tag' => false);
}
}
@@ -0,0 +1,46 @@
<?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_activity_modules.
*
* @package block_activity_modules
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_activity_modules\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for block_activity_modules implementing null_provider.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+41
View File
@@ -0,0 +1,41 @@
<?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/>.
/**
* Activity modules block caps.
*
* @package block_activity_modules
* @copyright Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'block/activity_modules:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
);
@@ -0,0 +1,27 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'block_activity_modules', language 'en', branch 'MOODLE_20_STABLE'
*
* @package block_activity_modules
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['activity_modules:addinstance'] = 'Add a new activities block';
$string['pluginname'] = 'Activities';
$string['privacy:metadata'] = 'The Activities block only shows data stored in other locations.';
@@ -0,0 +1,163 @@
@block @block_activity_modules
Feature: Block activity modules
In order to overview activity modules in a course
As a manager
I can add activities block in a course or on the frontpage
Background:
Given I enable "chat" "mod" plugin
And I enable "survey" "mod" plugin
Scenario: Add activities block on the frontpage
Given the following "activities" exist:
| activity | name | intro | course | idnumber |
| assign | Frontpage assignment name | Frontpage assignment description | Acceptance test site | assign0 |
| book | Frontpage book name | Frontpage book description | Acceptance test site | book0 |
| chat | Frontpage chat name | Frontpage chat description | Acceptance test site | chat0 |
| choice | Frontpage choice name | Frontpage choice description | Acceptance test site | choice0 |
| data | Frontpage database name | Frontpage database description | Acceptance test site | data0 |
| feedback | Frontpage feedback name | Frontpage feedback description | Acceptance test site | feedback0 |
| forum | Frontpage forum name | Frontpage forum description | Acceptance test site | forum0 |
| label | Frontpage label name | Frontpage label description | Acceptance test site | label0 |
| lti | Frontpage lti name | Frontpage lti description | Acceptance test site | lti0 |
| page | Frontpage page name | Frontpage page description | Acceptance test site | page0 |
| quiz | Frontpage quiz name | Frontpage quiz description | Acceptance test site | quiz0 |
| resource | Frontpage resource name | Frontpage resource description | Acceptance test site | resource0 |
| imscp | Frontpage imscp name | Frontpage imscp description | Acceptance test site | imscp0 |
| folder | Frontpage folder name | Frontpage folder description | Acceptance test site | folder0 |
| glossary | Frontpage glossary name | Frontpage glossary description | Acceptance test site | glossary0 |
| scorm | Frontpage scorm name | Frontpage scorm description | Acceptance test site | scorm0 |
| lesson | Frontpage lesson name | Frontpage lesson description | Acceptance test site | lesson0 |
| survey | Frontpage survey name | Frontpage survey description | Acceptance test site | survey0 |
| url | Frontpage url name | Frontpage url description | Acceptance test site | url0 |
| wiki | Frontpage wiki name | Frontpage wiki description | Acceptance test site | wiki0 |
| workshop | Frontpage workshop name | Frontpage workshop description | Acceptance test site | workshop0 |
When I log in as "admin"
And I am on site homepage
And I turn editing mode on
And I add the "Activities" block
And I click on "Assignments" "link" in the "Activities" "block"
Then I should see "Frontpage assignment name"
And I am on site homepage
And I click on "Chats" "link" in the "Activities" "block"
And I should see "Frontpage chat name"
And I am on site homepage
And I click on "Choices" "link" in the "Activities" "block"
And I should see "Frontpage choice name"
And I am on site homepage
And I click on "Databases" "link" in the "Activities" "block"
And I should see "Frontpage database name"
And I am on site homepage
And I click on "Feedback" "link" in the "Activities" "block"
And I should see "Frontpage feedback name"
And I am on site homepage
And I click on "Forums" "link" in the "Activities" "block"
And I should see "Frontpage forum name"
And I am on site homepage
And I click on "External tools" "link" in the "Activities" "block"
And I should see "Frontpage lti name"
And I am on site homepage
And I click on "Quizzes" "link" in the "Activities" "block"
And I should see "Frontpage quiz name"
And I am on site homepage
And I click on "Glossaries" "link" in the "Activities" "block"
And I should see "Frontpage glossary name"
And I am on site homepage
And I click on "SCORM packages" "link" in the "Activities" "block"
And I should see "Frontpage scorm name"
And I am on site homepage
And I click on "Lessons" "link" in the "Activities" "block"
And I should see "Frontpage lesson name"
And I am on site homepage
And I click on "Wikis" "link" in the "Activities" "block"
And I should see "Frontpage wiki name"
And I am on site homepage
And I click on "Workshop" "link" in the "Activities" "block"
And I should see "Frontpage workshop name"
And I am on site homepage
And I click on "Resources" "link" in the "Activities" "block"
And I should see "Frontpage book name"
And I should see "Frontpage page name"
And I should see "Frontpage resource name"
And I should see "Frontpage imscp name"
And I should see "Frontpage folder name"
And I should see "Frontpage url name"
Scenario: Add activities block in a course
Given the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| assign | Test assignment name | Test assignment description | C1 | assign1 |
| book | Test book name | Test book description | C1 | book1 |
| chat | Test chat name | Test chat description | C1 | chat1 |
| choice | Test choice name | Test choice description | C1 | choice1 |
| data | Test database name | Test database description | C1 | data1 |
| feedback | Test feedback name | Test feedback description | C1 | feedback1 |
| folder | Test folder name | Test folder description | C1 | folder1 |
| forum | Test forum name | Test forum description | C1 | forum1 |
| glossary | Test glossary name | Test glossary description | C1 | glossary1 |
| imscp | Test imscp name | Test imscp description | C1 | imscp1 |
| label | Test label name | Test label description | C1 | label1 |
| lesson | Test lesson name | Test lesson description | C1 | lesson1 |
| lti | Test lti name | Test lti description | C1 | lti1 |
| page | Test page name | Test page description | C1 | page1 |
| quiz | Test quiz name | Test quiz description | C1 | quiz1 |
| resource | Test resource name | Test resource description | C1 | resource1 |
| scorm | Test scorm name | Test scorm description | C1 | scorm1 |
| survey | Test survey name | Test survey description | C1 | survey1 |
| url | Test url name | Test url description | C1 | url1 |
| wiki | Test wiki name | Test wiki description | C1 | wiki1 |
| workshop | Test workshop name | Test workshop description | C1 | workshop1 |
When I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add the "Activities" block
And I click on "Assignments" "link" in the "Activities" "block"
Then I should see "Test assignment name"
And I am on "Course 1" course homepage
And I click on "Chats" "link" in the "Activities" "block"
And I should see "Test chat name"
And I am on "Course 1" course homepage
And I click on "Choices" "link" in the "Activities" "block"
And I should see "Test choice name"
And I am on "Course 1" course homepage
And I click on "Databases" "link" in the "Activities" "block"
And I should see "Test database name"
And I am on "Course 1" course homepage
And I click on "Feedback" "link" in the "Activities" "block"
And I should see "Test feedback name"
And I am on "Course 1" course homepage
And I click on "Forums" "link" in the "Activities" "block"
And I should see "Test forum name"
And I am on "Course 1" course homepage
And I click on "External tools" "link" in the "Activities" "block"
And I should see "Test lti name"
And I am on "Course 1" course homepage
And I click on "Quizzes" "link" in the "Activities" "block"
And I should see "Test quiz name"
And I am on "Course 1" course homepage
And I click on "Glossaries" "link" in the "Activities" "block"
And I should see "Test glossary name"
And I am on "Course 1" course homepage
And I click on "SCORM packages" "link" in the "Activities" "block"
And I should see "Test scorm name"
And I am on "Course 1" course homepage
And I click on "Lessons" "link" in the "Activities" "block"
And I should see "Test lesson name"
And I am on "Course 1" course homepage
And I click on "Wikis" "link" in the "Activities" "block"
And I should see "Test wiki name"
And I am on "Course 1" course homepage
And I click on "Workshop" "link" in the "Activities" "block"
And I should see "Test workshop name"
And I am on "Course 1" course homepage
And I click on "Resources" "link" in the "Activities" "block"
And I should see "Test book name"
And I should see "Test page name"
And I should see "Test resource name"
And I should see "Test imscp name"
And I should see "Test folder name"
And I should see "Test url name"
+29
View File
@@ -0,0 +1,29 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Version details
*
* @package block_activity_modules
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'block_activity_modules'; // Full name of the plugin (used for diagnostics)
@@ -0,0 +1,115 @@
<?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/>.
/**
* Define all the backup steps that will be used by the backup_block_task
* @package block_activity_results
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @copyright 2015 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Specialised restore task for the activity_results block
* (using execute_after_tasks for recoding of target activity)
*
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class restore_activity_results_block_task extends restore_block_task {
/**
* Define (add) particular settings this activity can have
*/
protected function define_my_settings() {
}
/**
* Define (add) particular steps this activity can have
*/
protected function define_my_steps() {
}
/**
* Define the associated file areas
*/
public function get_fileareas() {
return array(); // No associated fileareas.
}
/**
* Define special handling of configdata.
*/
public function get_configdata_encoded_attributes() {
return array(); // No special handling of configdata.
}
/**
* This function, executed after all the tasks in the plan
* have been executed, will perform the recode of the
* target activity for the block. This must be done here
* and not in normal execution steps because the activity
* can be restored after the block.
*/
public function after_restore() {
global $DB;
// Get the blockid.
$blockid = $this->get_blockid();
if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) {
$config = $this->decode_configdata($configdata);
if (!empty($config->activityparentid)) {
// Get the mapping and replace it in config.
if ($mapping = restore_dbops::get_backup_ids_record($this->get_restoreid(),
$config->activityparent, $config->activityparentid)) {
// Update the parent module id (the id from mdl_quiz etc...)
$config->activityparentid = $mapping->newitemid;
// Get the grade_items record to update the activitygradeitemid.
$info = $DB->get_record('grade_items',
array('iteminstance' => $config->activityparentid, 'itemmodule' => $config->activityparent));
// Update the activitygradeitemid the id from the grade_items table.
$config->activitygradeitemid = $info->id;
// Encode and save the config.
$configdata = base64_encode(serialize($config));
$DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid));
}
}
}
}
/**
* Define the contents in the activity that must be
* processed by the link decoder
*/
public static function define_decode_contents() {
return array();
}
/**
* Define the decoding rules for links belonging
* to the activity to be executed by the link decoder
*/
public static function define_decode_rules() {
return array();
}
}
@@ -0,0 +1,735 @@
<?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/>.
/**
* Classes to enforce the various access rules that can apply to a activity.
*
* @package block_activity_results
* @copyright 2009 Tim Hunt
* @copyright 2015 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/lib/grade/constants.php');
require_once($CFG->dirroot . '/course/lib.php');
define('B_ACTIVITYRESULTS_NAME_FORMAT_FULL', 1);
define('B_ACTIVITYRESULTS_NAME_FORMAT_ID', 2);
define('B_ACTIVITYRESULTS_NAME_FORMAT_ANON', 3);
define('B_ACTIVITYRESULTS_GRADE_FORMAT_PCT', 1);
define('B_ACTIVITYRESULTS_GRADE_FORMAT_FRA', 2);
define('B_ACTIVITYRESULTS_GRADE_FORMAT_ABS', 3);
define('B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE', 4);
/**
* Block activity_results class definition.
*
* This block can be added to a course page or a activity page to display of list of
* the best/worst students/groups in a particular activity.
*
* @package block_activity_results
* @copyright 2009 Tim Hunt
* @copyright 2015 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_activity_results extends block_base {
/**
* Core function used to initialize the block.
*/
public function init() {
$this->title = get_string('pluginname', 'block_activity_results');
}
/**
* Allow the block to have a configuration page
*
* @return boolean
*/
public function has_config() {
return true;
}
/**
* Core function, specifies where the block can be used.
* @return array
*/
public function applicable_formats() {
return array('course-view' => true, 'mod' => true);
}
/**
* If this block belongs to a activity context, then return that activity's id.
* Otherwise, return 0.
* @return stdclass the activity record.
*/
public function get_owning_activity() {
global $DB;
// Set some defaults.
$result = new stdClass();
$result->id = 0;
if (empty($this->instance->parentcontextid)) {
return $result;
}
$parentcontext = context::instance_by_id($this->instance->parentcontextid);
if ($parentcontext->contextlevel != CONTEXT_MODULE) {
return $result;
}
$cm = get_coursemodule_from_id($this->page->cm->modname, $parentcontext->instanceid);
if (!$cm) {
return $result;
}
// Get the grade_items id.
$rec = $DB->get_record('grade_items', array('iteminstance' => $cm->instance, 'itemmodule' => $this->page->cm->modname));
if (!$rec) {
return $result;
}
// See if it is a gradable activity.
if (($rec->gradetype != GRADE_TYPE_VALUE) && ($rec->gradetype != GRADE_TYPE_SCALE)) {
return $result;
}
return $rec;
}
/**
* Used to save the form config data
* @param stdclass $data
* @param bool $nolongerused
*/
public function instance_config_save($data, $nolongerused = false) {
global $DB;
if (empty($data->activitygradeitemid)) {
// Figure out info about parent module.
$info = $this->get_owning_activity();
$data->activitygradeitemid = $info->id;
if ($info->id < 1) {
// No activity was selected.
$info->itemmodule = '';
$info->iteminstance = '';
} else {
$data->activityparent = $info->itemmodule;
$data->activityparentid = $info->iteminstance;
}
} else {
// Lookup info about the parent module (we have the id from mdl_grade_items.
$info = $DB->get_record('grade_items', array('id' => $data->activitygradeitemid));
$data->activityparent = $info->itemmodule;
$data->activityparentid = $info->iteminstance;
}
parent::instance_config_save($data);
}
/**
* Used to generate the content for the block.
* @return string
*/
public function get_content() {
global $USER, $CFG, $DB;
if ($this->content !== null) {
return $this->content;
}
$this->content = new stdClass;
$this->content->text = '';
$this->content->footer = '';
if (empty($this->instance)) {
return $this->content;
}
// We are configured so use the configuration.
if (!empty($this->config->activitygradeitemid)) {
// We are configured.
$activitygradeitemid = $this->config->activitygradeitemid;
// Lookup the module in the grade_items table.
$activity = $DB->get_record('grade_items', array('id' => $activitygradeitemid));
if (empty($activity)) {
// Activity does not exist.
$this->content->text = get_string('error_emptyactivityrecord', 'block_activity_results');
return $this->content;
}
$courseid = $activity->courseid;
$inactivity = false;
} else {
// Not configured.
$activitygradeitemid = 0;
}
// Check to see if we are in the moule we are displaying results for.
if (!empty($this->config->activitygradeitemid)) {
if ($this->get_owning_activity()->id == $this->config->activitygradeitemid) {
$inactivity = true;
} else {
$inactivity = false;
}
}
// Activity ID is missing.
if (empty($activitygradeitemid)) {
$this->content->text = get_string('error_emptyactivityid', 'block_activity_results');
return $this->content;
}
// Check to see if we are configured.
if (empty($this->config->showbest) && empty($this->config->showworst)) {
$this->content->text = get_string('configuredtoshownothing', 'block_activity_results');
return $this->content;
}
// Check to see if it is a supported grade type.
if (empty($activity->gradetype) || ($activity->gradetype != GRADE_TYPE_VALUE && $activity->gradetype != GRADE_TYPE_SCALE)) {
$this->content->text = get_string('error_unsupportedgradetype', 'block_activity_results');
return $this->content;
}
// Get the grades for this activity.
$sql = 'SELECT * FROM {grade_grades}
WHERE itemid = ? AND finalgrade is not NULL
ORDER BY finalgrade, timemodified DESC';
$grades = $DB->get_records_sql($sql, array( $activitygradeitemid));
if (empty($grades) || $activity->hidden) {
// No grades available, The block will hide itself in this case.
return $this->content;
}
// Set up results.
$groupmode = NOGROUPS;
$best = array();
$worst = array();
if (!empty($this->config->nameformat)) {
$nameformat = $this->config->nameformat;
} else {
$nameformat = B_ACTIVITYRESULTS_NAME_FORMAT_FULL;
}
// Get $cm and context.
if ($inactivity) {
$cm = $this->page->cm;
$context = $this->page->context;
} else {
$cm = get_coursemodule_from_instance($activity->itemmodule, $activity->iteminstance, $courseid);
$context = context_module::instance($cm->id);
}
if (!empty($this->config->usegroups)) {
$groupmode = groups_get_activity_groupmode($cm);
if ($groupmode == SEPARATEGROUPS && has_capability('moodle/site:accessallgroups', $context)) {
// If you have the ability to see all groups then lets show them.
$groupmode = VISIBLEGROUPS;
}
}
switch ($groupmode) {
case VISIBLEGROUPS:
// Display group-mode results.
$groups = groups_get_all_groups($courseid);
if (empty($groups)) {
// No groups exist, sorry.
$this->content->text = get_string('error_nogroupsexist', 'block_activity_results');
return $this->content;
}
// Find out all the userids which have a submitted grade.
$userids = array();
$gradeforuser = array();
foreach ($grades as $grade) {
$userids[] = $grade->userid;
$gradeforuser[$grade->userid] = (float)$grade->finalgrade;
}
// Now find which groups these users belong in.
list($usertest, $params) = $DB->get_in_or_equal($userids);
$params[] = $courseid;
$usergroups = $DB->get_records_sql('
SELECT gm.id, gm.userid, gm.groupid, g.name
FROM {groups} g
LEFT JOIN {groups_members} gm ON g.id = gm.groupid
WHERE gm.userid ' . $usertest . ' AND g.courseid = ?', $params);
// Now, iterate the grades again and sum them up for each group.
$groupgrades = array();
foreach ($usergroups as $usergroup) {
if (!isset($groupgrades[$usergroup->groupid])) {
$groupgrades[$usergroup->groupid] = array(
'sum' => (float)$gradeforuser[$usergroup->userid],
'number' => 1,
'group' => $usergroup->name);
} else {
$groupgrades[$usergroup->groupid]['sum'] += $gradeforuser[$usergroup->userid];
$groupgrades[$usergroup->groupid]['number'] += 1;
}
}
foreach ($groupgrades as $groupid => $groupgrade) {
$groupgrades[$groupid]['average'] = $groupgrades[$groupid]['sum'] / $groupgrades[$groupid]['number'];
}
// Sort groupgrades according to average grade, ascending.
uasort($groupgrades, function($a, $b) {
if ($a["average"] == $b["average"]) {
return 0;
}
return ($a["average"] > $b["average"] ? 1 : -1);
});
// How many groups do we have with graded member submissions to show?
$numbest = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($groupgrades));
$numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($groupgrades) - $numbest);
// Collect all the group results we are going to use in $best and $worst.
$remaining = $numbest;
$groupgrade = end($groupgrades);
while ($remaining--) {
$best[key($groupgrades)] = $groupgrade['average'];
$groupgrade = prev($groupgrades);
}
$remaining = $numworst;
$groupgrade = reset($groupgrades);
while ($remaining--) {
$worst[key($groupgrades)] = $groupgrade['average'];
$groupgrade = next($groupgrades);
}
// Ready for output!
if ($activity->gradetype == GRADE_TYPE_SCALE) {
// We must display the results using scales.
$gradeformat = B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE;
// Preload the scale.
$scale = $this->get_scale($activity->scaleid);
} else if (intval(empty($this->config->gradeformat))) {
$gradeformat = B_ACTIVITYRESULTS_GRADE_FORMAT_PCT;
} else {
$gradeformat = $this->config->gradeformat;
}
// Generate the header.
$this->content->text .= $this->activity_link($activity, $cm);
if ($nameformat == B_ACTIVITYRESULTS_NAME_FORMAT_FULL) {
if (has_capability('moodle/course:managegroups', $context)) {
$grouplink = $CFG->wwwroot.'/group/overview.php?id='.$courseid.'&amp;group=';
} else if (course_can_view_participants($context)) {
$grouplink = $CFG->wwwroot.'/user/index.php?id='.$courseid.'&amp;group=';
} else {
$grouplink = '';
}
}
$rank = 0;
if (!empty($best)) {
$this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
if ($numbest == 1) {
$this->content->text .= get_string('bestgroupgrade', 'block_activity_results');
} else {
$this->content->text .= get_string('bestgroupgrades', 'block_activity_results', $numbest);
}
$this->content->text .= '</h6></caption><colgroup class="number" />';
$this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
foreach ($best as $groupid => $averagegrade) {
switch ($nameformat) {
case B_ACTIVITYRESULTS_NAME_FORMAT_ANON:
case B_ACTIVITYRESULTS_NAME_FORMAT_ID:
$thisname = get_string('group');
break;
default:
case B_ACTIVITYRESULTS_NAME_FORMAT_FULL:
if ($grouplink) {
$thisname = '<a href="'.$grouplink.$groupid.'">'.$groupgrades[$groupid]['group'].'</a>';
} else {
$thisname = $groupgrades[$groupid]['group'];
}
break;
}
$this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
switch ($gradeformat) {
case B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE:
// Round answer up and locate appropriate scale.
$answer = (round($averagegrade, 0, PHP_ROUND_HALF_UP) - 1);
if (isset($scale[$answer])) {
$this->content->text .= $scale[$answer];
} else {
// Value is not in the scale.
$this->content->text .= get_string('unknown', 'block_activity_results');
}
break;
case B_ACTIVITYRESULTS_GRADE_FORMAT_FRA:
$this->content->text .= $this->activity_format_grade($averagegrade)
. '/' . $this->activity_format_grade($activity->grademax);
break;
case B_ACTIVITYRESULTS_GRADE_FORMAT_ABS:
$this->content->text .= $this->activity_format_grade($averagegrade);
break;
default:
case B_ACTIVITYRESULTS_GRADE_FORMAT_PCT:
$this->content->text .= $this->activity_format_grade((float)$averagegrade /
(float)$activity->grademax * 100).'%';
break;
}
$this->content->text .= '</td></tr>';
}
$this->content->text .= '</tbody></table>';
}
$rank = 0;
if (!empty($worst)) {
$worst = array_reverse($worst, true);
$this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
if ($numworst == 1) {
$this->content->text .= get_string('worstgroupgrade', 'block_activity_results');
} else {
$this->content->text .= get_string('worstgroupgrades', 'block_activity_results', $numworst);
}
$this->content->text .= '</h6></caption><colgroup class="number" />';
$this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
foreach ($worst as $groupid => $averagegrade) {
switch ($nameformat) {
case B_ACTIVITYRESULTS_NAME_FORMAT_ANON:
case B_ACTIVITYRESULTS_NAME_FORMAT_ID:
$thisname = get_string('group');
break;
default:
case B_ACTIVITYRESULTS_NAME_FORMAT_FULL:
if ($grouplink) {
$thisname = '<a href="'.$grouplink.$groupid.'">'.$groupgrades[$groupid]['group'].'</a>';
} else {
$thisname = $groupgrades[$groupid]['group'];
}
break;
}
$this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
switch ($gradeformat) {
case B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE:
// Round answer up and locate appropriate scale.
$answer = (round($averagegrade, 0, PHP_ROUND_HALF_UP) - 1);
if (isset($scale[$answer])) {
$this->content->text .= $scale[$answer];
} else {
// Value is not in the scale.
$this->content->text .= get_string('unknown', 'block_activity_results');
}
break;
case B_ACTIVITYRESULTS_GRADE_FORMAT_FRA:
$this->content->text .= $this->activity_format_grade($averagegrade)
. '/' . $this->activity_format_grade($activity->grademax);
break;
case B_ACTIVITYRESULTS_GRADE_FORMAT_ABS:
$this->content->text .= $this->activity_format_grade($averagegrade);
break;
default:
case B_ACTIVITYRESULTS_GRADE_FORMAT_PCT:
$this->content->text .= $this->activity_format_grade((float)$averagegrade /
(float)$activity->grademax * 100).'%';
break;
}
$this->content->text .= '</td></tr>';
}
$this->content->text .= '</tbody></table>';
}
break;
case SEPARATEGROUPS:
// This is going to be just like no-groups mode, only we 'll filter
// out the grades from people not in our group.
if (!isloggedin()) {
// Not logged in, so show nothing.
return $this->content;
}
$mygroups = groups_get_all_groups($courseid, $USER->id);
if (empty($mygroups)) {
// Not member of a group, show nothing.
return $this->content;
}
// Get users from the same groups as me.
list($grouptest, $params) = $DB->get_in_or_equal(array_keys($mygroups));
$mygroupsusers = $DB->get_records_sql_menu(
'SELECT DISTINCT userid, 1 FROM {groups_members} WHERE groupid ' . $grouptest,
$params);
// Filter out the grades belonging to other users, and proceed as if there were no groups.
foreach ($grades as $key => $grade) {
if (!isset($mygroupsusers[$grade->userid])) {
unset($grades[$key]);
}
}
// No break, fall through to the default case now we have filtered the $grades array.
default:
case NOGROUPS:
// Single user mode.
$numbest = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($grades));
$numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($grades) - $numbest);
// Collect all the usernames we are going to need.
$remaining = $numbest;
$grade = end($grades);
while ($remaining--) {
$best[$grade->userid] = $grade->id;
$grade = prev($grades);
}
$remaining = $numworst;
$grade = reset($grades);
while ($remaining--) {
$worst[$grade->userid] = $grade->id;
$grade = next($grades);
}
if (empty($best) && empty($worst)) {
// Nothing to show, for some reason...
return $this->content;
}
// Now grab all the users from the database.
$userids = array_merge(array_keys($best), array_keys($worst));
$fields = array_merge(array('id', 'idnumber'), \core_user\fields::get_name_fields());
$fields = implode(',', $fields);
$users = $DB->get_records_list('user', 'id', $userids, '', $fields);
// If configured to view user idnumber, ensure current user can see it.
$extrafields = \core_user\fields::for_identity($this->context)->get_required_fields();
$canviewidnumber = (array_search('idnumber', $extrafields) !== false);
// Ready for output!
if ($activity->gradetype == GRADE_TYPE_SCALE) {
// We must display the results using scales.
$gradeformat = B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE;
// Preload the scale.
$scale = $this->get_scale($activity->scaleid);
} else if (intval(empty($this->config->gradeformat))) {
$gradeformat = B_ACTIVITYRESULTS_GRADE_FORMAT_PCT;
} else {
$gradeformat = $this->config->gradeformat;
}
// Generate the header.
$this->content->text .= $this->activity_link($activity, $cm);
$rank = 0;
if (!empty($best)) {
$this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
if ($numbest == 1) {
$this->content->text .= get_string('bestgrade', 'block_activity_results');
} else {
$this->content->text .= get_string('bestgrades', 'block_activity_results', $numbest);
}
$this->content->text .= '</h6></caption><colgroup class="number" />';
$this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
foreach ($best as $userid => $gradeid) {
switch ($nameformat) {
case B_ACTIVITYRESULTS_NAME_FORMAT_ID:
$thisname = get_string('user');
if ($canviewidnumber) {
$thisname .= ' ' . s($users[$userid]->idnumber);
}
break;
case B_ACTIVITYRESULTS_NAME_FORMAT_ANON:
$thisname = get_string('user');
break;
default:
case B_ACTIVITYRESULTS_NAME_FORMAT_FULL:
if (has_capability('moodle/user:viewdetails', $context)) {
$thisname = html_writer::link(new moodle_url('/user/view.php',
array('id' => $userid, 'course' => $courseid)), fullname($users[$userid]));
} else {
$thisname = fullname($users[$userid]);
}
break;
}
$this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
switch ($gradeformat) {
case B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE:
// Round answer up and locate appropriate scale.
$answer = (round($grades[$gradeid]->finalgrade, 0, PHP_ROUND_HALF_UP) - 1);
if (isset($scale[$answer])) {
$this->content->text .= $scale[$answer];
} else {
// Value is not in the scale.
$this->content->text .= get_string('unknown', 'block_activity_results');
}
break;
case B_ACTIVITYRESULTS_GRADE_FORMAT_FRA:
$this->content->text .= $this->activity_format_grade($grades[$gradeid]->finalgrade);
$this->content->text .= '/'.$this->activity_format_grade($activity->grademax);
break;
case B_ACTIVITYRESULTS_GRADE_FORMAT_ABS:
$this->content->text .= $this->activity_format_grade($grades[$gradeid]->finalgrade);
break;
default:
case B_ACTIVITYRESULTS_GRADE_FORMAT_PCT:
if ($activity->grademax) {
$this->content->text .= $this->activity_format_grade((float)$grades[$gradeid]->finalgrade /
(float)$activity->grademax * 100).'%';
} else {
$this->content->text .= '--%';
}
break;
}
$this->content->text .= '</td></tr>';
}
$this->content->text .= '</tbody></table>';
}
$rank = 0;
if (!empty($worst)) {
$worst = array_reverse($worst, true);
$this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
if ($numbest == 1) {
$this->content->text .= get_string('worstgrade', 'block_activity_results');
} else {
$this->content->text .= get_string('worstgrades', 'block_activity_results', $numworst);
}
$this->content->text .= '</h6></caption><colgroup class="number" />';
$this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
foreach ($worst as $userid => $gradeid) {
switch ($nameformat) {
case B_ACTIVITYRESULTS_NAME_FORMAT_ID:
$thisname = get_string('user');
if ($canviewidnumber) {
$thisname .= ' ' . s($users[$userid]->idnumber);
};
break;
case B_ACTIVITYRESULTS_NAME_FORMAT_ANON:
$thisname = get_string('user');
break;
default:
case B_ACTIVITYRESULTS_NAME_FORMAT_FULL:
if (has_capability('moodle/user:viewdetails', $context)) {
$thisname = html_writer::link(new moodle_url('/user/view.php',
array('id' => $userid, 'course' => $courseid)), fullname($users[$userid]));
} else {
$thisname = fullname($users[$userid]);
}
break;
}
$this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
switch ($gradeformat) {
case B_ACTIVITYRESULTS_GRADE_FORMAT_SCALE:
// Round answer up and locate appropriate scale.
$answer = (round($grades[$gradeid]->finalgrade, 0, PHP_ROUND_HALF_UP) - 1);
if (isset($scale[$answer])) {
$this->content->text .= $scale[$answer];
} else {
// Value is not in the scale.
$this->content->text .= get_string('unknown', 'block_activity_results');
}
break;
case B_ACTIVITYRESULTS_GRADE_FORMAT_FRA:
$this->content->text .= $this->activity_format_grade($grades[$gradeid]->finalgrade);
$this->content->text .= '/'.$this->activity_format_grade($activity->grademax);
break;
case B_ACTIVITYRESULTS_GRADE_FORMAT_ABS:
$this->content->text .= $this->activity_format_grade($grades[$gradeid]->finalgrade);
break;
default:
case B_ACTIVITYRESULTS_GRADE_FORMAT_PCT:
if ($activity->grademax) {
$this->content->text .= $this->activity_format_grade((float)$grades[$gradeid]->finalgrade /
(float)$activity->grademax * 100).'%';
} else {
$this->content->text .= '--%';
}
break;
}
$this->content->text .= '</td></tr>';
}
$this->content->text .= '</tbody></table>';
}
break;
}
return $this->content;
}
/**
* Allows the block to be added multiple times to a single page
* @return boolean
*/
public function instance_allow_multiple() {
return true;
}
/**
* Formats the grade to the specified decimal points
* @param float $grade
* @return string
*/
private function activity_format_grade($grade) {
if (is_null($grade)) {
return get_string('notyetgraded', 'block_activity_results');
}
return format_float($grade, $this->config->decimalpoints);
}
/**
* Generates the Link to the activity module when displayed outside of the module.
* @param stdclass $activity
* @param stdclass $cm
* @return string
*/
private function activity_link($activity, $cm) {
$o = html_writer::start_tag('h5');
$o .= html_writer::link(new moodle_url('/mod/'.$activity->itemmodule.'/view.php',
array('id' => $cm->id)), format_string(($activity->itemname), true, ['context' => context_module::instance($cm->id)]));
$o .= html_writer::end_tag('h5');
return $o;
}
/**
* Generates a numeric array of scale entries
* @param int $scaleid
* @return array
*/
private function get_scale($scaleid) {
global $DB;
$scaletext = $DB->get_field('scale', 'scale', array('id' => $scaleid), IGNORE_MISSING);
$scale = explode ( ',', $scaletext);
return $scale;
}
/**
* Return the plugin config settings for external functions.
*
* @return stdClass the configs for both the block instance and plugin
* @since Moodle 3.8
*/
public function get_config_for_external() {
// Return all settings for all users since it is safe (no private keys, etc..).
$instanceconfigs = !empty($this->config) ? $this->config : new stdClass();
$pluginconfigs = get_config('block_activity_results');
return (object) [
'instance' => $instanceconfigs,
'plugin' => $pluginconfigs,
];
}
}
@@ -0,0 +1,46 @@
<?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_activity_results.
*
* @package block_activity_results
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_activity_results\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for block_activity_results implementing null_provider.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+41
View File
@@ -0,0 +1,41 @@
<?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/>.
/**
* Activity results block caps.
*
* @package block_activity_results
* @copyright 2015 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'block/activity_results:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
);
+136
View File
@@ -0,0 +1,136 @@
<?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/>.
/**
* Defines the form for editing Quiz results block instances.
*
* @package block_activity_results
* @copyright 2009 Tim Hunt
* @copyright 2015 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/lib/grade/constants.php');
/**
* Form for editing activity results block instances.
*
* @copyright 2009 Tim Hunt
* @copyright 2015 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_activity_results_edit_form extends block_edit_form {
/**
* The definition of the fields to use.
*
* @param MoodleQuickForm $mform
*/
protected function specific_definition($mform) {
global $DB;
// Load defaults.
$blockconfig = get_config('block_activity_results');
// Fields for editing activity_results block title and contents.
$mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
// Get supported modules (Only modules using grades or scales will be listed).
$sql = 'SELECT id, itemname FROM {grade_items} WHERE courseid = ? and itemtype = ? and (gradetype = ? or gradetype = ?)';
$params = array($this->page->course->id, 'mod', GRADE_TYPE_VALUE, GRADE_TYPE_SCALE);
$activities = $DB->get_records_sql_menu($sql, $params);
core_collator::asort($activities);
if (empty($activities)) {
$mform->addElement('static', 'noactivitieswarning', get_string('config_select_activity', 'block_activity_results'),
get_string('config_no_activities_in_course', 'block_activity_results'));
} else {
foreach ($activities as $id => $name) {
$activities[$id] = strip_tags(format_string($name));
}
$mform->addElement('select', 'config_activitygradeitemid',
get_string('config_select_activity', 'block_activity_results'), $activities);
$mform->setDefault('config_activitygradeitemid', $this->block->get_owning_activity()->id);
}
$mform->addElement('text', 'config_showbest',
get_string('config_show_best', 'block_activity_results'), array('size' => 3));
$mform->setDefault('config_showbest', $blockconfig->config_showbest);
$mform->setType('config_showbest', PARAM_INT);
if ($blockconfig->config_showbest_locked) {
$mform->freeze('config_showbest');
}
$mform->addElement('text', 'config_showworst',
get_string('config_show_worst', 'block_activity_results'), array('size' => 3));
$mform->setDefault('config_showworst', $blockconfig->config_showworst);
$mform->setType('config_showworst', PARAM_INT);
if ($blockconfig->config_showworst_locked) {
$mform->freeze('config_showworst');
}
$mform->addElement('selectyesno', 'config_usegroups', get_string('config_use_groups', 'block_activity_results'));
$mform->setDefault('config_usegroups', $blockconfig->config_usegroups);
if ($blockconfig->config_usegroups_locked) {
$mform->freeze('config_usegroups');
}
$nameoptions = array(
B_ACTIVITYRESULTS_NAME_FORMAT_FULL => get_string('config_names_full', 'block_activity_results'),
B_ACTIVITYRESULTS_NAME_FORMAT_ID => get_string('config_names_id', 'block_activity_results'),
B_ACTIVITYRESULTS_NAME_FORMAT_ANON => get_string('config_names_anon', 'block_activity_results')
);
$mform->addElement('select', 'config_nameformat',
get_string('config_name_format', 'block_activity_results'), $nameoptions);
$mform->setDefault('config_nameformat', $blockconfig->config_nameformat);
if ($blockconfig->config_nameformat_locked) {
$mform->freeze('config_nameformat');
}
$gradeeoptions = array(
B_ACTIVITYRESULTS_GRADE_FORMAT_PCT => get_string('config_format_percentage', 'block_activity_results'),
B_ACTIVITYRESULTS_GRADE_FORMAT_FRA => get_string('config_format_fraction', 'block_activity_results'),
B_ACTIVITYRESULTS_GRADE_FORMAT_ABS => get_string('config_format_absolute', 'block_activity_results')
);
$mform->addElement('select', 'config_gradeformat',
get_string('config_grade_format', 'block_activity_results'), $gradeeoptions);
$mform->setDefault('config_gradeformat', $blockconfig->config_gradeformat);
if ($blockconfig->config_gradeformat_locked) {
$mform->freeze('config_gradeformat');
}
$options = array();
for ($i = 0; $i <= 5; $i++) {
$options[$i] = $i;
}
$mform->addElement('select', 'config_decimalpoints', get_string('config_decimalplaces', 'block_activity_results'),
$options);
$mform->setDefault('config_decimalpoints', $blockconfig->config_decimalpoints);
$mform->setType('config_decimalpoints', PARAM_INT);
if ($blockconfig->config_decimalpoints_locked) {
$mform->freeze('config_decimalpoints');
}
}
/**
* Display the configuration form when block is being added to the page
*
* @return bool
*/
public static function display_form_when_adding(): bool {
return true;
}
}
@@ -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/>.
/**
* Strings for component 'block_activity_results', language 'en', branch 'MOODLE_20_STABLE'
*
* @package block_activity_results
* @copyright 2015 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['activity_results:addinstance'] = 'Add a new activity results block';
$string['bestgrade'] = 'The highest grade:';
$string['bestgrades'] = 'The {$a} highest grades:';
$string['bestgroupgrade'] = 'The group with the highest average:';
$string['bestgroupgrades'] = 'The {$a} groups with the highest average:';
$string['config_format_absolute'] = 'Absolute numbers';
$string['config_format_fraction'] = 'Fractions';
$string['config_format_percentage'] = 'Percentages';
$string['config_decimalplaces'] = 'Decimal places to display';
$string['config_grade_format'] = 'Display grades as';
$string['config_name_format'] = 'Privacy of results';
$string['config_names_anon'] = 'Anonymous results';
$string['config_names_full'] = 'Display full names';
$string['config_names_id'] = 'Display only ID numbers';
$string['config_no_activities_in_course'] = 'There are not yet any activities in this course.';
$string['config_select_activity'] = 'Which activity should this block display results from?';
$string['config_show_best'] = 'How many of the highest grades should be shown (0 to disable)?';
$string['config_show_worst'] = 'How many of the lowest grades should be shown (0 to disable)?';
$string['configuredtoshownothing'] = 'This block\'s configuration currently does not allow it to show any results.';
$string['config_use_groups'] = 'Show groups instead of students (only if the activity supports groups)?';
$string['defaulthighestgrades'] = 'Default highest grades shown';
$string['defaulthighestgrades_desc'] = 'How many of the highest grades should be shown by default?';
$string['defaultlowestgrades'] = 'Default lowest grades shown';
$string['defaultlowestgrades_desc'] = 'How many of the lowest grades should be shown by default?';
$string['defaultshowgroups'] = 'Default show groups';
$string['defaultnameoptions'] = 'Privacy of results';
$string['defaultnameoptions_desc'] = 'How should the students be identified by default?';
$string['defaultshowgroups_desc'] = 'Show groups instead of students by default (only if the activity supports groups)';
$string['defaultgradedisplay'] = 'Display grades as';
$string['defaultgradedisplay_desc'] = 'How should the grades be displayed by default?';
$string['defaultdecimalplaces'] = 'Decimal places';
$string['defaultdecimalplaces_desc'] = 'Number of decimal places to display by default';
$string['error_emptyactivityid'] = 'Please configure this block and select which activity it should display results from.';
$string['error_emptyactivityrecord'] = 'Error: the selected activity does not exist in the database.';
$string['error_nogroupsexist'] = 'Error: the block is set to display grades in group mode, but there are no groups defined.';
$string['error_unsupportedgradetype'] = 'Error: the activity selected uses a grading method that is not supported by this block.';
$string['notyetgraded'] = 'Not yet graded';
$string['pluginname'] = 'Activity results';
$string['unknown'] = 'Unknown scale';
$string['worstgrade'] = 'The lowest grade:';
$string['worstgrades'] = 'The {$a} lowest grades:';
$string['worstgroupgrade'] = 'The group with the lowest average:';
$string['worstgroupgrades'] = 'The {$a} groups with the lowest average:';
$string['privacy:metadata'] = 'The Activity results block only shows data stored in other locations.';
+86
View File
@@ -0,0 +1,86 @@
<?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/>.
/**
* Defines the form for editing activity results block instances.
*
* @package block_activity_results
* @copyright 2016 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($ADMIN->fulltree) {
// Default high scores.
$setting = new admin_setting_configtext('block_activity_results/config_showbest',
new lang_string('defaulthighestgrades', 'block_activity_results'),
new lang_string('defaulthighestgrades_desc', 'block_activity_results'), 3, PARAM_INT);
$setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
$settings->add($setting);
// Default low scores.
$setting = new admin_setting_configtext('block_activity_results/config_showworst',
new lang_string('defaultlowestgrades', 'block_activity_results'),
new lang_string('defaultlowestgrades_desc', 'block_activity_results'), 0, PARAM_INT);
$setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
$settings->add($setting);
// Default group display.
$yesno = array(0 => get_string('no'), 1 => get_string('yes'));
$setting = new admin_setting_configselect('block_activity_results/config_usegroups',
new lang_string('defaultshowgroups', 'block_activity_results'),
new lang_string('defaultshowgroups_desc', 'block_activity_results'), 0, $yesno);
$setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
$settings->add($setting);
// Default privacy settings.
$nameoptions = array(
B_ACTIVITYRESULTS_NAME_FORMAT_FULL => get_string('config_names_full', 'block_activity_results'),
B_ACTIVITYRESULTS_NAME_FORMAT_ID => get_string('config_names_id', 'block_activity_results'),
B_ACTIVITYRESULTS_NAME_FORMAT_ANON => get_string('config_names_anon', 'block_activity_results')
);
$setting = new admin_setting_configselect('block_activity_results/config_nameformat',
new lang_string('defaultnameoptions', 'block_activity_results'),
new lang_string('defaultnameoptions_desc', 'block_activity_results'), B_ACTIVITYRESULTS_NAME_FORMAT_FULL, $nameoptions);
$setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
$settings->add($setting);
// Default grade display settings.
$gradeoptions = array(
B_ACTIVITYRESULTS_GRADE_FORMAT_PCT => get_string('config_format_percentage', 'block_activity_results'),
B_ACTIVITYRESULTS_GRADE_FORMAT_FRA => get_string('config_format_fraction', 'block_activity_results'),
B_ACTIVITYRESULTS_GRADE_FORMAT_ABS => get_string('config_format_absolute', 'block_activity_results')
);
$setting = new admin_setting_configselect('block_activity_results/config_gradeformat',
new lang_string('defaultgradedisplay', 'block_activity_results'),
new lang_string('defaultgradedisplay_desc', 'block_activity_results'), B_ACTIVITYRESULTS_GRADE_FORMAT_PCT, $gradeoptions);
$setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
$settings->add($setting);
// Default decimal places.
$places = array();
for ($i = 0; $i <= 5; $i++) {
$places[$i] = $i;
}
$setting = new admin_setting_configselect('block_activity_results/config_decimalpoints',
new lang_string('defaultdecimalplaces', 'block_activity_results'),
new lang_string('defaultdecimalplaces_desc', 'block_activity_results'), 2, $places);
$setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
$settings->add($setting);
}
+23
View File
@@ -0,0 +1,23 @@
.block_activity_results h1 {
margin: 4px;
font-size: 1.1em;
}
.block_activity_results table.grades {
text-align: left;
width: 100%;
}
.block_activity_results table.grades .number {
text-align: left;
width: 10%;
}
.block_activity_results table.grades .name {
text-align: left;
width: 77%;
}
.block_activity_results table.grades .grade {
text-align: right;
}
@@ -0,0 +1,80 @@
@block @block_activity_results @javascript
Feature: The activity results block displays student scores
In order to be display student scores
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | section | idnumber | assignsubmission_file_enabled |
| assign | Test assignment 1 | Offline text | C1 | 1 | assign1 | 0 |
| assign | Test assignment 2 | Offline text | C1 | 1 | assign2 | 0 |
| assign | Test assignment 3 | Offline text | C1 | 1 | assign3 | 0 |
And the following "activities" exist:
| activity | name | content | course | section | idnumber |
| page | Test page name | This is a page | C1 | 1 | page1 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment 1 | student1 | 90.00 |
| Test assignment 1 | student2 | 80.00 |
| Test assignment 1 | student3 | 70.00 |
| Test assignment 1 | student4 | 60.00 |
| Test assignment 1 | student5 | 50.00 |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Scenario: Configure the block on a non-graded activity to show 3 high scores
Given I am on the "Test page name" "page activity" page
And I add the "Activity results" block to the default region with:
| config_activitygradeitemid | Test assignment 1 |
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
Then I should see "Student 1" in the "Activity results" "block"
And I should see "90.00" in the "Activity results" "block"
And I should see "Student 2" in the "Activity results" "block"
And I should see "80.00" in the "Activity results" "block"
And I should see "Student 3" in the "Activity results" "block"
And I should see "70.00" in the "Activity results" "block"
@javascript @addablocklink
Scenario: Block should select current activity by default
Given I click on "Test assignment 1" "link" in the "region-main" "region"
When I add the "Activity results..." block
Then the field "config_activitygradeitemid" in the "Add Activity results block" "dialogue" matches value "Test assignment 1"
And I click on "Save changes" "button" in the "Add Activity results block" "dialogue"
And I am on "Course 1" course homepage
And I click on "Test assignment 2" "link" in the "region-main" "region"
And I add the "Activity results..." block
And the field "config_activitygradeitemid" in the "Add Activity results block" "dialogue" matches value "Test assignment 2"
And I click on "Save changes" "button" in the "Add Activity results block" "dialogue"
And I am on "Course 1" course homepage
And I click on "Test assignment 3" "link" in the "region-main" "region"
And I add the "Activity results..." block
And the field "config_activitygradeitemid" in the "Add Activity results block" "dialogue" matches value "Test assignment 3"
And I click on "Save changes" "button" in the "Add Activity results block" "dialogue"
And I am on "Course 1" course homepage
And I click on "Test page name" "link" in the "region-main" "region"
And I add the "Activity results..." block
And the field "config_activitygradeitemid" in the "Add Activity results block" "dialogue" does not match value "Test page name"
And I click on "Save changes" "button" in the "Add Activity results block" "dialogue"
@@ -0,0 +1,51 @@
@block @block_activity_results
Feature: The activity results block doesn't displays student scores for unconfigured block
In order to be display student scores
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Scenario: Add the block to a the course with Javascript disabled
Given I add the "Activity results" block
Then I should see "Please configure this block and select which activity it should display results from." in the "Activity results" "block"
@javascript
Scenario: Add the block to a the course with Javascript enabled
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
Then I should see "Please configure this block and select which activity it should display results from." in the "Activity results" "block"
Scenario: Try to configure the block on the course page in a course without activities
Given I add the "Activity results" block
When I configure the "Activity results" block
And I should see "There are not yet any activities in this course."
And I press "Save changes"
Then I should see "Please configure this block and select which activity it should display results from." in the "Activity results" "block"
Scenario: Try to configure the block on a resource page in a course without activities
Given the following "activity" exists:
| activity | page |
| course | C1 |
| idnumber | 0001 |
| name | Test page name |
| intro | Test page description |
| section | 1 |
| content | This is a page |
And I am on "Course 1" course homepage
When I add the "Activity results" block
And I configure the "Activity results" block
And I should see "There are not yet any activities in this course."
And I press "Save changes"
Then I should see "Please configure this block and select which activity it should display results from." in the "Activity results" "block"
@@ -0,0 +1,39 @@
@block @block_activity_results
Feature: The activity results block doesn't display student scores for unsupported activity
In order to be display student scores
As a user
I need to properly configure the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Scenario: Try to configure the block to use an activity without grades
Given the following "activities" exist:
| activity | name | intro | course | section | idnumber | assignsubmission_file_enabled |
| assign | Test assignment | Offline text | C1 | 1 | assign1 | 0 |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| activity_results | Course | C1 | course-view-* | side-pre |
And I am on "Course 1" course homepage
And I configure the "Activity results" block
And I set the following fields to these values:
| config_showbest | 1 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
And I press "Save changes"
When I am on the "Test assignment" "assign activity editing" page
And I set the following fields to these values:
| id_grade_modgrade_type | None |
And I press "Save and return to course"
Then I should see "Error: the activity selected uses a grading method that is not supported by this block." in the "Activity results" "block"
@@ -0,0 +1,62 @@
@block @block_activity_results
Feature: The activity results block can have administrator set defaults
In order to be customize the activity results block
As an admin
I need can assign some site wide defaults
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| idnumber | 0001 |
| name | Test assignment |
| assignsubmission_file_enabled | 0 |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Scenario: Assign some site-wide defaults to the block.
Given the following config values are set as admin:
| config_showbest | 0 | block_activity_results |
| config_showworst | 0 | block_activity_results |
| config_gradeformat | 2 | block_activity_results |
| config_nameformat | 2 | block_activity_results |
And I am on "Course 1" course homepage
And I add the "Activity results" block
When I configure the "Activity results" block
And the following fields match these values:
| config_showbest | 0 |
| config_showworst | 0 |
| config_gradeformat | Fractions |
| config_nameformat | Display only ID numbers |
And I press "Save changes"
Then I should see "This block's configuration currently does not allow it to show any results." in the "Activity results" "block"
Scenario: Assign some site-wide defaults to the block and lock them.
Given the following config values are set as admin:
| config_showbest | 0 | block_activity_results |
| config_showbest_locked | 1 | block_activity_results |
| config_showworst | 0 | block_activity_results |
| config_showworst_locked | 1 | block_activity_results |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| activity_results | Course | C1 | course-view-* | side-pre |
And I am on "Course 1" course homepage
When I configure the "Activity results" block
And the following fields match these values:
| config_showbest | 0 |
| config_showworst | 0 |
And the "config_showbest" "field" should be readonly
And the "config_showworst" "field" should be readonly
And I press "Save changes"
Then I should see "This block's configuration currently does not allow it to show any results." in the "Activity results" "block"
@@ -0,0 +1,140 @@
@block @block_activity_results @javascript
Feature: The activity results block displays student high scores
In order to be display student scores
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | section | idnumber | assignsubmission_file_enabled |
| assign | Test assignment | Offline text | C1 | 1 | assign1 | 0 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment | student1 | 90.00 |
| Test assignment | student2 | 80.00 |
| Test assignment | student3 | 70.00 |
| Test assignment | student4 | 60.00 |
| Test assignment | student5 | 50.00 |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Scenario: Configure the block on the course page to show 0 high scores
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
Then I should see "This block's configuration currently does not allow it to show any results." in the "Activity results" "block"
Scenario: Configure the block on the course page to show 1 high score
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
Then I should see "Student 1" in the "Activity results" "block"
And I should see "90%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 high score as a fraction
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
Then I should see "Student 1" in the "Activity results" "block"
And I should see "90.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 high score as a absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
Then I should see "Student 1" in the "Activity results" "block"
And I should see "90.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores as percentages
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
Then I should see "Student 1" in the "Activity results" "block"
And I should see "90%" in the "Activity results" "block"
And I should see "Student 2" in the "Activity results" "block"
And I should see "80%" in the "Activity results" "block"
And I should see "Student 3" in the "Activity results" "block"
And I should see "70%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores as fractions
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
Then I should see "Student 1" in the "Activity results" "block"
And I should see "90.00/100.00" in the "Activity results" "block"
And I should see "Student 2" in the "Activity results" "block"
And I should see "80.00/100.00" in the "Activity results" "block"
And I should see "Student 3" in the "Activity results" "block"
And I should see "70.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores as absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
Then I should see "Student 1" in the "Activity results" "block"
And I should see "90.00" in the "Activity results" "block"
And I should see "Student 2" in the "Activity results" "block"
And I should see "80.00" in the "Activity results" "block"
And I should see "Student 3" in the "Activity results" "block"
And I should see "70.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
Given the following config values are set as admin:
| showuseridentity | idnumber,email |
And I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display only ID numbers |
Then I should see "User S1" in the "Activity results" "block"
And I should see "90.00%" in the "Activity results" "block"
And I should see "User S2" in the "Activity results" "block"
And I should see "80.00%" in the "Activity results" "block"
And I should see "User S3" in the "Activity results" "block"
And I should see "70.00%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Anonymous results |
Then I should see "User" in the "Activity results" "block"
And I should see "90.00%" in the "Activity results" "block"
And I should see "80.00%" in the "Activity results" "block"
And I should see "70.00%" in the "Activity results" "block"
@@ -0,0 +1,98 @@
@block @block_activity_results @javascript
Feature: The activity results block displays students high scores in group as scales
In order to be display student scores as scales
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| idnumber | 0001 |
| name | Test assignment |
| intro | Offline text |
| assignsubmission_file_enabled | 0 |
And the following "scales" exist:
| name | scale |
| My Scale | Disappointing, Not good enough, Average, Good, Very good, Excellent! |
And I am on the "Test assignment" "assign activity editing" page logged in as teacher1
And I set the following fields to these values:
| id_grade_modgrade_type | Scale |
| id_grade_modgrade_scale | My Scale |
And I press "Save and return to course"
And I am on the "Course 1" "grades > Grader report > View" page
And I turn editing mode on
And I give the grade "Excellent!" to the user "Student 1" for the grade item "Test assignment"
And I give the grade "Very good" to the user "Student 2" for the grade item "Test assignment"
And I give the grade "Good" to the user "Student 3" for the grade item "Test assignment"
And I give the grade "Average" to the user "Student 4" for the grade item "Test assignment"
And I give the grade "Not good enough" to the user "Student 5" for the grade item "Test assignment"
And I press "Save changes"
And I am on "Course 1" course homepage with editing mode on
Scenario: Configure the block on the course page to show 1 high score
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
Then I should see "Student 1" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using full names
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_nameformat | Display full names |
Then I should see "Student 1" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
And I should see "Student 2" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should see "Student 3" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
Given the following config values are set as admin:
| showuseridentity | idnumber,email |
And I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_nameformat | Display only ID numbers |
Then I should see "User S1" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
And I should see "User S2" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should see "User S3" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_nameformat | Anonymous results |
Then I should see "User" in the "Activity results" "block"
And I should not see "Student 1" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
And I should not see "Student 2" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should not see "Student 3" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
@@ -0,0 +1,132 @@
@block @block_activity_results @javascript
Feature: The activity results block displays student in group high scores as scales
In order to be display student scores as scales
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
| student6 | Student | 6 | student6@example.com | S6 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "groups" exist:
| name | course | idnumber |
| Group 1 | C1 | G1 |
| Group 2 | C1 | G2 |
| Group 3 | C1 | G3 |
| Group 4 | C1 | G4 |
| Group 5 | C1 | G5 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
| student6 | C1 | student |
And the following "group members" exist:
| user | group |
| student1 | G1 |
| student2 | G1 |
| student3 | G2 |
| student4 | G2 |
| student5 | G3 |
| student6 | G3 |
And the following "activities" exist:
| activity | name | intro | course | section | idnumber |
| assign | Test assignment | Offline text | C1 | 1 | assign1 |
And the following "scales" exist:
| name | scale |
| My Scale | Disappointing, Not good enough, Average, Good, Very good, Excellent! |
And I change window size to "large"
And I am on the "Test assignment" "assign activity editing" page logged in as teacher1
And I set the following fields to these values:
| assignsubmission_file_enabled | 0 |
| id_grade_modgrade_type | Scale |
| id_grade_modgrade_scale | My Scale |
| Group mode | Separate groups |
And I press "Save and return to course"
And I turn editing mode on
And I am on the "Course 1" "grades > Grader report > View" page
And I give the grade "Excellent!" to the user "Student 1" for the grade item "Test assignment"
And I give the grade "Very good" to the user "Student 2" for the grade item "Test assignment"
And I give the grade "Very good" to the user "Student 3" for the grade item "Test assignment"
And I give the grade "Good" to the user "Student 4" for the grade item "Test assignment"
And I give the grade "Good" to the user "Student 5" for the grade item "Test assignment"
And I give the grade "Average" to the user "Student 6" for the grade item "Test assignment"
And I press "Save changes"
And I am on "Course 1" course homepage
Scenario: Try to configure the block on the course page to show 1 high score
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student1
And I should see "Student 1" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using full names
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
And I should see "Group 2" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student3
And I should see "Student 3" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should see "Student 4" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
Given the following config values are set as admin:
| showuseridentity | idnumber,email |
And I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_nameformat | Display only ID numbers |
| config_usegroups | Yes |
Then I should see "Group" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
# Students cannot see user identity fields.
And I am on the "Course 1" course page logged in as student1
And I should see "User" in the "Activity results" "block"
And I should not see "User S1" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
And I should not see "User S2" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_nameformat | Anonymous results |
| config_usegroups | Yes |
Then I should see "Group" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student1
And I should see "User" in the "Activity results" "block"
And I should see "Excellent!" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
@@ -0,0 +1,193 @@
@block @block_activity_results @javascript
Feature: The activity results block displays student in separate groups scores
In order to be display student scores
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
| student6 | Student | 6 | student6@example.com | S6 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "groups" exist:
| name | course | idnumber |
| Group 1 | C1 | G1 |
| Group 2 | C1 | G2 |
| Group 3 | C1 | G3 |
| Group 4 | C1 | G4 |
| Group 5 | C1 | G5 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
| student6 | C1 | student |
And the following "group members" exist:
| user | group |
| student1 | G1 |
| student2 | G1 |
| student3 | G2 |
| student4 | G2 |
| student5 | G3 |
| student6 | G3 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| idnumber | 0001 |
| name | Test assignment |
| section | 1 |
| assignsubmission_file_enabled | 0 |
| groupmode | 1 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment | student1 | 100.00 |
| Test assignment | student2 | 90.00 |
| Test assignment | student3 | 90.00 |
| Test assignment | student4 | 80.00 |
| Test assignment | student5 | 80.00 |
| Test assignment | student6 | 70.00 |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Scenario: Configure the block on the course page to show 1 high score
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
| config_usegroups | Yes |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "95%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 high score as a fraction
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "95.00/100.00" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student1
And I should see "Student 1" in the "Activity results" "block"
And I should see "100.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 high score as a absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "95.00" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student1
And I should see "Student 1" in the "Activity results" "block"
And I should see "100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores as percentages
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
| config_usegroups | Yes |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "95%" in the "Activity results" "block"
And I should see "Group 2" in the "Activity results" "block"
And I should see "85%" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75%" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student1
And I should see "Student 1" in the "Activity results" "block"
And I should see "100%" in the "Activity results" "block"
And I should see "Student 2" in the "Activity results" "block"
And I should see "90%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores as fractions
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "95.00/100.00" in the "Activity results" "block"
And I should see "Group 2" in the "Activity results" "block"
And I should see "85.00/100.00" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75.00/100.00" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student3
And I should see "Student 3" in the "Activity results" "block"
And I should see "90.00/100.00" in the "Activity results" "block"
And I should see "Student 4" in the "Activity results" "block"
And I should see "80.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores as absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "95.00" in the "Activity results" "block"
And I should see "Group 2" in the "Activity results" "block"
And I should see "85.00" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75.00" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student1
And I should see "Student 1" in the "Activity results" "block"
And I should see "100.00" in the "Activity results" "block"
And I should see "Student 2" in the "Activity results" "block"
And I should see "90.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
Given the following config values are set as admin:
| showuseridentity | idnumber,email |
And I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display only ID numbers |
| config_usegroups | Yes |
Then I should see "Group" in the "Activity results" "block"
And I should see "95.00%" in the "Activity results" "block"
And I should see "85.00%" in the "Activity results" "block"
And I should see "75.00%" in the "Activity results" "block"
# Students cannot see user identity fields.
And I am on the "Course 1" course page logged in as student1
And I should see "User" in the "Activity results" "block"
And I should not see "User S1" in the "Activity results" "block"
And I should see "100.00%" in the "Activity results" "block"
And I should not see "User S2" in the "Activity results" "block"
And I should see "90.00%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Anonymous results |
| config_usegroups | Yes |
Then I should see "Group" in the "Activity results" "block"
And I should see "95.00%" in the "Activity results" "block"
And I should see "85.00%" in the "Activity results" "block"
And I should see "75.00%" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student1
And I should see "User" in the "Activity results" "block"
And I should see "100.00%" in the "Activity results" "block"
And I should see "90.00%" in the "Activity results" "block"
@@ -0,0 +1,163 @@
@block @block_activity_results @javascript
Feature: The activity results block displays student in visible groups scores
In order to be display student scores
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
| student6 | Student | 6 | student6@example.com | S6 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "groups" exist:
| name | course | idnumber |
| Group 1 | C1 | G1 |
| Group 2 | C1 | G2 |
| Group 3 | C1 | G3 |
| Group 4 | C1 | G4 |
| Group 5 | C1 | G5 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
| student6 | C1 | student |
And the following "group members" exist:
| user | group |
| student1 | G1 |
| student2 | G1 |
| student3 | G2 |
| student4 | G2 |
| student5 | G3 |
| student6 | G3 |
And the following "activities" exist:
| activity | name | course | idnumber | section | assignsubmission_file_enabled | groupmode |
| assign | Test assignment | C1 | assign1 | 1 | 0 | 2 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment | student1 | 100.00 |
| Test assignment | student2 | 90.00 |
| Test assignment | student3 | 90.00 |
| Test assignment | student4 | 80.00 |
| Test assignment | student5 | 80.00 |
| Test assignment | student6 | 70.00 |
And I am on the "Course 1" course page logged in as teacher1
And I turn editing mode on
Scenario: Configure the block on the course page to show 1 high score
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
| config_usegroups | Yes |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "95%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 high score as a fraction
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
| config_usegroups | Yes |
And I am on the "Course 1" course page logged in as student1
Then I should see "Group 1" in the "Activity results" "block"
And I should see "95.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 high score as a absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 1 |
| config_showworst | 0 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group 1" in the "Activity results" "block"
And I should see "95.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores as percentages
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group 1" in the "Activity results" "block"
And I should see "95%" in the "Activity results" "block"
And I should see "Group 2" in the "Activity results" "block"
And I should see "85%" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores as fractions
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group 1" in the "Activity results" "block"
And I should see "95.00/100.00" in the "Activity results" "block"
And I should see "Group 2" in the "Activity results" "block"
And I should see "85.00/100.00" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores as absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group 1" in the "Activity results" "block"
And I should see "95.00" in the "Activity results" "block"
And I should see "Group 2" in the "Activity results" "block"
And I should see "85.00" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
Given the following config values are set as admin:
| showuseridentity | idnumber,email |
And I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Display only ID numbers |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group" in the "Activity results" "block"
And I should see "95.00%" in the "Activity results" "block"
And I should see "85.00%" in the "Activity results" "block"
And I should see "75.00%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
Given I add the "Activity results" block to the default region with:
| config_showbest | 3 |
| config_showworst | 0 |
| config_gradeformat | Percentages |
| config_nameformat | Anonymous results |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group" in the "Activity results" "block"
And I should see "95.00%" in the "Activity results" "block"
And I should see "85.00%" in the "Activity results" "block"
And I should see "75.00%" in the "Activity results" "block"
@@ -0,0 +1,135 @@
@block @block_activity_results @javascript
Feature: The activity results block displays student low scores
In order to be display student scores
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| idnumber | 0001 |
| name | Test assignment |
| assignsubmission_file_enabled | 0 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment | student1 | 90.00 |
| Test assignment | student2 | 80.00 |
| Test assignment | student3 | 70.00 |
| Test assignment | student4 | 60.00 |
| Test assignment | student5 | 50.00 |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Scenario: Configure the block on the course page to show 1 low score
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
Then I should see "Student 5" in the "Activity results" "block"
And I should see "50%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 low score as a fraction
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
Then I should see "Student 5" in the "Activity results" "block"
And I should see "50.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 low score as a absolute number
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
Then I should see "Student 5" in the "Activity results" "block"
And I should see "50.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores as percentages
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 3 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
Then I should see "Student 5" in the "Activity results" "block"
And I should see "50%" in the "Activity results" "block"
And I should see "Student 4" in the "Activity results" "block"
And I should see "60%" in the "Activity results" "block"
And I should see "Student 3" in the "Activity results" "block"
And I should see "70%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores as fractions
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 3 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
Then I should see "Student 5" in the "Activity results" "block"
And I should see "50.00/100.00" in the "Activity results" "block"
And I should see "Student 4" in the "Activity results" "block"
And I should see "60.00/100.00" in the "Activity results" "block"
And I should see "Student 3" in the "Activity results" "block"
And I should see "70.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores as absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 3 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
Then I should see "Student 5" in the "Activity results" "block"
And I should see "50.00" in the "Activity results" "block"
And I should see "Student 4" in the "Activity results" "block"
And I should see "60.00" in the "Activity results" "block"
And I should see "Student 3" in the "Activity results" "block"
And I should see "70.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores using ID numbers
Given the following config values are set as admin:
| showuseridentity | idnumber,email |
And I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 3 |
| config_gradeformat | Percentages |
| config_nameformat | Display only ID numbers |
Then I should see "User S5" in the "Activity results" "block"
And I should see "50.00%" in the "Activity results" "block"
And I should see "User S4" in the "Activity results" "block"
And I should see "60.00%" in the "Activity results" "block"
And I should see "User S3" in the "Activity results" "block"
And I should see "70.00%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores using anonymous names
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 3 |
| config_gradeformat | Percentages |
| config_nameformat | Anonymous results |
Then I should see "User" in the "Activity results" "block"
And I should see "50.00%" in the "Activity results" "block"
And I should see "60.00%" in the "Activity results" "block"
And I should see "70.00%" in the "Activity results" "block"
@@ -0,0 +1,100 @@
@block @block_activity_results @javascript
Feature: The activity results block displays student low scores as scales
In order to be display student scores as scales
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
Given the following "activity" exists:
| activity | assign |
| name | Test assignment |
| intro | Offline text |
| course | C1 |
| idnumber | 0001 |
| section | 1 |
| assignsubmission_file_enabled | 0 |
And the following "scales" exist:
| name | scale |
| My Scale | Disappointing, Not good enough, Average, Good, Very good, Excellent! |
And I am on the "Test assignment" "assign activity editing" page logged in as teacher1
And I set the following fields to these values:
| id_grade_modgrade_type | Scale |
| id_grade_modgrade_scale | My Scale |
And I press "Save and return to course"
And I turn editing mode on
And I am on the "Course 1" "grades > Grader report > View" page
And I give the grade "Excellent!" to the user "Student 1" for the grade item "Test assignment"
And I give the grade "Very good" to the user "Student 2" for the grade item "Test assignment"
And I give the grade "Good" to the user "Student 3" for the grade item "Test assignment"
And I give the grade "Average" to the user "Student 4" for the grade item "Test assignment"
And I give the grade "Not good enough" to the user "Student 5" for the grade item "Test assignment"
And I press "Save changes"
And I am on "Course 1" course homepage
Scenario: Configure the block on the course page to show 1 low score
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
Then I should see "Student 5" in the "Activity results" "block"
And I should see "Not good enough" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores using full names
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 3 |
| config_nameformat | Display full names |
Then I should see "Student 5" in the "Activity results" "block"
And I should see "Not good enough" in the "Activity results" "block"
And I should see "Student 4" in the "Activity results" "block"
And I should see "Average" in the "Activity results" "block"
And I should see "Student 3" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores using ID numbers
Given the following config values are set as admin:
| showuseridentity | idnumber,email |
And I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 3 |
| config_nameformat | Display only ID numbers |
Then I should see "User S5" in the "Activity results" "block"
And I should see "Not good enough" in the "Activity results" "block"
And I should see "User S4" in the "Activity results" "block"
And I should see "Average" in the "Activity results" "block"
And I should see "User S3" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores using anonymous names
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 3 |
| config_nameformat | Anonymous results |
Then I should see "User" in the "Activity results" "block"
And I should not see "Student 5" in the "Activity results" "block"
And I should see "Not good enough" in the "Activity results" "block"
And I should not see "Student 4" in the "Activity results" "block"
And I should see "Average" in the "Activity results" "block"
And I should not see "Student 3" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
@@ -0,0 +1,131 @@
@block @block_activity_results @javascript
Feature: The activity results block displays students in groups low scores as scales
In order to be display student scores as scales
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
| student6 | Student | 6 | student6@example.com | S6 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "groups" exist:
| name | course | idnumber |
| Group 1 | C1 | G1 |
| Group 2 | C1 | G2 |
| Group 3 | C1 | G3 |
| Group 4 | C1 | G4 |
| Group 5 | C1 | G5 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
| student6 | C1 | student |
And the following "group members" exist:
| user | group |
| student1 | G1 |
| student2 | G1 |
| student3 | G2 |
| student4 | G2 |
| student5 | G3 |
| student6 | G3 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| idnumber | 0001 |
| name | Test assignment |
| description | Offline text |
| assignsubmission_file_enabled | 0 |
| groupmode | 1 |
And the following "scales" exist:
| name | scale |
| My Scale | Disappointing, Not good enough, Average, Good, Very good, Excellent! |
And I change window size to "large"
And I am on the "Test assignment" "assign activity editing" page logged in as teacher1
And I set the following fields to these values:
| id_grade_modgrade_type | Scale |
| id_grade_modgrade_scale | My Scale |
And I press "Save and return to course"
And I am on the "Course 1" "grades > Grader report > View" page
And I turn editing mode on
And I give the grade "Excellent!" to the user "Student 1" for the grade item "Test assignment"
And I give the grade "Very good" to the user "Student 2" for the grade item "Test assignment"
And I give the grade "Very good" to the user "Student 3" for the grade item "Test assignment"
And I give the grade "Good" to the user "Student 4" for the grade item "Test assignment"
And I give the grade "Good" to the user "Student 5" for the grade item "Test assignment"
And I give the grade "Average" to the user "Student 6" for the grade item "Test assignment"
And I press "Save changes"
And I am on "Course 1" course homepage
Scenario: Try to configure the block on the course page to show 1 low score
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 3" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student5
And I should see "Student 6" in the "Activity results" "block"
And I should see "Average" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using full names
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 2" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student3
And I should see "Student 3" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should see "Student 4" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
Given the following config values are set as admin:
| showuseridentity | idnumber,email |
And I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_nameformat | Display only ID numbers |
| config_usegroups | Yes |
Then I should see "Group" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
# Students cannot see user identity fields.
And I am on the "Course 1" course page logged in as student5
And I should see "User" in the "Activity results" "block"
And I should not see "User S5" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
And I should not see "User S6" in the "Activity results" "block"
And I should see "Average" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_nameformat | Anonymous results |
| config_usegroups | Yes |
Then I should see "Group" in the "Activity results" "block"
And I should see "Very good" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student5
And I should see "User" in the "Activity results" "block"
And I should see "Good" in the "Activity results" "block"
And I should see "Average" in the "Activity results" "block"
@@ -0,0 +1,180 @@
@block @block_activity_results @javascript
Feature: The activity results block displays students in separate groups scores
In order to be display student scores
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
| student6 | Student | 6 | student6@example.com | S6 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "groups" exist:
| name | course | idnumber |
| Group 1 | C1 | G1 |
| Group 2 | C1 | G2 |
| Group 3 | C1 | G3 |
| Group 4 | C1 | G4 |
| Group 5 | C1 | G5 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
| student6 | C1 | student |
And the following "group members" exist:
| user | group |
| student1 | G1 |
| student2 | G1 |
| student3 | G2 |
| student4 | G2 |
| student5 | G3 |
| student6 | G3 |
And the following "activities" exist:
| activity | course | idnumber | name | assignsubmission_file_enabled | groupmode |
| assign | C1 | a1 | Test assignment | 0 | 1 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment | student1 | 100.00 |
| Test assignment | student2 | 90.00 |
| Test assignment | student3 | 90.00 |
| Test assignment | student4 | 80.00 |
| Test assignment | student5 | 80.00 |
| Test assignment | student6 | 70.00 |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Scenario: Configure the block on the course page to show 1 low score
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
| config_usegroups | Yes |
Then I should see "Group 3" in the "Activity results" "block"
And I should see "75%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 low score as a fraction
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 3" in the "Activity results" "block"
And I should see "75.00/100.00" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student5
And I should see "Student 6" in the "Activity results" "block"
And I should see "70.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 low score as a absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 3" in the "Activity results" "block"
And I should see "75.00" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student5
And I should see "Student 6" in the "Activity results" "block"
And I should see "70.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores as percentages
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
| config_usegroups | Yes |
Then I should see "Group 2" in the "Activity results" "block"
And I should see "85%" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75%" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student5
And I should see "Student 6" in the "Activity results" "block"
And I should see "70%" in the "Activity results" "block"
And I should see "Student 5" in the "Activity results" "block"
And I should see "80%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores as fractions
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 2" in the "Activity results" "block"
And I should see "85.00/100.00" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75.00/100.00" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student3
And I should see "Student 3" in the "Activity results" "block"
And I should see "90.00/100.00" in the "Activity results" "block"
And I should see "Student 4" in the "Activity results" "block"
And I should see "80.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores as absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I should see "Group 2" in the "Activity results" "block"
And I should see "85.00" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75.00" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student5
And I should see "Student 5" in the "Activity results" "block"
And I should see "80.00" in the "Activity results" "block"
And I should see "Student 6" in the "Activity results" "block"
And I should see "70.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores using ID numbers
Given the following config values are set as admin:
| showuseridentity | idnumber,email |
And I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_gradeformat | Percentages |
| config_nameformat | Display only ID numbers |
| config_usegroups | Yes |
Then I should see "Group" in the "Activity results" "block"
And I should see "85.00%" in the "Activity results" "block"
And I should see "75.00%" in the "Activity results" "block"
# Students cannot see user identity fields.
And I am on the "Course 1" course page logged in as student1
And I should see "User" in the "Activity results" "block"
And I should not see "User S1" in the "Activity results" "block"
And I should see "100.00%" in the "Activity results" "block"
And I should not see "User S2" in the "Activity results" "block"
And I should see "90.00%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores using anonymous names
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_gradeformat | Percentages |
| config_nameformat | Anonymous results |
| config_usegroups | Yes |
Then I should see "Group" in the "Activity results" "block"
And I should see "85.00%" in the "Activity results" "block"
And I should see "75.00%" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student1
And I should see "User" in the "Activity results" "block"
And I should see "100.00%" in the "Activity results" "block"
And I should see "90.00%" in the "Activity results" "block"
@@ -0,0 +1,163 @@
@block @block_activity_results @javascript
Feature: The activity results block displays student in visible groups low scores
In order to be display student scores
As a user
I need to see the activity results block
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
| student3 | Student | 3 | student3@example.com | S3 |
| student4 | Student | 4 | student4@example.com | S4 |
| student5 | Student | 5 | student5@example.com | S5 |
| student6 | Student | 6 | student6@example.com | S6 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "groups" exist:
| name | course | idnumber |
| Group 1 | C1 | G1 |
| Group 2 | C1 | G2 |
| Group 3 | C1 | G3 |
| Group 4 | C1 | G4 |
| Group 5 | C1 | G5 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| student5 | C1 | student |
| student6 | C1 | student |
And the following "group members" exist:
| user | group |
| student1 | G1 |
| student2 | G1 |
| student3 | G2 |
| student4 | G2 |
| student5 | G3 |
| student6 | G3 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| idnumber | 0001 |
| name | Test assignment |
| assignsubmission_file_enabled | 0 |
| groupmode | 2 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment | student1 | 100.00 |
| Test assignment | student2 | 90.00 |
| Test assignment | student3 | 90.00 |
| Test assignment | student4 | 80.00 |
| Test assignment | student5 | 80.00 |
| Test assignment | student6 | 70.00 |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Scenario: Configure the block on the course page to show 1 low score
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
| config_usegroups | Yes |
Then I should see "Group 3" in the "Activity results" "block"
And I should see "75%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 low score as a fraction
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group 3" in the "Activity results" "block"
And I should see "75.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show 1 low score as a absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 1 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
| config_usegroups | Yes |
When I am on the "Course 1" course page logged in as student1
Then I should see "Group 3" in the "Activity results" "block"
And I should see "75.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores as percentages
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_gradeformat | Percentages |
| config_nameformat | Display full names |
| config_decimalpoints | 0 |
| config_usegroups | Yes |
Then I should see "Group 2" in the "Activity results" "block"
And I should see "85%" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75%" in the "Activity results" "block"
And I am on the "Course 1" course page logged in as student5
Then I should see "Group 2" in the "Activity results" "block"
And I should see "85%" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores as fractions
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_gradeformat | Fractions |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group 2" in the "Activity results" "block"
And I should see "85.00/100.00" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75.00/100.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores as absolute numbers
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_gradeformat | Absolute numbers |
| config_nameformat | Display full names |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group 2" in the "Activity results" "block"
And I should see "85.00" in the "Activity results" "block"
And I should see "Group 3" in the "Activity results" "block"
And I should see "75.00" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores using ID numbers
Given the following config values are set as admin:
| showuseridentity | idnumber,email |
And I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_gradeformat | Percentages |
| config_nameformat | Display only ID numbers |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group" in the "Activity results" "block"
And I should see "85.00%" in the "Activity results" "block"
And I should see "75.00%" in the "Activity results" "block"
Scenario: Try to configure the block on the course page to show multiple low scores using anonymous names
Given I add the "Activity results" block to the default region with:
| config_showbest | 0 |
| config_showworst | 2 |
| config_gradeformat | Percentages |
| config_nameformat | Anonymous results |
| config_usegroups | Yes |
Then I am on the "Course 1" course page logged in as student1
And I should see "Group" in the "Activity results" "block"
And I should see "85.00%" in the "Activity results" "block"
And I should see "75.00%" in the "Activity results" "block"
+29
View File
@@ -0,0 +1,29 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Version information for the block_activity_results plugin.
*
* @package block_activity_results
* @copyright 2015 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'block_activity_results'; // Full name of the plugin (used for diagnostics).
@@ -0,0 +1,141 @@
<?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/>.
/**
* Admin Bookmarks Block page.
*
* @package block_admin_bookmarks
* @copyright 2011 Moodle
* @author 2006 vinkmar
* 2011 Rossiani Wijaya (updated)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* The admin bookmarks block class
*/
class block_admin_bookmarks extends block_base {
/** @var string */
public $blockname = null;
/** @var bool|null */
protected $docked = null;
/**
* Set the initial properties for the block
*/
function init() {
$this->blockname = get_class($this);
$this->title = get_string('pluginname', $this->blockname);
}
/**
* All multiple instances of this block
* @return bool Returns false
*/
function instance_allow_multiple() {
return false;
}
/**
* Set the applicable formats for this block to all
* @return array
*/
function applicable_formats() {
if (has_capability('moodle/site:config', context_system::instance())) {
return array('all' => true);
} else {
return array('site' => true);
}
}
/**
* Gets the content for this block
*/
function get_content() {
global $CFG;
// First check if we have already generated, don't waste cycles
if ($this->content !== null) {
return $this->content;
}
$this->content = new stdClass();
if (get_user_preferences('admin_bookmarks')) {
require_once($CFG->libdir.'/adminlib.php');
$adminroot = admin_get_root(false, false); // settings not required - only pages
$bookmarks = explode(',', get_user_preferences('admin_bookmarks'));
/// Accessibility: markup as a list.
$contents = array();
foreach($bookmarks as $bookmark) {
$temp = $adminroot->locate($bookmark);
if ($temp instanceof admin_settingpage) {
$contenturl = new moodle_url('/admin/settings.php', array('section'=>$bookmark));
$contentlink = html_writer::link($contenturl, $temp->visiblename);
$contents[] = html_writer::tag('li', $contentlink);
} else if ($temp instanceof admin_externalpage) {
$contenturl = new moodle_url($temp->url);
$contentlink = html_writer::link($contenturl, $temp->visiblename);
$contents[] = html_writer::tag('li', $contentlink);
} else if ($temp instanceof admin_category) {
$contenturl = new moodle_url('/admin/category.php', array('category' => $bookmark));
$contentlink = html_writer::link($contenturl, $temp->visiblename);
$contents[] = html_writer::tag('li', $contentlink);
}
}
$this->content->text = html_writer::tag('ol', implode('', $contents), array('class' => 'list'));
} else {
$bookmarks = array();
}
$this->content->footer = '';
$this->page->settingsnav->initialise();
$node = $this->page->settingsnav->get('root', navigation_node::TYPE_SITE_ADMIN);
if (!$node || !$node->contains_active_node()) {
return $this->content;
}
$section = $node->find_active_node()->key;
if ($section == 'search' || empty($section)){
// the search page can't be properly bookmarked at present
$this->content->footer = '';
} else if (in_array($section, $bookmarks)) {
$deleteurl = new moodle_url('/blocks/admin_bookmarks/delete.php', array('section'=>$section, 'sesskey'=>sesskey()));
$this->content->footer = html_writer::link($deleteurl, get_string('unbookmarkthispage','admin'));
} else {
$createurl = new moodle_url('/blocks/admin_bookmarks/create.php', array('section'=>$section, 'sesskey'=>sesskey()));
$this->content->footer = html_writer::link($createurl, get_string('bookmarkthispage','admin'));
}
return $this->content;
}
/**
* Returns the role that best describes the admin bookmarks block.
*
* @return string
*/
public function get_aria_role() {
return 'navigation';
}
}
@@ -0,0 +1,46 @@
<?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_admin_bookmarks.
*
* @package block_admin_bookmarks
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_admin_bookmarks\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for block_admin_bookmarks implementing null_provider.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+76
View File
@@ -0,0 +1,76 @@
<?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/>.
/**
* Create admin bookmarks.
*
* @package block_admin_bookmarks
* @copyright 2006 vinkmar
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require('../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_login();
$context = context_system::instance();
$PAGE->set_context($context);
$adminroot = admin_get_root(false, false); // settings not required - only pages
// We clean section with safe path here for compatibility with external pages that include a slash in their name.
if ($section = optional_param('section', '', PARAM_SAFEPATH) and confirm_sesskey()) {
if (get_user_preferences('admin_bookmarks')) {
$bookmarks = explode(',', get_user_preferences('admin_bookmarks'));
if (in_array($section, $bookmarks)) {
throw new \moodle_exception('bookmarkalreadyexists', 'admin');
die;
}
} else {
$bookmarks = array();
}
$temp = $adminroot->locate($section);
if ($temp instanceof admin_settingpage || $temp instanceof admin_externalpage || $temp instanceof admin_category) {
$bookmarks[] = $section;
$bookmarks = implode(',', $bookmarks);
set_user_preference('admin_bookmarks', $bookmarks);
} else {
throw new \moodle_exception('invalidsection', 'admin');
die;
}
if ($temp instanceof admin_settingpage) {
redirect($CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=' . $section);
} elseif ($temp instanceof admin_externalpage) {
redirect($temp->url);
} else if ($temp instanceof admin_category) {
redirect($CFG->wwwroot . '/' . $CFG->admin . '/category.php?category=' . $section);
}
} else {
throw new \moodle_exception('invalidsection', 'admin');
die;
}
+51
View File
@@ -0,0 +1,51 @@
<?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/>.
/**
* Admin bookmarks block caps.
*
* @package block_admin_bookmarks
* @copyright Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'block/admin_bookmarks:myaddinstance' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/my:manageblocks'
),
'block/admin_bookmarks:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
);
+76
View File
@@ -0,0 +1,76 @@
<?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/>.
/**
* Delete admin bookmarks.
*
* @package block_admin_bookmarks
* @copyright 2006 vinkmar
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require('../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_login();
$context = context_system::instance();
$PAGE->set_context($context);
$adminroot = admin_get_root(false, false); // settings not required - only pages
// We clean section with safe path here for compatibility with external pages that include a slash in their name.
if ($section = optional_param('section', '', PARAM_SAFEPATH) and confirm_sesskey()) {
if (get_user_preferences('admin_bookmarks')) {
$bookmarks = explode(',', get_user_preferences('admin_bookmarks'));
$key = array_search($section, $bookmarks);
if ($key === false) {
throw new \moodle_exception('nonexistentbookmark', 'admin');
die;
}
unset($bookmarks[$key]);
$bookmarks = implode(',', $bookmarks);
set_user_preference('admin_bookmarks', $bookmarks);
$temp = $adminroot->locate($section);
if ($temp instanceof admin_externalpage) {
redirect($temp->url, get_string('bookmarkdeleted','admin'));
} elseif ($temp instanceof admin_settingpage) {
redirect($CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=' . $section);
} else if ($temp instanceof admin_category) {
redirect($CFG->wwwroot . '/' . $CFG->admin . '/category.php?category=' . $section);
} else {
redirect($CFG->wwwroot);
}
die;
}
throw new \moodle_exception('nobookmarksforuser', 'admin');
die;
} else {
throw new \moodle_exception('invalidsection', 'admin');
die;
}
@@ -0,0 +1,28 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'block_admin_bookmarks', language 'en', branch 'MOODLE_20_STABLE'
*
* @package block_admin_bookmarks
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['admin_bookmarks:addinstance'] = 'Add a new admin bookmarks block';
$string['admin_bookmarks:myaddinstance'] = 'Add a new admin bookmarks block to Dashboard';
$string['pluginname'] = 'Admin bookmarks';
$string['privacy:metadata'] = 'The Admin bookmarks block only shows data stored in other locations.';
@@ -0,0 +1,36 @@
@block @block_admin_bookmarks
Feature: Add a bookmarks to an admin pages
In order to speed up common tasks
As an admin
I need to add and access pages through bookmarks
Background:
Given I log in as "admin"
And I navigate to "Server > Tasks > Scheduled tasks" in site administration
And I click on "Bookmark this page" "link" in the "Admin bookmarks" "block"
And I log out
# Test bookmark functionality using the "User profile fields" page as our bookmark.
Scenario: Admin page can be bookmarked
Given I log in as "admin"
And I navigate to "Users > Accounts > User profile fields" in site administration
When I click on "Bookmark this page" "link" in the "Admin bookmarks" "block"
Then I should see "User profile fields" in the "Admin bookmarks" "block"
# See the existing bookmark is there too.
And I should see "Scheduled tasks" in the "Admin bookmarks" "block"
Scenario: Admin page can be accessed through bookmarks block
Given I log in as "admin"
And I navigate to "Notifications" in site administration
And I click on "Scheduled tasks" "link" in the "Admin bookmarks" "block"
# Verify that we are on the right page.
Then I should see "Day of week" in the "admintable" "table"
Scenario: Admin page can be removed from bookmarks
Given I log in as "admin"
And I navigate to "Notifications" in site administration
And I click on "Scheduled tasks" "link" in the "Admin bookmarks" "block"
When I click on "Unbookmark this page" "link" in the "Admin bookmarks" "block"
Then I should see "Bookmark deleted"
And I wait to be redirected
And I should not see "Scheduled tasks" in the "Admin bookmarks" "block"
+29
View File
@@ -0,0 +1,29 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Version details
*
* @package block_admin_bookmarks
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'block_admin_bookmarks'; // Full name of the plugin (used for diagnostics)
+10
View File
@@ -0,0 +1,10 @@
define("core_block/add_modal",["exports","core/templates","core/str","core/ajax","core_form/modalform","core/modal_cancel"],(function(_exports,_templates,_str,_ajax,_modalform,_modal_cancel){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* Show an add block modal instead of doing it on a separate page.
*
* @module core_block/add_modal
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=_interopRequireDefault(_templates),_ajax=_interopRequireDefault(_ajax),_modalform=_interopRequireDefault(_modalform),_modal_cancel=_interopRequireDefault(_modal_cancel);const SELECTORS_ADD_BLOCK='[data-key="addblock"]',SELECTORS_SHOW_BLOCK_FORM='[data-action="showaddblockform"][data-blockname][data-blockform]';let listenerEventsRegistered=!1;const registerListenerEvents=(addBlockUrl,pagehash)=>{let addBlockModal=null;document.addEventListener("click",(e=>{const showAddBlockForm=e.target.closest(SELECTORS_SHOW_BLOCK_FORM);if(showAddBlockForm){e.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:(0,_str.getString)("addblock","core_block",showAddBlockForm.getAttribute("data-blocktitle"))},args:{blockname:showAddBlockForm.getAttribute("data-blockname"),pagehash:pagehash,blockregion:showAddBlockForm.getAttribute("data-blockregion")},formClass:showAddBlockForm.getAttribute("data-blockform"),returnFocus:showAddBlockForm});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>{addBlockModal.destroy(),window.location.reload()})),modalForm.show()}const addBlock=e.target.closest(SELECTORS_ADD_BLOCK);if(addBlock){e.preventDefault();let addBlockModalUrl=null!=addBlockUrl?addBlockUrl:addBlock.dataset.url;buildAddBlockModal().then((modal=>{addBlockModal=modal;const modalBody=renderBlocks(addBlockModalUrl,pagehash,addBlock.getAttribute("data-blockregion"));return modal.setBody(modalBody),modal.show(),modalBody})).catch((()=>{addBlockModal.destroy()}))}}))},buildAddBlockModal=()=>_modal_cancel.default.create({title:(0,_str.getString)("addblock")}),renderBlocks=async(addBlockUrl,pagehash,region)=>{const blocks=await getAddableBlocks(pagehash);return _templates.default.render("core/add_block_body",{blocks:blocks,url:addBlockUrl,blockregion:region,pagehash:pagehash})},getAddableBlocks=async pagehash=>{const request={methodname:"core_block_fetch_addable_blocks",args:{pagecontextid:0,pagetype:"",pagelayout:"",subpage:"",pagehash:pagehash}};return _ajax.default.call([request])[0]};_exports.init=function(){let addBlockUrl=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,pagehash=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";listenerEventsRegistered||(registerListenerEvents(addBlockUrl,pagehash),listenerEventsRegistered=!0)}}));
//# sourceMappingURL=add_modal.min.js.map
File diff suppressed because one or more lines are too long
+10
View File
@@ -0,0 +1,10 @@
define("core_block/edit",["exports","core_form/modalform"],(function(_exports,_modalform){var obj;
/**
* Javascript module for editing blocks
*
* @module core_block/edit
* @copyright 2022 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modalform=(obj=_modalform)&&obj.__esModule?obj:{default:obj};const SELECTORS_EDITBLOCK='[data-action="editblock"][data-blockid][data-blockform]';_exports.init=pagehash=>{document.addEventListener("click",(e=>{const target=e.target.closest(SELECTORS_EDITBLOCK);if(!target||!target.getAttribute("data-blockform"))return;e.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:target.getAttribute("data-header")},args:{blockid:target.getAttribute("data-blockid"),pagehash:pagehash},formClass:target.getAttribute("data-blockform"),returnFocus:target});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>{location.reload()})),modalForm.show()}))}}));
//# sourceMappingURL=edit.min.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"edit.min.js","sources":["../src/edit.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript module for editing blocks\n *\n * @module core_block/edit\n * @copyright 2022 Marina Glancy\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalForm from 'core_form/modalform';\n\nconst SELECTORS = {\n EDITBLOCK: '[data-action=\"editblock\"][data-blockid][data-blockform]',\n};\n\n/**\n * Initialize module\n * @param {String} pagehash\n */\nexport const init = (pagehash) => {\n document.addEventListener('click', e => {\n const target = e.target.closest(SELECTORS.EDITBLOCK);\n if (!target || !target.getAttribute('data-blockform')) {\n return;\n }\n e.preventDefault();\n\n const modalForm = new ModalForm({\n modalConfig: {\n title: target.getAttribute('data-header'),\n },\n args: {blockid: target.getAttribute('data-blockid'), pagehash},\n formClass: target.getAttribute('data-blockform'),\n returnFocus: target,\n });\n\n // Reload the page when the form is submitted, there is no possibility\n // currently to request contents update of just one block on the page.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => {\n location.reload();\n });\n\n modalForm.show();\n });\n};\n"],"names":["SELECTORS","pagehash","document","addEventListener","e","target","closest","getAttribute","preventDefault","modalForm","ModalForm","modalConfig","title","args","blockid","formClass","returnFocus","events","FORM_SUBMITTED","location","reload","show"],"mappings":";;;;;;;sJAyBMA,oBACS,wEAOMC,WACjBC,SAASC,iBAAiB,SAASC,UACzBC,OAASD,EAAEC,OAAOC,QAAQN,yBAC3BK,SAAWA,OAAOE,aAAa,yBAGpCH,EAAEI,uBAEIC,UAAY,IAAIC,mBAAU,CAC5BC,YAAa,CACTC,MAAOP,OAAOE,aAAa,gBAE/BM,KAAM,CAACC,QAAST,OAAOE,aAAa,gBAAiBN,SAAAA,UACrDc,UAAWV,OAAOE,aAAa,kBAC/BS,YAAaX,SAKjBI,UAAUN,iBAAiBM,UAAUQ,OAAOC,gBAAgB,KACxDC,SAASC,YAGbX,UAAUY"}
+20
View File
@@ -0,0 +1,20 @@
define("core_block/events",["exports","core/event_dispatcher"],(function(_exports,_event_dispatcher){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.notifyBlockContentUpdated=_exports.eventTypes=void 0;
/**
* Javascript events for the `core_block` subsystem.
*
* @module core_block/events
* @copyright 2021 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 4.0
*
* @example <caption>Example of listening to a block event.</caption>
* import {eventTypes as blockEventTypes} from 'core_block/events';
*
* document.addEventListener(blockEventTypes.blockContentUpdated, e => {
* window.console.log(e.target); // The HTMLElement relating to the block whose content was updated.
* window.console.log(e.detail.instanceId); // The instanceId of the block that was updated.
* });
*/
const eventTypes={blockContentUpdated:"core_block/contentUpdated"};_exports.eventTypes=eventTypes;_exports.notifyBlockContentUpdated=element=>(0,_event_dispatcher.dispatchEvent)(eventTypes.blockContentUpdated,{instanceId:element.dataset.instanceId},element);let legacyEventsRegistered=!1;legacyEventsRegistered||(Y.use("event","moodle-core-event",(Y=>{document.addEventListener(eventTypes.blockContentUpdated,(e=>{Y.Global.fire(M.core.event.BLOCK_CONTENT_UPDATED,{instanceid:e.detail.instanceId})}))})),legacyEventsRegistered=!0)}));
//# sourceMappingURL=events.min.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"events.min.js","sources":["../src/events.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/ //\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript events for the `core_block` subsystem.\n *\n * @module core_block/events\n * @copyright 2021 Andrew Nicols <andrew@nicols.co.uk>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.0\n *\n * @example <caption>Example of listening to a block event.</caption>\n * import {eventTypes as blockEventTypes} from 'core_block/events';\n *\n * document.addEventListener(blockEventTypes.blockContentUpdated, e => {\n * window.console.log(e.target); // The HTMLElement relating to the block whose content was updated.\n * window.console.log(e.detail.instanceId); // The instanceId of the block that was updated.\n * });\n */\n\nimport {dispatchEvent} from 'core/event_dispatcher';\n\n/**\n * Events for `core_block`.\n *\n * @constant\n * @property {String} blockContentUpdated See {@link event:blockContentUpdated}\n */\nexport const eventTypes = {\n /**\n * An event triggered when the content of a block has changed.\n *\n * @event blockContentUpdated\n * @type {CustomEvent}\n * @property {HTMLElement} target The block element that was updated\n * @property {object} detail\n * @property {number} detail.instanceId The block instance id\n */\n blockContentUpdated: 'core_block/contentUpdated',\n};\n\n/**\n * Trigger an event to indicate that the content of a block was updated.\n *\n * @method notifyBlockContentUpdated\n * @param {HTMLElement} element The HTMLElement containing the updated block.\n * @returns {CustomEvent}\n * @fires blockContentUpdated\n */\nexport const notifyBlockContentUpdated = element => dispatchEvent(\n eventTypes.blockContentUpdated,\n {\n instanceId: element.dataset.instanceId,\n },\n element\n);\n\nlet legacyEventsRegistered = false;\nif (!legacyEventsRegistered) {\n // The following event triggers are legacy and will be removed in the future.\n // The following approach provides a backwards-compatability layer for the new events.\n // Code should be updated to make use of native events.\n\n Y.use('event', 'moodle-core-event', Y => {\n // Provide a backwards-compatability layer for YUI Events.\n document.addEventListener(eventTypes.blockContentUpdated, e => {\n // Trigger the legacy YUI event.\n Y.Global.fire(M.core.event.BLOCK_CONTENT_UPDATED, {instanceid: e.detail.instanceId});\n });\n });\n\n legacyEventsRegistered = true;\n}\n"],"names":["eventTypes","blockContentUpdated","element","instanceId","dataset","legacyEventsRegistered","Y","use","document","addEventListener","e","Global","fire","M","core","event","BLOCK_CONTENT_UPDATED","instanceid","detail"],"mappings":";;;;;;;;;;;;;;;;;MAuCaA,WAAa,CAUtBC,oBAAqB,+FAWgBC,UAAW,mCAChDF,WAAWC,oBACX,CACIE,WAAYD,QAAQE,QAAQD,YAEhCD,aAGAG,wBAAyB,EACxBA,yBAKDC,EAAEC,IAAI,QAAS,qBAAqBD,IAEhCE,SAASC,iBAAiBT,WAAWC,qBAAqBS,IAEtDJ,EAAEK,OAAOC,KAAKC,EAAEC,KAAKC,MAAMC,sBAAuB,CAACC,WAAYP,EAAEQ,OAAOf,mBAIhFE,wBAAyB"}
+160
View File
@@ -0,0 +1,160 @@
// 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/>.
/**
* Show an add block modal instead of doing it on a separate page.
*
* @module core_block/add_modal
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Templates from 'core/templates';
import {getString} from 'core/str';
import Ajax from 'core/ajax';
import ModalForm from "core_form/modalform";
import CancelModal from 'core/modal_cancel';
const SELECTORS = {
ADD_BLOCK: '[data-key="addblock"]',
SHOW_BLOCK_FORM: '[data-action="showaddblockform"][data-blockname][data-blockform]'
};
// Ensure we only add our listeners once.
let listenerEventsRegistered = false;
/**
* Register related event listeners.
*
* @method registerListenerEvents
* @param {String|null} addBlockUrl The add block URL
* @param {String} pagehash
*/
const registerListenerEvents = (addBlockUrl, pagehash) => {
let addBlockModal = null;
document.addEventListener('click', e => {
const showAddBlockForm = e.target.closest(SELECTORS.SHOW_BLOCK_FORM);
if (showAddBlockForm) {
e.preventDefault();
const modalForm = new ModalForm({
modalConfig: {
title: getString('addblock', 'core_block',
showAddBlockForm.getAttribute('data-blocktitle')),
},
args: {blockname: showAddBlockForm.getAttribute('data-blockname'), pagehash,
blockregion: showAddBlockForm.getAttribute('data-blockregion')},
formClass: showAddBlockForm.getAttribute('data-blockform'),
returnFocus: showAddBlockForm,
});
modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => {
addBlockModal.destroy();
window.location.reload();
});
modalForm.show();
}
const addBlock = e.target.closest(SELECTORS.ADD_BLOCK);
if (addBlock) {
e.preventDefault();
let addBlockModalUrl = addBlockUrl ?? addBlock.dataset.url;
buildAddBlockModal()
.then(modal => {
addBlockModal = modal;
const modalBody = renderBlocks(addBlockModalUrl, pagehash,
addBlock.getAttribute('data-blockregion'));
modal.setBody(modalBody);
modal.show();
return modalBody;
})
.catch(() => {
addBlockModal.destroy();
});
}
});
};
/**
* Method that creates the 'add block' modal.
*
* @method buildAddBlockModal
* @returns {Promise} The modal promise (modal's body will be rendered later).
*/
const buildAddBlockModal = () => CancelModal.create({
title: getString('addblock'),
});
/**
* Method that renders the list of available blocks.
*
* @method renderBlocks
* @param {String} addBlockUrl The add block URL
* @param {String} pagehash
* @param {String} region
* @return {Promise}
*/
const renderBlocks = async(addBlockUrl, pagehash, region) => {
// Fetch all addable blocks in the given page.
const blocks = await getAddableBlocks(pagehash);
return Templates.render('core/add_block_body', {
blocks: blocks,
url: addBlockUrl,
blockregion: region,
pagehash
});
};
/**
* Method that fetches all addable blocks in a given page.
*
* @method getAddableBlocks
* @param {String} pagehash
* @return {Promise}
*/
const getAddableBlocks = async(pagehash) => {
const request = {
methodname: 'core_block_fetch_addable_blocks',
args: {
pagecontextid: 0,
pagetype: '',
pagelayout: '',
subpage: '',
pagehash: pagehash,
},
};
return Ajax.call([request])[0];
};
/**
* Set up the actions.
*
* @method init
* @param {String} addBlockUrl The add block URL
* @param {String} pagehash
*/
export const init = (addBlockUrl = null, pagehash = '') => {
if (!listenerEventsRegistered) {
registerListenerEvents(addBlockUrl, pagehash);
listenerEventsRegistered = true;
}
};
+59
View File
@@ -0,0 +1,59 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Javascript module for editing blocks
*
* @module core_block/edit
* @copyright 2022 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import ModalForm from 'core_form/modalform';
const SELECTORS = {
EDITBLOCK: '[data-action="editblock"][data-blockid][data-blockform]',
};
/**
* Initialize module
* @param {String} pagehash
*/
export const init = (pagehash) => {
document.addEventListener('click', e => {
const target = e.target.closest(SELECTORS.EDITBLOCK);
if (!target || !target.getAttribute('data-blockform')) {
return;
}
e.preventDefault();
const modalForm = new ModalForm({
modalConfig: {
title: target.getAttribute('data-header'),
},
args: {blockid: target.getAttribute('data-blockid'), pagehash},
formClass: target.getAttribute('data-blockform'),
returnFocus: target,
});
// Reload the page when the form is submitted, there is no possibility
// currently to request contents update of just one block on the page.
modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => {
location.reload();
});
modalForm.show();
});
};
+84
View File
@@ -0,0 +1,84 @@
// This file is part of Moodle - http://moodle.org/ //
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Javascript events for the `core_block` subsystem.
*
* @module core_block/events
* @copyright 2021 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 4.0
*
* @example <caption>Example of listening to a block event.</caption>
* import {eventTypes as blockEventTypes} from 'core_block/events';
*
* document.addEventListener(blockEventTypes.blockContentUpdated, e => {
* window.console.log(e.target); // The HTMLElement relating to the block whose content was updated.
* window.console.log(e.detail.instanceId); // The instanceId of the block that was updated.
* });
*/
import {dispatchEvent} from 'core/event_dispatcher';
/**
* Events for `core_block`.
*
* @constant
* @property {String} blockContentUpdated See {@link event:blockContentUpdated}
*/
export const eventTypes = {
/**
* An event triggered when the content of a block has changed.
*
* @event blockContentUpdated
* @type {CustomEvent}
* @property {HTMLElement} target The block element that was updated
* @property {object} detail
* @property {number} detail.instanceId The block instance id
*/
blockContentUpdated: 'core_block/contentUpdated',
};
/**
* Trigger an event to indicate that the content of a block was updated.
*
* @method notifyBlockContentUpdated
* @param {HTMLElement} element The HTMLElement containing the updated block.
* @returns {CustomEvent}
* @fires blockContentUpdated
*/
export const notifyBlockContentUpdated = element => dispatchEvent(
eventTypes.blockContentUpdated,
{
instanceId: element.dataset.instanceId,
},
element
);
let legacyEventsRegistered = false;
if (!legacyEventsRegistered) {
// The following event triggers are legacy and will be removed in the future.
// The following approach provides a backwards-compatability layer for the new events.
// Code should be updated to make use of native events.
Y.use('event', 'moodle-core-event', Y => {
// Provide a backwards-compatability layer for YUI Events.
document.addEventListener(eventTypes.blockContentUpdated, e => {
// Trigger the legacy YUI event.
Y.Global.fire(M.core.event.BLOCK_CONTENT_UPDATED, {instanceid: e.detail.instanceId});
});
});
legacyEventsRegistered = true;
}
+116
View File
@@ -0,0 +1,116 @@
<?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/>.
/**
* Block for displaying earned local badges to users
*
* @package block_badges
* @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Yuliya Bozhko <yuliya.bozhko@totaralms.com>
*/
class block_badges extends block_base {
public function init() {
global $CFG;
require_once($CFG->libdir . "/badgeslib.php");
$this->title = get_string('pluginname', 'block_badges');
}
public function instance_allow_multiple() {
return true;
}
public function has_config() {
return false;
}
public function instance_allow_config() {
return true;
}
public function applicable_formats() {
return array(
'admin' => false,
'site-index' => true,
'course-view' => true,
'mod' => false,
'my' => true
);
}
public function specialization() {
if (empty($this->config->title)) {
$this->title = get_string('pluginname', 'block_badges');
} else {
$this->title = $this->config->title;
}
}
public function get_content() {
global $USER, $CFG;
if ($this->content !== null) {
return $this->content;
}
if (empty($this->config)) {
$this->config = new stdClass();
}
// Number of badges to display.
if (!isset($this->config->numberofbadges)) {
$this->config->numberofbadges = 10;
}
// Create empty content.
$this->content = new stdClass();
$this->content->text = '';
if (empty($CFG->enablebadges)) {
$this->content->text .= get_string('badgesdisabled', 'badges');
return $this->content;
}
$courseid = $this->page->course->id;
if ($courseid == SITEID) {
$courseid = null;
}
if ($badges = badges_get_user_badges($USER->id, $courseid, 0, $this->config->numberofbadges)) {
$output = $this->page->get_renderer('core', 'badges');
$this->content->text = $output->print_badges_list($badges, $USER->id, true);
} else {
$this->content->text .= get_string('nothingtodisplay', 'block_badges');
}
return $this->content;
}
/**
* This block shouldn't be added to a page if the badges advanced feature is disabled.
*
* @param moodle_page $page
* @return bool
*/
public function can_block_be_added(moodle_page $page): bool {
global $CFG;
return $CFG->enablebadges;
}
}
@@ -0,0 +1,46 @@
<?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_badges.
*
* @package block_badges
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_badges\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for block_badges implementing null_provider.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+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/>.
/**
* Latest badges block capabilities.
*
* @package block_badges
* @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Yuliya Bozhko <yuliya.bozhko@totaralms.com>
*/
$capabilities = array(
'block/badges:addinstance' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
'block/badges:myaddinstance' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW,
),
'clonepermissionsfrom' => 'moodle/my:manageblocks'
),
);
+59
View File
@@ -0,0 +1,59 @@
<?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/>.
/**
* This file keeps track of upgrades to the badges block
*
* Sometimes, changes between versions involve alterations to database structures
* and other major things that may break installations.
*
* The upgrade function in this file will attempt to perform all the necessary
* actions to upgrade your older installation to the current version.
*
* If there's something it cannot do itself, it will tell you what you need to do.
*
* The commands in here will all be database-neutral, using the methods of
* database_manager class
*
* Please do not forget to use upgrade_set_timeout()
* before any action that may take longer time to finish.
*
* @since Moodle 2.8
* @package block_badges
* @copyright 2014 Andrew Davis
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Upgrade the badges block
* @param int $oldversion
* @param object $block
*/
function xmldb_block_badges_upgrade($oldversion, $block) {
// Automatically generated Moodle v4.1.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
+38
View File
@@ -0,0 +1,38 @@
<?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/>.
/**
* Form for editing badges block instances.
*
* @package block_badges
* @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Yuliya Bozhko <yuliya.bozhko@totaralms.com>
*/
class block_badges_edit_form extends block_edit_form {
protected function specific_definition($mform) {
$mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
$numberofbadges = array('0' => get_string('all'));
for ($i = 1; $i <= 20; $i++) {
$numberofbadges[$i] = $i;
}
$mform->addElement('select', 'config_numberofbadges', get_string('numbadgestodisplay', 'block_badges'), $numberofbadges);
$mform->setDefault('config_numberofbadges', 10);
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Language file for block "badges"
*
* @package block_badges
* @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Yuliya Bozhko <yuliya.bozhko@totaralms.com>
*/
$string['pluginname'] = 'Latest badges';
$string['numbadgestodisplay'] = 'Number of latest badges to display';
$string['nothingtodisplay'] = 'You have no badges to display';
$string['badges:addinstance'] = 'Add a new Latest badges block';
$string['badges:myaddinstance'] = 'Add a new Latest badges block to Dashboard';
$string['privacy:metadata'] = 'The Latest badges block only shows data stored in other locations.';
+63
View File
@@ -0,0 +1,63 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace block_badges;
use advanced_testcase;
use block_badges;
use context_course;
/**
* PHPUnit block_badges tests
*
* @package block_badges
* @category test
* @copyright 2021 Sara Arjona (sara@moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @coversDefaultClass \block_badges
*/
class badges_test extends advanced_testcase {
public static function setUpBeforeClass(): void {
require_once(__DIR__ . '/../../moodleblock.class.php');
require_once(__DIR__ . '/../block_badges.php');
}
/**
* 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_badges();
// If badges advanced feature is enabled, the method should return true.
set_config('enablebadges', true);
$this->assertTrue($block->can_block_be_added($page));
// However, if the badges advanced feature is disabled, the method should return false.
set_config('enablebadges', false);
$this->assertFalse($block->can_block_be_added($page));
}
}
@@ -0,0 +1,31 @@
@block @block_badges
Feature: Enable Block Badges in a course without badges
In order to view the badges block in a course
As a teacher
I can add badges block to a course and view the contents
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
Scenario: Add the block to a the course when badges are disabled
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
When I add the "Latest badges" block
And the following config values are set as admin:
| enablebadges | 0 |
And I reload the page
Then I should see "Badges are not enabled on this site." in the "Latest badges" "block"
Scenario: Add the block to a the course when badges are enabled
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
When I add the "Latest badges" block
Then I should see "You have no badges to display" in the "Latest badges" "block"
@@ -0,0 +1,70 @@
@block @block_badges @core_badges @_file_upload @javascript
Feature: Enable Block Badges in a course
In order to enable the badges block in a course
As a teacher
I can add badges block to a course
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
# Issue badge 1 of 2
And I navigate to "Badges > Add a new badge" in current page administration
And I set the following fields to these values:
| id_name | Badge 1 |
| id_description | Badge 1 |
And I upload "blocks/badges/tests/fixtures/badge.png" file to "Image" filemanager
And I press "Create badge"
And I select "Manual issue by role" from the "Add badge criteria" singleselect
And I set the field "Teacher" to "1"
And I press "Save"
And I press "Enable access"
And I press "Continue"
And I select "Recipients (0)" from the "jump" singleselect
And I press "Award badge"
And I set the field "potentialrecipients[]" to "Teacher 1 (teacher1@example.com)"
And I press "Award badge"
# Issue Badge 2 of 2
And I am on "Course 1" course homepage
And I navigate to "Badges > Add a new badge" in current page administration
And I set the following fields to these values:
| id_name | Badge 2 |
| id_description | Badge 2 |
And I upload "blocks/badges/tests/fixtures/badge.png" file to "Image" filemanager
And I press "Create badge"
And I select "Manual issue by role" from the "Add badge criteria" singleselect
And I set the field "Teacher" to "1"
And I press "Save"
And I press "Enable access"
And I press "Continue"
And I select "Recipients (0)" from the "jump" singleselect
And I press "Award badge"
And I set the field "potentialrecipients[]" to "Teacher 1 (teacher1@example.com)"
And I press "Award badge"
And I log out
Scenario: Add the recent badges block to a course.
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
When I add the "Latest badges" block
Then I should see "Badge 1" in the "Latest badges" "block"
And I should see "Badge 2" in the "Latest badges" "block"
Scenario: Add the recent badges block to a course and limit it to only display 1 badge.
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
When I add the "Latest badges" block
And I configure the "Latest badges" block
And I set the following fields to these values:
| Number of latest badges to display | 1 |
And I press "Save changes"
Then I should see "Badge 2" in the "Latest badges" "block"
And I should not see "Badge 1" in the "Latest badges" "block"
@@ -0,0 +1,40 @@
@block @block_badges @core_badges @_file_upload @javascript
Feature: Enable Block Badges on the dashboard and view awarded badges
In order to view recent badges on the dashboard
As a teacher
I can add badges block to the dashboard
Scenario: Add the recent badges block to a course.
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| badges | System | 1 | my-index | side-post |
And I log in as "teacher1"
And I am on "Course 1" course homepage
# Issue badge 1 of 2
And I navigate to "Badges > Add a new badge" in current page administration
And I set the following fields to these values:
| id_name | Badge 1 |
| id_description | Badge 1 |
And I upload "blocks/badges/tests/fixtures/badge.png" file to "Image" filemanager
And I press "Create badge"
And I select "Manual issue by role" from the "Add badge criteria" singleselect
And I set the field "Teacher" to "1"
And I press "Save"
And I press "Enable access"
And I press "Continue"
And I select "Recipients (0)" from the "jump" singleselect
And I press "Award badge"
And I set the field "potentialrecipients[]" to "Teacher 1 (teacher1@example.com)"
And I press "Award badge"
And I log out
When I log in as "teacher1"
Then I should see "Badge 1" in the "Latest badges" "block"
@@ -0,0 +1,38 @@
@block @block_badges @core_badges @_file_upload @javascript
Feature: Enable Block Badges on the frontpage and view awarded badges
In order to enable the badges block on the frontpage
As a admin
I can add badges block to the frontpage
Scenario: Add the recent badges block on the frontpage and view recent badges
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| badges | System | 1 | site-index | side-pre |
And I am on the "Course 1" course page logged in as teacher1
# Issue badge 1 of 2
And I navigate to "Badges > Add a new badge" in current page administration
And I set the following fields to these values:
| id_name | Badge 1 |
| id_description | Badge 1 |
And I upload "blocks/badges/tests/fixtures/badge.png" file to "Image" filemanager
And I press "Create badge"
And I select "Manual issue by role" from the "Add badge criteria" singleselect
And I set the field "Teacher" to "1"
And I press "Save"
And I press "Enable access"
And I press "Continue"
And I select "Recipients (0)" from the "jump" singleselect
And I press "Award badge"
And I set the field "potentialrecipients[]" to "Teacher 1 (teacher1@example.com)"
And I press "Award badge"
When I am on site homepage
Then I should see "Badge 1" in the "Latest badges" "block"
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

+30
View File
@@ -0,0 +1,30 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Version details
*
* @package block_badges
* @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Yuliya Bozhko <yuliya.bozhko@totaralms.com>
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'block_badges';
+138
View File
@@ -0,0 +1,138 @@
<?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/>.
/**
* Blog Menu Block page.
*
* @package block_blog_menu
* @copyright 2009 Nicolas Connault
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* The blog menu block class
*/
class block_blog_menu extends block_base {
function init() {
$this->title = get_string('pluginname', 'block_blog_menu');
}
function instance_allow_multiple() {
return true;
}
function has_config() {
return false;
}
function applicable_formats() {
return array('all' => true, 'my' => false, 'tag' => false);
}
function instance_allow_config() {
return true;
}
function get_content() {
global $CFG, $OUTPUT;
// detect if blog enabled
if ($this->content !== NULL) {
return $this->content;
}
if (empty($CFG->enableblogs)) {
$this->content = new stdClass();
$this->content->text = '';
if ($this->page->user_is_editing()) {
$this->content->text = get_string('blogdisable', 'blog');
}
return $this->content;
} else if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL and (!isloggedin() or isguestuser())) {
$this->content = new stdClass();
$this->content->text = '';
return $this->content;
}
// require necessary libs and get content
require_once($CFG->dirroot .'/blog/lib.php');
// Prep the content
$this->content = new stdClass();
$options = blog_get_all_options($this->page);
if (count($options) == 0) {
$this->content->text = '';
return $this->content;
}
// Iterate the option types
$menulist = array();
foreach ($options as $types) {
foreach ($types as $link) {
$menulist[] = html_writer::link($link['link'], $link['string']);
}
$menulist[] = '<hr />';
}
// Remove the last element (will be an HR)
array_pop($menulist);
// Display the content as a list
$this->content->text = html_writer::alist($menulist, array('class'=>'list'));
// Prepare the footer for this block
if (has_capability('moodle/blog:search', context_system::instance())) {
$data = [
'action' => new moodle_url('/blog/index.php'),
'inputname' => 'search',
'searchstring' => get_string('search', 'admin'),
'extraclasses' => 'mt-3'
];
$this->content->footer = $OUTPUT->render_from_template('core/search_input', $data);
} else {
// No footer to display
$this->content->footer = '';
}
// Return the content object
return $this->content;
}
/**
* Returns the role that best describes the blog menu block.
*
* @return string
*/
public function get_aria_role() {
return 'navigation';
}
/**
* This block shouldn't be added to a page if the blogs advanced feature is disabled.
*
* @param moodle_page $page
* @return bool
*/
public function can_block_be_added(moodle_page $page): bool {
global $CFG;
return $CFG->enableblogs;
}
}
@@ -0,0 +1,46 @@
<?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_blog_menu.
*
* @package block_blog_menu
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_blog_menu\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for block_blog_menu implementing null_provider.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+41
View File
@@ -0,0 +1,41 @@
<?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/>.
/**
* Blog menu block caps.
*
* @package block_blog_menu
* @copyright Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'block/blog_menu:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
);
@@ -0,0 +1,28 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'block_blog_menu', language 'en', branch 'MOODLE_20_STABLE'
*
* @package block_blog_menu
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['blog_menu:addinstance'] = 'Add a new blog menu block';
$string['pluginname'] = 'Blog menu';
$string['privacy:metadata'] = 'The Blog menu block only shows data stored in other locations.';

Some files were not shown because too many files have changed in this diff Show More