MDL-20652 workshop: initial work on example submissions

This commit is contained in:
David Mudrak 2010-01-04 18:27:21 +00:00
parent 0d0b7d99db
commit 81eccf0a36
7 changed files with 373 additions and 20 deletions

177
mod/workshop/example.php Normal file
View File

@ -0,0 +1,177 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* View or edit a single example example
*
* @package mod-workshop
* @copyright 2009 David Mudrak <david.mudrak@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once(dirname(__FILE__).'/lib.php');
require_once(dirname(__FILE__).'/locallib.php');
$cmid = required_param('cmid', PARAM_INT); // course module id
$id = required_param('id', PARAM_INT); // example submission id, 0 for the new one
$edit = optional_param('edit', false, PARAM_BOOL); // open for editing?
$delete = optional_param('delete', false, PARAM_BOOL); // example removal requested
$confirm = optional_param('confirm', false, PARAM_BOOL); // example removal request confirmed
$cm = get_coursemodule_from_id('workshop', $cmid, 0, false, MUST_EXIST);
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
require_login($course, false, $cm);
if (isguestuser()) {
print_error('guestsarenotallowed');
}
$workshop = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST);
$workshop = new workshop($workshop, $cm, $course);
$PAGE->set_url(new moodle_url($workshop->example_url($id), array('edit' => $edit)));
if ($id) { // example is specified
$example = $workshop->get_example_by_id($id);
} else { // no example specified - create new one
require_capability('mod/workshop:manageexamples', $workshop->context);
$example = new stdClass();
$example->id = null;
$example->authorid = $USER->id;
}
$canmanage = has_capability('mod/workshop:manageexamples', $workshop->context);
$isreviewer = $DB->record_exists('workshop_assessments', array('submissionid' => $example->id, 'reviewerid' => $USER->id));
if ($id and $delete and $confirm and $canmanage) {
require_sesskey();
$workshop->delete_submission($example);
redirect($workshop->view_url());
}
if ($example->id and ($canmanage or $isreviewer)) {
// ok you can go
} elseif (is_null($example->id) and $canmanage) {
// ok you can go
} else {
print_error('nopermissions');
}
if ($edit and $canmanage) {
require_once(dirname(__FILE__).'/submission_form.php');
$maxfiles = $workshop->nattachments;
$maxbytes = $workshop->maxbytes;
$contentopts = array('trusttext' => true, 'subdirs' => false, 'maxfiles' => $maxfiles, 'maxbytes' => $maxbytes);
$attachmentopts = array('subdirs' => true, 'maxfiles' => $maxfiles, 'maxbytes' => $maxbytes);
$example = file_prepare_standard_editor($example, 'content', $contentopts, $workshop->context,
'workshop_submission_content', $example->id);
$example = file_prepare_standard_filemanager($example, 'attachment', $attachmentopts, $workshop->context,
'workshop_submission_attachment', $example->id);
$mform = new workshop_submission_form($PAGE->url, array('current' => $example, 'workshop' => $workshop,
'contentopts' => $contentopts, 'attachmentopts' => $attachmentopts));
if ($mform->is_cancelled()) {
redirect($workshop->view_url());
} elseif ($canmanage and $formdata = $mform->get_data()) {
$timenow = time();
if (empty($formdata->id)) {
$formdata->workshopid = $workshop->id;
$formdata->example = 1;
$formdata->authorid = $USER->id;
$formdata->timecreated = $timenow;
$formdata->feedbackauthorformat = FORMAT_HTML; // todo better default
}
$formdata->timemodified = $timenow;
$formdata->title = trim($formdata->title);
$formdata->content = ''; // updated later
$formdata->contentformat = FORMAT_HTML; // updated later
$formdata->contenttrust = 0; // updated later
if (empty($formdata->id)) {
$formdata->id = $DB->insert_record('workshop_submissions', $formdata);
// todo add to log
}
// save and relink embedded images and save attachments
$formdata = file_postupdate_standard_editor($formdata, 'content', $contentopts, $workshop->context,
'workshop_submission_content', $formdata->id);
$formdata = file_postupdate_standard_filemanager($formdata, 'attachment', $attachmentopts, $workshop->context,
'workshop_submission_attachment', $formdata->id);
if (empty($formdata->attachment)) {
// explicit cast to zero integer
$formdata->attachment = 0;
}
// store the updated values or re-save the new example (re-saving needed because URLs are now rewritten)
$DB->update_record('workshop_submissions', $formdata);
redirect($workshop->example_url($formdata->id));
}
}
$PAGE->set_title($workshop->name);
$PAGE->set_heading($course->fullname);
if ($edit) {
$PAGE->navbar->add(get_string('exampleediting', 'workshop'));
} else {
$PAGE->navbar->add(get_string('example', 'workshop'));
}
// Output starts here
echo $OUTPUT->header();
$currenttab = 'submission';
include(dirname(__FILE__) . '/tabs.php');
echo $OUTPUT->heading(format_string($workshop->name), 2);
// if in edit mode, display the form to edit the example
if ($edit and $canmanage) {
$mform->display();
echo $OUTPUT->footer();
die();
}
// else display the example...
if ($example->id) {
if ($canmanage and $delete) {
echo $OUTPUT->confirm(get_string('exampledeleteconfirm', 'workshop'),
new moodle_url($PAGE->url, array('delete' => 1, 'confirm' => 1)), $workshop->view_url());
}
$wsoutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE);
echo $wsoutput->example_full($example, true);
}
// ...with an option to edit and remove it
if ($canmanage) {
echo $OUTPUT->container_start('buttonsbar');
if (empty($edit) and empty($delete)) {
$editbutton = new html_form();
$editbutton->method = 'get';
$editbutton->button->text = get_string('exampleedit', 'workshop');
$editbutton->url = new moodle_url($workshop->example_url($example->id), array('edit' => 'on'));
echo $OUTPUT->button($editbutton);
}
if (empty($delete)) {
$deletebutton = new html_form();
$deletebutton->method = 'get';
$deletebutton->button->text = get_string('exampledelete', 'workshop');
$deletebutton->url = new moodle_url($workshop->example_url($example->id), array('delete' => 'on'));
echo $OUTPUT->button($deletebutton);
}
echo $OUTPUT->container_end();
}
// and possibly display the example's review(s) - todo
echo $OUTPUT->footer();

