diff --git a/classes/renderable/panoptosubmission_grading_summary.php b/classes/renderable/panoptosubmission_grading_summary.php new file mode 100644 index 0000000..4356f36 --- /dev/null +++ b/classes/renderable/panoptosubmission_grading_summary.php @@ -0,0 +1,94 @@ +. + +/** + * This file contains the definition for the renderable classes for the submissions + * + * @package mod_panoptosubmission + * @copyright Panopto 2023 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Renderable grading summary. + * + * @package mod_panoptosubmission + * @copyright Panopto 2023 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class panoptosubmission_grading_summary implements renderable { + /** @var int participantcount - The number of users who can submit to this submission */ + public $participantcount = 0; + /** @var bool submissionsenabled - Allow submissions */ + public $submissionsenabled = false; + /** @var int submissionssubmittedcount - The number of submissions in submitted status */ + public $submissionssubmittedcount = 0; + /** @var int submissionsneedgradingcount - The number of submissions that need grading */ + public $submissionsneedgradingcount = 0; + /** @var int duedate - The submission due date (if one is set) */ + public $duedate = 0; + /** @var int cutoffdate - The submission cut off date (if one is set) */ + public $cutoffdate = 0; + /** @var int timelimit - The submission time limit (if one is set) */ + public $timelimit = 0; + /** @var int coursemoduleid - The submission course module id */ + public $coursemoduleid = 0; + /** @var boolean relativedatesmode - Is the course a relative dates mode course or not */ + public $courserelativedatesmode = false; + /** @var int coursestartdate - start date of the course as a unix timestamp*/ + public $coursestartdate; + /** @var boolean isvisible - Is the submission's context module visible to students? */ + public $isvisible = true; + + /** + * constructor + * + * @param int $participantcount + * @param bool $submissionsenabled + * @param int $submissionssubmittedcount + * @param int $cutoffdate + * @param int $duedate + * @param int $timelimit + * @param int $coursemoduleid + * @param int $submissionsneedgradingcount + * @param bool $courserelativedatesmode true if the course is using relative dates, false otherwise. + * @param int $coursestartdate unix timestamp representation of the course start date. + * @param bool $isvisible + */ + public function __construct($participantcount, + $submissionsenabled, + $submissionssubmittedcount, + $cutoffdate, + $duedate, + $timelimit, + $coursemoduleid, + $submissionsneedgradingcount, + $courserelativedatesmode, + $coursestartdate, + $isvisible = true) { + $this->participantcount = $participantcount; + $this->submissionsenabled = $submissionsenabled; + $this->submissionssubmittedcount = $submissionssubmittedcount; + $this->duedate = $duedate; + $this->cutoffdate = $cutoffdate; + $this->timelimit = $timelimit; + $this->coursemoduleid = $coursemoduleid; + $this->submissionsneedgradingcount = $submissionsneedgradingcount; + $this->courserelativedatesmode = $courserelativedatesmode; + $this->coursestartdate = $coursestartdate; + $this->isvisible = $isvisible; + } +} diff --git a/classes/renderable/panoptosubmission_submissions_feedback_status.php b/classes/renderable/panoptosubmission_submissions_feedback_status.php new file mode 100644 index 0000000..1b17df4 --- /dev/null +++ b/classes/renderable/panoptosubmission_submissions_feedback_status.php @@ -0,0 +1,69 @@ +. + +/** + * This file contains the definition for the renderable classes for the submissions + * + * @package mod_panoptosubmission + * @copyright Panopto 2023 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Renderable feedback status + * + * @package mod_panoptosubmission + * @copyright Panopto 2023 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class panoptosubmission_submissions_feedback_status implements renderable { + + /** @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; + /** @var mixed the grader (may be null) */ + public $grader = null; + /** @var stdClass grade record */ + public $grade = null; + /** @var int coursemoduleid */ + public $coursemoduleid = 0; + /** @var bool canviewfullnames */ + public $canviewfullnames = false; + + /** + * Constructor + * @param string $gradefordisplay + * @param mixed $gradeddate + * @param mixed $grader + * @param mixed $grade + * @param int $coursemoduleid + * @param bool $canviewfullnames + */ + public function __construct($gradefordisplay, + $gradeddate, + $grader, + $grade, + $coursemoduleid, + $canviewfullnames) { + $this->gradefordisplay = $gradefordisplay; + $this->gradeddate = $gradeddate; + $this->grader = $grader; + $this->grade = $grade; + $this->coursemoduleid = $coursemoduleid; + $this->canviewfullnames = $canviewfullnames; + } +} diff --git a/contentitem.php b/contentitem.php index 958c6a8..848d739 100644 --- a/contentitem.php +++ b/contentitem.php @@ -31,7 +31,7 @@ $courseid = required_param('courseid', PARAM_INT); /** - * Student Submission path. + * @var string Student Submission path. */ const STUDENT_SUBMISSION_PATH = '/mod/panoptosubmission/contentitem_return.php'; diff --git a/grade_preferences_form.php b/grade_preferences_form.php index efd218b..d60f379 100644 --- a/grade_preferences_form.php +++ b/grade_preferences_form.php @@ -103,7 +103,8 @@ public function definition() { $filters = array( PANOPTOSUBMISSION_ALL => get_string('all', 'panoptosubmission'), PANOPTOSUBMISSION_REQ_GRADING => get_string('reqgrading', 'panoptosubmission'), - PANOPTOSUBMISSION_SUBMITTED => get_string('submitted', 'panoptosubmission') + PANOPTOSUBMISSION_SUBMITTED => get_string('submitted', 'panoptosubmission'), + PANOPTOSUBMISSION_NOT_SUBMITTED => get_string('not_submitted', 'panoptosubmission') ); $mform->addElement('select', 'filter', get_string('show'), $filters); diff --git a/grade_submissions.php b/grade_submissions.php index 56604e2..40f6dc9 100644 --- a/grade_submissions.php +++ b/grade_submissions.php @@ -186,7 +186,7 @@ $userid, $gradedata->submissioncomment) && empty($gradedata->submissioncomment[$userid] ); - if ($emptygrade && $emptycomment ) { + if ($emptygrade && $emptycomment) { continue; } diff --git a/lang/en/panoptosubmission.php b/lang/en/panoptosubmission.php index c76315c..58c7c40 100644 --- a/lang/en/panoptosubmission.php +++ b/lang/en/panoptosubmission.php @@ -57,7 +57,22 @@ $string['fullname'] = 'Name'; $string['gradeverb'] = 'Grade'; $string['gradenoun'] = 'Grade'; +$string['gradedon'] = 'Graded on'; +$string['gradedby'] = 'Graded by'; +$string['gradingsummary'] = 'Grading summary'; +$string['numberofparticipants'] = 'Participants'; +$string['numberofsubmittedassignments'] = 'Submitted'; +$string['numberofsubmissionsneedgrading'] = 'Needs grading'; +$string['timeremaining'] = 'Time remaining'; +$string['hiddenfromstudents'] = 'Hidden from students'; +$string['yes'] = 'Yes'; +$string['no'] = 'No'; +$string['submissionisdue'] = 'Submission is due'; +$string['relativedatessubmissiontimeleft'] = 'Calculated for each student'; +$string['latesubmissions'] = 'Late submissions'; +$string['latesubmissionsaccepted'] = 'Allowed until {$a}'; $string['submissioncomment'] = 'Comment'; +$string['submissioncommentfeedback'] = 'Comment Feedback'; $string['timemodified'] = 'Last modified (Submission)'; $string['grademodified'] = 'Last modified (Grade)'; $string['finalgrade'] = 'Final grade'; @@ -67,6 +82,7 @@ $string['all'] = 'All'; $string['reqgrading'] = 'Require grading'; $string['submitted'] = 'Submitted'; +$string['not_submitted'] = 'Not submitted'; $string['pagesize'] = 'Submissions shown per page'; $string['pagesize_help'] = 'Set the number of assignment to display per page'; $string['show'] = 'Show'; diff --git a/lib.php b/lib.php index 77a47d4..ab094a9 100644 --- a/lib.php +++ b/lib.php @@ -43,8 +43,8 @@ function panoptosubmission_add_instance($newactivity) { $newactivity->id = $DB->insert_record('panoptosubmission', $newactivity); if ($newactivity->timedue) { - $event = new stdClass(); + $event = new stdClass(); $event->name = $newactivity->name; $event->description = format_module_intro('panoptosubmission', $newactivity, $newactivity->coursemodule, false); $event->format = FORMAT_HTML; @@ -262,12 +262,6 @@ function panoptosubmission_scale_used_anywhere($scaleid) { */ function panoptosubmission_supports($feature) { switch($feature) { - case FEATURE_GROUPS: - return true; - case FEATURE_GROUPINGS: - return true; - case FEATURE_GROUPMEMBERSONLY: - return true; case FEATURE_MOD_INTRO: return true; case FEATURE_COMPLETION_TRACKS_VIEWS: @@ -280,6 +274,8 @@ function panoptosubmission_supports($feature) { return true; case FEATURE_BACKUP_MOODLE2: return true; + case FEATURE_SHOW_DESCRIPTION; + return true; default: return null; } diff --git a/locallib.php b/locallib.php index fb600f1..9a2a457 100644 --- a/locallib.php +++ b/locallib.php @@ -15,7 +15,7 @@ // along with Moodle. If not, see . /** - * main locallib.php file for the Panopto Student Submission mod + * Main locallib.php file for the Panopto Student Submission mod * * @package mod_panoptosubmission * @copyright Panopto 2021 @@ -27,6 +27,7 @@ define('PANOPTOSUBMISSION_ALL', 0); define('PANOPTOSUBMISSION_REQ_GRADING', 1); define('PANOPTOSUBMISSION_SUBMITTED', 2); +define('PANOPTOSUBMISSION_NOT_SUBMITTED', 3); require_once($CFG->libdir . '/gradelib.php'); require_once($CFG->dirroot . '/grade/grading/lib.php'); @@ -136,7 +137,6 @@ function panoptosubmission_get_submission($targetinstanceid, $userid) { } return $record; - } /** @@ -173,7 +173,7 @@ function panoptosubmission_get_submission_grade_object($targetinstanceid, $useri * @return array an array with the following values array(course module object, $course object, activity instance object). * @throws moodle_exception */ -function panoptosubmission_validate_cmid ($cmid) { +function panoptosubmission_validate_cmid($cmid) { global $DB; if (!$cm = get_coursemodule_from_id('panoptosubmission', $cmid)) { @@ -430,6 +430,124 @@ function panoptosubmission_get_grading_instance($cminstance, $context, $submissi return $gradinginstance; } +/** + * Creates an panoptosubmission_submissions_feedback_status renderable. + * + * @param object $cm Panopto video assignment course module object. + * @param object $pansubmissionactivity The submission object or NULL in which case it will be loaded + * @param object $submission current submission with grade information + * @param object $context A context object. + * @param string $userid of the user to get the report for + * @param object $grade user grade + * @param object $teacher user that graded the submission + * @return panoptosubmission_submissions_feedback_status renderable object + */ +function panoptosubmission_get_feedback_status_renderable($cm, + $pansubmissionactivity, $submission, $context, $userid, $grade, $teacher) { + global $DB, $PAGE; + + $gradinginfo = grade_get_grades($pansubmissionactivity->course, + 'mod', + 'panoptosubmission', + $cm->instance, + $userid); + + $gradingitem = null; + $gradebookgrade = null; + if (isset($gradinginfo->items[0])) { + $gradingitem = $gradinginfo->items[0]; + $gradebookgrade = $gradingitem->grades[$userid]; + } + + $cangrade = has_capability('mod/panoptosubmission:gradesubmission', $context); + $hasgrade = !is_null($gradebookgrade) && !is_null($gradebookgrade->grade); + $gradevisible = $cangrade || (!is_null($gradebookgrade) && !$gradebookgrade->hidden); + + // If there is a visible grade, show the summary. + if ($hasgrade && $gradevisible) { + + $gradefordisplay = null; + $gradeddate = null; + $grader = null; + $gradingmanager = get_grading_manager($context, 'mod_panoptosubmission', 'submissions'); + + // Criteria feedback. + if ($controller = $gradingmanager->get_active_controller()) { + $menu = make_grades_menu($submission->grade); + $controller->set_grade_range($menu, $submission->grade > 0); + $gradefordisplay = $controller->render_grade($PAGE, + $submission->id, + $gradingitem, + $gradebookgrade->str_long_grade, + $cangrade); + } else { + // Normal feedback, which is just a grade. + $gradefordisplay = $grade->str_long_grade; + } + $gradeddate = $gradebookgrade->dategraded; + + if (isset($teacher)) { + $grader = $DB->get_record('user', array('id' => $teacher->id)); + } else if (isset($gradebookgrade->usermodified) + && $gradebookgrade->usermodified > 0 + && has_capability('mod/panoptosubmission:gradesubmission', $context, $gradebookgrade->usermodified)) { + // Grader not provided. Check that usermodified is a user who can grade. + // Case 1: When an assignment is reopened an empty grade is created so the feedback + // plugin can know which attempt it's referring to. In this case, usermodifed is a student. + // Case 2: When an assignment's grade is overrided via the gradebook, usermodified is a grader. + $grader = $DB->get_record('user', array('id' => $gradebookgrade->usermodified)); + } + + $viewfullnames = has_capability('moodle/site:viewfullnames', $context); + $feedbackstatus = new panoptosubmission_submissions_feedback_status($gradefordisplay, + $gradeddate, + $grader, + $grade, + $cm->id, + $viewfullnames); + + return $feedbackstatus; + } + return; +} + +/** + * Creates an panoptosubmission_grading_summary renderable. + * + * @param object $cm Panopto video assignment course module object. + * @param object $course Course object. + * @return panoptosubmission_grading_summary renderable object + */ +function panoptosubmission_get_grading_summary_renderable($cm, $course) { + global $DB; + $instance = $DB->get_record('panoptosubmission', array('id' => $cm->instance), '*', MUST_EXIST); + + $isvisible = $cm->visible; + $countparticipants = count(array_keys(panoptosubmission_get_assignment_students($cm))); + + $submissionssubmitted = panoptosubmission_get_submissions($cm->instance, PANOPTOSUBMISSION_SUBMITTED); + $submissionssubmittedcount = $submissionssubmitted ? count($submissionssubmitted) : 0; + + $submissionrequiregrading = panoptosubmission_get_submissions($cm->instance, PANOPTOSUBMISSION_REQ_GRADING); + $submissionrequiregradingcount = $submissionrequiregrading ? count($submissionrequiregrading) : 0; + + $summary = new panoptosubmission_grading_summary( + $countparticipants, + true, + $submissionssubmittedcount, + $instance->cutofftime, + $instance->timedue, + $instance->timeavailable, + $course->id, + $submissionrequiregradingcount, + $course->relativedatesmode, + $course->startdate, + $isvisible + ); + + return $summary; +} + /** * Provision the course if not provisioned already. * diff --git a/renderer.php b/renderer.php index 0d81233..f268c91 100644 --- a/renderer.php +++ b/renderer.php @@ -18,7 +18,7 @@ * This file contains the renderers for the Panopto Student Submission activity within Moodle * * @package mod_panoptosubmission - * @copyright Panopto 2021 + * @copyright Panopto 2021 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -27,6 +27,8 @@ require_once(dirname(dirname(dirname(__FILE__))).'/lib/tablelib.php'); require_once(dirname(dirname(dirname(__FILE__))).'/lib/moodlelib.php'); require_once($CFG->dirroot.'/mod/panoptosubmission/classes/renderable/panoptosubmission_course_index_summary.php'); +require_once($CFG->dirroot.'/mod/panoptosubmission/classes/renderable/panoptosubmission_submissions_feedback_status.php'); +require_once($CFG->dirroot.'/mod/panoptosubmission/classes/renderable/panoptosubmission_grading_summary.php'); /** * Table class for displaying video submissions for grading @@ -99,7 +101,6 @@ public function __construct($uniqueid, $cm, $currentgrades, $quickgrade = false, $instance = $DB->get_record('panoptosubmission', array('id' => $cm->instance), 'id,grade,timedue'); $instance->cmid = $cm->id; $this->cminstance = $instance; - } /** @@ -217,7 +218,7 @@ public function col_selectgrade($rowdata) { $finalgrade->formatted_grade = $this->currentgrades->items[0]->grades[$rowdata->id]->str_grade; } else { // Taken from mod/assignment/lib.php display_submissions(). - $finalgrade->formatted_grade = round($finalgrade->grade, 2) . ' / ' . round($this->grademax, 2); + $finalgrade->formatted_grade = round($finalgrade->grade ?? 0, 2) . ' / ' . round($this->grademax, 2); } } @@ -315,7 +316,7 @@ public function col_submissioncomment($rowdata) { $output .= html_writer::tag('textarea', strip_tags($rowdata->submissioncomment), $param); } else { - $output = shorten_text(strip_tags($rowdata->submissioncomment), 15); + $output = shorten_text(strip_tags($rowdata->submissioncomment ?? ''), 15); } return $output; @@ -819,7 +820,10 @@ public function display_submissions_table( $where = ' ps.timemodified > 0 AND '; break; case PANOPTOSUBMISSION_REQ_GRADING: - $where = ' ps.timemarked < ps.timemodified AND '; + $where = ' (ps.timemarked = 0 or ps.timemarked is null) AND '; + break; + case PANOPTOSUBMISSION_NOT_SUBMITTED: + $where = ' (ps.timecreated = 0 or ps.timecreated is null) AND '; break; } @@ -1182,7 +1186,7 @@ public function get_view_video_container($submission, $courseid, $cmid) { 'var sessionIframe = document.getElementById("contentframe");' . 'var titleElem = document.getElementById("panoptosessiontitle");' . - 'if(sessionContainerDiv.classList.contains("session-hidden")) {' . + 'if (sessionContainerDiv.classList.contains("session-hidden")) {' . 'sessionContainerDiv.classList.remove("session-hidden");' . 'sessionIframe.setAttribute("src", titleElem.getAttribute("href"));' . 'showSessionPreviewToggle.textContent = "' . get_string('sessionpreview_hide', 'panoptosubmission') . @@ -1238,7 +1242,6 @@ public function get_view_video_container($submission, $courseid, $cmid) { 'class' => 'panopto-session-title', 'href' => $ltiviewerurl, 'target' => '_blank' - ); $output .= html_writer::tag('a', $sessiontitle, $titleparams); @@ -1259,11 +1262,14 @@ public function get_view_video_container($submission, $courseid, $cmid) { * This default method prints the teacher picture and name, date when marked, * grade and teacher submission comment. * + * @param object $cm A course module object. * @param object $pansubmissionactivity The submission object or NULL in which case it will be loaded + * @param object $submission current submission with grade information * @param object $context the context for the current submission */ - public function display_grade_feedback($pansubmissionactivity, $context) { + public function display_grade_feedback($cm, $pansubmissionactivity, $submission, $context) { global $USER, $CFG, $DB; + $renderer = $this->page->get_renderer('mod_panoptosubmission'); require_once($CFG->libdir.'/gradelib.php'); @@ -1290,7 +1296,6 @@ public function display_grade_feedback($pansubmissionactivity, $context) { return; } - $gradedate = $grade->dategraded; $gradeby = $grade->usermodified; // We need the teacher info. @@ -1298,41 +1303,128 @@ public function display_grade_feedback($pansubmissionactivity, $context) { throw new moodle_exception('cannotfindteacher'); } - // Print the feedback. - echo $this->output->heading(get_string('feedbackfromteacher', 'panoptosubmission', fullname($teacher))); + $feedbackstatus = panoptosubmission_get_feedback_status_renderable($cm, + $pansubmissionactivity, $submission, $context, $USER->id, $grade, $teacher); + + if ($feedbackstatus) { + return $renderer->render($feedbackstatus); + } + } + + /** + * Display grading summary. + * + * @param object $cm A course module object. + * @param object $course Course object. + */ + public function display_grading_summary($cm, $course) { + $renderer = $this->page->get_renderer('mod_panoptosubmission'); + $gradingsummary = panoptosubmission_get_grading_summary_renderable($cm, $course); + + if ($gradingsummary) { + return $renderer->render($gradingsummary); + } + } + + /** + * Render a table containing the current status of the grading process. + * + * @param \panoptosubmission_grading_summary $summary + * @return string + */ + public function render_panoptosubmission_grading_summary(\panoptosubmission_grading_summary $summary) { + // Create a table for the data. + $o = ''; + $o .= $this->output->container_start('gradingsummary'); + $o .= $this->output->heading(get_string('gradingsummary', 'panoptosubmission'), 3); + + $o .= $this->output->box_start('boxaligncenter gradingsummarytable'); + $t = new \html_table(); + $t->attributes['class'] = 'generaltable table-bordered'; + + // Visibility Status. + $cell1content = get_string('hiddenfromstudents', 'panoptosubmission'); + $cell2content = (!$summary->isvisible) ? get_string('yes', 'panoptosubmission') : get_string('no', 'panoptosubmission'); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + // Status. + $cell1content = get_string('numberofparticipants', 'panoptosubmission'); + $cell2content = $summary->participantcount; + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + // Submitted for grading. + if ($summary->submissionsenabled) { + $cell1content = get_string('numberofsubmittedassignments', 'panoptosubmission'); + $cell2content = $summary->submissionssubmittedcount; + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + + $time = time(); + if ($summary->duedate) { + // Time remaining. + $duedate = $summary->duedate; + $cell1content = get_string('timeremaining', 'panoptosubmission'); + if ($summary->courserelativedatesmode) { + $cell2content = get_string('relativedatessubmissiontimeleft', 'panoptosubmission'); + } else { + if ($duedate - $time <= 0) { + $cell2content = get_string('submissionisdue', 'panoptosubmission'); + } else { + $cell2content = format_time($duedate - $time); + } + } + + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + if ($duedate < $time) { + $cutoffdate = $summary->cutoffdate; + if ($cutoffdate) { + if ($cutoffdate > $time) { + $cell1content = get_string('latesubmissions', 'panoptosubmission'); + $cell2content = get_string('latesubmissionsaccepted', 'panoptosubmission', userdate($summary->cutoffdate)); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + } + } + } + + // All done - write the table. + $o .= \html_writer::table($t); + $o .= $this->output->box_end(); + + // Close the container and insert a spacer. + $o .= $this->output->container_end(); + $o .= \html_writer::end_tag('center'); - echo ''; + return $o; + } - echo ''; - echo ''; - echo ''; - echo ''; - - echo ''; - echo ''; - echo ''; - - echo '
'; - if ($teacher) { - echo $this->output->user_picture($teacher); + /** + * 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; } - echo ''; - echo '
'; - if ($teacher) { - echo '
'.fullname($teacher).'
'; + + $cell2 = new html_table_cell($second); + if (!empty($secondattributes)) { + $cell2->attributes = $secondattributes; } - echo '
'.userdate($gradedate).'
'; - echo '
'; - echo '
 '; - echo '
'; - echo get_string("gradenoun", "panoptosubmission").': '.$grade->str_long_grade; - echo '
'; - echo '
'; - - echo '
'; - echo $grade->str_feedback; - echo '
'; - echo '
'; + $row->cells = array($cell1, $cell2); + $table->data[] = $row; } /** @@ -1387,4 +1479,54 @@ public function render_panoptosubmission_course_index_summary(panoptosubmission_ return html_writer::table($table); } + + /** + * Render a table containing all the current grades and feedback. + * + * @param panoptosubmission_submissions_feedback_status $status + * @return string + */ + public function render_panoptosubmission_submissions_feedback_status(panoptosubmission_submissions_feedback_status $status) { + $o = ''; + + $o .= $this->output->container_start('feedback'); + $o .= $this->output->heading(get_string('feedbackfromteacher', 'panoptosubmission'), 3); + $o .= $this->output->box_start('boxaligncenter feedbacktable'); + $t = new html_table(); + + if (isset($status->gradefordisplay)) { + // Grade. + $cell1content = get_string('gradenoun', 'panoptosubmission'); + $cell2content = $status->gradefordisplay; + $this->add_table_row_tuple($t, $cell1content, $cell2content); + + // Grade date. + $cell1content = get_string('gradedon', 'panoptosubmission'); + $cell2content = userdate($status->gradeddate); + $this->add_table_row_tuple($t, $cell1content, $cell2content); + } + + if ($status->grader) { + // Grader. + $cell1content = get_string('gradedby', 'panoptosubmission'); + $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); + } + + if ($status->grade->str_feedback) { + // Feedback. + $feedback = $this->output->box_start('boxaligncenter plugincontentsummary summary_submission_feedback'); + $feedback .= $status->grade->str_feedback; + $feedback .= $this->output->box_end(); + $this->add_table_row_tuple($t, get_string('submissioncommentfeedback', 'panoptosubmission'), $feedback); + } + + $o .= html_writer::table($t); + $o .= $this->output->box_end(); + + $o .= $this->output->container_end(); + return $o; + } } diff --git a/single_submission.php b/single_submission.php index 575afd8..a5b4e62 100644 --- a/single_submission.php +++ b/single_submission.php @@ -170,7 +170,10 @@ if (!$blanksubmission) { - $submissionchanged = strcmp($submission->submissioncomment, $submitteddata->submissioncomment_editor['text']); + $submissionchanged = strcmp( + $submission->submissioncomment ?? '', + $submitteddata->submissioncomment_editor['text'] ?? '' + ); if ($submission->grade == $currentgrade && !$submissionchanged) { $updategrade = false; } diff --git a/styles.css b/styles.css index 4892665..b2e64a3 100644 --- a/styles.css +++ b/styles.css @@ -1,7 +1,7 @@ .panopto-player-container { - transition: opacity .5s ease-in-out; - -moz-transition: opacity .5s ease-in-out; -webkit-transition: opacity .5s ease-in-out; + -moz-transition: opacity .5s ease-in-out; + transition: opacity .5s ease-in-out; } .panopto-player-container.no-session { @@ -19,16 +19,16 @@ top: 0px; left: 0px; opacity: 0; - transition: opacity .5s ease-in-out; - -moz-transition: opacity .5s ease-in-out; -webkit-transition: opacity .5s ease-in-out; + -moz-transition: opacity .5s ease-in-out; + transition: opacity .5s ease-in-out; } .panopto-session-container .panopto-player-iframe { opacity: 1; - transition: visibility .5s ease-in-out, opacity .5s ease-in-out, height .5s ease-in-out; - -moz-transition: visibility .5s ease-in-out, opacity .5s ease-in-out, height .5s ease-in-out; -webkit-transition: visibility .5s ease-in-out, opacity .5s ease-in-out, height .5s ease-in-out; + -moz-transition: visibility .5s ease-in-out, opacity .5s ease-in-out, height .5s ease-in-out; + transition: visibility .5s ease-in-out, opacity .5s ease-in-out, height .5s ease-in-out; } .panopto-session-container.session-hidden .panopto-thumbnail-container { diff --git a/version.php b/version.php index e46d7f0..9a9aa3c 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); // The current plugin version (Date: YYYYMMDDXX). -$plugin->version = 2023031400; +$plugin->version = 2023083100; // Requires this Moodle version - 2.7. $plugin->requires = 2014051202; diff --git a/view.php b/view.php index 2cb2d73..b15e3e6 100644 --- a/view.php +++ b/view.php @@ -36,7 +36,7 @@ require_course_login($course->id, true, $cm); -global $PAGE, $OUTPUT, $DB; +global $CFG, $PAGE, $OUTPUT, $DB; $PAGE->set_url('/mod/panoptosubmission/view.php', array('id' => $id)); $PAGE->set_title(format_string($panactivityinstance->name)); @@ -44,6 +44,14 @@ $pageclass = 'panoptosubmission-body'; $PAGE->add_body_class($pageclass); +$ismoodle40minimum = empty($CFG->version) ? false : $CFG->version >= 2022041908.00; +if ($ismoodle40minimum) { + $PAGE->activityheader->set_attrs([ + "title" => '', + "hidecompletion" => false, + "description" => '']); +} + $context = context_module::instance($cm->id); $PAGE->requires->css('/mod/panoptosubmission/styles.css'); @@ -85,6 +93,7 @@ // Limit the instructor buttons to ONLY those users with the role appropriate for them. if (has_capability('mod/panoptosubmission:gradesubmission', $context)) { echo $renderer->display_instructor_buttons($cm, $USER->id); + echo $renderer->display_grading_summary($cm, $course); } else { echo $renderer->get_view_video_container($submission, $course->id, $cm->id); @@ -98,7 +107,7 @@ echo $renderer->display_student_submit_buttons($cm, $USER->id, $submitdisabled); } - echo $renderer->display_grade_feedback($panactivityinstance, $context); + echo $renderer->display_grade_feedback($cm, $panactivityinstance, $submission, $context); $url = new moodle_url('/mod/panoptosubmission/contentitem.php', $contentitemparams);