diff --git a/mod/workshop/db/access.php b/mod/workshop/db/access.php index 84827f63021..74a038e0705 100644 --- a/mod/workshop/db/access.php +++ b/mod/workshop/db/access.php @@ -169,8 +169,8 @@ $capabilities = array( ) ), - // Ability to view the assessments of other users' work. Applies to the user's group only - // or - if the user is allowed to access all groups - applies to any assessment + // Ability to always view the assessments of other users' work and the calculated grades, regardless the phase. + // Applies to the user's group only or - if the user is allowed to access all groups - applies to any assessment 'mod/workshop:viewallassessments' => array( 'captype' => 'read', 'contextlevel' => CONTEXT_MODULE, diff --git a/mod/workshop/lang/en/workshop.php b/mod/workshop/lang/en/workshop.php index 9905fb4b09f..ff4fb754dd8 100644 --- a/mod/workshop/lang/en/workshop.php +++ b/mod/workshop/lang/en/workshop.php @@ -95,7 +95,6 @@ $string['exampledelete'] = 'Delete example'; $string['exampledeleteconfirm'] = 'Are you sure you want to delete the following example submission? Click \'Continue\' button to delete the submission.'; $string['exampleedit'] = 'Edit example'; $string['exampleediting'] = 'Editing example'; -$string['examplegrade'] = 'Grade: {$a->received} of {$a->max}'; $string['exampleneedassessed'] = 'You have to assess all example submissions first'; $string['exampleneedsubmission'] = 'You have to submit your work and assess all example submissions first'; $string['examplesbeforeassessment'] = 'Examples are available after own submission and must be assessed before assessment phase'; @@ -118,7 +117,9 @@ $string['gradegivento'] = '>'; $string['gradeitemassessment'] = '{$a->workshopname} (assessment)'; $string['gradeitemsubmission'] = '{$a->workshopname} (submission)'; $string['gradeover'] = 'Override grade for submission'; +$string['gradesreport'] = 'Workshop grades report'; $string['gradereceivedfrom'] = '<'; +$string['gradeinfo'] = 'Grade: {$a->received} of {$a->max}'; $string['gradinggrade'] = 'Grade for assessment'; $string['gradinggrade_help'] = 'This setting specifies the maximum grade a student can obtain for their assessment of the work of others.'; $string['gradinggradecalculated'] = 'Calculated grade for assessment'; @@ -221,6 +222,7 @@ $string['userplan_help'] = 'The workshop planner displays all phases of the acti $string['useselfassessment'] = 'Use self-assessment'; $string['useselfassessment_help'] = 'If enabled, a student may be allocated their own submission to assess and will receive a grade for assessment in addition to a grade for their submission.'; $string['useselfassessment_desc'] = 'Students may assess their own work'; +$string['weightinfo'] = 'Weight: {$a}'; $string['withoutsubmission'] = 'Reviewer without own submission'; $string['workshopadministration'] = 'Workshop administration'; $string['workshop:allocate'] = 'Allocate submissions for review'; diff --git a/mod/workshop/locallib.php b/mod/workshop/locallib.php index 2c178ce8b32..94bbc9463c3 100644 --- a/mod/workshop/locallib.php +++ b/mod/workshop/locallib.php @@ -701,7 +701,7 @@ class workshop { * Get the complete information about the given assessment * * @param int $id Assessment ID - * @return mixed false if not found, stdclass otherwise + * @return stdclass */ public function get_assessment_by_id($id) { global $DB; @@ -720,6 +720,50 @@ class workshop { return $DB->get_record_sql($sql, $params, MUST_EXIST); } + /** + * Get the complete information about the user's assessment of the given submission + * + * @param int $sid submission ID + * @param int $uid user ID of the reviewer + * @return false|stdclass false if not found, stdclass otherwise + */ + public function get_assessment_of_submission_by_user($submissionid, $reviewerid) { + global $DB; + + $sql = 'SELECT a.*, + reviewer.id AS reviewerid,reviewer.firstname AS reviewerfirstname,reviewer.lastname as reviewerlastname, + s.title, + author.id AS authorid, author.firstname AS authorfirstname,author.lastname as authorlastname + FROM {workshop_assessments} a + INNER JOIN {user} reviewer ON (a.reviewerid = reviewer.id) + INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id AND s.example = 0) + INNER JOIN {user} author ON (s.authorid = author.id) + WHERE s.id = :sid AND reviewer.id = :rid AND s.workshopid = :workshopid'; + $params = array('sid' => $submissionid, 'rid' => $reviewerid, 'workshopid' => $this->id); + + return $DB->get_record_sql($sql, $params, IGNORE_MISSING); + } + + /** + * Get the complete information about all assessments of the given submission + * + * @param int $submissionid + * @return array + */ + public function get_assessments_of_submission($submissionid) { + global $DB; + + $sql = 'SELECT a.*, + reviewer.id AS reviewerid,reviewer.firstname AS reviewerfirstname,reviewer.lastname AS reviewerlastname + FROM {workshop_assessments} a + INNER JOIN {user} reviewer ON (a.reviewerid = reviewer.id) + INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id) + WHERE s.example = 0 AND s.id = :submissionid AND s.workshopid = :workshopid'; + $params = array('submissionid' => $submissionid, 'workshopid' => $this->id); + + return $DB->get_records_sql($sql, $params); + } + /** * Get the complete information about all assessments allocated to the given reviewer * @@ -1068,24 +1112,10 @@ class workshop { /** * Are the peer-reviews available to the authors? * - * TODO: this depends on the workshop phase - * * @return bool */ public function assessments_available() { - return true; - } - - /** - * Can the given grades be displayed to the authors? - * - * Grades are not displayed if {@link self::assessments_available()} return false. The returned - * value may be true (if yes, display grades) or false (no, hide grades yet) - * - * @return bool - */ - public function grades_available() { - return true; + return $this->phase == self::PHASE_CLOSED; } /** diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php index aee166584a5..ecbbae268e5 100644 --- a/mod/workshop/renderer.php +++ b/mod/workshop/renderer.php @@ -311,7 +311,7 @@ class mod_workshop_renderer extends plugin_renderer_base { if ($summary->status == 'notgraded') { $o .= $this->output->container(get_string('nogradeyet', 'workshop'), 'example-info nograde'); } else { - $o .= $this->output->container(get_string('examplegrade', 'workshop' , $summary->gradeinfo), 'example-info grade'); + $o .= $this->output->container(get_string('gradeinfo', 'workshop' , $summary->gradeinfo), 'example-info grade'); } // button to assess diff --git a/mod/workshop/submission.php b/mod/workshop/submission.php index d3fcbff65af..4bad65ba90c 100644 --- a/mod/workshop/submission.php +++ b/mod/workshop/submission.php @@ -64,7 +64,8 @@ $cansubmit = has_capability('mod/workshop:submit', $workshop->context); $canallocate = has_capability('mod/workshop:allocate', $workshop->context); $canpublish = has_capability('mod/workshop:publishsubmissions', $workshop->context); $canoverride = (($workshop->phase == workshop::PHASE_EVALUATION) and has_capability('mod/workshop:overridegrades', $workshop->context)); -$isreviewer = $DB->record_exists('workshop_assessments', array('submissionid' => $submission->id, 'reviewerid' => $USER->id)); +$userassessment = $workshop->get_assessment_of_submission_by_user($submission->id, $USER->id); +$isreviewer = !empty($userassessment); $editable = ($cansubmit and $ownsubmission and $workshop->submitting_allowed()); if ($editable and $workshop->useexamples and $workshop->examplesmode == workshop::EXAMPLES_BEFORE_SUBMISSION and !has_capability('mod/workshop:manageexamples', $workshop->context)) { @@ -213,28 +214,62 @@ if ($submission->id and !$edit and !$isreviewer and $canallocate and $workshop-> // and possibly display the submission's review(s) -$canviewallassessments = false; -if (has_capability('mod/workshop:viewallassessments', $PAGE->context)) { - $canviewallassessments = true; -} elseif ($ownsubmission and $workshop->assessments_available()) { - $canviewallassessments = true; -} - -$canviewgrades = false; if ($isreviewer) { - $canviewgrades = true; // reviewers can always see the grades they gave even they are not available yet -} elseif ($ownsubmission or $canviewallassessments) { - $canviewgrades = $workshop->grades_available(); // bool|null, see the function phpdoc + $strategy = $workshop->grading_strategy_instance(); + $mform = $strategy->get_assessment_form($PAGE->url, 'assessment', $userassessment, false); + echo $OUTPUT->heading(get_string('assessmentbyyourself', 'workshop'), 2); + // reviewers can always see the grades they gave even they are not available yet + if (is_null($userassessment->grade)) { + echo $OUTPUT->heading(get_string('notassessed', 'workshop'), 3); + if ($workshop->assessing_allowed()) { + echo $OUTPUT->single_button($workshop->assess_url($userassessment->id), get_string('assess', 'workshop'), 'get'); + } + } else { + $a = new stdclass(); + $a->max = $workshop->real_grade(100); + $a->received = $workshop->real_grade($userassessment->grade); + echo $OUTPUT->heading(get_string('gradeinfo', 'workshop', $a), 3); + if ($userassessment->weight != 1) { + echo $OUTPUT->heading(get_string('weightinfo', 'workshop', $userassessment->weight), 3); + } + if ($workshop->assessing_allowed()) { + echo $OUTPUT->single_button($workshop->assess_url($userassessment->id), get_string('reassess', 'workshop'), 'get'); + } + $mform->display(); + } } -if ($isreviewer) { - // display own assessment - todo - $strategy = $workshop->grading_strategy_instance(); -} - -if ($canviewallassessments) { - // display all assessments (except the eventual own one - that has been already displayed) - todo +if (has_capability('mod/workshop:viewallassessments', $workshop->context) or ($ownsubmission and $workshop->assessments_available())) { $strategy = $workshop->grading_strategy_instance(); + $assessments = $workshop->get_assessments_of_submission($submission->id); + $canviewreviewernames = has_capability('mod/workshop:viewreviewernames', $workshop->context); + foreach ($assessments as $assessment) { + if ($assessment->reviewerid == $USER->id) { + // own assessment has been displayed already + continue; + } + if (is_null($assessment->grade)) { + // not graded assessment are not displayed + continue; + } + if ($canviewreviewernames) { + $reviewer = new stdclass(); + $reviewer->firstname = $assessment->reviewerfirstname; + $reviewer->lastname = $assessment->reviewerlastname; + echo $OUTPUT->heading(get_string('assessmentbyknown', 'workshop', fullname($reviewer)), 2); + } else { + echo $OUTPUT->heading(get_string('assessmentbyunknown', 'workshop'), 2); + } + $a = new stdclass(); + $a->max = $workshop->real_grade(100); + $a->received = $workshop->real_grade($assessment->grade); + echo $OUTPUT->heading(get_string('gradeinfo', 'workshop', $a), 3); + if ($assessment->weight != 1) { + echo $OUTPUT->heading(get_string('weightinfo', 'workshop', $assessment->weight), 3); + } + $mform = $strategy->get_assessment_form($PAGE->url, 'assessment', $assessment, false); + $mform->display(); + } } if (!$edit and $canoverride) { diff --git a/mod/workshop/view.php b/mod/workshop/view.php index 4d12cb094e4..7e8a007c132 100644 --- a/mod/workshop/view.php +++ b/mod/workshop/view.php @@ -360,6 +360,37 @@ case workshop::PHASE_EVALUATION: } break; case workshop::PHASE_CLOSED: + if (has_capability('mod/workshop:viewallassessments', $PAGE->context)) { + $page = optional_param('page', 0, PARAM_INT); + $sortby = optional_param('sortby', 'lastname', PARAM_ALPHA); + $sorthow = optional_param('sorthow', 'ASC', PARAM_ALPHA); + $perpage = 10; // todo let the user modify this + $groups = ''; // todo let the user choose the group + $PAGE->set_url($PAGE->url, compact('sortby', 'sorthow', 'page')); // TODO: this is suspicious + $data = $workshop->prepare_grading_report($USER->id, $groups, $page, $perpage, $sortby, $sorthow); + if ($data) { + $showauthornames = has_capability('mod/workshop:viewauthornames', $workshop->context); + $showreviewernames = has_capability('mod/workshop:viewreviewernames', $workshop->context); + + // prepare paging bar + $pagingbar = new paging_bar($data->totalcount, $page, $perpage, $PAGE->url, 'page'); + + // grading report display options + $reportopts = new stdclass(); + $reportopts->showauthornames = $showauthornames; + $reportopts->showreviewernames = $showreviewernames; + $reportopts->sortby = $sortby; + $reportopts->sorthow = $sorthow; + $reportopts->showsubmissiongrade = true; + $reportopts->showgradinggrade = true; + + print_collapsible_region_start('', 'workshop-viewlet-gradereport', get_string('gradesreport', 'workshop')); + echo $output->render($pagingbar); + echo $output->grading_report($data, $reportopts); + echo $output->render($pagingbar); + print_collapsible_region_end(); + } + } if (has_capability('mod/workshop:viewpublishedsubmissions', $workshop->context)) { if ($submissions = $workshop->get_published_submissions()) { print_collapsible_region_start('', 'workshop-viewlet-publicsubmissions', get_string('publishedsubmissions', 'workshop'));