Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
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 * This file contains a renderer for the assignment class 19 * 20 * @package mod_assign 21 * @copyright 2012 NetSpot {@link http://www.netspot.com.au} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 require_once($CFG->dirroot . '/mod/assign/locallib.php'); 28 29 use \mod_assign\output\grading_app; 30 31 /** 32 * A custom renderer class that extends the plugin_renderer_base and is used by the assign module. 33 * 34 * @package mod_assign 35 * @copyright 2012 NetSpot {@link http://www.netspot.com.au} 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class mod_assign_renderer extends plugin_renderer_base { 39 40 /** 41 * Rendering assignment files 42 * 43 * @param context $context 44 * @param int $userid 45 * @param string $filearea 46 * @param string $component 47 * @return string 48 */ 49 public function assign_files(context $context, $userid, $filearea, $component) { 50 return $this->render(new assign_files($context, $userid, $filearea, $component)); 51 } 52 53 /** 54 * Rendering assignment files 55 * 56 * @param assign_files $tree 57 * @return string 58 */ 59 public function render_assign_files(assign_files $tree) { 60 $this->htmlid = html_writer::random_id('assign_files_tree'); 61 $this->page->requires->js_init_call('M.mod_assign.init_tree', array(true, $this->htmlid)); 62 $html = '<div id="'.$this->htmlid.'">'; 63 $html .= $this->htmllize_tree($tree, $tree->dir); 64 $html .= '</div>'; 65 66 if ($tree->portfolioform) { 67 $html .= $tree->portfolioform; 68 } 69 return $html; 70 } 71 72 /** 73 * Utility function to add a row of data to a table with 2 columns where the first column is the table's header. 74 * Modified the table param and does not return a value. 75 * 76 * @param html_table $table The table to append the row of data to 77 * @param string $first The first column text 78 * @param string $second The second column text 79 * @param array $firstattributes The first column attributes (optional) 80 * @param array $secondattributes The second column attributes (optional) 81 * @return void 82 */ 83 private function add_table_row_tuple(html_table $table, $first, $second, $firstattributes = [], 84 $secondattributes = []) { 85 $row = new html_table_row(); 86 $cell1 = new html_table_cell($first); 87 $cell1->header = true; 88 if (!empty($firstattributes)) { 89 $cell1->attributes = $firstattributes; 90 } 91 $cell2 = new html_table_cell($second); 92 if (!empty($secondattributes)) { 93 $cell2->attributes = $secondattributes; 94 } 95 $row->cells = array($cell1, $cell2); 96 $table->data[] = $row; 97 } 98 99 /** 100 * Render a grading message notification 101 * @param assign_gradingmessage $result The result to render 102 * @return string 103 */ 104 public function render_assign_gradingmessage(assign_gradingmessage $result) { 105 $urlparams = array('id' => $result->coursemoduleid, 'action'=>'grading'); 106 if (!empty($result->page)) { 107 $urlparams['page'] = $result->page; 108 } 109 $url = new moodle_url('/mod/assign/view.php', $urlparams); 110 $classes = $result->gradingerror ? 'notifyproblem' : 'notifysuccess'; 111 112 $o = ''; 113 $o .= $this->output->heading($result->heading, 4); 114 $o .= $this->output->notification($result->message, $classes); 115 $o .= $this->output->continue_button($url); 116 return $o; 117 } 118 119 /** 120 * Render the generic form 121 * @param assign_form $form The form to render 122 * @return string 123 */ 124 public function render_assign_form(assign_form $form) { 125 $o = ''; 126 if ($form->jsinitfunction) { 127 $this->page->requires->js_init_call($form->jsinitfunction, array()); 128 } 129 $o .= $this->output->box_start('boxaligncenter ' . $form->classname); 130 $o .= $this->moodleform($form->form); 131 $o .= $this->output->box_end(); 132 return $o; 133 } 134 135 /** 136 * Render the user summary 137 * 138 * @param assign_user_summary $summary The user summary to render 139 * @return string 140 */ 141 public function render_assign_user_summary(assign_user_summary $summary) { 142 $o = ''; 143 $supendedclass = ''; 144 $suspendedicon = ''; 145 146 if (!$summary->user) { 147 return; 148 } 149 150 if ($summary->suspendeduser) { 151 $supendedclass = ' usersuspended'; 152 $suspendedstring = get_string('userenrolmentsuspended', 'grades'); 153 $suspendedicon = ' ' . $this->pix_icon('i/enrolmentsuspended', $suspendedstring); 154 } 155 $o .= $this->output->container_start('usersummary'); 156 $o .= $this->output->box_start('boxaligncenter usersummarysection'.$supendedclass); 157 if ($summary->blindmarking) { 158 $o .= get_string('hiddenuser', 'assign') . $summary->uniqueidforuser.$suspendedicon; 159 } else { 160 $o .= $this->output->user_picture($summary->user); 161 $o .= $this->output->spacer(array('width'=>30)); 162 $urlparams = array('id' => $summary->user->id, 'course'=>$summary->courseid); 163 $url = new moodle_url('/user/view.php', $urlparams); 164 $fullname = fullname($summary->user, $summary->viewfullnames); 165 $extrainfo = array(); 166 foreach ($summary->extrauserfields as $extrafield) { 167 $extrainfo[] = s($summary->user->$extrafield); 168 } 169 if (count($extrainfo)) { 170 $fullname .= ' (' . implode(', ', $extrainfo) . ')'; 171 } 172 $fullname .= $suspendedicon; 173 $o .= $this->output->action_link($url, $fullname); 174 } 175 $o .= $this->output->box_end(); 176 $o .= $this->output->container_end(); 177 178 return $o; 179 } 180 181 /** 182 * Render the submit for grading page 183 * 184 * @param assign_submit_for_grading_page $page 185 * @return string 186 */ 187 public function render_assign_submit_for_grading_page($page) { 188 $o = ''; 189 190 $o .= $this->output->container_start('submitforgrading'); 191 $o .= $this->output->heading(get_string('confirmsubmissionheading', 'assign'), 3); 192 193 $cancelurl = new moodle_url('/mod/assign/view.php', array('id' => $page->coursemoduleid)); 194 if (count($page->notifications)) { 195 // At least one of the submission plugins is not ready for submission. 196 197 $o .= $this->output->heading(get_string('submissionnotready', 'assign'), 4); 198 199 foreach ($page->notifications as $notification) { 200 $o .= $this->output->notification($notification); 201 } 202 203 $o .= $this->output->continue_button($cancelurl); 204 } else { 205 // All submission plugins ready - show the confirmation form. 206 $o .= $this->moodleform($page->confirmform); 207 } 208 $o .= $this->output->container_end(); 209 210 return $o; 211 } 212 213 /** 214 * Page is done - render the footer. 215 * 216 * @return void 217 */ 218 public function render_footer() { 219 return $this->output->footer(); 220 } 221 222 /** 223 * Render the header. 224 * 225 * @param assign_header $header 226 * @return string 227 */ 228 public function render_assign_header(assign_header $header) { 229 global $USER; 230 231 $o = ''; 232 233 if ($header->subpage) { 234 $this->page->navbar->add($header->subpage); 235 $args = ['contextname' => $header->context->get_context_name(false, true), 'subpage' => $header->subpage]; 236 $title = get_string('subpagetitle', 'assign', $args); 237 } else { 238 $title = $header->context->get_context_name(false, true); 239 } 240 $courseshortname = $header->context->get_course_context()->get_context_name(false, true); 241 $title = $courseshortname . ': ' . $title; 242 $heading = format_string($header->assign->name, false, array('context' => $header->context)); 243 244 $this->page->set_title($title); 245 $this->page->set_heading($this->page->course->fullname); 246 247 $o .= $this->output->header(); 248 $o .= $this->output->heading($heading); 249 250 // Show the activity information output component. 251 $modinfo = get_fast_modinfo($header->assign->course); 252 $cm = $modinfo->get_cm($header->coursemoduleid); 253 $cmcompletion = \core_completion\cm_completion_details::get_instance($cm, $USER->id); 254 $activitydates = \core\activity_dates::get_dates_for_module($cm, $USER->id); 255 $o .= $this->output->activity_information($cm, $cmcompletion, $activitydates); 256 257 if ($header->preface) { 258 $o .= $header->preface; 259 } 260 261 if ($header->showintro) { 262 $o .= $this->output->box_start('generalbox boxaligncenter', 'intro'); 263 $o .= format_module_intro('assign', $header->assign, $header->coursemoduleid); 264 $o .= $header->postfix; 265 $o .= $this->output->box_end(); 266 } 267 268 return $o; 269 } 270 271 /** 272 * Render the header for an individual plugin. 273 * 274 * @param assign_plugin_header $header 275 * @return string 276 */ 277 public function render_assign_plugin_header(assign_plugin_header $header) { 278 $o = $header->plugin->view_header(); 279 return $o; 280 } 281 282 /** 283 * Render a table containing the current status of the grading process. 284 * 285 * @param assign_grading_summary $summary 286 * @return string 287 */ 288 public function render_assign_grading_summary(assign_grading_summary $summary) { 289 // Create a table for the data. 290 $o = ''; 291 $o .= $this->output->container_start('gradingsummary'); 292 $o .= $this->output->heading(get_string('gradingsummary', 'assign'), 3); 293 $o .= $this->output->box_start('boxaligncenter gradingsummarytable'); 294 $t = new html_table(); 295 296 // Visibility Status. 297 $cell1content = get_string('hiddenfromstudents'); 298 $cell2content = (!$summary->isvisible) ? get_string('yes') : get_string('no'); 299 $this->add_table_row_tuple($t, $cell1content, $cell2content); 300 301 // Status. 302 if ($summary->teamsubmission) { 303 if ($summary->warnofungroupedusers === assign_grading_summary::WARN_GROUPS_REQUIRED) { 304 $o .= $this->output->notification(get_string('ungroupedusers', 'assign')); 305 } else if ($summary->warnofungroupedusers === assign_grading_summary::WARN_GROUPS_OPTIONAL) { 306 $o .= $this->output->notification(get_string('ungroupedusersoptional', 'assign')); 307 } 308 $cell1content = get_string('numberofteams', 'assign'); 309 } else { 310 $cell1content = get_string('numberofparticipants', 'assign'); 311 } 312 313 $cell2content = $summary->participantcount; 314 $this->add_table_row_tuple($t, $cell1content, $cell2content); 315 316 // Drafts count and dont show drafts count when using offline assignment. 317 if ($summary->submissiondraftsenabled && $summary->submissionsenabled) { 318 $cell1content = get_string('numberofdraftsubmissions', 'assign'); 319 $cell2content = $summary->submissiondraftscount; 320 $this->add_table_row_tuple($t, $cell1content, $cell2content); 321 } 322 323 // Submitted for grading. 324 if ($summary->submissionsenabled) { 325 $cell1content = get_string('numberofsubmittedassignments', 'assign'); 326 $cell2content = $summary->submissionssubmittedcount; 327 $this->add_table_row_tuple($t, $cell1content, $cell2content); 328 329 if (!$summary->teamsubmission) { 330 $cell1content = get_string('numberofsubmissionsneedgrading', 'assign'); 331 $cell2content = $summary->submissionsneedgradingcount; 332 $this->add_table_row_tuple($t, $cell1content, $cell2content); 333 } 334 } 335 336 $time = time(); 337 if ($summary->duedate) { 338 // Time remaining. 339 $duedate = $summary->duedate; 340 $cell1content = get_string('timeremaining', 'assign'); 341 if ($summary->courserelativedatesmode) { 342 $cell2content = get_string('relativedatessubmissiontimeleft', 'mod_assign'); 343 } else { 344 if ($duedate - $time <= 0) { 345 $cell2content = get_string('assignmentisdue', 'assign'); 346 } else { 347 $cell2content = format_time($duedate - $time); 348 } 349 } 350 351 $this->add_table_row_tuple($t, $cell1content, $cell2content); 352 353 if ($duedate < $time) { 354 $cell1content = get_string('latesubmissions', 'assign'); 355 $cutoffdate = $summary->cutoffdate; 356 if ($cutoffdate) { 357 if ($cutoffdate > $time) { 358 $cell2content = get_string('latesubmissionsaccepted', 'assign', userdate($summary->cutoffdate)); 359 } else { 360 $cell2content = get_string('nomoresubmissionsaccepted', 'assign'); 361 } 362 363 $this->add_table_row_tuple($t, $cell1content, $cell2content); 364 } 365 } 366 367 } 368 369 // All done - write the table. 370 $o .= html_writer::table($t); 371 $o .= $this->output->box_end(); 372 373 // Link to the grading page. 374 $o .= html_writer::start_tag('center'); 375 $o .= $this->output->container_start('submissionlinks'); 376 $urlparams = array('id' => $summary->coursemoduleid, 'action' => 'grading'); 377 $url = new moodle_url('/mod/assign/view.php', $urlparams); 378 $o .= html_writer::link($url, get_string('viewgrading', 'mod_assign'), 379 ['class' => 'btn btn-secondary']); 380 if ($summary->cangrade) { 381 $urlparams = array('id' => $summary->coursemoduleid, 'action' => 'grader'); 382 $url = new moodle_url('/mod/assign/view.php', $urlparams); 383 $o .= html_writer::link($url, get_string('gradeverb'), 384 ['class' => 'btn btn-primary ml-1']); 385 } 386 $o .= $this->output->container_end(); 387 388 // Close the container and insert a spacer. 389 $o .= $this->output->container_end(); 390 $o .= html_writer::end_tag('center'); 391 392 return $o; 393 } 394 395 /** 396 * Render a table containing all the current grades and feedback. 397 * 398 * @param assign_feedback_status $status 399 * @return string 400 */ 401 public function render_assign_feedback_status(assign_feedback_status $status) { 402 $o = ''; 403 404 $o .= $this->output->container_start('feedback'); 405 $o .= $this->output->heading(get_string('feedback', 'assign'), 3); 406 $o .= $this->output->box_start('boxaligncenter feedbacktable'); 407 $t = new html_table(); 408 409 // Grade. 410 if (isset($status->gradefordisplay)) { 411 $cell1content = get_string('gradenoun'); 412 $cell2content = $status->gradefordisplay; 413 $this->add_table_row_tuple($t, $cell1content, $cell2content); 414 415 // Grade date. 416 $cell1content = get_string('gradedon', 'assign'); 417 $cell2content = userdate($status->gradeddate); 418 $this->add_table_row_tuple($t, $cell1content, $cell2content); 419 } 420 421 if ($status->grader) { 422 // Grader. 423 $cell1content = get_string('gradedby', 'assign'); 424 $cell2content = $this->output->user_picture($status->grader) . 425 $this->output->spacer(array('width' => 30)) . 426 fullname($status->grader, $status->canviewfullnames); 427 $this->add_table_row_tuple($t, $cell1content, $cell2content); 428 } 429 430 foreach ($status->feedbackplugins as $plugin) { 431 if ($plugin->is_enabled() && 432 $plugin->is_visible() && 433 $plugin->has_user_summary() && 434 !empty($status->grade) && 435 !$plugin->is_empty($status->grade)) { 436 437 $displaymode = assign_feedback_plugin_feedback::SUMMARY; 438 $pluginfeedback = new assign_feedback_plugin_feedback($plugin, 439 $status->grade, 440 $displaymode, 441 $status->coursemoduleid, 442 $status->returnaction, 443 $status->returnparams); 444 $cell1content = $plugin->get_name(); 445 $cell2content = $this->render($pluginfeedback); 446 $this->add_table_row_tuple($t, $cell1content, $cell2content); 447 } 448 } 449 450 $o .= html_writer::table($t); 451 $o .= $this->output->box_end(); 452 453 $o .= $this->output->container_end(); 454 return $o; 455 } 456 457 /** 458 * Render a compact view of the current status of the submission. 459 * 460 * @param assign_submission_status_compact $status 461 * @return string 462 */ 463 public function render_assign_submission_status_compact(assign_submission_status_compact $status) { 464 $o = ''; 465 $o .= $this->output->container_start('submissionstatustable'); 466 $o .= $this->output->heading(get_string('submission', 'assign'), 3); 467 $time = time(); 468 469 if ($status->teamsubmissionenabled) { 470 $group = $status->submissiongroup; 471 if ($group) { 472 $team = format_string($group->name, false, $status->context); 473 } else if ($status->preventsubmissionnotingroup) { 474 if (count($status->usergroups) == 0) { 475 $team = '<span class="alert alert-error">' . get_string('noteam', 'assign') . '</span>'; 476 } else if (count($status->usergroups) > 1) { 477 $team = '<span class="alert alert-error">' . get_string('multipleteams', 'assign') . '</span>'; 478 } 479 } else { 480 $team = get_string('defaultteam', 'assign'); 481 } 482 $o .= $this->output->container(get_string('teamname', 'assign', $team), 'teamname'); 483 } 484 485 if (!$status->teamsubmissionenabled) { 486 if ($status->submission && $status->submission->status != ASSIGN_SUBMISSION_STATUS_NEW) { 487 $statusstr = get_string('submissionstatus_' . $status->submission->status, 'assign'); 488 $o .= $this->output->container($statusstr, 'submissionstatus' . $status->submission->status); 489 } else { 490 if (!$status->submissionsenabled) { 491 $o .= $this->output->container(get_string('noonlinesubmissions', 'assign'), 'submissionstatus'); 492 } else { 493 $o .= $this->output->container(get_string('noattempt', 'assign'), 'submissionstatus'); 494 } 495 } 496 } else { 497 $group = $status->submissiongroup; 498 if (!$group && $status->preventsubmissionnotingroup) { 499 $o .= $this->output->container(get_string('nosubmission', 'assign'), 'submissionstatus'); 500 } else if ($status->teamsubmission && $status->teamsubmission->status != ASSIGN_SUBMISSION_STATUS_NEW) { 501 $teamstatus = $status->teamsubmission->status; 502 $submissionsummary = get_string('submissionstatus_' . $teamstatus, 'assign'); 503 $groupid = 0; 504 if ($status->submissiongroup) { 505 $groupid = $status->submissiongroup->id; 506 } 507 508 $members = $status->submissiongroupmemberswhoneedtosubmit; 509 $userslist = array(); 510 foreach ($members as $member) { 511 $urlparams = array('id' => $member->id, 'course' => $status->courseid); 512 $url = new moodle_url('/user/view.php', $urlparams); 513 if ($status->view == assign_submission_status::GRADER_VIEW && $status->blindmarking) { 514 $userslist[] = $member->alias; 515 } else { 516 $fullname = fullname($member, $status->canviewfullnames); 517 $userslist[] = $this->output->action_link($url, $fullname); 518 } 519 } 520 if (count($userslist) > 0) { 521 $userstr = join(', ', $userslist); 522 $formatteduserstr = get_string('userswhoneedtosubmit', 'assign', $userstr); 523 $submissionsummary .= $this->output->container($formatteduserstr); 524 } 525 $o .= $this->output->container($submissionsummary, 'submissionstatus' . $status->teamsubmission->status); 526 } else { 527 if (!$status->submissionsenabled) { 528 $o .= $this->output->container(get_string('noonlinesubmissions', 'assign'), 'submissionstatus'); 529 } else { 530 $o .= $this->output->container(get_string('nosubmission', 'assign'), 'submissionstatus'); 531 } 532 } 533 } 534 535 // Is locked? 536 if ($status->locked) { 537 $o .= $this->output->container(get_string('submissionslocked', 'assign'), 'submissionlocked'); 538 } 539 540 // Grading status. 541 $statusstr = ''; 542 $classname = 'gradingstatus'; 543 if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || 544 $status->gradingstatus == ASSIGN_GRADING_STATUS_NOT_GRADED) { 545 $statusstr = get_string($status->gradingstatus, 'assign'); 546 } else { 547 $gradingstatus = 'markingworkflowstate' . $status->gradingstatus; 548 $statusstr = get_string($gradingstatus, 'assign'); 549 } 550 if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || 551 $status->gradingstatus == ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) { 552 $classname = 'submissiongraded'; 553 } else { 554 $classname = 'submissionnotgraded'; 555 } 556 $o .= $this->output->container($statusstr, $classname); 557 558 $submission = $status->teamsubmission ? $status->teamsubmission : $status->submission; 559 $duedate = $status->duedate; 560 if ($duedate > 0) { 561 562 if ($status->extensionduedate) { 563 // Extension date. 564 $duedate = $status->extensionduedate; 565 } 566 567 // Time remaining. 568 $classname = 'timeremaining'; 569 if ($duedate - $time <= 0) { 570 if (!$submission || 571 $submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) { 572 if ($status->submissionsenabled) { 573 $remaining = get_string('overdue', 'assign', format_time($time - $duedate)); 574 $classname = 'overdue'; 575 } else { 576 $remaining = get_string('duedatereached', 'assign'); 577 } 578 } else { 579 if ($submission->timemodified > $duedate) { 580 $remaining = get_string('submittedlate', 581 'assign', 582 format_time($submission->timemodified - $duedate)); 583 $classname = 'latesubmission'; 584 } else { 585 $remaining = get_string('submittedearly', 586 'assign', 587 format_time($submission->timemodified - $duedate)); 588 $classname = 'earlysubmission'; 589 } 590 } 591 } else { 592 $remaining = get_string('paramtimeremaining', 'assign', format_time($duedate - $time)); 593 } 594 $o .= $this->output->container($remaining, $classname); 595 } 596 597 // Show graders whether this submission is editable by students. 598 if ($status->view == assign_submission_status::GRADER_VIEW) { 599 if ($status->canedit) { 600 $o .= $this->output->container(get_string('submissioneditable', 'assign'), 'submissioneditable'); 601 } else { 602 $o .= $this->output->container(get_string('submissionnoteditable', 'assign'), 'submissionnoteditable'); 603 } 604 } 605 606 // Grading criteria preview. 607 if (!empty($status->gradingcontrollerpreview)) { 608 $o .= $this->output->container($status->gradingcontrollerpreview, 'gradingmethodpreview'); 609 } 610 611 if ($submission) { 612 613 if (!$status->teamsubmission || $status->submissiongroup != false || !$status->preventsubmissionnotingroup) { 614 foreach ($status->submissionplugins as $plugin) { 615 $pluginshowsummary = !$plugin->is_empty($submission) || !$plugin->allow_submissions(); 616 if ($plugin->is_enabled() && 617 $plugin->is_visible() && 618 $plugin->has_user_summary() && 619 $pluginshowsummary 620 ) { 621 622 $displaymode = assign_submission_plugin_submission::SUMMARY; 623 $pluginsubmission = new assign_submission_plugin_submission($plugin, 624 $submission, 625 $displaymode, 626 $status->coursemoduleid, 627 $status->returnaction, 628 $status->returnparams); 629 $plugincomponent = $plugin->get_subtype() . '_' . $plugin->get_type(); 630 $o .= $this->output->container($this->render($pluginsubmission), 'assignsubmission ' . $plugincomponent); 631 } 632 } 633 } 634 } 635 636 $o .= $this->output->container_end(); 637 return $o; 638 } 639 640 /** 641 * Render a table containing the current status of the submission. 642 * 643 * @param assign_submission_status $status 644 * @return string 645 */ 646 public function render_assign_submission_status(assign_submission_status $status) { 647 $o = ''; 648 $o .= $this->output->container_start('submissionstatustable'); 649 $o .= $this->output->heading(get_string('submissionstatusheading', 'assign'), 3); 650 $time = time(); 651 652 $o .= $this->output->box_start('boxaligncenter submissionsummarytable'); 653 654 $t = new html_table(); 655 656 $warningmsg = ''; 657 if ($status->teamsubmissionenabled) { 658 $cell1content = get_string('submissionteam', 'assign'); 659 $group = $status->submissiongroup; 660 if ($group) { 661 $cell2content = format_string($group->name, false, $status->context); 662 } else if ($status->preventsubmissionnotingroup) { 663 if (count($status->usergroups) == 0) { 664 $notification = new \core\output\notification(get_string('noteam', 'assign'), 'error'); 665 $notification->set_show_closebutton(false); 666 $warningmsg = $this->output->notification(get_string('noteam_desc', 'assign'), 'error'); 667 } else if (count($status->usergroups) > 1) { 668 $notification = new \core\output\notification(get_string('multipleteams', 'assign'), 'error'); 669 $notification->set_show_closebutton(false); 670 $warningmsg = $this->output->notification(get_string('multipleteams_desc', 'assign'), 'error'); 671 } 672 $cell2content = $this->output->render($notification); 673 } else { 674 $cell2content = get_string('defaultteam', 'assign'); 675 } 676 677 $this->add_table_row_tuple($t, $cell1content, $cell2content); 678 } 679 680 if ($status->attemptreopenmethod != ASSIGN_ATTEMPT_REOPEN_METHOD_NONE) { 681 $currentattempt = 1; 682 if (!$status->teamsubmissionenabled) { 683 if ($status->submission) { 684 $currentattempt = $status->submission->attemptnumber + 1; 685 } 686 } else { 687 if ($status->teamsubmission) { 688 $currentattempt = $status->teamsubmission->attemptnumber + 1; 689 } 690 } 691 692 $cell1content = get_string('attemptnumber', 'assign'); 693 $maxattempts = $status->maxattempts; 694 if ($maxattempts == ASSIGN_UNLIMITED_ATTEMPTS) { 695 $cell2content = get_string('currentattempt', 'assign', $currentattempt); 696 } else { 697 $cell2content = get_string('currentattemptof', 'assign', 698 array('attemptnumber' => $currentattempt, 'maxattempts' => $maxattempts)); 699 } 700 701 $this->add_table_row_tuple($t, $cell1content, $cell2content); 702 } 703 704 $cell1content = get_string('submissionstatus', 'assign'); 705 $cell2attributes = []; 706 if (!$status->teamsubmissionenabled) { 707 if ($status->submission && $status->submission->status != ASSIGN_SUBMISSION_STATUS_NEW) { 708 $cell2content = get_string('submissionstatus_' . $status->submission->status, 'assign'); 709 $cell2attributes = array('class' => 'submissionstatus' . $status->submission->status); 710 } else { 711 if (!$status->submissionsenabled) { 712 $cell2content = get_string('noonlinesubmissions', 'assign'); 713 } else { 714 $cell2content = get_string('noattempt', 'assign'); 715 } 716 } 717 } else { 718 $group = $status->submissiongroup; 719 if (!$group && $status->preventsubmissionnotingroup) { 720 $cell2content = get_string('nosubmission', 'assign'); 721 } else if ($status->teamsubmission && $status->teamsubmission->status != ASSIGN_SUBMISSION_STATUS_NEW) { 722 $teamstatus = $status->teamsubmission->status; 723 $cell2content = get_string('submissionstatus_' . $teamstatus, 'assign'); 724 725 $members = $status->submissiongroupmemberswhoneedtosubmit; 726 $userslist = array(); 727 foreach ($members as $member) { 728 $urlparams = array('id' => $member->id, 'course'=>$status->courseid); 729 $url = new moodle_url('/user/view.php', $urlparams); 730 if ($status->view == assign_submission_status::GRADER_VIEW && $status->blindmarking) { 731 $userslist[] = $member->alias; 732 } else { 733 $fullname = fullname($member, $status->canviewfullnames); 734 $userslist[] = $this->output->action_link($url, $fullname); 735 } 736 } 737 if (count($userslist) > 0) { 738 $userstr = join(', ', $userslist); 739 $formatteduserstr = get_string('userswhoneedtosubmit', 'assign', $userstr); 740 $cell2content .= $this->output->container($formatteduserstr); 741 } 742 743 $cell2attributes = array('class' => 'submissionstatus' . $status->teamsubmission->status); 744 } else { 745 if (!$status->submissionsenabled) { 746 $cell2content = get_string('noonlinesubmissions', 'assign'); 747 } else { 748 $cell2content = get_string('nosubmission', 'assign'); 749 } 750 } 751 } 752 753 $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); 754 755 // Is locked? 756 if ($status->locked) { 757 $cell1content = ''; 758 $cell2content = get_string('submissionslocked', 'assign'); 759 $cell2attributes = array('class' => 'submissionlocked'); 760 $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); 761 } 762 763 // Grading status. 764 $cell1content = get_string('gradingstatus', 'assign'); 765 if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || 766 $status->gradingstatus == ASSIGN_GRADING_STATUS_NOT_GRADED) { 767 $cell2content = get_string($status->gradingstatus, 'assign'); 768 } else { 769 $gradingstatus = 'markingworkflowstate' . $status->gradingstatus; 770 $cell2content = get_string($gradingstatus, 'assign'); 771 } 772 if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || 773 $status->gradingstatus == ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) { 774 $cell2attributes = array('class' => 'submissiongraded'); 775 } else { 776 $cell2attributes = array('class' => 'submissionnotgraded'); 777 } 778 $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); 779 780 $submission = $status->teamsubmission ? $status->teamsubmission : $status->submission; 781 $duedate = $status->duedate; 782 if ($duedate > 0) { 783 if ($status->view == assign_submission_status::GRADER_VIEW) { 784 if ($status->cutoffdate) { 785 // Cut off date. 786 $cell1content = get_string('cutoffdate', 'assign'); 787 $cell2content = userdate($status->cutoffdate); 788 $this->add_table_row_tuple($t, $cell1content, $cell2content); 789 } 790 } 791 792 if ($status->extensionduedate) { 793 // Extension date. 794 $cell1content = get_string('extensionduedate', 'assign'); 795 $cell2content = userdate($status->extensionduedate); 796 $this->add_table_row_tuple($t, $cell1content, $cell2content); 797 $duedate = $status->extensionduedate; 798 } 799 800 // Time remaining. 801 $cell1content = get_string('timeremaining', 'assign'); 802 $cell2attributes = []; 803 if ($duedate - $time <= 0) { 804 if (!$submission || 805 $submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) { 806 if ($status->submissionsenabled) { 807 $cell2content = get_string('overdue', 'assign', format_time($time - $duedate)); 808 $cell2attributes = array('class' => 'overdue'); 809 } else { 810 $cell2content = get_string('duedatereached', 'assign'); 811 } 812 } else { 813 if ($submission->timemodified > $duedate) { 814 $cell2content = get_string('submittedlate', 815 'assign', 816 format_time($submission->timemodified - $duedate)); 817 $cell2attributes = array('class' => 'latesubmission'); 818 } else { 819 $cell2content = get_string('submittedearly', 820 'assign', 821 format_time($submission->timemodified - $duedate)); 822 $cell2attributes = array('class' => 'earlysubmission'); 823 } 824 } 825 } else { 826 $cell2content = format_time($duedate - $time); 827 } 828 $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); 829 } 830 831 // Show graders whether this submission is editable by students. 832 if ($status->view == assign_submission_status::GRADER_VIEW) { 833 $cell1content = get_string('editingstatus', 'assign'); 834 if ($status->canedit) { 835 $cell2content = get_string('submissioneditable', 'assign'); 836 $cell2attributes = array('class' => 'submissioneditable'); 837 } else { 838 $cell2content = get_string('submissionnoteditable', 'assign'); 839 $cell2attributes = array('class' => 'submissionnoteditable'); 840 } 841 $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); 842 } 843 844 // Grading criteria preview. 845 if (!empty($status->gradingcontrollerpreview)) { 846 $cell1content = get_string('gradingmethodpreview', 'assign'); 847 $cell2content = $status->gradingcontrollerpreview; 848 $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); 849 } 850 851 // Last modified. 852 if ($submission) { 853 $cell1content = get_string('timemodified', 'assign'); 854 855 if ($submission->status != ASSIGN_SUBMISSION_STATUS_NEW) { 856 $cell2content = userdate($submission->timemodified); 857 } else { 858 $cell2content = "-"; 859 } 860 861 $this->add_table_row_tuple($t, $cell1content, $cell2content); 862 863 if (!$status->teamsubmission || $status->submissiongroup != false || !$status->preventsubmissionnotingroup) { 864 foreach ($status->submissionplugins as $plugin) { 865 $pluginshowsummary = !$plugin->is_empty($submission) || !$plugin->allow_submissions(); 866 if ($plugin->is_enabled() && 867 $plugin->is_visible() && 868 $plugin->has_user_summary() && 869 $pluginshowsummary 870 ) { 871 872 $cell1content = $plugin->get_name(); 873 $displaymode = assign_submission_plugin_submission::SUMMARY; 874 $pluginsubmission = new assign_submission_plugin_submission($plugin, 875 $submission, 876 $displaymode, 877 $status->coursemoduleid, 878 $status->returnaction, 879 $status->returnparams); 880 $cell2content = $this->render($pluginsubmission); 881 $this->add_table_row_tuple($t, $cell1content, $cell2content); 882 } 883 } 884 } 885 } 886 887 $o .= $warningmsg; 888 $o .= html_writer::table($t); 889 $o .= $this->output->box_end(); 890 891 // Links. 892 if ($status->view == assign_submission_status::STUDENT_VIEW) { 893 if ($status->canedit) { 894 if (!$submission || $submission->status == ASSIGN_SUBMISSION_STATUS_NEW) { 895 $o .= $this->output->box_start('generalbox submissionaction'); 896 $urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission'); 897 $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), 898 get_string('addsubmission', 'assign'), 'get'); 899 $o .= $this->output->box_start('boxaligncenter submithelp'); 900 $o .= get_string('addsubmission_help', 'assign'); 901 $o .= $this->output->box_end(); 902 $o .= $this->output->box_end(); 903 } else if ($submission->status == ASSIGN_SUBMISSION_STATUS_REOPENED) { 904 $o .= $this->output->box_start('generalbox submissionaction'); 905 $urlparams = array('id' => $status->coursemoduleid, 906 'action' => 'editprevioussubmission', 907 'sesskey'=>sesskey()); 908 $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), 909 get_string('addnewattemptfromprevious', 'assign'), 'get'); 910 $o .= $this->output->box_start('boxaligncenter submithelp'); 911 $o .= get_string('addnewattemptfromprevious_help', 'assign'); 912 $o .= $this->output->box_end(); 913 $o .= $this->output->box_end(); 914 $o .= $this->output->box_start('generalbox submissionaction'); 915 $urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission'); 916 $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), 917 get_string('addnewattempt', 'assign'), 'get'); 918 $o .= $this->output->box_start('boxaligncenter submithelp'); 919 $o .= get_string('addnewattempt_help', 'assign'); 920 $o .= $this->output->box_end(); 921 $o .= $this->output->box_end(); 922 } else { 923 $o .= $this->output->box_start('generalbox submissionaction'); 924 $urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission'); 925 $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), 926 get_string('editsubmission', 'assign'), 'get'); 927 $urlparams = array('id' => $status->coursemoduleid, 'action' => 'removesubmissionconfirm'); 928 $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), 929 get_string('removesubmission', 'assign'), 'get'); 930 $o .= $this->output->box_start('boxaligncenter submithelp'); 931 $o .= get_string('editsubmission_help', 'assign'); 932 $o .= $this->output->box_end(); 933 $o .= $this->output->box_end(); 934 } 935 } 936 937 if ($status->cansubmit) { 938 $urlparams = array('id' => $status->coursemoduleid, 'action'=>'submit'); 939 $o .= $this->output->box_start('generalbox submissionaction'); 940 $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), 941 get_string('submitassignment', 'assign'), 'get'); 942 $o .= $this->output->box_start('boxaligncenter submithelp'); 943 $o .= get_string('submitassignment_help', 'assign'); 944 $o .= $this->output->box_end(); 945 $o .= $this->output->box_end(); 946 } 947 } 948 949 $o .= $this->output->container_end(); 950 return $o; 951 } 952 953 /** 954 * Output the attempt history chooser for this assignment 955 * 956 * @param assign_attempt_history_chooser $history 957 * @return string 958 */ 959 public function render_assign_attempt_history_chooser(assign_attempt_history_chooser $history) { 960 $o = ''; 961 962 $context = $history->export_for_template($this); 963 $o .= $this->render_from_template('mod_assign/attempt_history_chooser', $context); 964 965 return $o; 966 } 967 968 /** 969 * Output the attempt history for this assignment 970 * 971 * @param assign_attempt_history $history 972 * @return string 973 */ 974 public function render_assign_attempt_history(assign_attempt_history $history) { 975 $o = ''; 976 977 // Don't show the last one because it is the current submission. 978 array_pop($history->submissions); 979 980 // Show newest to oldest. 981 $history->submissions = array_reverse($history->submissions); 982 983 if (empty($history->submissions)) { 984 return ''; 985 } 986 987 $containerid = 'attempthistory' . uniqid(); 988 $o .= $this->output->heading(get_string('attempthistory', 'assign'), 3); 989 $o .= $this->box_start('attempthistory', $containerid); 990 991 foreach ($history->submissions as $i => $submission) { 992 $grade = null; 993 foreach ($history->grades as $onegrade) { 994 if ($onegrade->attemptnumber == $submission->attemptnumber) { 995 if ($onegrade->grade != ASSIGN_GRADE_NOT_SET) { 996 $grade = $onegrade; 997 } 998 break; 999 } 1000 } 1001 1002 if ($submission) { 1003 $submissionsummary = userdate($submission->timemodified); 1004 } else { 1005 $submissionsummary = get_string('nosubmission', 'assign'); 1006 } 1007 1008 $attemptsummaryparams = array('attemptnumber'=>$submission->attemptnumber+1, 1009 'submissionsummary'=>$submissionsummary); 1010 $o .= $this->heading(get_string('attemptheading', 'assign', $attemptsummaryparams), 4); 1011 1012 $t = new html_table(); 1013 1014 if ($submission) { 1015 $cell1content = get_string('submissionstatus', 'assign'); 1016 $cell2content = get_string('submissionstatus_' . $submission->status, 'assign'); 1017 $this->add_table_row_tuple($t, $cell1content, $cell2content); 1018 1019 foreach ($history->submissionplugins as $plugin) { 1020 $pluginshowsummary = !$plugin->is_empty($submission) || !$plugin->allow_submissions(); 1021 if ($plugin->is_enabled() && 1022 $plugin->is_visible() && 1023 $plugin->has_user_summary() && 1024 $pluginshowsummary) { 1025 1026 $cell1content = $plugin->get_name(); 1027 $pluginsubmission = new assign_submission_plugin_submission($plugin, 1028 $submission, 1029 assign_submission_plugin_submission::SUMMARY, 1030 $history->coursemoduleid, 1031 $history->returnaction, 1032 $history->returnparams); 1033 $cell2content = $this->render($pluginsubmission); 1034 $this->add_table_row_tuple($t, $cell1content, $cell2content); 1035 } 1036 } 1037 } 1038 1039 if ($grade) { 1040 // Heading 'feedback'. 1041 $title = get_string('feedback', 'assign', $i); 1042 $title .= $this->output->spacer(array('width'=>10)); 1043 if ($history->cangrade) { 1044 // Edit previous feedback. 1045 $returnparams = http_build_query($history->returnparams); 1046 $urlparams = array('id' => $history->coursemoduleid, 1047 'rownum'=>$history->rownum, 1048 'useridlistid'=>$history->useridlistid, 1049 'attemptnumber'=>$grade->attemptnumber, 1050 'action'=>'grade', 1051 'returnaction'=>$history->returnaction, 1052 'returnparams'=>$returnparams); 1053 $url = new moodle_url('/mod/assign/view.php', $urlparams); 1054 $icon = new pix_icon('gradefeedback', 1055 get_string('editattemptfeedback', 'assign', $grade->attemptnumber+1), 1056 'mod_assign'); 1057 $title .= $this->output->action_icon($url, $icon); 1058 } 1059 $cell = new html_table_cell($title); 1060 $cell->attributes['class'] = 'feedbacktitle'; 1061 $cell->colspan = 2; 1062 $t->data[] = new html_table_row(array($cell)); 1063 1064 // Grade. 1065 $cell1content = get_string('gradenoun'); 1066 $cell2content = $grade->gradefordisplay; 1067 $this->add_table_row_tuple($t, $cell1content, $cell2content); 1068 1069 // Graded on. 1070 $cell1content = get_string('gradedon', 'assign'); 1071 $cell2content = userdate($grade->timemodified); 1072 $this->add_table_row_tuple($t, $cell1content, $cell2content); 1073 1074 // Graded by set to a real user. Not set can be empty or -1. 1075 if (!empty($grade->grader) && is_object($grade->grader)) { 1076 $cell1content = get_string('gradedby', 'assign'); 1077 $cell2content = $this->output->user_picture($grade->grader) . 1078 $this->output->spacer(array('width' => 30)) . fullname($grade->grader); 1079 $this->add_table_row_tuple($t, $cell1content, $cell2content); 1080 } 1081 1082 // Feedback from plugins. 1083 foreach ($history->feedbackplugins as $plugin) { 1084 if ($plugin->is_enabled() && 1085 $plugin->is_visible() && 1086 $plugin->has_user_summary() && 1087 !$plugin->is_empty($grade)) { 1088 1089 $pluginfeedback = new assign_feedback_plugin_feedback( 1090 $plugin, $grade, assign_feedback_plugin_feedback::SUMMARY, $history->coursemoduleid, 1091 $history->returnaction, $history->returnparams 1092 ); 1093 1094 $cell1content = $plugin->get_name(); 1095 $cell2content = $this->render($pluginfeedback); 1096 $this->add_table_row_tuple($t, $cell1content, $cell2content); 1097 } 1098 1099 } 1100 1101 } 1102 1103 $o .= html_writer::table($t); 1104 } 1105 $o .= $this->box_end(); 1106 1107 $this->page->requires->yui_module('moodle-mod_assign-history', 'Y.one("#' . $containerid . '").history'); 1108 1109 return $o; 1110 } 1111 1112 /** 1113 * Render a submission plugin submission 1114 * 1115 * @param assign_submission_plugin_submission $submissionplugin 1116 * @return string 1117 */ 1118 public function render_assign_submission_plugin_submission(assign_submission_plugin_submission $submissionplugin) { 1119 $o = ''; 1120 1121 if ($submissionplugin->view == assign_submission_plugin_submission::SUMMARY) { 1122 $showviewlink = false; 1123 $summary = $submissionplugin->plugin->view_summary($submissionplugin->submission, 1124 $showviewlink); 1125 1126 $classsuffix = $submissionplugin->plugin->get_subtype() . 1127 '_' . 1128 $submissionplugin->plugin->get_type() . 1129 '_' . 1130 $submissionplugin->submission->id; 1131 1132 $o .= $this->output->box_start('boxaligncenter plugincontentsummary summary_' . $classsuffix); 1133 1134 $link = ''; 1135 if ($showviewlink) { 1136 $previewstr = get_string('viewsubmission', 'assign'); 1137 $icon = $this->output->pix_icon('t/preview', $previewstr); 1138 1139 $expandstr = get_string('viewfull', 'assign'); 1140 $expandicon = $this->output->pix_icon('t/switch_plus', $expandstr); 1141 $options = array( 1142 'class' => 'expandsummaryicon expand_' . $classsuffix, 1143 'aria-label' => $expandstr, 1144 'role' => 'button', 1145 'aria-expanded' => 'false' 1146 ); 1147 $o .= html_writer::link('', $expandicon, $options); 1148 1149 $jsparams = array($submissionplugin->plugin->get_subtype(), 1150 $submissionplugin->plugin->get_type(), 1151 $submissionplugin->submission->id); 1152 1153 $this->page->requires->js_init_call('M.mod_assign.init_plugin_summary', $jsparams); 1154 1155 $action = 'viewplugin' . $submissionplugin->plugin->get_subtype(); 1156 $returnparams = http_build_query($submissionplugin->returnparams); 1157 $link .= '<noscript>'; 1158 $urlparams = array('id' => $submissionplugin->coursemoduleid, 1159 'sid'=>$submissionplugin->submission->id, 1160 'plugin'=>$submissionplugin->plugin->get_type(), 1161 'action'=>$action, 1162 'returnaction'=>$submissionplugin->returnaction, 1163 'returnparams'=>$returnparams); 1164 $url = new moodle_url('/mod/assign/view.php', $urlparams); 1165 $link .= $this->output->action_link($url, $icon); 1166 $link .= '</noscript>'; 1167 1168 $link .= $this->output->spacer(array('width'=>15)); 1169 } 1170 1171 $o .= $link . $summary; 1172 $o .= $this->output->box_end(); 1173 if ($showviewlink) { 1174 $o .= $this->output->box_start('boxaligncenter hidefull full_' . $classsuffix); 1175 $collapsestr = get_string('viewsummary', 'assign'); 1176 $options = array( 1177 'class' => 'expandsummaryicon contract_' . $classsuffix, 1178 'aria-label' => $collapsestr, 1179 'role' => 'button', 1180 'aria-expanded' => 'true' 1181 ); 1182 $collapseicon = $this->output->pix_icon('t/switch_minus', $collapsestr); 1183 $o .= html_writer::link('', $collapseicon, $options); 1184 1185 $o .= $submissionplugin->plugin->view($submissionplugin->submission); 1186 $o .= $this->output->box_end(); 1187 } 1188 } else if ($submissionplugin->view == assign_submission_plugin_submission::FULL) { 1189 $o .= $this->output->box_start('boxaligncenter submissionfull'); 1190 $o .= $submissionplugin->plugin->view($submissionplugin->submission); 1191 $o .= $this->output->box_end(); 1192 } 1193 1194 return $o; 1195 } 1196 1197 /** 1198 * Render the grading table. 1199 * 1200 * @param assign_grading_table $table 1201 * @return string 1202 */ 1203 public function render_assign_grading_table(assign_grading_table $table) { 1204 $o = ''; 1205 $o .= $this->output->box_start('boxaligncenter gradingtable'); 1206 1207 $this->page->requires->js_init_call('M.mod_assign.init_grading_table', array()); 1208 $this->page->requires->string_for_js('nousersselected', 'assign'); 1209 $this->page->requires->string_for_js('batchoperationconfirmgrantextension', 'assign'); 1210 $this->page->requires->string_for_js('batchoperationconfirmlock', 'assign'); 1211 $this->page->requires->string_for_js('batchoperationconfirmremovesubmission', 'assign'); 1212 $this->page->requires->string_for_js('batchoperationconfirmreverttodraft', 'assign'); 1213 $this->page->requires->string_for_js('batchoperationconfirmunlock', 'assign'); 1214 $this->page->requires->string_for_js('batchoperationconfirmaddattempt', 'assign'); 1215 $this->page->requires->string_for_js('batchoperationconfirmdownloadselected', 'assign'); 1216 $this->page->requires->string_for_js('batchoperationconfirmsetmarkingworkflowstate', 'assign'); 1217 $this->page->requires->string_for_js('batchoperationconfirmsetmarkingallocation', 'assign'); 1218 $this->page->requires->string_for_js('editaction', 'assign'); 1219 foreach ($table->plugingradingbatchoperations as $plugin => $operations) { 1220 foreach ($operations as $operation => $description) { 1221 $this->page->requires->string_for_js('batchoperationconfirm' . $operation, 1222 'assignfeedback_' . $plugin); 1223 } 1224 } 1225 $o .= $this->flexible_table($table, $table->get_rows_per_page(), true); 1226 $o .= $this->output->box_end(); 1227 1228 return $o; 1229 } 1230 1231 /** 1232 * Render a feedback plugin feedback 1233 * 1234 * @param assign_feedback_plugin_feedback $feedbackplugin 1235 * @return string 1236 */ 1237 public function render_assign_feedback_plugin_feedback(assign_feedback_plugin_feedback $feedbackplugin) { 1238 $o = ''; 1239 1240 if ($feedbackplugin->view == assign_feedback_plugin_feedback::SUMMARY) { 1241 $showviewlink = false; 1242 $summary = $feedbackplugin->plugin->view_summary($feedbackplugin->grade, $showviewlink); 1243 1244 $classsuffix = $feedbackplugin->plugin->get_subtype() . 1245 '_' . 1246 $feedbackplugin->plugin->get_type() . 1247 '_' . 1248 $feedbackplugin->grade->id; 1249 $o .= $this->output->box_start('boxaligncenter plugincontentsummary summary_' . $classsuffix); 1250 1251 $link = ''; 1252 if ($showviewlink) { 1253 $previewstr = get_string('viewfeedback', 'assign'); 1254 $icon = $this->output->pix_icon('t/preview', $previewstr); 1255 1256 $expandstr = get_string('viewfull', 'assign'); 1257 $expandicon = $this->output->pix_icon('t/switch_plus', $expandstr); 1258 $options = array( 1259 'class' => 'expandsummaryicon expand_' . $classsuffix, 1260 'aria-label' => $expandstr, 1261 'role' => 'button', 1262 'aria-expanded' => 'false' 1263 ); 1264 $o .= html_writer::link('', $expandicon, $options); 1265 1266 $jsparams = array($feedbackplugin->plugin->get_subtype(), 1267 $feedbackplugin->plugin->get_type(), 1268 $feedbackplugin->grade->id); 1269 $this->page->requires->js_init_call('M.mod_assign.init_plugin_summary', $jsparams); 1270 1271 $urlparams = array('id' => $feedbackplugin->coursemoduleid, 1272 'gid'=>$feedbackplugin->grade->id, 1273 'plugin'=>$feedbackplugin->plugin->get_type(), 1274 'action'=>'viewplugin' . $feedbackplugin->plugin->get_subtype(), 1275 'returnaction'=>$feedbackplugin->returnaction, 1276 'returnparams'=>http_build_query($feedbackplugin->returnparams)); 1277 $url = new moodle_url('/mod/assign/view.php', $urlparams); 1278 $link .= '<noscript>'; 1279 $link .= $this->output->action_link($url, $icon); 1280 $link .= '</noscript>'; 1281 1282 $link .= $this->output->spacer(array('width'=>15)); 1283 } 1284 1285 $o .= $link . $summary; 1286 $o .= $this->output->box_end(); 1287 if ($showviewlink) { 1288 $o .= $this->output->box_start('boxaligncenter hidefull full_' . $classsuffix); 1289 $collapsestr = get_string('viewsummary', 'assign'); 1290 $options = array( 1291 'class' => 'expandsummaryicon contract_' . $classsuffix, 1292 'aria-label' => $collapsestr, 1293 'role' => 'button', 1294 'aria-expanded' => 'true' 1295 ); 1296 $collapseicon = $this->output->pix_icon('t/switch_minus', $collapsestr); 1297 $o .= html_writer::link('', $collapseicon, $options); 1298 1299 $o .= $feedbackplugin->plugin->view($feedbackplugin->grade); 1300 $o .= $this->output->box_end(); 1301 } 1302 } else if ($feedbackplugin->view == assign_feedback_plugin_feedback::FULL) { 1303 $o .= $this->output->box_start('boxaligncenter feedbackfull'); 1304 $o .= $feedbackplugin->plugin->view($feedbackplugin->grade); 1305 $o .= $this->output->box_end(); 1306 } 1307 1308 return $o; 1309 } 1310 1311 /** 1312 * Render a course index summary 1313 * 1314 * @param assign_course_index_summary $indexsummary 1315 * @return string 1316 */ 1317 public function render_assign_course_index_summary(assign_course_index_summary $indexsummary) { 1318 $o = ''; 1319 1320 $strplural = get_string('modulenameplural', 'assign'); 1321 $strsectionname = $indexsummary->courseformatname; 1322 $strduedate = get_string('duedate', 'assign'); 1323 $strsubmission = get_string('submission', 'assign'); 1324 $strgrade = get_string('gradenoun'); 1325 1326 $table = new html_table(); 1327 if ($indexsummary->usesections) { 1328 $table->head = array ($strsectionname, $strplural, $strduedate, $strsubmission, $strgrade); 1329 $table->align = array ('left', 'left', 'center', 'right', 'right'); 1330 } else { 1331 $table->head = array ($strplural, $strduedate, $strsubmission, $strgrade); 1332 $table->align = array ('left', 'left', 'center', 'right'); 1333 } 1334 $table->data = array(); 1335 1336 $currentsection = ''; 1337 foreach ($indexsummary->assignments as $info) { 1338 $params = array('id' => $info['cmid']); 1339 $link = html_writer::link(new moodle_url('/mod/assign/view.php', $params), 1340 $info['cmname']); 1341 $due = $info['timedue'] ? userdate($info['timedue']) : '-'; 1342 1343 $printsection = ''; 1344 if ($indexsummary->usesections) { 1345 if ($info['sectionname'] !== $currentsection) { 1346 if ($info['sectionname']) { 1347 $printsection = $info['sectionname']; 1348 } 1349 if ($currentsection !== '') { 1350 $table->data[] = 'hr'; 1351 } 1352 $currentsection = $info['sectionname']; 1353 } 1354 } 1355 1356 if ($indexsummary->usesections) { 1357 $row = array($printsection, $link, $due, $info['submissioninfo'], $info['gradeinfo']); 1358 } else { 1359 $row = array($link, $due, $info['submissioninfo'], $info['gradeinfo']); 1360 } 1361 $table->data[] = $row; 1362 } 1363 1364 $o .= html_writer::table($table); 1365 1366 return $o; 1367 } 1368 1369 1370 1371 /** 1372 * Internal function - creates htmls structure suitable for YUI tree. 1373 * 1374 * @param assign_files $tree 1375 * @param array $dir 1376 * @return string 1377 */ 1378 protected function htmllize_tree(assign_files $tree, $dir) { 1379 global $CFG; 1380 $yuiconfig = array(); 1381 $yuiconfig['type'] = 'html'; 1382 1383 if (empty($dir['subdirs']) and empty($dir['files'])) { 1384 return ''; 1385 } 1386 1387 $result = '<ul>'; 1388 foreach ($dir['subdirs'] as $subdir) { 1389 $image = $this->output->pix_icon(file_folder_icon(), 1390 $subdir['dirname'], 1391 'moodle', 1392 array('class'=>'icon')); 1393 $result .= '<li yuiConfig=\'' . json_encode($yuiconfig) . '\'>' . 1394 '<div>' . $image . ' ' . s($subdir['dirname']) . '</div> ' . 1395 $this->htmllize_tree($tree, $subdir) . 1396 '</li>'; 1397 } 1398 1399 foreach ($dir['files'] as $file) { 1400 $filename = $file->get_filename(); 1401 if ($CFG->enableplagiarism) { 1402 require_once($CFG->libdir.'/plagiarismlib.php'); 1403 $plagiarismlinks = plagiarism_get_links(array('userid'=>$file->get_userid(), 1404 'file'=>$file, 1405 'cmid'=>$tree->cm->id, 1406 'course'=>$tree->course)); 1407 } else { 1408 $plagiarismlinks = ''; 1409 } 1410 $image = $this->output->pix_icon(file_file_icon($file), 1411 $filename, 1412 'moodle', 1413 array('class'=>'icon')); 1414 $result .= '<li yuiConfig=\'' . json_encode($yuiconfig) . '\'>' . 1415 '<div>' . 1416 '<div class="fileuploadsubmission">' . $image . ' ' . 1417 $file->fileurl . ' ' . 1418 $plagiarismlinks . ' ' . 1419 $file->portfoliobutton . ' ' . 1420 '</div>' . 1421 '<div class="fileuploadsubmissiontime">' . $file->timemodified . '</div>' . 1422 '</div>' . 1423 '</li>'; 1424 } 1425 1426 $result .= '</ul>'; 1427 1428 return $result; 1429 } 1430 1431 /** 1432 * Helper method dealing with the fact we can not just fetch the output of flexible_table 1433 * 1434 * @param flexible_table $table The table to render 1435 * @param int $rowsperpage How many assignments to render in a page 1436 * @param bool $displaylinks - Whether to render links in the table 1437 * (e.g. downloads would not enable this) 1438 * @return string HTML 1439 */ 1440 protected function flexible_table(flexible_table $table, $rowsperpage, $displaylinks) { 1441 1442 $o = ''; 1443 ob_start(); 1444 $table->out($rowsperpage, $displaylinks); 1445 $o = ob_get_contents(); 1446 ob_end_clean(); 1447 1448 return $o; 1449 } 1450 1451 /** 1452 * Helper method dealing with the fact we can not just fetch the output of moodleforms 1453 * 1454 * @param moodleform $mform 1455 * @return string HTML 1456 */ 1457 protected function moodleform(moodleform $mform) { 1458 1459 $o = ''; 1460 ob_start(); 1461 $mform->display(); 1462 $o = ob_get_contents(); 1463 ob_end_clean(); 1464 1465 return $o; 1466 } 1467 1468 /** 1469 * Defer to template.. 1470 * 1471 * @param grading_app $app - All the data to render the grading app. 1472 */ 1473 public function render_grading_app(grading_app $app) { 1474 $context = $app->export_for_template($this); 1475 return $this->render_from_template('mod_assign/grading_app', $context); 1476 } 1477 } 1478
title
Description
Body
title
Description
Body
title
Description
Body
title
Body