View File

@ -25,10 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$string[''] = '';
$string[''] = '';
$string[''] = '';
$string[''] = '';
$string[''] = '';
$string[''] = '';
$string[''] = '';
@ -41,6 +37,7 @@ $string['allocatedetails'] = 'expected: $a->expected<br />submitted: $a->submitt
$string['allocationdone'] = 'Allocation done';
$string['allocationerror'] = 'Allocation error';
$string['allocation'] = 'Submission allocation';
$string['allsubmissions'] = 'All submissions';
$string['alreadygraded'] = 'Already graded';
$string['areainstructauthors'] = 'Instructions for submitting';
$string['areasubmissionattachment'] = 'Submission attachments';
@ -79,9 +76,16 @@ $string['err_removegrademappings'] = 'Unable to remove the unused grade mappings
$string['evaluategradeswait'] = 'Please wait until the assessments are evaluated and the grades are calculated';
$string['evaluation'] = 'Grading evaluation';
$string['evaluationmethod'] = 'Grading evaluation method';
$string['exampleadd'] = 'Add example submission';
$string['exampledeleteconfirm'] = 'Are you sure you want to delete the following example submission?';
$string['exampledelete'] = 'Delete example';
$string['exampleedit'] = 'Edit example';
$string['exampleediting'] = 'Editing example';
$string['example'] = 'Example submission';
$string['examplesbeforeassessment'] = 'Examples are available after own submission and must be assessed before assessment phase';
$string['examplesbeforesubmission'] = 'Examples must be assessed before own submission';
$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['feedbackreviewer'] = 'Feedback for the reviewer';
@ -117,6 +121,7 @@ $string['modulenameplural'] = 'Workshops';
$string['modulename'] = 'Workshop';
$string['mysubmission'] = 'My submission';
$string['nattachments'] = 'Maximum number of submission attachments';
$string['noexamples'] = 'No examples yet in this workshop';
$string['nogradeyet'] = 'No grade yet';
$string['nosubmissionfound'] = 'No submission found for this user';
$string['nosubmissions'] = 'No submissions yet in this workshop';
@ -133,6 +138,7 @@ $string['phaseclosed'] = 'Closed';
$string['phaseevaluation'] = 'Grading evaluation phase';
$string['phasesetup'] = 'Setup phase';
$string['phasesubmission'] = 'Submission phase';
$string['prepareexamples'] = 'Prepare example submissions';
$string['previewassessmentform'] = 'Preview';
$string['reassess'] = 'Re-assess';
$string['receivedgrades'] = 'Received grades';
@ -182,3 +188,4 @@ $string['withoutsubmission'] = 'Reviewer without own submission';
$string['workshopadministration'] = 'Workshop administration';
$string['workshopfeatures'] = 'Workshop features';
$string['workshopname'] = 'Workshop name';
$string['yoursubmission'] = 'Your submission';

