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