diff --git a/mod/workshop/allocation/manual/allocator.php b/mod/workshop/allocation/manual/lib.php similarity index 84% rename from mod/workshop/allocation/manual/allocator.php rename to mod/workshop/allocation/manual/lib.php index 739615c1cf0..2182cb6b2d4 100644 --- a/mod/workshop/allocation/manual/allocator.php +++ b/mod/workshop/allocation/manual/lib.php @@ -192,27 +192,29 @@ class workshop_manual_allocator implements workshop_allocator { $peers = array(); $rs = $this->workshop->get_allocations_recordset(); - foreach ($rs as $allocation) { - $currentuserid = $allocation->authorid; - if (!isset($peers[$currentuserid])) { - $peers[$currentuserid] = new stdClass(); - $peers[$currentuserid]->id = $allocation->authorid; - $peers[$currentuserid]->firstname = $allocation->authorfirstname; - $peers[$currentuserid]->lastname = $allocation->authorlastname; - $peers[$currentuserid]->picture = $allocation->authorpicture; - $peers[$currentuserid]->imagealt = $allocation->authorimagealt; - $peers[$currentuserid]->submissionid = $allocation->submissionid; - $peers[$currentuserid]->submissiontitle = $allocation->submissiontitle; - $peers[$currentuserid]->submissiongrade = $allocation->submissiongrade; - $peers[$currentuserid]->reviewedby = array(); // users who are reviewing this user's submission - $peers[$currentuserid]->reviewerof = array(); // users whom submission is being reviewed by this user - } - if (!empty($allocation->reviewerid)) { - // example: "submission of user with id 45 is reviewed by user with id 87 in the assessment record 12" - $peers[$currentuserid]->reviewedby[$allocation->reviewerid] = $allocation->assessmentid; + if (!is_null($rs)) { + foreach ($rs as $allocation) { + $currentuserid = $allocation->authorid; + if (!isset($peers[$currentuserid])) { + $peers[$currentuserid] = new stdClass(); + $peers[$currentuserid]->id = $allocation->authorid; + $peers[$currentuserid]->firstname = $allocation->authorfirstname; + $peers[$currentuserid]->lastname = $allocation->authorlastname; + $peers[$currentuserid]->picture = $allocation->authorpicture; + $peers[$currentuserid]->imagealt = $allocation->authorimagealt; + $peers[$currentuserid]->submissionid = $allocation->submissionid; + $peers[$currentuserid]->submissiontitle = $allocation->submissiontitle; + $peers[$currentuserid]->submissiongrade = $allocation->submissiongrade; + $peers[$currentuserid]->reviewedby = array(); // users who are reviewing this user's submission + $peers[$currentuserid]->reviewerof = array(); // users whom submission is being reviewed by this user + } + if (!empty($allocation->reviewerid)) { + // example: "submission of user with id 45 is reviewed by user with id 87 in the assessment record 12" + $peers[$currentuserid]->reviewedby[$allocation->reviewerid] = $allocation->assessmentid; + } } + $rs->close(); } - $rs->close(); foreach ($peers as $author) { foreach ($author->reviewedby as $reviewerid => $assessmentid) { @@ -230,8 +232,8 @@ class workshop_manual_allocator implements workshop_allocator { $data = new stdClass(); $data->wsoutput = $wsoutput; $data->peers = $peers; - $data->authors = $this->workshop->get_potential_authors(); - $data->reviewers = $this->workshop->get_potential_reviewers(); + $data->authors = $this->workshop->get_potential_authors($PAGE->context); + $data->reviewers = $this->workshop->get_potential_reviewers($PAGE->context); $data->hlauthorid = $hlauthorid; $data->hlreviewerid = $hlreviewerid; $data->msg = $msg; diff --git a/mod/workshop/allocation/random/allocator.php b/mod/workshop/allocation/random/lib.php similarity index 98% rename from mod/workshop/allocation/random/allocator.php rename to mod/workshop/allocation/random/lib.php index a6f34544745..cba20d52eb0 100644 --- a/mod/workshop/allocation/random/allocator.php +++ b/mod/workshop/allocation/random/lib.php @@ -75,14 +75,14 @@ class workshop_random_allocator implements workshop_allocator { $o = array(); // list of output messages $numofreviews = required_param('numofreviews', PARAM_INT); $numper = required_param('numper', PARAM_INT); - $removecurrent = required_param('removecurrent', PARAM_INT); - $assesswosubmission = required_param('assesswosubmission', PARAM_INT); + $removecurrent = optional_param('removecurrent', false, PARAM_BOOL); + $assesswosubmission = optional_param('assesswosubmission', false, PARAM_BOOL); + $addselfassessment = optional_param('addselfassessment', false, PARAM_BOOL); $musthavesubmission = empty($assesswosubmission); - $addselfassessment = optional_param('addselfassessment', false, PARAM_INT); // may be frozen in the form - $authors = $this->workshop->get_potential_authors(); + $authors = $this->workshop->get_potential_authors($PAGE->context); $authors = $this->workshop->get_grouped($authors); - $reviewers = $this->workshop->get_potential_reviewers($musthavesubmission); + $reviewers = $this->workshop->get_potential_reviewers($PAGE->context, $musthavesubmission); $reviewers = $this->workshop->get_grouped($reviewers); $assessments = $this->workshop->get_all_assessments(); diff --git a/mod/workshop/allocation/random/settings_form.php b/mod/workshop/allocation/random/settings_form.php index da35a5a4c96..59d6e2b6ce5 100644 --- a/mod/workshop/allocation/random/settings_form.php +++ b/mod/workshop/allocation/random/settings_form.php @@ -72,22 +72,17 @@ class workshop_random_allocator_form extends moodleform { $mform->setDefault('numper', workshop_random_allocator::USERTYPE_AUTHOR); $mform->addGroup($grpnumofreviews, 'grpnumofreviews', get_string('numofreviews', 'workshop'), array(' '), false); - $mform->addElement('advcheckbox', 'removecurrent', get_string('removecurrentallocations', 'workshopallocation_random')); + $mform->addElement('checkbox', 'removecurrent', get_string('removecurrentallocations', 'workshopallocation_random')); $mform->setDefault('removecurrent', 0); - $mform->addElement('advcheckbox', 'assesswosubmission', get_string('assesswosubmission', 'workshopallocation_random')); + $mform->addElement('checkbox', 'assesswosubmission', get_string('assesswosubmission', 'workshopallocation_random')); $mform->setDefault('assesswosubmission', 0); - $grpselfassessment = array(); - $grpselfassessment[] = $mform->createElement('advcheckbox', 'addselfassessment'); - $mform->setDefault('addselfassessment', 0); - if (!$workshop->useselfassessment) { - $grpselfassessment[] = $mform->createElement('static', 'selfassessmentcheck', '', - get_string('selfassessmentdisabled', 'workshop')); - } - $mform->addGroup($grpselfassessment, 'grpselfassessment', get_string('addselfassessment', 'workshopallocation_random')); - if (!$workshop->useselfassessment) { - $mform->freeze(array('grpselfassessment')); + if (empty($workshop->useselfassessment)) { + $mform->addElement('static', 'addselfassessment', get_string('addselfassessment', 'workshopallocation_random'), + get_string('selfassessmentdisabled', 'workshop')); + } else { + $mform->addElement('checkbox', 'addselfassessment', get_string('addselfassessment', 'workshopallocation_random')); } $this->add_action_buttons(); diff --git a/mod/workshop/allocation/random/simpletest/testallocator.php b/mod/workshop/allocation/random/simpletest/testallocator.php index 894a6a9e6b3..4a5be21845a 100644 --- a/mod/workshop/allocation/random/simpletest/testallocator.php +++ b/mod/workshop/allocation/random/simpletest/testallocator.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . /** - * Unit tests for mod/workshop/allocation/random/allocator.php + * Unit tests for Random allocation * * @package mod-workshop * @copyright 2009 David Mudrak @@ -26,7 +26,8 @@ defined('MOODLE_INTERNAL') || die(); // Include the code to test -require_once($CFG->dirroot . '/mod/workshop/allocation/random/allocator.php'); +require_once($CFG->dirroot . '/mod/workshop/locallib.php'); +require_once($CFG->dirroot . '/mod/workshop/allocation/random/lib.php'); /** * Make protected methods we want to test public diff --git a/mod/workshop/db/install.xml b/mod/workshop/db/install.xml index 1efdff25ee4..71e39432cbb 100644 --- a/mod/workshop/db/install.xml +++ b/mod/workshop/db/install.xml @@ -1,5 +1,5 @@ - @@ -93,33 +93,20 @@ - +
- - - + + + + - - - - -
- - - - - - - - - - - + +
diff --git a/mod/workshop/develtools.php b/mod/workshop/develtools.php index 12a35891263..3f7672ac489 100644 --- a/mod/workshop/develtools.php +++ b/mod/workshop/develtools.php @@ -53,8 +53,8 @@ $wsoutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE); switch ($tool) { case 'mksubmissions': - $authors = $workshop->get_potential_authors(false); - $authorswithsubmission = $workshop->get_potential_authors(true); + $authors = $workshop->get_potential_authors($PAGE->context, false); + $authorswithsubmission = $workshop->get_potential_authors($PAGE->context, true); $authors = array_diff_key($authors, $authorswithsubmission); echo $OUTPUT->header(); $c = 0; // counter diff --git a/mod/workshop/editform.php b/mod/workshop/editform.php index 63db56c0666..b211f8afb2a 100644 --- a/mod/workshop/editform.php +++ b/mod/workshop/editform.php @@ -70,7 +70,7 @@ if ($mform->is_cancelled()) { echo $OUTPUT->header(); $currenttab = 'editform'; include(dirname(__FILE__) . '/tabs.php'); -echo $OUTPUT->heading(get_string('pluginname', 'workshopgrading_' . $workshop->strategy)); +echo $OUTPUT->heading(get_string('pluginname', 'workshopform_' . $workshop->strategy)); $mform->display(); diff --git a/mod/workshop/grading/accumulative/assessment_form.php b/mod/workshop/form/accumulative/assessment_form.php similarity index 89% rename from mod/workshop/grading/accumulative/assessment_form.php rename to mod/workshop/form/accumulative/assessment_form.php index 3d4c1ffa506..25d6a7e80da 100644 --- a/mod/workshop/grading/accumulative/assessment_form.php +++ b/mod/workshop/form/accumulative/assessment_form.php @@ -50,8 +50,8 @@ class workshop_accumulative_assessment_form extends workshop_assessment_form { for ($i = 0; $i < $nodims; $i++) { // dimension header - $dimtitle = get_string('dimensionnumber', 'workshopgrading_accumulative', $i+1); - $mform->addElement('header', "dimensionhdr__idx_$i", $dimtitle); + $dimtitle = get_string('dimensionnumber', 'workshopform_accumulative', $i+1); + $mform->addElement('header', 'dimensionhdr__idx_'.$i, $dimtitle); // dimension id $mform->addElement('hidden', 'dimensionid__idx_'.$i, $fields->{'dimensionid__idx_'.$i}); @@ -66,12 +66,12 @@ class workshop_accumulative_assessment_form extends workshop_assessment_form { $mform->addElement('html', $desc); // grade for this aspect - $label = get_string('dimensiongrade', 'workshopgrading_accumulative'); + $label = get_string('dimensiongrade', 'workshopform_accumulative'); $options = make_grades_menu($fields->{'grade__idx_' . $i}); $mform->addElement('select', 'grade__idx_' . $i, $label, $options); // comment - $label = get_string('dimensioncomment', 'workshopgrading_accumulative'); + $label = get_string('dimensioncomment', 'workshopform_accumulative'); //$mform->addElement('editor', 'peercomment__idx_' . $i, $label, null, array('maxfiles' => 0)); $mform->addElement('textarea', 'peercomment__idx_' . $i, $label, array('cols' => 60, 'rows' => 5)); } diff --git a/mod/workshop/grading/accumulative/db/install.xml b/mod/workshop/form/accumulative/db/install.xml similarity index 58% rename from mod/workshop/grading/accumulative/db/install.xml rename to mod/workshop/form/accumulative/db/install.xml index 5bfb1e7fce7..075cf24521e 100644 --- a/mod/workshop/grading/accumulative/db/install.xml +++ b/mod/workshop/form/accumulative/db/install.xml @@ -1,20 +1,23 @@ - - +
- - + + + + - + +
-
+
\ No newline at end of file diff --git a/mod/workshop/grading/accumulative/edit_form.php b/mod/workshop/form/accumulative/edit_form.php similarity index 89% rename from mod/workshop/grading/accumulative/edit_form.php rename to mod/workshop/form/accumulative/edit_form.php index dcb2a79e729..9643c91cc3d 100644 --- a/mod/workshop/grading/accumulative/edit_form.php +++ b/mod/workshop/form/accumulative/edit_form.php @@ -55,20 +55,21 @@ class workshop_edit_accumulative_strategy_form extends workshop_edit_strategy_fo $weights = workshop_get_dimension_weights(); for ($i = 0; $i < $norepeats; $i++) { - $mform->addElement('header', 'dimension'.$i, get_string('dimensionnumber', 'workshopgrading_accumulative', $i+1)); - $mform->addElement('hidden', 'dimensionid__idx_'.$i); // the id in workshop_forms + $mform->addElement('header', 'dimension'.$i, get_string('dimensionnumber', 'workshopform_accumulative', $i+1)); + $mform->addElement('hidden', 'dimensionid__idx_'.$i); $mform->addElement('editor', 'description__idx_'.$i.'_editor', - get_string('dimensiondescription', 'workshopgrading_accumulative'), '', $descriptionopts); + get_string('dimensiondescription', 'workshopform_accumulative'), '', $descriptionopts); + // todo replace modgrade with an advanced element (usability issue discussed with Olli) $mform->addElement('modgrade', 'grade__idx_'.$i, - get_string('dimensionmaxgrade','workshopgrading_accumulative'), null, true); + get_string('dimensionmaxgrade','workshopform_accumulative'), null, true); $mform->setDefault('grade__idx_'.$i, 10); $mform->addElement('select', 'weight__idx_'.$i, - get_string('dimensionweight', 'workshopgrading_accumulative'), $weights); + get_string('dimensionweight', 'workshopform_accumulative'), $weights); $mform->setDefault('weight__idx_'.$i, 1); } $mform->registerNoSubmitButton('noadddims'); - $mform->addElement('submit', 'noadddims', get_string('addmoredimensions', 'workshopgrading_accumulative', + $mform->addElement('submit', 'noadddims', get_string('addmoredimensions', 'workshopform_accumulative', WORKSHOP_STRATEGY_ADDDIMS)); $mform->closeHeaderBefore('noadddims'); $this->set_data($current); diff --git a/mod/workshop/grading/accumulative/lang/en_utf8/workshopgrading_accumulative.php b/mod/workshop/form/accumulative/lang/en_utf8/workshopform_accumulative.php similarity index 100% rename from mod/workshop/grading/accumulative/lang/en_utf8/workshopgrading_accumulative.php rename to mod/workshop/form/accumulative/lang/en_utf8/workshopform_accumulative.php diff --git a/mod/workshop/grading/accumulative/strategy.php b/mod/workshop/form/accumulative/lib.php similarity index 76% rename from mod/workshop/grading/accumulative/strategy.php rename to mod/workshop/form/accumulative/lib.php index d85aafede7b..609291ce204 100644 --- a/mod/workshop/grading/accumulative/strategy.php +++ b/mod/workshop/form/accumulative/lib.php @@ -53,8 +53,6 @@ class workshop_accumulative_strategy implements workshop_strategy { $this->descriptionopts = array('trusttext' => true, 'subdirs' => false, 'maxfiles' => -1); } -/// Public API - /** * Factory method returning an instance of an assessment form editor class * @@ -112,34 +110,29 @@ class workshop_accumulative_strategy implements workshop_strategy { $norepeats = $data->norepeats; $data = $this->prepare_database_fields($data); - $masters = $data->forms; // data to be saved into workshop_forms - $locals = $data->accumulative; // data to be saved into workshop_forms_accumulative - $todelete = array(); // master ids to be deleted + $records = $data->accumulative; // records to be saved into {workshopform_accumulative} + $todelete = array(); // dimension ids to be deleted for ($i=0; $i < $norepeats; $i++) { - $local = $locals[$i]; - $master = $masters[$i]; - if (empty($local->description_editor['text'])) { - if (!empty($master->id)) { + $record = $records[$i]; + if (empty($record->description_editor['text'])) { + if (!empty($record->id)) { // existing record with empty description - to be deleted - $todelete[] = $master->id; + $todelete[] = $record->id; } continue; } - if (empty($master->id)) { + if (empty($record->id)) { // new field - $local->id = $DB->insert_record("workshop_forms_accumulative", $local); - $master->localid = $local->id; - $master->id = $DB->insert_record("workshop_forms", $master); + $record->id = $DB->insert_record('workshopform_accumulative', $record); } else { // exiting field - $DB->update_record("workshop_forms", $master); - $local->id = $DB->get_field("workshop_forms", "localid", array("id" => $master->id), MUST_EXIST); + $DB->update_record('workshopform_accumulative', $record); } // re-save with correct path to embeded media files - $local = file_postupdate_standard_editor($local, 'description', $this->descriptionopts, - $PAGE->context, 'workshop_dimension_description', $master->id); - $DB->update_record("workshop_forms_accumulative", $local); + $record = file_postupdate_standard_editor($record, 'description', $this->descriptionopts, + $PAGE->context, 'workshopform_accumulative_description', $record->id); + $DB->update_record('workshopform_accumulative', $record); } $this->delete_dimensions($todelete); } @@ -162,12 +155,12 @@ class workshop_accumulative_strategy implements workshop_strategy { // rewrite URLs to the embeded files for ($i = 0; $i < $nodimensions; $i++) { $fields->{'description__idx_'.$i} = file_rewrite_pluginfile_urls($fields->{'description__idx_'.$i}, - 'pluginfile.php', $PAGE->context->id, 'workshop_dimension_description', $fields->{'dimensionid__idx_'.$i}); + 'pluginfile.php', $PAGE->context->id, 'workshopform_accumulative_description', $fields->{'dimensionid__idx_'.$i}); } if ('assessment' === $mode and !empty($assessment)) { // load the previously saved assessment data - $grades = $this->reindex_grades_by_dimension($this->get_current_assessment_data($assessment)); + $grades = $this->get_current_assessment_data($assessment); $current = new stdClass(); for ($i = 0; $i < $nodimensions; $i++) { $dimid = $fields->{'dimensionid__idx_'.$i}; @@ -181,6 +174,7 @@ class workshop_accumulative_strategy implements workshop_strategy { // set up the required custom data common for all strategies $customdata['strategy'] = $this; + $customdata['workshop'] = $this->workshop; $customdata['mode'] = $mode; // set up strategy-specific custom data @@ -211,10 +205,11 @@ class workshop_accumulative_strategy implements workshop_strategy { $grade = new stdClass(); $grade->id = $data->{'gradeid__idx_' . $i}; $grade->assessmentid = $assessment->id; + $grade->strategy = 'accumulative'; $grade->dimensionid = $data->{'dimensionid__idx_' . $i}; $grade->grade = $data->{'grade__idx_' . $i}; $grade->peercomment = $data->{'peercomment__idx_' . $i}; - $grade->peercommentformat = FORMAT_HTML; + $grade->peercommentformat = FORMAT_MOODLE; if (empty($grade->id)) { // new grade $grade->id = $DB->insert_record('workshop_grades', $grade); @@ -238,7 +233,9 @@ class workshop_accumulative_strategy implements workshop_strategy { return false; } -/// Internal methods +//////////////////////////////////////////////////////////////////////////////// +// Internal methods // +//////////////////////////////////////////////////////////////////////////////// /** * Loads the fields of the assessment form currently used in this workshop @@ -248,12 +245,11 @@ class workshop_accumulative_strategy implements workshop_strategy { protected function load_fields() { global $DB; - $sql = "SELECT master.id,dim.description,dim.descriptionformat,dim.grade,dim.weight - FROM {workshop_forms} master - INNER JOIN {workshop_forms_accumulative} dim ON (dim.id=master.localid) - WHERE master.workshopid = :workshopid AND master.strategy = :strategy - ORDER BY master.sort"; - $params = array("workshopid" => $this->workshop->id, "strategy" => $this->workshop->strategy); + $sql = 'SELECT * + FROM {workshopform_accumulative} + WHERE workshopid = :workshopid + ORDER BY sort'; + $params = array('workshopid' => $this->workshop->id); return $DB->get_records_sql($sql, $params); } @@ -269,7 +265,7 @@ class workshop_accumulative_strategy implements workshop_strategy { $formdata = new stdClass(); $key = 0; foreach ($raw as $dimension) { - $formdata->{'dimensionid__idx_' . $key} = $dimension->id; // master id, not the local one! + $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; @@ -287,20 +283,16 @@ class workshop_accumulative_strategy implements workshop_strategy { * @param array $masterids * @return void */ - protected function delete_dimensions($masterids) { + protected function delete_dimensions(array $ids) { global $DB, $PAGE; - $masters = $DB->get_records_list("workshop_forms", "id", $masterids, "", "id,localid"); - $masterids = array_keys($masters); // now contains only those really existing - $localids = array(); - $fs = get_file_storage(); - - foreach ($masters as $itemid => $master) { - $fs->delete_area_files($PAGE->context->id, 'workshop_dimension_description', $itemid); - $localids[] = $master->localid; + $fs = get_file_storage(); + foreach ($ids as $id) { + if (!empty($id)) { // to prevent accidental removal of all files in the area + $fs->delete_area_files($PAGE->context->id, 'workshopform_accumulative_description', $id); + } } - $DB->delete_records_list("workshop_forms_accumulative", "id", $localids); - $DB->delete_records_list("workshop_forms", "id", $masterids); + $DB->delete_records_list('workshopform_accumulative', 'id', $ids); } /** @@ -318,57 +310,38 @@ class workshop_accumulative_strategy implements workshop_strategy { global $PAGE; $cook = new stdClass(); // to be returned - $cook->forms = array(); // to be stored in {workshop_forms} - $cook->accumulative = array(); // to be stored in {workshop_forms_accumulative} + $cook->accumulative = array(); // records to be stored in {workshopform_accumulative} for ($i = 0; $i < $raw->norepeats; $i++) { - $cook->forms[$i] = new stdClass(); - $cook->forms[$i]->id = $raw->{'dimensionid__idx_'.$i}; - $cook->forms[$i]->workshopid = $this->workshop->id; - $cook->forms[$i]->sort = $i + 1; - $cook->forms[$i]->strategy = 'accumulative'; - - $cook->accumulative[$i] = new stdClass(); + $cook->accumulative[$i] = new stdClass(); + $cook->accumulative[$i]->id = $raw->{'dimensionid__idx_'.$i}; + $cook->accumulative[$i]->workshopid = $this->workshop->id; + $cook->accumulative[$i]->sort = $i + 1; $cook->accumulative[$i]->description_editor = $raw->{'description__idx_'.$i.'_editor'}; - $cook->accumulative[$i]->grade = $raw->{'grade__idx_'.$i}; - $cook->accumulative[$i]->weight = $raw->{'weight__idx_'.$i}; + $cook->accumulative[$i]->grade = $raw->{'grade__idx_'.$i}; + $cook->accumulative[$i]->weight = $raw->{'weight__idx_'.$i}; } return $cook; } /** - * Returns the list of current grades filled by the reviewer + * Returns the list of current grades filled by the reviewer indexed by dimensionid * * @param stdClass $assessment Assessment record - * @return array of filtered records from the table workshop_grades + * @return array [int dimensionid] => stdClass workshop_grades record */ protected function get_current_assessment_data(stdClass $assessment) { global $DB; - // fetch all grades accociated with this assessment - $grades = $DB->get_records("workshop_grades", array("assessmentid" => $assessment->id)); + list($dimsql, $dimparams) = $DB->get_in_or_equal(array_keys($this->dimensions), SQL_PARAMS_NAMED); + // beware! the caller may rely on the returned array is indexed by dimensionid + $sql = "SELECT dimensionid, * + FROM {workshop_grades} + WHERE assessmentid = :assessmentid AND strategy= :strategy AND dimensionid $dimsql"; + $params = array('assessmentid' => $assessment->id, 'strategy' => 'acumulative'); + $params = array_merge($params, $dimparams); - // filter grades given under an other strategy or assessment form - foreach ($grades as $grade) { - if (!isset($this->dimensions[$grade->dimensionid])) { - unset ($grades[$grade->id]); - } - } - return $grades; - } - - /** - * Reindexes the records returned by {@link get_current_assessment_data} by dimensionid - * - * @param mixed $grades - * @return array - */ - protected function reindex_grades_by_dimension($grades) { - $reindexed = array(); - foreach ($grades as $grade) { - $reindexed[$grade->dimensionid] = $grade; - } - return $reindexed; + return $DB->get_records_sql($sql, $params); } /** @@ -405,7 +378,7 @@ class workshop_accumulative_strategy implements workshop_strategy { if ($dimension->weight < 0) { throw new coding_exception('Negative weights are not supported any more. Something is wrong with your data'); } - if ($dimension->weight == 0 or $dimension->grade == 0) { + if (grade_floats_equal($dimension->weight, 0) or grade_floats_equal($dimension->grade, 0)) { // does not influence the final grade continue; } @@ -424,7 +397,7 @@ class workshop_accumulative_strategy implements workshop_strategy { if ($sumweights === 0) { return 0; } - return $sumgrades / $sumweights; + return grade_floatval($sumgrades / $sumweights); } /** diff --git a/mod/workshop/grading/accumulative/simpletest/teststrategy.php b/mod/workshop/form/accumulative/simpletest/teststrategy.php similarity index 78% rename from mod/workshop/grading/accumulative/simpletest/teststrategy.php rename to mod/workshop/form/accumulative/simpletest/teststrategy.php index 72577a7520f..b8888d17567 100644 --- a/mod/workshop/grading/accumulative/simpletest/teststrategy.php +++ b/mod/workshop/form/accumulative/simpletest/teststrategy.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . /** - * Unit tests for (some of) mod/workshop/grading/accumulative/strategy.php + * Unit tests for Accumulative grading strategy logic * * @package mod-workshop * @copyright 2009 David Mudrak @@ -26,7 +26,8 @@ defined('MOODLE_INTERNAL') || die(); // Include the code to test -require_once($CFG->dirroot . '/mod/workshop/grading/accumulative/strategy.php'); +require_once($CFG->dirroot . '/mod/workshop/locallib.php'); +require_once($CFG->dirroot . '/mod/workshop/form/accumulative/lib.php'); global $DB; Mock::generate(get_class($DB), 'mockDB'); @@ -93,18 +94,18 @@ class workshop_accumulative_strategy_test extends UnitTestCase { public function test_calculate_peer_grade_one_numerical() { // fixture set-up - $this->strategy->dimensions[1003] = (object)array('grade' => 20, 'weight' => 1); - $grades[] = (object)array('dimensionid' => 1003, 'grade' => 5); + $this->strategy->dimensions[1003] = (object)array('grade' => '20', 'weight' => '1'); + $grades[] = (object)array('dimensionid' => 1003, 'grade' => '5.00000'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); // validate - $this->assertEqual(5/20, $suggested); + $this->assertEqual(grade_floatval(5/20), $suggested); } public function test_calculate_peer_grade_negative_weight() { // fixture set-up - $this->strategy->dimensions[1003] = (object)array('grade' => 20, 'weight' => -1); - $grades[] = (object)array('dimensionid' => 1003, 'grade' => 20); + $this->strategy->dimensions[1003] = (object)array('grade' => '20', 'weight' => '-1'); + $grades[] = (object)array('dimensionid' => 1003, 'grade' => '20'); $this->expectException('coding_exception'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); @@ -112,46 +113,46 @@ class workshop_accumulative_strategy_test extends UnitTestCase { public function test_calculate_peer_grade_one_numerical_weighted() { // fixture set-up - $this->strategy->dimensions[1003] = (object)array('grade' => 20, 'weight' => 3); - $grades[] = (object)array('dimensionid' => 1003, 'grade' => 5); + $this->strategy->dimensions[1003] = (object)array('grade' => '20', 'weight' => '3'); + $grades[] = (object)array('dimensionid' => '1003', 'grade' => '5'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); // validate - $this->assertEqual(5/20, $suggested); + $this->assertEqual(grade_floatval(5/20), $suggested); } public function test_calculate_peer_grade_three_numericals_same_weight() { // fixture set-up - $this->strategy->dimensions[1003] = (object)array('grade' =>20, 'weight' => 2); - $this->strategy->dimensions[1004] = (object)array('grade' =>100, 'weight' => 2); - $this->strategy->dimensions[1005] = (object)array('grade' =>10, 'weight' => 2); + $this->strategy->dimensions[1003] = (object)array('grade' => '20', 'weight' => '2'); + $this->strategy->dimensions[1004] = (object)array('grade' => '100', 'weight' => '2'); + $this->strategy->dimensions[1005] = (object)array('grade' => '10', 'weight' => '2'); - $grades[] = (object)array('dimensionid' => 1003, 'grade' => 11); - $grades[] = (object)array('dimensionid' => 1004, 'grade' => 87); - $grades[] = (object)array('dimensionid' => 1005, 'grade' => 10); + $grades[] = (object)array('dimensionid' => 1003, 'grade' => '11.00000'); + $grades[] = (object)array('dimensionid' => 1004, 'grade' => '87.00000'); + $grades[] = (object)array('dimensionid' => 1005, 'grade' => '10.00000'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); // validate - $this->assertEqual((11/20 + 87/100 + 10/10)/3, $suggested); + $this->assertEqual(grade_floatval((11/20 + 87/100 + 10/10)/3), $suggested); } public function test_calculate_peer_grade_three_numericals_different_weights() { // fixture set-up - $this->strategy->dimensions[1003] = (object)array('grade' =>15, 'weight' => 3); - $this->strategy->dimensions[1004] = (object)array('grade' =>80, 'weight' => 1); - $this->strategy->dimensions[1005] = (object)array('grade' =>5, 'weight' => 2); + $this->strategy->dimensions[1003] = (object)array('grade' => '15', 'weight' => 3); + $this->strategy->dimensions[1004] = (object)array('grade' => '80', 'weight' => 1); + $this->strategy->dimensions[1005] = (object)array('grade' => '5', 'weight' => 2); - $grades[] = (object)array('dimensionid' => 1003, 'grade' => 7); - $grades[] = (object)array('dimensionid' => 1004, 'grade' => 66); - $grades[] = (object)array('dimensionid' => 1005, 'grade' => 4); + $grades[] = (object)array('dimensionid' => 1003, 'grade' => '7.00000'); + $grades[] = (object)array('dimensionid' => 1004, 'grade' => '66.00000'); + $grades[] = (object)array('dimensionid' => 1005, 'grade' => '4.00000'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); // validate - $this->assertEqual((7/15*3 + 66/80*1 + 4/5*2)/6, $suggested); + $this->assertEqual(grade_floatval((7/15*3 + 66/80*1 + 4/5*2)/6), $suggested); } public function test_calculate_peer_grade_one_scale_max() { @@ -159,31 +160,31 @@ class workshop_accumulative_strategy_test extends UnitTestCase { // fixture set-up $mockscale = 'E,D,C,B,A'; - $this->strategy->dimensions[1008] = (object)array('grade' => -10, 'weight' => 1); - $grades[] = (object)array('dimensionid' => 1008, 'grade' => 5); - $DB->expectOnce('get_field', array("scales", "scale", array("id" => 10), MUST_EXIST)); + $this->strategy->dimensions[1008] = (object)array('grade' => '-10', 'weight' => 1); + $grades[] = (object)array('dimensionid' => 1008, 'grade' => '5.00000'); + $DB->expectOnce('get_field', array('scales', 'scale', array('id' => 10), MUST_EXIST)); $DB->setReturnValue('get_field', $mockscale); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); // validate - $this->assertEqual(1, $suggested); + $this->assertEqual(1.00000, $suggested); } public function test_calculate_peer_grade_one_scale_min_with_scale_caching() { global $DB; // fixture set-up - $this->strategy->dimensions[1008] = (object)array('grade' => -10, 'weight' => 1); - $grades[] = (object)array('dimensionid' => 1008, 'grade' => 1); - $DB->expectNever('get_field', array("scales", "scale", array("id" => 10), MUST_EXIST)); // cached + $this->strategy->dimensions[1008] = (object)array('grade' => '-10', 'weight' => 1); + $grades[] = (object)array('dimensionid' => 1008, 'grade' => '1.00000'); + $DB->expectNever('get_field', array('scales', 'scale', array('id' => 10), MUST_EXIST)); // cached // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); // validate - $this->assertEqual(0, $suggested); + $this->assertEqual(0.00000, $suggested); } public function test_calculate_peer_grade_two_scales_weighted() { @@ -193,23 +194,23 @@ class workshop_accumulative_strategy_test extends UnitTestCase { $mockscale13 = 'Poor,Good,Excellent'; $mockscale17 = '-,*,**,***,****,*****,******'; - $this->strategy->dimensions[1012] = (object)array('grade' => -13, 'weight' => 2); - $this->strategy->dimensions[1019] = (object)array('grade' => -17, 'weight' => 3); + $this->strategy->dimensions[1012] = (object)array('grade' => '-13', 'weight' => 2); + $this->strategy->dimensions[1019] = (object)array('grade' => '-17', 'weight' => 3); - $grades[] = (object)array('dimensionid' => 1012, 'grade' => 2); // "Good" - $grades[] = (object)array('dimensionid' => 1019, 'grade' => 5); // "****" + $grades[] = (object)array('dimensionid' => 1012, 'grade' => '2.00000'); // "Good" + $grades[] = (object)array('dimensionid' => 1019, 'grade' => '5.00000'); // "****" - $DB->expectAt(0, 'get_field', array("scales", "scale", array("id" => 13), MUST_EXIST)); + $DB->expectAt(0, 'get_field', array('scales', 'scale', array('id' => 13), MUST_EXIST)); $DB->setReturnValueAt(0, 'get_field', $mockscale13); - $DB->expectAt(1, 'get_field', array("scales", "scale", array("id" => 17), MUST_EXIST)); + $DB->expectAt(1, 'get_field', array('scales', 'scale', array('id' => 17), MUST_EXIST)); $DB->setReturnValueAt(1, 'get_field', $mockscale17); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); // validate - $this->assertEqual((1/2*2 + 4/6*3)/5, $suggested); + $this->assertEqual(grade_floatval((1/2*2 + 4/6*3)/5), $suggested); } public function test_calculate_peer_grade_scale_exception() { @@ -218,8 +219,8 @@ class workshop_accumulative_strategy_test extends UnitTestCase { // fixture set-up $mockscale13 = 'Poor,Good,Excellent'; $this->strategy->dimensions[1012] = (object)array('grade' => -13, 'weight' => 1); - $DB->expectNever('get_field', array("scales", "scale", array("id" => 13), MUST_EXIST)); // cached - $grades[] = (object)array('dimensionid' => 1012, 'grade' => 4); // exceeds the number of scale items + $DB->expectNever('get_field', array('scales', 'scale', array('id' => 13), MUST_EXIST)); // cached + $grades[] = (object)array('dimensionid' => 1012, 'grade' => '4.00000'); // exceeds the number of scale items $this->expectException('coding_exception'); // excercise SUT diff --git a/mod/workshop/grading/accumulative/version.php b/mod/workshop/form/accumulative/version.php similarity index 100% rename from mod/workshop/grading/accumulative/version.php rename to mod/workshop/form/accumulative/version.php diff --git a/mod/workshop/grading/assessment_form.php b/mod/workshop/form/assessment_form.php similarity index 89% rename from mod/workshop/grading/assessment_form.php rename to mod/workshop/form/assessment_form.php index 77754a82f3f..16dd0691786 100644 --- a/mod/workshop/grading/assessment_form.php +++ b/mod/workshop/form/assessment_form.php @@ -53,7 +53,11 @@ class workshop_assessment_form extends moodleform { $mform = $this->_form; $this->mode = $this->_customdata['mode']; // influences the save buttons - $this->strategy = $this->_customdata['strategy']; // strategy name sends back for cross check + $this->strategy = $this->_customdata['strategy']; // instance of the strategy api class + $this->workshop = $this->_customdata['workshop']; // instance of the workshop api class + + // add the data common for all subplugins + $mform->addElement('hidden', 'strategy', $this->workshop->strategy); // add the strategy-specific fields $this->definition_inner($mform); diff --git a/mod/workshop/form/comments/db/install.xml b/mod/workshop/form/comments/db/install.xml new file mode 100644 index 00000000000..191ae1adfab --- /dev/null +++ b/mod/workshop/form/comments/db/install.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + +
+
+
\ No newline at end of file diff --git a/mod/workshop/grading/edit_form.php b/mod/workshop/form/edit_form.php similarity index 96% rename from mod/workshop/grading/edit_form.php rename to mod/workshop/form/edit_form.php index dc552e5fc87..daac75a113f 100644 --- a/mod/workshop/grading/edit_form.php +++ b/mod/workshop/form/edit_form.php @@ -58,7 +58,8 @@ class workshop_edit_strategy_form extends moodleform { $this->workshop = $this->_customdata['workshop']; $this->strategy = $this->_customdata['strategy']; - $mform->addElement('hidden', 'workshopid', $this->workshop->id); + $mform->addElement('hidden', 'workshopid', $this->workshop->id); // workshopid + $mform->addElement('hidden', 'strategy', $this->workshop->strategy); // strategy name $this->definition_inner($mform); diff --git a/mod/workshop/grading/lib.php b/mod/workshop/form/lib.php similarity index 94% rename from mod/workshop/grading/lib.php rename to mod/workshop/form/lib.php index 1efde373350..bd5239c7c1a 100644 --- a/mod/workshop/grading/lib.php +++ b/mod/workshop/form/lib.php @@ -46,7 +46,7 @@ interface workshop_strategy { * * Assessment dimension (also know as assessment element) represents one aspect or criterion * to be evaluated. Each dimension consists of a set of form fields. Strategy-specific information - * are saved in workshop_forms_{strategyname} tables. + * are saved in workshopform_{strategyname} tables. * * @param stdClass $data Raw data as returned by the form editor * @return void @@ -65,7 +65,9 @@ interface workshop_strategy { * Saves the filled assessment and returns the grade for submission as suggested by the reviewer * * This method processes data submitted using the form returned by {@link get_assessment_form()} + * The returned grade should be rounded to 5 decimals as with round($grade, 5). * + * @see grade_floatval() * @param stdClass $assessment Assessment being filled * @param stdClass $data Raw data as returned by the assessment form * @return float|null Raw grade (0 to 1) for submission as suggested by the peer or null if impossible to count diff --git a/mod/workshop/grading/noerrors/assessment_form.php b/mod/workshop/form/numerrors/assessment_form.php similarity index 83% rename from mod/workshop/grading/noerrors/assessment_form.php rename to mod/workshop/form/numerrors/assessment_form.php index 56d6685b5ba..6d92199a12a 100644 --- a/mod/workshop/grading/noerrors/assessment_form.php +++ b/mod/workshop/form/numerrors/assessment_form.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . /** - * This file defines an mform to assess a submission by noerrors grading strategy + * This file defines an mform to assess a submission by numerrors grading strategy * * @package mod-workshop * @copyright 2009 David Mudrak @@ -28,11 +28,11 @@ defined('MOODLE_INTERNAL') || die(); require_once(dirname(dirname(__FILE__)).'/assessment_form.php'); // parent class definition /** - * Class representing a form for assessing submissions by noerrors grading strategy + * Class representing a form for assessing submissions by numerrors grading strategy * * @uses moodleform */ -class workshop_noerrors_assessment_form extends workshop_assessment_form { +class workshop_numerrors_assessment_form extends workshop_assessment_form { /** * Define the elements to be displayed at the form @@ -50,7 +50,7 @@ class workshop_noerrors_assessment_form extends workshop_assessment_form { for ($i = 0; $i < $nodims; $i++) { // dimension header - $dimtitle = get_string('dimensionnumber', 'workshopgrading_noerrors', $i+1); + $dimtitle = get_string('dimensionnumber', 'workshopform_numerrors', $i+1); $mform->addElement('header', "dimensionhdr__idx_$i", $dimtitle); // dimension id @@ -60,19 +60,19 @@ class workshop_noerrors_assessment_form extends workshop_assessment_form { $mform->addElement('hidden', 'gradeid__idx_'.$i); // value set by set_data() later // dimension description - $desc = '
'."\n"; + $desc = '
'."\n"; $desc .= format_text($fields->{'description__idx_'.$i}, $fields->{'description__idx_'.$i.'format'}); $desc .= "\n
"; $mform->addElement('html', $desc); // evaluation of the assertion - $label = get_string('dimensiongrade', 'workshopgrading_noerrors'); + $label = get_string('dimensiongrade', 'workshopform_numerrors'); $mform->addElement('radio', 'grade__idx_' . $i, 'Your assessment', $fields->{'grade0__idx_'.$i}, 0); // todo localize $mform->addElement('radio', 'grade__idx_' . $i, '', $fields->{'grade1__idx_'.$i}, 1); $mform->setDefault('grade__idx_' . $i, 0); // comment - $label = get_string('dimensioncomment', 'workshopgrading_noerrors'); + $label = get_string('dimensioncomment', 'workshopform_numerrors'); $mform->addElement('textarea', 'peercomment__idx_' . $i, $label, array('cols' => 60, 'rows' => 5)); } $this->set_data($current); diff --git a/mod/workshop/grading/noerrors/db/install.xml b/mod/workshop/form/numerrors/db/install.xml similarity index 70% rename from mod/workshop/grading/noerrors/db/install.xml rename to mod/workshop/form/numerrors/db/install.xml index 57c2b7213da..0107271b96c 100644 --- a/mod/workshop/grading/noerrors/db/install.xml +++ b/mod/workshop/form/numerrors/db/install.xml @@ -1,13 +1,15 @@ - - +
- - + + + + @@ -15,10 +17,11 @@ - + +
- +
diff --git a/mod/workshop/grading/noerrors/edit_form.php b/mod/workshop/form/numerrors/edit_form.php similarity index 84% rename from mod/workshop/grading/noerrors/edit_form.php rename to mod/workshop/form/numerrors/edit_form.php index 9f78138aae0..a4c0731f4df 100644 --- a/mod/workshop/grading/noerrors/edit_form.php +++ b/mod/workshop/form/numerrors/edit_form.php @@ -33,7 +33,7 @@ require_once(dirname(dirname(__FILE__)).'/edit_form.php'); // parent class de * * @uses moodleform */ -class workshop_edit_noerrors_strategy_form extends workshop_edit_strategy_form { +class workshop_edit_numerrors_strategy_form extends workshop_edit_strategy_form { /** * Define the elements to be displayed at the form @@ -44,7 +44,7 @@ class workshop_edit_noerrors_strategy_form extends workshop_edit_strategy_form { */ protected function definition_inner(&$mform) { - $plugindefaults = get_config('workshopgrading_noerrors'); + $plugindefaults = get_config('workshopform_numerrors'); $nodimensions = $this->_customdata['nodimensions']; // number of currently filled dimensions $norepeats = $this->_customdata['norepeats']; // number of dimensions to display $descriptionopts = $this->_customdata['descriptionopts']; // wysiwyg fields options @@ -57,23 +57,23 @@ class workshop_edit_noerrors_strategy_form extends workshop_edit_strategy_form { $weights = workshop_get_dimension_weights(); for ($i = 0; $i < $norepeats; $i++) { - $mform->addElement('header', 'dimension'.$i, get_string('dimensionnumber', 'workshopgrading_noerrors', $i+1)); + $mform->addElement('header', 'dimension'.$i, get_string('dimensionnumber', 'workshopform_numerrors', $i+1)); $mform->addElement('hidden', 'dimensionid__idx_'.$i); // the id in workshop_forms $mform->addElement('editor', 'description__idx_'.$i.'_editor', - get_string('dimensiondescription', 'workshopgrading_noerrors'), '', $descriptionopts); - $mform->addElement('text', 'grade0__idx_'.$i, get_string('grade0', 'workshopgrading_noerrors'), array('size'=>'15')); + get_string('dimensiondescription', 'workshopform_numerrors'), '', $descriptionopts); + $mform->addElement('text', 'grade0__idx_'.$i, get_string('grade0', 'workshopform_numerrors'), array('size'=>'15')); $mform->setDefault('grade0__idx_'.$i, $plugindefaults->grade0); $mform->setType('grade0__idx_'.$i, PARAM_TEXT); - $mform->addElement('text', 'grade1__idx_'.$i, get_string('grade1', 'workshopgrading_noerrors'), array('size'=>'15')); + $mform->addElement('text', 'grade1__idx_'.$i, get_string('grade1', 'workshopform_numerrors'), array('size'=>'15')); $mform->setDefault('grade1__idx_'.$i, $plugindefaults->grade1); $mform->setType('grade1__idx_'.$i, PARAM_TEXT); - $mform->addElement('select', 'weight__idx_'.$i, get_string('dimensionweight', 'workshopgrading_noerrors'), $weights); + $mform->addElement('select', 'weight__idx_'.$i, get_string('dimensionweight', 'workshopform_numerrors'), $weights); $mform->setDefault('weight__idx_'.$i, 1); } - $mform->addElement('header', 'mappingheader', get_string('grademapping', 'workshopgrading_noerrors')); - $mform->addElement('static', 'mappinginfo', get_string('maperror', 'workshopgrading_noerrors'), - get_string('mapgrade', 'workshopgrading_noerrors')); + $mform->addElement('header', 'mappingheader', get_string('grademapping', 'workshopform_numerrors')); + $mform->addElement('static', 'mappinginfo', get_string('maperror', 'workshopform_numerrors'), + get_string('mapgrade', 'workshopform_numerrors')); // get the total weight of all items == maximum weighted number of errors $totalweight = 0; @@ -87,20 +87,20 @@ class workshop_edit_noerrors_strategy_form extends workshop_edit_strategy_form { $percents = array(); $percents[''] = ''; for ($i = 100; $i >= 0; $i--) { - $percents[$i] = get_string('percents', 'workshopgrading_noerrors', $i); + $percents[$i] = get_string('percents', 'workshopform_numerrors', $i); } - $mform->addElement('static', 'mappingzero', 0, get_string('percents', 'workshopgrading_noerrors', 100)); + $mform->addElement('static', 'mappingzero', 0, get_string('percents', 'workshopform_numerrors', 100)); for ($i = 1; $i <= $totalweight; $i++) { $selects = array(); $selects[] = $mform->createElement('select', 'map__idx_'.$i, $i, $percents); $selects[] = $mform->createElement('static', 'mapdefault__idx_'.$i, '', - get_string('percents', 'workshopgrading_noerrors', floor(100 - $i * 100 / $totalweight))); + get_string('percents', 'workshopform_numerrors', floor(100 - $i * 100 / $totalweight))); $mform->addGroup($selects, 'grademapping'.$i, $i, array(' '), false); $mform->setDefault('map__idx_'.$i, ''); } $mform->registerNoSubmitButton('noadddims'); - $mform->addElement('submit', 'noadddims', get_string('addmoredimensions', 'workshopgrading_noerrors', + $mform->addElement('submit', 'noadddims', get_string('addmoredimensions', 'workshopform_numerrors', WORKSHOP_STRATEGY_ADDDIMS)); $mform->closeHeaderBefore('noadddims'); $this->set_data($current); diff --git a/mod/workshop/grading/noerrors/lang/en_utf8/workshopgrading_noerrors.php b/mod/workshop/form/numerrors/lang/en_utf8/workshopform_numerrors.php similarity index 100% rename from mod/workshop/grading/noerrors/lang/en_utf8/workshopgrading_noerrors.php rename to mod/workshop/form/numerrors/lang/en_utf8/workshopform_numerrors.php diff --git a/mod/workshop/grading/noerrors/strategy.php b/mod/workshop/form/numerrors/lib.php similarity index 70% rename from mod/workshop/grading/noerrors/strategy.php rename to mod/workshop/form/numerrors/lib.php index 77e9021610e..5a6e494fd16 100644 --- a/mod/workshop/grading/noerrors/strategy.php +++ b/mod/workshop/form/numerrors/lib.php @@ -25,12 +25,13 @@ defined('MOODLE_INTERNAL') || die(); -require_once(dirname(dirname(__FILE__)) . '/lib.php'); // interface definition +require_once(dirname(dirname(__FILE__)) . '/lib.php'); // interface definition +require_once($CFG->libdir . '/gradelib.php'); // to handle float vs decimal issues /** * "Number of errors" grading strategy logic. */ -class workshop_noerrors_strategy implements workshop_strategy { +class workshop_numerrors_strategy implements workshop_strategy { /** @var workshop the parent workshop instance */ protected $workshop; @@ -57,8 +58,6 @@ class workshop_noerrors_strategy implements workshop_strategy { $this->descriptionopts = array('trusttext' => true, 'subdirs' => false, 'maxfiles' => -1); } -/// Public API methods - /** * Factory method returning an instance of an assessment form editor class * @@ -83,7 +82,7 @@ class workshop_noerrors_strategy implements workshop_strategy { for ($i = 0; $i < $nodimensions; $i++) { // prepare all editor elements $fields = file_prepare_standard_editor($fields, 'description__idx_'.$i, $this->descriptionopts, - $PAGE->context, 'workshop_dimension_description', $fields->{'dimensionid__idx_'.$i}); + $PAGE->context, 'workshopform_numerrors_description', $fields->{'dimensionid__idx_'.$i}); } $customdata = array(); @@ -95,7 +94,7 @@ class workshop_noerrors_strategy implements workshop_strategy { $customdata['current'] = $fields; $attributes = array('class' => 'editstrategyform'); - return new workshop_edit_noerrors_strategy_form($actionurl, $customdata, 'post', '', $attributes); + return new workshop_edit_numerrors_strategy_form($actionurl, $customdata, 'post', '', $attributes); } /** @@ -117,35 +116,30 @@ class workshop_noerrors_strategy implements workshop_strategy { $norepeats = $data->norepeats; $data = $this->prepare_database_fields($data); - $masters = $data->forms; // data to be saved into {workshop_forms} - $locals = $data->noerrors; // data to be saved into {workshop_forms_noerrors} - $mappings = $data->mappings; // data to be saved into {workshop_forms_noerrors_map} - $todelete = array(); // master ids to be deleted + $records = $data->numerrors; // data to be saved into {workshopform_numerrors} + $mappings = $data->mappings; // data to be saved into {workshopform_numerrors_map} + $todelete = array(); // dimension ids to be deleted for ($i=0; $i < $norepeats; $i++) { - $local = $locals[$i]; - $master = $masters[$i]; - if (empty($local->description_editor['text'])) { - if (!empty($master->id)) { - // existing record with empty description - to be deleted - $todelete[] = $master->id; + $record = $records[$i]; + if (empty($record->description_editor['text'])) { + if (!empty($record->id)) { + // existing dimension record with empty description - to be deleted + $todelete[] = $record->id; } continue; } - if (empty($master->id)) { + if (empty($record->id)) { // new field - $local->id = $DB->insert_record('workshop_forms_noerrors', $local); - $master->localid = $local->id; - $master->id = $DB->insert_record('workshop_forms', $master); + $record->id = $DB->insert_record('workshopform_numerrors', $record); } else { // exiting field - $DB->update_record('workshop_forms', $master); - $local->id = $DB->get_field('workshop_forms', 'localid', array('id' => $master->id), MUST_EXIST); + $DB->update_record('workshopform_numerrors', $record); } // re-save with correct path to embeded media files - $local = file_postupdate_standard_editor($local, 'description', $this->descriptionopts, - $PAGE->context, 'workshop_dimension_description', $master->id); - $DB->update_record('workshop_forms_noerrors', $local); + $record = file_postupdate_standard_editor($record, 'description', $this->descriptionopts, $PAGE->context, + 'workshopform_numerrors_description', $record->id); + $DB->update_record('workshopform_numerrors', $record); } $this->delete_dimensions($todelete); @@ -158,10 +152,10 @@ class workshop_noerrors_strategy implements workshop_strategy { continue; } if (isset($this->mappings[$nonegative])) { - $DB->set_field('workshop_forms_noerrors_map', 'grade', $grade, + $DB->set_field('workshopform_numerrors_map', 'grade', $grade, array('workshopid' => $this->workshop->id, 'nonegative' => $nonegative)); } else { - $DB->insert_record('workshop_forms_noerrors_map', + $DB->insert_record('workshopform_numerrors_map', (object)array('workshopid' => $this->workshop->id, 'nonegative' => $nonegative, 'grade' => $grade)); } } @@ -172,13 +166,11 @@ class workshop_noerrors_strategy implements workshop_strategy { } else { $insql = ''; } - $sql = "DELETE FROM {workshop_forms_noerrors_map} + $sql = "DELETE FROM {workshopform_numerrors_map} WHERE (($insql nonegative > :nodimensions) AND (workshopid = :workshopid))"; $params['nodimensions'] = $norepeats; $params['workshopid'] = $this->workshop->id; - if (!$DB->execute($sql, $params)){ - print_error('err_removegrademappings', 'workshop'); - } + $DB->execute($sql, $params); } /** @@ -199,12 +191,12 @@ class workshop_noerrors_strategy implements workshop_strategy { // rewrite URLs to the embeded files for ($i = 0; $i < $nodimensions; $i++) { $fields->{'description__idx_'.$i} = file_rewrite_pluginfile_urls($fields->{'description__idx_'.$i}, - 'pluginfile.php', $PAGE->context->id, 'workshop_dimension_description', $fields->{'dimensionid__idx_'.$i}); + 'pluginfile.php', $PAGE->context->id, 'workshopform_numerrors_description', $fields->{'dimensionid__idx_'.$i}); } if ('assessment' === $mode and !empty($assessment)) { // load the previously saved assessment data - $grades = $this->reindex_grades_by_dimension($this->get_current_assessment_data($assessment)); + $grades = $this->get_current_assessment_data($assessment); $current = new stdClass(); for ($i = 0; $i < $nodimensions; $i++) { $dimid = $fields->{'dimensionid__idx_'.$i}; @@ -217,6 +209,7 @@ class workshop_noerrors_strategy implements workshop_strategy { } // set up the required custom data common for all strategies + $customdata['workshop'] = $this->workshop; $customdata['strategy'] = $this; $customdata['mode'] = $mode; @@ -224,9 +217,9 @@ class workshop_noerrors_strategy implements workshop_strategy { $customdata['nodims'] = $nodimensions; $customdata['fields'] = $fields; $customdata['current'] = isset($current) ? $current : null; - $attributes = array('class' => 'assessmentform noerrors'); + $attributes = array('class' => 'assessmentform numerrors'); - return new workshop_noerrors_assessment_form($actionurl, $customdata, 'post', '', $attributes); + return new workshop_numerrors_assessment_form($actionurl, $customdata, 'post', '', $attributes); } /** @@ -246,12 +239,13 @@ class workshop_noerrors_strategy implements workshop_strategy { } for ($i = 0; $i < $data->nodims; $i++) { $grade = new stdClass(); - $grade->id = $data->{'gradeid__idx_' . $i}; - $grade->assessmentid = $assessment->id; - $grade->dimensionid = $data->{'dimensionid__idx_' . $i}; - $grade->grade = $data->{'grade__idx_' . $i}; - $grade->peercomment = $data->{'peercomment__idx_' . $i}; - $grade->peercommentformat = FORMAT_HTML; + $grade->id = $data->{'gradeid__idx_' . $i}; + $grade->assessmentid = $assessment->id; + $grade->strategy = 'numerrors'; + $grade->dimensionid = $data->{'dimensionid__idx_' . $i}; + $grade->grade = $data->{'grade__idx_' . $i}; + $grade->peercomment = $data->{'peercomment__idx_' . $i}; + $grade->peercommentformat = FORMAT_HTML; if (empty($grade->id)) { // new grade $grade->id = $DB->insert_record('workshop_grades', $grade); @@ -275,7 +269,9 @@ class workshop_noerrors_strategy implements workshop_strategy { return false; } -/// Internal methods +//////////////////////////////////////////////////////////////////////////////// +// Internal methods // +//////////////////////////////////////////////////////////////////////////////// /** * Loads the fields of the assessment form currently used in this workshop @@ -285,12 +281,11 @@ class workshop_noerrors_strategy implements workshop_strategy { protected function load_fields() { global $DB; - $sql = 'SELECT master.id,dim.description,dim.descriptionformat,dim.grade0,dim.grade1,dim.weight - FROM {workshop_forms} master - INNER JOIN {workshop_forms_noerrors} dim ON (dim.id=master.localid) - WHERE master.workshopid = :workshopid AND master.strategy = :strategy - ORDER BY master.sort'; - $params = array('workshopid' => $this->workshop->id, 'strategy' => $this->workshop->strategy); + $sql = 'SELECT * + FROM {workshopform_numerrors} + WHERE workshopid = :workshopid + ORDER BY sort'; + $params = array('workshopid' => $this->workshop->id); return $DB->get_records_sql($sql, $params); } @@ -302,7 +297,7 @@ class workshop_noerrors_strategy implements workshop_strategy { */ protected function load_mappings() { global $DB; - return $DB->get_records('workshop_forms_noerrors_map', array('workshopid' => $this->workshop->id), 'nonegative', + return $DB->get_records('workshopform_numerrors_map', array('workshopid' => $this->workshop->id), 'nonegative', 'nonegative,grade'); // we can use nonegative as key here as it must be unique within workshop } @@ -318,7 +313,7 @@ class workshop_noerrors_strategy implements workshop_strategy { $formdata = new stdClass(); $key = 0; foreach ($dims as $dimension) { - $formdata->{'dimensionid__idx_' . $key} = $dimension->id; // master id, not the local one! + $formdata->{'dimensionid__idx_' . $key} = $dimension->id; $formdata->{'description__idx_' . $key} = $dimension->description; $formdata->{'description__idx_' . $key.'format'} = $dimension->descriptionformat; $formdata->{'grade0__idx_' . $key} = $dimension->grade0; @@ -339,27 +334,21 @@ class workshop_noerrors_strategy implements workshop_strategy { * * todo we may check that there are no assessments done using these dimensions and probably remove them * - * @param array $masterids + * @param array $ids list to delete * @return void */ - protected function delete_dimensions($masterids) { + protected function delete_dimensions(array $ids) { global $DB, $PAGE; - $masters = $DB->get_records_list('workshop_forms', 'id', $masterids, '', 'id,localid'); - $masterids = array_keys($masters); // now contains only those really existing - $localids = array(); $fs = get_file_storage(); - - foreach ($masters as $itemid => $master) { - $fs->delete_area_files($PAGE->context->id, 'workshop_dimension_description', $itemid); - $localids[] = $master->localid; + foreach ($ids as $id) { + $fs->delete_area_files($PAGE->context->id, 'workshopform_numerrors_description', $id); } - $DB->delete_records_list('workshop_forms_noerrors', 'id', $localids); - $DB->delete_records_list('workshop_forms', 'id', $masterids); + $DB->delete_records_list('workshopform_numerrors', 'id', $ids); } /** - * Prepares data returned by {@link workshop_edit_noerrors_strategy_form} so they can be saved into database + * Prepares data returned by {@link workshop_edit_numerrors_strategy_form} so they can be saved into database * * It automatically adds some columns into every record. The sorting is * done by the order of the returned array and starts with 1. @@ -372,23 +361,19 @@ class workshop_noerrors_strategy implements workshop_strategy { protected function prepare_database_fields(stdClass $raw) { global $PAGE; - $cook = new stdClass(); // to be returned - $cook->forms = array(); // to be stored in {workshop_forms} - $cook->noerrors = array(); // to be stored in {workshop_forms_noerrors} - $cook->mappings = array(); // to be stored in {workshop_forms_noerrors_map} + $cook = new stdClass(); // to be returned + $cook->numerrors = array(); // to be stored in {workshopform_numerrors} + $cook->mappings = array(); // to be stored in {workshopform_numerrors_map} for ($i = 0; $i < $raw->norepeats; $i++) { - $cook->forms[$i] = new stdClass(); - $cook->forms[$i]->id = $raw->{'dimensionid__idx_'.$i}; - $cook->forms[$i]->workshopid = $this->workshop->id; - $cook->forms[$i]->sort = $i + 1; - $cook->forms[$i]->strategy = 'noerrors'; - - $cook->noerrors[$i] = new stdClass(); - $cook->noerrors[$i]->description_editor = $raw->{'description__idx_'.$i.'_editor'}; - $cook->noerrors[$i]->grade0 = $raw->{'grade0__idx_'.$i}; - $cook->noerrors[$i]->grade1 = $raw->{'grade1__idx_'.$i}; - $cook->noerrors[$i]->weight = $raw->{'weight__idx_'.$i}; + $cook->numerrors[$i] = new stdClass(); + $cook->numerrors[$i]->id = $raw->{'dimensionid__idx_'.$i}; + $cook->numerrors[$i]->workshopid = $this->workshop->id; + $cook->numerrors[$i]->sort = $i + 1; + $cook->numerrors[$i]->description_editor = $raw->{'description__idx_'.$i.'_editor'}; + $cook->numerrors[$i]->grade0 = $raw->{'grade0__idx_'.$i}; + $cook->numerrors[$i]->grade1 = $raw->{'grade1__idx_'.$i}; + $cook->numerrors[$i]->weight = $raw->{'weight__idx_'.$i}; } $i = 1; @@ -413,30 +398,15 @@ class workshop_noerrors_strategy implements workshop_strategy { protected function get_current_assessment_data(stdClass $assessment) { global $DB; - // fetch all grades accociated with this assessment - $grades = $DB->get_records('workshop_grades', array('assessmentid' => $assessment->id)); + list($dimsql, $dimparams) = $DB->get_in_or_equal(array_keys($this->dimensions), SQL_PARAMS_NAMED); + // beware! the caller may rely on the returned array is indexed by dimensionid + $sql = "SELECT dimensionid, * + FROM {workshop_grades} + WHERE assessmentid = :assessmentid AND strategy= :strategy AND dimensionid $dimsql"; + $params = array('assessmentid' => $assessment->id, 'strategy' => 'numerrors'); + $params = array_merge($params, $dimparams); - // filter grades given under an other strategy or assessment form - foreach ($grades as $grade) { - if (!isset($this->dimensions[$grade->dimensionid])) { - unset ($grades[$grade->id]); - } - } - return $grades; - } - - /** - * Reindexes the records returned by {@link get_current_assessment_data} by dimensionid - * - * @param mixed $grades - * @return array - */ - protected function reindex_grades_by_dimension($grades) { - $reindexed = array(); - foreach ($grades as $grade) { - $reindexed[$grade->dimensionid] = $grade; - } - return $reindexed; + return $DB->get_records_sql($sql, $params); } /** @@ -449,7 +419,7 @@ class workshop_noerrors_strategy implements workshop_strategy { $grades = $this->get_current_assessment_data($assessment); $suggested = $this->calculate_peer_grade($grades); if (!is_null($suggested)) { - // todo save into workshop_assessments + $this->workshop->set_peer_grade($assessment->id, $suggested); } return $suggested; } @@ -466,7 +436,7 @@ class workshop_noerrors_strategy implements workshop_strategy { } $sumerrors = 0; // sum of the weighted errors (ie the negative responses) foreach ($grades as $grade) { - if (empty($grade->grade)) { + if (grade_floats_different($grade->grade, 1.00000)) { // negative reviewer's response $sumerrors += $this->dimensions[$grade->dimensionid]->weight; } @@ -490,12 +460,12 @@ class workshop_noerrors_strategy implements workshop_strategy { * 6 | 0% * With this mapping, one error is mapped to 100% grade and 4 errors is mapped to 60%. * - * @param mixed $noerrors Number of errors + * @param mixed $numerrors Number of errors * @return float Raw grade (0 to 1) for the given number of negative assertions */ - protected function errors_to_grade($noerrors) { + protected function errors_to_grade($numerrors) { $grade = 100; - for ($i = 1; $i <= $noerrors; $i++) { + for ($i = 1; $i <= $numerrors; $i++) { if (isset($this->mappings[$i])) { $grade = $this->mappings[$i]->grade; } @@ -506,6 +476,6 @@ class workshop_noerrors_strategy implements workshop_strategy { if ($grade < 0) { $grade = 0; } - return $grade/100; + return grade_floatval($grade/100); } } diff --git a/mod/workshop/grading/noerrors/settings.php b/mod/workshop/form/numerrors/settings.php similarity index 62% rename from mod/workshop/grading/noerrors/settings.php rename to mod/workshop/form/numerrors/settings.php index 6567b9a39e4..e1b4ee74701 100644 --- a/mod/workshop/grading/noerrors/settings.php +++ b/mod/workshop/form/numerrors/settings.php @@ -27,10 +27,10 @@ defined('MOODLE_INTERNAL') || die(); -$settings->add(new admin_setting_configtext('workshopgrading_noerrors/grade0', get_string('grade0', 'workshopgrading_noerrors'), - get_string('configgrade0', 'workshopgrading_noerrors'), - get_string('grade0default', 'workshopgrading_noerrors'), $paramtype=PARAM_TEXT, $size=15)); +$settings->add(new admin_setting_configtext('workshopform_numerrors/grade0', get_string('grade0', 'workshopform_numerrors'), + get_string('configgrade0', 'workshopform_numerrors'), + get_string('grade0default', 'workshopform_numerrors'), $paramtype=PARAM_TEXT, $size=15)); -$settings->add(new admin_setting_configtext('workshopgrading_noerrors/grade1', get_string('grade1', 'workshopgrading_noerrors'), - get_string('configgrade1', 'workshopgrading_noerrors'), - get_string('grade1default', 'workshopgrading_noerrors'), $paramtype=PARAM_TEXT, $size=15)); +$settings->add(new admin_setting_configtext('workshopform_numerrors/grade1', get_string('grade1', 'workshopform_numerrors'), + get_string('configgrade1', 'workshopform_numerrors'), + get_string('grade1default', 'workshopform_numerrors'), $paramtype=PARAM_TEXT, $size=15)); diff --git a/mod/workshop/grading/noerrors/simpletest/teststrategy.php b/mod/workshop/form/numerrors/simpletest/teststrategy.php similarity index 85% rename from mod/workshop/grading/noerrors/simpletest/teststrategy.php rename to mod/workshop/form/numerrors/simpletest/teststrategy.php index eba90807647..943be186d53 100644 --- a/mod/workshop/grading/noerrors/simpletest/teststrategy.php +++ b/mod/workshop/form/numerrors/simpletest/teststrategy.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . /** - * Unit tests for (some of) mod/workshop/grading/noerrors/strategy.php + * Unit tests for Number of errors grading logic * * @package mod-workshop * @copyright 2009 David Mudrak @@ -26,7 +26,8 @@ defined('MOODLE_INTERNAL') || die(); // Include the code to test -require_once($CFG->dirroot . '/mod/workshop/grading/noerrors/strategy.php'); +require_once($CFG->dirroot . '/mod/workshop/locallib.php'); +require_once($CFG->dirroot . '/mod/workshop/form/numerrors/lib.php'); global $DB; Mock::generate(get_class($DB), 'mockDB'); @@ -34,7 +35,7 @@ Mock::generate(get_class($DB), 'mockDB'); /** * Test subclass that makes all the protected methods we want to test public */ -class testable_workshop_noerrors_strategy extends workshop_noerrors_strategy { +class testable_workshop_numerrors_strategy extends workshop_numerrors_strategy { /** allows to set dimensions manually */ public $dimensions = array(); @@ -50,7 +51,7 @@ class testable_workshop_noerrors_strategy extends workshop_noerrors_strategy { } } -class workshop_noerrors_strategy_test extends UnitTestCase { +class workshop_numerrors_strategy_test extends UnitTestCase { /** real database */ protected $realDB; @@ -71,9 +72,9 @@ class workshop_noerrors_strategy_test extends UnitTestCase { $cm = (object)array('id' => 3); $course = (object)array('id' => 11); - $workshop = (object)array('id' => 42, 'strategy' => 'noerrors'); + $workshop = (object)array('id' => 42, 'strategy' => 'numerrors'); $this->workshop = new workshop($workshop, $cm, $course); - $this->strategy = new testable_workshop_noerrors_strategy($this->workshop); + $this->strategy = new testable_workshop_numerrors_strategy($this->workshop); } public function tearDown() { @@ -98,14 +99,14 @@ class workshop_noerrors_strategy_test extends UnitTestCase { public function test_calculate_peer_grade_no_error() { // fixture set-up $this->strategy->dimensions = array(); - $this->strategy->dimensions[108] = (object)array('weight' => 1); - $this->strategy->dimensions[109] = (object)array('weight' => 1); - $this->strategy->dimensions[111] = (object)array('weight' => 1); + $this->strategy->dimensions[108] = (object)array('weight' => '1'); + $this->strategy->dimensions[109] = (object)array('weight' => '1'); + $this->strategy->dimensions[111] = (object)array('weight' => '1'); $this->strategy->mappings = array(); $grades = array(); - $grades[] = (object)array('dimensionid' => 108, 'grade' => 1); - $grades[] = (object)array('dimensionid' => 111, 'grade' => 1); - $grades[] = (object)array('dimensionid' => 109, 'grade' => 1); + $grades[] = (object)array('dimensionid' => 108, 'grade' => '1.00000'); + $grades[] = (object)array('dimensionid' => 111, 'grade' => '1.00000'); + $grades[] = (object)array('dimensionid' => 109, 'grade' => '1.00000'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); // validate @@ -115,19 +116,19 @@ class workshop_noerrors_strategy_test extends UnitTestCase { public function test_calculate_peer_grade_one_error() { // fixture set-up $this->strategy->dimensions = array(); - $this->strategy->dimensions[108] = (object)array('weight' => 1); - $this->strategy->dimensions[109] = (object)array('weight' => 1); - $this->strategy->dimensions[111] = (object)array('weight' => 1); + $this->strategy->dimensions[108] = (object)array('weight' => '1'); + $this->strategy->dimensions[109] = (object)array('weight' => '1'); + $this->strategy->dimensions[111] = (object)array('weight' => '1'); $this->strategy->mappings = array( - 1 => (object)array('grade' => 80.0), - 2 => (object)array('grade' => 60.0), + 1 => (object)array('grade' => '80.00000'), + 2 => (object)array('grade' => '60.00000'), ); $grades = array(); - $grades[] = (object)array('dimensionid' => 108, 'grade' => 1); - $grades[] = (object)array('dimensionid' => 111, 'grade' => 0); - $grades[] = (object)array('dimensionid' => 109, 'grade' => 1); + $grades[] = (object)array('dimensionid' => 108, 'grade' => '1.00000'); + $grades[] = (object)array('dimensionid' => 111, 'grade' => '0.00000'); + $grades[] = (object)array('dimensionid' => 109, 'grade' => '1.00000'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); @@ -138,20 +139,20 @@ class workshop_noerrors_strategy_test extends UnitTestCase { public function test_calculate_peer_grade_three_errors_same_weight_a() { // fixture set-up $this->strategy->dimensions = array(); - $this->strategy->dimensions[108] = (object)array('weight' => 1); - $this->strategy->dimensions[109] = (object)array('weight' => 1); - $this->strategy->dimensions[111] = (object)array('weight' => 1); + $this->strategy->dimensions[108] = (object)array('weight' => '1.00000'); + $this->strategy->dimensions[109] = (object)array('weight' => '1.00000'); + $this->strategy->dimensions[111] = (object)array('weight' => '1.00000'); $this->strategy->mappings = array( - 1 => (object)array('grade' => 80.0), - 2 => (object)array('grade' => 60.0), - 3 => (object)array('grade' => 10.0), + 1 => (object)array('grade' => '80.00000'), + 2 => (object)array('grade' => '60.00000'), + 3 => (object)array('grade' => '10.00000'), ); $grades = array(); - $grades[] = (object)array('dimensionid' => 108, 'grade' => 0); - $grades[] = (object)array('dimensionid' => 111, 'grade' => 0); - $grades[] = (object)array('dimensionid' => 109, 'grade' => 0); + $grades[] = (object)array('dimensionid' => 108, 'grade' => '0.00000'); + $grades[] = (object)array('dimensionid' => 111, 'grade' => '0.00000'); + $grades[] = (object)array('dimensionid' => 109, 'grade' => '0.00000'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); @@ -162,20 +163,20 @@ class workshop_noerrors_strategy_test extends UnitTestCase { public function test_calculate_peer_grade_three_errors_same_weight_b() { // fixture set-up $this->strategy->dimensions = array(); - $this->strategy->dimensions[108] = (object)array('weight' => 1); - $this->strategy->dimensions[109] = (object)array('weight' => 1); - $this->strategy->dimensions[111] = (object)array('weight' => 1); + $this->strategy->dimensions[108] = (object)array('weight' => '1.00000'); + $this->strategy->dimensions[109] = (object)array('weight' => '1.00000'); + $this->strategy->dimensions[111] = (object)array('weight' => '1.00000'); $this->strategy->mappings = array( - 1 => (object)array('grade' => 80.0), - 2 => (object)array('grade' => 60.0), - 3 => (object)array('grade' => 0.0), + 1 => (object)array('grade' => '80.00000'), + 2 => (object)array('grade' => '60.00000'), + 3 => (object)array('grade' => '0.00000'), ); $grades = array(); - $grades[] = (object)array('dimensionid' => 108, 'grade' => 0); - $grades[] = (object)array('dimensionid' => 111, 'grade' => 0); - $grades[] = (object)array('dimensionid' => 109, 'grade' => 0); + $grades[] = (object)array('dimensionid' => 108, 'grade' => '0.00000'); + $grades[] = (object)array('dimensionid' => 111, 'grade' => '0.00000'); + $grades[] = (object)array('dimensionid' => 109, 'grade' => '0.00000'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); @@ -186,20 +187,20 @@ class workshop_noerrors_strategy_test extends UnitTestCase { public function test_calculate_peer_grade_one_error_weighted() { // fixture set-up $this->strategy->dimensions = array(); - $this->strategy->dimensions[108] = (object)array('weight' => 1); - $this->strategy->dimensions[109] = (object)array('weight' => 2); - $this->strategy->dimensions[111] = (object)array('weight' => 0); + $this->strategy->dimensions[108] = (object)array('weight' => '1'); + $this->strategy->dimensions[109] = (object)array('weight' => '2'); + $this->strategy->dimensions[111] = (object)array('weight' => '0'); $this->strategy->mappings = array( - 1 => (object)array('grade' => 66.0), - 2 => (object)array('grade' => 33.0), - 3 => (object)array('grade' => 0.0), + 1 => (object)array('grade' => '66.00000'), + 2 => (object)array('grade' => '33.00000'), + 3 => (object)array('grade' => '0.00000'), ); $grades = array(); - $grades[] = (object)array('dimensionid' => 108, 'grade' => 1); - $grades[] = (object)array('dimensionid' => 111, 'grade' => 1); - $grades[] = (object)array('dimensionid' => 109, 'grade' => 0); + $grades[] = (object)array('dimensionid' => 108, 'grade' => '1.00000'); + $grades[] = (object)array('dimensionid' => 111, 'grade' => '1.00000'); + $grades[] = (object)array('dimensionid' => 109, 'grade' => '0.00000'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); @@ -210,20 +211,20 @@ class workshop_noerrors_strategy_test extends UnitTestCase { public function test_calculate_peer_grade_zero_weight() { // fixture set-up $this->strategy->dimensions = array(); - $this->strategy->dimensions[108] = (object)array('weight' => 1); - $this->strategy->dimensions[109] = (object)array('weight' => 2); - $this->strategy->dimensions[111] = (object)array('weight' => 0); + $this->strategy->dimensions[108] = (object)array('weight' => '1'); + $this->strategy->dimensions[109] = (object)array('weight' => '2'); + $this->strategy->dimensions[111] = (object)array('weight' => '0'); $this->strategy->mappings = array( - 1 => (object)array('grade' => 66.0), - 2 => (object)array('grade' => 33.0), - 3 => (object)array('grade' => 0.0), + 1 => (object)array('grade' => '66.00000'), + 2 => (object)array('grade' => '33.00000'), + 3 => (object)array('grade' => '0.00000'), ); $grades = array(); - $grades[] = (object)array('dimensionid' => 108, 'grade' => 1); - $grades[] = (object)array('dimensionid' => 111, 'grade' => 0); - $grades[] = (object)array('dimensionid' => 109, 'grade' => 1); + $grades[] = (object)array('dimensionid' => 108, 'grade' => '1.00000'); + $grades[] = (object)array('dimensionid' => 111, 'grade' => '0.00000'); + $grades[] = (object)array('dimensionid' => 109, 'grade' => '1.00000'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); @@ -234,24 +235,24 @@ class workshop_noerrors_strategy_test extends UnitTestCase { public function test_calculate_peer_grade_sum_weight() { // fixture set-up $this->strategy->dimensions = array(); - $this->strategy->dimensions[108] = (object)array('weight' => 1); - $this->strategy->dimensions[109] = (object)array('weight' => 2); - $this->strategy->dimensions[111] = (object)array('weight' => 3); + $this->strategy->dimensions[108] = (object)array('weight' => '1'); + $this->strategy->dimensions[109] = (object)array('weight' => '2'); + $this->strategy->dimensions[111] = (object)array('weight' => '3'); $this->strategy->mappings = array( - 1 => (object)array('grade' => 90.0), - 2 => (object)array('grade' => 80.0), - 3 => (object)array('grade' => 70.0), - 4 => (object)array('grade' => 60.0), - 5 => (object)array('grade' => 30.0), - 6 => (object)array('grade' => 5.0), - 7 => (object)array('grade' => 0.0), + 1 => (object)array('grade' => '90.00000'), + 2 => (object)array('grade' => '80.00000'), + 3 => (object)array('grade' => '70.00000'), + 4 => (object)array('grade' => '60.00000'), + 5 => (object)array('grade' => '30.00000'), + 6 => (object)array('grade' => '5.00000'), + 7 => (object)array('grade' => '0.00000'), ); $grades = array(); - $grades[] = (object)array('dimensionid' => 108, 'grade' => 0); - $grades[] = (object)array('dimensionid' => 111, 'grade' => 0); - $grades[] = (object)array('dimensionid' => 109, 'grade' => 0); + $grades[] = (object)array('dimensionid' => 108, 'grade' => '0.00000'); + $grades[] = (object)array('dimensionid' => 111, 'grade' => '0.00000'); + $grades[] = (object)array('dimensionid' => 109, 'grade' => '0.00000'); // excercise SUT $suggested = $this->strategy->calculate_peer_grade($grades); diff --git a/mod/workshop/grading/noerrors/version.php b/mod/workshop/form/numerrors/version.php similarity index 100% rename from mod/workshop/grading/noerrors/version.php rename to mod/workshop/form/numerrors/version.php diff --git a/mod/workshop/grading/rubric/db/install.xml b/mod/workshop/form/rubric/db/install.xml similarity index 53% rename from mod/workshop/grading/rubric/db/install.xml rename to mod/workshop/form/rubric/db/install.xml index 3ddfa85a791..baec8b2eb4a 100644 --- a/mod/workshop/grading/rubric/db/install.xml +++ b/mod/workshop/form/rubric/db/install.xml @@ -1,31 +1,34 @@ - -
+
- - + + + + - + +
- +
- + - +
-
+ \ No newline at end of file diff --git a/mod/workshop/grading/nograding/db/install.xml b/mod/workshop/grading/nograding/db/install.xml deleted file mode 100644 index c0989a8c57c..00000000000 --- a/mod/workshop/grading/nograding/db/install.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - -
-
-
diff --git a/mod/workshop/lang/en_utf8/workshop.php b/mod/workshop/lang/en_utf8/workshop.php index 42a93803b24..9dfe3020089 100644 --- a/mod/workshop/lang/en_utf8/workshop.php +++ b/mod/workshop/lang/en_utf8/workshop.php @@ -42,7 +42,6 @@ $string['allocatedetails'] = 'expected: $a->expected
submitted: $a->submitt $string['allocationdone'] = 'Allocation done'; $string['allocationerror'] = 'Allocation error'; $string['allocation'] = 'Submission allocation'; -$string['areadimensiondescription'] = 'Assessment form fields'; $string['areasubmissionattachment'] = 'Submission attachments'; $string['areasubmissioncontent'] = 'Submission texts'; $string['assessallexamples'] = 'Assess all examples'; diff --git a/mod/workshop/lib.php b/mod/workshop/lib.php index 94edbd1e323..27fa35b1091 100644 --- a/mod/workshop/lib.php +++ b/mod/workshop/lib.php @@ -62,7 +62,7 @@ function workshop_supports($feature) { case FEATURE_GROUPMEMBERSONLY: return true; case FEATURE_MOD_INTRO: return true; case FEATURE_MOD_SUBPLUGINS: return array( - 'workshopgrading' => 'mod/workshop/grading', + 'workshopform' => 'mod/workshop/form', 'workshopallocation' => 'mod/workshop/allocation' ); default: return null; @@ -124,6 +124,9 @@ function workshop_update_instance($data) { $data->timemodified = time(); $data->id = $data->instance; + // todo - if the grading strategy is being changed, we must replace all aggregated peer grades with nulls + // todo - if maximum grades are being changed, we should probably recalculate or invalidate them + $DB->update_record('workshop', $data); $context = get_context_instance(CONTEXT_MODULE, $data->coursemodule); @@ -296,6 +299,10 @@ function workshop_get_extra_capabilities() { * The file area workshop_intro for the activity introduction field is added automatically * by {@link file_browser::get_file_info_module()} * + * TODO: we use the following areas + * workshopform_accumulative_description + * workshopform_numerrors_description + * * @param stdClass $course * @param stdClass $cm * @param stdClass $context @@ -305,7 +312,6 @@ 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'); } @@ -363,6 +369,7 @@ function workshop_pluginfile($course, $cminfo, $context, $filearea, array $args, send_stored_file($file, $lifetime, 0); } + /** todo - this filearea has been replaced by subplugins' areas if ($filearea === 'workshop_dimension_description') { $itemid = (int)array_shift($args); if (!$dimension = $DB->get_record('workshop_forms', array('id' => $itemid))) { @@ -386,6 +393,7 @@ function workshop_pluginfile($course, $cminfo, $context, $filearea, array $args, // finally send the file send_stored_file($file); } + */ if ($filearea === 'workshop_submission_content' or $filearea === 'workshop_submission_attachment') { $itemid = (int)array_shift($args); @@ -469,6 +477,7 @@ function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filea return new file_info_stored($browser, $context, $storedfile, $urlbase, $topvisiblename, true, true, false, false); } + /* todo was replaced by subplugins' areas if ($filearea === 'workshop_dimension_description') { // always only itemid 0 - TODO not true, review @@ -486,6 +495,7 @@ function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filea } return new file_info_stored($browser, $context, $storedfile, $urlbase, $areas[$filearea], false, true, true, false); } + */ if ($filearea === 'workshop_instructauthors') { // always only itemid 0 @@ -630,14 +640,15 @@ function workshop_get_dimension_weights() { /** * Return an array of the localized grading strategy names * + * @todo remove this function from lib.php * $return array Array ['string' => 'string'] */ function workshop_get_strategies() { - $installed = get_plugin_list('workshopgrading'); + $installed = get_plugin_list('workshopform'); $forms = array(); foreach ($installed as $strategy => $strategypath) { - if (file_exists($strategypath . '/strategy.php')) { - $forms[$strategy] = get_string('pluginname', 'workshopgrading_' . $strategy); + if (file_exists($strategypath . '/lib.php')) { + $forms[$strategy] = get_string('pluginname', 'workshopform_' . $strategy); } } return $forms; diff --git a/mod/workshop/locallib.php b/mod/workshop/locallib.php index 8581a98cd64..87b067af248 100644 --- a/mod/workshop/locallib.php +++ b/mod/workshop/locallib.php @@ -58,18 +58,12 @@ class workshop { /** @var stdClass course record */ public $course = null; - /** @var stdClass the workshop instance context */ - public $context = null; - /** * @var workshop_strategy grading strategy instance * Do not use directly, get the instance using {@link workshop::grading_strategy_instance()} */ protected $strategyinstance = null; - /** @var stdClass underlying database record */ - protected $dbrecord = null; - /** * Initializes the workshop API instance using the data from DB * @@ -81,25 +75,13 @@ class workshop { * @param stdClass $course Course record from {course} table */ public function __construct(stdClass $dbrecord, stdClass $cm, stdClass $course) { - $this->dbrecord = $dbrecord; - $this->cm = $cm; - $this->course = $course; - $this->context = get_context_instance(CONTEXT_MODULE, $this->cm->id); - } - - /** - * Magic method to retrieve the value of the underlying database record's field - * - * @throws coding_exception if the field does not exist - * @param mixed $key the name of the database field - * @return mixed|null the value of the field - */ - public function __get($key) { - if (!isset($this->dbrecord->{$key})) { - // todo remove the comment here // throw new coding_exception('You are trying to get a non-existing property'); - return null; + foreach ($dbrecord as $field => $value) { + $this->{$field} = $value; } - return $this->dbrecord->{$key}; + $this->cm = $cm; + $this->course = $course; // beware - this replaces the standard course field in the instance table + // this is intentional - IMO there should be no such field as it violates + // 3rd normal form with no real performance gain } /** @@ -107,12 +89,15 @@ class workshop { * * Example submissions are ignored. * - * @param array $userids - * @return TODO + * @param array $userids + * @return array */ protected function users_with_submission(array $userids) { global $DB; + if (empty($userids)) { + return array(); + } $userswithsubmission = array(); list($usql, $uparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED); $sql = "SELECT id,userid @@ -133,11 +118,12 @@ class workshop { * * The returned objects contain id, lastname and firstname properties and are ordered by lastname,firstname * + * @param stdClass $context * @param bool $musthavesubmission If true, return only users who have already submitted. All possible authors otherwise. * @return array array[userid] => stdClass{->id ->lastname ->firstname} */ - public function get_potential_authors($musthavesubmission=true) { - $users = get_users_by_capability($this->context, 'mod/workshop:submit', + public function get_potential_authors(stdClass $context, $musthavesubmission=true) { + $users = get_users_by_capability($context, 'mod/workshop:submit', 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true); if ($musthavesubmission) { $users = array_intersect_key($users, $this->users_with_submission(array_keys($users))); @@ -150,11 +136,12 @@ class workshop { * * The returned objects contain id, lastname and firstname properties and are ordered by lastname,firstname * + * @param stdClass $context * @param bool $musthavesubmission If true, return only users who have already submitted. All possible users otherwise. * @return array array[userid] => stdClass{->id ->lastname ->firstname} */ - public function get_potential_reviewers($musthavesubmission=false) { - $users = get_users_by_capability($this->context, 'mod/workshop:peerassess', + public function get_potential_reviewers(stdClass $context, $musthavesubmission=false) { + $users = get_users_by_capability($context, 'mod/workshop:peerassess', 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true); if ($musthavesubmission) { // users without their own submission can not be reviewers @@ -215,7 +202,7 @@ class workshop { * * @param mixed $userid int|array|'all' If set to [array of] integer, return submission[s] of the given user[s] only * @param mixed $examples false|true|'all' Only regular submissions, only examples, all submissions - * @return stdClass moodle_recordset + * @return array */ public function get_submissions($userid='all', $examples=false) { global $DB; @@ -390,14 +377,18 @@ class workshop { * Note that the returned recordset includes participants without submission as well as those * without any review allocated yet. * - * @return stdClass moodle_recordset + * @return null|stdClass moodle_recordset */ public function get_allocations_recordset() { - global $DB; + global $DB, $PAGE; - $users = get_users_by_capability($this->context, array('mod/workshop:submit', 'mod/workshop:peerassess'), + $users = get_users_by_capability($PAGE->context, array('mod/workshop:submit', 'mod/workshop:peerassess'), 'u.id', 'u.lastname,u.firstname', '', '', '', '', false, false, true); + if (empty($users)) { + return null; + } + list($usql, $params) = $DB->get_in_or_equal(array_keys($users), SQL_PARAMS_NAMED); $params['workshopid'] = $this->id; @@ -469,11 +460,11 @@ class workshop { global $CFG; // because we require other libs here if (is_null($this->strategyinstance)) { - $strategylib = dirname(__FILE__) . '/grading/' . $this->strategy . '/strategy.php'; + $strategylib = dirname(__FILE__) . '/form/' . $this->strategy . '/lib.php'; if (is_readable($strategylib)) { require_once($strategylib); } else { - throw new coding_exception('the grading subplugin must contain library ' . $strategylib); + throw new coding_exception('the grading forms subplugin must contain library ' . $strategylib); } $classname = 'workshop_' . $this->strategy . '_strategy'; $this->strategyinstance = new $classname($this); @@ -493,7 +484,7 @@ class workshop { $installed = get_plugin_list('workshopallocation'); $forms = array(); foreach ($installed as $allocation => $allocationpath) { - if (file_exists($allocationpath . '/allocator.php')) { + if (file_exists($allocationpath . '/lib.php')) { $forms[$allocation] = get_string('pluginname', 'workshopallocation_' . $allocation); } } @@ -515,11 +506,11 @@ class workshop { public function allocator_instance($method) { global $CFG; // because we require other libs here - $allocationlib = dirname(__FILE__) . '/allocation/' . $method . '/allocator.php'; + $allocationlib = dirname(__FILE__) . '/allocation/' . $method . '/lib.php'; if (is_readable($allocationlib)) { require_once($allocationlib); } else { - throw new coding_exception('Unable to find allocator.php'); + throw new coding_exception('Unable to find the allocation library ' . $allocationlib); } $classname = 'workshop_' . $method . '_allocator'; return new $classname($this); @@ -650,16 +641,17 @@ class workshop { * @return string */ public function strategy_name() { - return get_string('pluginname', 'workshopgrading_' . $this->strategy); + return get_string('pluginname', 'workshopform_' . $this->strategy); } /** * Prepare an individual workshop plan for the given user. * - * @param mixed $userid - * @return TODO + * @param int $userid whom the plan is prepared for + * @param stdClass context of the planned workshop + * @return stdClass data object to be passed to the renderer */ - public function prepare_user_plan($userid) { + public function prepare_user_plan($userid, stdClass $context) { global $DB; $phases = array(); @@ -668,21 +660,21 @@ class workshop { $phase = new stdClass(); $phase->title = get_string('phasesetup', 'workshop'); $phase->tasks = array(); - if (has_capability('moodle/course:manageactivities', $this->context, $userid)) { + if (has_capability('moodle/course:manageactivities', $context, $userid)) { $task = new stdClass(); $task->title = get_string('taskintro', 'workshop'); $task->link = $this->updatemod_url(); $task->completed = !(trim(strip_tags($this->intro)) == ''); $phase->tasks['intro'] = $task; } - if (has_capability('moodle/course:manageactivities', $this->context, $userid)) { + if (has_capability('moodle/course:manageactivities', $context, $userid)) { $task = new stdClass(); $task->title = get_string('taskinstructauthors', 'workshop'); $task->link = $this->updatemod_url(); $task->completed = !(trim(strip_tags($this->instructauthors)) == ''); $phase->tasks['instructauthors'] = $task; } - if (has_capability('mod/workshop:editdimensions', $this->context, $userid)) { + if (has_capability('mod/workshop:editdimensions', $context, $userid)) { $task = new stdClass(); $task->title = get_string('editassessmentform', 'workshop'); $task->link = $this->editform_url(); @@ -707,7 +699,7 @@ class workshop { $phase = new stdClass(); $phase->title = get_string('phasesubmission', 'workshop'); $phase->tasks = array(); - if (has_capability('mod/workshop:submit', $this->context, $userid)) { + if (has_capability('mod/workshop:submit', $context, $userid)) { $task = new stdClass(); $task->title = get_string('tasksubmit', 'workshop'); $task->link = $this->submission_url(); @@ -720,7 +712,7 @@ class workshop { } $phase->tasks['submit'] = $task; } - if (has_capability('moodle/course:manageactivities', $this->context, $userid)) { + if (has_capability('moodle/course:manageactivities', $context, $userid)) { $task = new stdClass(); $task->title = get_string('taskinstructreviewers', 'workshop'); $task->link = $this->updatemod_url(); @@ -732,30 +724,32 @@ class workshop { $phase->tasks['instructreviewers'] = $task; } $phases[self::PHASE_SUBMISSION] = $phase; - if (has_capability('mod/workshop:allocate', $this->context, $userid)) { + if (has_capability('mod/workshop:allocate', $context, $userid)) { $task = new stdClass(); $task->title = get_string('allocate', 'workshop'); $task->link = $this->allocation_url(); - $rs = $this->get_allocations_recordset(); $authors = array(); $allocations = array(); // 'submissionid' => isallocated - foreach ($rs as $allocation) { - if (!isset($authors[$allocation->authorid])) { - $authors[$allocation->authorid] = true; - } - if (isset($allocation->submissionid)) { - if (!isset($allocations[$allocation->submissionid])) { - $allocations[$allocation->submissionid] = false; + $rs = $this->get_allocations_recordset(); + if (!is_null($rs)) { + foreach ($rs as $allocation) { + if (!isset($authors[$allocation->authorid])) { + $authors[$allocation->authorid] = true; } - if (!empty($allocation->reviewerid)) { - $allocations[$allocation->submissionid] = true; + if (isset($allocation->submissionid)) { + if (!isset($allocations[$allocation->submissionid])) { + $allocations[$allocation->submissionid] = false; + } + if (!empty($allocation->reviewerid)) { + $allocations[$allocation->submissionid] = true; + } } } + $rs->close(); } $numofauthors = count($authors); $numofsubmissions = count($allocations); $numofallocated = count(array_filter($allocations)); - $rs->close(); if ($numofsubmissions == 0) { $task->completed = null; } elseif ($numofsubmissions == $numofallocated) { @@ -785,7 +779,7 @@ class workshop { $phase = new stdClass(); $phase->title = get_string('phaseassessment', 'workshop'); $phase->tasks = array(); - $phase->isreviewer = has_capability('mod/workshop:peerassess', $this->context, $userid); + $phase->isreviewer = has_capability('mod/workshop:peerassess', $context, $userid); $phase->assessments = $this->get_assessments_by_reviewer($userid); $numofpeers = 0; // number of allocated peer-assessments $numofpeerstodo = 0; // number of peer-assessments to do @@ -866,7 +860,7 @@ class workshop { } // Add phase swithing actions - if (has_capability('mod/workshop:switchphase', $this->context, $userid)) { + if (has_capability('mod/workshop:switchphase', $context, $userid)) { foreach ($phases as $phasecode => $phase) { if (! $phase->active) { $action = new stdClass(); diff --git a/mod/workshop/settings.php b/mod/workshop/settings.php index 972ebb0c531..3ea3befa30d 100644 --- a/mod/workshop/settings.php +++ b/mod/workshop/settings.php @@ -66,11 +66,11 @@ $settings->add(new admin_setting_configselect('workshop/assessmentcomps', get_st get_string('configassessmentcomps', 'workshop'), WORKSHOP_COMPARISON_NORMAL, $levels)); // include the settings of grading strategy subplugins -$strategies = get_plugin_list('workshopgrading'); +$strategies = get_plugin_list('workshopform'); foreach ($strategies as $strategy => $path) { if (file_exists($settingsfile = $path . '/settings.php')) { - $settings->add(new admin_setting_heading('workshopgradingsetting'.$strategy, - get_string('pluginname', 'workshopgrading_' . $strategy), '')); + $settings->add(new admin_setting_heading('workshopformsetting'.$strategy, + get_string('pluginname', 'workshopform_' . $strategy), '')); include($settingsfile); } } diff --git a/mod/workshop/styles.php b/mod/workshop/styles.php index 95d3644885b..223a274911d 100644 --- a/mod/workshop/styles.php +++ b/mod/workshop/styles.php @@ -1,43 +1,43 @@ /** * Submission - one line summary display */ -.submission-summary { +.mod-workshop .submission-summary { position: relative; margin-bottom: 10px; } -.submission-summary .title, -.submission-summary .author, -.submission-summary .author .fullname, -.submission-summary .author .picture { +.mod-workshop .submission-summary .title, +.mod-workshop .submission-summary .author, +.mod-workshop .submission-summary .author .fullname, +.mod-workshop .submission-summary .author .picture { display: inline; } -.submission-summary .title, -.submission-summary .userdate { +.mod-workshop .submission-summary .title, +.mod-workshop .submission-summary .userdate { margin: 0px 0px 0px 40px; } -.submission-summary .author { +.mod-workshop .submission-summary .author { margin-left: 1ex; } -.submission-summary.anonymous .title, -.submission-summary.anonymous .author, -.submission-summary.anonymous .userdate { +.mod-workshop .submission-summary.anonymous .title, +.mod-workshop .submission-summary.anonymous .author, +.mod-workshop .submission-summary.anonymous .userdate { margin: 0px 0px 0px 5px; } -.submission-summary .userdate { +.mod-workshop .submission-summary .userdate { font-size: x-small; color: #333; } -.submission-summary .userdate span { +.mod-workshop .submission-summary .userdate span { font-style: italic; } -.submission-summary .author .picture { +.mod-workshop .submission-summary .author .picture { position: absolute; top: 0px; left: 0px; @@ -46,57 +46,57 @@ /** * Submission - full display */ -.submission-full { +.mod-workshop .submission-full { border: 1px solid #ddd; margin: 0px 0px 1em 0px; } -.submission-full .header { +.mod-workshop .submission-full .header { position: relative; background-color: #ddd; padding: 3px; } -.submission-full .header .title, -.submission-full .header .author, -.submission-full .header .userdate { +.mod-workshop .submission-full .header .title, +.mod-workshop .submission-full .header .author, +.mod-workshop .submission-full .header .userdate { margin: 0px 0px 0px 80px; } -.submission-full.anonymous .header .title, -.submission-full.anonymous .header .author, -.submission-full.anonymous .header .userdate { +.mod-workshop .submission-full.anonymous .header .title, +.mod-workshop .submission-full.anonymous .header .author, +.mod-workshop .submission-full.anonymous .header .userdate { margin: 0px 0px 0px 5px; } -.submission-full .header .userdate.modified { +.mod-workshop .submission-full .header .userdate.modified { margin-left: 10px; padding-left: 10px; border-left: 1px solid #000; } -.submission-full .header .userdate { +.mod-workshop .submission-full .header .userdate { font-size: x-small; color: #333; display: inline; } -.submission-full .header .userdate span { +.mod-workshop .submission-full .header .userdate span { font-style: italic; } -.submission-full .header .author .picture { +.mod-workshop .submission-full .header .author .picture { position: absolute; top: 3px; left: 3px; } -.submission-full .content, -.submission-full .attachments { +.mod-workshop .submission-full .content, +.mod-workshop .submission-full .attachments { padding: 5px 10px; } -.submission-full .attachments .files img.icon { +.mod-workshop .submission-full .attachments .files img.icon { margin-right: 5px; } @@ -218,103 +218,99 @@ margin-top: 1em; } -/** - * Assessment - */ -.assessmentform .description { - margin: 0px 1em; -} - /** * User plan */ -.userplan { +.mod-workshop .userplan { width: 70%; margin: 1em auto 1em auto; font-size: 80%; + border-left: 1px solid #ddd; + border-right: 1px solid #ddd; } -.userplan th { +.mod-workshop .userplan th { vertical-align: bottom; white-space: normal; color: #999; + border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; padding: 3px; } -.userplan th.active { +.mod-workshop .userplan th.active { vertical-align: top; color: black; font-size: 140%; border: 1px solid #ddd; border-bottom: none; - background-color: #e7f1c3; + background: #e7f1c3; } -.userplan td { +.mod-workshop .userplan td { width: 20%; vertical-align: top; border-right: 1px solid #ddd; background-color: #f5f5f5; } -.userplan td, -.userplan td a, -.userplan td a:link, -.userplan td a:hover, -.userplan td a:visited, -.userplan td a:active { +.mod-workshop .userplan td, +.mod-workshop .userplan td a, +.mod-workshop .userplan td a:link, +.mod-workshop .userplan td a:hover, +.mod-workshop .userplan td a:visited, +.mod-workshop .userplan td a:active { color: #999; } -.userplan td.active, -.userplan td.active a, -.userplan td.active a:link, -.userplan td.active a:hover, -.userplan td.active a:visited, -.userplan td.active a:active { +.mod-workshop .userplan td.active, +.mod-workshop .userplan td.active a, +.mod-workshop .userplan td.active a:link, +.mod-workshop .userplan td.active a:hover, +.mod-workshop .userplan td.active a:visited, +.mod-workshop .userplan td.active a:active { color: black; } -.userplan td.lastcol { +.mod-workshop .userplan td.lastcol { border-right: none; } -.userplan td.active { +.mod-workshop .userplan td.active { border-left: 1px solid #ddd; border-right: 1px solid #ddd; background-color: #e7f1c3; } -.userplan tr.phasetasks li { +.mod-workshop .userplan tr.phasetasks li { background-image: url(../../pix/i/completion-auto-n.gif); background-position: top left; background-repeat: no-repeat; } -.userplan tr.phasetasks li.completed { +.mod-workshop .userplan tr.phasetasks li.completed { background-image: url(../../pix/i/completion-auto-y.gif); } -.userplan tr.phasetasks li.fail { +.mod-workshop .userplan tr.phasetasks li.fail { background-image: url(../../pix/i/completion-auto-fail.gif); } -.userplan tr.phasetasks li.info { +.mod-workshop .userplan tr.phasetasks li.info { background-image: url(../../pix/i/info.gif); } -.userplan tr.phasetasks .tasks { +.mod-workshop .userplan tr.phasetasks .tasks { list-style:none; margin: 3px; padding: 0px; } -.userplan tr.phasetasks .title { +.mod-workshop .userplan tr.phasetasks .title { padding: 0px 10px 0px 20px; } -.userplan tr.phasetasks .details { +.mod-workshop .userplan tr.phasetasks .details { padding: 0px 10px 0px 25px; font-size: 80%; } @@ -322,7 +318,10 @@ /** * Assessment */ -.assessment-summary.graded { +.mod-workshop .assessment-summary.graded { background-color: #e7f1c3; } +.mod-workshop .assessmentform .description { + margin: 0px 1em; +} diff --git a/mod/workshop/tabs.php b/mod/workshop/tabs.php index 22b6268ccb8..cf8b11a04d3 100644 --- a/mod/workshop/tabs.php +++ b/mod/workshop/tabs.php @@ -40,16 +40,16 @@ $inactive = array(); $activated = array(); // top level tabs -if (has_capability('mod/workshop:view', $workshop->context)) { +if (has_capability('mod/workshop:view', $PAGE->context)) { $row[] = new tabobject('info', $workshop->view_url()->out(), get_string('info', 'workshop')); } -if (has_capability('mod/workshop:editdimensions', $workshop->context)) { +if (has_capability('mod/workshop:editdimensions', $PAGE->context)) { $row[] = new tabobject('editform', $workshop->editform_url()->out(), get_string('editassessmentform', 'workshop')); } -if (has_capability('mod/workshop:submit', $workshop->context)) { +if (has_capability('mod/workshop:submit', $PAGE->context)) { $row[] = new tabobject('submission', $workshop->submission_url()->out(), get_string('submission', 'workshop')); } -if (has_capability('mod/workshop:allocate', $workshop->context)) { +if (has_capability('mod/workshop:allocate', $PAGE->context)) { $row[] = new tabobject('allocation', $workshop->allocation_url()->out(), get_string('allocate', 'workshop')); } if (has_capability('moodle/site:config', get_system_context())) { diff --git a/mod/workshop/view.php b/mod/workshop/view.php index d04fc15336c..91aedb135ab 100644 --- a/mod/workshop/view.php +++ b/mod/workshop/view.php @@ -76,7 +76,7 @@ $wsoutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE); echo $OUTPUT->header(); include(dirname(__FILE__) . '/tabs.php'); echo $OUTPUT->heading(format_string($workshop->name), 2); -echo $wsoutput->user_plan($workshop->prepare_user_plan($USER->id)); +echo $wsoutput->user_plan($workshop->prepare_user_plan($USER->id, $PAGE->context)); switch ($workshop->phase) { case workshop::PHASE_SETUP: