Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402] [Versions 402 and 403]
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 * The screen with a list of users. 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 grade_report; 28 use gradereport_singleview\local\ui\range; 29 use gradereport_singleview\local\ui\bulk_insert; 30 use grade_grade; 31 use grade_item; 32 use moodle_url; 33 use pix_icon; 34 use html_writer; 35 use gradereport_singleview; 36 37 defined('MOODLE_INTERNAL') || die; 38 39 /** 40 * The screen with a list of users. 41 * 42 * @package gradereport_singleview 43 * @copyright 2014 Moodle Pty Ltd (http://moodle.com) 44 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 45 */ 46 class grade extends tablelike implements selectable_items, filterable_items { 47 48 /** 49 * Used for paging 50 * @var int $totalitemcount 51 */ 52 private $totalitemcount = 0; 53 54 /** 55 * True if this is a manual grade item 56 * @var bool $requiresextra 57 */ 58 private $requiresextra = false; 59 60 /** 61 * True if there are more users than our limit. 62 * @var bool $requirepaging 63 */ 64 private $requirespaging = true; 65 66 /** 67 * To store UI element that generates a grade_item min/max range. 68 * @var range; 69 */ 70 protected $range; 71 72 /** 73 * Returns a grade_item instance or false if none found. 74 * @var grade_item|bool 75 */ 76 public $item; 77 78 /** 79 * True if $CFG->grade_overridecat is true 80 * 81 * @return bool 82 */ 83 public static function allowcategories(): bool { 84 return get_config('moodle', 'grade_overridecat'); 85 } 86 87 /** 88 * Filter the list excluding category items (if required)? 89 * @param grade_item $item The grade item. 90 * @return bool 91 */ 92 public static function filter($item): bool { 93 return get_config('moodle', 'grade_overridecat') || 94 !($item->is_course_item() || $item->is_category_item()); 95 } 96 97 /** 98 * Get the label for the select box that chooses items for this page. 99 * @return string 100 */ 101 public function select_label(): string { 102 return get_string('selectuser', 'gradereport_singleview'); 103 } 104 105 /** 106 * Get the description of this page 107 * @return string 108 */ 109 public function description(): string { 110 return get_string('users'); 111 } 112 113 /** 114 * Convert this list of items into an options list 115 * 116 * @return array 117 */ 118 public function options(): array { 119 $options = []; 120 foreach ($this->items as $userid => $user) { 121 $options[$userid] = fullname($user); 122 } 123 124 return $options; 125 } 126 127 /** 128 * Return the type of the things in this list. 129 * @return string 130 */ 131 public function item_type(): string { 132 return 'user'; 133 } 134 135 /** 136 * Get the original settings for this item 137 * @return array 138 */ 139 public function original_definition(): array { 140 return [ 141 'finalgrade', 142 'feedback', 143 'override', 144 'exclude' 145 ]; 146 } 147 148 /** 149 * Init this page 150 * 151 * @param bool $selfitemisempty True if we have not selected a user. 152 */ 153 public function init($selfitemisempty = false) { 154 155 $this->items = grade_report::get_gradable_users($this->courseid, $this->groupid); 156 $this->totalitemcount = count($this->items); 157 158 if ($selfitemisempty) { 159 return; 160 } 161 162 $params = [ 163 'id' => $this->itemid, 164 'courseid' => $this->courseid 165 ]; 166 167 $this->item = grade_item::fetch($params); 168 if (!self::filter($this->item)) { 169 $this->items = []; 170 $this->set_init_error(get_string('gradeitemcannotbeoverridden', 'gradereport_singleview')); 171 } 172 173 $this->requiresextra = !$this->item->is_manual_item(); 174 175 $this->setup_structure(); 176 177 $this->set_definition($this->original_definition()); 178 $this->set_headers($this->original_headers()); 179 } 180 181 /** 182 * Get the table headers 183 * 184 * @return array 185 */ 186 public function original_headers() { 187 return [ 188 get_string('fullnameuser', 'core'), 189 '', // For filter icon. 190 get_string('grade', 'grades'), 191 get_string('range', 'grades'), 192 get_string('feedback', 'grades'), 193 get_string('override', 'gradereport_singleview'), 194 get_string('exclude', 'gradereport_singleview'), 195 ]; 196 } 197 198 /** 199 * Format a row in the table 200 * 201 * @param stdClass $item 202 * @return array 203 */ 204 public function format_line($item): array { 205 global $OUTPUT; 206 207 $grade = $this->fetch_grade_or_default($this->item, $item->id); 208 209 $lockicon = ''; 210 211 $lockedgrade = $lockedgradeitem = 0; 212 if (!empty($grade->locked)) { 213 $lockedgrade = 1; 214 } 215 if (!empty($grade->grade_item->locked)) { 216 $lockedgradeitem = 1; 217 } 218 // Check both grade and grade item. 219 if ( $lockedgrade || $lockedgradeitem ) { 220 $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked') . ' '; 221 } 222 223 if (has_capability('moodle/site:viewfullnames', \context_course::instance($this->courseid))) { 224 $fullname = $lockicon . fullname($item, true); 225 } else { 226 $fullname = $lockicon . fullname($item); 227 } 228 229 $item->imagealt = $fullname; 230 $url = new moodle_url("/user/view.php", ['id' => $item->id, 'course' => $this->courseid]); 231 $grade->label = $fullname; 232 $userpic = $OUTPUT->user_picture($item, ['link' => false, 'visibletoscreenreaders' => false]); 233 234 $formatteddefinition = $this->format_definition($grade); 235 236 $line = [ 237 html_writer::link($url, $userpic . $fullname), 238 $this->get_user_action_menu($item), 239 $formatteddefinition['finalgrade'], 240 $this->item_range(), 241 $formatteddefinition['feedback'], 242 $formatteddefinition['override'], 243 $formatteddefinition['exclude'], 244 ]; 245 $lineclasses = [ 246 'user', 247 'action', 248 'grade', 249 'range', 250 ]; 251 $outputline = []; 252 $i = 0; 253 foreach ($line as $key => $value) { 254 $cell = new \html_table_cell($value); 255 if ($isheader = $i == 0) { 256 $cell->header = $isheader; 257 $cell->scope = "row"; 258 } 259 if (array_key_exists($key, $lineclasses)) { 260 $cell->attributes['class'] = $lineclasses[$key]; 261 } 262 $outputline[] = $cell; 263 $i++; 264 } 265 266 return $outputline; 267 } 268 269 /** 270 * Get the range ui element for this grade_item 271 * 272 * @return element; 273 */ 274 public function item_range() { 275 if (empty($this->range)) { 276 $this->range = new range($this->item); 277 } 278 279 return $this->range; 280 } 281 282 /** 283 * Does this page require paging? 284 * 285 * @return bool 286 */ 287 public function supports_paging(): bool { 288 return $this->requirespaging; 289 } 290 291 /** 292 * Get the pager for this page. 293 * 294 * @return string 295 */ 296 public function pager(): string { 297 global $OUTPUT; 298 299 return $OUTPUT->paging_bar( 300 $this->totalitemcount, $this->page, $this->perpage, 301 new moodle_url('/grade/report/singleview/index.php', [ 302 'perpage' => $this->perpage, 303 'id' => $this->courseid, 304 'group' => $this->groupid, 305 'itemid' => $this->itemid, 306 'item' => 'grade' 307 ]) 308 ); 309 } 310 311 /** 312 * Get the heading for this page. 313 * 314 * @return string 315 */ 316 public function heading(): string { 317 global $PAGE; 318 $headinglangstring = $PAGE->user_is_editing() ? 'gradeitemedit' : 'gradeitem'; 319 return get_string($headinglangstring, 'gradereport_singleview', $this->item->get_name()); 320 } 321 322 /** 323 * Get the summary for this table. 324 * 325 * @return string 326 */ 327 public function summary(): string { 328 return get_string('summarygrade', 'gradereport_singleview'); 329 } 330 331 /** 332 * Process the data from the form. 333 * 334 * @param array $data 335 * @return \stdClass of warnings 336 */ 337 public function process($data): \stdClass { 338 $bulk = new bulk_insert($this->item); 339 // Bulk insert messages the data to be passed in 340 // ie: for all grades of empty grades apply the specified value. 341 if ($bulk->is_applied($data)) { 342 $filter = $bulk->get_type($data); 343 $insertvalue = $bulk->get_insert_value($data); 344 // Appropriately massage data that may not exist. 345 if ($this->supports_paging()) { 346 $gradeitem = grade_item::fetch([ 347 'courseid' => $this->courseid, 348 'id' => $this->item->id 349 ]); 350 351 $null = $gradeitem->gradetype == GRADE_TYPE_SCALE ? -1 : ''; 352 353 foreach ($this->items as $itemid => $item) { 354 $field = "finalgrade_{$gradeitem->id}_{$itemid}"; 355 if (isset($data->$field)) { 356 continue; 357 } 358 359 $grade = grade_grade::fetch([ 360 'itemid' => $gradeitem->id, 361 'userid' => $itemid 362 ]); 363 364 $data->$field = empty($grade) ? $null : $grade->finalgrade; 365 $data->{"old$field"} = $data->$field; 366 } 367 } 368 369 foreach ($data as $varname => $value) { 370 if (preg_match('/^oldoverride_(\d+)_(\d+)/', $varname, $matches)) { 371 // If we've selected overriding all grades. 372 if ($filter == 'all') { 373 $override = "override_{$matches[1]}_{$matches[2]}"; 374 $data->$override = '1'; 375 } 376 } 377 if (!preg_match('/^finalgrade_(\d+)_/', $varname, $matches)) { 378 continue; 379 } 380 381 $gradeitem = grade_item::fetch([ 382 'courseid' => $this->courseid, 383 'id' => $matches[1] 384 ]); 385 386 $isscale = ($gradeitem->gradetype == GRADE_TYPE_SCALE); 387 388 $empties = (trim($value) === '' || ($isscale && $value == -1)); 389 390 if ($filter == 'all' || $empties) { 391 $data->$varname = ($isscale && empty($insertvalue)) ? 392 -1 : $insertvalue; 393 } 394 } 395 } 396 return parent::process($data); 397 } 398 399 /** 400 * Return the action menu HTML for the user item. 401 * 402 * @param \stdClass $user 403 * @return mixed 404 */ 405 private function get_user_action_menu(\stdClass $user) { 406 global $OUTPUT; 407 408 $menuitems = []; 409 $url = new moodle_url($this->format_link('user', $user->id)); 410 $title = get_string('showallgrades', 'core_grades'); 411 $menuitems[] = new \action_menu_link_secondary($url, null, $title); 412 $menu = new \action_menu($menuitems); 413 $icon = $OUTPUT->pix_icon('i/moremenu', get_string('actions')); 414 $extraclasses = 'btn btn-link btn-icon icon-size-3 d-flex align-items-center justify-content-center'; 415 $menu->set_menu_trigger($icon, $extraclasses); 416 $menu->set_menu_left(); 417 $menu->set_boundary('window'); 418 419 return $OUTPUT->render($menu); 420 } 421 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body