Merge branch 'MDL-27550-workshop-feedback_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE

This commit is contained in:
Eloy Lafuente (stronk7)
2011-08-10 02:49:28 +02:00
10 changed files with 714 additions and 145 deletions
+23 -14
View File
@@ -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();
+35 -12
View File
@@ -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();
+34 -22
View File
@@ -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();
+5 -3
View File
@@ -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 href="{$a->url}">{$a->name}</a>';
$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})';
@@ -113,6 +114,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'] = '<del>{$a->grade}</del><br /><ins>{$a->over}</ins>';
+2 -2
View File
@@ -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');
}
+297 -41
View File
@@ -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
@@ -705,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
*
@@ -730,17 +769,20 @@ 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');
$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,
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, $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';
ORDER BY reviewer.lastname, reviewer.firstname";
$params = array('workshopid' => $this->id);
return $DB->get_records_sql($sql, $params);
@@ -755,15 +797,16 @@ 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');
$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)
WHERE a.id = :id AND s.workshopid = :workshopid';
LEFT JOIN {user} overby ON (a.gradinggradeoverby = overby.id)
WHERE a.id = :id AND s.workshopid = :workshopid";
$params = array('id' => $id, 'workshopid' => $this->id);
return $DB->get_record_sql($sql, $params, MUST_EXIST);
@@ -779,15 +822,16 @@ 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');
$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)
WHERE s.id = :sid AND reviewer.id = :rid AND s.workshopid = :workshopid';
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);
return $DB->get_record_sql($sql, $params, IGNORE_MISSING);
@@ -802,12 +846,15 @@ 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');
$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)
WHERE s.example = 0 AND s.id = :submissionid AND s.workshopid = :workshopid';
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);
return $DB->get_records_sql($sql, $params);
@@ -822,17 +869,18 @@ 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');
$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,
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';
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);
return $DB->get_records_sql($sql, $params);
@@ -2592,6 +2640,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
*
@@ -2786,3 +2952,93 @@ 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;
}
}
/**
* 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;
}
}
+155 -1
View File
@@ -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 = format_string($submission->title);
if ($this->page->url != $submission->url) {
$title = html_writer::link($submission->url, $title);
}
$o .= $this->output->heading($title, 3, 'title');
if (!$anonymous) {
$author = new stdclass();
@@ -490,6 +497,137 @@ 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) {
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');
$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();
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)) {
$title = s($assessment->title);
} else {
$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) {
$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
@@ -726,6 +864,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
*
+94 -4
View File
@@ -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;
}
@@ -309,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;
}
@@ -395,6 +455,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
*/
+60 -46
View File
@@ -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);
@@ -272,69 +276,79 @@ 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) {
$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 ($canoverride) {
$assessment->add_action($workshop->assess_url($assessment->id), get_string('assessmentsettings', 'workshop'));
}
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 ($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 (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
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;
}
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);
$mform = $strategy->get_assessment_form($PAGE->url, 'assessment', $assessment, false);
$options = array(
'showreviewer' => $showreviewer,
'showauthor' => $showauthor,
'showform' => !is_null($assessment->grade),
'showweight' => true,
);
$displayassessment = $workshop->prepare_assessment($assessment, $mform, $options);
if ($canoverride) {
$displayassessment->add_action($workshop->assess_url($assessment->id), get_string('assessmentsettings', 'workshop'));
}
$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);
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));
}
}
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();
}
}
+9
View File
@@ -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)) {
@@ -535,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();
}