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
@@ -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/>.
/**
* Single view report viewed event.
*
* @package gradereport_singleview
* @copyright 2014 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\event;
defined('MOODLE_INTERNAL') || die();
/**
* User report viewed event class.
*
* @package gradereport_singleview
* @since Moodle 2.8
* @copyright 2014 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grade_report_viewed extends \core\event\grade_report_viewed {
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventgradereportviewed', 'gradereport_singleview');
}
/**
* Custom validation.
*
* Throw \coding_exception notice in case of any problems.
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' value must be set.');
}
}
}
+111
View File
@@ -0,0 +1,111 @@
<?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 gradereport_singleview\external;
use context_course;
use core_course_external;
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_warnings;
use grade_tree;
defined('MOODLE_INTERNAL') || die;
require_once($CFG->dirroot.'/course/externallib.php');
require_once($CFG->dirroot.'/grade/lib.php');
/**
* External grade report singleview API
*
* @package gradereport_singleview
* @copyright 2022 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class singleview extends core_course_external {
/**
* Describes the parameters for get_users_for_course.
*
* @return external_function_parameters
*/
public static function get_grade_items_for_search_widget_parameters(): external_function_parameters {
return new external_function_parameters (
[
'courseid' => new external_value(PARAM_INT, 'Course Id', VALUE_REQUIRED)
]
);
}
/**
* Given a course ID find the
*
* @param int $courseid
* @return array Users and warnings to pass back to the calling widget.
* @throws coding_exception
* @throws invalid_parameter_exception
* @throws moodle_exception
* @throws restricted_context_exception
*/
protected static function get_grade_items_for_search_widget(int $courseid): array {
global $PAGE, $USER, $CFG;
$params = self::validate_parameters(
self::get_grade_items_for_search_widget_parameters(),
[
'courseid' => $courseid,
]
);
$warnings = [];
$coursecontext = context_course::instance($params['courseid']);
parent::validate_context($coursecontext);
$gtree = new grade_tree($params['courseid'], false, true, null, !$CFG->enableoutcomes);
$gradeableitems = $gtree->get_items();
$gradeitems = array_map(function ($gradeitem) use ($PAGE, $USER, $params) {
$item = new \stdClass();
$item->id = $gradeitem->id;
$item->name = $gradeitem->get_name(true);
return $item;
}, $gradeableitems);
return [
'gradeitems' => $gradeitems,
'warnings' => $warnings,
];
}
/**
* Returns description of what the user search for the widget should return.
*
* @return external_single_structure
*/
public static function get_grade_items_for_search_widget_returns(): external_single_structure {
return new external_single_structure([
'gradeitems' => new external_multiple_structure(
new external_single_structure([
'id' => new external_value(PARAM_INT, 'ID of the grade item', VALUE_OPTIONAL),
'name' => new external_value(PARAM_TEXT, 'The full name of the grade item', VALUE_OPTIONAL)
])
),
'warnings' => new external_warnings(),
]);
}
}
@@ -0,0 +1,44 @@
<?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/>.
/**
* The gradebook interface for a filterable class.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\screen;
defined('MOODLE_INTERNAL') || die;
/**
* The gradebook interface for a filterable class.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
interface filterable_items {
/**
* Return true/false if this item should be filtered.
* @param mixed $item (user or grade_item)
* @return bool
*/
public static function filter($item): bool;
}
@@ -0,0 +1,428 @@
<?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/>.
/**
* The screen with a list of users.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\screen;
use grade_report;
use gradereport_singleview\local\ui\range;
use gradereport_singleview\local\ui\bulk_insert;
use grade_grade;
use grade_item;
use moodle_url;
use pix_icon;
use html_writer;
use gradereport_singleview;
defined('MOODLE_INTERNAL') || die;
/**
* The screen with a list of users.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grade extends tablelike implements selectable_items, filterable_items {
/**
* Used for paging
* @var int $totalitemcount
*/
private $totalitemcount = 0;
/**
* True if this is a manual grade item
* @var bool $requiresextra
*/
private $requiresextra = false;
/**
* True if there are more users than our limit.
* @var bool $requirepaging
*/
private $requirespaging = true;
/**
* To store UI element that generates a grade_item min/max range.
* @var range;
*/
protected $range;
/**
* Returns a grade_item instance or false if none found.
* @var grade_item|bool
*/
public $item;
/**
* True if $CFG->grade_overridecat is true
*
* @return bool
*/
public static function allowcategories(): bool {
return get_config('moodle', 'grade_overridecat');
}
/**
* Filter the list excluding category items (if required)?
* @param grade_item $item The grade item.
* @return bool
*/
public static function filter($item): bool {
return get_config('moodle', 'grade_overridecat') ||
!($item->is_course_item() || $item->is_category_item());
}
/**
* Get the label for the select box that chooses items for this page.
* @return string
*/
public function select_label(): string {
return get_string('selectuser', 'gradereport_singleview');
}
/**
* Get the description of this page
* @return string
*/
public function description(): string {
return get_string('users');
}
/**
* Convert this list of items into an options list
*
* @return array
*/
public function options(): array {
$options = [];
foreach ($this->items as $userid => $user) {
$options[$userid] = fullname($user);
}
return $options;
}
/**
* Return the type of the things in this list.
* @return string
*/
public function item_type(): string {
return 'user';
}
/**
* Get the original settings for this item
* @return array
*/
public function original_definition(): array {
return [
'finalgrade',
'feedback',
'override',
'exclude'
];
}
/**
* Init this page
*
* @param bool $selfitemisempty True if we have not selected a user.
*/
public function init($selfitemisempty = false) {
$this->items = grade_report::get_gradable_users($this->courseid, $this->groupid);
$this->totalitemcount = count($this->items);
if ($selfitemisempty) {
return;
}
// If we change perpage on pagination we might end up with a page that doesn't exist.
if ($this->perpage) {
$numpages = intval($this->totalitemcount / $this->perpage) + 1;
if ($numpages <= $this->page) {
$this->page = 0;
}
} else {
$this->page = 0;
}
$params = [
'id' => $this->itemid,
'courseid' => $this->courseid
];
$this->item = grade_item::fetch($params);
if (!self::filter($this->item)) {
$this->items = [];
$this->set_init_error(get_string('gradeitemcannotbeoverridden', 'gradereport_singleview'));
}
$this->requiresextra = !$this->item->is_manual_item();
$this->setup_structure();
$this->set_definition($this->original_definition());
$this->set_headers($this->original_headers());
}
/**
* Get the table headers
*
* @return array
*/
public function original_headers() {
return [
get_string('fullnameuser', 'core'),
'', // For filter icon.
get_string('gradenoun'),
get_string('range', 'grades'),
get_string('feedback', 'grades'),
get_string('override', 'gradereport_singleview'),
get_string('exclude', 'gradereport_singleview'),
];
}
/**
* Format a row in the table
*
* @param stdClass $item
* @return array
*/
public function format_line($item): array {
global $OUTPUT;
$grade = $this->fetch_grade_or_default($this->item, $item->id);
$gradestatus = '';
$context = [
'hidden' => $grade->is_hidden(),
'locked' => $grade->is_locked(),
];
if (in_array(true, $context)) {
$context['classes'] = 'gradestatus';
$gradestatus = $OUTPUT->render_from_template('core_grades/status_icons', $context);
}
if (has_capability('moodle/site:viewfullnames', \context_course::instance($this->courseid))) {
$fullname = fullname($item, true);
} else {
$fullname = fullname($item);
}
$item->imagealt = $fullname;
$url = new moodle_url("/user/view.php", ['id' => $item->id, 'course' => $this->courseid]);
$grade->label = $fullname;
$userpic = $OUTPUT->user_picture($item, ['link' => false, 'visibletoscreenreaders' => false]);
$formatteddefinition = $this->format_definition($grade);
$line = [
html_writer::link($url, $userpic . $fullname),
$this->get_user_action_menu($item),
$formatteddefinition['finalgrade'] . $gradestatus,
$this->item_range(),
$formatteddefinition['feedback'],
$formatteddefinition['override'],
$formatteddefinition['exclude'],
];
$lineclasses = [
'user',
'action',
'grade',
'range',
];
$outputline = [];
$i = 0;
foreach ($line as $key => $value) {
$cell = new \html_table_cell($value);
if ($isheader = $i == 0) {
$cell->header = $isheader;
$cell->scope = "row";
}
if (array_key_exists($key, $lineclasses)) {
$cell->attributes['class'] = $lineclasses[$key];
}
$outputline[] = $cell;
$i++;
}
return $outputline;
}
/**
* Get the range ui element for this grade_item
*
* @return element;
*/
public function item_range() {
if (empty($this->range)) {
$this->range = new range($this->item);
}
return $this->range;
}
/**
* Does this page require paging?
*
* @return bool
*/
public function supports_paging(): bool {
return $this->requirespaging;
}
/**
* Get the pager for this page.
*
* @return string
*/
public function pager(): string {
global $OUTPUT;
return $OUTPUT->paging_bar(
$this->totalitemcount, $this->page, $this->perpage,
new moodle_url('/grade/report/singleview/index.php', [
'perpage' => $this->perpage,
'id' => $this->courseid,
'group' => $this->groupid,
'itemid' => $this->itemid,
'item' => 'grade'
])
);
}
/**
* Get the heading for this page.
*
* @return string
*/
public function heading(): string {
global $PAGE;
$headinglangstring = $PAGE->user_is_editing() ? 'gradeitemedit' : 'gradeitem';
return get_string($headinglangstring, 'gradereport_singleview', $this->item->get_name());
}
/**
* Get the summary for this table.
*
* @return string
*/
public function summary(): string {
return get_string('summarygrade', 'gradereport_singleview');
}
/**
* Process the data from the form.
*
* @param array $data
* @return \stdClass of warnings
*/
public function process($data): \stdClass {
$bulk = new bulk_insert($this->item);
// Bulk insert messages the data to be passed in
// ie: for all grades of empty grades apply the specified value.
if ($bulk->is_applied($data)) {
$filter = $bulk->get_type($data);
$insertvalue = $bulk->get_insert_value($data);
// Appropriately massage data that may not exist.
if ($this->supports_paging()) {
$gradeitem = grade_item::fetch([
'courseid' => $this->courseid,
'id' => $this->item->id
]);
$null = $gradeitem->gradetype == GRADE_TYPE_SCALE ? -1 : '';
foreach ($this->items as $itemid => $item) {
$field = "finalgrade_{$gradeitem->id}_{$itemid}";
if (isset($data->$field)) {
continue;
}
$grade = grade_grade::fetch([
'itemid' => $gradeitem->id,
'userid' => $itemid
]);
$data->$field = empty($grade) ? $null : $grade->finalgrade;
$data->{"old$field"} = $data->$field;
}
}
foreach ($data as $varname => $value) {
if (preg_match('/^oldoverride_(\d+)_(\d+)/', $varname, $matches)) {
// If we've selected overriding all grades.
if ($filter == 'all') {
$override = "override_{$matches[1]}_{$matches[2]}";
$data->$override = '1';
}
}
if (!preg_match('/^finalgrade_(\d+)_/', $varname, $matches)) {
continue;
}
$gradeitem = grade_item::fetch([
'courseid' => $this->courseid,
'id' => $matches[1]
]);
$isscale = ($gradeitem->gradetype == GRADE_TYPE_SCALE);
$empties = (trim($value) === '' || ($isscale && $value == -1));
if ($filter == 'all' || $empties) {
$data->$varname = ($isscale && empty($insertvalue)) ?
-1 : $insertvalue;
}
}
}
return parent::process($data);
}
/**
* Return the action menu HTML for the user item.
*
* @param \stdClass $user
* @return mixed
*/
private function get_user_action_menu(\stdClass $user) {
global $OUTPUT;
$menuitems = [];
$url = new moodle_url($this->format_link('user', $user->id));
$title = get_string('showallgrades', 'core_grades');
$menuitems[] = new \action_menu_link_secondary($url, null, $title);
$menu = new \action_menu($menuitems);
$icon = $OUTPUT->pix_icon('i/moremenu', get_string('actions'));
$extraclasses = 'btn btn-link btn-icon icon-size-3 d-flex align-items-center justify-content-center';
$menu->set_menu_trigger($icon, $extraclasses);
$menu->set_menu_left();
$menu->set_boundary('window');
return $OUTPUT->render($menu);
}
}
@@ -0,0 +1,85 @@
<?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 gradereport_singleview\local\screen;
/**
* The grade search screen.
*
* @package gradereport_singleview
* @copyright 2022 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grade_select extends screen {
public function init($selfitemisempty = false) {
}
/**
* Return the HTML for the page.
*
* @return string
*/
public function html(): string {
global $OUTPUT, $COURSE, $USER;
$userlink = new \moodle_url('/grade/report/singleview/index.php', ['id' => $COURSE->id, 'item' => 'user_select']);
$gradelink = new \moodle_url('/grade/report/singleview/index.php', ['id' => $COURSE->id, 'item' => 'grade_select']);
$gpr = new \grade_plugin_return(['type' => 'report', 'plugin' => 'singleview', 'courseid' => $COURSE->id,
'userid' => $USER->id]);
$context = [
'courseid' => $gpr->courseid,
'imglink' => $OUTPUT->image_url('zero_state_grade', 'gradereport_singleview'),
'userzerolink' => $userlink->out(false),
'userselectactive' => false,
'gradezerolink' => $gradelink->out(false),
'gradeselectactive' => true,
'displaylabel' => true,
'groupmodeenabled' => $COURSE->groupmode,
'groupactionbaseurl' => 'index.php?item=grade_select',
'groupid' => $gpr->groupid
];
return $OUTPUT->render_from_template('gradereport_singleview/zero_state_grade', $context);
}
public function item_type(): ?string {
return false;
}
/**
* Should we show the base singlereport group selector?
* @return bool
*/
public function display_group_selector(): bool {
return false;
}
/**
* Get the heading for the screen.
*
* @return string
*/
public function heading(): string {
return ' ';
}
/**
* Does this screen support paging?
*
* @return bool
*/
public function supports_paging(): bool {
return false;
}
}
@@ -0,0 +1,466 @@
<?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/>.
/**
* Abstract class used as a base for the 3 screens.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\screen;
use context_course;
use grade_report;
use moodle_url;
use html_writer;
use grade_structure;
use grade_grade;
use grade_item;
use stdClass;
defined('MOODLE_INTERNAL') || die;
require_once($CFG->dirroot . '/grade/report/lib.php');
/**
* Abstract class used as a base for the 3 screens.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class screen {
/**
* The id of the course
* @var int $courseid
*/
protected $courseid;
/**
* Either a user id or a grade_item id
* @var int|null $itemid
*/
protected $itemid;
/**
* The currently set groupid (if set)
* @var int $groupid
*/
protected $groupid;
/**
* The course context
* @var context_course $context
*/
protected $context;
/**
* The page number
* @var int $page
*/
protected $page;
/**
* Results per page
* @var int $perpage
*/
protected $perpage;
/**
* List of items on the page, they could be users or grade_items
* @var array $items
*/
protected $items;
/** @var int Maximum number of students that can be shown on one page */
protected static $maxperpage = 5000;
/**
* List of allowed values for 'perpage' setting
* @var array $validperpage
*/
protected static $validperpage = [20, 100];
/**
* To store course data
* @var stdClass
*/
protected $course;
/**
* General structure representing grade items in course
* @var grade_structure
*/
protected $structure;
/**
* Constructor
*
* @param int $courseid The course id
* @param int|null $itemid The item id
* @param int|null $groupid The group id
*/
public function __construct(int $courseid, ?int $itemid, ?int $groupid = null) {
global $DB;
$this->courseid = $courseid;
$this->itemid = $itemid;
$this->groupid = $groupid;
$this->context = context_course::instance($this->courseid);
$this->course = $DB->get_record('course', ['id' => $courseid]);
$this->page = optional_param('page', 0, PARAM_INT);
$cache = \cache::make_from_params(\cache_store::MODE_SESSION, 'gradereport_singleview', 'perpage');
$perpage = optional_param('perpage', null, PARAM_INT);
if (!in_array($perpage, self::$validperpage) && ($perpage !== 0)) {
// Get from cache.
$perpage = $cache->get(get_class($this));
} else {
// Save to cache.
$cache->set(get_class($this), $perpage);
}
if (isset($perpage) && $perpage) {
$this->perpage = $perpage;
} else {
// Get from cache.
$perpage = $cache->get(get_class($this));
$this->perpage = ($perpage === 0) ? $perpage : min(self::$validperpage);
}
$this->init(empty($itemid));
}
/**
* Cache the grade_structure class
*/
public function setup_structure() {
$this->structure = new grade_structure();
$this->structure->modinfo = get_fast_modinfo($this->course);
}
/**
* Create a nice link from a thing (user or grade_item).
*
* @param string $screen
* @param int $itemid
* @param bool|null $display Should we wrap this in an anchor ?
* @return string The link
*/
public function format_link(string $screen, int $itemid, bool $display = null): string {
$url = new moodle_url('/grade/report/singleview/index.php', [
'id' => $this->courseid,
'item' => $screen,
'itemid' => $itemid,
'group' => $this->groupid,
]);
if ($display) {
return html_writer::link($url, $display);
} else {
return $url;
}
}
/**
* Get the grade_grade
*
* @param grade_item $item The grade_item
* @param int $userid The user id
* @return grade_grade
*/
public function fetch_grade_or_default(grade_item $item, int $userid): grade_grade {
$grade = grade_grade::fetch([
'itemid' => $item->id, 'userid' => $userid
]);
if (!$grade) {
$default = new stdClass;
$default->userid = $userid;
$default->itemid = $item->id;
$default->feedback = '';
$grade = new grade_grade($default, false);
}
$grade->grade_item = $item;
return $grade;
}
/**
* Get the default heading for the screen.
*
* @return string
*/
public function heading(): string {
return get_string('entrypage', 'gradereport_singleview');
}
/**
* Override this to init the screen.
*
* @param boolean $selfitemisempty True if no item has been selected yet.
*/
abstract public function init(bool $selfitemisempty = false);
/**
* Get the type of items in the list.
*
* @return null|string
*/
abstract public function item_type(): ?string;
/**
* Get the entire screen as a string.
*
* @return string
*/
abstract public function html(): string;
/**
* Does this screen support paging?
*
* @return bool
*/
public function supports_paging(): bool {
return true;
}
/**
* Default pager
*
* @return string
*/
public function pager(): string {
return '';
}
/**
* Initialise the js for this screen.
*/
public function js() {
global $PAGE;
$module = [
'name' => 'gradereport_singleview',
'fullpath' => '/grade/report/singleview/js/singleview.js',
'requires' => ['base', 'dom', 'event', 'event-simulate', 'io-base']
];
$PAGE->requires->strings_for_js(['overridenoneconfirm', 'removeoverride', 'removeoverridesave'],
'gradereport_singleview');
$PAGE->requires->js_init_call('M.gradereport_singleview.init', [], false, $module);
}
/**
* Process the data from a form submission.
*
* @param array|object $data
* @return stdClass of warnings
*/
public function process($data): stdClass {
$warnings = [];
$fields = $this->definition();
// Avoiding execution timeouts when updating
// a large amount of grades.
$progress = 0;
$progressbar = new \core\progress\display_if_slow();
$progressbar->start_html();
$progressbar->start_progress(get_string('savegrades', 'gradereport_singleview'), count((array) $data) - 1);
$changecount = [];
// This array is used to determine if the override should be excluded from being counted as a change.
$ignorevalues = [];
foreach ($data as $varname => $throw) {
$progressbar->progress($progress);
$progress++;
if (preg_match("/(\w+)_(\d+)_(\d+)/", $varname, $matches)) {
$itemid = $matches[2];
$userid = $matches[3];
} else {
continue;
}
$gradeitem = grade_item::fetch([
'id' => $itemid, 'courseid' => $this->courseid
]);
if (preg_match('/^old[oe]{1}/', $varname)) {
$elementname = preg_replace('/^old/', '', $varname);
if (!isset($data->$elementname)) {
// Decrease the progress because we've increased the
// size of the array we are iterating through.
$progress--;
$data->$elementname = false;
}
}
if (!in_array($matches[1], $fields)) {
continue;
}
if (!$gradeitem) {
continue;
}
$grade = $this->fetch_grade_or_default($gradeitem, $userid);
$classname = '\\gradereport_singleview\\local\\ui\\' . $matches[1];
$element = new $classname($grade);
$name = $element->get_name();
$oldname = "old$name";
$posted = $data->$name;
$format = $element->determine_format();
if ($format->is_textbox() and trim($data->$name) === '') {
$data->$name = null;
}
// Same value; skip.
if (isset($data->$oldname) && $data->$oldname == $posted) {
continue;
}
// If the user submits Exclude grade elements without the proper.
// permissions then we should refuse to update.
if ($matches[1] === 'exclude' && !has_capability('moodle/grade:manage', $this->context)){
$warnings[] = get_string('nopermissions', 'error', get_string('grade:manage', 'role'));
continue;
}
$msg = $element->set($posted);
// Value to check against our list of matchelements to ignore.
$check = explode('_', $varname, 2);
// Optional type.
if (!empty($msg)) {
$warnings[] = $msg;
if ($element instanceof \gradereport_singleview\local\ui\finalgrade) {
// Add this value to this list so that the override object that is coming next will also be skipped.
$ignorevalues[$check[1]] = $check[1];
// This item wasn't changed so don't add to the changecount.
continue;
}
}
// Check to see if this value has already been skipped.
if (array_key_exists($check[1], $ignorevalues)) {
continue;
}
if (preg_match('/_(\d+)_(\d+)/', $varname, $matchelement)) {
$changecount[$matchelement[0]] = 1;
}
}
// Some post-processing.
$eventdata = new stdClass;
$eventdata->warnings = $warnings;
$eventdata->post_data = $data;
$eventdata->instance = $this;
$eventdata->changecount = $changecount;
$progressbar->end_html();
return $eventdata;
}
/**
* By default, there are no options.
* @return array
*/
public function options(): array {
return [];
}
/**
* Should we show the group selector?
* @return bool
*/
public function display_group_selector(): bool {
return true;
}
/**
* Should we show the next prev selector?
* @return bool
*/
public function supports_next_prev(): bool {
return true;
}
/**
* Load a valid list of users for this gradebook as the screen "items".
*
* @deprecated since Moodle 4.3
* @return array A list of enroled users.
*/
protected function load_users(): array {
debugging('The function ' . __FUNCTION__ . '() is deprecated. Please use grade_report::get_gradable_users() instead.',
DEBUG_DEVELOPER);
return grade_report::get_gradable_users($this->courseid, $this->groupid);
}
/**
* Allow selection of number of items to display per page.
* @return string
*/
public function perpage_select(): string {
global $PAGE, $OUTPUT;
$url = new moodle_url($PAGE->url);
$numusers = count($this->items);
// Print per-page dropdown.
$pagingoptions = self::$validperpage;
if ($this->perpage) {
$pagingoptions[] = $this->perpage; // To make sure the current preference is within the options.
}
$pagingoptions = array_unique($pagingoptions);
sort($pagingoptions);
$pagingoptions = array_combine($pagingoptions, $pagingoptions);
if ($numusers > self::$maxperpage) {
$pagingoptions['0'] = self::$maxperpage;
} else {
$pagingoptions['0'] = get_string('all');
}
$perpagedata = [
'baseurl' => $url->out(false),
'options' => []
];
foreach ($pagingoptions as $key => $name) {
$perpagedata['options'][] = [
'name' => $name,
'value' => $key,
'selected' => $key == $this->perpage,
];
}
// The number of students per page is always limited even if it is claimed to be unlimited.
$this->perpage = $this->perpage ?: self::$maxperpage;
$perpagedata['pagingbar'] = $this->pager();
return $OUTPUT->render_from_template('gradereport_singleview/perpage', $perpagedata);;
}
}
@@ -0,0 +1,205 @@
<?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/>.
/**
* The gradebook simple view - initial view to select your search options
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\screen;
use gradereport_singleview;
use moodle_url;
defined('MOODLE_INTERNAL') || die;
/**
* The gradebook simple view - initial view to select your search options
*
* @deprecated since Moodle 4.3
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class select extends screen {
/** @var \stdClass course data. */
public $item;
/**
* Initialise this screen
*
* @deprecated since Moodle 4.3
* @param bool $selfitemisempty Has an item been selected (will be false)
*/
public function init($selfitemisempty = false) {
global $DB;
debugging('The function ' . __FUNCTION__ . '() is deprecated as part of the deprecation process of the ' .
'\gradereport_singleview\local\screen\select class which is no longer used.', DEBUG_DEVELOPER);
$roleids = explode(',', get_config('moodle', 'gradebookroles'));
$this->items = [];
foreach ($roleids as $roleid) {
// Keeping the first user appearance.
$this->items = $this->items + get_role_users(
$roleid, $this->context, false, '',
'u.id, u.lastname, u.firstname', null, $this->groupid,
$this->perpage * $this->page, $this->perpage
);
}
$this->item = $DB->get_record('course', ['id' => $this->courseid]);
}
/**
* Get the type of items on this screen, not valid so return false.
*
* @deprecated since Moodle 4.3
* @return string|null
*/
public function item_type(): ?string {
debugging('The function ' . __FUNCTION__ . '() is deprecated as part of the deprecation process of the ' .
'\gradereport_singleview\local\screen\select class which is no longer used.', DEBUG_DEVELOPER);
return false;
}
/**
* Return the HTML for the page.
*
* @deprecated since Moodle 4.3
* @return string
*/
public function html(): string {
global $OUTPUT, $COURSE;
debugging('The function ' . __FUNCTION__ . '() is deprecated as part of the deprecation process of the ' .
'\gradereport_singleview\local\screen\select class which is no longer used.', DEBUG_DEVELOPER);
if ($this->itemid === null) {
$userlink = new \moodle_url('/grade/report/singleview/index.php', ['id' => $COURSE->id, 'item' => 'user_select']);
$gradelink = new \moodle_url('/grade/report/singleview/index.php', ['id' => $COURSE->id, 'item' => 'grade_select']);
$context = [
'courseid' => $COURSE->id,
'imglink' => $OUTPUT->image_url('zero_state', 'gradereport_singleview'),
'userzerolink' => $userlink->out(false),
'userselectactive' => false,
'gradezerolink' => $gradelink->out(false),
'gradeselectactive' => false,
'displaylabel' => false
];
return $OUTPUT->render_from_template('gradereport_singleview/zero_state', $context);
}
$html = '';
$types = gradereport_singleview\report\singleview::valid_screens();
foreach ($types as $type) {
$classname = "gradereport_singleview\\local\\screen\\{$type}";
$screen = new $classname($this->courseid, null, $this->groupid);
if (!$screen instanceof selectable_items) {
continue;
}
$options = $screen->options();
if (empty($options)) {
continue;
}
$params = [
'id' => $this->courseid,
'item' => $screen->item_type(),
'group' => $this->groupid
];
$url = new moodle_url('/grade/report/singleview/index.php', $params);
$select = new \single_select($url, 'itemid', $options, '', ['' => $screen->select_label()]);
$select->set_label($screen->select_label(), ['class' => 'accesshide']);
$html .= $OUTPUT->render($select);
}
$html = $OUTPUT->container($html, 'selectitems');
if (empty($html)) {
$OUTPUT->notification(get_string('noscreens', 'gradereport_singleview'));
}
return $html;
}
/**
* Should we show the next prev selector?
*
* @deprecated since Moodle 4.3
* @return bool
*/
public function supports_next_prev(): bool {
debugging('The function ' . __FUNCTION__ . '() is deprecated as part of the deprecation process of the ' .
'\gradereport_singleview\local\screen\select class which is no longer used.', DEBUG_DEVELOPER);
return false;
}
/**
* Should we show the base singlereport group selector?
*
* @deprecated since Moodle 4.3
* @return bool
*/
public function display_group_selector(): bool {
debugging('The function ' . __FUNCTION__ . '() is deprecated as part of the deprecation process of the ' .
'\gradereport_singleview\local\screen\select class which is no longer used.', DEBUG_DEVELOPER);
if ($this->itemid === null) {
return false;
}
return true;
}
/**
* Get the heading for the screen.
*
* @deprecated since Moodle 4.3
* @return string
*/
public function heading(): string {
debugging('The function ' . __FUNCTION__ . '() is deprecated as part of the deprecation process of the ' .
'\gradereport_singleview\local\screen\select class which is no longer used.', DEBUG_DEVELOPER);
return ' ';
}
/**
* Does this screen support paging?
*
* @deprecated since Moodle 4.3
* @return bool
*/
public function supports_paging(): bool {
debugging('The function ' . __FUNCTION__ . '() is deprecated as part of the deprecation process of the ' .
'\gradereport_singleview\local\screen\select class which is no longer used.', DEBUG_DEVELOPER);
return false;
}
}
@@ -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/>.
/**
* Interface for a list of selectable things.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\screen;
defined('MOODLE_INTERNAL') || die;
/**
* Interface for a list of selectable things.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
interface selectable_items {
/**
* Get the description of this list
* @return string
*/
public function description(): string;
/**
* Get the label for the select box that chooses items for this page.
* @return string
*/
public function select_label(): string;
/**
* Get the list of options to show.
* @return array
*/
public function options(): array;
/**
* Get type of things in the list (gradeitem or user)
* @return string
*/
public function item_type(): string;
}
@@ -0,0 +1,265 @@
<?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/>.
/**
* The gradebook simple view - base class for the table
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\screen;
use gradereport_singleview\local\ui\be_readonly;
use html_table;
use html_writer;
use stdClass;
use grade_grade;
use gradereport_singleview\local\ui\bulk_insert;
defined('MOODLE_INTERNAL') || die;
/**
* The gradebook simple view - base class for the table
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class tablelike extends screen implements be_readonly {
/**
* A list of table headers
* @var array $headers
*/
protected $headers = [];
/**
* A list of errors that mean we should not show the table
* @var array $initerrors
*/
protected $initerrors = [];
/**
* Describes the columns in the table
* @var array $definition
*/
protected $definition = [];
/**
* Total items
* @var int $total
*/
protected $total;
/**
* Table tab index
* @var int $index
*/
protected $index;
/**
* The grade item or user.
* @var mixed $item
*/
protected $item;
/**
* Format a row of the table
*
* @var mixed $item
* @return array
*/
abstract public function format_line($item): array;
/**
* Get the summary for this table.
*
* @return string
*/
abstract public function summary(): string;
/**
* Get the table headers
*
* @return array
*/
public function headers(): array {
return $this->headers;
}
/**
* Set the table headers
*
* @param array $overwrite New headers
* @return tablelike This
*/
public function set_headers(array $overwrite): tablelike {
$this->headers = $overwrite;
return $this;
}
/**
* Get the list of errors
*
* @return array
*/
public function init_errors(): array {
return $this->initerrors;
}
/**
* Set an error detected while building the page.
*
* @param string $mesg
*/
public function set_init_error(string $mesg) {
$this->initerrors[] = $mesg;
}
/**
* Get the table definition
*
* @return array The definition.
*/
public function definition(): array {
return $this->definition;
}
/**
* Set the table definition
*
* @param array $overwrite New definition
* @return tablelike This
*/
public function set_definition(array $overwrite): tablelike {
$this->definition = $overwrite;
return $this;
}
/**
* Get a element to generate the HTML for this table row
* @param grade_grade $grade The grade.
* @return array
*/
public function format_definition(grade_grade $grade): array {
$line = [];
foreach ($this->definition() as $i => $field) {
// Table tab index.
$tab = ($i * $this->total) + $this->index;
$classname = '\\gradereport_singleview\\local\\ui\\' . $field;
$html = new $classname($grade, $tab);
if ($field == 'finalgrade' and !empty($this->structure)) {
$html .= $this->structure->get_grade_action_menu($grade);
}
// Singleview users without proper permissions should be presented
// disabled checkboxes for the Exclude grade attribute.
if ($field == 'exclude' && !has_capability('moodle/grade:manage', $this->context)) {
$html->disabled = true;
}
$line[$field] = $html;
}
return $line;
}
/**
* Get the HTML for the whole table
* @return string
*/
public function html(): string {
global $OUTPUT;
if (!empty($this->initerrors)) {
$warnings = '';
foreach ($this->initerrors as $mesg) {
$warnings .= $OUTPUT->notification($mesg);
}
return $warnings;
}
$table = new html_table();
$table->id = 'singleview-grades';
$table->head = $this->headers();
$summary = $this->summary();
if (!empty($summary)) {
$table->caption = $summary;
$table->captionhide = true;
}
// To be used for extra formatting.
$this->index = 0;
$this->total = count($this->items);
foreach ($this->items as $item) {
if ($this->index >= ($this->perpage * $this->page) &&
$this->index < ($this->perpage * ($this->page + 1))) {
$table->data[] = $this->format_line($item);
}
$this->index++;
}
$data = new stdClass();
$data->table = $table;
$data->instance = $this;
$html = html_writer::table($table);
return html_writer::div($html, 'reporttable position-relative');
}
/**
* Get the HTML for the bulk insert form
*
* @return string
*/
public function bulk_insert() {
return html_writer::tag(
'div',
(new bulk_insert($this->item))->html(),
['class' => 'singleview_bulk', 'hidden' => 'hidden']
);
}
/**
* Return true if this is read-only.
*
* @return bool
*/
public function is_readonly(): bool {
global $USER;
return empty($USER->editing);
}
/**
* Get the buttons for saving changes.
* @param bool $disabled If button is disabled
*
* @return array
*/
public function buttons(bool $disabled = false): array {
global $OUTPUT;
$params = ['type' => 'submit', 'value' => get_string('save', 'gradereport_singleview')];
if ($disabled) {
$params['disabled'] = 'disabled';
}
return [$OUTPUT->render_from_template('gradereport_singleview/button', $params)];
}
}
@@ -0,0 +1,432 @@
<?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/>.
/**
* The user screen.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\screen;
use grade_seq;
use gradereport_singleview;
use moodle_url;
use pix_icon;
use html_writer;
use gradereport_singleview\local\ui\range;
use gradereport_singleview\local\ui\bulk_insert;
use grade_item;
use grade_grade;
use stdClass;
defined('MOODLE_INTERNAL') || die;
/**
* The user screen.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user extends tablelike implements selectable_items {
/** @var array $categories A cache for grade_item categories */
private $categories = [];
/** @var int $requirespaging Do we have more items than the paging limit? */
private $requirespaging = true;
/** @var array get a valid user. */
public $item = [];
/**
* Get the label for the select box that chooses items for this page.
* @return string
*/
public function select_label(): string {
return get_string('selectgrade', 'gradereport_singleview');
}
/**
* Get the description for the screen.
*
* @return string
*/
public function description(): string {
return get_string('gradeitems', 'grades');
}
/**
* Convert the list of items to a list of options.
*
* @return array
*/
public function options(): array {
$result = [];
foreach ($this->items as $itemid => $item) {
$result[$itemid] = $item->get_name();
}
return $result;
}
/**
* Get the type of items on this screen.
*
* @return string
*/
public function item_type(): string {
return 'grade';
}
/**
* Init the screen
*
* @param bool $selfitemisempty Have we selected an item yet?
*/
public function init($selfitemisempty = false) {
if (!$selfitemisempty) {
$validusers = \grade_report::get_gradable_users($this->courseid, $this->groupid);
if (!isset($validusers[$this->itemid])) {
// If the passed user id is not valid, show the first user from the list instead.
$this->item = reset($validusers);
$this->itemid = $this->item->id;
} else {
$this->item = $validusers[$this->itemid];
}
}
$seq = new grade_seq($this->courseid, true);
$this->items = [];
foreach ($seq->items as $itemid => $item) {
if (grade::filter($item)) {
$this->items[$itemid] = $item;
}
}
// If we change perpage on pagination we might end up with a page that doesn't exist.
if ($this->perpage) {
$numpages = intval(count($this->items) / $this->perpage) + 1;
if ($numpages <= $this->page) {
$this->page = 0;
}
} else {
$this->page = 0;
}
$this->requirespaging = count($this->items) > $this->perpage;
$this->setup_structure();
$this->definition = [
'finalgrade', 'feedback', 'override', 'exclude'
];
$this->set_headers($this->original_headers());
}
/**
* Get the list of headers for the table.
*
* @return array List of headers
*/
public function original_headers(): array {
return [
get_string('assessmentname', 'gradereport_singleview'),
'', // For filter icon.
get_string('gradecategory', 'grades'),
get_string('gradenoun'),
get_string('range', 'grades'),
get_string('feedback', 'grades'),
get_string('override', 'gradereport_singleview'),
get_string('exclude', 'gradereport_singleview'),
];
}
/**
* Format each row of the table.
*
* @param grade_item $item
* @return array
*/
public function format_line($item): array {
global $OUTPUT;
$grade = $this->fetch_grade_or_default($item, $this->item->id);
$gradestatus = '';
$context = [
'hidden' => $grade->is_hidden(),
'locked' => $grade->is_locked(),
];
if (in_array(true, $context)) {
$context['classes'] = 'gradestatus';
$gradestatus = $OUTPUT->render_from_template('core_grades/status_icons', $context);
}
// Create a fake gradetreeitem so we can call get_element_header().
// The type logic below is from grade_category->_get_children_recursion().
$gradetreeitem = [];
$type = in_array($item->itemtype, ['course', 'category']) ? "{$item->itemtype}item" : 'item';
$gradetreeitem['type'] = $type;
$gradetreeitem['object'] = $item;
$gradetreeitem['userid'] = $this->item->id;
$itemname = \grade_helper::get_element_header($gradetreeitem, true, false, false, false, true);
$grade->label = $item->get_name();
$formatteddefinition = $this->format_definition($grade);
$itemicon = html_writer::div($this->format_icon($item), 'mr-1');
$itemtype = \html_writer::span(\grade_helper::get_element_type_string($gradetreeitem),
'd-block text-uppercase small dimmed_text');
$itemtitle = html_writer::div($itemname, 'rowtitle');
$itemcontent = html_writer::div($itemtype . $itemtitle);
$line = [
html_writer::div($itemicon . $itemcontent, "{$type} d-flex align-items-center"),
$this->get_item_action_menu($item),
$this->category($item),
$formatteddefinition['finalgrade'] . $gradestatus,
new range($item),
$formatteddefinition['feedback'],
$formatteddefinition['override'],
$formatteddefinition['exclude'],
];
$lineclasses = [
'gradeitem',
'action',
'category',
'grade',
'range',
];
$outputline = [];
$i = 0;
foreach ($line as $key => $value) {
$cell = new \html_table_cell($value);
if ($isheader = $i == 0) {
$cell->header = $isheader;
$cell->scope = "row";
}
if (array_key_exists($key, $lineclasses)) {
$cell->attributes['class'] = $lineclasses[$key];
}
$outputline[] = $cell;
$i++;
}
return $outputline;
}
/**
* Helper to get the icon for an item.
*
* @param grade_item $item
* @return string
*/
private function format_icon($item): string {
$element = ['type' => 'item', 'object' => $item];
return \grade_helper::get_element_icon($element);
}
/**
* Return the action menu HTML for the grade item.
*
* @param grade_item $item
* @return mixed
*/
private function get_item_action_menu(grade_item $item) {
global $OUTPUT;
$menuitems = [];
$url = new moodle_url($this->format_link('grade', $item->id));
$title = get_string('showallgrades', 'core_grades');
$menuitems[] = new \action_menu_link_secondary($url, null, $title);
$menu = new \action_menu($menuitems);
$icon = $OUTPUT->pix_icon('i/moremenu', get_string('actions'));
$extraclasses = 'btn btn-link btn-icon icon-size-3 d-flex align-items-center justify-content-center';
$menu->set_menu_trigger($icon, $extraclasses);
$menu->set_menu_left();
$menu->set_boundary('window');
return $OUTPUT->render($menu);
}
/**
* Helper to get the category for an item.
*
* @param grade_item $item
* @return string
*/
private function category(grade_item $item): string {
global $DB;
if (empty($item->categoryid)) {
if ($item->itemtype == 'course') {
return $this->course->fullname;
}
$params = ['id' => $item->iteminstance];
$elem = $DB->get_record('grade_categories', $params);
return $elem->fullname;
}
if (!isset($this->categories[$item->categoryid])) {
$category = $item->get_parent_category();
$this->categories[$category->id] = $category;
}
return $this->categories[$item->categoryid]->get_name();
}
/**
* Get the heading for the page.
*
* @return string
*/
public function heading(): string {
global $PAGE;
$headinglangstring = $PAGE->user_is_editing() ? 'gradeuseredit' : 'gradeuser';
return get_string($headinglangstring, 'gradereport_singleview', fullname($this->item));
}
/**
* Get the summary for this table.
*
* @return string
*/
public function summary(): string {
return get_string('summaryuser', 'gradereport_singleview');
}
/**
* Default pager
*
* @return string
*/
public function pager(): string {
global $OUTPUT;
if (!$this->supports_paging()) {
return '';
}
return $OUTPUT->paging_bar(
count($this->items), $this->page, $this->perpage,
new moodle_url('/grade/report/singleview/index.php', [
'perpage' => $this->perpage,
'id' => $this->courseid,
'group' => $this->groupid,
'itemid' => $this->itemid,
'item' => 'user'
])
);
}
/**
* Does this page require paging?
*
* @return bool
*/
public function supports_paging(): bool {
return $this->requirespaging;
}
/**
* Process the data from the form.
*
* @param array $data
* @return stdClass of warnings
*/
public function process($data): stdClass {
$bulk = new bulk_insert($this->item);
// Bulk insert messages the data to be passed in
// ie: for all grades of empty grades apply the specified value.
if ($bulk->is_applied($data)) {
$filter = $bulk->get_type($data);
$insertvalue = $bulk->get_insert_value($data);
$userid = $this->item->id;
foreach ($this->items as $gradeitemid => $gradeitem) {
$null = $gradeitem->gradetype == GRADE_TYPE_SCALE ? -1 : '';
$field = "finalgrade_{$gradeitem->id}_{$this->itemid}";
if (isset($data->$field)) {
continue;
}
$oldfinalgradefield = "oldfinalgrade_{$gradeitem->id}_{$this->itemid}";
// Bulk grade changes for all grades need to be processed and shouldn't be skipped if they had a previous grade.
if ($gradeitem->is_course_item() || ($filter != 'all' && !empty($data->$oldfinalgradefield))) {
if ($gradeitem->is_course_item()) {
// The course total should not be overridden.
unset($data->$field);
unset($data->oldfinalgradefield);
$oldoverride = "oldoverride_{$gradeitem->id}_{$this->itemid}";
unset($data->$oldoverride);
$oldfeedback = "oldfeedback_{$gradeitem->id}_{$this->itemid}";
unset($data->$oldfeedback);
}
continue;
}
$grade = grade_grade::fetch([
'itemid' => $gradeitemid,
'userid' => $userid
]);
$data->$field = empty($grade) ? $null : $grade->finalgrade;
$data->{"old$field"} = $data->$field;
}
foreach ($data as $varname => $value) {
if (preg_match('/^oldoverride_(\d+)_(\d+)/', $varname, $matches)) {
// If we've selected overriding all grades.
if ($filter == 'all') {
$override = "override_{$matches[1]}_{$matches[2]}";
$data->$override = '1';
}
}
if (!preg_match('/^finalgrade_(\d+)_(\d+)/', $varname, $matches)) {
continue;
}
$gradeitem = grade_item::fetch([
'courseid' => $this->courseid,
'id' => $matches[1],
]);
$isscale = ($gradeitem->gradetype == GRADE_TYPE_SCALE);
$empties = (trim($value ?? '') === '' || ($isscale && $value == -1));
if ($filter == 'all' || $empties) {
$data->$varname = ($isscale && empty($insertvalue)) ? -1 : $insertvalue;
}
}
}
return parent::process($data);
}
}
@@ -0,0 +1,87 @@
<?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 gradereport_singleview\local\screen;
use gradereport_singleview;
/**
* The user search screen.
*
* @package gradereport_singleview
* @copyright 2022 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_select extends screen {
public function init($selfitemisempty = false) {
}
/**
* Return the HTML for the page.
*
* @return string
*/
public function html(): string {
global $OUTPUT, $COURSE, $USER;
$userlink = new \moodle_url('/grade/report/singleview/index.php', ['id' => $COURSE->id, 'item' => 'user_select']);
$gradelink = new \moodle_url('/grade/report/singleview/index.php', ['id' => $COURSE->id, 'item' => 'grade_select']);
$gpr = new \grade_plugin_return(['type' => 'report', 'plugin' => 'singleview', 'courseid' => $COURSE->id,
'userid' => $USER->id]);
$context = [
'courseid' => $gpr->courseid,
'imglink' => $OUTPUT->image_url('zero_state_user', 'gradereport_singleview'),
'userzerolink' => $userlink->out(false),
'userselectactive' => true,
'gradezerolink' => $gradelink->out(false),
'gradeselectactive' => false,
'displaylabel' => true,
'groupmodeenabled' => $COURSE->groupmode,
'groupactionbaseurl' => 'index.php?item=user_select',
'groupid' => $gpr->groupid
];
return $OUTPUT->render_from_template('gradereport_singleview/zero_state_user', $context);
}
public function item_type(): ?string {
return false;
}
/**
* Should we show the base singlereport group selector?
* @return bool
*/
public function display_group_selector(): bool {
return false;
}
/**
* Get the heading for the screen.
*
* @return string
*/
public function heading(): string {
return ' ';
}
/**
* Does this screen support paging?
*
* @return bool
*/
public function supports_paging(): bool {
return false;
}
}
@@ -0,0 +1,52 @@
<?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/>.
/**
* Class that builds an element tree that can be converted to a string
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* Class that builds an element tree that can be converted to a string
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class attribute_format {
/**
* Used to convert this class to an "element" which can be converted to a string.
* @return element
*/
abstract public function determine_format(): element;
/**
* Convert this to an element and then to a string
* @return string
*/
public function __toString(): string {
return $this->determine_format()->html();
}
}
@@ -0,0 +1,42 @@
<?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/>.
/**
* Is this thing checked?
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* Is this thing checked?
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
interface be_checked {
/**
* Return true if this is checked.
* @return bool
*/
public function is_checked(): bool;
}
@@ -0,0 +1,40 @@
<?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/>.
/**
* be_disabled interface.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* Simple interface implemented to add behaviour that an element can be checked to see
* if it should be disabled.
*/
interface be_disabled {
/**
* Am I disabled ?
*
* @return bool
*/
public function is_disabled(): bool;
}
@@ -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/>.
/**
* be_readonly interface.
*
* @package gradereport_singleview
* @copyright 2022 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
/**
* Simple interface implemented to add behaviour that an element can be checked to see
* if it should be read-only.
*/
interface be_readonly {
/**
* Return true if this is read-only.
*
* @return bool
*/
public function is_readonly(): bool;
}
@@ -0,0 +1,125 @@
<?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/>.
/**
* Checkbox element used for bulk inserting values in the gradebook.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* Checkbox element used for bulk inserting values in the gradebook.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class bulk_insert extends element {
/** @var string $applyname To store the "apply" suffix. */
protected $applyname;
/** @var string $selectname To store the "type" suffix. */
protected $selectname;
/** @var string $insertname To store the "value" suffix. */
protected $insertname;
/**
* Constructor
*
* @param mixed $item The grade item or user.
*/
public function __construct($item) {
$this->name = 'bulk_' . $item->id;
$this->applyname = $this->name_for('apply');
$this->selectname = $this->name_for('type');
$this->insertname = $this->name_for('value');
}
/**
* Is this checkbox checked?
*
* @param array|object $data The form data
* @return bool
*/
public function is_applied($data): bool {
return isset($data->{$this->applyname});
}
/**
* Get the type of this input (user or grade)
*
* @param array|object $data The form data
* @return string
*/
public function get_type($data): string {
return $data->{$this->selectname};
}
/**
* Get the value from either the user or grade.
*
* @param array|object $data The form data
* @return string
*/
public function get_insert_value($data): string {
return $data->{$this->insertname};
}
/**
* Generate the html for this form element.
*
* @return string HTML
*/
public function html(): string {
global $OUTPUT;
$text = new text_attribute($this->insertname, "0", 'bulk');
$context = (object) [
'label' => get_string('bulklegend', 'gradereport_singleview'),
'applylabel' => get_string('bulkperform', 'gradereport_singleview'),
'applyname' => $this->applyname,
'menuname' => $this->selectname,
'menulabel' => get_string('bulkappliesto', 'gradereport_singleview'),
'menuoptions' => [
['value' => 'all', 'name' => get_string('all_grades', 'gradereport_singleview')],
['value' => 'blanks', 'name' => get_string('blanks', 'gradereport_singleview'), 'selected' => true],
],
'valuename' => $this->insertname,
'valuefield' => $text->html()
];
return $OUTPUT->render_from_template('gradereport_singleview/bulk_insert', $context);
}
/**
* This form element has 3 elements with different suffixes.
* Generate the name with the suffix.
*
* @param string $extend The suffix.
* @return string
*/
private function name_for($extend) {
return "{$this->name}_$extend";
}
}
@@ -0,0 +1,122 @@
<?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/>.
/**
* A checkbox ui element.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
use html_writer;
defined('MOODLE_INTERNAL') || die;
/**
* A checkbox ui element.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class checkbox_attribute extends element {
/** @var bool $ischecked Is it checked? */
private $ischecked;
/** @var bool If this is a read-only input. */
private bool $isreadonly;
/** @var int Is this element locked either 0 or a time. */
protected int $locked;
/**
* Constructor
*
* @param string $name The element name
* @param string $label The label for the form element
* @param bool $ischecked Is this thing on?
* @param int $locked Is this element locked either 0 or a time.
* @param bool $isreadonly If this is a read-only input.
*/
public function __construct(string $name, string $label, bool $ischecked = false, int $locked=0, bool $isreadonly = false) {
$this->ischecked = $ischecked;
$this->locked = $locked;
$this->isreadonly = $isreadonly;
parent::__construct($name, 1, $label);
}
/**
* Nasty function allowing checkbox logic to escape the class.
* @return bool
*/
public function is_checkbox(): bool {
return true;
}
/**
* Generate the HTML
*
* @return string
*/
public function html(): string {
global $OUTPUT;
$attributes = [
'type' => 'checkbox',
'name' => $this->name,
'value' => 1,
'id' => $this->name
];
// UCSB fixed user should not be able to override locked grade.
if ( $this->locked) {
$attributes['disabled'] = 'DISABLED';
}
$hidden = [
'type' => 'hidden',
'name' => 'old' . $this->name
];
if ($this->ischecked) {
$attributes['checked'] = 'CHECKED';
$hidden['value'] = 1;
}
$type = "override";
if (preg_match("/^exclude/", $this->name)) {
$type = "exclude";
}
if (!$this->isreadonly) {
return (
html_writer::tag('label',
get_string($type . 'for', 'gradereport_singleview', $this->label),
['for' => $this->name, 'class' => 'accesshide']) .
html_writer::empty_tag('input', $attributes) .
html_writer::empty_tag('input', $hidden)
);
} else if ($this->ischecked) {
return $OUTPUT->pix_icon('i/checked', get_string('selected', 'core_form'),
'moodle', ['class' => 'overrideexcludecheck']);
} else {
return '';
}
}
}
@@ -0,0 +1,122 @@
<?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/>.
/**
* Drop down list (select list) element
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* Drop down list (select list) element
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class dropdown_attribute extends element {
/**
* Who is selected?
* @var string $selected
*/
private $selected;
/**
* List of options
* @var array $options
*/
private $options;
/**
* Is this input disabled.
* @var bool $isdisabled
*/
private $isdisabled;
/** @var bool If this is a read-only input. */
private bool $isreadonly;
/**
* Constructor
*
* @param string $name The first bit of the name of this input.
* @param array $options The options list for this select.
* @param string $label The form label for this input.
* @param string $selected The name of the selected item in this input.
* @param bool $isdisabled Are we disabled?
* @param bool $isreadonly If this is a read-only input.
*/
public function __construct(
string $name,
array $options,
string $label,
string $selected = '',
bool $isdisabled = false,
bool $isreadonly = false
) {
$this->selected = $selected;
$this->options = $options;
$this->isdisabled = $isdisabled;
$this->isreadonly = $isreadonly;
parent::__construct($name, $selected, $label);
}
/**
* Nasty function spreading dropdown logic around.
*
* @return bool
*/
public function is_dropdown(): bool {
return true;
}
/**
* Render this element as html.
*
* @return string
*/
public function html(): string {
global $OUTPUT;
$options = $this->options;
$selected = $this->selected;
$context = [
'name' => $this->name,
'value' => $this->selected,
'text' => $options[$selected],
'disabled' => !empty($this->isdisabled),
'readonly' => $this->isreadonly,
'options' => array_map(function($option) use ($options, $selected) {
return [
'name' => $options[$option],
'value' => $option,
'selected' => $selected == $option
];
}, array_keys($options)),
'label' => get_string('gradefor', 'gradereport_singleview', $this->label),
];
return $OUTPUT->render_from_template('gradereport_singleview/dropdown_attribute', $context);
}
}
@@ -0,0 +1,98 @@
<?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/>.
/**
* UI Element for an excluded grade_grade.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* UI Element for an excluded grade_grade.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class element {
/**
* The first bit of the name for this input.
* @var string $name
*/
public $name;
/**
* The value for this input.
* @var string $value
*/
public $value;
/**
* The form label for this input.
* @var string $label
*/
public $label;
/**
* Constructor
*
* @param string $name The first bit of the name for this input
* @param string $value The value for this input
* @param string $label The label for this form field
*/
public function __construct(string $name, string $value, string $label) {
$this->name = $name;
$this->value = $value;
$this->label = $label;
}
/**
* Nasty function used for spreading checkbox logic all around
* @return bool
*/
public function is_checkbox(): bool {
return false;
}
/**
* Nasty function used for spreading textbox logic all around
* @return bool
*/
public function is_textbox(): bool {
return false;
}
/**
* Nasty function used for spreading dropdown logic all around
* @return bool
*/
public function is_dropdown(): bool {
return false;
}
/**
* Return the HTML
* @return string
*/
abstract public function html(): string;
}
@@ -0,0 +1,62 @@
<?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/>.
/**
* Element that just generates some text.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* Element that just generates some text.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class empty_element extends element {
/** @var string message text. */
private $text;
/**
* Constructor
*
* @param string|null $msg The text
*/
public function __construct(?string $msg = null) {
if (is_null($msg)) {
$this->text = '&nbsp;';
} else {
$this->text = $msg;
}
}
/**
* Generate the html (simple case)
*
* @return string HTML
*/
public function html(): string {
return $this->text;
}
}
@@ -0,0 +1,142 @@
<?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/>.
/**
* Class that represents the exclude checkbox on a grade_grade.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
use grade_grade;
/**
* Class that represents the exclude checkbox on a grade_grade.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class exclude extends grade_attribute_format implements be_checked, be_disabled, be_readonly {
/**
* The name of the input
* @var string $name
*/
public $name = 'exclude';
/**
* Is the checkbox disabled?
* @var bool $disabled
*/
public $disabled = false;
/**
* Is it checked?
*
* @return bool
*/
public function is_checked(): bool {
return $this->grade->is_excluded();
}
/**
* Is it disabled?
*
* @return bool
*/
public function is_disabled(): bool {
return $this->disabled;
}
/**
* Return true if this is read-only.
*
* @return bool
*/
public function is_readonly(): bool {
global $USER;
return empty($USER->editing);
}
/**
* Generate the element used to render the UI
*
* @return element
*/
public function determine_format(): element {
return new checkbox_attribute(
$this->get_name(),
$this->get_label(),
$this->is_checked(),
$this->is_disabled(),
$this->is_readonly()
);
}
/**
* Get the label for the form input
*
* @return string
*/
public function get_label(): string {
if (!isset($this->grade->label)) {
$this->grade->label = '';
}
return $this->grade->label;
}
/**
* Set the value that was changed in the form.
*
* @param string $value The value to set.
* @return mixed string|bool An error message or false.
*/
public function set($value) {
if (empty($this->grade->id)) {
if (empty($value)) {
return false;
}
$gradeitem = $this->grade->grade_item;
// Fill in arbitrary grade to be excluded.
$gradeitem->update_final_grade(
$this->grade->userid, null, 'singleview', null, FORMAT_MOODLE
);
$gradeparams = [
'userid' => $this->grade->userid,
'itemid' => $this->grade->itemid
];
$this->grade = grade_grade::fetch($gradeparams);
$this->grade->grade_item = $gradeitem;
}
$state = !($value == 0);
$this->grade->set_excluded($state);
$this->grade->grade_item->get_parent_category()->force_regrading();
return false;
}
}
@@ -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/>.
/**
* Class used to render a feedback input box.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* Class used to render a feedback input box.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class feedback extends grade_attribute_format implements unique_value, be_disabled, be_readonly {
/**
* Name of this input
* @var string $name
*/
public $name = 'feedback';
/**
* Get the value for this input.
*
* @return string The value
*/
public function get_value(): ?string {
return $this->grade->feedback ? $this->grade->feedback : '';
}
/**
* Get the string to use in the label for this input.
*
* @return string The label text
*/
public function get_label(): string {
if (!isset($this->grade->label)) {
$this->grade->label = '';
}
return $this->grade->label;
}
/**
* Determine if this input should be disabled based on the other settings.
*
* @return boolean Should this input be disabled when the page loads.
*/
public function is_disabled(): bool {
$locked = 0;
$gradeitemlocked = 0;
$overridden = 0;
/* Disable editing if grade item or grade score is locked
* if any of these items are set, then we will disable editing
* at some point, we might want to show the reason for the lock
* this code could be simplified, but its more readable for steve's little mind
*/
if (!empty($this->grade->locked)) {
$locked = 1;
}
if (!empty($this->grade->grade_item->locked)) {
$gradeitemlocked = 1;
}
if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) {
$overridden = 1;
}
return ($locked || $gradeitemlocked || $overridden);
}
/**
* Return true if this is read-only.
*
* @return bool
*/
public function is_readonly(): bool {
global $USER;
return empty($USER->editing);
}
/**
* Create a text_attribute for this ui element.
*
* @return element
*/
public function determine_format(): element {
return new text_attribute(
$this->get_name(),
$this->get_value(),
$this->get_label(),
$this->is_disabled(),
$this->is_readonly()
);
}
/**
* Update the value for this input.
*
* @param string $value The new feedback value.
* @return null|string Any error message
*/
public function set($value) {
$finalgrade = false;
$trimmed = trim($value);
if (empty($trimmed)) {
$feedback = null;
} else {
$feedback = $value;
}
$this->grade->grade_item->update_final_grade(
$this->grade->userid, $finalgrade, 'singleview',
$feedback, FORMAT_MOODLE
);
}
}
@@ -0,0 +1,218 @@
<?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/>.
/**
* UI element representing the finalgrade column.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
use stdClass;
/**
* UI element representing the finalgrade column.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class finalgrade extends grade_attribute_format implements unique_value, be_disabled, be_readonly {
/**
* Name of this input
* @var string $name
*/
public $name = 'finalgrade';
/**
* Get the value for this input.
*
* @return null|string The value based on the grade_grade.
*/
public function get_value(): ?string {
$this->label = $this->grade->grade_item->itemname;
$val = $this->grade->finalgrade;
if ($this->grade->grade_item->scaleid) {
return $val ? (int)$val : -1;
} else {
return $val ? format_float($val, $this->grade->grade_item->get_decimals()) : '';
}
}
/**
* Get the label for this input.
*
* @return string The label for this form input.
*/
public function get_label(): string {
if (!isset($this->grade->label)) {
$this->grade->label = '';
}
return $this->grade->label;
}
/**
* Is this input field disabled.
*
* @return bool Set disabled on this input or not.
*/
public function is_disabled(): bool {
$locked = 0;
$gradeitemlocked = 0;
$overridden = 0;
// Disable editing if grade item or grade score is locked
// if any of these items are set, then we will disable editing
// at some point, we might want to show the reason for the lock
// this code could be simplified, but its more readable for steve's little mind.
if (!empty($this->grade->locked)) {
$locked = 1;
}
if (!empty($this->grade->grade_item->locked)) {
$gradeitemlocked = 1;
}
if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) {
$overridden = 1;
}
return ($locked || $gradeitemlocked || $overridden);
}
/**
* Return true if this is read-only.
*
* @return bool
*/
public function is_readonly(): bool {
global $USER;
return empty($USER->editing);
}
/**
* Create the element for this column.
*
* @return element
*/
public function determine_format(): element {
global $CFG;
if ($this->grade->grade_item->load_scale()) {
$scale = $this->grade->grade_item->load_scale();
$options = [-1 => get_string('nograde')];
foreach ($scale->scale_items as $i => $name) {
$options[$i + 1] = $name;
}
return new dropdown_attribute(
$this->get_name(),
$options,
$this->get_label(),
$this->get_value(),
$this->is_disabled(),
$this->is_readonly()
);
} else {
$textattribute = new text_attribute(
$this->get_name(),
$this->get_value(),
$this->get_label(),
$this->is_disabled(),
$this->is_readonly()
);
// Set min/max attributes, if applicable.
$textattribute->set_type('number');
$gradeitem = $this->grade->grade_item;
$decimals = $gradeitem->get_decimals();
// Min attribute.
$minvalue = null;
if (isset($gradeitem->grademin)) {
$minvalue = format_float($gradeitem->grademin, $decimals);
}
$textattribute->set_min($minvalue);
// Max attribute.
$maxvalue = null;
if (isset($gradeitem->grademax) && empty($CFG->unlimitedgrades)) {
$maxvalue = format_float($gradeitem->grademax, $decimals);
}
$textattribute->set_max($maxvalue);
return $textattribute;
}
}
/**
* Save the altered value for this field.
*
* @param string $value The new value.
* @return string Any error string
*/
public function set($value) {
$userid = $this->grade->userid;
$gradeitem = $this->grade->grade_item;
$feedback = false;
$feedbackformat = false;
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$value = (int)unformat_float($value);
if ($value == -1) {
$finalgrade = null;
} else {
$finalgrade = $value;
}
} else {
$finalgrade = unformat_float($value);
}
$errorstr = '';
if ($finalgrade) {
$bounded = $gradeitem->bounded_grade($finalgrade);
if ($bounded > $finalgrade) {
$errorstr = 'lessthanmin';
} else if ($bounded < $finalgrade) {
$errorstr = 'morethanmax';
}
}
if ($errorstr) {
$user = get_complete_user_data('id', $userid);
$gradestr = new stdClass;
if (has_capability('moodle/site:viewfullnames', \context_course::instance($gradeitem->courseid))) {
$gradestr->username = fullname($user, true);
} else {
$gradestr->username = fullname($user);
}
$gradestr->itemname = $this->grade->grade_item->get_name();
$errorstr = get_string($errorstr, 'grades', $gradestr);
return $errorstr;
}
// Only update grades if there are no errors.
$gradeitem->update_final_grade($userid, $finalgrade, 'singleview', $feedback, FORMAT_MOODLE,
null, null, true);
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/>.
/**
* Abstract class for a form element representing something about a grade_grade.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
use grade_grade;
defined('MOODLE_INTERNAL') || die;
/**
* Abstract class for a form element representing something about a grade_grade.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class grade_attribute_format extends attribute_format implements unique_name {
/**
* The first part of the name attribute of the form input
* @var string $name
*/
public $name;
/**
* The label of the input
* @var null|string $label
*/
public $label;
/**
* The grade_grade of the input
* @var grade_grade $grade
*/
public $grade;
/**
* Constructor
*
* @param grade_grade $grade The grade_grade we are editing.
*/
public function __construct($grade = 0) {
$this->grade = $grade;
}
/**
* Get a unique name for this form input
*
* @return string The form input name attribute.
*/
public function get_name(): string {
return "{$this->name}_{$this->grade->itemid}_{$this->grade->userid}";
}
/**
* Should be overridden by the child class to save the value returned in this input.
*
* @param string $value The value from the form.
* @return string Any error message
*/
abstract public function set($value);
}
@@ -0,0 +1,126 @@
<?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/>.
/**
* An override grade checkbox element
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* An override grade checkbox element
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class override extends grade_attribute_format implements be_checked, be_disabled, be_readonly {
/**
* The name for this input
* @var string $name
*/
public $name = 'override';
/**
* Is this input checked
*
* @return bool
*/
public function is_checked(): bool {
return $this->grade->is_overridden();
}
/**
* Is this input disabled
*
* @return bool
*/
public function is_disabled(): bool {
$lockedgrade = $lockedgradeitem = 0;
if (!empty($this->grade->locked)) {
$lockedgrade = 1;
}
if (!empty($this->grade->grade_item->locked)) {
$lockedgradeitem = 1;
}
return ($lockedgrade || $lockedgradeitem);
}
/**
* Return true if this is read-only.
*
* @return bool
*/
public function is_readonly(): bool {
global $USER;
return empty($USER->editing);
}
/**
* Get the label for this form element.
*
* @return string
*/
public function get_label(): string {
if (!isset($this->grade->label)) {
$this->grade->label = '';
}
return $this->grade->label;
}
/**
* Generate the element for this form input.
*
* @return element
*/
public function determine_format(): element {
if (!$this->grade->grade_item->is_overridable_item()) {
return new empty_element();
}
return new checkbox_attribute(
$this->get_name(),
$this->get_label(),
$this->is_checked(),
$this->is_disabled(),
$this->is_readonly()
);
}
/**
* Save the modified value of this form element.
*
* @param string $value The new value to set
* @return mixed string|false Any error message
*/
public function set($value) {
if (empty($this->grade->id)) {
return false;
}
$state = !($value == 0);
$this->grade->set_overridden($state);
$this->grade->grade_item->force_regrading();
return false;
}
}
@@ -0,0 +1,64 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* UI element that generates a min/max range (text only).
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
use grade_item;
defined('MOODLE_INTERNAL') || die;
/**
* UI element that generates a grade_item min/max range (text only).
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class range extends attribute_format {
/** @var grade_item To store the grade item. */
private grade_item $item;
/**
* Constructor
* @param grade_item $item The grade item
*/
public function __construct(grade_item $item) {
$this->item = $item;
}
/**
* Build this UI element.
*
* @return element
*/
public function determine_format(): element {
$decimals = $this->item->get_decimals();
$min = format_float($this->item->grademin, $decimals);
$max = format_float($this->item->grademax, $decimals);
return new empty_element("$min - $max");
}
}
@@ -0,0 +1,152 @@
<?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/>.
/**
* UI element for a text input field.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* UI element for a text input field.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class text_attribute extends element {
/**
* Is this input disabled?
* @var bool $isdisabled
*/
private $isdisabled;
/** @var bool If this is a read-only input. */
private bool $isreadonly;
/**
* @var string|null The input type to pass to the template.
* This defaults to text but can be overridden to number for grade inputs.
*/
private $type = null;
/**
* @var string|null The value to set for the input's `min` attribute.
* This is set if a minimum grade is provided for the grade input field.
*/
private $min = null;
/**
* @var string|null The value to set for the input's `max` attribute.
* This is set if a maximum grade is provided for the grade input field.
*/
private $max = null;
/**
* Constructor
*
* @param string $name The input name (the first bit)
* @param string $value The input initial value.
* @param string $label The label for this input field.
* @param bool $isdisabled Is this input disabled.
* @param bool $isreadonly If this is a read-only input.
*/
public function __construct(string $name, string $value, string $label, bool $isdisabled = false, bool $isreadonly = false) {
$this->isdisabled = $isdisabled;
$this->isreadonly = $isreadonly;
parent::__construct($name, $value, $label);
}
/**
* Nasty function allowing custom textbox behaviour outside the class.
* @return bool Is this a textbox.
*/
public function is_textbox(): bool {
return true;
}
/**
* Render the html for this field.
* @return string The HTML.
*/
public function html(): string {
global $OUTPUT;
$context = (object) [
'id' => $this->name,
'name' => $this->name,
'value' => $this->value,
'disabled' => $this->isdisabled,
'readonly' => $this->isreadonly,
];
$context->label = '';
if (preg_match("/^feedback/", $this->name)) {
$context->label = get_string('feedbackfor', 'gradereport_singleview', $this->label);
} else if (preg_match("/^finalgrade/", $this->name)) {
$context->label = get_string('gradefor', 'gradereport_singleview', $this->label);
}
// Set this input field with type="number" if the decimal separator for current language is set to a period.
// Other decimal separators may not be recognised by browsers yet which may cause issues when entering grades.
$decsep = get_string('decsep', 'core_langconfig');
$context->isnumeric = $this->type === 'number' && $decsep === '.';
if ($context->isnumeric) {
$context->type = $this->type;
$context->min = $this->min;
$context->max = $this->max;
}
return $OUTPUT->render_from_template('gradereport_singleview/text_attribute', $context);
}
/**
* Input type setter.
*
* @param string|null $type
* @return void
*/
public function set_type(?string $type): void {
$this->type = $type;
}
/**
* Min attribute setter.
*
* @param string|null $min
* @return void
*/
public function set_min(?string $min): void {
$this->min = $min;
}
/**
* Max attribute setter.
*
* @param string|null $max
* @return void
*/
public function set_max(?string $max): void {
$this->max = $max;
}
}
@@ -0,0 +1,43 @@
<?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/>.
/**
* A form element with a name field.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* A form element with a name field.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
interface unique_name {
/**
* Get the name for this form element
* @return string
*/
public function get_name(): string;
}
@@ -0,0 +1,42 @@
<?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/>.
/**
* The gradebook simple view - UI factory
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\local\ui;
defined('MOODLE_INTERNAL') || die;
/**
* Simple interface for an item with a value.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
interface unique_value {
/**
* Get the value for this item.
* @return null|string
*/
public function get_value(): ?string;
}
@@ -0,0 +1,103 @@
<?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/>.
declare(strict_types=1);
namespace gradereport_singleview\output;
use moodle_url;
use renderer_base;
use gradereport_singleview\report\singleview;
/**
* Renderable class for the action bar elements in the single view report page.
*
* @package gradereport_singleview
* @copyright 2022 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class action_bar extends \core_grades\output\action_bar {
/** @var singleview $report The single view report class. */
protected singleview $report;
/** @var string $itemtype The single view item type. */
protected string $itemtype;
/**
* The class constructor.
*
* @param \context $context The context object.
* @param singleview $report The single view report class.
* @param string $itemtype The single view item type.
*/
public function __construct(\context $context, singleview $report, string $itemtype) {
parent::__construct($context);
$this->report = $report;
$this->itemtype = $itemtype;
}
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'gradereport_singleview/action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(renderer_base $output) {
global $USER;
$courseid = $this->context->instanceid;
// Get the data used to output the general navigation selector.
$generalnavselector = new \core_grades\output\general_action_bar(
$this->context,
new moodle_url('/grade/report/singleview/index.php', ['id' => $courseid]),
'report',
'singleview'
);
$data = $generalnavselector->export_for_template($output);
// The data required to output the page toggle element.
$data['pagetoggler'] = [
'displaylabel' => true,
'userselectactive' => $this->itemtype === 'user',
'gradeselectactive' => $this->itemtype === 'grade',
'gradezerolink' => (new moodle_url('/grade/report/singleview/index.php',
['id' => $courseid, 'item' => 'grade_select']))->out(false),
'userzerolink' => (new moodle_url('/grade/report/singleview/index.php',
['id' => $courseid, 'item' => 'user_select']))->out(false)
];
$data['groupselector'] = $this->report->group_selector;
$data['itemselector'] = $this->report->itemselector;
$data['pbarurl'] = $this->report->pbarurl->out(false);
if (!empty($USER->editing) && isset($this->report->screen->item)) {
$data['bulkactions'] = $this->report->bulk_actions_menu($output);
}
return $data;
}
}
@@ -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 gradereport_singleview.
*
* @package gradereport_singleview
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_singleview\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for gradereport_singleview implementing null_provider.
*
* @copyright 2018 Sara Arjona <sara@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';
}
}
@@ -0,0 +1,196 @@
<?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 gradereport_singleview\report;
use context_course;
use grade_report;
use moodle_url;
use renderer_base;
use stdClass;
defined('MOODLE_INTERNAL') || die;
require_once($CFG->dirroot . '/grade/report/lib.php');
/**
* This class is the main class that must be implemented by a grade report plugin.
*
* @package gradereport_singleview
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class singleview extends grade_report {
/** @var string|null $itemselector The raw HTML of the item selector based on the selected single view item type. */
public ?string $itemselector = null;
/** @var \gradereport_singleview\local\screen\screen screen type. */
public $screen;
/**
* Return the list of valid screens, used to validate the input.
*
* @return array List of screens.
*/
public static function valid_screens(): array {
// This is a list of all the known classes representing a screen in this plugin.
return ['user', 'select', 'grade', 'user_select', 'grade_select'];
}
/**
* Process data from a form submission. Delegated to the current screen.
*
* @param array $data The data from the form
* @return array|object List of warnings
*/
public function process_data($data) {
if (has_capability('moodle/grade:edit', $this->context)) {
return $this->screen->process($data);
}
}
/**
* Unused - abstract function declared in the parent class.
*
* @param string $target
* @param string $action
*/
public function process_action($target, $action) {
}
/**
* Constructor for this report. Creates the appropriate screen class based on itemtype.
*
* @param int $courseid The course id.
* @param object $gpr grade plugin return tracking object
* @param context_course $context
* @param string $itemtype Should be user, select or grade
* @param int|null $itemid The id of the user or grade item
* @param string|null $unused Used to be group id but that was removed and this is now unused.
*/
public function __construct(
int $courseid,
object $gpr,
context_course $context,
string $itemtype,
?int $itemid,
?string $unused = null
) {
parent::__construct($courseid, $gpr, $context);
$base = '/grade/report/singleview/index.php';
$idparams = ['id' => $courseid];
$this->baseurl = new moodle_url($base, $idparams);
$this->pbarurl = new moodle_url($base, $idparams + [
'item' => $itemtype,
'itemid' => $itemid
]);
// The setup_group method is used to validate group mode and permissions and define the currentgroup value.
$this->setup_groups();
if (($itemtype !== 'grade') && ($itemtype !== 'user')) {
$itemid = null;
}
$this->setup_item_selector($itemtype, $itemid);
$screenclass = "\\gradereport_singleview\\local\\screen\\{$itemtype}";
$this->screen = new $screenclass($courseid, $itemid, $this->currentgroup);
// Load custom or predifined js.
$this->screen->js();
}
/**
* Build the html for the screen.
* @return string HTML to display
*/
public function output(): string {
global $OUTPUT;
return $OUTPUT->container($this->screen->html());
}
protected function setup_groups() {
parent::setup_groups();
$this->group_selector = static::groups_course_menu($this->course);
}
/**
* Ideally we should move this function to the base class and call it from the setup_groups in the base class,
* so all reports would automatically use it.
*
* @param stdClass $course
* @return string
*/
protected static function groups_course_menu(stdClass $course) {
global $PAGE;
$renderer = $PAGE->get_renderer('core_grades');
return $renderer->group_selector($course);
}
/**
* Function used to set the appropriate item selector (raw HTML) based on the selected single view item type.
*
* @param string $itemtype The single view item type.
* @param int|null $itemid The item ID.
*/
protected function setup_item_selector(string $itemtype, ?int $itemid) {
global $PAGE;
$renderer = $PAGE->get_renderer('gradereport_singleview');
if ($itemtype === 'user' || $itemtype === 'user_select' ) {
$this->itemselector = $renderer->users_selector($this->course, $itemid, $this->currentgroup);
} else if ($itemtype === 'grade' || $itemtype === 'grade_select' ) {
$this->itemselector = $renderer->grade_items_selector($this->course, $itemid);
}
}
/**
* Adds bulk actions menu.
*
* @param renderer_base $output
* @return string HTML to display
*/
public function bulk_actions_menu(renderer_base $output): string {
$options = [
'overrideallgrades' => get_string('overrideallgrades', 'gradereport_singleview'),
'overridenonegrades' => get_string('overridenonegrades', 'gradereport_singleview'),
'excludeallgrades' => get_string('excludeallgrades', 'gradereport_singleview'),
'excludenonegrades' => get_string('excludenonegrades', 'gradereport_singleview'),
'bulklegend' => get_string('bulklegend', 'gradereport_singleview')
];
$menu = new \action_menu();
$menu->set_menu_trigger(get_string('actions'), 'text-dark');
foreach ($options as $type => $option) {
$action = new \action_menu_link_secondary(new \moodle_url('#'), null, $option,
['data-action' => $type, 'data-role' => 'bulkaction']);
$menu->add($action);
}
$menu->attributes['class'] .= ' float-left my-auto';
return $output->render($menu);
}
}