2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * Abstract class used as a base for the 3 screens.
20 * @package gradereport_singleview
21 * @copyright 2014 Moodle Pty Ltd (http://moodle.com)
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 namespace gradereport_singleview\local\screen
;
35 defined('MOODLE_INTERNAL') ||
die;
38 * Abstract class used as a base for the 3 screens.
40 * @package gradereport_singleview
41 * @copyright 2014 Moodle Pty Ltd (http://moodle.com)
42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
44 abstract class screen
{
46 /** @var int $courseid The id of the course */
49 /** @var int $itemid Either a user id or a grade_item id */
52 /** @var int $groupid The currently set groupid (if set) */
55 /** @var course_context $context The course context */
58 /** @var int $page The page number */
61 /** @var int $perpage Results per page */
64 /** @var array $items List of items on the page, they could be users or grade_items */
67 /** @var array $validperpage List of allowed values for 'perpage' setting */
68 protected static $validperpage = [20, 50, 100, 200, 400, 1000, 5000];
73 * @param int $courseid The course id
74 * @param int $itemid The item id
75 * @param int $groupid The group id
77 public function __construct($courseid, $itemid, $groupid = null) {
80 $this->courseid
= $courseid;
81 $this->itemid
= $itemid;
82 $this->groupid
= $groupid;
84 $this->context
= context_course
::instance($this->courseid
);
85 $this->course
= $DB->get_record('course', array('id' => $courseid));
87 $this->page
= optional_param('page', 0, PARAM_INT
);
89 $cache = \cache
::make_from_params(\cache_store
::MODE_SESSION
, 'gradereport_singleview', 'perpage');
90 $perpage = optional_param('perpage', null, PARAM_INT
);
91 if (!in_array($perpage, self
::$validperpage)) {
93 $perpage = $cache->get(get_class($this));
96 $cache->set(get_class($this), $perpage);
99 $this->perpage
= $perpage;
101 $this->perpage
= 100;
104 $this->init(empty($itemid));
108 * Cache the grade_structure class
110 public function setup_structure() {
111 $this->structure
= new grade_structure();
112 $this->structure
->modinfo
= get_fast_modinfo($this->course
);
116 * Create a nice link from a thing (user or grade_item).
118 * @param string $screen
120 * @param bool $display Should we wrap this in an anchor ?
121 * @return string The link
123 public function format_link($screen, $itemid, $display = null) {
124 $url = new moodle_url('/grade/report/singleview/index.php', array(
125 'id' => $this->courseid
,
128 'group' => $this->groupid
,
132 return html_writer
::link($url, $display);
139 * Get the grade_grade
141 * @param grade_item $item The grade_item
142 * @param int $userid The user id
143 * @return grade_grade
145 public function fetch_grade_or_default($item, $userid) {
146 $grade = grade_grade
::fetch(array(
147 'itemid' => $item->id
, 'userid' => $userid
151 $default = new stdClass
;
153 $default->userid
= $userid;
154 $default->itemid
= $item->id
;
155 $default->feedback
= '';
157 $grade = new grade_grade($default, false);
160 $grade->grade_item
= $item;
166 * Make the HTML element that toggles all the checkboxes on or off.
168 * @param string $key A unique key for this control - inserted in the classes.
171 public function make_toggle($key) {
172 $attrs = array('href' => '#');
174 // Do proper lang strings for title attributes exist for the given key?
175 $strmanager = \
get_string_manager();
176 $titleall = get_string('all');
177 $titlenone = get_string('none');
178 if ($strmanager->string_exists(strtolower($key) . 'all', 'gradereport_singleview')) {
179 $titleall = get_string(strtolower($key) . 'all', 'gradereport_singleview');
181 if ($strmanager->string_exists(strtolower($key) . 'none', 'gradereport_singleview')) {
182 $titlenone = get_string(strtolower($key) . 'none', 'gradereport_singleview');
185 $all = html_writer
::tag('a', get_string('all'), $attrs +
array(
186 'class' => 'include all ' . $key,
190 $none = html_writer
::tag('a', get_string('none'), $attrs +
array(
191 'class' => 'include none ' . $key,
192 'title' => $titlenone
195 return html_writer
::tag('span', "$all / $none", array(
196 'class' => 'inclusion_links'
201 * Make a toggle link with some text before it.
203 * @param string $key A unique key for this control - inserted in the classes.
206 public function make_toggle_links($key) {
207 return get_string($key, 'gradereport_singleview') . ' ' .
208 $this->make_toggle($key);
212 * Get the default heading for the screen.
216 public function heading() {
217 return get_string('entrypage', 'gradereport_singleview');
221 * Override this to init the screen.
223 * @param boolean $selfitemisempty True if no item has been selected yet.
225 public abstract function init($selfitemisempty = false);
228 * Get the type of items in the list.
232 public abstract function item_type();
235 * Get the entire screen as a string.
239 public abstract function html();
242 * Does this screen support paging?
246 public function supports_paging() {
255 public function pager() {
260 * Initialise the js for this screen.
262 public function js() {
266 'name' => 'gradereport_singleview',
267 'fullpath' => '/grade/report/singleview/js/singleview.js',
268 'requires' => array('base', 'dom', 'event', 'event-simulate', 'io-base')
271 $PAGE->requires
->js_init_call('M.gradereport_singleview.init', array(), false, $module);
275 * Process the data from a form submission.
278 * @return array of warnings
280 public function process($data) {
283 $fields = $this->definition();
285 // Avoiding execution timeouts when updating
286 // a large amount of grades.
288 $progressbar = new \core\progress\
display_if_slow();
289 $progressbar->start_html();
290 $progressbar->start_progress(get_string('savegrades', 'gradereport_singleview'), count((array) $data) - 1);
291 $changecount = array();
293 foreach ($data as $varname => $throw) {
294 $progressbar->progress($progress);
296 if (preg_match("/(\w+)_(\d+)_(\d+)/", $varname, $matches)) {
297 $itemid = $matches[2];
298 $userid = $matches[3];
303 $gradeitem = grade_item
::fetch(array(
304 'id' => $itemid, 'courseid' => $this->courseid
307 if (preg_match('/^old[oe]{1}/', $varname)) {
308 $elementname = preg_replace('/^old/', '', $varname);
309 if (!isset($data->$elementname)) {
310 // Decrease the progress because we've increased the
311 // size of the array we are iterating through.
313 $data->$elementname = false;
317 if (!in_array($matches[1], $fields)) {
325 $grade = $this->fetch_grade_or_default($gradeitem, $userid);
327 $classname = '\\gradereport_singleview\\local\\ui\\' . $matches[1];
328 $element = new $classname($grade);
330 $name = $element->get_name();
331 $oldname = "old$name";
333 $posted = $data->$name;
335 $format = $element->determine_format();
337 if ($format->is_textbox() and trim($data->$name) === '') {
342 if (isset($data->$oldname) && $data->$oldname == $posted) {
346 // If the user submits Exclude grade elements without the proper.
347 // permissions then we should refuse to update.
348 if ($matches[1] === 'exclude' && !has_capability('moodle/grade:manage', $this->context
)){
349 $warnings[] = get_string('nopermissions', 'error', get_string('grade:manage', 'role'));
353 $msg = $element->set($posted);
359 if (preg_match('/_(\d+)_(\d+)/', $varname, $matchelement)) {
360 $changecount[$matchelement[0]] = 1;
364 // Some post-processing.
365 $eventdata = new stdClass
;
366 $eventdata->warnings
= $warnings;
367 $eventdata->post_data
= $data;
368 $eventdata->instance
= $this;
369 $eventdata->changecount
= $changecount;
371 $progressbar->end_html();
377 * By default there are no options.
380 public function options() {
385 * Should we show the group selector?
388 public function display_group_selector() {
393 * Should we show the next prev selector?
396 public function supports_next_prev() {
401 * Load a valid list of users for this gradebook as the screen "items".
402 * @return array $users A list of enroled users.
404 protected function load_users() {
407 // Create a graded_users_iterator because it will properly check the groups etc.
408 $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol
);
409 $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
410 $showonlyactiveenrol = $showonlyactiveenrol ||
!has_capability('moodle/course:viewsuspendedusers', $this->context
);
412 require_once($CFG->dirroot
.'/grade/lib.php');
413 $gui = new \
graded_users_iterator($this->course
, null, $this->groupid
);
414 $gui->require_active_enrolment($showonlyactiveenrol);
417 // Flatten the users.
419 while ($user = $gui->next_user()) {
420 $users[$user->user
->id
] = $user->user
;
427 * Allow selection of number of items to display per page.
430 public function perpage_select() {
431 global $PAGE, $OUTPUT;
433 $options = array_combine(self
::$validperpage, self
::$validperpage);
435 $url = new moodle_url($PAGE->url
);
436 $url->remove_params(['page', 'perpage']);
439 $select = new \
single_select($url, 'perpage', $options, $this->perpage
, null, 'perpagechanger');
440 $select->label
= get_string('itemsperpage', 'gradereport_singleview');
441 $out .= $OUTPUT->render($select);