View File

@ -394,7 +394,7 @@ class workshop {
u.picture AS authorpicture, u.imagealt AS authorimagealt
FROM {workshop_submissions} s
INNER JOIN {user} u ON (s.authorid = u.id)
WHERE s.workshopid = :workshopid AND s.id = :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);
}
@ -421,6 +421,41 @@ class workshop {
return $DB->get_record_sql($sql, $params);
}
/**
* Returns example submissions for this workshop
*
* @return array of records or an empty array
*/
public function get_examples() {
global $DB;
return $DB->get_records('workshop_submissions', array('workshopid' => $this->id, 'example' => 1), 'title', 'id,title');
}
/**
* Returns full record of the given example submission
*
* @param int $id example submission od
* @return object
*/
public function get_example_by_id($id) {
global $DB;
return $DB->get_record('workshop_submissions',
array('id' => $id, 'workshopid' => $this->id, 'example' => 1), '*', MUST_EXIST);
}
/**
* Removes the submission and all relevant data
*
* @param stdClass $submission record to delete
* @return void
*/
public function delete_submission(stdClass $submission) {
global $DB;
$assessments = $DB->get_records('workshop_assessments', array('submissionid' => $submission->id), '', 'id');
$this->delete_assessment(array_keys($assessments));
$DB->delete_records('workshop_submissions', array('id' => $submission->id));
}
/**
* Returns the list of all assessments in the workshop with some data added
*
@ -652,6 +687,15 @@ class workshop {
return new moodle_url($CFG->wwwroot . '/mod/workshop/submission.php', array('cmid' => $this->cm->id, 'id' => $id));
}
/**
* @param int $id example submission id
* @return moodle_url of the page to view an example submission
*/
public function example_url($id) {
global $CFG;
return new moodle_url($CFG->wwwroot . '/mod/workshop/example.php', array('cmid' => $this->cm->id, 'id' => $id));
}
/**
* @return moodle_url of the mod_edit form
*/
@ -773,6 +817,16 @@ class workshop {
}
$phase->tasks['editform'] = $task;
}
if ($this->useexamples and has_capability('mod/workshop:manageexamples', $this->context, $userid)) {
$task = new stdClass();
$task->title = get_string('prepareexamples', 'workshop');
if ($DB->count_records('workshop_submissions', array('example' => 1, 'workshopid' => $this->id)) > 0) {
$task->completed = true;
} elseif ($this->phase > self::PHASE_SETUP) {
$task->completed = false;
}
$phase->tasks['prepareexamples'] = $task;
}
if (empty($phase->tasks) and $this->phase == self::PHASE_SETUP) {
// if we are in the setup phase and there is no task (typical for students), let us
// display some explanation what is going on
@ -787,7 +841,8 @@ class workshop {
$phase = new stdClass();
$phase->title = get_string('phasesubmission', 'workshop');
$phase->tasks = array();
if (has_capability('moodle/course:manageactivities', $this->context, $userid)) {
if (($this->usepeerassessment or $this->useselfassessment)
and has_capability('moodle/course:manageactivities', $this->context, $userid)) {
$task = new stdClass();
$task->title = get_string('taskinstructreviewers', 'workshop');
$task->link = $this->updatemod_url();
@ -811,7 +866,6 @@ class workshop {
}
$phase->tasks['submit'] = $task;
}
$phases[self::PHASE_SUBMISSION] = $phase;
if (has_capability('mod/workshop:allocate', $this->context, $userid)) {
$task = new stdClass();
$task->title = get_string('allocate', 'workshop');
@ -849,6 +903,7 @@ class workshop {
$phase->tasks['allocateinfo'] = $task;
}
}
$phases[self::PHASE_SUBMISSION] = $phase;
// Prepare tasks for the peer-assessment phase (includes eventual self-assessments)
$phase = new stdClass();
@ -874,7 +929,7 @@ class workshop {
}
}
unset($a);
if ($numofpeers) {
if ($this->usepeerassessment and $numofpeers) {
$task = new stdClass();
if ($numofpeerstodo == 0) {
$task->completed = true;
@ -889,7 +944,7 @@ class workshop {
unset($a);
$phase->tasks['assesspeers'] = $task;
}
if ($numofself) {
if ($this->useselfassessment and $numofself) {
$task = new stdClass();
if ($numofselftodo == 0) {
$task->completed = true;

View File

@ -153,7 +153,6 @@ class mod_workshop_renderer extends plugin_renderer_base {
return $o;
}
/**
* Displays the submission fulltext
*
@ -290,6 +289,81 @@ class mod_workshop_renderer extends plugin_renderer_base {
return $this->output->container($outputimgs . $outputfiles, 'attachments');
}
/**
* Display a short summary of the example submission
*
* The passed submission object must define at least: id and title
*
* @param stdClass $example The example submission record
* @return string html to be echoed
*/
public function example_summary(stdClass $example) {
global $CFG;
$o = ''; // output HTML code
$classes = 'submission-summary example';
$o .= $this->output->container_start($classes); // main wrapper
$link = new html_link();
$link->url = new moodle_url($CFG->wwwroot . '/mod/workshop/example.php',
array('cmid' => $this->page->context->instanceid, 'id' => $example->id));
$link->text = format_string($example->title);
$link->set_classes('title');
$o .= $this->output->link($link);
$icon = new moodle_action_icon();
$icon->image->src = $this->old_icon_url('i/edit');
$icon->image->alt = get_string('edit');
$icon->link->url = new moodle_url($CFG->wwwroot . '/mod/workshop/example.php',
array('cmid' => $this->page->context->instanceid, 'id' => $example->id, 'edit' => 'on'));
$o .= $this->output->action_icon($icon);
$icon = new moodle_action_icon();
$icon->image->src = $this->old_icon_url('t/delete');
$icon->image->alt = get_string('delete');
$icon->link->url = new moodle_url($CFG->wwwroot . '/mod/workshop/example.php',
array('cmid' => $this->page->context->instanceid, 'id' => $example->id, 'delete' => 1));
$o .= $this->output->action_icon($icon);
$o .= $this->output->container_end(); // end of the main wrapper
return $o;
}
/**
* Displays the example submission fulltext
*
* By default, this looks similar to a forum post.
*
* @param stdClass $example The example submission data
* @return string html to be echoed
*/
public function example_full(stdClass $example) {
global $CFG;
$o = ''; // output HTML code
$classes = 'submission-full example';
$o .= $this->output->container_start($classes);
$o .= $this->output->container_start('header');
$o .= $this->output->heading(format_string($example->title), 3, 'title');
$created = get_string('userdatecreated', 'workshop', userdate($example->timecreated));
$o .= $this->output->container($created, 'userdate created');
if ($example->timemodified > $example->timecreated) {
$modified = get_string('userdatemodified', 'workshop', userdate($example->timemodified));
$o .= $this->output->container($modified, 'userdate modified');
}
$o .= $this->output->container_end(); // end of header
$content = format_text($example->content, $example->contentformat);
$content = file_rewrite_pluginfile_urls($content, 'pluginfile.php', $this->page->context->id,
'workshop_submission_content', $example->id);
$o .= $this->output->container($content, 'content');
$o .= $this->submission_attachments($example);
$o .= $this->output->container_end(); // end of example-full
return $o;
}
/**
* Renders the user plannner tool
*

View File

@ -100,6 +100,22 @@
margin-right: 5px;
}
/**
* Example submission - summary display
*/
.mod-workshop .submission-summary.example .title,
.mod-workshop .submission-summary.example .userdate {
margin: 0px 0px 0px 0px;
}
/**
* Example submission - full display
*/
.mod-workshop .submission-full.example .header .title,
.mod-workshop .submission-full.example .header .userdate {
margin: 0px 0px 0px 0px;
}
/**
* Elements generated by the workshop renderer
*/
@ -470,6 +486,10 @@
text-align: center;
}
.mod-workshop div.buttonsbar .singlebutton {
display: inline;
}
.mod-workshop div.buttonwithhelp div {
display: inline;
}

View File

@ -90,7 +90,7 @@ if ($edit and $ownsubmission) {
$timenow = time();
if (empty($formdata->id)) {
$formdata->workshopid = $workshop->id;
$formdata->example = 0; // todo add examples support
$formdata->example = 0;
$formdata->authorid = $USER->id;
$formdata->timecreated = $timenow;
$formdata->feedbackauthorformat = FORMAT_HTML; // todo better default

View File

@ -83,6 +83,22 @@ case workshop::PHASE_SETUP:
if (trim(strip_tags($workshop->intro))) {
echo $OUTPUT->box(format_module_intro('workshop', $workshop, $workshop->cm->id), 'generalbox', 'intro');
}
if ($workshop->useexamples and has_capability('mod/workshop:manageexamples', $PAGE->context)) {
echo $OUTPUT->box_start('generalbox examples');
echo $OUTPUT->heading(get_string('examplesubmissions', 'workshop'), 3);
if (! $examples = $workshop->get_examples()) {
echo $OUTPUT->container(get_string('noexamples', 'workshop'), 'noexamples');
}
foreach ($examples as $example) {
echo $wsoutput->example_summary($example);
}
$editbutton = new html_form();
$editbutton->method = 'get';
$editbutton->button->text = get_string('exampleadd', 'workshop');
$editbutton->url = new moodle_url($workshop->example_url(0), array('edit' => 'on'));
echo $OUTPUT->button($editbutton);
echo $OUTPUT->box_end();
}
break;
case workshop::PHASE_SUBMISSION:
if (trim(strip_tags($workshop->instructauthors))) {
@ -91,22 +107,26 @@ case workshop::PHASE_SUBMISSION:
echo $OUTPUT->box(format_text($instructions, $workshop->instructauthorsformat), array('generalbox', 'instructions'));
}
if (has_capability('mod/workshop:submit', $PAGE->context)) {
echo $OUTPUT->box_start('generalbox ownsubmission');
echo $OUTPUT->heading(get_string('yoursubmission', 'workshop'), 3);
if ($submission = $workshop->get_submission_by_author($USER->id)) {
echo $OUTPUT->box_start('generalbox mysubmission');
echo $wsoutput->submission_summary($submission, true);
if ($workshop->submitting_allowed()) {
$editbutton = new html_form();
$editbutton->method = 'get';
$editbutton->button->text = get_string('editsubmission', 'workshop');
$editbutton->url = new moodle_url($workshop->submission_url(), array('edit' => 'on', 'id' => $submission->id));
echo $OUTPUT->button($editbutton);
}
echo $OUTPUT->box_end();
} else {
echo $OUTPUT->container(get_string('noyoursubmission', 'workshop'));
}
if ($workshop->submitting_allowed()) {
$editbutton = new html_form();
$editbutton->method = 'get';
$editbutton->button->text = get_string('editsubmission', 'workshop');
$editbutton->url = new moodle_url($workshop->submission_url(), array('edit' => 'on'));
echo $OUTPUT->button($editbutton);
}
echo $OUTPUT->box_end();
}
if (has_capability('mod/workshop:viewallsubmissions', $PAGE->context)) {
$shownames = has_capability('mod/workshop:viewauthornames', $PAGE->context);
echo $OUTPUT->box_start('generalbox allsubmissions');
echo $OUTPUT->heading(get_string('allsubmissions', 'workshop'), 3);
if (! $submissions = $workshop->get_submissions('all')) {
echo $OUTPUT->container(get_string('nosubmissions', 'workshop'), 'nosubmissions');
}