From 1cb6f330a31b9535ace1adb52b688a6182117f74 Mon Sep 17 00:00:00 2001 From: Matt Porritt Date: Wed, 6 Jan 2021 05:03:50 +0000 Subject: [PATCH 1/2] MDL-69696 mod_assign: Class refactoring - UI style change Assign view UI style change. Style submission status and grading summary tables to have matched visual styles. --- mod/assign/renderer.php | 2 ++ mod/assign/styles.css | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mod/assign/renderer.php b/mod/assign/renderer.php index f32e978ff64..950983a2df8 100644 --- a/mod/assign/renderer.php +++ b/mod/assign/renderer.php @@ -294,6 +294,7 @@ class mod_assign_renderer extends plugin_renderer_base { $o .= $this->output->heading(get_string('gradingsummary', 'assign'), 3); $o .= $this->output->box_start('boxaligncenter gradingsummarytable'); $t = new html_table(); + $t->attributes['class'] = 'generaltable table-bordered'; // Visibility Status. $cell1content = get_string('hiddenfromstudents'); @@ -654,6 +655,7 @@ class mod_assign_renderer extends plugin_renderer_base { $o .= $this->output->box_start('boxaligncenter submissionsummarytable'); $t = new html_table(); + $t->attributes['class'] = 'generaltable table-bordered'; $warningmsg = ''; if ($status->teamsubmissionenabled) { diff --git a/mod/assign/styles.css b/mod/assign/styles.css index 5be6098dfca..43bb6232d7b 100644 --- a/mod/assign/styles.css +++ b/mod/assign/styles.css @@ -11,7 +11,7 @@ .path-mod-assign div.usersummary, .path-mod-assign div.feedback, .path-mod-assign div.gradingsummary { - margin-bottom: 5em; + margin-bottom: 1.5em; } .path-mod-assign div.submissionstatus .generaltable, @@ -102,7 +102,6 @@ .path-mod-assign td.submissionnotgraded, .path-mod-assign div.submissionnotgraded { color: black; - background-color: #efefef; } .path-mod-assign td.latesubmission, @@ -277,8 +276,9 @@ } .path-mod-assign .submissionsummarytable .c0, +.path-mod-assign .gradingsummarytable .c0, .path-mod-assign .mod-assign-history-panel .c0 { - width: 150px; + width: 15em; } .path-mod-assign .gradingtable .moodle-actionmenu { From f5d9267a29ede3539576995696fe9651308e1b4c Mon Sep 17 00:00:00 2001 From: Matt Porritt Date: Wed, 6 Jan 2021 05:13:31 +0000 Subject: [PATCH 2/2] MDL-69696 mod_assign: Class refactoring - rendering Refactor rendering classes to be more PSR compliant. Move renderer to output class folder and initial splitting of classes in renderable.php into individual class files. To make it easier to refactor assign UI functionality in the future. --- mod/assign/classes/output/assign_header.php | 82 + .../output/assign_submission_status.php | 197 +++ mod/assign/classes/output/renderer.php | 1483 +++++++++++++++++ mod/assign/db/renamedclasses.php | 32 + mod/assign/feedback/file/importziplib.php | 2 + mod/assign/feedback/file/locallib.php | 2 + mod/assign/feedback/offline/locallib.php | 2 + mod/assign/locallib.php | 2 + mod/assign/renderable.php | 227 +-- mod/assign/renderer.php | 1461 +--------------- mod/assign/tests/locallib_test.php | 2 +- mod/assign/upgrade.txt | 3 + mod/assign/version.php | 2 +- 13 files changed, 1814 insertions(+), 1683 deletions(-) create mode 100644 mod/assign/classes/output/assign_header.php create mode 100644 mod/assign/classes/output/assign_submission_status.php create mode 100644 mod/assign/classes/output/renderer.php create mode 100644 mod/assign/db/renamedclasses.php diff --git a/mod/assign/classes/output/assign_header.php b/mod/assign/classes/output/assign_header.php new file mode 100644 index 00000000000..eece1de830a --- /dev/null +++ b/mod/assign/classes/output/assign_header.php @@ -0,0 +1,82 @@ +. + +/** + * This file contains the definition for the renderable assign header. + * + * @package mod_assign + * @copyright 2020 Matt Porritt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_assign\output; + +/** + * This file contains the definition for the renderable assign header. + * + * @package mod_assign + * @copyright 2012 NetSpot {@link http://www.netspot.com.au} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class assign_header implements \renderable { + /** @var \stdClass The assign record. */ + public $assign; + /** @var mixed \context|null the context record. */ + public $context; + /** @var bool $showintro Show or hide the intro. */ + public $showintro; + /** @var int coursemoduleid The course module id. */ + public $coursemoduleid; + /** @var string $subpage Optional subpage (extra level in the breadcrumbs). */ + public $subpage; + /** @var string $preface Optional preface (text to show before the heading). */ + public $preface; + /** @var string $postfix Optional postfix (text to show after the intro). */ + public $postfix; + /** @var \moodle_url|null $subpageurl link for the sub page */ + public $subpageurl; + + /** + * Constructor + * + * @param \stdClass $assign The assign database record. + * @param \context|null $context The course module context. + * @param bool $showintro Show or hide the intro. + * @param int $coursemoduleid The course module id. + * @param string $subpage An optional sub page in the navigation. + * @param string $preface An optional preface to show before the heading. + * @param string $postfix An optional postfix to show after the intro. + * @param \moodle_url|null $subpageurl An optional sub page URL link for the subpage. + */ + public function __construct( + \stdClass $assign, + $context, + $showintro, + $coursemoduleid, + $subpage = '', + $preface = '', + $postfix = '', + \moodle_url $subpageurl = null + ) { + $this->assign = $assign; + $this->context = $context; + $this->showintro = $showintro; + $this->coursemoduleid = $coursemoduleid; + $this->subpage = $subpage; + $this->preface = $preface; + $this->postfix = $postfix; + $this->subpageurl = $subpageurl; + } +} diff --git a/mod/assign/classes/output/assign_submission_status.php b/mod/assign/classes/output/assign_submission_status.php new file mode 100644 index 00000000000..13fb6bdafb4 --- /dev/null +++ b/mod/assign/classes/output/assign_submission_status.php @@ -0,0 +1,197 @@ +. + +/** + * This file contains the definition for the renderable assign submission status. + * + * @package mod_assign + * @copyright 2020 Matt Porritt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_assign\output; + +/** + * This file contains the definition for the renderable assign submission status. + * + * @package mod_assign + * @copyright 2012 NetSpot {@link http://www.netspot.com.au} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class assign_submission_status implements \renderable { + /** @var int STUDENT_VIEW */ + const STUDENT_VIEW = 10; + /** @var int GRADER_VIEW */ + const GRADER_VIEW = 20; + + /** @var int allowsubmissionsfromdate */ + public $allowsubmissionsfromdate = 0; + /** @var bool alwaysshowdescription */ + public $alwaysshowdescription = false; + /** @var mixed the submission info (may be null or an integer) */ + public $submission = null; + /** @var boolean teamsubmissionenabled - true or false */ + public $teamsubmissionenabled = false; + /** @var \stdClass teamsubmission the team submission info (may be null) */ + public $teamsubmission = null; + /** @var mixed submissiongroup the submission group info (may be null) */ + public $submissiongroup = null; + /** @var array submissiongroupmemberswhoneedtosubmit list of users who still need to submit */ + public $submissiongroupmemberswhoneedtosubmit = array(); + /** @var bool submissionsenabled */ + public $submissionsenabled = false; + /** @var bool locked */ + public $locked = false; + /** @var bool graded */ + public $graded = false; + /** @var int duedate */ + public $duedate = 0; + /** @var int cutoffdate */ + public $cutoffdate = 0; + /** @var array submissionplugins - the list of submission plugins */ + public $submissionplugins = array(); + /** @var string returnaction */ + public $returnaction = ''; + /** @var string returnparams */ + public $returnparams = array(); + /** @var int courseid */ + public $courseid = 0; + /** @var int coursemoduleid */ + public $coursemoduleid = 0; + /** @var int the view (STUDENT_VIEW OR GRADER_VIEW) */ + public $view = self::STUDENT_VIEW; + /** @var bool canviewfullnames */ + public $canviewfullnames = false; + /** @var bool canedit */ + public $canedit = false; + /** @var bool cansubmit */ + public $cansubmit = false; + /** @var int extensionduedate */ + public $extensionduedate = 0; + /** @var \context context */ + public $context = 0; + /** @var bool blindmarking - Should we hide student identities from graders? */ + public $blindmarking = false; + /** @var string gradingcontrollerpreview */ + public $gradingcontrollerpreview = ''; + /** @var string attemptreopenmethod */ + public $attemptreopenmethod = 'none'; + /** @var int maxattempts */ + public $maxattempts = -1; + /** @var string gradingstatus */ + public $gradingstatus = ''; + /** @var bool preventsubmissionnotingroup */ + public $preventsubmissionnotingroup = 0; + /** @var array usergroups */ + public $usergroups = array(); + + /** + * Constructor + * + * @param int $allowsubmissionsfromdate + * @param bool $alwaysshowdescription + * @param mixed $submission + * @param bool $teamsubmissionenabled + * @param \stdClass $teamsubmission + * @param mixed $submissiongroup + * @param array $submissiongroupmemberswhoneedtosubmit + * @param bool $submissionsenabled + * @param bool $locked + * @param bool $graded + * @param int $duedate + * @param int $cutoffdate + * @param array $submissionplugins + * @param string $returnaction + * @param array $returnparams + * @param int $coursemoduleid + * @param int $courseid + * @param string $view + * @param bool $canedit + * @param bool $cansubmit + * @param bool $canviewfullnames + * @param int $extensionduedate Any extension to the due date granted for this user. + * @param \context $context Any extension to the due date granted for this user. + * @param bool $blindmarking Should we hide student identities from graders? + * @param string $gradingcontrollerpreview + * @param string $attemptreopenmethod The method of reopening student attempts. + * @param int $maxattempts How many attempts can a student make? + * @param string $gradingstatus The submission status (ie. Graded, Not Released etc). + * @param bool $preventsubmissionnotingroup Prevent submission if user is not in a group. + * @param array $usergroups Array containing all groups the user is assigned to. + */ + public function __construct( + $allowsubmissionsfromdate, + $alwaysshowdescription, + $submission, + $teamsubmissionenabled, + $teamsubmission, + $submissiongroup, + $submissiongroupmemberswhoneedtosubmit, + $submissionsenabled, + $locked, + $graded, + $duedate, + $cutoffdate, + $submissionplugins, + $returnaction, + $returnparams, + $coursemoduleid, + $courseid, + $view, + $canedit, + $cansubmit, + $canviewfullnames, + $extensionduedate, + $context, + $blindmarking, + $gradingcontrollerpreview, + $attemptreopenmethod, + $maxattempts, + $gradingstatus, + $preventsubmissionnotingroup, + $usergroups + ) { + $this->allowsubmissionsfromdate = $allowsubmissionsfromdate; + $this->alwaysshowdescription = $alwaysshowdescription; + $this->submission = $submission; + $this->teamsubmissionenabled = $teamsubmissionenabled; + $this->teamsubmission = $teamsubmission; + $this->submissiongroup = $submissiongroup; + $this->submissiongroupmemberswhoneedtosubmit = $submissiongroupmemberswhoneedtosubmit; + $this->submissionsenabled = $submissionsenabled; + $this->locked = $locked; + $this->graded = $graded; + $this->duedate = $duedate; + $this->cutoffdate = $cutoffdate; + $this->submissionplugins = $submissionplugins; + $this->returnaction = $returnaction; + $this->returnparams = $returnparams; + $this->coursemoduleid = $coursemoduleid; + $this->courseid = $courseid; + $this->view = $view; + $this->canedit = $canedit; + $this->cansubmit = $cansubmit; + $this->canviewfullnames = $canviewfullnames; + $this->extensionduedate = $extensionduedate; + $this->context = $context; + $this->blindmarking = $blindmarking; + $this->gradingcontrollerpreview = $gradingcontrollerpreview; + $this->attemptreopenmethod = $attemptreopenmethod; + $this->maxattempts = $maxattempts; + $this->gradingstatus = $gradingstatus; + $this->preventsubmissionnotingroup = $preventsubmissionnotingroup; + $this->usergroups = $usergroups; + } +} diff --git a/mod/assign/classes/output/renderer.php b/mod/assign/classes/output/renderer.php new file mode 100644 index 00000000000..6fb3a41af7b --- /dev/null +++ b/mod/assign/classes/output/renderer.php @@ -0,0 +1,1483 @@ +. + +/** + * This file contains a renderer for the assignment class + * + * @package mod_assign + * @copyright 2012 NetSpot {@link http://www.netspot.com.au} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_assign\output; + +require_once($CFG->dirroot . '/mod/assign/locallib.php'); + +use \mod_assign\output\grading_app; + +/** + * A custom renderer class that extends the plugin_renderer_base and is used by the assign module. + * + * @package mod_assign + * @copyright 2012 NetSpot {@link http://www.netspot.com.au} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class renderer extends \plugin_renderer_base { + + /** + * Rendering assignment files + * + * @param \context $context + * @param int $userid + * @param string $filearea + * @param string $component + * @param stdClass $course + * @param stdClass $coursemodule + * @return string + */ + public function assign_files(\context $context, $userid, $filearea, $component, $course = null, $coursemodule = null) { + return $this->render(new \assign_files($context, $userid, $filearea, $component, $course, $coursemodule)); + } + + /** + * Rendering assignment files + * + * @param \assign_files $tree + * @return string + */ + public function render_assign_files(\assign_files $tree) { + $this->htmlid = \html_writer::random_id('assign_files_tree'); + $this->page->requires->js_init_call('M.mod_assign.init_tree', array(true, $this->htmlid)); + $html = '
'; + $html .= $this->htmllize_tree($tree, $tree->dir); + $html .= '
'; + + if ($tree->portfolioform) { + $html .= $tree->portfolioform; + } + return $html; + } + + /** + * Utility function to add a row of data to a table with 2 columns where the first column is the table's header. + * Modified the table param and does not return a value. + * + * @param \html_table $table The table to append the row of data to + * @param string $first The first column text + * @param string $second The second column text + * @param array $firstattributes The first column attributes (optional) + * @param array $secondattributes The second column attributes (optional) + * @return void + */ + private function add_table_row_tuple(\html_table $table, $first, $second, $firstattributes = [], + $secondattributes = []) { + $row = new \html_table_row(); + $cell1 = new \html_table_cell($first); + $cell1->header = true; + if (!empty($firstattributes)) { + $cell1->attributes = $firstattributes; + } + $cell2 = new \html_table_cell($second); + if (!empty($secondattributes)) { + $cell2->attributes = $secondattributes; + } + $row->cells = array($cell1, $cell2); + $table->data[] = $row; + } + + /** + * Render a grading message notification + * @param \assign_gradingmessage $result The result to render + * @return string + */ + public function render_assign_gradingmessage(\assign_gradingmessage $result) { + $urlparams = array('id' => $result->coursemoduleid, 'action'=>'grading'); + if (!empty($result->page)) { + $urlparams['page'] = $result->page; + } + $url = new \moodle_url('/mod/assign/view.php', $urlparams); + $classes = $result->gradingerror ? 'notifyproblem' : 'notifysuccess'; + + $o = ''; + $o .= $this->output->heading($result->heading, 4); + $o .= $this->output->notification($result->message, $classes); + $o .= $this->output->continue_button($url); + return $o; + } + + /** + * Render the generic form + * @param \assign_form $form The form to render + * @return string + */ + public function render_assign_form(\assign_form $form) { + $o = ''; + if ($form->jsinitfunction) { + $this->page->requires->js_init_call($form->jsinitfunction, array()); + } + $o .= $this->output->box_start('boxaligncenter ' . $form->classname); + $o .= $this->moodleform($form->form); + $o .= $this->output->box_end(); + return $o; + } + + /** + * Render the user summary + * + * @param \assign_user_summary $summary The user summary to render + * @return string + */ + public function render_assign_user_summary(\assign_user_summary $summary) { + $o = ''; + $supendedclass = ''; + $suspendedicon = ''; + + if (!$summary->user) { + return; + } + + if ($summary->suspendeduser) { + $supendedclass = ' usersuspended'; + $suspendedstring = get_string('userenrolmentsuspended', 'grades'); + $suspendedicon = ' ' . $this->pix_icon('i/enrolmentsuspended', $suspendedstring); + } + $o .= $this->output->container_start('usersummary'); + $o .= $this->output->box_start('boxaligncenter usersummarysection'.$supendedclass); + if ($summary->blindmarking) { + $o .= get_string('hiddenuser', 'assign') . $summary->uniqueidforuser.$suspendedicon; + } else { + $o .= $this->output->user_picture($summary->user); + $o .= $this->output->spacer(array('width'=>30)); + $urlparams = array('id' => $summary->user->id, 'course'=>$summary->courseid); + $url = new \moodle_url('/user/view.php', $urlparams); + $fullname = fullname($summary->user, $summary->viewfullnames); + $extrainfo = array(); + foreach ($summary->extrauserfields as $extrafield) { + $extrainfo[] = $summary->user->$extrafield; + } + if (count($extrainfo)) { + $fullname .= ' (' . implode(', ', $extrainfo) . ')'; + } + $fullname .= $suspendedicon; + $o .= $this->output->action_link($url, $fullname); + } + $o .= $this->output->box_end(); + $o .= $this->output->container_end(); + + return $o; + } + + /** + * Render the submit for grading page + * + * @param \assign_submit_for_grading_page $page + * @return string + */ + public function render_assign_submit_for_grading_page($page) { + $o = ''; + + $o .= $this->output->container_start('submitforgrading'); + $o .= $this->output->heading(get_string('confirmsubmissionheading', 'assign'), 3); + + $cancelurl = new \moodle_url('/mod/assign/view.php', array('id' => $page->coursemoduleid)); + if (count($page->notifications)) { + // At least one of the submission plugins is not ready for submission. + + $o .= $this->output->heading(get_string('submissionnotready', 'assign'), 4); + + foreach ($page->notifications as $notification) { + $o .= $this->output->notification($notification); + } + + $o .= $this->output->continue_button($cancelurl); + } else { + // All submission plugins ready - show the confirmation form. + $o .= $this->moodleform($page->confirmform); + } + $o .= $this->output->container_end(); + + return $o; + } + + /** + * Page is done - render the footer. + * + * @return void + */ + public function render_footer() { + return $this->output->footer(); + } + + /** + * Render the header. + * + * @param assign_header $header + * @return string + */ + public function render_assign_header(assign_header $header) { + global $USER; + + $o = ''; + + if ($header->subpage) { + $this->page->navbar->add($header->subpage, $header->subpageurl); + $args = ['contextname' => $header->context->get_context_name(false, true), 'subpage' => $header->subpage]; + $title = get_string('subpagetitle', 'assign', $args); + } else { + $title = $header->context->get_context_name(false, true); + } + $courseshortname = $header->context->get_course_context()->get_context_name(false, true); + $title = $courseshortname . ': ' . $title; + $heading = format_string($header->assign->name, false, array('context' => $header->context)); + + $this->page->set_title($title); + $this->page->set_heading($this->page->course->fullname); + + $o .= $this->output->header(); + $o .= $this->output->heading($heading); + + // Show the activity information output component. + $modinfo = get_fast_modinfo($header->assign->course); + $cm = $modinfo->get_cm($header->coursemoduleid); + $cmcompletion = \core_completion\cm_completion_details::get_instance($cm, $USER->id); + $activitydates = \core\activity_dates::get_dates_for_module($cm, $USER->id); + $o .= $this->output->activity_information($cm, $cmcompletion, $activitydates); + + if ($header->preface) { + $o .= $header->preface; + } + + if ($header->showintro) { + $o .= $this->output->box_start('generalbox boxaligncenter', 'intro'); + $o .= format_module_intro('assign', $header->assign, $header->coursemoduleid); + $o .= $header->postfix; + $o .= $this->output->box_end(); + } + + return $o; + } + + /** + * Render the header for an individual plugin. + * + * @param \assign_plugin_header $header + * @return string + */ + public function render_assign_plugin_header(\assign_plugin_header $header) { + $o = $header->plugin->view_header(); + return $o; + } + + /** + * Render a table containing the current status of the grading process. + * + * @param \assign_grading_summary $summary + * @return string + */ + public function render_assign_grading_summary(\assign_grading_summary $summary) { + // Create a table for the data. + $o = ''; + $o .= $this->output->container_start('gradingsummary'); + $o .= $this->output->heading(get_string('gradingsummary', 'assign'), 3); + $o .= $this->output->box_start('boxaligncenter gradingsummarytable'); + $t = new \html_table(); + $t->attributes['class'] = 'generaltable table-bordered'; + + // Visibility Status. + $cell1content = get_string('hiddenfromstudents'); + $cell2content = (!$summary->isvisible) ? get_string('yes') : get_string('no'); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + // Status. + if ($summary->teamsubmission) { + if ($summary->warnofungroupedusers === \assign_grading_summary::WARN_GROUPS_REQUIRED) { + $o .= $this->output->notification(get_string('ungroupedusers', 'assign')); + } else if ($summary->warnofungroupedusers === \assign_grading_summary::WARN_GROUPS_OPTIONAL) { + $o .= $this->output->notification(get_string('ungroupedusersoptional', 'assign')); + } + $cell1content = get_string('numberofteams', 'assign'); + } else { + $cell1content = get_string('numberofparticipants', 'assign'); + } + + $cell2content = $summary->participantcount; + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + // Drafts count and dont show drafts count when using offline assignment. + if ($summary->submissiondraftsenabled && $summary->submissionsenabled) { + $cell1content = get_string('numberofdraftsubmissions', 'assign'); + $cell2content = $summary->submissiondraftscount; + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + + // Submitted for grading. + if ($summary->submissionsenabled) { + $cell1content = get_string('numberofsubmittedassignments', 'assign'); + $cell2content = $summary->submissionssubmittedcount; + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + if (!$summary->teamsubmission) { + $cell1content = get_string('numberofsubmissionsneedgrading', 'assign'); + $cell2content = $summary->submissionsneedgradingcount; + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + } + + $time = time(); + if ($summary->duedate) { + // Time remaining. + $duedate = $summary->duedate; + $cell1content = get_string('timeremaining', 'assign'); + if ($summary->courserelativedatesmode) { + $cell2content = get_string('relativedatessubmissiontimeleft', 'mod_assign'); + } else { + if ($duedate - $time <= 0) { + $cell2content = get_string('assignmentisdue', 'assign'); + } else { + $cell2content = format_time($duedate - $time); + } + } + + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + if ($duedate < $time) { + $cell1content = get_string('latesubmissions', 'assign'); + $cutoffdate = $summary->cutoffdate; + if ($cutoffdate) { + if ($cutoffdate > $time) { + $cell2content = get_string('latesubmissionsaccepted', 'assign', userdate($summary->cutoffdate)); + } else { + $cell2content = get_string('nomoresubmissionsaccepted', 'assign'); + } + + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + } + + } + + // All done - write the table. + $o .= \html_writer::table($t); + $o .= $this->output->box_end(); + + // Link to the grading page. + $o .= \html_writer::start_tag('center'); + $o .= $this->output->container_start('submissionlinks'); + $urlparams = array('id' => $summary->coursemoduleid, 'action' => 'grading'); + $url = new \moodle_url('/mod/assign/view.php', $urlparams); + $o .= \html_writer::link($url, get_string('viewgrading', 'mod_assign'), + ['class' => 'btn btn-secondary']); + if ($summary->cangrade) { + $urlparams = array('id' => $summary->coursemoduleid, 'action' => 'grader'); + $url = new \moodle_url('/mod/assign/view.php', $urlparams); + $o .= \html_writer::link($url, get_string('gradeverb'), + ['class' => 'btn btn-primary ml-1']); + } + $o .= $this->output->container_end(); + + // Close the container and insert a spacer. + $o .= $this->output->container_end(); + $o .= \html_writer::end_tag('center'); + + return $o; + } + + /** + * Render a table containing all the current grades and feedback. + * + * @param \assign_feedback_status $status + * @return string + */ + public function render_assign_feedback_status(\assign_feedback_status $status) { + $o = ''; + + $o .= $this->output->container_start('feedback'); + $o .= $this->output->heading(get_string('feedback', 'assign'), 3); + $o .= $this->output->box_start('boxaligncenter feedbacktable'); + $t = new \html_table(); + + // Grade. + if (isset($status->gradefordisplay)) { + $cell1content = get_string('gradenoun'); + $cell2content = $status->gradefordisplay; + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + // Grade date. + $cell1content = get_string('gradedon', 'assign'); + $cell2content = userdate($status->gradeddate); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + + if ($status->grader) { + // Grader. + $cell1content = get_string('gradedby', 'assign'); + $cell2content = $this->output->user_picture($status->grader) . + $this->output->spacer(array('width' => 30)) . + fullname($status->grader, $status->canviewfullnames); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + + foreach ($status->feedbackplugins as $plugin) { + if ($plugin->is_enabled() && + $plugin->is_visible() && + $plugin->has_user_summary() && + !empty($status->grade) && + !$plugin->is_empty($status->grade)) { + + $displaymode = \assign_feedback_plugin_feedback::SUMMARY; + $pluginfeedback = new \assign_feedback_plugin_feedback($plugin, + $status->grade, + $displaymode, + $status->coursemoduleid, + $status->returnaction, + $status->returnparams); + $cell1content = $plugin->get_name(); + $cell2content = $this->render($pluginfeedback); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + } + + $o .= \html_writer::table($t); + $o .= $this->output->box_end(); + + $o .= $this->output->container_end(); + return $o; + } + + /** + * Render a compact view of the current status of the submission. + * + * @param \assign_submission_status_compact $status + * @return string + */ + public function render_assign_submission_status_compact(\assign_submission_status_compact $status) { + $o = ''; + $o .= $this->output->container_start('submissionstatustable'); + $o .= $this->output->heading(get_string('submission', 'assign'), 3); + $time = time(); + + if ($status->teamsubmissionenabled) { + $group = $status->submissiongroup; + if ($group) { + $team = format_string($group->name, false, $status->context); + } else if ($status->preventsubmissionnotingroup) { + if (count($status->usergroups) == 0) { + $team = '' . get_string('noteam', 'assign') . ''; + } else if (count($status->usergroups) > 1) { + $team = '' . get_string('multipleteams', 'assign') . ''; + } + } else { + $team = get_string('defaultteam', 'assign'); + } + $o .= $this->output->container(get_string('teamname', 'assign', $team), 'teamname'); + } + + if (!$status->teamsubmissionenabled) { + if ($status->submission && $status->submission->status != ASSIGN_SUBMISSION_STATUS_NEW) { + $statusstr = get_string('submissionstatus_' . $status->submission->status, 'assign'); + $o .= $this->output->container($statusstr, 'submissionstatus' . $status->submission->status); + } else { + if (!$status->submissionsenabled) { + $o .= $this->output->container(get_string('noonlinesubmissions', 'assign'), 'submissionstatus'); + } else { + $o .= $this->output->container(get_string('noattempt', 'assign'), 'submissionstatus'); + } + } + } else { + $group = $status->submissiongroup; + if (!$group && $status->preventsubmissionnotingroup) { + $o .= $this->output->container(get_string('nosubmission', 'assign'), 'submissionstatus'); + } else if ($status->teamsubmission && $status->teamsubmission->status != ASSIGN_SUBMISSION_STATUS_NEW) { + $teamstatus = $status->teamsubmission->status; + $submissionsummary = get_string('submissionstatus_' . $teamstatus, 'assign'); + $groupid = 0; + if ($status->submissiongroup) { + $groupid = $status->submissiongroup->id; + } + + $members = $status->submissiongroupmemberswhoneedtosubmit; + $userslist = array(); + foreach ($members as $member) { + $urlparams = array('id' => $member->id, 'course' => $status->courseid); + $url = new \moodle_url('/user/view.php', $urlparams); + if ($status->view == assign_submission_status::GRADER_VIEW && $status->blindmarking) { + $userslist[] = $member->alias; + } else { + $fullname = fullname($member, $status->canviewfullnames); + $userslist[] = $this->output->action_link($url, $fullname); + } + } + if (count($userslist) > 0) { + $userstr = join(', ', $userslist); + $formatteduserstr = get_string('userswhoneedtosubmit', 'assign', $userstr); + $submissionsummary .= $this->output->container($formatteduserstr); + } + $o .= $this->output->container($submissionsummary, 'submissionstatus' . $status->teamsubmission->status); + } else { + if (!$status->submissionsenabled) { + $o .= $this->output->container(get_string('noonlinesubmissions', 'assign'), 'submissionstatus'); + } else { + $o .= $this->output->container(get_string('nosubmission', 'assign'), 'submissionstatus'); + } + } + } + + // Is locked? + if ($status->locked) { + $o .= $this->output->container(get_string('submissionslocked', 'assign'), 'submissionlocked'); + } + + // Grading status. + $statusstr = ''; + $classname = 'gradingstatus'; + if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || + $status->gradingstatus == ASSIGN_GRADING_STATUS_NOT_GRADED) { + $statusstr = get_string($status->gradingstatus, 'assign'); + } else { + $gradingstatus = 'markingworkflowstate' . $status->gradingstatus; + $statusstr = get_string($gradingstatus, 'assign'); + } + if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || + $status->gradingstatus == ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) { + $classname = 'submissiongraded'; + } else { + $classname = 'submissionnotgraded'; + } + + $o .= $this->output->container($statusstr, $classname); + + $submission = $status->teamsubmission ? $status->teamsubmission : $status->submission; + $duedate = $status->duedate; + if ($duedate > 0) { + + if ($status->extensionduedate) { + // Extension date. + $duedate = $status->extensionduedate; + } + + // Time remaining. + $classname = 'timeremaining'; + if ($duedate - $time <= 0) { + if (!$submission || + $submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) { + if ($status->submissionsenabled) { + $remaining = get_string('overdue', 'assign', format_time($time - $duedate)); + $classname = 'overdue'; + } else { + $remaining = get_string('duedatereached', 'assign'); + } + } else { + if ($submission->timemodified > $duedate) { + $remaining = get_string('submittedlate', + 'assign', + format_time($submission->timemodified - $duedate)); + $classname = 'latesubmission'; + } else { + $remaining = get_string('submittedearly', + 'assign', + format_time($submission->timemodified - $duedate)); + $classname = 'earlysubmission'; + } + } + } else { + $remaining = get_string('paramtimeremaining', 'assign', format_time($duedate - $time)); + } + $o .= $this->output->container($remaining, $classname); + } + + // Show graders whether this submission is editable by students. + if ($status->view == assign_submission_status::GRADER_VIEW) { + if ($status->canedit) { + $o .= $this->output->container(get_string('submissioneditable', 'assign'), 'submissioneditable'); + } else { + $o .= $this->output->container(get_string('submissionnoteditable', 'assign'), 'submissionnoteditable'); + } + } + + // Grading criteria preview. + if (!empty($status->gradingcontrollerpreview)) { + $o .= $this->output->container($status->gradingcontrollerpreview, 'gradingmethodpreview'); + } + + if ($submission) { + + if (!$status->teamsubmission || $status->submissiongroup != false || !$status->preventsubmissionnotingroup) { + foreach ($status->submissionplugins as $plugin) { + $pluginshowsummary = !$plugin->is_empty($submission) || !$plugin->allow_submissions(); + if ($plugin->is_enabled() && + $plugin->is_visible() && + $plugin->has_user_summary() && + $pluginshowsummary + ) { + + $displaymode = \assign_submission_plugin_submission::SUMMARY; + $pluginsubmission = new \assign_submission_plugin_submission($plugin, + $submission, + $displaymode, + $status->coursemoduleid, + $status->returnaction, + $status->returnparams); + $plugincomponent = $plugin->get_subtype() . '_' . $plugin->get_type(); + $o .= $this->output->container($this->render($pluginsubmission), 'assignsubmission ' . $plugincomponent); + } + } + } + } + + $o .= $this->output->container_end(); + return $o; + } + + /** + * Render a table containing the current status of the submission. + * + * @param assign_submission_status $status + * @return string + */ + public function render_assign_submission_status(assign_submission_status $status) { + $o = ''; + $o .= $this->output->container_start('submissionstatustable'); + $o .= $this->output->heading(get_string('submissionstatusheading', 'assign'), 3); + $time = time(); + + $o .= $this->output->box_start('boxaligncenter submissionsummarytable'); + + $t = new \html_table(); + $t->attributes['class'] = 'generaltable table-bordered'; + + $warningmsg = ''; + if ($status->teamsubmissionenabled) { + $cell1content = get_string('submissionteam', 'assign'); + $group = $status->submissiongroup; + if ($group) { + $cell2content = format_string($group->name, false, $status->context); + } else if ($status->preventsubmissionnotingroup) { + if (count($status->usergroups) == 0) { + $notification = new \core\output\notification(get_string('noteam', 'assign'), 'error'); + $notification->set_show_closebutton(false); + $warningmsg = $this->output->notification(get_string('noteam_desc', 'assign'), 'error'); + } else if (count($status->usergroups) > 1) { + $notification = new \core\output\notification(get_string('multipleteams', 'assign'), 'error'); + $notification->set_show_closebutton(false); + $warningmsg = $this->output->notification(get_string('multipleteams_desc', 'assign'), 'error'); + } + $cell2content = $this->output->render($notification); + } else { + $cell2content = get_string('defaultteam', 'assign'); + } + + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + + if ($status->attemptreopenmethod != ASSIGN_ATTEMPT_REOPEN_METHOD_NONE) { + $currentattempt = 1; + if (!$status->teamsubmissionenabled) { + if ($status->submission) { + $currentattempt = $status->submission->attemptnumber + 1; + } + } else { + if ($status->teamsubmission) { + $currentattempt = $status->teamsubmission->attemptnumber + 1; + } + } + + $cell1content = get_string('attemptnumber', 'assign'); + $maxattempts = $status->maxattempts; + if ($maxattempts == ASSIGN_UNLIMITED_ATTEMPTS) { + $cell2content = get_string('currentattempt', 'assign', $currentattempt); + } else { + $cell2content = get_string('currentattemptof', 'assign', + array('attemptnumber' => $currentattempt, 'maxattempts' => $maxattempts)); + } + + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + + $cell1content = get_string('submissionstatus', 'assign'); + $cell2attributes = []; + if (!$status->teamsubmissionenabled) { + if ($status->submission && $status->submission->status != ASSIGN_SUBMISSION_STATUS_NEW) { + $cell2content = get_string('submissionstatus_' . $status->submission->status, 'assign'); + $cell2attributes = array('class' => 'submissionstatus' . $status->submission->status); + } else { + if (!$status->submissionsenabled) { + $cell2content = get_string('noonlinesubmissions', 'assign'); + } else { + $cell2content = get_string('noattempt', 'assign'); + } + } + } else { + $group = $status->submissiongroup; + if (!$group && $status->preventsubmissionnotingroup) { + $cell2content = get_string('nosubmission', 'assign'); + } else if ($status->teamsubmission && $status->teamsubmission->status != ASSIGN_SUBMISSION_STATUS_NEW) { + $teamstatus = $status->teamsubmission->status; + $cell2content = get_string('submissionstatus_' . $teamstatus, 'assign'); + + $members = $status->submissiongroupmemberswhoneedtosubmit; + $userslist = array(); + foreach ($members as $member) { + $urlparams = array('id' => $member->id, 'course'=>$status->courseid); + $url = new \moodle_url('/user/view.php', $urlparams); + if ($status->view == assign_submission_status::GRADER_VIEW && $status->blindmarking) { + $userslist[] = $member->alias; + } else { + $fullname = fullname($member, $status->canviewfullnames); + $userslist[] = $this->output->action_link($url, $fullname); + } + } + if (count($userslist) > 0) { + $userstr = join(', ', $userslist); + $formatteduserstr = get_string('userswhoneedtosubmit', 'assign', $userstr); + $cell2content .= $this->output->container($formatteduserstr); + } + + $cell2attributes = array('class' => 'submissionstatus' . $status->teamsubmission->status); + } else { + if (!$status->submissionsenabled) { + $cell2content = get_string('noonlinesubmissions', 'assign'); + } else { + $cell2content = get_string('nosubmission', 'assign'); + } + } + } + + $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); + + // Is locked? + if ($status->locked) { + $cell1content = ''; + $cell2content = get_string('submissionslocked', 'assign'); + $cell2attributes = array('class' => 'submissionlocked'); + $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); + } + + // Grading status. + $cell1content = get_string('gradingstatus', 'assign'); + if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || + $status->gradingstatus == ASSIGN_GRADING_STATUS_NOT_GRADED) { + $cell2content = get_string($status->gradingstatus, 'assign'); + } else { + $gradingstatus = 'markingworkflowstate' . $status->gradingstatus; + $cell2content = get_string($gradingstatus, 'assign'); + } + if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || + $status->gradingstatus == ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) { + $cell2attributes = array('class' => 'submissiongraded'); + } else { + $cell2attributes = array('class' => 'submissionnotgraded'); + } + $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); + + $submission = $status->teamsubmission ? $status->teamsubmission : $status->submission; + $duedate = $status->duedate; + if ($duedate > 0) { + if ($status->view == assign_submission_status::GRADER_VIEW) { + if ($status->cutoffdate) { + // Cut off date. + $cell1content = get_string('cutoffdate', 'assign'); + $cell2content = userdate($status->cutoffdate); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + } + + if ($status->extensionduedate) { + // Extension date. + $cell1content = get_string('extensionduedate', 'assign'); + $cell2content = userdate($status->extensionduedate); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + $duedate = $status->extensionduedate; + } + + // Time remaining. + $cell1content = get_string('timeremaining', 'assign'); + $cell2attributes = []; + if ($duedate - $time <= 0) { + if (!$submission || + $submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) { + if ($status->submissionsenabled) { + $cell2content = get_string('overdue', 'assign', format_time($time - $duedate)); + $cell2attributes = array('class' => 'overdue'); + } else { + $cell2content = get_string('duedatereached', 'assign'); + } + } else { + if ($submission->timemodified > $duedate) { + $cell2content = get_string('submittedlate', + 'assign', + format_time($submission->timemodified - $duedate)); + $cell2attributes = array('class' => 'latesubmission'); + } else { + $cell2content = get_string('submittedearly', + 'assign', + format_time($submission->timemodified - $duedate)); + $cell2attributes = array('class' => 'earlysubmission'); + } + } + } else { + $cell2content = format_time($duedate - $time); + } + $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); + } + + // Show graders whether this submission is editable by students. + if ($status->view == assign_submission_status::GRADER_VIEW) { + $cell1content = get_string('editingstatus', 'assign'); + if ($status->canedit) { + $cell2content = get_string('submissioneditable', 'assign'); + $cell2attributes = array('class' => 'submissioneditable'); + } else { + $cell2content = get_string('submissionnoteditable', 'assign'); + $cell2attributes = array('class' => 'submissionnoteditable'); + } + $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); + } + + // Grading criteria preview. + if (!empty($status->gradingcontrollerpreview)) { + $cell1content = get_string('gradingmethodpreview', 'assign'); + $cell2content = $status->gradingcontrollerpreview; + $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); + } + + // Last modified. + if ($submission) { + $cell1content = get_string('timemodified', 'assign'); + + if ($submission->status != ASSIGN_SUBMISSION_STATUS_NEW) { + $cell2content = userdate($submission->timemodified); + } else { + $cell2content = "-"; + } + + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + if (!$status->teamsubmission || $status->submissiongroup != false || !$status->preventsubmissionnotingroup) { + foreach ($status->submissionplugins as $plugin) { + $pluginshowsummary = !$plugin->is_empty($submission) || !$plugin->allow_submissions(); + if ($plugin->is_enabled() && + $plugin->is_visible() && + $plugin->has_user_summary() && + $pluginshowsummary + ) { + + $cell1content = $plugin->get_name(); + $displaymode = \assign_submission_plugin_submission::SUMMARY; + $pluginsubmission = new \assign_submission_plugin_submission($plugin, + $submission, + $displaymode, + $status->coursemoduleid, + $status->returnaction, + $status->returnparams); + $cell2content = $this->render($pluginsubmission); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + } + } + } + + $o .= $warningmsg; + $o .= \html_writer::table($t); + $o .= $this->output->box_end(); + + // Links. + if ($status->view == assign_submission_status::STUDENT_VIEW) { + if ($status->canedit) { + if (!$submission || $submission->status == ASSIGN_SUBMISSION_STATUS_NEW) { + $o .= $this->output->box_start('generalbox submissionaction'); + $urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission'); + $o .= $this->output->single_button(new \moodle_url('/mod/assign/view.php', $urlparams), + get_string('addsubmission', 'assign'), 'get'); + $o .= $this->output->box_start('boxaligncenter submithelp'); + $o .= get_string('addsubmission_help', 'assign'); + $o .= $this->output->box_end(); + $o .= $this->output->box_end(); + } else if ($submission->status == ASSIGN_SUBMISSION_STATUS_REOPENED) { + $o .= $this->output->box_start('generalbox submissionaction'); + $urlparams = array('id' => $status->coursemoduleid, + 'action' => 'editprevioussubmission', + 'sesskey'=>sesskey()); + $o .= $this->output->single_button(new \moodle_url('/mod/assign/view.php', $urlparams), + get_string('addnewattemptfromprevious', 'assign'), 'get'); + $o .= $this->output->box_start('boxaligncenter submithelp'); + $o .= get_string('addnewattemptfromprevious_help', 'assign'); + $o .= $this->output->box_end(); + $o .= $this->output->box_end(); + $o .= $this->output->box_start('generalbox submissionaction'); + $urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission'); + $o .= $this->output->single_button(new \moodle_url('/mod/assign/view.php', $urlparams), + get_string('addnewattempt', 'assign'), 'get'); + $o .= $this->output->box_start('boxaligncenter submithelp'); + $o .= get_string('addnewattempt_help', 'assign'); + $o .= $this->output->box_end(); + $o .= $this->output->box_end(); + } else { + $o .= $this->output->box_start('generalbox submissionaction'); + $urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission'); + $o .= $this->output->single_button(new \moodle_url('/mod/assign/view.php', $urlparams), + get_string('editsubmission', 'assign'), 'get'); + $urlparams = array('id' => $status->coursemoduleid, 'action' => 'removesubmissionconfirm'); + $o .= $this->output->single_button(new \moodle_url('/mod/assign/view.php', $urlparams), + get_string('removesubmission', 'assign'), 'get'); + $o .= $this->output->box_start('boxaligncenter submithelp'); + $o .= get_string('editsubmission_help', 'assign'); + $o .= $this->output->box_end(); + $o .= $this->output->box_end(); + } + } + + if ($status->cansubmit) { + $urlparams = array('id' => $status->coursemoduleid, 'action'=>'submit'); + $o .= $this->output->box_start('generalbox submissionaction'); + $o .= $this->output->single_button(new \moodle_url('/mod/assign/view.php', $urlparams), + get_string('submitassignment', 'assign'), 'get'); + $o .= $this->output->box_start('boxaligncenter submithelp'); + $o .= get_string('submitassignment_help', 'assign'); + $o .= $this->output->box_end(); + $o .= $this->output->box_end(); + } + } + + $o .= $this->output->container_end(); + return $o; + } + + /** + * Output the attempt history chooser for this assignment + * + * @param \assign_attempt_history_chooser $history + * @return string + */ + public function render_assign_attempt_history_chooser(\assign_attempt_history_chooser $history) { + $o = ''; + + $context = $history->export_for_template($this); + $o .= $this->render_from_template('mod_assign/attempt_history_chooser', $context); + + return $o; + } + + /** + * Output the attempt history for this assignment + * + * @param \assign_attempt_history $history + * @return string + */ + public function render_assign_attempt_history(\assign_attempt_history $history) { + $o = ''; + + // Don't show the last one because it is the current submission. + array_pop($history->submissions); + + // Show newest to oldest. + $history->submissions = array_reverse($history->submissions); + + if (empty($history->submissions)) { + return ''; + } + + $containerid = 'attempthistory' . uniqid(); + $o .= $this->output->heading(get_string('attempthistory', 'assign'), 3); + $o .= $this->box_start('attempthistory', $containerid); + + foreach ($history->submissions as $i => $submission) { + $grade = null; + foreach ($history->grades as $onegrade) { + if ($onegrade->attemptnumber == $submission->attemptnumber) { + if ($onegrade->grade != ASSIGN_GRADE_NOT_SET) { + $grade = $onegrade; + } + break; + } + } + + if ($submission) { + $submissionsummary = userdate($submission->timemodified); + } else { + $submissionsummary = get_string('nosubmission', 'assign'); + } + + $attemptsummaryparams = array('attemptnumber'=>$submission->attemptnumber+1, + 'submissionsummary'=>$submissionsummary); + $o .= $this->heading(get_string('attemptheading', 'assign', $attemptsummaryparams), 4); + + $t = new \html_table(); + + if ($submission) { + $cell1content = get_string('submissionstatus', 'assign'); + $cell2content = get_string('submissionstatus_' . $submission->status, 'assign'); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + foreach ($history->submissionplugins as $plugin) { + $pluginshowsummary = !$plugin->is_empty($submission) || !$plugin->allow_submissions(); + if ($plugin->is_enabled() && + $plugin->is_visible() && + $plugin->has_user_summary() && + $pluginshowsummary) { + + $cell1content = $plugin->get_name(); + $pluginsubmission = new \assign_submission_plugin_submission($plugin, + $submission, + \assign_submission_plugin_submission::SUMMARY, + $history->coursemoduleid, + $history->returnaction, + $history->returnparams); + $cell2content = $this->render($pluginsubmission); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + } + } + + if ($grade) { + // Heading 'feedback'. + $title = get_string('feedback', 'assign', $i); + $title .= $this->output->spacer(array('width'=>10)); + if ($history->cangrade) { + // Edit previous feedback. + $returnparams = http_build_query($history->returnparams); + $urlparams = array('id' => $history->coursemoduleid, + 'rownum'=>$history->rownum, + 'useridlistid'=>$history->useridlistid, + 'attemptnumber'=>$grade->attemptnumber, + 'action'=>'grade', + 'returnaction'=>$history->returnaction, + 'returnparams'=>$returnparams); + $url = new \moodle_url('/mod/assign/view.php', $urlparams); + $icon = new \pix_icon('gradefeedback', + get_string('editattemptfeedback', 'assign', $grade->attemptnumber+1), + 'mod_assign'); + $title .= $this->output->action_icon($url, $icon); + } + $cell = new \html_table_cell($title); + $cell->attributes['class'] = 'feedbacktitle'; + $cell->colspan = 2; + $t->data[] = new \html_table_row(array($cell)); + + // Grade. + $cell1content = get_string('gradenoun'); + $cell2content = $grade->gradefordisplay; + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + // Graded on. + $cell1content = get_string('gradedon', 'assign'); + $cell2content = userdate($grade->timemodified); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + // Graded by set to a real user. Not set can be empty or -1. + if (!empty($grade->grader) && is_object($grade->grader)) { + $cell1content = get_string('gradedby', 'assign'); + $cell2content = $this->output->user_picture($grade->grader) . + $this->output->spacer(array('width' => 30)) . fullname($grade->grader); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + + // Feedback from plugins. + foreach ($history->feedbackplugins as $plugin) { + if ($plugin->is_enabled() && + $plugin->is_visible() && + $plugin->has_user_summary() && + !$plugin->is_empty($grade)) { + + $pluginfeedback = new \assign_feedback_plugin_feedback( + $plugin, $grade, \assign_feedback_plugin_feedback::SUMMARY, $history->coursemoduleid, + $history->returnaction, $history->returnparams + ); + + $cell1content = $plugin->get_name(); + $cell2content = $this->render($pluginfeedback); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + + } + + } + + $o .= \html_writer::table($t); + } + $o .= $this->box_end(); + + $this->page->requires->yui_module('moodle-mod_assign-history', 'Y.one("#' . $containerid . '").history'); + + return $o; + } + + /** + * Render a submission plugin submission + * + * @param \assign_submission_plugin_submission $submissionplugin + * @return string + */ + public function render_assign_submission_plugin_submission(\assign_submission_plugin_submission $submissionplugin) { + $o = ''; + + if ($submissionplugin->view == \assign_submission_plugin_submission::SUMMARY) { + $showviewlink = false; + $summary = $submissionplugin->plugin->view_summary($submissionplugin->submission, + $showviewlink); + + $classsuffix = $submissionplugin->plugin->get_subtype() . + '_' . + $submissionplugin->plugin->get_type() . + '_' . + $submissionplugin->submission->id; + + $o .= $this->output->box_start('boxaligncenter plugincontentsummary summary_' . $classsuffix); + + $link = ''; + if ($showviewlink) { + $previewstr = get_string('viewsubmission', 'assign'); + $icon = $this->output->pix_icon('t/preview', $previewstr); + + $expandstr = get_string('viewfull', 'assign'); + $expandicon = $this->output->pix_icon('t/switch_plus', $expandstr); + $options = array( + 'class' => 'expandsummaryicon expand_' . $classsuffix, + 'aria-label' => $expandstr, + 'role' => 'button', + 'aria-expanded' => 'false' + ); + $o .= \html_writer::link('', $expandicon, $options); + + $jsparams = array($submissionplugin->plugin->get_subtype(), + $submissionplugin->plugin->get_type(), + $submissionplugin->submission->id); + + $this->page->requires->js_init_call('M.mod_assign.init_plugin_summary', $jsparams); + + $action = 'viewplugin' . $submissionplugin->plugin->get_subtype(); + $returnparams = http_build_query($submissionplugin->returnparams); + $link .= ''; + + $link .= $this->output->spacer(array('width'=>15)); + } + + $o .= $link . $summary; + $o .= $this->output->box_end(); + if ($showviewlink) { + $o .= $this->output->box_start('boxaligncenter hidefull full_' . $classsuffix); + $collapsestr = get_string('viewsummary', 'assign'); + $options = array( + 'class' => 'expandsummaryicon contract_' . $classsuffix, + 'aria-label' => $collapsestr, + 'role' => 'button', + 'aria-expanded' => 'true' + ); + $collapseicon = $this->output->pix_icon('t/switch_minus', $collapsestr); + $o .= \html_writer::link('', $collapseicon, $options); + + $o .= $submissionplugin->plugin->view($submissionplugin->submission); + $o .= $this->output->box_end(); + } + } else if ($submissionplugin->view == \assign_submission_plugin_submission::FULL) { + $o .= $this->output->box_start('boxaligncenter submissionfull'); + $o .= $submissionplugin->plugin->view($submissionplugin->submission); + $o .= $this->output->box_end(); + } + + return $o; + } + + /** + * Render the grading table. + * + * @param \assign_grading_table $table + * @return string + */ + public function render_assign_grading_table(\assign_grading_table $table) { + $o = ''; + $o .= $this->output->box_start('boxaligncenter gradingtable'); + + $this->page->requires->js_init_call('M.mod_assign.init_grading_table', array()); + $this->page->requires->string_for_js('nousersselected', 'assign'); + $this->page->requires->string_for_js('batchoperationconfirmgrantextension', 'assign'); + $this->page->requires->string_for_js('batchoperationconfirmlock', 'assign'); + $this->page->requires->string_for_js('batchoperationconfirmremovesubmission', 'assign'); + $this->page->requires->string_for_js('batchoperationconfirmreverttodraft', 'assign'); + $this->page->requires->string_for_js('batchoperationconfirmunlock', 'assign'); + $this->page->requires->string_for_js('batchoperationconfirmaddattempt', 'assign'); + $this->page->requires->string_for_js('batchoperationconfirmdownloadselected', 'assign'); + $this->page->requires->string_for_js('batchoperationconfirmsetmarkingworkflowstate', 'assign'); + $this->page->requires->string_for_js('batchoperationconfirmsetmarkingallocation', 'assign'); + $this->page->requires->string_for_js('editaction', 'assign'); + foreach ($table->plugingradingbatchoperations as $plugin => $operations) { + foreach ($operations as $operation => $description) { + $this->page->requires->string_for_js('batchoperationconfirm' . $operation, + 'assignfeedback_' . $plugin); + } + } + $o .= $this->flexible_table($table, $table->get_rows_per_page(), true); + $o .= $this->output->box_end(); + + return $o; + } + + /** + * Render a feedback plugin feedback + * + * @param \assign_feedback_plugin_feedback $feedbackplugin + * @return string + */ + public function render_assign_feedback_plugin_feedback(\assign_feedback_plugin_feedback $feedbackplugin) { + $o = ''; + + if ($feedbackplugin->view == \assign_feedback_plugin_feedback::SUMMARY) { + $showviewlink = false; + $summary = $feedbackplugin->plugin->view_summary($feedbackplugin->grade, $showviewlink); + + $classsuffix = $feedbackplugin->plugin->get_subtype() . + '_' . + $feedbackplugin->plugin->get_type() . + '_' . + $feedbackplugin->grade->id; + $o .= $this->output->box_start('boxaligncenter plugincontentsummary summary_' . $classsuffix); + + $link = ''; + if ($showviewlink) { + $previewstr = get_string('viewfeedback', 'assign'); + $icon = $this->output->pix_icon('t/preview', $previewstr); + + $expandstr = get_string('viewfull', 'assign'); + $expandicon = $this->output->pix_icon('t/switch_plus', $expandstr); + $options = array( + 'class' => 'expandsummaryicon expand_' . $classsuffix, + 'aria-label' => $expandstr, + 'role' => 'button', + 'aria-expanded' => 'false' + ); + $o .= \html_writer::link('', $expandicon, $options); + + $jsparams = array($feedbackplugin->plugin->get_subtype(), + $feedbackplugin->plugin->get_type(), + $feedbackplugin->grade->id); + $this->page->requires->js_init_call('M.mod_assign.init_plugin_summary', $jsparams); + + $urlparams = array('id' => $feedbackplugin->coursemoduleid, + 'gid'=>$feedbackplugin->grade->id, + 'plugin'=>$feedbackplugin->plugin->get_type(), + 'action'=>'viewplugin' . $feedbackplugin->plugin->get_subtype(), + 'returnaction'=>$feedbackplugin->returnaction, + 'returnparams'=>http_build_query($feedbackplugin->returnparams)); + $url = new \moodle_url('/mod/assign/view.php', $urlparams); + $link .= ''; + + $link .= $this->output->spacer(array('width'=>15)); + } + + $o .= $link . $summary; + $o .= $this->output->box_end(); + if ($showviewlink) { + $o .= $this->output->box_start('boxaligncenter hidefull full_' . $classsuffix); + $collapsestr = get_string('viewsummary', 'assign'); + $options = array( + 'class' => 'expandsummaryicon contract_' . $classsuffix, + 'aria-label' => $collapsestr, + 'role' => 'button', + 'aria-expanded' => 'true' + ); + $collapseicon = $this->output->pix_icon('t/switch_minus', $collapsestr); + $o .= \html_writer::link('', $collapseicon, $options); + + $o .= $feedbackplugin->plugin->view($feedbackplugin->grade); + $o .= $this->output->box_end(); + } + } else if ($feedbackplugin->view == \assign_feedback_plugin_feedback::FULL) { + $o .= $this->output->box_start('boxaligncenter feedbackfull'); + $o .= $feedbackplugin->plugin->view($feedbackplugin->grade); + $o .= $this->output->box_end(); + } + + return $o; + } + + /** + * Render a course index summary + * + * @param \assign_course_index_summary $indexsummary + * @return string + */ + public function render_assign_course_index_summary(\assign_course_index_summary $indexsummary) { + $o = ''; + + $strplural = get_string('modulenameplural', 'assign'); + $strsectionname = $indexsummary->courseformatname; + $strduedate = get_string('duedate', 'assign'); + $strsubmission = get_string('submission', 'assign'); + $strgrade = get_string('gradenoun'); + + $table = new \html_table(); + if ($indexsummary->usesections) { + $table->head = array ($strsectionname, $strplural, $strduedate, $strsubmission, $strgrade); + $table->align = array ('left', 'left', 'center', 'right', 'right'); + } else { + $table->head = array ($strplural, $strduedate, $strsubmission, $strgrade); + $table->align = array ('left', 'left', 'center', 'right'); + } + $table->data = array(); + + $currentsection = ''; + foreach ($indexsummary->assignments as $info) { + $params = array('id' => $info['cmid']); + $link = \html_writer::link(new \moodle_url('/mod/assign/view.php', $params), + $info['cmname']); + $due = $info['timedue'] ? userdate($info['timedue']) : '-'; + + $printsection = ''; + if ($indexsummary->usesections) { + if ($info['sectionname'] !== $currentsection) { + if ($info['sectionname']) { + $printsection = $info['sectionname']; + } + if ($currentsection !== '') { + $table->data[] = 'hr'; + } + $currentsection = $info['sectionname']; + } + } + + if ($indexsummary->usesections) { + $row = array($printsection, $link, $due, $info['submissioninfo'], $info['gradeinfo']); + } else { + $row = array($link, $due, $info['submissioninfo'], $info['gradeinfo']); + } + $table->data[] = $row; + } + + $o .= \html_writer::table($table); + + return $o; + } + + + + /** + * Internal function - creates htmls structure suitable for YUI tree. + * + * @param \assign_files $tree + * @param array $dir + * @return string + */ + protected function htmllize_tree(\assign_files $tree, $dir) { + global $CFG; + $yuiconfig = array(); + $yuiconfig['type'] = 'html'; + + if (empty($dir['subdirs']) and empty($dir['files'])) { + return ''; + } + + $result = '
    '; + foreach ($dir['subdirs'] as $subdir) { + $image = $this->output->pix_icon(file_folder_icon(), + $subdir['dirname'], + 'moodle', + array('class'=>'icon')); + $result .= '
  • ' . + '
    ' . $image . ' ' . s($subdir['dirname']) . '
    ' . + $this->htmllize_tree($tree, $subdir) . + '
  • '; + } + + foreach ($dir['files'] as $file) { + $filename = $file->get_filename(); + if ($CFG->enableplagiarism) { + require_once($CFG->libdir.'/plagiarismlib.php'); + $plagiarismlinks = plagiarism_get_links(array('userid'=>$file->get_userid(), + 'file'=>$file, + 'cmid'=>$tree->cm->id, + 'course'=>$tree->course)); + } else { + $plagiarismlinks = ''; + } + $image = $this->output->pix_icon(file_file_icon($file), + $filename, + 'moodle', + array('class'=>'icon')); + $result .= '
  • ' . + '
    ' . + '
    ' . $image . ' ' . + $file->fileurl . ' ' . + $plagiarismlinks . ' ' . + $file->portfoliobutton . ' ' . + '
    ' . + '
    ' . $file->timemodified . '
    ' . + '
    ' . + '
  • '; + } + + $result .= '
'; + + return $result; + } + + /** + * Helper method dealing with the fact we can not just fetch the output of flexible_table + * + * @param \flexible_table $table The table to render + * @param int $rowsperpage How many assignments to render in a page + * @param bool $displaylinks - Whether to render links in the table + * (e.g. downloads would not enable this) + * @return string HTML + */ + protected function flexible_table(\flexible_table $table, $rowsperpage, $displaylinks) { + + $o = ''; + ob_start(); + $table->out($rowsperpage, $displaylinks); + $o = ob_get_contents(); + ob_end_clean(); + + return $o; + } + + /** + * Helper method dealing with the fact we can not just fetch the output of moodleforms + * + * @param \moodleform $mform + * @return string HTML + */ + protected function moodleform(\moodleform $mform) { + + $o = ''; + ob_start(); + $mform->display(); + $o = ob_get_contents(); + ob_end_clean(); + + return $o; + } + + /** + * Defer to template. + * + * @param grading_app $app - All the data to render the grading app. + */ + public function render_grading_app(grading_app $app) { + $context = $app->export_for_template($this); + return $this->render_from_template('mod_assign/grading_app', $context); + } + +} diff --git a/mod/assign/db/renamedclasses.php b/mod/assign/db/renamedclasses.php new file mode 100644 index 00000000000..dca2b289f9f --- /dev/null +++ b/mod/assign/db/renamedclasses.php @@ -0,0 +1,32 @@ +. + +/** + * This file contains mappings for classes that have been renamed. + * + * @package mod_assign + * @copyright 2021 Catalyst IT Australia Pty Ltd + * @author Cameron Ball + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$renamedclasses = [ + // Since Moodle 4.0. + 'assign_header' => 'mod_assign\output\assign_header', + 'assign_submission_status' => 'mod_assign\output\assign_submission_status' +]; diff --git a/mod/assign/feedback/file/importziplib.php b/mod/assign/feedback/file/importziplib.php index 3cbe9f79c1e..3b61b15e119 100644 --- a/mod/assign/feedback/file/importziplib.php +++ b/mod/assign/feedback/file/importziplib.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die(); +use mod_assign\output\assign_header; + /** * library class for importing feedback files from a zip * diff --git a/mod/assign/feedback/file/locallib.php b/mod/assign/feedback/file/locallib.php index dd65b23903d..30c2821116b 100644 --- a/mod/assign/feedback/file/locallib.php +++ b/mod/assign/feedback/file/locallib.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die(); +use \mod_assign\output\assign_header; + // File areas for file feedback assignment. define('ASSIGNFEEDBACK_FILE_FILEAREA', 'feedback_files'); define('ASSIGNFEEDBACK_FILE_BATCH_FILEAREA', 'feedback_files_batch'); diff --git a/mod/assign/feedback/offline/locallib.php b/mod/assign/feedback/offline/locallib.php index efbf3b34d98..c93246147ee 100644 --- a/mod/assign/feedback/offline/locallib.php +++ b/mod/assign/feedback/offline/locallib.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die(); +use \mod_assign\output\assign_header; + require_once($CFG->dirroot.'/grade/grading/lib.php'); /** diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index 05c71bcbe5a..81807ca172b 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -92,6 +92,8 @@ require_once($CFG->dirroot . '/mod/assign/gradingtable.php'); require_once($CFG->libdir . '/portfolio/caller.php'); use \mod_assign\output\grading_app; +use \mod_assign\output\assign_header; +use \mod_assign\output\assign_submission_status; /** * Standard base class for mod_assign (assignment types). diff --git a/mod/assign/renderable.php b/mod/assign/renderable.php index 295fc3c93f0..836686c0fd8 100644 --- a/mod/assign/renderable.php +++ b/mod/assign/renderable.php @@ -22,6 +22,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use \mod_assign\output\assign_submission_status; + defined('MOODLE_INTERNAL') || die(); /** @@ -271,7 +273,7 @@ class assign_submission_plugin_submission implements renderable { */ class assign_feedback_status implements renderable { - /** @var stding $gradefordisplay the student grade rendered into a format suitable for display */ + /** @var string $gradefordisplay the student grade rendered into a format suitable for display */ public $gradefordisplay = ''; /** @var mixed the graded date (may be null) */ public $gradeddate = 0; @@ -323,176 +325,6 @@ class assign_feedback_status implements renderable { } } -/** - * Renderable submission status - * @package mod_assign - * @copyright 2012 NetSpot {@link http://www.netspot.com.au} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class assign_submission_status implements renderable { - /** @var int STUDENT_VIEW */ - const STUDENT_VIEW = 10; - /** @var int GRADER_VIEW */ - const GRADER_VIEW = 20; - - /** @var int allowsubmissionsfromdate */ - public $allowsubmissionsfromdate = 0; - /** @var bool alwaysshowdescription */ - public $alwaysshowdescription = false; - /** @var stdClass the submission info (may be null) */ - public $submission = null; - /** @var boolean teamsubmissionenabled - true or false */ - public $teamsubmissionenabled = false; - /** @var stdClass teamsubmission the team submission info (may be null) */ - public $teamsubmission = null; - /** @var stdClass submissiongroup the submission group info (may be null) */ - public $submissiongroup = null; - /** @var array submissiongroupmemberswhoneedtosubmit list of users who still need to submit */ - public $submissiongroupmemberswhoneedtosubmit = array(); - /** @var bool submissionsenabled */ - public $submissionsenabled = false; - /** @var bool locked */ - public $locked = false; - /** @var bool graded */ - public $graded = false; - /** @var int duedate */ - public $duedate = 0; - /** @var int cutoffdate */ - public $cutoffdate = 0; - /** @var array submissionplugins - the list of submission plugins */ - public $submissionplugins = array(); - /** @var string returnaction */ - public $returnaction = ''; - /** @var string returnparams */ - public $returnparams = array(); - /** @var int courseid */ - public $courseid = 0; - /** @var int coursemoduleid */ - public $coursemoduleid = 0; - /** @var int the view (STUDENT_VIEW OR GRADER_VIEW) */ - public $view = self::STUDENT_VIEW; - /** @var bool canviewfullnames */ - public $canviewfullnames = false; - /** @var bool canedit */ - public $canedit = false; - /** @var bool cansubmit */ - public $cansubmit = false; - /** @var int extensionduedate */ - public $extensionduedate = 0; - /** @var context context */ - public $context = 0; - /** @var bool blindmarking - Should we hide student identities from graders? */ - public $blindmarking = false; - /** @var string gradingcontrollerpreview */ - public $gradingcontrollerpreview = ''; - /** @var string attemptreopenmethod */ - public $attemptreopenmethod = 'none'; - /** @var int maxattempts */ - public $maxattempts = -1; - /** @var string gradingstatus */ - public $gradingstatus = ''; - /** @var bool preventsubmissionnotingroup */ - public $preventsubmissionnotingroup = 0; - /** @var array usergroups */ - public $usergroups = array(); - - - /** - * Constructor - * - * @param int $allowsubmissionsfromdate - * @param bool $alwaysshowdescription - * @param stdClass $submission - * @param bool $teamsubmissionenabled - * @param stdClass $teamsubmission - * @param int $submissiongroup - * @param array $submissiongroupmemberswhoneedtosubmit - * @param bool $submissionsenabled - * @param bool $locked - * @param bool $graded - * @param int $duedate - * @param int $cutoffdate - * @param array $submissionplugins - * @param string $returnaction - * @param array $returnparams - * @param int $coursemoduleid - * @param int $courseid - * @param string $view - * @param bool $canedit - * @param bool $cansubmit - * @param bool $canviewfullnames - * @param int $extensionduedate - Any extension to the due date granted for this user - * @param context $context - Any extension to the due date granted for this user - * @param bool $blindmarking - Should we hide student identities from graders? - * @param string $gradingcontrollerpreview - * @param string $attemptreopenmethod - The method of reopening student attempts. - * @param int $maxattempts - How many attempts can a student make? - * @param string $gradingstatus - The submission status (ie. Graded, Not Released etc). - * @param bool $preventsubmissionnotingroup - Prevent submission if user is not in a group - * @param array $usergroups - Array containing all groups the user is assigned to - */ - public function __construct($allowsubmissionsfromdate, - $alwaysshowdescription, - $submission, - $teamsubmissionenabled, - $teamsubmission, - $submissiongroup, - $submissiongroupmemberswhoneedtosubmit, - $submissionsenabled, - $locked, - $graded, - $duedate, - $cutoffdate, - $submissionplugins, - $returnaction, - $returnparams, - $coursemoduleid, - $courseid, - $view, - $canedit, - $cansubmit, - $canviewfullnames, - $extensionduedate, - $context, - $blindmarking, - $gradingcontrollerpreview, - $attemptreopenmethod, - $maxattempts, - $gradingstatus, - $preventsubmissionnotingroup, - $usergroups) { - $this->allowsubmissionsfromdate = $allowsubmissionsfromdate; - $this->alwaysshowdescription = $alwaysshowdescription; - $this->submission = $submission; - $this->teamsubmissionenabled = $teamsubmissionenabled; - $this->teamsubmission = $teamsubmission; - $this->submissiongroup = $submissiongroup; - $this->submissiongroupmemberswhoneedtosubmit = $submissiongroupmemberswhoneedtosubmit; - $this->submissionsenabled = $submissionsenabled; - $this->locked = $locked; - $this->graded = $graded; - $this->duedate = $duedate; - $this->cutoffdate = $cutoffdate; - $this->submissionplugins = $submissionplugins; - $this->returnaction = $returnaction; - $this->returnparams = $returnparams; - $this->coursemoduleid = $coursemoduleid; - $this->courseid = $courseid; - $this->view = $view; - $this->canedit = $canedit; - $this->cansubmit = $cansubmit; - $this->canviewfullnames = $canviewfullnames; - $this->extensionduedate = $extensionduedate; - $this->context = $context; - $this->blindmarking = $blindmarking; - $this->gradingcontrollerpreview = $gradingcontrollerpreview; - $this->attemptreopenmethod = $attemptreopenmethod; - $this->maxattempts = $maxattempts; - $this->gradingstatus = $gradingstatus; - $this->preventsubmissionnotingroup = $preventsubmissionnotingroup; - $this->usergroups = $usergroups; - } -} /** * Renderable submission status * @package mod_assign @@ -650,59 +482,6 @@ class assign_attempt_history_chooser implements renderable, templatable { } } -/** - * Renderable header - * @package mod_assign - * @copyright 2012 NetSpot {@link http://www.netspot.com.au} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class assign_header implements renderable { - /** @var stdClass the assign record */ - public $assign = null; - /** @var mixed context|null the context record */ - public $context = null; - /** @var bool $showintro - show or hide the intro */ - public $showintro = false; - /** @var int coursemoduleid - The course module id */ - public $coursemoduleid = 0; - /** @var string $subpage optional subpage (extra level in the breadcrumbs) */ - public $subpage = ''; - /** @var string $preface optional preface (text to show before the heading) */ - public $preface = ''; - /** @var string $postfix optional postfix (text to show after the intro) */ - public $postfix = ''; - /** @var moodle_url $subpageurl link for the subpage */ - public $subpageurl = null; - - /** - * Constructor - * - * @param stdClass $assign - the assign database record - * @param mixed $context context|null the course module context - * @param bool $showintro - show or hide the intro - * @param int $coursemoduleid - the course module id - * @param string $subpage - an optional sub page in the navigation - * @param string $preface - an optional preface to show before the heading - */ - public function __construct(stdClass $assign, - $context, - $showintro, - $coursemoduleid, - $subpage='', - $preface='', - $postfix='', - moodle_url $subpageurl = null) { - $this->assign = $assign; - $this->context = $context; - $this->showintro = $showintro; - $this->coursemoduleid = $coursemoduleid; - $this->subpage = $subpage; - $this->preface = $preface; - $this->postfix = $postfix; - $this->subpageurl = $subpageurl; - } -} - /** * Renderable header related to an individual subplugin * @package mod_assign diff --git a/mod/assign/renderer.php b/mod/assign/renderer.php index 950983a2df8..aac1178a403 100644 --- a/mod/assign/renderer.php +++ b/mod/assign/renderer.php @@ -15,8 +15,10 @@ // along with Moodle. If not, see . /** - * This file contains a renderer for the assignment class + * Legacy file to avoid exceptions when scripts require it. + * Please use classes from mod/assign/classes/output instead. * + * @deprecated since Moodle 4.0 - please do not include this file anymore. * @package mod_assign * @copyright 2012 NetSpot {@link http://www.netspot.com.au} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later @@ -24,1459 +26,4 @@ defined('MOODLE_INTERNAL') || die(); -require_once($CFG->dirroot . '/mod/assign/locallib.php'); - -use \mod_assign\output\grading_app; - -/** - * A custom renderer class that extends the plugin_renderer_base and is used by the assign module. - * - * @package mod_assign - * @copyright 2012 NetSpot {@link http://www.netspot.com.au} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class mod_assign_renderer extends plugin_renderer_base { - - /** - * Rendering assignment files - * - * @param context $context - * @param int $userid - * @param string $filearea - * @param string $component - * @param stdClass $course - * @param stdClass $coursemodule - * @return string - */ - public function assign_files(context $context, $userid, $filearea, $component, $course = null, $coursemodule = null) { - return $this->render(new assign_files($context, $userid, $filearea, $component, $course, $coursemodule)); - } - - /** - * Rendering assignment files - * - * @param assign_files $tree - * @return string - */ - public function render_assign_files(assign_files $tree) { - $this->htmlid = html_writer::random_id('assign_files_tree'); - $this->page->requires->js_init_call('M.mod_assign.init_tree', array(true, $this->htmlid)); - $html = '
'; - $html .= $this->htmllize_tree($tree, $tree->dir); - $html .= '
'; - - if ($tree->portfolioform) { - $html .= $tree->portfolioform; - } - return $html; - } - - /** - * Utility function to add a row of data to a table with 2 columns where the first column is the table's header. - * Modified the table param and does not return a value. - * - * @param html_table $table The table to append the row of data to - * @param string $first The first column text - * @param string $second The second column text - * @param array $firstattributes The first column attributes (optional) - * @param array $secondattributes The second column attributes (optional) - * @return void - */ - private function add_table_row_tuple(html_table $table, $first, $second, $firstattributes = [], - $secondattributes = []) { - $row = new html_table_row(); - $cell1 = new html_table_cell($first); - $cell1->header = true; - if (!empty($firstattributes)) { - $cell1->attributes = $firstattributes; - } - $cell2 = new html_table_cell($second); - if (!empty($secondattributes)) { - $cell2->attributes = $secondattributes; - } - $row->cells = array($cell1, $cell2); - $table->data[] = $row; - } - - /** - * Render a grading message notification - * @param assign_gradingmessage $result The result to render - * @return string - */ - public function render_assign_gradingmessage(assign_gradingmessage $result) { - $urlparams = array('id' => $result->coursemoduleid, 'action'=>'grading'); - if (!empty($result->page)) { - $urlparams['page'] = $result->page; - } - $url = new moodle_url('/mod/assign/view.php', $urlparams); - $classes = $result->gradingerror ? 'notifyproblem' : 'notifysuccess'; - - $o = ''; - $o .= $this->output->heading($result->heading, 4); - $o .= $this->output->notification($result->message, $classes); - $o .= $this->output->continue_button($url); - return $o; - } - - /** - * Render the generic form - * @param assign_form $form The form to render - * @return string - */ - public function render_assign_form(assign_form $form) { - $o = ''; - if ($form->jsinitfunction) { - $this->page->requires->js_init_call($form->jsinitfunction, array()); - } - $o .= $this->output->box_start('boxaligncenter ' . $form->classname); - $o .= $this->moodleform($form->form); - $o .= $this->output->box_end(); - return $o; - } - - /** - * Render the user summary - * - * @param assign_user_summary $summary The user summary to render - * @return string - */ - public function render_assign_user_summary(assign_user_summary $summary) { - $o = ''; - $supendedclass = ''; - $suspendedicon = ''; - - if (!$summary->user) { - return; - } - - if ($summary->suspendeduser) { - $supendedclass = ' usersuspended'; - $suspendedstring = get_string('userenrolmentsuspended', 'grades'); - $suspendedicon = ' ' . $this->pix_icon('i/enrolmentsuspended', $suspendedstring); - } - $o .= $this->output->container_start('usersummary'); - $o .= $this->output->box_start('boxaligncenter usersummarysection'.$supendedclass); - if ($summary->blindmarking) { - $o .= get_string('hiddenuser', 'assign') . $summary->uniqueidforuser.$suspendedicon; - } else { - $o .= $this->output->user_picture($summary->user); - $o .= $this->output->spacer(array('width'=>30)); - $urlparams = array('id' => $summary->user->id, 'course'=>$summary->courseid); - $url = new moodle_url('/user/view.php', $urlparams); - $fullname = fullname($summary->user, $summary->viewfullnames); - $extrainfo = array(); - foreach ($summary->extrauserfields as $extrafield) { - $extrainfo[] = $summary->user->$extrafield; - } - if (count($extrainfo)) { - $fullname .= ' (' . implode(', ', $extrainfo) . ')'; - } - $fullname .= $suspendedicon; - $o .= $this->output->action_link($url, $fullname); - } - $o .= $this->output->box_end(); - $o .= $this->output->container_end(); - - return $o; - } - - /** - * Render the submit for grading page - * - * @param assign_submit_for_grading_page $page - * @return string - */ - public function render_assign_submit_for_grading_page($page) { - $o = ''; - - $o .= $this->output->container_start('submitforgrading'); - $o .= $this->output->heading(get_string('confirmsubmissionheading', 'assign'), 3); - - $cancelurl = new moodle_url('/mod/assign/view.php', array('id' => $page->coursemoduleid)); - if (count($page->notifications)) { - // At least one of the submission plugins is not ready for submission. - - $o .= $this->output->heading(get_string('submissionnotready', 'assign'), 4); - - foreach ($page->notifications as $notification) { - $o .= $this->output->notification($notification); - } - - $o .= $this->output->continue_button($cancelurl); - } else { - // All submission plugins ready - show the confirmation form. - $o .= $this->moodleform($page->confirmform); - } - $o .= $this->output->container_end(); - - return $o; - } - - /** - * Page is done - render the footer. - * - * @return void - */ - public function render_footer() { - return $this->output->footer(); - } - - /** - * Render the header. - * - * @param assign_header $header - * @return string - */ - public function render_assign_header(assign_header $header) { - global $USER; - - $o = ''; - - if ($header->subpage) { - $this->page->navbar->add($header->subpage, $header->subpageurl); - $args = ['contextname' => $header->context->get_context_name(false, true), 'subpage' => $header->subpage]; - $title = get_string('subpagetitle', 'assign', $args); - } else { - $title = $header->context->get_context_name(false, true); - } - $courseshortname = $header->context->get_course_context()->get_context_name(false, true); - $title = $courseshortname . ': ' . $title; - $heading = format_string($header->assign->name, false, array('context' => $header->context)); - - $this->page->set_title($title); - $this->page->set_heading($this->page->course->fullname); - - $o .= $this->output->header(); - $o .= $this->output->heading($heading); - - // Show the activity information output component. - $modinfo = get_fast_modinfo($header->assign->course); - $cm = $modinfo->get_cm($header->coursemoduleid); - $cmcompletion = \core_completion\cm_completion_details::get_instance($cm, $USER->id); - $activitydates = \core\activity_dates::get_dates_for_module($cm, $USER->id); - $o .= $this->output->activity_information($cm, $cmcompletion, $activitydates); - - if ($header->preface) { - $o .= $header->preface; - } - - if ($header->showintro) { - $o .= $this->output->box_start('generalbox boxaligncenter', 'intro'); - $o .= format_module_intro('assign', $header->assign, $header->coursemoduleid); - $o .= $header->postfix; - $o .= $this->output->box_end(); - } - - return $o; - } - - /** - * Render the header for an individual plugin. - * - * @param assign_plugin_header $header - * @return string - */ - public function render_assign_plugin_header(assign_plugin_header $header) { - $o = $header->plugin->view_header(); - return $o; - } - - /** - * Render a table containing the current status of the grading process. - * - * @param assign_grading_summary $summary - * @return string - */ - public function render_assign_grading_summary(assign_grading_summary $summary) { - // Create a table for the data. - $o = ''; - $o .= $this->output->container_start('gradingsummary'); - $o .= $this->output->heading(get_string('gradingsummary', 'assign'), 3); - $o .= $this->output->box_start('boxaligncenter gradingsummarytable'); - $t = new html_table(); - $t->attributes['class'] = 'generaltable table-bordered'; - - // Visibility Status. - $cell1content = get_string('hiddenfromstudents'); - $cell2content = (!$summary->isvisible) ? get_string('yes') : get_string('no'); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - - // Status. - if ($summary->teamsubmission) { - if ($summary->warnofungroupedusers === assign_grading_summary::WARN_GROUPS_REQUIRED) { - $o .= $this->output->notification(get_string('ungroupedusers', 'assign')); - } else if ($summary->warnofungroupedusers === assign_grading_summary::WARN_GROUPS_OPTIONAL) { - $o .= $this->output->notification(get_string('ungroupedusersoptional', 'assign')); - } - $cell1content = get_string('numberofteams', 'assign'); - } else { - $cell1content = get_string('numberofparticipants', 'assign'); - } - - $cell2content = $summary->participantcount; - $this->add_table_row_tuple($t, $cell1content, $cell2content); - - // Drafts count and dont show drafts count when using offline assignment. - if ($summary->submissiondraftsenabled && $summary->submissionsenabled) { - $cell1content = get_string('numberofdraftsubmissions', 'assign'); - $cell2content = $summary->submissiondraftscount; - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - - // Submitted for grading. - if ($summary->submissionsenabled) { - $cell1content = get_string('numberofsubmittedassignments', 'assign'); - $cell2content = $summary->submissionssubmittedcount; - $this->add_table_row_tuple($t, $cell1content, $cell2content); - - if (!$summary->teamsubmission) { - $cell1content = get_string('numberofsubmissionsneedgrading', 'assign'); - $cell2content = $summary->submissionsneedgradingcount; - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - } - - $time = time(); - if ($summary->duedate) { - // Time remaining. - $duedate = $summary->duedate; - $cell1content = get_string('timeremaining', 'assign'); - if ($summary->courserelativedatesmode) { - $cell2content = get_string('relativedatessubmissiontimeleft', 'mod_assign'); - } else { - if ($duedate - $time <= 0) { - $cell2content = get_string('assignmentisdue', 'assign'); - } else { - $cell2content = format_time($duedate - $time); - } - } - - $this->add_table_row_tuple($t, $cell1content, $cell2content); - - if ($duedate < $time) { - $cell1content = get_string('latesubmissions', 'assign'); - $cutoffdate = $summary->cutoffdate; - if ($cutoffdate) { - if ($cutoffdate > $time) { - $cell2content = get_string('latesubmissionsaccepted', 'assign', userdate($summary->cutoffdate)); - } else { - $cell2content = get_string('nomoresubmissionsaccepted', 'assign'); - } - - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - } - - } - - // All done - write the table. - $o .= html_writer::table($t); - $o .= $this->output->box_end(); - - // Link to the grading page. - $o .= html_writer::start_tag('center'); - $o .= $this->output->container_start('submissionlinks'); - $urlparams = array('id' => $summary->coursemoduleid, 'action' => 'grading'); - $url = new moodle_url('/mod/assign/view.php', $urlparams); - $o .= html_writer::link($url, get_string('viewgrading', 'mod_assign'), - ['class' => 'btn btn-secondary']); - if ($summary->cangrade) { - $urlparams = array('id' => $summary->coursemoduleid, 'action' => 'grader'); - $url = new moodle_url('/mod/assign/view.php', $urlparams); - $o .= html_writer::link($url, get_string('gradeverb'), - ['class' => 'btn btn-primary ml-1']); - } - $o .= $this->output->container_end(); - - // Close the container and insert a spacer. - $o .= $this->output->container_end(); - $o .= html_writer::end_tag('center'); - - return $o; - } - - /** - * Render a table containing all the current grades and feedback. - * - * @param assign_feedback_status $status - * @return string - */ - public function render_assign_feedback_status(assign_feedback_status $status) { - $o = ''; - - $o .= $this->output->container_start('feedback'); - $o .= $this->output->heading(get_string('feedback', 'assign'), 3); - $o .= $this->output->box_start('boxaligncenter feedbacktable'); - $t = new html_table(); - - // Grade. - if (isset($status->gradefordisplay)) { - $cell1content = get_string('gradenoun'); - $cell2content = $status->gradefordisplay; - $this->add_table_row_tuple($t, $cell1content, $cell2content); - - // Grade date. - $cell1content = get_string('gradedon', 'assign'); - $cell2content = userdate($status->gradeddate); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - - if ($status->grader) { - // Grader. - $cell1content = get_string('gradedby', 'assign'); - $cell2content = $this->output->user_picture($status->grader) . - $this->output->spacer(array('width' => 30)) . - fullname($status->grader, $status->canviewfullnames); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - - foreach ($status->feedbackplugins as $plugin) { - if ($plugin->is_enabled() && - $plugin->is_visible() && - $plugin->has_user_summary() && - !empty($status->grade) && - !$plugin->is_empty($status->grade)) { - - $displaymode = assign_feedback_plugin_feedback::SUMMARY; - $pluginfeedback = new assign_feedback_plugin_feedback($plugin, - $status->grade, - $displaymode, - $status->coursemoduleid, - $status->returnaction, - $status->returnparams); - $cell1content = $plugin->get_name(); - $cell2content = $this->render($pluginfeedback); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - } - - $o .= html_writer::table($t); - $o .= $this->output->box_end(); - - $o .= $this->output->container_end(); - return $o; - } - - /** - * Render a compact view of the current status of the submission. - * - * @param assign_submission_status_compact $status - * @return string - */ - public function render_assign_submission_status_compact(assign_submission_status_compact $status) { - $o = ''; - $o .= $this->output->container_start('submissionstatustable'); - $o .= $this->output->heading(get_string('submission', 'assign'), 3); - $time = time(); - - if ($status->teamsubmissionenabled) { - $group = $status->submissiongroup; - if ($group) { - $team = format_string($group->name, false, $status->context); - } else if ($status->preventsubmissionnotingroup) { - if (count($status->usergroups) == 0) { - $team = '' . get_string('noteam', 'assign') . ''; - } else if (count($status->usergroups) > 1) { - $team = '' . get_string('multipleteams', 'assign') . ''; - } - } else { - $team = get_string('defaultteam', 'assign'); - } - $o .= $this->output->container(get_string('teamname', 'assign', $team), 'teamname'); - } - - if (!$status->teamsubmissionenabled) { - if ($status->submission && $status->submission->status != ASSIGN_SUBMISSION_STATUS_NEW) { - $statusstr = get_string('submissionstatus_' . $status->submission->status, 'assign'); - $o .= $this->output->container($statusstr, 'submissionstatus' . $status->submission->status); - } else { - if (!$status->submissionsenabled) { - $o .= $this->output->container(get_string('noonlinesubmissions', 'assign'), 'submissionstatus'); - } else { - $o .= $this->output->container(get_string('noattempt', 'assign'), 'submissionstatus'); - } - } - } else { - $group = $status->submissiongroup; - if (!$group && $status->preventsubmissionnotingroup) { - $o .= $this->output->container(get_string('nosubmission', 'assign'), 'submissionstatus'); - } else if ($status->teamsubmission && $status->teamsubmission->status != ASSIGN_SUBMISSION_STATUS_NEW) { - $teamstatus = $status->teamsubmission->status; - $submissionsummary = get_string('submissionstatus_' . $teamstatus, 'assign'); - $groupid = 0; - if ($status->submissiongroup) { - $groupid = $status->submissiongroup->id; - } - - $members = $status->submissiongroupmemberswhoneedtosubmit; - $userslist = array(); - foreach ($members as $member) { - $urlparams = array('id' => $member->id, 'course' => $status->courseid); - $url = new moodle_url('/user/view.php', $urlparams); - if ($status->view == assign_submission_status::GRADER_VIEW && $status->blindmarking) { - $userslist[] = $member->alias; - } else { - $fullname = fullname($member, $status->canviewfullnames); - $userslist[] = $this->output->action_link($url, $fullname); - } - } - if (count($userslist) > 0) { - $userstr = join(', ', $userslist); - $formatteduserstr = get_string('userswhoneedtosubmit', 'assign', $userstr); - $submissionsummary .= $this->output->container($formatteduserstr); - } - $o .= $this->output->container($submissionsummary, 'submissionstatus' . $status->teamsubmission->status); - } else { - if (!$status->submissionsenabled) { - $o .= $this->output->container(get_string('noonlinesubmissions', 'assign'), 'submissionstatus'); - } else { - $o .= $this->output->container(get_string('nosubmission', 'assign'), 'submissionstatus'); - } - } - } - - // Is locked? - if ($status->locked) { - $o .= $this->output->container(get_string('submissionslocked', 'assign'), 'submissionlocked'); - } - - // Grading status. - $statusstr = ''; - $classname = 'gradingstatus'; - if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || - $status->gradingstatus == ASSIGN_GRADING_STATUS_NOT_GRADED) { - $statusstr = get_string($status->gradingstatus, 'assign'); - } else { - $gradingstatus = 'markingworkflowstate' . $status->gradingstatus; - $statusstr = get_string($gradingstatus, 'assign'); - } - if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || - $status->gradingstatus == ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) { - $classname = 'submissiongraded'; - } else { - $classname = 'submissionnotgraded'; - } - $o .= $this->output->container($statusstr, $classname); - - $submission = $status->teamsubmission ? $status->teamsubmission : $status->submission; - $duedate = $status->duedate; - if ($duedate > 0) { - - if ($status->extensionduedate) { - // Extension date. - $duedate = $status->extensionduedate; - } - - // Time remaining. - $classname = 'timeremaining'; - if ($duedate - $time <= 0) { - if (!$submission || - $submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) { - if ($status->submissionsenabled) { - $remaining = get_string('overdue', 'assign', format_time($time - $duedate)); - $classname = 'overdue'; - } else { - $remaining = get_string('duedatereached', 'assign'); - } - } else { - if ($submission->timemodified > $duedate) { - $remaining = get_string('submittedlate', - 'assign', - format_time($submission->timemodified - $duedate)); - $classname = 'latesubmission'; - } else { - $remaining = get_string('submittedearly', - 'assign', - format_time($submission->timemodified - $duedate)); - $classname = 'earlysubmission'; - } - } - } else { - $remaining = get_string('paramtimeremaining', 'assign', format_time($duedate - $time)); - } - $o .= $this->output->container($remaining, $classname); - } - - // Show graders whether this submission is editable by students. - if ($status->view == assign_submission_status::GRADER_VIEW) { - if ($status->canedit) { - $o .= $this->output->container(get_string('submissioneditable', 'assign'), 'submissioneditable'); - } else { - $o .= $this->output->container(get_string('submissionnoteditable', 'assign'), 'submissionnoteditable'); - } - } - - // Grading criteria preview. - if (!empty($status->gradingcontrollerpreview)) { - $o .= $this->output->container($status->gradingcontrollerpreview, 'gradingmethodpreview'); - } - - if ($submission) { - - if (!$status->teamsubmission || $status->submissiongroup != false || !$status->preventsubmissionnotingroup) { - foreach ($status->submissionplugins as $plugin) { - $pluginshowsummary = !$plugin->is_empty($submission) || !$plugin->allow_submissions(); - if ($plugin->is_enabled() && - $plugin->is_visible() && - $plugin->has_user_summary() && - $pluginshowsummary - ) { - - $displaymode = assign_submission_plugin_submission::SUMMARY; - $pluginsubmission = new assign_submission_plugin_submission($plugin, - $submission, - $displaymode, - $status->coursemoduleid, - $status->returnaction, - $status->returnparams); - $plugincomponent = $plugin->get_subtype() . '_' . $plugin->get_type(); - $o .= $this->output->container($this->render($pluginsubmission), 'assignsubmission ' . $plugincomponent); - } - } - } - } - - $o .= $this->output->container_end(); - return $o; - } - - /** - * Render a table containing the current status of the submission. - * - * @param assign_submission_status $status - * @return string - */ - public function render_assign_submission_status(assign_submission_status $status) { - $o = ''; - $o .= $this->output->container_start('submissionstatustable'); - $o .= $this->output->heading(get_string('submissionstatusheading', 'assign'), 3); - $time = time(); - - $o .= $this->output->box_start('boxaligncenter submissionsummarytable'); - - $t = new html_table(); - $t->attributes['class'] = 'generaltable table-bordered'; - - $warningmsg = ''; - if ($status->teamsubmissionenabled) { - $cell1content = get_string('submissionteam', 'assign'); - $group = $status->submissiongroup; - if ($group) { - $cell2content = format_string($group->name, false, $status->context); - } else if ($status->preventsubmissionnotingroup) { - if (count($status->usergroups) == 0) { - $notification = new \core\output\notification(get_string('noteam', 'assign'), 'error'); - $notification->set_show_closebutton(false); - $warningmsg = $this->output->notification(get_string('noteam_desc', 'assign'), 'error'); - } else if (count($status->usergroups) > 1) { - $notification = new \core\output\notification(get_string('multipleteams', 'assign'), 'error'); - $notification->set_show_closebutton(false); - $warningmsg = $this->output->notification(get_string('multipleteams_desc', 'assign'), 'error'); - } - $cell2content = $this->output->render($notification); - } else { - $cell2content = get_string('defaultteam', 'assign'); - } - - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - - if ($status->attemptreopenmethod != ASSIGN_ATTEMPT_REOPEN_METHOD_NONE) { - $currentattempt = 1; - if (!$status->teamsubmissionenabled) { - if ($status->submission) { - $currentattempt = $status->submission->attemptnumber + 1; - } - } else { - if ($status->teamsubmission) { - $currentattempt = $status->teamsubmission->attemptnumber + 1; - } - } - - $cell1content = get_string('attemptnumber', 'assign'); - $maxattempts = $status->maxattempts; - if ($maxattempts == ASSIGN_UNLIMITED_ATTEMPTS) { - $cell2content = get_string('currentattempt', 'assign', $currentattempt); - } else { - $cell2content = get_string('currentattemptof', 'assign', - array('attemptnumber' => $currentattempt, 'maxattempts' => $maxattempts)); - } - - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - - $cell1content = get_string('submissionstatus', 'assign'); - $cell2attributes = []; - if (!$status->teamsubmissionenabled) { - if ($status->submission && $status->submission->status != ASSIGN_SUBMISSION_STATUS_NEW) { - $cell2content = get_string('submissionstatus_' . $status->submission->status, 'assign'); - $cell2attributes = array('class' => 'submissionstatus' . $status->submission->status); - } else { - if (!$status->submissionsenabled) { - $cell2content = get_string('noonlinesubmissions', 'assign'); - } else { - $cell2content = get_string('noattempt', 'assign'); - } - } - } else { - $group = $status->submissiongroup; - if (!$group && $status->preventsubmissionnotingroup) { - $cell2content = get_string('nosubmission', 'assign'); - } else if ($status->teamsubmission && $status->teamsubmission->status != ASSIGN_SUBMISSION_STATUS_NEW) { - $teamstatus = $status->teamsubmission->status; - $cell2content = get_string('submissionstatus_' . $teamstatus, 'assign'); - - $members = $status->submissiongroupmemberswhoneedtosubmit; - $userslist = array(); - foreach ($members as $member) { - $urlparams = array('id' => $member->id, 'course'=>$status->courseid); - $url = new moodle_url('/user/view.php', $urlparams); - if ($status->view == assign_submission_status::GRADER_VIEW && $status->blindmarking) { - $userslist[] = $member->alias; - } else { - $fullname = fullname($member, $status->canviewfullnames); - $userslist[] = $this->output->action_link($url, $fullname); - } - } - if (count($userslist) > 0) { - $userstr = join(', ', $userslist); - $formatteduserstr = get_string('userswhoneedtosubmit', 'assign', $userstr); - $cell2content .= $this->output->container($formatteduserstr); - } - - $cell2attributes = array('class' => 'submissionstatus' . $status->teamsubmission->status); - } else { - if (!$status->submissionsenabled) { - $cell2content = get_string('noonlinesubmissions', 'assign'); - } else { - $cell2content = get_string('nosubmission', 'assign'); - } - } - } - - $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); - - // Is locked? - if ($status->locked) { - $cell1content = ''; - $cell2content = get_string('submissionslocked', 'assign'); - $cell2attributes = array('class' => 'submissionlocked'); - $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); - } - - // Grading status. - $cell1content = get_string('gradingstatus', 'assign'); - if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || - $status->gradingstatus == ASSIGN_GRADING_STATUS_NOT_GRADED) { - $cell2content = get_string($status->gradingstatus, 'assign'); - } else { - $gradingstatus = 'markingworkflowstate' . $status->gradingstatus; - $cell2content = get_string($gradingstatus, 'assign'); - } - if ($status->gradingstatus == ASSIGN_GRADING_STATUS_GRADED || - $status->gradingstatus == ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) { - $cell2attributes = array('class' => 'submissiongraded'); - } else { - $cell2attributes = array('class' => 'submissionnotgraded'); - } - $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); - - $submission = $status->teamsubmission ? $status->teamsubmission : $status->submission; - $duedate = $status->duedate; - if ($duedate > 0) { - if ($status->view == assign_submission_status::GRADER_VIEW) { - if ($status->cutoffdate) { - // Cut off date. - $cell1content = get_string('cutoffdate', 'assign'); - $cell2content = userdate($status->cutoffdate); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - } - - if ($status->extensionduedate) { - // Extension date. - $cell1content = get_string('extensionduedate', 'assign'); - $cell2content = userdate($status->extensionduedate); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - $duedate = $status->extensionduedate; - } - - // Time remaining. - $cell1content = get_string('timeremaining', 'assign'); - $cell2attributes = []; - if ($duedate - $time <= 0) { - if (!$submission || - $submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) { - if ($status->submissionsenabled) { - $cell2content = get_string('overdue', 'assign', format_time($time - $duedate)); - $cell2attributes = array('class' => 'overdue'); - } else { - $cell2content = get_string('duedatereached', 'assign'); - } - } else { - if ($submission->timemodified > $duedate) { - $cell2content = get_string('submittedlate', - 'assign', - format_time($submission->timemodified - $duedate)); - $cell2attributes = array('class' => 'latesubmission'); - } else { - $cell2content = get_string('submittedearly', - 'assign', - format_time($submission->timemodified - $duedate)); - $cell2attributes = array('class' => 'earlysubmission'); - } - } - } else { - $cell2content = format_time($duedate - $time); - } - $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); - } - - // Show graders whether this submission is editable by students. - if ($status->view == assign_submission_status::GRADER_VIEW) { - $cell1content = get_string('editingstatus', 'assign'); - if ($status->canedit) { - $cell2content = get_string('submissioneditable', 'assign'); - $cell2attributes = array('class' => 'submissioneditable'); - } else { - $cell2content = get_string('submissionnoteditable', 'assign'); - $cell2attributes = array('class' => 'submissionnoteditable'); - } - $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); - } - - // Grading criteria preview. - if (!empty($status->gradingcontrollerpreview)) { - $cell1content = get_string('gradingmethodpreview', 'assign'); - $cell2content = $status->gradingcontrollerpreview; - $this->add_table_row_tuple($t, $cell1content, $cell2content, [], $cell2attributes); - } - - // Last modified. - if ($submission) { - $cell1content = get_string('timemodified', 'assign'); - - if ($submission->status != ASSIGN_SUBMISSION_STATUS_NEW) { - $cell2content = userdate($submission->timemodified); - } else { - $cell2content = "-"; - } - - $this->add_table_row_tuple($t, $cell1content, $cell2content); - - if (!$status->teamsubmission || $status->submissiongroup != false || !$status->preventsubmissionnotingroup) { - foreach ($status->submissionplugins as $plugin) { - $pluginshowsummary = !$plugin->is_empty($submission) || !$plugin->allow_submissions(); - if ($plugin->is_enabled() && - $plugin->is_visible() && - $plugin->has_user_summary() && - $pluginshowsummary - ) { - - $cell1content = $plugin->get_name(); - $displaymode = assign_submission_plugin_submission::SUMMARY; - $pluginsubmission = new assign_submission_plugin_submission($plugin, - $submission, - $displaymode, - $status->coursemoduleid, - $status->returnaction, - $status->returnparams); - $cell2content = $this->render($pluginsubmission); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - } - } - } - - $o .= $warningmsg; - $o .= html_writer::table($t); - $o .= $this->output->box_end(); - - // Links. - if ($status->view == assign_submission_status::STUDENT_VIEW) { - if ($status->canedit) { - if (!$submission || $submission->status == ASSIGN_SUBMISSION_STATUS_NEW) { - $o .= $this->output->box_start('generalbox submissionaction'); - $urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission'); - $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), - get_string('addsubmission', 'assign'), 'get'); - $o .= $this->output->box_start('boxaligncenter submithelp'); - $o .= get_string('addsubmission_help', 'assign'); - $o .= $this->output->box_end(); - $o .= $this->output->box_end(); - } else if ($submission->status == ASSIGN_SUBMISSION_STATUS_REOPENED) { - $o .= $this->output->box_start('generalbox submissionaction'); - $urlparams = array('id' => $status->coursemoduleid, - 'action' => 'editprevioussubmission', - 'sesskey'=>sesskey()); - $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), - get_string('addnewattemptfromprevious', 'assign'), 'get'); - $o .= $this->output->box_start('boxaligncenter submithelp'); - $o .= get_string('addnewattemptfromprevious_help', 'assign'); - $o .= $this->output->box_end(); - $o .= $this->output->box_end(); - $o .= $this->output->box_start('generalbox submissionaction'); - $urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission'); - $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), - get_string('addnewattempt', 'assign'), 'get'); - $o .= $this->output->box_start('boxaligncenter submithelp'); - $o .= get_string('addnewattempt_help', 'assign'); - $o .= $this->output->box_end(); - $o .= $this->output->box_end(); - } else { - $o .= $this->output->box_start('generalbox submissionaction'); - $urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission'); - $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), - get_string('editsubmission', 'assign'), 'get'); - $urlparams = array('id' => $status->coursemoduleid, 'action' => 'removesubmissionconfirm'); - $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), - get_string('removesubmission', 'assign'), 'get'); - $o .= $this->output->box_start('boxaligncenter submithelp'); - $o .= get_string('editsubmission_help', 'assign'); - $o .= $this->output->box_end(); - $o .= $this->output->box_end(); - } - } - - if ($status->cansubmit) { - $urlparams = array('id' => $status->coursemoduleid, 'action'=>'submit'); - $o .= $this->output->box_start('generalbox submissionaction'); - $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams), - get_string('submitassignment', 'assign'), 'get'); - $o .= $this->output->box_start('boxaligncenter submithelp'); - $o .= get_string('submitassignment_help', 'assign'); - $o .= $this->output->box_end(); - $o .= $this->output->box_end(); - } - } - - $o .= $this->output->container_end(); - return $o; - } - - /** - * Output the attempt history chooser for this assignment - * - * @param assign_attempt_history_chooser $history - * @return string - */ - public function render_assign_attempt_history_chooser(assign_attempt_history_chooser $history) { - $o = ''; - - $context = $history->export_for_template($this); - $o .= $this->render_from_template('mod_assign/attempt_history_chooser', $context); - - return $o; - } - - /** - * Output the attempt history for this assignment - * - * @param assign_attempt_history $history - * @return string - */ - public function render_assign_attempt_history(assign_attempt_history $history) { - $o = ''; - - // Don't show the last one because it is the current submission. - array_pop($history->submissions); - - // Show newest to oldest. - $history->submissions = array_reverse($history->submissions); - - if (empty($history->submissions)) { - return ''; - } - - $containerid = 'attempthistory' . uniqid(); - $o .= $this->output->heading(get_string('attempthistory', 'assign'), 3); - $o .= $this->box_start('attempthistory', $containerid); - - foreach ($history->submissions as $i => $submission) { - $grade = null; - foreach ($history->grades as $onegrade) { - if ($onegrade->attemptnumber == $submission->attemptnumber) { - if ($onegrade->grade != ASSIGN_GRADE_NOT_SET) { - $grade = $onegrade; - } - break; - } - } - - if ($submission) { - $submissionsummary = userdate($submission->timemodified); - } else { - $submissionsummary = get_string('nosubmission', 'assign'); - } - - $attemptsummaryparams = array('attemptnumber'=>$submission->attemptnumber+1, - 'submissionsummary'=>$submissionsummary); - $o .= $this->heading(get_string('attemptheading', 'assign', $attemptsummaryparams), 4); - - $t = new html_table(); - - if ($submission) { - $cell1content = get_string('submissionstatus', 'assign'); - $cell2content = get_string('submissionstatus_' . $submission->status, 'assign'); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - - foreach ($history->submissionplugins as $plugin) { - $pluginshowsummary = !$plugin->is_empty($submission) || !$plugin->allow_submissions(); - if ($plugin->is_enabled() && - $plugin->is_visible() && - $plugin->has_user_summary() && - $pluginshowsummary) { - - $cell1content = $plugin->get_name(); - $pluginsubmission = new assign_submission_plugin_submission($plugin, - $submission, - assign_submission_plugin_submission::SUMMARY, - $history->coursemoduleid, - $history->returnaction, - $history->returnparams); - $cell2content = $this->render($pluginsubmission); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - } - } - - if ($grade) { - // Heading 'feedback'. - $title = get_string('feedback', 'assign', $i); - $title .= $this->output->spacer(array('width'=>10)); - if ($history->cangrade) { - // Edit previous feedback. - $returnparams = http_build_query($history->returnparams); - $urlparams = array('id' => $history->coursemoduleid, - 'rownum'=>$history->rownum, - 'useridlistid'=>$history->useridlistid, - 'attemptnumber'=>$grade->attemptnumber, - 'action'=>'grade', - 'returnaction'=>$history->returnaction, - 'returnparams'=>$returnparams); - $url = new moodle_url('/mod/assign/view.php', $urlparams); - $icon = new pix_icon('gradefeedback', - get_string('editattemptfeedback', 'assign', $grade->attemptnumber+1), - 'mod_assign'); - $title .= $this->output->action_icon($url, $icon); - } - $cell = new html_table_cell($title); - $cell->attributes['class'] = 'feedbacktitle'; - $cell->colspan = 2; - $t->data[] = new html_table_row(array($cell)); - - // Grade. - $cell1content = get_string('gradenoun'); - $cell2content = $grade->gradefordisplay; - $this->add_table_row_tuple($t, $cell1content, $cell2content); - - // Graded on. - $cell1content = get_string('gradedon', 'assign'); - $cell2content = userdate($grade->timemodified); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - - // Graded by set to a real user. Not set can be empty or -1. - if (!empty($grade->grader) && is_object($grade->grader)) { - $cell1content = get_string('gradedby', 'assign'); - $cell2content = $this->output->user_picture($grade->grader) . - $this->output->spacer(array('width' => 30)) . fullname($grade->grader); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - - // Feedback from plugins. - foreach ($history->feedbackplugins as $plugin) { - if ($plugin->is_enabled() && - $plugin->is_visible() && - $plugin->has_user_summary() && - !$plugin->is_empty($grade)) { - - $pluginfeedback = new assign_feedback_plugin_feedback( - $plugin, $grade, assign_feedback_plugin_feedback::SUMMARY, $history->coursemoduleid, - $history->returnaction, $history->returnparams - ); - - $cell1content = $plugin->get_name(); - $cell2content = $this->render($pluginfeedback); - $this->add_table_row_tuple($t, $cell1content, $cell2content); - } - - } - - } - - $o .= html_writer::table($t); - } - $o .= $this->box_end(); - - $this->page->requires->yui_module('moodle-mod_assign-history', 'Y.one("#' . $containerid . '").history'); - - return $o; - } - - /** - * Render a submission plugin submission - * - * @param assign_submission_plugin_submission $submissionplugin - * @return string - */ - public function render_assign_submission_plugin_submission(assign_submission_plugin_submission $submissionplugin) { - $o = ''; - - if ($submissionplugin->view == assign_submission_plugin_submission::SUMMARY) { - $showviewlink = false; - $summary = $submissionplugin->plugin->view_summary($submissionplugin->submission, - $showviewlink); - - $classsuffix = $submissionplugin->plugin->get_subtype() . - '_' . - $submissionplugin->plugin->get_type() . - '_' . - $submissionplugin->submission->id; - - $o .= $this->output->box_start('boxaligncenter plugincontentsummary summary_' . $classsuffix); - - $link = ''; - if ($showviewlink) { - $previewstr = get_string('viewsubmission', 'assign'); - $icon = $this->output->pix_icon('t/preview', $previewstr); - - $expandstr = get_string('viewfull', 'assign'); - $expandicon = $this->output->pix_icon('t/switch_plus', $expandstr); - $options = array( - 'class' => 'expandsummaryicon expand_' . $classsuffix, - 'aria-label' => $expandstr, - 'role' => 'button', - 'aria-expanded' => 'false' - ); - $o .= html_writer::link('', $expandicon, $options); - - $jsparams = array($submissionplugin->plugin->get_subtype(), - $submissionplugin->plugin->get_type(), - $submissionplugin->submission->id); - - $this->page->requires->js_init_call('M.mod_assign.init_plugin_summary', $jsparams); - - $action = 'viewplugin' . $submissionplugin->plugin->get_subtype(); - $returnparams = http_build_query($submissionplugin->returnparams); - $link .= ''; - - $link .= $this->output->spacer(array('width'=>15)); - } - - $o .= $link . $summary; - $o .= $this->output->box_end(); - if ($showviewlink) { - $o .= $this->output->box_start('boxaligncenter hidefull full_' . $classsuffix); - $collapsestr = get_string('viewsummary', 'assign'); - $options = array( - 'class' => 'expandsummaryicon contract_' . $classsuffix, - 'aria-label' => $collapsestr, - 'role' => 'button', - 'aria-expanded' => 'true' - ); - $collapseicon = $this->output->pix_icon('t/switch_minus', $collapsestr); - $o .= html_writer::link('', $collapseicon, $options); - - $o .= $submissionplugin->plugin->view($submissionplugin->submission); - $o .= $this->output->box_end(); - } - } else if ($submissionplugin->view == assign_submission_plugin_submission::FULL) { - $o .= $this->output->box_start('boxaligncenter submissionfull'); - $o .= $submissionplugin->plugin->view($submissionplugin->submission); - $o .= $this->output->box_end(); - } - - return $o; - } - - /** - * Render the grading table. - * - * @param assign_grading_table $table - * @return string - */ - public function render_assign_grading_table(assign_grading_table $table) { - $o = ''; - $o .= $this->output->box_start('boxaligncenter gradingtable'); - - $this->page->requires->js_init_call('M.mod_assign.init_grading_table', array()); - $this->page->requires->string_for_js('nousersselected', 'assign'); - $this->page->requires->string_for_js('batchoperationconfirmgrantextension', 'assign'); - $this->page->requires->string_for_js('batchoperationconfirmlock', 'assign'); - $this->page->requires->string_for_js('batchoperationconfirmremovesubmission', 'assign'); - $this->page->requires->string_for_js('batchoperationconfirmreverttodraft', 'assign'); - $this->page->requires->string_for_js('batchoperationconfirmunlock', 'assign'); - $this->page->requires->string_for_js('batchoperationconfirmaddattempt', 'assign'); - $this->page->requires->string_for_js('batchoperationconfirmdownloadselected', 'assign'); - $this->page->requires->string_for_js('batchoperationconfirmsetmarkingworkflowstate', 'assign'); - $this->page->requires->string_for_js('batchoperationconfirmsetmarkingallocation', 'assign'); - $this->page->requires->string_for_js('editaction', 'assign'); - foreach ($table->plugingradingbatchoperations as $plugin => $operations) { - foreach ($operations as $operation => $description) { - $this->page->requires->string_for_js('batchoperationconfirm' . $operation, - 'assignfeedback_' . $plugin); - } - } - $o .= $this->flexible_table($table, $table->get_rows_per_page(), true); - $o .= $this->output->box_end(); - - return $o; - } - - /** - * Render a feedback plugin feedback - * - * @param assign_feedback_plugin_feedback $feedbackplugin - * @return string - */ - public function render_assign_feedback_plugin_feedback(assign_feedback_plugin_feedback $feedbackplugin) { - $o = ''; - - if ($feedbackplugin->view == assign_feedback_plugin_feedback::SUMMARY) { - $showviewlink = false; - $summary = $feedbackplugin->plugin->view_summary($feedbackplugin->grade, $showviewlink); - - $classsuffix = $feedbackplugin->plugin->get_subtype() . - '_' . - $feedbackplugin->plugin->get_type() . - '_' . - $feedbackplugin->grade->id; - $o .= $this->output->box_start('boxaligncenter plugincontentsummary summary_' . $classsuffix); - - $link = ''; - if ($showviewlink) { - $previewstr = get_string('viewfeedback', 'assign'); - $icon = $this->output->pix_icon('t/preview', $previewstr); - - $expandstr = get_string('viewfull', 'assign'); - $expandicon = $this->output->pix_icon('t/switch_plus', $expandstr); - $options = array( - 'class' => 'expandsummaryicon expand_' . $classsuffix, - 'aria-label' => $expandstr, - 'role' => 'button', - 'aria-expanded' => 'false' - ); - $o .= html_writer::link('', $expandicon, $options); - - $jsparams = array($feedbackplugin->plugin->get_subtype(), - $feedbackplugin->plugin->get_type(), - $feedbackplugin->grade->id); - $this->page->requires->js_init_call('M.mod_assign.init_plugin_summary', $jsparams); - - $urlparams = array('id' => $feedbackplugin->coursemoduleid, - 'gid'=>$feedbackplugin->grade->id, - 'plugin'=>$feedbackplugin->plugin->get_type(), - 'action'=>'viewplugin' . $feedbackplugin->plugin->get_subtype(), - 'returnaction'=>$feedbackplugin->returnaction, - 'returnparams'=>http_build_query($feedbackplugin->returnparams)); - $url = new moodle_url('/mod/assign/view.php', $urlparams); - $link .= ''; - - $link .= $this->output->spacer(array('width'=>15)); - } - - $o .= $link . $summary; - $o .= $this->output->box_end(); - if ($showviewlink) { - $o .= $this->output->box_start('boxaligncenter hidefull full_' . $classsuffix); - $collapsestr = get_string('viewsummary', 'assign'); - $options = array( - 'class' => 'expandsummaryicon contract_' . $classsuffix, - 'aria-label' => $collapsestr, - 'role' => 'button', - 'aria-expanded' => 'true' - ); - $collapseicon = $this->output->pix_icon('t/switch_minus', $collapsestr); - $o .= html_writer::link('', $collapseicon, $options); - - $o .= $feedbackplugin->plugin->view($feedbackplugin->grade); - $o .= $this->output->box_end(); - } - } else if ($feedbackplugin->view == assign_feedback_plugin_feedback::FULL) { - $o .= $this->output->box_start('boxaligncenter feedbackfull'); - $o .= $feedbackplugin->plugin->view($feedbackplugin->grade); - $o .= $this->output->box_end(); - } - - return $o; - } - - /** - * Render a course index summary - * - * @param assign_course_index_summary $indexsummary - * @return string - */ - public function render_assign_course_index_summary(assign_course_index_summary $indexsummary) { - $o = ''; - - $strplural = get_string('modulenameplural', 'assign'); - $strsectionname = $indexsummary->courseformatname; - $strduedate = get_string('duedate', 'assign'); - $strsubmission = get_string('submission', 'assign'); - $strgrade = get_string('gradenoun'); - - $table = new html_table(); - if ($indexsummary->usesections) { - $table->head = array ($strsectionname, $strplural, $strduedate, $strsubmission, $strgrade); - $table->align = array ('left', 'left', 'center', 'right', 'right'); - } else { - $table->head = array ($strplural, $strduedate, $strsubmission, $strgrade); - $table->align = array ('left', 'left', 'center', 'right'); - } - $table->data = array(); - - $currentsection = ''; - foreach ($indexsummary->assignments as $info) { - $params = array('id' => $info['cmid']); - $link = html_writer::link(new moodle_url('/mod/assign/view.php', $params), - $info['cmname']); - $due = $info['timedue'] ? userdate($info['timedue']) : '-'; - - $printsection = ''; - if ($indexsummary->usesections) { - if ($info['sectionname'] !== $currentsection) { - if ($info['sectionname']) { - $printsection = $info['sectionname']; - } - if ($currentsection !== '') { - $table->data[] = 'hr'; - } - $currentsection = $info['sectionname']; - } - } - - if ($indexsummary->usesections) { - $row = array($printsection, $link, $due, $info['submissioninfo'], $info['gradeinfo']); - } else { - $row = array($link, $due, $info['submissioninfo'], $info['gradeinfo']); - } - $table->data[] = $row; - } - - $o .= html_writer::table($table); - - return $o; - } - - - - /** - * Internal function - creates htmls structure suitable for YUI tree. - * - * @param assign_files $tree - * @param array $dir - * @return string - */ - protected function htmllize_tree(assign_files $tree, $dir) { - global $CFG; - $yuiconfig = array(); - $yuiconfig['type'] = 'html'; - - if (empty($dir['subdirs']) and empty($dir['files'])) { - return ''; - } - - $result = '
    '; - foreach ($dir['subdirs'] as $subdir) { - $image = $this->output->pix_icon(file_folder_icon(), - $subdir['dirname'], - 'moodle', - array('class'=>'icon')); - $result .= '
  • ' . - '
    ' . $image . ' ' . s($subdir['dirname']) . '
    ' . - $this->htmllize_tree($tree, $subdir) . - '
  • '; - } - - foreach ($dir['files'] as $file) { - $filename = $file->get_filename(); - if ($CFG->enableplagiarism) { - require_once($CFG->libdir.'/plagiarismlib.php'); - $plagiarismlinks = plagiarism_get_links(array('userid'=>$file->get_userid(), - 'file'=>$file, - 'cmid'=>$tree->cm->id, - 'course'=>$tree->course)); - } else { - $plagiarismlinks = ''; - } - $image = $this->output->pix_icon(file_file_icon($file), - $filename, - 'moodle', - array('class'=>'icon')); - $result .= '
  • ' . - '
    ' . - '
    ' . $image . ' ' . - $file->fileurl . ' ' . - $plagiarismlinks . ' ' . - $file->portfoliobutton . ' ' . - '
    ' . - '
    ' . $file->timemodified . '
    ' . - '
    ' . - '
  • '; - } - - $result .= '
'; - - return $result; - } - - /** - * Helper method dealing with the fact we can not just fetch the output of flexible_table - * - * @param flexible_table $table The table to render - * @param int $rowsperpage How many assignments to render in a page - * @param bool $displaylinks - Whether to render links in the table - * (e.g. downloads would not enable this) - * @return string HTML - */ - protected function flexible_table(flexible_table $table, $rowsperpage, $displaylinks) { - - $o = ''; - ob_start(); - $table->out($rowsperpage, $displaylinks); - $o = ob_get_contents(); - ob_end_clean(); - - return $o; - } - - /** - * Helper method dealing with the fact we can not just fetch the output of moodleforms - * - * @param moodleform $mform - * @return string HTML - */ - protected function moodleform(moodleform $mform) { - - $o = ''; - ob_start(); - $mform->display(); - $o = ob_get_contents(); - ob_end_clean(); - - return $o; - } - - /** - * Defer to template.. - * - * @param grading_app $app - All the data to render the grading app. - */ - public function render_grading_app(grading_app $app) { - $context = $app->export_for_template($this); - return $this->render_from_template('mod_assign/grading_app', $context); - } -} - +// TODO - MDL-72749 add debugging message. diff --git a/mod/assign/tests/locallib_test.php b/mod/assign/tests/locallib_test.php index 5d098f90b2b..00fbb337e87 100644 --- a/mod/assign/tests/locallib_test.php +++ b/mod/assign/tests/locallib_test.php @@ -4308,7 +4308,7 @@ Anchor link 2:Link text $_GET['group'] = $activegroup->id; /** @var assign $assign */ - $header = new assign_header( + $header = new \mod_assign\output\assign_header( $assign->get_instance(), $assign->get_context(), false, diff --git a/mod/assign/upgrade.txt b/mod/assign/upgrade.txt index 130cf298119..4a703e6a509 100644 --- a/mod/assign/upgrade.txt +++ b/mod/assign/upgrade.txt @@ -1,6 +1,9 @@ This files describes API changes in the assign code. === 4.0 === * The method \assign::grading_disabled() now has optional $gradinginfo parameter to improve performance +* Renderer (renderer.php) has been moved from mod root to classes/output/ to be more PSR compliant. +* Class assign_header has been moved from renderable.php to classes/ouput/assign_header.php +* Class assign_submion_status has been moved from renderable.php to classes/ouput/assign_submion_status.php === 3.9 === diff --git a/mod/assign/version.php b/mod/assign/version.php index 08be89e031e..f047cc5a8eb 100644 --- a/mod/assign/version.php +++ b/mod/assign/version.php @@ -25,5 +25,5 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'mod_assign'; // Full name of the plugin (used for diagnostics). -$plugin->version = 2021052503; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2021093000; // The current module version (Date: YYYYMMDDXX). $plugin->requires = 2021052500; // Requires this Moodle version.