From 3675dbc32b1b567ead4547e8e58c66aab5f73ba6 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Wed, 27 Jul 2011 19:15:41 +0200 Subject: [PATCH 1/6] MDL-27550 workshop: display the feedback for the submission author when the workshop is closed The method user_picture::fields() was not available when these SQL statements were originally written. Now instead of hard-coding the list of returned fields, the user_picture is asked for the list. Together with this change, methods workshop::get_submission_by_id() and workshop::get_submission_by_author() now return the information about the user who provided the feedback and overwrote the grade. --- mod/workshop/lang/en/workshop.php | 1 + mod/workshop/locallib.php | 106 +++++++++++++++++++++++++----- mod/workshop/renderer.php | 24 +++++++ mod/workshop/styles.css | 33 +++++++++- mod/workshop/submission.php | 6 ++ mod/workshop/view.php | 5 ++ 6 files changed, 157 insertions(+), 18 deletions(-) diff --git a/mod/workshop/lang/en/workshop.php b/mod/workshop/lang/en/workshop.php index b3679e27b72..3944a35c1aa 100644 --- a/mod/workshop/lang/en/workshop.php +++ b/mod/workshop/lang/en/workshop.php @@ -113,6 +113,7 @@ $string['examplesmode'] = 'Mode of examples assessment'; $string['examplesubmissions'] = 'Example submissions'; $string['examplesvoluntary'] = 'Assessment of example submission is voluntary'; $string['feedbackauthor'] = 'Feedback for the author'; +$string['feedbackby'] = 'Feedback by {$a}'; $string['feedbackreviewer'] = 'Feedback for the reviewer'; $string['formataggregatedgrade'] = '{$a->grade}'; $string['formataggregatedgradeover'] = '{$a->grade}
{$a->over}'; diff --git a/mod/workshop/locallib.php b/mod/workshop/locallib.php index 99ebb3a4ef0..4480bc962ca 100644 --- a/mod/workshop/locallib.php +++ b/mod/workshop/locallib.php @@ -489,16 +489,15 @@ class workshop { public function get_submissions($authorid='all') { global $DB; - $sql = 'SELECT s.id, s.workshopid, s.example, s.authorid, s.timecreated, s.timemodified, + $authorfields = user_picture::fields('u', null, 'authoridx', 'author'); + $gradeoverbyfields = user_picture::fields('t', null, 'gradeoverbyx', 'over'); + $sql = "SELECT s.id, s.workshopid, s.example, s.authorid, s.timecreated, s.timemodified, s.title, s.grade, s.gradeover, s.gradeoverby, s.published, - u.lastname AS authorlastname, u.firstname AS authorfirstname, - u.picture AS authorpicture, u.imagealt AS authorimagealt, u.email AS authoremail, - t.lastname AS overlastname, t.firstname AS overfirstname, - t.picture AS overpicture, t.imagealt AS overimagealt, t.email AS overemail + $authorfields, $gradeoverbyfields FROM {workshop_submissions} s INNER JOIN {user} u ON (s.authorid = u.id) LEFT JOIN {user} t ON (s.gradeoverby = t.id) - WHERE s.example = 0 AND s.workshopid = :workshopid'; + WHERE s.example = 0 AND s.workshopid = :workshopid"; $params = array('workshopid' => $this->id); if ('all' === $authorid) { @@ -511,7 +510,7 @@ class workshop { // $authorid is empty return array(); } - $sql .= ' ORDER BY u.lastname, u.firstname'; + $sql .= " ORDER BY u.lastname, u.firstname"; return $DB->get_records_sql($sql, $params); } @@ -527,12 +526,13 @@ class workshop { // we intentionally check the workshopid here, too, so the workshop can't touch submissions // from other instances - $sql = 'SELECT s.*, - u.lastname AS authorlastname, u.firstname AS authorfirstname, u.id AS authorid, - u.picture AS authorpicture, u.imagealt AS authorimagealt, u.email AS authoremail + $authorfields = user_picture::fields('u', null, 'authoridx', 'author'); + $gradeoverbyfields = user_picture::fields('g', null, 'gradeoverbyx', 'gradeoverby'); + $sql = "SELECT s.*, $authorfields, $gradeoverbyfields FROM {workshop_submissions} s INNER JOIN {user} u ON (s.authorid = u.id) - WHERE s.example = 0 AND s.workshopid = :workshopid AND s.id = :id'; + LEFT JOIN {user} g ON (s.gradeoverby = g.id) + WHERE s.example = 0 AND s.workshopid = :workshopid AND s.id = :id"; $params = array('workshopid' => $this->id, 'id' => $id); return $DB->get_record_sql($sql, $params, MUST_EXIST); } @@ -549,12 +549,13 @@ class workshop { if (empty($authorid)) { return false; } - $sql = 'SELECT s.*, - u.lastname AS authorlastname, u.firstname AS authorfirstname, u.id AS authorid, - u.picture AS authorpicture, u.imagealt AS authorimagealt, u.email AS authoremail + $authorfields = user_picture::fields('u', null, 'authoridx', 'author'); + $gradeoverbyfields = user_picture::fields('g', null, 'gradeoverbyx', 'gradeoverby'); + $sql = "SELECT s.*, $authorfields, $gradeoverbyfields FROM {workshop_submissions} s INNER JOIN {user} u ON (s.authorid = u.id) - WHERE s.example = 0 AND s.workshopid = :workshopid AND s.authorid = :authorid'; + LEFT JOIN {user} g ON (s.gradeoverby = g.id) + WHERE s.example = 0 AND s.workshopid = :workshopid AND s.authorid = :authorid"; $params = array('workshopid' => $this->id, 'authorid' => $authorid); return $DB->get_record_sql($sql, $params); } @@ -567,10 +568,10 @@ class workshop { public function get_published_submissions($orderby='finalgrade DESC') { global $DB; + $authorfields = user_picture::fields('u', null, 'authoridx', 'author'); $sql = "SELECT s.id, s.authorid, s.timecreated, s.timemodified, s.title, s.grade, s.gradeover, COALESCE(s.gradeover,s.grade) AS finalgrade, - u.lastname AS authorlastname, u.firstname AS authorfirstname, u.id AS authorid, - u.picture AS authorpicture, u.imagealt AS authorimagealt, u.email AS authoremail + $authorfields FROM {workshop_submissions} s INNER JOIN {user} u ON (s.authorid = u.id) WHERE s.example = 0 AND s.workshopid = :workshopid AND s.published = 1 @@ -2786,3 +2787,74 @@ class workshop_grading_report implements renderable { return $this->options; } } + + +/** + * Base class for renderable feedback for author and feedback for reviewer + */ +abstract class workshop_feedback { + + /** @var stdClass the user info */ + protected $provider = null; + + /** @var string the feedback text */ + protected $content = null; + + /** @var int format of the feedback text */ + protected $format = null; + + /** + * @return stdClass the user info + */ + public function get_provider() { + + if (is_null($this->provider)) { + throw new coding_exception('Feedback provider not set'); + } + + return $this->provider; + } + + /** + * @return string the feedback text + */ + public function get_content() { + + if (is_null($this->content)) { + throw new coding_exception('Feedback content not set'); + } + + return $this->content; + } + + /** + * @return int format of the feedback text + */ + public function get_format() { + + if (is_null($this->format)) { + throw new coding_exception('Feedback text format not set'); + } + + return $this->format; + } +} + + +/** + * Renderable feedback for the author of submission + */ +class workshop_feedback_author extends workshop_feedback implements renderable { + + /** + * Extracts feedback from the given submission record + * + * @param stdClass $submission record as returned by {@see self::get_submission_by_id()} + */ + public function __construct(stdClass $submission) { + + $this->provider = user_picture::unalias($submission, null, 'gradeoverbyx', 'gradeoverby'); + $this->content = $submission->feedbackauthor; + $this->format = $submission->feedbackauthorformat; + } +} diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php index 1b1333e5e7f..22b24191bb7 100644 --- a/mod/workshop/renderer.php +++ b/mod/workshop/renderer.php @@ -490,6 +490,30 @@ class mod_workshop_renderer extends plugin_renderer_base { return html_writer::table($table); } + /** + * Renders the feedback for the author of the submission + * + * @param workshop_feedback_author $feedback + * @return string HTML + */ + protected function render_workshop_feedback_author(workshop_feedback_author $feedback) { + + $o = ''; // output HTML code + $o .= $this->output->container_start('feedback feedbackforauthor'); + $o .= $this->output->container_start('header'); + $o .= $this->output->heading(get_string('feedbackby', 'workshop', s(fullname($feedback->get_provider()))), 3, 'title'); + + $userpic = $this->output->user_picture($feedback->get_provider(), array('courseid' => $this->page->course->id, 'size' => 32)); + $o .= $this->output->container($userpic, 'picture'); + $o .= $this->output->container_end(); // end of header + + $content = format_text($feedback->get_content(), $feedback->get_format(), array('overflowdiv' => true)); + $o .= $this->output->container($content, 'content'); + + $o .= $this->output->container_end(); // end of submission-full + + return $o; + } //////////////////////////////////////////////////////////////////////////// // Internal rendering helper methods diff --git a/mod/workshop/styles.css b/mod/workshop/styles.css index 22c48513451..e160e517252 100644 --- a/mod/workshop/styles.css +++ b/mod/workshop/styles.css @@ -45,7 +45,8 @@ .path-mod-workshop .submission-summary.anonymous .title, .path-mod-workshop .submission-summary.anonymous .author, -.path-mod-workshop .submission-summary.anonymous .userdate { +.path-mod-workshop .submission-summary.anonymous .userdate, +.path-mod-workshop .submission-summary.anonymous .grade-status { margin: 0px 0px 0px 5px; } @@ -395,6 +396,36 @@ vertical-align: top; } +/** + * Feedback + */ +.path-mod-workshop .feedback { + border: 1px solid #ddd; + margin: 0px auto 1em auto; + width: 80%; +} + +.path-mod-workshop .feedback .header { + position: relative; + background-color: #ddd; + padding: 3px; + min-height: 35px; +} + +.path-mod-workshop .feedback .header .title { + margin: 0px 0px 0px 40px; +} + +.path-mod-workshop .feedback .header .picture { + position: absolute; + top: 3px; + left: 3px; +} + +.path-mod-workshop .feedback .content { + padding: 5px 10px; +} + /** * Misc */ diff --git a/mod/workshop/submission.php b/mod/workshop/submission.php index 81b5e9a8226..36d8ee316cb 100644 --- a/mod/workshop/submission.php +++ b/mod/workshop/submission.php @@ -272,6 +272,12 @@ if ($submission->id and !$edit and !$isreviewer and $canallocate and $workshop-> echo $output->single_button($url, get_string('assess', 'workshop'), 'post'); } +if (($workshop->phase == workshop::PHASE_CLOSED) and ($ownsubmission or $canviewall)) { + if (!empty($submission->gradeoverby) and strlen(trim($submission->feedbackauthor)) > 0) { + echo $output->render(new workshop_feedback_author($submission)); + } +} + // and possibly display the submission's review(s) if ($isreviewer) { diff --git a/mod/workshop/view.php b/mod/workshop/view.php index 7edceb54afc..2ab477be697 100644 --- a/mod/workshop/view.php +++ b/mod/workshop/view.php @@ -493,6 +493,11 @@ case workshop::PHASE_CLOSED: echo $output->container(get_string('noyoursubmission', 'workshop')); } echo $output->box_end(); + + if (!empty($submission->gradeoverby) and strlen(trim($submission->feedbackauthor)) > 0) { + echo $output->render(new workshop_feedback_author($submission)); + } + print_collapsible_region_end(); } if (has_capability('mod/workshop:viewpublishedsubmissions', $workshop->context)) { From c9f31ba3a3832632772cd026ac65b74ff1b07000 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Thu, 28 Jul 2011 15:41:56 +0200 Subject: [PATCH 2/6] MDL-27550 workshop: assessments are now displayed via proper rendering subsystem AMOS BEGIN MOV [assessmentbyknown,mod_workshop],[assessmentbyfullname,mod_workshop] AMOS END --- mod/workshop/assessment.php | 37 +++--- mod/workshop/exassessment.php | 47 +++++-- mod/workshop/excompare.php | 56 +++++---- mod/workshop/lang/en/workshop.php | 7 +- mod/workshop/lib.php | 4 +- mod/workshop/locallib.php | 203 ++++++++++++++++++++++++++---- mod/workshop/renderer.php | 98 +++++++++++++++ mod/workshop/styles.css | 65 +++++++++- mod/workshop/submission.php | 86 ++++++------- 9 files changed, 474 insertions(+), 129 deletions(-) diff --git a/mod/workshop/assessment.php b/mod/workshop/assessment.php index e747b2c9f63..25c62ffb946 100644 --- a/mod/workshop/assessment.php +++ b/mod/workshop/assessment.php @@ -182,24 +182,33 @@ if (trim($workshop->instructreviewers)) { print_collapsible_region_end(); } +// extend the current assessment record with user details +$assessment = $workshop->get_assessment_by_id($assessment->id); + if ($isreviewer) { - echo $output->heading(get_string('assessmentbyyourself', 'workshop'), 2); -} elseif (has_capability('mod/workshop:viewreviewernames', $workshop->context)) { - $assessment = $workshop->get_assessment_by_id($assessment->id); // extend the current record with user details - $reviewer = new stdclass(); - $reviewer->firstname = $assessment->reviewerfirstname; - $reviewer->lastname = $assessment->reviewerlastname; - echo $output->heading(get_string('assessmentbyknown', 'workshop', fullname($reviewer)), 2); + $options = array( + 'showreviewer' => true, + 'showauthor' => has_capability('mod/workshop:viewauthornames', $workshop->context), + 'showform' => $assessmenteditable or !is_null($assessment->grade), + 'showweight' => true, + ); + $assessment = $workshop->prepare_assessment($assessment, $mform, $options); + $assessment->title = get_string('assessmentbyyourself', 'workshop'); + echo $output->render($assessment); + } else { - echo $output->heading(get_string('assessmentbyunknown', 'workshop'), 2); + $options = array( + 'showreviewer' => has_capability('mod/workshop:viewreviewernames', $workshop->context), + 'showauthor' => has_capability('mod/workshop:viewauthornames', $workshop->context), + 'showform' => $assessmenteditable or !is_null($assessment->grade), + 'showweight' => true, + ); + $assessment = $workshop->prepare_assessment($assessment, $mform, $options); + echo $output->render($assessment); } -if ($mform) { - $mform->display(); -} else { - echo $output->heading(get_string('notassessed', 'workshop')); -} -if ($canoverridegrades) { +if (!$assessmenteditable and $canoverridegrades) { $feedbackform->display(); } + echo $output->footer(); diff --git a/mod/workshop/exassessment.php b/mod/workshop/exassessment.php index aee2e4179d2..a487dff2de4 100644 --- a/mod/workshop/exassessment.php +++ b/mod/workshop/exassessment.php @@ -56,7 +56,7 @@ if ($isreviewer or $canmanage) { } // only the reviewer is allowed to modify the assessment -if ($canmanage or ($isreviewer and $workshop->assessing_examples_allowed())) { +if (($canmanage and $assessment->weight == 1) or ($isreviewer and $workshop->assessing_examples_allowed())) { $assessmenteditable = true; } else { $assessmenteditable = false; @@ -119,17 +119,40 @@ if (trim($workshop->instructreviewers)) { print_collapsible_region_end(); } -if ($canmanage) { - echo $output->heading(get_string('assessmentreference', 'workshop'), 2); -} elseif ($isreviewer) { - echo $output->heading(get_string('assessmentbyyourself', 'workshop'), 2); -} else { - $assessment = $workshop->get_assessment_by_id($assessment->id); // extend the current record with user details - $reviewer = new stdclass(); - $reviewer->firstname = $assessment->reviewerfirstname; - $reviewer->lastname = $assessment->reviewerlastname; - echo $output->heading(get_string('assessmentbyknown', 'workshop', fullname($reviewer)), 2); +// extend the current assessment record with user details +$assessment = $workshop->get_assessment_by_id($assessment->id); + +if ($canmanage and $assessment->weight == 1) { + $options = array( + 'showreviewer' => false, + 'showauthor' => false, + 'showform' => true, + 'showweight' => false, + ); + $assessment = $workshop->prepare_assessment($assessment, $mform, $options); + $assessment->title = get_string('assessmentreference', 'workshop'); + echo $output->render($assessment); + +} else if ($isreviewer) { + $options = array( + 'showreviewer' => true, + 'showauthor' => false, + 'showform' => true, + 'showweight' => false, + ); + $assessment = $workshop->prepare_assessment($assessment, $mform, $options); + $assessment->title = get_string('assessmentbyyourself', 'workshop'); + echo $output->render($assessment); + +} else if ($canmanage) { + $options = array( + 'showreviewer' => true, + 'showauthor' => false, + 'showform' => true, + 'showweight' => false, + ); + $assessment = $workshop->prepare_assessment($assessment, $mform, $options); + echo $output->render($assessment); } -$mform->display(); echo $output->footer(); diff --git a/mod/workshop/excompare.php b/mod/workshop/excompare.php index 56628605de3..126fc040050 100644 --- a/mod/workshop/excompare.php +++ b/mod/workshop/excompare.php @@ -78,33 +78,45 @@ echo $output->heading(get_string('assessedexample', 'workshop'), 2); echo $output->render($workshop->prepare_example_submission($example)); +// if the reference assessment is available, display it if (!empty($mformreference)) { - echo $output->heading(get_string('assessmentreference', 'workshop'), 2); - $a = new stdclass(); - $a->received = $workshop->real_grade($reference->grade); - $a->max = $workshop->real_grade(100); - echo $output->heading(get_string('gradeinfo', 'workshop' , $a), 3); - $mformreference->display(); + $options = array( + 'showreviewer' => false, + 'showauthor' => false, + 'showform' => true, + 'showweight' => false, + ); + $reference = $workshop->prepare_assessment($reference, $mformreference, $options); + $reference->title = get_string('assessmentreference', 'workshop'); + echo $output->render($reference); } if ($isreviewer) { - echo $output->heading(get_string('assessmentbyyourself', 'workshop'), 2); + $options = array( + 'showreviewer' => true, + 'showauthor' => false, + 'showform' => true, + 'showweight' => false, + ); + $assessment = $workshop->prepare_assessment($assessment, $mformassessment, $options); + $assessment->title = get_string('assessmentbyyourself', 'workshop'); + if ($workshop->assessing_examples_allowed()) { + $assessment->add_action( + new moodle_url($workshop->exsubmission_url($example->id), array('assess' => 'on', 'sesskey' => sesskey())), + get_string('reassess', 'workshop') + ); + } + echo $output->render($assessment); + } elseif ($canmanage) { - $reviewer = new stdclass(); - $reviewer->firstname = $assessment->reviewerfirstname; - $reviewer->lastname = $assessment->reviewerlastname; - echo $output->heading(get_string('assessmentbyknown', 'workshop', fullname($reviewer)), 2); + $options = array( + 'showreviewer' => true, + 'showauthor' => false, + 'showform' => true, + 'showweight' => false, + ); + $assessment = $workshop->prepare_assessment($assessment, $mformassessment, $options); + echo $output->render($assessment); } -$a = new stdclass(); -$a->received = $workshop->real_grade($assessment->grade); -$a->max = $workshop->real_grade(100); -echo $output->heading(get_string('gradeinfo', 'workshop' , $a), 3); -$mformassessment->display(); -echo $output->container_start('buttonsbar'); -if ($isreviewer and $workshop->assessing_examples_allowed()) { - $aurl = new moodle_url($workshop->exsubmission_url($example->id), array('assess' => 'on', 'sesskey' => sesskey())); - echo $output->single_button($aurl, get_string('reassess', 'workshop'), 'get'); -} -echo $output->container_end(); // buttonsbar echo $output->footer(); diff --git a/mod/workshop/lang/en/workshop.php b/mod/workshop/lang/en/workshop.php index 3944a35c1aa..239abbac7a6 100644 --- a/mod/workshop/lang/en/workshop.php +++ b/mod/workshop/lang/en/workshop.php @@ -43,9 +43,10 @@ $string['assessedexample'] = 'Assessed example submission'; $string['assessedsubmission'] = 'Assessed submission'; $string['assessingexample'] = 'Assessing example submission'; $string['assessingsubmission'] = 'Assessing submission'; -$string['assessmentbyknown'] = 'Assessment by {$a}'; -$string['assessmentbyunknown'] = 'Assessment'; -$string['assessmentbyyourself'] = 'Assessment by yourself'; +$string['assessment'] = 'Assessment'; +$string['assessmentby'] = 'by {$a->name}'; +$string['assessmentbyfullname'] = 'Assessment by {$a}'; +$string['assessmentbyyourself'] = 'Your assessment'; $string['assessmentdeleted'] = 'Assessment deallocated'; $string['assessmentend'] = 'Deadline for assessment'; $string['assessmentenddatetime'] = 'Assessment deadline: {$a->daydatetime} ({$a->distanceday})'; diff --git a/mod/workshop/lib.php b/mod/workshop/lib.php index 83aded85c2d..4962c45720c 100644 --- a/mod/workshop/lib.php +++ b/mod/workshop/lib.php @@ -862,12 +862,12 @@ function workshop_print_recent_mod_activity($activity, $courseid, $detail, $modn $url = new moodle_url('/user/view.php', array('id'=>$activity->user->id, 'course'=>$courseid)); $name = fullname($activity->user); $link = html_writer::link($url, $name); - echo get_string('assessmentbyknown', 'workshop', $link); + echo get_string('assessmentbyfullname', 'workshop', $link); echo ' - '.userdate($activity->timestamp); echo html_writer::end_tag('div'); } else { echo html_writer::start_tag('div', array('class'=>'anonymous')); - echo get_string('assessmentbyunknown', 'workshop'); + echo get_string('assessment', 'workshop'); echo ' - '.userdate($activity->timestamp); echo html_writer::end_tag('div'); } diff --git a/mod/workshop/locallib.php b/mod/workshop/locallib.php index 4480bc962ca..ae6ad22b071 100644 --- a/mod/workshop/locallib.php +++ b/mod/workshop/locallib.php @@ -706,6 +706,44 @@ class workshop { return $summary; } + /** + * Prepares renderable assessment component + * + * The $options array supports the following keys: + * showauthor - should the author user info be available for the renderer + * showreviewer - should the reviewer user info be available for the renderer + * showform - show the assessment form if it is available + * + * @param stdClass $record as returned by eg {@link self::get_assessment_by_id()} + * @param workshop_assessment_form|null $form as returned by {@link workshop_strategy::get_assessment_form()} + * @param array $options + * @return workshop_assessment + */ + public function prepare_assessment(stdClass $record, $form, array $options = array()) { + + $assessment = new workshop_assessment($record, $options); + $assessment->url = $this->assess_url($record->id); + $assessment->maxgrade = $this->real_grade(100); + + if (!empty($options['showform']) and !($form instanceof workshop_assessment_form)) { + debugging('Not a valid instance of workshop_assessment_form supplied', DEBUG_DEVELOPER); + } + + if (!empty($options['showform']) and ($form instanceof workshop_assessment_form)) { + $assessment->form = $form; + } + + if (empty($options['showweight'])) { + $assessment->weight = null; + } + + if (!is_null($record->grade)) { + $assessment->realgrade = $this->real_grade($record->grade); + } + + return $assessment; + } + /** * Removes the submission and all relevant data * @@ -731,17 +769,18 @@ class workshop { public function get_all_assessments() { global $DB; - $sql = 'SELECT a.id, a.submissionid, a.reviewerid, a.timecreated, a.timemodified, + $reviewerfields = user_picture::fields('reviewer', null, 'revieweridx', 'reviewer'); + $authorfields = user_picture::fields('author', null, 'authorid', 'author'); + $sql = "SELECT a.id, a.submissionid, a.reviewerid, a.timecreated, a.timemodified, a.grade, a.gradinggrade, a.gradinggradeover, a.gradinggradeoverby, - 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 + $reviewerfields, $authorfields, + s.title FROM {workshop_assessments} a INNER JOIN {user} reviewer ON (a.reviewerid = reviewer.id) INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id) INNER JOIN {user} author ON (s.authorid = author.id) WHERE s.workshopid = :workshopid AND s.example = 0 - ORDER BY reviewer.lastname, reviewer.firstname'; + ORDER BY reviewer.lastname, reviewer.firstname"; $params = array('workshopid' => $this->id); return $DB->get_records_sql($sql, $params); @@ -756,15 +795,14 @@ class workshop { public function get_assessment_by_id($id) { 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 + $reviewerfields = user_picture::fields('reviewer', null, 'revieweridx', 'reviewer'); + $authorfields = user_picture::fields('author', null, 'authorid', 'author'); + $sql = "SELECT a.*, s.title, $reviewerfields, $authorfields FROM {workshop_assessments} a INNER JOIN {user} reviewer ON (a.reviewerid = reviewer.id) INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id) INNER JOIN {user} author ON (s.authorid = author.id) - WHERE a.id = :id AND s.workshopid = :workshopid'; + WHERE a.id = :id AND s.workshopid = :workshopid"; $params = array('id' => $id, 'workshopid' => $this->id); return $DB->get_record_sql($sql, $params, MUST_EXIST); @@ -780,15 +818,14 @@ class workshop { 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 + $reviewerfields = user_picture::fields('reviewer', null, 'revieweridx', 'reviewer'); + $authorfields = user_picture::fields('author', null, 'authorid', 'author'); + $sql = "SELECT a.*, s.title, $reviewerfields, $authorfields 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'; + 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); @@ -803,12 +840,13 @@ class workshop { public function get_assessments_of_submission($submissionid) { global $DB; - $sql = 'SELECT a.*, - reviewer.id AS reviewerid,reviewer.firstname AS reviewerfirstname,reviewer.lastname AS reviewerlastname + $reviewerfields = user_picture::fields('reviewer', null, 'revieweridx', 'reviewer'); + $sql = "SELECT a.*, s.title, $reviewerfields 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'; + WHERE s.example = 0 AND s.id = :submissionid AND s.workshopid = :workshopid + ORDER BY reviewer.lastname, reviewer.firstname, reviewer.id"; $params = array('submissionid' => $submissionid, 'workshopid' => $this->id); return $DB->get_records_sql($sql, $params); @@ -823,17 +861,16 @@ class workshop { public function get_assessments_by_reviewer($reviewerid) { global $DB; - $sql = 'SELECT a.*, - reviewer.id AS reviewerid,reviewer.firstname AS reviewerfirstname,reviewer.lastname AS reviewerlastname, + $reviewerfields = user_picture::fields('reviewer', null, 'revieweridx', 'reviewer'); + $authorfields = user_picture::fields('author', null, 'authorid', 'author'); + $sql = "SELECT a.*, $reviewerfields, $authorfields, s.id AS submissionid, s.title AS submissiontitle, s.timecreated AS submissioncreated, - s.timemodified AS submissionmodified, - author.id AS authorid, author.firstname AS authorfirstname,author.lastname AS authorlastname, - author.picture AS authorpicture, author.imagealt AS authorimagealt, author.email AS authoremail + s.timemodified AS submissionmodified FROM {workshop_assessments} a INNER JOIN {user} reviewer ON (a.reviewerid = reviewer.id) INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id) INNER JOIN {user} author ON (s.authorid = author.id) - WHERE s.example = 0 AND reviewer.id = :reviewerid AND s.workshopid = :workshopid'; + WHERE s.example = 0 AND reviewer.id = :reviewerid AND s.workshopid = :workshopid"; $params = array('reviewerid' => $reviewerid, 'workshopid' => $this->id); return $DB->get_records_sql($sql, $params); @@ -2593,6 +2630,124 @@ class workshop_example_submission extends workshop_example_submission_summary im protected $fields = array('id', 'title', 'content', 'contentformat', 'contenttrust', 'attachment'); } + +/** + * Common base class for assessments rendering + * + * Subclasses of this class convert raw assessment record from + * workshop_assessments table (as returned by {@see workshop::get_assessment_by_id()} + * for example) into renderable objects. + */ +abstract class workshop_assessment_base { + + /** @var string the optional title of the assessment */ + public $title = ''; + + /** @var workshop_assessment_form $form as returned by {@link workshop_strategy::get_assessment_form()} */ + public $form; + + /** @var moodle_url */ + public $url; + + /** @var float|null the real received grade */ + public $realgrade = null; + + /** @var float the real maximum grade */ + public $maxgrade; + + /** @var stdClass|null reviewer user info */ + public $reviewer = null; + + /** @var stdClass|null assessed submission's author user info */ + public $author = null; + + /** @var array of actions */ + public $actions = array(); + + /* @var array of columns that are assigned as properties */ + protected $fields = array(); + + /** + * Copies the properties of the given database record into properties of $this instance + * + * The $options keys are: showreviewer, showauthor + * @param stdClass $assessment full record + * @param array $options additional properties + */ + public function __construct(stdClass $record, array $options = array()) { + + foreach ($this->fields as $field) { + if (!property_exists($record, $field)) { + throw new coding_exception('Assessment record must provide public property ' . $field); + } + if (!property_exists($this, $field)) { + throw new coding_exception('Renderable component must accept public property ' . $field); + } + $this->{$field} = $record->{$field}; + } + + if (!empty($options['showreviewer'])) { + $this->reviewer = user_picture::unalias($record, null, 'revieweridx', 'reviewer'); + } + + if (!empty($options['showauthor'])) { + $this->author = user_picture::unalias($record, null, 'authorid', 'author'); + } + } + + /** + * Adds a new action + * + * @param moodle_url $url action URL + * @param string $label action label + * @param string $method get|post + */ + public function add_action(moodle_url $url, $label, $method = 'get') { + + $action = new stdClass(); + $action->url = $url; + $action->label = $label; + $action->method = $method; + + $this->actions[] = $action; + } +} + + +/** + * Represents a rendarable full assessment + */ +class workshop_assessment extends workshop_assessment_base implements renderable { + + /** @var int */ + public $id; + + /** @var int */ + public $submissionid; + + /** @var int */ + public $weight; + + /** @var int */ + public $timecreated; + + /** @var int */ + public $timemodified; + + /** @var float */ + public $grade; + + /** @var float */ + public $gradinggrade; + + /** @var float */ + public $gradinggradeover; + + /** @var array */ + protected $fields = array('id', 'submissionid', 'weight', 'timecreated', + 'timemodified', 'grade', 'gradinggrade', 'gradinggradeover'); +} + /** * Renderable message to be displayed to the user * diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php index 22b24191bb7..b500d12ef8a 100644 --- a/mod/workshop/renderer.php +++ b/mod/workshop/renderer.php @@ -515,6 +515,88 @@ class mod_workshop_renderer extends plugin_renderer_base { return $o; } + /** + * Renders the full assessment + * + * @param workshop_assessment $assessment + * @return string HTML + */ + protected function render_workshop_assessment(workshop_assessment $assessment) { + + $o = ''; // output HTML code + $anonymous = is_null($assessment->reviewer); + $classes = 'assessment-full'; + if ($anonymous) { + $classes .= ' anonymous'; + } + + $o .= $this->output->container_start($classes); + $o .= $this->output->container_start('header'); + + if (!empty($assessment->title)) { + $o .= $this->output->container(s($assessment->title), 'title'); + } else { + $o .= $this->output->container(get_string('assessment', 'workshop'), 'title'); + } + + if (!$anonymous) { + $reviewer = $assessment->reviewer; + $userpic = $this->output->user_picture($reviewer, array('courseid' => $this->page->course->id, 'size' => 32)); + + $userurl = new moodle_url('/user/view.php', + array('id' => $reviewer->id, 'course' => $this->page->course->id)); + $a = new stdClass(); + $a->name = fullname($reviewer); + $a->url = $userurl->out(); + $byfullname = get_string('assessmentby', 'workshop', $a); + $oo = $this->output->container($userpic, 'picture'); + $oo .= $this->output->container($byfullname, 'fullname'); + + $o .= $this->output->container($oo, 'reviewer'); + } + + if (is_null($assessment->realgrade)) { + $o .= $this->output->container( + get_string('notassessed', 'workshop'), + 'grade nograde' + ); + } else { + $a = new stdClass(); + $a->max = $assessment->maxgrade; + $a->received = $assessment->realgrade; + $o .= $this->output->container( + get_string('gradeinfo', 'workshop', $a), + 'grade' + ); + + if (!is_null($assessment->weight) and $assessment->weight != 1) { + $o .= $this->output->container( + get_string('weightinfo', 'workshop', $assessment->weight), + 'weight' + ); + } + } + + $o .= $this->output->container_start('actions'); + foreach ($assessment->actions as $action) { + $o .= $this->output->single_button($action->url, $action->label, $action->method); + } + $o .= $this->output->container_end(); // actions + + $o .= $this->output->container_end(); // header + + if (!is_null($assessment->form)) { + $o .= print_collapsible_region_start('assessment-form-wrapper', uniqid('workshop-assessment'), + get_string('assessmentform', 'workshop'), '', false, true); + $o .= $this->output->container(self::moodleform($assessment->form), 'assessment-form'); + $o .= print_collapsible_region_end(true); + } + + $o .= $this->output->container_end(); // main wrapper + + return $o; + } + //////////////////////////////////////////////////////////////////////////// // Internal rendering helper methods //////////////////////////////////////////////////////////////////////////// @@ -750,6 +832,22 @@ class mod_workshop_renderer extends plugin_renderer_base { // Static helpers //////////////////////////////////////////////////////////////////////////// + /** + * Helper method dealing with the fact we can not just fetch the output of moodleforms + * + * @param moodleform $mform + * @return string HTML + */ + protected static function moodleform(moodleform $mform) { + + ob_start(); + $mform->display(); + $o = ob_get_contents(); + ob_end_clean(); + + return $o; + } + /** * Helper function returning the n-th item of the array * diff --git a/mod/workshop/styles.css b/mod/workshop/styles.css index e160e517252..aea0cf8f842 100644 --- a/mod/workshop/styles.css +++ b/mod/workshop/styles.css @@ -310,16 +310,75 @@ } /** - * Assessment + * Assessment - full display */ -.path-mod-workshop .assessment-summary.graded { +.path-mod-workshop .assessment-full { + border: 1px solid #ddd; + margin: 0px auto 1em auto; +} + +.path-mod-workshop .assessment-full .header { + position: relative; + background-color: #ddd; + padding: 3px; + min-height: 35px; +} + +.path-mod-workshop .assessment-full .header .title { + font-weight: bold; +} + +.path-mod-workshop .assessment-full .header .title, +.path-mod-workshop .assessment-full .header .reviewer, +.path-mod-workshop .assessment-full .header .grade, +.path-mod-workshop .assessment-full .header .weight { + margin: 0px 0px 0px 40px; +} + +.path-mod-workshop .assessment-full.anonymous .header .title, +.path-mod-workshop .assessment-full.anonymous .header .reviewer, +.path-mod-workshop .assessment-full.anonymous .header .grade, +.path-mod-workshop .assessment-full.anonymous .header .weight { + margin: 0px 0px 0px 5px; +} + +.path-mod-workshop .assessment-full .header .reviewer .picture { + position: absolute; + top: 3px; + left: 3px; +} + +.path-mod-workshop .assessment-full .header .actions { + position: absolute; + top: 5px; + right: 5px; + text-align: right; +} + +.path-mod-workshop .assessment-full .header .actions .singlebutton, +.path-mod-workshop .assessment-full .header .actions .singlebutton form, +.path-mod-workshop .assessment-full .header .actions .singlebutton form div { + display: inline; +} + +.path-mod-workshop .assessment-full .assessment-form-wrapper { + margin-top: 0.5em; + padding: 0px 1em; +} + +.path-mod-workshop .assessment-summary.graded .singlebutton input[type="submit"], +.path-mod-workshop .example-summary.graded .singlebutton input[type="submit"] { background-color: #e7f1c3; } -.path-mod-workshop .example-summary.notgraded { +.path-mod-workshop .assessment-summary.notgraded .singlebutton input[type="submit"], +.path-mod-workshop .example-summary.notgraded .singlebutton input[type="submit"] { background-color: #ffd3d9; } +/** + * Assessment form + */ .path-mod-workshop .assessmentform .description { margin: 0px 1em; } diff --git a/mod/workshop/submission.php b/mod/workshop/submission.php index 36d8ee316cb..ce10708cc84 100644 --- a/mod/workshop/submission.php +++ b/mod/workshop/submission.php @@ -281,66 +281,54 @@ if (($workshop->phase == workshop::PHASE_CLOSED) and ($ownsubmission or $canview // and possibly display the submission's review(s) if ($isreviewer) { - $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->container($output->single_button($workshop->assess_url($userassessment->id), get_string('assess', 'workshop'), 'get'), - array('class' => 'buttonsbar')); + // user's own assessment + $strategy = $workshop->grading_strategy_instance(); + $mform = $strategy->get_assessment_form($PAGE->url, 'assessment', $userassessment, false); + $options = array( + 'showreviewer' => true, + 'showauthor' => $showauthor, + 'showform' => !is_null($userassessment->grade), + 'showweight' => true, + ); + $assessment = $workshop->prepare_assessment($userassessment, $mform, $options); + $assessment->title = get_string('assessmentbyyourself', 'workshop'); + + if ($workshop->assessing_allowed()) { + if (is_null($userassessment->grade)) { + $assessment->add_action($workshop->assess_url($assessment->id), get_string('assess', 'workshop')); + } else { + $assessment->add_action($workshop->assess_url($assessment->id), get_string('reassess', 'workshop')); } - } 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->container($output->single_button($workshop->assess_url($userassessment->id), get_string('reassess', 'workshop'), 'get'), - array('class' => 'buttonsbar')); - } - $mform->display(); } + if ($canoverride) { + $assessment->add_action($workshop->assess_url($assessment->id), get_string('assessmentsettings', 'workshop')); + } + + echo $output->render($assessment); } 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); + // other assessments + $strategy = $workshop->grading_strategy_instance(); + $assessments = $workshop->get_assessments_of_submission($submission->id); + $showreviewer = 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; + $mform = $strategy->get_assessment_form($PAGE->url, 'assessment', $assessment, false); + $options = array( + 'showreviewer' => $showreviewer, + 'showauthor' => $showauthor, + 'showform' => !is_null($assessment->grade), + 'showweight' => true, + ); + $assessment = $workshop->prepare_assessment($assessment, $mform, $options); + if ($canoverride) { + $assessment->add_action($workshop->assess_url($assessment->id), get_string('assessmentsettings', 'workshop')); } - 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); - } - if (has_capability('mod/workshop:overridegrades', $workshop->context)) { - echo $output->container($output->single_button($workshop->assess_url($assessment->id), get_string('assessmentsettings', 'workshop'), 'get'), - array('class' => 'buttonsbar')); - } - $mform = $strategy->get_assessment_form($PAGE->url, 'assessment', $assessment, false); - $mform->display(); + echo $output->render($assessment); } } From 6e6b96d57bea8c3578943a907f84756bc3a32395 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Thu, 28 Jul 2011 22:18:45 +0200 Subject: [PATCH 3/6] MDL-27550 workshop: display the feedback for the submission reviewer when the workshop is closed --- mod/workshop/locallib.php | 39 ++++++++++++++++++++++++++++++++----- mod/workshop/renderer.php | 22 ++++++++++++++++++++- mod/workshop/submission.php | 18 ++++++++++++++--- mod/workshop/view.php | 4 ++++ 4 files changed, 74 insertions(+), 9 deletions(-) diff --git a/mod/workshop/locallib.php b/mod/workshop/locallib.php index ae6ad22b071..77362cd90a6 100644 --- a/mod/workshop/locallib.php +++ b/mod/workshop/locallib.php @@ -771,14 +771,16 @@ class workshop { $reviewerfields = user_picture::fields('reviewer', null, 'revieweridx', 'reviewer'); $authorfields = user_picture::fields('author', null, 'authorid', 'author'); + $overbyfields = user_picture::fields('overby', null, 'gradinggradeoverbyx', 'overby'); $sql = "SELECT a.id, a.submissionid, a.reviewerid, a.timecreated, a.timemodified, a.grade, a.gradinggrade, a.gradinggradeover, a.gradinggradeoverby, - $reviewerfields, $authorfields, + $reviewerfields, $authorfields, $overbyfields, s.title FROM {workshop_assessments} a INNER JOIN {user} reviewer ON (a.reviewerid = reviewer.id) INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id) INNER JOIN {user} author ON (s.authorid = author.id) + LEFT JOIN {user} overby ON (a.gradinggradeoverby = overby.id) WHERE s.workshopid = :workshopid AND s.example = 0 ORDER BY reviewer.lastname, reviewer.firstname"; $params = array('workshopid' => $this->id); @@ -797,11 +799,13 @@ class workshop { $reviewerfields = user_picture::fields('reviewer', null, 'revieweridx', 'reviewer'); $authorfields = user_picture::fields('author', null, 'authorid', 'author'); - $sql = "SELECT a.*, s.title, $reviewerfields, $authorfields + $overbyfields = user_picture::fields('overby', null, 'gradinggradeoverbyx', 'overby'); + $sql = "SELECT a.*, s.title, $reviewerfields, $authorfields, $overbyfields FROM {workshop_assessments} a INNER JOIN {user} reviewer ON (a.reviewerid = reviewer.id) INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id) INNER JOIN {user} author ON (s.authorid = author.id) + LEFT JOIN {user} overby ON (a.gradinggradeoverby = overby.id) WHERE a.id = :id AND s.workshopid = :workshopid"; $params = array('id' => $id, 'workshopid' => $this->id); @@ -820,11 +824,13 @@ class workshop { $reviewerfields = user_picture::fields('reviewer', null, 'revieweridx', 'reviewer'); $authorfields = user_picture::fields('author', null, 'authorid', 'author'); - $sql = "SELECT a.*, s.title, $reviewerfields, $authorfields + $overbyfields = user_picture::fields('overby', null, 'gradinggradeoverbyx', 'overby'); + $sql = "SELECT a.*, s.title, $reviewerfields, $authorfields, $overbyfields 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) + LEFT JOIN {user} overby ON (a.gradinggradeoverby = overby.id) WHERE s.id = :sid AND reviewer.id = :rid AND s.workshopid = :workshopid"; $params = array('sid' => $submissionid, 'rid' => $reviewerid, 'workshopid' => $this->id); @@ -841,10 +847,12 @@ class workshop { global $DB; $reviewerfields = user_picture::fields('reviewer', null, 'revieweridx', 'reviewer'); - $sql = "SELECT a.*, s.title, $reviewerfields + $overbyfields = user_picture::fields('overby', null, 'gradinggradeoverbyx', 'overby'); + $sql = "SELECT a.*, s.title, $reviewerfields, $overbyfields FROM {workshop_assessments} a INNER JOIN {user} reviewer ON (a.reviewerid = reviewer.id) INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id) + LEFT JOIN {user} overby ON (a.gradinggradeoverby = overby.id) WHERE s.example = 0 AND s.id = :submissionid AND s.workshopid = :workshopid ORDER BY reviewer.lastname, reviewer.firstname, reviewer.id"; $params = array('submissionid' => $submissionid, 'workshopid' => $this->id); @@ -863,13 +871,15 @@ class workshop { $reviewerfields = user_picture::fields('reviewer', null, 'revieweridx', 'reviewer'); $authorfields = user_picture::fields('author', null, 'authorid', 'author'); - $sql = "SELECT a.*, $reviewerfields, $authorfields, + $overbyfields = user_picture::fields('overby', null, 'gradinggradeoverbyx', 'overby'); + $sql = "SELECT a.*, $reviewerfields, $authorfields, $overbyfields, s.id AS submissionid, s.title AS submissiontitle, s.timecreated AS submissioncreated, s.timemodified AS submissionmodified FROM {workshop_assessments} a INNER JOIN {user} reviewer ON (a.reviewerid = reviewer.id) INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id) INNER JOIN {user} author ON (s.authorid = author.id) + LEFT JOIN {user} overby ON (a.gradinggradeoverby = overby.id) WHERE s.example = 0 AND reviewer.id = :reviewerid AND s.workshopid = :workshopid"; $params = array('reviewerid' => $reviewerid, 'workshopid' => $this->id); @@ -3013,3 +3023,22 @@ class workshop_feedback_author extends workshop_feedback implements renderable { $this->format = $submission->feedbackauthorformat; } } + + +/** + * Renderable feedback for the reviewer + */ +class workshop_feedback_reviewer extends workshop_feedback implements renderable { + + /** + * Extracts feedback from the given assessment record + * + * @param stdClass $assessment record as returned by eg {@see self::get_assessment_by_id()} + */ + public function __construct(stdClass $assessment) { + + $this->provider = user_picture::unalias($assessment, null, 'gradinggradeoverbyx', 'overby'); + $this->content = $assessment->feedbackreviewer; + $this->format = $assessment->feedbackreviewerformat; + } +} diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php index b500d12ef8a..2dd91bc955a 100644 --- a/mod/workshop/renderer.php +++ b/mod/workshop/renderer.php @@ -497,6 +497,26 @@ class mod_workshop_renderer extends plugin_renderer_base { * @return string HTML */ protected function render_workshop_feedback_author(workshop_feedback_author $feedback) { + return $this->helper_render_feedback($feedback); + } + + /** + * Renders the feedback for the reviewer of the submission + * + * @param workshop_feedback_reviewer $feedback + * @return string HTML + */ + protected function render_workshop_feedback_reviewer(workshop_feedback_reviewer $feedback) { + return $this->helper_render_feedback($feedback); + } + + /** + * Helper method to rendering feedback + * + * @param workshop_feedback_author|workshop_feedback_reviewer $feedback + * @return string HTML + */ + private function helper_render_feedback($feedback) { $o = ''; // output HTML code $o .= $this->output->container_start('feedback feedbackforauthor'); @@ -510,7 +530,7 @@ class mod_workshop_renderer extends plugin_renderer_base { $content = format_text($feedback->get_content(), $feedback->get_format(), array('overflowdiv' => true)); $o .= $this->output->container($content, 'content'); - $o .= $this->output->container_end(); // end of submission-full + $o .= $this->output->container_end(); return $o; } diff --git a/mod/workshop/submission.php b/mod/workshop/submission.php index ce10708cc84..a365f1e0e6b 100644 --- a/mod/workshop/submission.php +++ b/mod/workshop/submission.php @@ -305,6 +305,12 @@ if ($isreviewer) { } echo $output->render($assessment); + + if ($workshop->phase == workshop::PHASE_CLOSED) { + if (strlen(trim($userassessment->feedbackreviewer)) > 0) { + echo $output->render(new workshop_feedback_reviewer($userassessment)); + } + } } if (has_capability('mod/workshop:viewallassessments', $workshop->context) or ($ownsubmission and $workshop->assessments_available())) { @@ -324,11 +330,17 @@ if (has_capability('mod/workshop:viewallassessments', $workshop->context) or ($o 'showform' => !is_null($assessment->grade), 'showweight' => true, ); - $assessment = $workshop->prepare_assessment($assessment, $mform, $options); + $displayassessment = $workshop->prepare_assessment($assessment, $mform, $options); if ($canoverride) { - $assessment->add_action($workshop->assess_url($assessment->id), get_string('assessmentsettings', 'workshop')); + $displayassessment->add_action($workshop->assess_url($assessment->id), get_string('assessmentsettings', 'workshop')); + } + echo $output->render($displayassessment); + + if ($workshop->phase == workshop::PHASE_CLOSED and has_capability('mod/workshop:viewallassessments', $workshop->context)) { + if (strlen(trim($assessment->feedbackreviewer)) > 0) { + echo $output->render(new workshop_feedback_reviewer($assessment)); + } } - echo $output->render($assessment); } } diff --git a/mod/workshop/view.php b/mod/workshop/view.php index 2ab477be697..e278dbe3296 100644 --- a/mod/workshop/view.php +++ b/mod/workshop/view.php @@ -540,6 +540,10 @@ case workshop::PHASE_CLOSED: echo $output->box_start('generalbox assessment-summary' . $class); echo $output->render($workshop->prepare_submission_summary($submission, $shownames)); echo $output->box_end(); + + if (strlen(trim($assessment->feedbackreviewer)) > 0) { + echo $output->render(new workshop_feedback_reviewer($assessment)); + } } print_collapsible_region_end(); } From a6a58c34852d77cfb34909f22b2b936aa044c772 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Thu, 28 Jul 2011 22:30:36 +0200 Subject: [PATCH 4/6] MDL-27550 workshop: students do not see peer-assessment that are not graded yet --- mod/workshop/submission.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mod/workshop/submission.php b/mod/workshop/submission.php index a365f1e0e6b..7d7fe39743a 100644 --- a/mod/workshop/submission.php +++ b/mod/workshop/submission.php @@ -323,6 +323,10 @@ if (has_capability('mod/workshop:viewallassessments', $workshop->context) or ($o // own assessment has been displayed already continue; } + if (is_null($assessment->grade) and !has_capability('mod/workshop:viewallassessments', $workshop->context)) { + // students do not see peer-assessment that are not graded yet + continue; + } $mform = $strategy->get_assessment_form($PAGE->url, 'assessment', $assessment, false); $options = array( 'showreviewer' => $showreviewer, From d98c8aedb2727ac3e73c55aeb1118446e137a865 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Fri, 29 Jul 2011 00:05:26 +0200 Subject: [PATCH 5/6] MDL-27550 workshop: rendering links to the submission and the assessment page This usability improvement helps to provide feedback quickly during the grading evaluation phase. --- mod/workshop/renderer.php | 18 +++++++++++++++--- mod/workshop/submission.php | 6 +++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php index 2dd91bc955a..d0053bb1224 100644 --- a/mod/workshop/renderer.php +++ b/mod/workshop/renderer.php @@ -91,7 +91,14 @@ class mod_workshop_renderer extends plugin_renderer_base { } $o .= $this->output->container_start($classes); $o .= $this->output->container_start('header'); - $o .= $this->output->heading(format_string($submission->title), 3, 'title'); + + $title = $this->output->heading(format_string($submission->title), 3, 'title'); + + if ($this->page->url != $submission->url) { + $o .= html_writer::link($submission->url, $title); + } else { + $o .= $title; + } if (!$anonymous) { $author = new stdclass(); @@ -554,9 +561,14 @@ class mod_workshop_renderer extends plugin_renderer_base { $o .= $this->output->container_start('header'); if (!empty($assessment->title)) { - $o .= $this->output->container(s($assessment->title), 'title'); + $title = s($assessment->title); } else { - $o .= $this->output->container(get_string('assessment', 'workshop'), 'title'); + $title = get_string('assessment', 'workshop'); + } + if ($this->page->url != $assessment->url) { + $o .= $this->output->container(html_writer::link($assessment->url, $title), 'title'); + } else { + $o .= $this->output->container($title, 'title'); } if (!$anonymous) { diff --git a/mod/workshop/submission.php b/mod/workshop/submission.php index 7d7fe39743a..f2c8a1b92af 100644 --- a/mod/workshop/submission.php +++ b/mod/workshop/submission.php @@ -43,7 +43,11 @@ if (isguestuser()) { $workshop = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST); $workshop = new workshop($workshop, $cm, $course); -$PAGE->set_url($workshop->submission_url(), array('cmid' => $cmid, 'id' => $id, 'edit' => $edit)); +$PAGE->set_url($workshop->submission_url(), array('cmid' => $cmid, 'id' => $id)); + +if ($edit) { + $PAGE->url->param('edit', $edit); +} if ($id) { // submission is specified $submission = $workshop->get_submission_by_id($id); From 4ac89c85d4f23b6098f7ca9ac5c5f88e77438117 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Tue, 2 Aug 2011 23:28:52 +0200 Subject: [PATCH 6/6] MDL-27550 workshop: fixed XHTML strictness of H3 and A combo H3 is block level element while A is in-line element in XHTML. Credit goes to Sam Hemelryk for spotting this during the peer-review. --- mod/workshop/renderer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php index d0053bb1224..955a1718087 100644 --- a/mod/workshop/renderer.php +++ b/mod/workshop/renderer.php @@ -92,14 +92,14 @@ class mod_workshop_renderer extends plugin_renderer_base { $o .= $this->output->container_start($classes); $o .= $this->output->container_start('header'); - $title = $this->output->heading(format_string($submission->title), 3, 'title'); + $title = format_string($submission->title); if ($this->page->url != $submission->url) { - $o .= html_writer::link($submission->url, $title); - } else { - $o .= $title; + $title = html_writer::link($submission->url, $title); } + $o .= $this->output->heading($title, 3, 'title'); + if (!$anonymous) { $author = new stdclass(); $author->id = $submission->authorid;