Assessment dimensions now have unique id which allows to embed media.

This commit is contained in:
David Mudrak 2010-01-04 17:49:23 +00:00
parent 0db82a04db
commit 6405b2549c
5 changed files with 120 additions and 64 deletions

View File

@ -57,7 +57,7 @@ class workshop_edit_accumulative_strategy_form extends workshop_edit_strategy_fo
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);

View File

@ -30,7 +30,7 @@ require_once(dirname(dirname(__FILE__)) . '/lib.php'); // interface definition
/**
* 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;
@ -81,11 +81,13 @@ class workshop_accumulative_strategy implements workshop_strategy {
$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;
@ -103,7 +105,14 @@ class workshop_accumulative_strategy implements workshop_strategy {
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;
@ -120,18 +129,17 @@ class workshop_accumulative_strategy implements workshop_strategy {
*/
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;
}
/**
@ -147,32 +155,50 @@ class workshop_accumulative_strategy implements workshop_strategy {
* @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');
}
$workshopid = $data->workshopid;
$norepeats = $data->norepeats;
$data = $this->_cook_edit_form_data($data);
$todelete = array();
foreach ($data as $record) {
if (empty($record->description)) {
if (!empty($record->id)) {
$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);
}
/**
@ -189,23 +215,27 @@ class workshop_accumulative_strategy implements workshop_strategy {
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;
}

View File

@ -81,3 +81,46 @@ interface workshop_strategy {
*/
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;
}
}

View File

@ -60,7 +60,7 @@ echo $OUTPUT->header($navigation);
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();
}

View File

@ -98,12 +98,6 @@ class mod_workshop_mod_form extends moodleform_mod {
/// 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;
@ -112,24 +106,21 @@ class mod_workshop_mod_form extends moodleform_mod {
$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');
@ -138,17 +129,12 @@ class mod_workshop_mod_form extends moodleform_mod {
$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');
@ -156,7 +142,6 @@ class mod_workshop_mod_form extends moodleform_mod {
$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');
@ -172,7 +157,6 @@ class mod_workshop_mod_form extends moodleform_mod {
$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'));
@ -206,7 +190,6 @@ class mod_workshop_mod_form extends moodleform_mod {
$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,