for ($i = 0; $i < $norepeats; $i++) {
$mform->addElement('header', 'dimension'.$i, get_string('dimensionnumberaccumulative', 'workshop', $i+1));
- $mform->addElement('hidden', 'dimensionid__idx_'.$i);
+ $mform->addElement('hidden', 'dimensionid__idx_'.$i); // the id in workshop_forms_accumulative
$mform->addElement('editor', 'description__idx_'.$i.'_editor', get_string('dimensiondescription', 'workshop'),
array('cols' => 20), $descriptionopts);
$mform->addElement('select', 'grade__idx_'.$i, get_string('grade'), $gradeoptions);
/**
* Accumulative grading strategy logic.
*/
-class workshop_accumulative_strategy implements workshop_strategy {
+class workshop_accumulative_strategy extends workshop_base_strategy implements workshop_strategy {
/** @var workshop the parent workshop instance */
protected $workshop;
$norepeats += WORKSHOP_STRATEGY_ADDDIMS;
}
- for ($i = 0; $i < $norepeats; $i++) {
+ // prepare the emebeded files
+ for ($i = 0; $i < $this->nodimensions; $i++) {
// prepare all editor elements
$fields = file_prepare_standard_editor($fields, 'description__idx_'.$i, $this->descriptionopts,
- $PAGE->context, 'workshop_dimension_description', 0);
+ $PAGE->context, 'workshop_dimension_description', $fields->{'dimensionid__idx_'.$i});
}
+
$customdata = array();
$customdata['workshop'] = $this->workshop;
$customdata['strategy'] = $this;
protected function load_fields() {
global $DB;
- $dims = $DB->get_records('workshop_forms_' . $this->name(), array('workshopid' => $this->workshop->id), 'sort');
+ $sql = 'SELECT master.id,dim.description,dim.descriptionformat,dim.grade,dim.weight
+ FROM {workshop_forms} master
+ JOIN {workshop_forms_accumulative} dim ON (dim.id=master.localid)
+ WHERE master.workshopid = ?
+ ORDER BY master.sort';
+ $params[0] = $this->workshop->id;
+
+ $dims = $DB->get_records_sql($sql, $params);
$this->nodimensions = count($dims);
$fields = $this->_cook_dimension_records($dims);
return $fields;
*/
protected function _cook_dimension_records(array $raw) {
- $formdata = array();
+ $formdata = new stdClass();
$key = 0;
foreach ($raw as $dimension) {
- $formdata['dimensionid__idx_' . $key] = $dimension->id;
- $formdata['description__idx_' . $key] = $dimension->description;
- $formdata['descriptionformat__idx_' . $key] = $dimension->descriptionformat;
- $formdata['grade__idx_' . $key] = $dimension->grade;
- $formdata['weight__idx_' . $key] = $dimension->weight;
+ $formdata->{'dimensionid__idx_' . $key} = $dimension->id;
+ $formdata->{'description__idx_' . $key} = $dimension->description;
+ $formdata->{'description__idx_' . $key.'format'} = $dimension->descriptionformat;
+ $formdata->{'grade__idx_' . $key} = $dimension->grade;
+ $formdata->{'weight__idx_' . $key} = $dimension->weight;
$key++;
}
- $cooked = (object)$formdata;
- return $cooked;
+ return $formdata;
}
/**
* @return void
*/
public function save_edit_strategy_form(stdClass $data) {
- global $DB;
+ global $DB, $PAGE;
if (!isset($data->strategyname) || ($data->strategyname != $this->name())) {
// the workshop strategy has changed since the form was opened for editing
throw new moodle_exception('strategyhaschanged', 'workshop');
}
-
- $data = $this->_cook_edit_form_data($data);
- $todelete = array();
- foreach ($data as $record) {
- if (empty($record->description)) {
- if (!empty($record->id)) {
+ $workshopid = $data->workshopid;
+ $norepeats = $data->norepeats;
+
+ $data = $this->_cook_edit_form_data($data);
+ $masterrecords = $data->forms;
+ $localrecords = $data->forms_accumulative;
+ $todeletelocal = array(); // local ids to be deleted
+ $todeletemaster = array(); // master ids to be deleted
+
+ for ($i=0; $i < $norepeats; $i++) {
+ $local = $localrecords[$i];
+ $master = $masterrecords[$i];
+ if (empty($local->description_editor['text'])) {
+ if (!empty($local->id)) {
// existing record with empty description - to be deleted
- $todelete[] = $record->id;
+ $todeletelocal[] = $local->id;
+ $todeletemaster[] = $this->dimension_master_id($local->id);
}
continue;
}
- if (empty($record->id)) {
+ if (empty($local->id)) {
// new field
- $record->id = $DB->insert_record('workshop_forms_' . $this->name(), $record);
+ $local->id = $DB->insert_record('workshop_forms_accumulative', $local);
+ $master->localid = $local->id;
+ $master->id = $DB->insert_record('workshop_forms', $master);
} else {
// exiting field
- $DB->update_record('workshop_forms_' . $this->name(), $record);
+ $master->id = $this->dimension_master_id($local->id);
+ $DB->update_record('workshop_forms', $master);
}
+ // $local record now has its id, let us re-save it with correct path to embeded media files
+ $local = file_postupdate_standard_editor($local, 'description', $this->descriptionopts,
+ $PAGE->context, 'workshop_dimension_description', $local->id);
+ $DB->update_record('workshop_forms_accumulative', $local);
}
- $DB->delete_records_list('workshop_forms_' . $this->name(), 'id', $todelete);
+ // todo unlink embedded files
+ $DB->delete_records_list('workshop_forms_accumulative', 'id', $todeletelocal);
+ $DB->delete_records_list('workshop_forms', 'id', $todeletemaster);
}
/**
protected function _cook_edit_form_data(stdClass $raw) {
global $PAGE;
- $cook = array();
+ $cook = new stdClass(); // to be returned
+ $cook->forms = array(); // to be stored in {workshop_forms}
+ $cook->forms_accumulative = array(); // to be stored in {workshop_forms_accumulative}
+
for ($i = 0; $i < $raw->norepeats; $i++) {
- $raw = file_postupdate_standard_editor($raw, 'description__idx_'.$i, $this->descriptionopts,
- $PAGE->context, 'workshop_dimension_description', 0);
- $cook[$i] = new stdClass();
- $fieldname = 'dimensionid__idx_'.$i;
- $cook[$i]->id = isset($raw->$fieldname) ? $raw->$fieldname : null;
- $cook[$i]->workshopid = $this->workshop->id;
- $cook[$i]->sort = $i + 1;
- $fieldname = 'description__idx_'.$i;
- $cook[$i]->description = isset($raw->$fieldname) ? $raw->$fieldname : null;
- $fieldname = 'description__idx_'.$i.'format';
- $cook[$i]->descriptionformat = isset($raw->$fieldname) ? $raw->$fieldname : FORMAT_HTML;
- $fieldname = 'grade__idx_'.$i;
- $cook[$i]->grade = isset($raw->$fieldname) ? $raw->$fieldname : null;
- $fieldname = 'weight__idx_'.$i;
- $cook[$i]->weight = isset($raw->$fieldname) ? $raw->$fieldname : null;
+ $cook->forms_accumulative[$i] = new stdClass();
+ $fieldname = 'dimensionid__idx_'.$i;
+ $cook->forms_accumulative[$i]->id = isset($raw->$fieldname) ? $raw->$fieldname : null;
+ $fieldname = 'description__idx_'.$i.'_editor';
+ $cook->forms_accumulative[$i]->description_editor = isset($raw->$fieldname) ? $raw->$fieldname : null;
+ $fieldname = 'grade__idx_'.$i;
+ $cook->forms_accumulative[$i]->grade = isset($raw->$fieldname) ? $raw->$fieldname : null;
+ $fieldname = 'weight__idx_'.$i;
+ $cook->forms_accumulative[$i]->weight = isset($raw->$fieldname) ? $raw->$fieldname : null;
+
+ $cook->forms[$i] = new stdClass();
+ $cook->forms[$i]->id = null; // will be checked later, considered unknown at the moment
+ $cook->forms[$i]->workshopid = $this->workshop->id;
+ $cook->forms[$i]->sort = $i + 1;
+ $cook->forms[$i]->strategy = 'accumulative';
+ $cook->forms[$i]->dimensionid = $cook->forms_accumulative[$i]->id;
}
return $cook;
}
*/
public function save_assessment(stdClass $assessment, stdClass $data);
}
+
+/**
+ * Provides common methods for all grading strategies
+ *
+ * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class workshop_base_strategy {
+
+ /**
+ * Returns the dimension's master id from table {workshop_forms}
+ *
+ * Every grading strategy defines its assessment dimensions in its own tables (eg workshop_forms_accumulative).
+ * But we need a unique identifier across all strategies to be able to embed media into dimension descriptions.
+ * So, every dimension has to have a record in the master table workshop_forms. This is a similar pattern
+ * to what Moodle already uses with course_modules and instances.
+ *
+ * @param int $localid The id if the dimension in the subplugin table (eg workshop_forms_accumulative)
+ * @return int|false The master id from workshop_forms_accumulative or false, if not found
+ */
+ public function dimension_master_id($localid) {
+ global $DB;
+ /** @var array Cache database query results so we can call from a loop */
+ static $cache=null;
+
+ if (is_null($cache)) {
+ $strategy = $this->name();
+ $dimids = $DB->get_records('workshop_forms',
+ array('workshopid' => $this->workshop->id, 'strategy' => 'accumulative'), '', 'id,localid');
+ $cache = array();
+ foreach ($dimids as $masterid => $master) {
+ $cache[$masterid] = $master->localid;
+ }
+ $cache = array_flip($cache);
+ // now the $cache contains records [$localid] => [$masterid]
+ }
+
+ if (isset($cache[$localid])) {
+ return $localid;
+ }
+ return false;
+ }
+}
if (! $workshops = get_all_instances_in_course('workshop', $course)) {
echo $OUTPUT->heading(get_string('noworkshops', 'workshop'), 2);
- echo $OUTPUT->continue_button("view.php?id=$course->id");
+ echo $OUTPUT->continue_button(new moodle_url($CFG->wwwroot . '/course/view.php', array('id' => $course->id)));
echo $OUTPUT->footer();
die();
}
/// Submission settings --------------------------------------------------------
$mform->addElement('header', 'submissionsettings', get_string('submissionsettings', 'workshop'));
- $label = get_string('latesubmissions', 'workshop');
- $text = get_string('latesubmissionsdesc', 'workshop');
- $mform->addElement('advcheckbox', 'latesubmissions', $label, $text);
- $mform->setHelpButton('latesubmissions', array('latesubmissions', $label, 'workshop'));
- $mform->setAdvanced('latesubmissions');
-
$options = array();
for ($i=7; $i>=0; $i--) {
$options[$i] = $i;
$mform->addElement('select', 'nattachments', $label, $options);
$mform->setDefault('nattachments', 1);
$mform->setHelpButton('nattachments', array('nattachments', $label, 'workshop'));
- $mform->setAdvanced('nattachments');
+
+ $label = get_string('latesubmissions', 'workshop');
+ $text = get_string('latesubmissionsdesc', 'workshop');
+ $mform->addElement('advcheckbox', 'latesubmissions', $label, $text);
+ $mform->setHelpButton('latesubmissions', array('latesubmissions', $label, 'workshop'));
$options = get_max_upload_sizes($CFG->maxbytes, $COURSE->maxbytes);
$options[0] = get_string('courseuploadlimit') . ' ('.display_size($COURSE->maxbytes).')';
$mform->addElement('select', 'maxbytes', get_string('maximumsize', 'assignment'), $options);
$mform->setDefault('maxbytes', $workshopconfig->maxbytes);
$mform->setHelpButton('maxbytes', array('maxbytes', $label, 'workshop'));
- $mform->setAdvanced('maxbytes');
/// Assessment settings
$mform->addElement('header', 'assessmentsettings', get_string('assessmentsettings', 'workshop'));
- $label = get_string('nsassessments', 'workshop');
- $options = workshop_get_numbers_of_assessments();
- $mform->addElement('select', 'nsassessments', $label, $options);
- $mform->setDefault('nsassessments', $workshopconfig->nsassessments);
- $mform->setHelpButton('nsassessments', array('nsassessments', $label, 'workshop'));
-
$label = get_string('nexassessments', 'workshop');
$options = workshop_get_numbers_of_assessments();
$options[0] = get_string('assessallexamples', 'workshop');
$mform->setHelpButton('nexassessments', array('nexassessments', $label, 'workshop'));
$mform->disabledIf('nexassessments', 'useexamples');
- $label = get_string('assesswosubmission', 'workshop');
- $text = get_string('assesswosubmissiondesc', 'workshop');
- $mform->addElement('advcheckbox', 'assesswosubmission', $label, $text);
- $mform->setHelpButton('assesswosubmission', array('assesswosubmission', $label, 'workshop'));
- $mform->setAdvanced('assesswosubmission');
-
$label = get_string('examplesmode', 'workshop');
$options = workshop_get_example_modes();
$mform->addElement('select', 'examplesmode', $label, $options);
$mform->setDefault('examplesmode', $workshopconfig->examplesmode);
$mform->setHelpButton('examplesmode', array('examplesmode', $label, 'workshop'));
+ $mform->disabledIf('nexassessments', 'useexamples');
$mform->setAdvanced('examplesmode');
$label = get_string('teacherweight', 'workshop');
$mform->addElement('select', 'teacherweight', $label, $options);
$mform->setDefault('teacherweight', 1);
$mform->setHelpButton('teacherweight', array('teacherweight', $label, 'workshop'));
- $mform->setAdvanced('teacherweight');
$label = get_string('agreeassessments', 'workshop');
$text = get_string('agreeassessmentsdesc', 'workshop');
$mform->addElement('select', 'assessmentcomps', $label, $levels);
$mform->setDefault('assessmentcomps', $workshopconfig->assessmentcomps);
$mform->setHelpButton('assessmentcomps', array('assessmentcomps', $label, 'workshop'));
- $mform->setAdvanced('assessmentcomps');
/// Access control
$mform->addElement('header', 'accesscontrol', get_string('accesscontrol', 'workshop'));
$mform->addElement('passwordunmask', 'password', $label);
$mform->setType('quizpassword', PARAM_TEXT);
$mform->setHelpButton('password', array('requirepassword', $label, 'workshop'));
- $mform->setAdvanced('password');
/// Common module settinga, Restrict availability, Activity completion etc. ----
$features = array('groups'=>true, 'groupings'=>true, 'groupmembersonly'=>true,