Differences Between: [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 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. 8 // 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. 13 // 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/>. 16 17 /** 18 * Abstract class used as a base for the 3 screens. 19 * 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 23 */ 24 25 namespace gradereport_singleview\local\screen; 26 27 use context_course; 28 use moodle_url; 29 use html_writer; 30 use grade_structure; 31 use grade_grade; 32 use grade_item; 33 use stdClass; 34 35 defined('MOODLE_INTERNAL') || die; 36 37 /** 38 * Abstract class used as a base for the 3 screens. 39 * 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 43 */ 44 abstract class screen { 45 46 /** @var int $courseid The id of the course */ 47 protected $courseid; 48 49 /** @var int $itemid Either a user id or a grade_item id */ 50 protected $itemid; 51 52 /** @var int $groupid The currently set groupid (if set) */ 53 protected $groupid; 54 55 /** @var course_context $context The course context */ 56 protected $context; 57 58 /** @var int $page The page number */ 59 protected $page; 60 61 /** @var int $perpage Results per page */ 62 protected $perpage; 63 64 /** @var array $items List of items on the page, they could be users or grade_items */ 65 protected $items; 66 67 /** @var array $validperpage List of allowed values for 'perpage' setting */ 68 protected static $validperpage = [20, 50, 100, 200, 400, 1000, 5000]; 69 70 /** 71 * Constructor 72 * 73 * @param int $courseid The course id 74 * @param int $itemid The item id 75 * @param int $groupid The group id 76 */ 77 public function __construct($courseid, $itemid, $groupid = null) { 78 global $DB; 79 80 $this->courseid = $courseid; 81 $this->itemid = $itemid; 82 $this->groupid = $groupid; 83 84 $this->context = context_course::instance($this->courseid); 85 $this->course = $DB->get_record('course', array('id' => $courseid)); 86 87 $this->page = optional_param('page', 0, PARAM_INT); 88 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)) { 92 // Get from cache. 93 $perpage = $cache->get(get_class($this)); 94 } else { 95 // Save to cache. 96 $cache->set(get_class($this), $perpage); 97 } 98 if ($perpage) { 99 $this->perpage = $perpage; 100 } else { 101 $this->perpage = 100; 102 } 103 104 $this->init(empty($itemid)); 105 } 106 107 /** 108 * Cache the grade_structure class 109 */ 110 public function setup_structure() { 111 $this->structure = new grade_structure(); 112 $this->structure->modinfo = get_fast_modinfo($this->course); 113 } 114 115 /** 116 * Create a nice link from a thing (user or grade_item). 117 * 118 * @param string $screen 119 * @param int $itemid 120 * @param bool $display Should we wrap this in an anchor ? 121 * @return string The link 122 */ 123 public function format_link($screen, $itemid, $display = null) { 124 $url = new moodle_url('/grade/report/singleview/index.php', array( 125 'id' => $this->courseid, 126 'item' => $screen, 127 'itemid' => $itemid, 128 'group' => $this->groupid, 129 )); 130 131 if ($display) { 132 return html_writer::link($url, $display); 133 } else { 134 return $url; 135 } 136 } 137 138 /** 139 * Get the grade_grade 140 * 141 * @param grade_item $item The grade_item 142 * @param int $userid The user id 143 * @return grade_grade 144 */ 145 public function fetch_grade_or_default($item, $userid) { 146 $grade = grade_grade::fetch(array( 147 'itemid' => $item->id, 'userid' => $userid 148 )); 149 150 if (!$grade) { 151 $default = new stdClass; 152 153 $default->userid = $userid; 154 $default->itemid = $item->id; 155 $default->feedback = ''; 156 157 $grade = new grade_grade($default, false); 158 } 159 160 $grade->grade_item = $item; 161 162 return $grade; 163 } 164 165 /** 166 * Make the HTML element that toggles all the checkboxes on or off. 167 * 168 * @param string $key A unique key for this control - inserted in the classes. 169 * @return string 170 */ 171 public function make_toggle($key) { 172 $attrs = array('href' => '#'); 173 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'); 180 } 181 if ($strmanager->string_exists(strtolower($key) . 'none', 'gradereport_singleview')) { 182 $titlenone = get_string(strtolower($key) . 'none', 'gradereport_singleview'); 183 } 184 185 $all = html_writer::tag('a', get_string('all'), $attrs + array( 186 'class' => 'include all ' . $key, 187 'title' => $titleall 188 )); 189 190 $none = html_writer::tag('a', get_string('none'), $attrs + array( 191 'class' => 'include none ' . $key, 192 'title' => $titlenone 193 )); 194 195 return html_writer::tag('span', "$all / $none", array( 196 'class' => 'inclusion_links' 197 )); 198 } 199 200 /** 201 * Make a toggle link with some text before it. 202 * 203 * @param string $key A unique key for this control - inserted in the classes. 204 * @return string 205 */ 206 public function make_toggle_links($key) { 207 return get_string($key, 'gradereport_singleview') . ' ' . 208 $this->make_toggle($key); 209 } 210 211 /** 212 * Get the default heading for the screen. 213 * 214 * @return string 215 */ 216 public function heading() { 217 return get_string('entrypage', 'gradereport_singleview'); 218 } 219 220 /** 221 * Override this to init the screen. 222 * 223 * @param boolean $selfitemisempty True if no item has been selected yet. 224 */ 225 public abstract function init($selfitemisempty = false); 226 227 /** 228 * Get the type of items in the list. 229 * 230 * @return string 231 */ 232 public abstract function item_type(); 233 234 /** 235 * Get the entire screen as a string. 236 * 237 * @return string 238 */ 239 public abstract function html(); 240 241 /** 242 * Does this screen support paging? 243 * 244 * @return bool 245 */ 246 public function supports_paging() { 247 return true; 248 } 249 250 /** 251 * Default pager 252 * 253 * @return string 254 */ 255 public function pager() { 256 return ''; 257 } 258 259 /** 260 * Initialise the js for this screen. 261 */ 262 public function js() { 263 global $PAGE; 264 265 $module = array( 266 'name' => 'gradereport_singleview', 267 'fullpath' => '/grade/report/singleview/js/singleview.js', 268 'requires' => array('base', 'dom', 'event', 'event-simulate', 'io-base') 269 ); 270 271 $PAGE->requires->string_for_js('overridenoneconfirm', 'gradereport_singleview'); 272 $PAGE->requires->js_init_call('M.gradereport_singleview.init', array(), false, $module); 273 } 274 275 /** 276 * Process the data from a form submission. 277 * 278 * @param array $data 279 * @return array of warnings 280 */ 281 public function process($data) { 282 $warnings = array(); 283 284 $fields = $this->definition(); 285 286 // Avoiding execution timeouts when updating 287 // a large amount of grades. 288 $progress = 0; 289 $progressbar = new \core\progress\display_if_slow(); 290 $progressbar->start_html(); 291 $progressbar->start_progress(get_string('savegrades', 'gradereport_singleview'), count((array) $data) - 1); 292 $changecount = array(); 293 // This array is used to determine if the override should be excluded from being counted as a change. 294 $ignorevalues = []; 295 296 foreach ($data as $varname => $throw) { 297 $progressbar->progress($progress); 298 $progress++; 299 if (preg_match("/(\w+)_(\d+)_(\d+)/", $varname, $matches)) { 300 $itemid = $matches[2]; 301 $userid = $matches[3]; 302 } else { 303 continue; 304 } 305 306 $gradeitem = grade_item::fetch(array( 307 'id' => $itemid, 'courseid' => $this->courseid 308 )); 309 310 if (preg_match('/^old[oe]{1}/', $varname)) { 311 $elementname = preg_replace('/^old/', '', $varname); 312 if (!isset($data->$elementname)) { 313 // Decrease the progress because we've increased the 314 // size of the array we are iterating through. 315 $progress--; 316 $data->$elementname = false; 317 } 318 } 319 320 if (!in_array($matches[1], $fields)) { 321 continue; 322 } 323 324 if (!$gradeitem) { 325 continue; 326 } 327 328 $grade = $this->fetch_grade_or_default($gradeitem, $userid); 329 330 $classname = '\\gradereport_singleview\\local\\ui\\' . $matches[1]; 331 $element = new $classname($grade); 332 333 $name = $element->get_name(); 334 $oldname = "old$name"; 335 336 $posted = $data->$name; 337 338 $format = $element->determine_format(); 339 340 if ($format->is_textbox() and trim($data->$name) === '') { 341 $data->$name = null; 342 } 343 344 // Same value; skip. 345 if (isset($data->$oldname) && $data->$oldname == $posted) { 346 continue; 347 } 348 349 // If the user submits Exclude grade elements without the proper. 350 // permissions then we should refuse to update. 351 if ($matches[1] === 'exclude' && !has_capability('moodle/grade:manage', $this->context)){ 352 $warnings[] = get_string('nopermissions', 'error', get_string('grade:manage', 'role')); 353 continue; 354 } 355 356 $msg = $element->set($posted); 357 // Value to check against our list of matchelements to ignore. 358 $check = explode('_', $varname, 2); 359 360 // Optional type. 361 if (!empty($msg)) { 362 $warnings[] = $msg; 363 if ($element instanceof \gradereport_singleview\local\ui\finalgrade) { 364 // Add this value to this list so that the override object that is coming next will also be skipped. 365 $ignorevalues[$check[1]] = $check[1]; 366 // This item wasn't changed so don't add to the changecount. 367 continue; 368 } 369 } 370 // Check to see if this value has already been skipped. 371 if (array_key_exists($check[1], $ignorevalues)) { 372 continue; 373 } 374 if (preg_match('/_(\d+)_(\d+)/', $varname, $matchelement)) { 375 $changecount[$matchelement[0]] = 1; 376 } 377 } 378 379 // Some post-processing. 380 $eventdata = new stdClass; 381 $eventdata->warnings = $warnings; 382 $eventdata->post_data = $data; 383 $eventdata->instance = $this; 384 $eventdata->changecount = $changecount; 385 386 $progressbar->end_html(); 387 388 return $eventdata; 389 } 390 391 /** 392 * By default there are no options. 393 * @return array 394 */ 395 public function options() { 396 return array(); 397 } 398 399 /** 400 * Should we show the group selector? 401 * @return bool 402 */ 403 public function display_group_selector() { 404 return true; 405 } 406 407 /** 408 * Should we show the next prev selector? 409 * @return bool 410 */ 411 public function supports_next_prev() { 412 return true; 413 } 414 415 /** 416 * Load a valid list of users for this gradebook as the screen "items". 417 * @return array $users A list of enroled users. 418 */ 419 protected function load_users() { 420 global $CFG; 421 422 // Create a graded_users_iterator because it will properly check the groups etc. 423 $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol); 424 $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol); 425 $showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $this->context); 426 427 require_once($CFG->dirroot.'/grade/lib.php'); 428 $gui = new \graded_users_iterator($this->course, null, $this->groupid); 429 $gui->require_active_enrolment($showonlyactiveenrol); 430 $gui->init(); 431 432 // Flatten the users. 433 $users = array(); 434 while ($user = $gui->next_user()) { 435 $users[$user->user->id] = $user->user; 436 } 437 $gui->close(); 438 return $users; 439 } 440 441 /** 442 * Allow selection of number of items to display per page. 443 * @return string 444 */ 445 public function perpage_select() { 446 global $PAGE, $OUTPUT; 447 448 $options = array_combine(self::$validperpage, self::$validperpage); 449 450 $url = new moodle_url($PAGE->url); 451 $url->remove_params(['page', 'perpage']); 452 453 $out = ''; 454 $select = new \single_select($url, 'perpage', $options, $this->perpage, null, 'perpagechanger'); 455 $select->label = get_string('itemsperpage', 'gradereport_singleview'); 456 $out .= $OUTPUT->render($select); 457 458 return $out; 459 } 460 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body