<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/workshop/db" VERSION="20090831" COMMENT="XMLDB file for Moodle mod/workshop"
+<XMLDB PATH="mod/workshop/db" VERSION="20090907" COMMENT="XMLDB file for Moodle mod/workshop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="ID of the parent course" PREVIOUS="id" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="Name of the activity" PREVIOUS="course" NEXT="intro"/>
<FIELD NAME="intro" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="The introduction or description of the activity" PREVIOUS="name" NEXT="introformat"/>
- <FIELD NAME="introformat" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the intro field" PREVIOUS="intro" NEXT="timemodified"/>
- <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The timestamp when the module was modified" PREVIOUS="introformat" NEXT="phase"/>
+ <FIELD NAME="introformat" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the intro field" PREVIOUS="intro" NEXT="instructauthors"/>
+ <FIELD NAME="instructauthors" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="Instructions for the submission phase" PREVIOUS="introformat" NEXT="instructauthorsformat"/>
+ <FIELD NAME="instructauthorsformat" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="instructauthors" NEXT="instructreviewers"/>
+ <FIELD NAME="instructreviewers" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="Instructions for the assessment phase" PREVIOUS="instructauthorsformat" NEXT="instructreviewersformat"/>
+ <FIELD NAME="instructreviewersformat" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="instructreviewers" NEXT="timemodified"/>
+ <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The timestamp when the module was modified" PREVIOUS="instructreviewersformat" NEXT="phase"/>
<FIELD NAME="phase" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The current phase of workshop (0 = not available, 1 = submission, 2 = assessment, 3 = closed)" PREVIOUS="timemodified" NEXT="useexamples"/>
<FIELD NAME="useexamples" TYPE="int" LENGTH="2" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="optional feature: students practise evaluating on example submissions from teacher" PREVIOUS="phase" NEXT="usepeerassessment"/>
<FIELD NAME="usepeerassessment" TYPE="int" LENGTH="2" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="optional feature: students perform peer assessment of others' work" PREVIOUS="useexamples" NEXT="useselfassessment"/>
$string['taskassesspeers'] = 'Assess peers';
$string['taskassesspeersdetails'] = 'total: $a->total<br />pending: $a->todo';
$string['taskassessself'] = 'Assess yourself';
+$string['instructauthors'] = 'Instructions for submitting';
$string['taskinstructauthors'] = 'Provide instructions for submitting';
-$string['taskinstructreviewers'] = 'Provide instructions for grading';
+$string['taskinstructreviewers'] = 'Provide instructions for assessing';
+$string['instructreviewers'] = 'Instructions for assessing';
$string['taskintro'] = 'Set the workshop introduction';
$string['tasksubmit'] = 'Submit your work';
$string['teacherweight'] = 'Weight of the teacher\'s assessments';
}
}
-
/**
* Saves a new instance of the workshop into the database
*
$data->timecreated = time();
$data->timemodified = $data->timecreated;
- return $DB->insert_record('workshop', $data);
+ // insert the new record so we get the id
+ $data->id = $DB->insert_record('workshop', $data);
+
+ // we need to use context now, so we need to make sure all needed info is already in db
+ $cmid = $data->coursemodule;
+ $DB->set_field('course_modules', 'instance', $data->id, array('id' => $cmid));
+ $context = get_context_instance(CONTEXT_MODULE, $cmid);
+
+ // process the custom wysiwyg editors
+ if ($draftitemid = $data->instructauthorseditor['itemid']) {
+ $data->instructauthors = file_save_draft_area_files($draftitemid, $context->id, 'workshop_instructauthors',
+ false, workshop::instruction_editors_options($context), $data->instructauthorseditor['text']);
+ $data->instructauthorsformat = $data->instructauthorseditor['format'];
+ }
+
+ // re-save the record with the replaced URLs in editor fields
+ $DB->update_record('workshop', $data);
+
+ return $data->id;
}
/**
* (defined by the form in mod_form.php) this function
* will update an existing instance with new data.
*
- * @param stdClass $workshop An object from the form in mod_form.php
- * @return boolean Success/Fail
+ * @param stdClass $data An object from the form in mod_form.php
+ * @return bool success
*/
-function workshop_update_instance($workshop) {
- global $DB;
+function workshop_update_instance($data) {
+ global $CFG, $DB;
+ require_once(dirname(__FILE__) . '/locallib.php');
+
+ $data->timemodified = time();
+ $data->id = $data->instance;
- $workshop->timemodified = time();
- $workshop->id = $workshop->instance;
+ $DB->update_record('workshop', $data);
+ $context = get_context_instance(CONTEXT_MODULE, $data->coursemodule);
- return $DB->update_record('workshop', $workshop);
+ // process the custom wysiwyg editors
+ if ($draftitemid = $data->instructauthorseditor['itemid']) {
+ $data->instructauthors = file_save_draft_area_files($draftitemid, $context->id, 'workshop_instructauthors',
+ false, workshop::instruction_editors_options($context), $data->instructauthorseditor['text']);
+ $data->instructauthorsformat = $data->instructauthorseditor['format'];
+ }
+
+ // re-save the record with the replaced URLs in editor fields
+ return $DB->update_record('workshop', $data);
}
/**
function workshop_get_file_areas($course, $cm, $context) {
$areas = array();
if (has_capability('moodle/course:managefiles', $context)) {
+ $areas['workshop_instructauthors'] = get_string('areainstructauthors', 'workshop');
$areas['workshop_dimension_description'] = get_string('areadimensiondescription', 'workshop');
$areas['workshop_submission_content'] = get_string('areasubmissioncontent', 'workshop');
$areas['workshop_submission_attachment'] = get_string('areasubmissionattachment', 'workshop');
* the fileareas workshop_submission_content and workshop_submission_attachment are used.
* The access rights to the files are checked here. The user must be either a peer-reviewer
* of the submission or have capability ... (todo) to access the submission files.
+ * Besides that, areas workshop_instructauthors and workshop_instructreviewers contain the media
+ * embedded using the mod_form.php.
*
* @param stdClass $course
* @param stdClass $cminfo
* @param string $filearea
* @param array $args
* @param bool $forcedownload
- * @return bool false if file not found, does not return if found - justsend the file
+ * @return void this should never return to the caller
*/
-function workshop_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) {
+function workshop_pluginfile($course, $cminfo, $context, $filearea, array $args, $forcedownload) {
global $DB;
if (!$cminfo->uservisible) {
- return false;
+ send_file_not_found();
}
if (!$cm = get_coursemodule_from_instance('workshop', $cminfo->instance, $course->id)) {
- return false;
+ send_file_not_found();
+ }
+ require_login($course, true, $cm);
+
+ if ($filearea === 'workshop_instructauthors') {
+ // submission instructions may contain sensitive data
+ if (!has_any_capability(array('moodle/course:manageactivities', 'mod/workshop:submit'), $context)) {
+ send_file_not_found();
+ }
+
+ array_shift($args); // we do not use itemids here
+ $relativepath = '/' . implode('/', $args);
+ $fullpath = $context->id . $filearea . '0' . $relativepath; // beware, slashes are not used here!
+
+ $fs = get_file_storage();
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
+ send_file_not_found();
+ }
+
+ $lifetime = isset($CFG->filelifetime) ? $CFG->filelifetime : 86400;
+
+ // finally send the file
+ send_stored_file($file, $lifetime, 0);
}
- require_course_login($course, true, $cm);
if ($filearea === 'workshop_dimension_description') {
$itemid = (int)array_shift($args);
}
if ($filearea === 'workshop_dimension_description') {
+ // always only itemid 0 - TODO not true, review
+
+ $filepath = is_null($filepath) ? '/' : $filepath;
+ $filename = is_null($filename) ? '.' : $filename;
+
+ $urlbase = $CFG->wwwroot.'/pluginfile.php';
+ if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
+ if ($filepath === '/' and $filename === '.') {
+ $storedfile = new virtual_root_file($context->id, $filearea, 0);
+ } else {
+ // not found
+ return null;
+ }
+ }
+ return new file_info_stored($browser, $context, $storedfile, $urlbase, $areas[$filearea], false, true, true, false);
+ }
+
+ if ($filearea === 'workshop_instructauthors') {
// always only itemid 0
$filepath = is_null($filepath) ? '/' : $filepath;
}
}
+////////////////////////////////////////////////////////////////////////////////
+// Navigation API //
+////////////////////////////////////////////////////////////////////////////////
+
/**
* Extends the global navigation tree by adding workshop nodes if there is a relevant content
*
$DB->update_record('workshop_assessments', $data);
return $grade;
}
+
+// Static methods
+
+ /**
+ * Returns an array of options for the editors that are used for submitting and assessing instructions
+ *
+ * @param stdClass $context
+ * @return array
+ */
+ public static function instruction_editors_options(stdClass $context) {
+ return array('subdirs' => 1, 'maxbytes' => 0, 'maxfiles' => EDITOR_UNLIMITED_FILES,
+ 'changeformat' => 1, 'context' => $context, 'noclean' => 1, 'trusttext' => 0);
+ }
+
}
defined('MOODLE_INTERNAL') || die();
-require_once($CFG->dirroot.'/course/moodleform_mod.php');
+require_once($CFG->dirroot . '/course/moodleform_mod.php');
+require_once(dirname(__FILE__) . '/locallib.php');
+require_once($CFG->libdir . '/filelib.php');
class mod_workshop_mod_form extends moodleform_mod {
+ /**
+ * Defines the workshop instance configuration form
+ *
+ * @return void
+ */
function definition() {
global $CFG, $COURSE;
$workshopconfig = get_config('workshop');
$mform = $this->_form;
-/// General --------------------------------------------------------------------
+ // General --------------------------------------------------------------------
$mform->addElement('header', 'general', get_string('general', 'form'));
- /// Workshop name
+ // Workshop name
$label = get_string('workshopname', 'workshop');
$mform->addElement('text', 'name', $label, array('size'=>'64'));
if (!empty($CFG->formatstringstriptags)) {
$mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
$mform->setHelpButton('name', array('workshopname', $label, 'workshop'));
- /// Introduction
+ // Introduction
$this->add_intro_editor(false, get_string('introduction', 'workshop'));
-/// Workshop features ----------------------------------------------------------
+ // Workshop features ----------------------------------------------------------
$mform->addElement('header', 'workshopfeatures', get_string('workshopfeatures', 'workshop'));
$label = get_string('useexamples', 'workshop');
$mform->addElement('advcheckbox', 'useselfassessment', $label, $text);
$mform->setHelpButton('useselfassessment', array('useselfassessment', $label, 'workshop'));
-/// Grading settings -----------------------------------------------------------
+ // Grading settings -----------------------------------------------------------
$mform->addElement('header', 'gradingsettings', get_string('gradingsettings', 'workshop'));
$grades = workshop_get_maxgrades();
$mform->setDefault('strategy', $workshopconfig->strategy);
$mform->setHelpButton('strategy', array('strategy', $label, 'workshop'));
-/// Submission settings --------------------------------------------------------
+ // Submission settings --------------------------------------------------------
$mform->addElement('header', 'submissionsettings', get_string('submissionsettings', 'workshop'));
+ $label = get_string('instructauthors', 'workshop');
+ $mform->addElement('editor', 'instructauthorseditor', $label, null,
+ workshop::instruction_editors_options($this->context));
+
$options = array();
for ($i=7; $i>=0; $i--) {
$options[$i] = $i;
$mform->setDefault('maxbytes', $workshopconfig->maxbytes);
$mform->setHelpButton('maxbytes', array('maxbytes', $label, 'workshop'));
-/// Assessment settings
+ // Assessment settings --------------------------------------------------------
$mform->addElement('header', 'assessmentsettings', get_string('assessmentsettings', 'workshop'));
+// $label = get_string('instructreviewers', 'workshop');
+// $mform->addElement('editor', 'instructreviewerseditor', $label, null,
+// workshop::instruction_editors_options($this->context));
+
$label = get_string('nexassessments', 'workshop');
$options = workshop_get_numbers_of_assessments();
$options[0] = get_string('assessallexamples', 'workshop');
$mform->setDefault('assessmentcomps', $workshopconfig->assessmentcomps);
$mform->setHelpButton('assessmentcomps', array('assessmentcomps', $label, 'workshop'));
-/// Access control
+ // Access control -------------------------------------------------------------
$mform->addElement('header', 'accesscontrol', get_string('accesscontrol', 'workshop'));
$label = get_string('submissionstart', 'workshop');
$mform->setHelpButton('releasegrades', array('releasegrades', $label, 'workshop'));
$mform->setAdvanced('releasegrades');
-/// Common module settinga, Restrict availability, Activity completion etc. ----
+ // Common module settinga, Restrict availability, Activity completion etc. ----
$features = array('groups'=>true, 'groupings'=>true, 'groupmembersonly'=>true,
'outcomes'=>true, 'gradecat'=>false, 'idnumber'=>false);
$this->standard_coursemodule_elements();
-/// Save and close, Save, Cancel -----------------------------------------------
- // add standard buttons, common to all modules
+ // Standard buttons, common to all modules ------------------------------------
$this->add_action_buttons();
+ }
+ /**
+ * Prepares the form before data are set
+ *
+ * Additional wysiwyg editor are prepared here, the introeditor is prepared automatically by core
+ *
+ * @param array $data to be set
+ * @return void
+ */
+ function data_preprocessing(&$data) {
+ if ($this->current->instance) {
+ // editing an existing workshop - let us prepare the added editor elements (intro done automatically)
+ $draftitemid = file_get_submitted_draft_itemid('instructauthors');
+ $data['instructauthorseditor']['text'] = file_prepare_draft_area($draftitemid, $this->context->id,
+ 'workshop_instructauthors', false,
+ workshop::instruction_editors_options($this->context),
+ $data['instructauthors']);
+ $data['instructauthorseditor']['format'] = $data['instructauthorsformat'];
+ $data['instructauthorseditor']['itemid'] = $draftitemid;
+ } else {
+ // adding a new workshop instance
+ $draftitemid = file_get_submitted_draft_itemid('instructauthors');
+ file_prepare_draft_area($draftitemid, null, null, null); // no context, no filearea yet
+ $data['instructauthorseditor'] = array('text' => '', 'format' => FORMAT_HTML, 'itemid' => $draftitemid);
+ }
}
}
defined('MOODLE_INTERNAL') || die();
-$module->version = 2009090400;
+$module->version = 2009090700;
$module->requires = 2009090400; // Requires this Moodle version
$module->cron = 60;
}
break;
case workshop::PHASE_SUBMISSION:
+ if (trim(strip_tags($workshop->instructauthors))) {
+ $instructions = file_rewrite_pluginfile_urls($workshop->instructauthors, 'pluginfile.php', $PAGE->context->id,
+ 'workshop_instructauthors', 0, workshop::instruction_editors_options($PAGE->context));
+ echo $OUTPUT->box(format_text($instructions, $workshop->instructauthorsformat), array('generalbox', 'instructions'));
+ }
if (has_capability('mod/workshop:submit', $PAGE->context)) {
if ($submission = $workshop->get_submission_by_author($USER->id)) {
echo $OUTPUT->box_start('generalbox mysubmission');