mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 04:30:15 +01:00
MDL-20236 overall codebase architecture cleanup and fixing regression
See the issue description for more details
This commit is contained in:
parent
6516b9e9e4
commit
f05c168d2e
@ -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;
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -16,7 +16,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Unit tests for mod/workshop/allocation/random/allocator.php
|
||||
* Unit tests for Random allocation
|
||||
*
|
||||
* @package mod-workshop
|
||||
* @copyright 2009 David Mudrak <david.mudrak@gmail.com>
|
||||
@ -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
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="mod/workshop/db" VERSION="20090907" COMMENT="XMLDB file for Moodle mod/workshop"
|
||||
<XMLDB PATH="mod/workshop/db" VERSION="20090908" COMMENT="XMLDB file for Moodle mod/workshop"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
@ -93,33 +93,20 @@
|
||||
<KEY NAME="overriddenby_fk" TYPE="foreign" FIELDS="gradinggradeoverby" REFTABLE="user" REFFIELDS="id" PREVIOUS="reviewer_fk"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
<TABLE NAME="workshop_grades" COMMENT="How the reviewers filled-up the grading forms, given grades and comments" PREVIOUS="workshop_assessments" NEXT="workshop_forms">
|
||||
<TABLE NAME="workshop_grades" COMMENT="How the reviewers filled-up the grading forms, given grades and comments" PREVIOUS="workshop_assessments">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="assessmentid"/>
|
||||
<FIELD NAME="assessmentid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Part of which assessment this grade is of" PREVIOUS="id" NEXT="dimensionid"/>
|
||||
<FIELD NAME="dimensionid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Foreign key. References dimension id in one of the grading strategy tables." PREVIOUS="assessmentid" NEXT="grade"/>
|
||||
<FIELD NAME="grade" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Given grade in the referenced assessment dimension." PREVIOUS="dimensionid" NEXT="peercomment"/>
|
||||
<FIELD NAME="assessmentid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Part of which assessment this grade is of" PREVIOUS="id" NEXT="strategy"/>
|
||||
<FIELD NAME="strategy" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" PREVIOUS="assessmentid" NEXT="dimensionid"/>
|
||||
<FIELD NAME="dimensionid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Foreign key. References dimension id in one of the grading strategy tables." PREVIOUS="strategy" NEXT="grade"/>
|
||||
<FIELD NAME="grade" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" DECIMALS="5" COMMENT="Given grade in the referenced assessment dimension." PREVIOUS="dimensionid" NEXT="peercomment"/>
|
||||
<FIELD NAME="peercomment" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="Reviewer's comment to the grade value." PREVIOUS="grade" NEXT="peercommentformat"/>
|
||||
<FIELD NAME="peercommentformat" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" COMMENT="The format of peercomment field" PREVIOUS="peercomment"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="assessment_fk"/>
|
||||
<KEY NAME="assessment_fk" TYPE="foreign" FIELDS="assessmentid" REFTABLE="workshop_assessments" REFFIELDS="id" PREVIOUS="primary" NEXT="dimension_fk"/>
|
||||
<KEY NAME="dimension_fk" TYPE="foreign" FIELDS="dimensionid" REFTABLE="workshop_forms" REFFIELDS="id" PREVIOUS="assessment_fk" NEXT="formfield"/>
|
||||
<KEY NAME="formfield" TYPE="unique" FIELDS="assessmentid, dimensionid" COMMENT="The combination of assessmentid and dimensionid must be unique" PREVIOUS="dimension_fk"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
<TABLE NAME="workshop_forms" COMMENT="Meta table to provide unique id for every assessment dimension which is needed for file api support." PREVIOUS="workshop_grades">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="workshopid"/>
|
||||
<FIELD NAME="workshopid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Workshop ID" PREVIOUS="id" NEXT="sort"/>
|
||||
<FIELD NAME="sort" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Defines the dimension order within the assessment form" PREVIOUS="workshopid" NEXT="strategy"/>
|
||||
<FIELD NAME="strategy" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" COMMENT="Defines the target assessment form table" PREVIOUS="sort" NEXT="localid"/>
|
||||
<FIELD NAME="localid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The foreign primary key of one of the assessment forms tables." PREVIOUS="strategy"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="workshop_fk"/>
|
||||
<KEY NAME="workshop_fk" TYPE="foreign" FIELDS="workshopid" REFTABLE="workshop" REFFIELDS="id" PREVIOUS="primary"/>
|
||||
<KEY NAME="assessment_fk" TYPE="foreign" FIELDS="assessmentid" REFTABLE="workshop_assessments" REFFIELDS="id" PREVIOUS="primary" NEXT="formfield_uk"/>
|
||||
<KEY NAME="formfield_uk" TYPE="unique" FIELDS="assessmentid, strategy, dimensionid" COMMENT="The combination of assessmentid, strategy and dimensionid must be unique" PREVIOUS="assessment_fk"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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));
|
||||
}
|
@ -1,20 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="mod/workshop/db" VERSION="20090813" COMMENT="XMLDB file for Moodle mod/workshop"
|
||||
<XMLDB PATH="mod/workshop/db" VERSION="20090908" COMMENT="XMLDB file for Moodle mod/workshop"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="workshop_forms_accumulative" COMMENT="The assessment dimensions definitions of Accumulative grading strategy forms">
|
||||
<TABLE NAME="workshopform_accumulative" COMMENT="The assessment dimensions definitions of Accumulative grading strategy forms">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="description"/>
|
||||
<FIELD NAME="description" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="The description of the dimension" PREVIOUS="id" NEXT="descriptionformat"/>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="workshopid"/>
|
||||
<FIELD NAME="workshopid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Workshop ID" PREVIOUS="id" NEXT="sort"/>
|
||||
<FIELD NAME="sort" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Defines the dimension order within the assessment form" PREVIOUS="workshopid" NEXT="description"/>
|
||||
<FIELD NAME="description" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="The description of the dimension" PREVIOUS="sort" NEXT="descriptionformat"/>
|
||||
<FIELD NAME="descriptionformat" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the description field" PREVIOUS="description" NEXT="grade"/>
|
||||
<FIELD NAME="grade" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" COMMENT="If greater than 0, then the value is maximum grade on a scale 0..grade. If lesser than 0, then its absolute value is the id of a record in scale table. If equals 0, then no grading is possible for this dimension, just commenting." PREVIOUS="descriptionformat" NEXT="weight"/>
|
||||
<FIELD NAME="weight" TYPE="int" LENGTH="5" NOTNULL="false" UNSIGNED="false" DEFAULT="1" SEQUENCE="false" COMMENT="The weigh of the dimension" PREVIOUS="grade"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="workshop_fk"/>
|
||||
<KEY NAME="workshop_fk" TYPE="foreign" FIELDS="workshopid" REFTABLE="workshop" REFFIELDS="id" PREVIOUS="primary"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
</XMLDB>
|
@ -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);
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
@ -16,7 +16,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* 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 <david.mudrak@gmail.com>
|
||||
@ -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
|
@ -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);
|
21
mod/workshop/form/comments/db/install.xml
Normal file
21
mod/workshop/form/comments/db/install.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="mod/workshop/db" VERSION="20090908" COMMENT="XMLDB file for Moodle Comments grading strategy"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="workshopform_comments" COMMENT="The assessment dimensions definitions of Comments strategy forms">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="workshopid"/>
|
||||
<FIELD NAME="workshopid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Workshop ID" PREVIOUS="id" NEXT="sort"/>
|
||||
<FIELD NAME="sort" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Defines the dimension order within the assessment form" PREVIOUS="workshopid" NEXT="description"/>
|
||||
<FIELD NAME="description" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="The description of the dimension" PREVIOUS="sort" NEXT="descriptionformat"/>
|
||||
<FIELD NAME="descriptionformat" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the description field" PREVIOUS="description"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="workshop_fk"/>
|
||||
<KEY NAME="workshop_fk" TYPE="foreign" FIELDS="workshopid" REFTABLE="workshop" REFFIELDS="id" PREVIOUS="primary"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
@ -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);
|
||||
|
@ -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
|
@ -16,7 +16,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* 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 <david.mudrak@gmail.com>
|
||||
@ -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 = '<div id="id_dim_'.$fields->{'dimensionid__idx_'.$i}.'_desc" class="fitem description noerrors">'."\n";
|
||||
$desc = '<div id="id_dim_'.$fields->{'dimensionid__idx_'.$i}.'_desc" class="fitem description numerrors">'."\n";
|
||||
$desc .= format_text($fields->{'description__idx_'.$i}, $fields->{'description__idx_'.$i.'format'});
|
||||
$desc .= "\n</div>";
|
||||
$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);
|
@ -1,13 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="mod/workshop/db" VERSION="20090831" COMMENT="XMLDB file for Moodle mod/workshop/grading/noerrors"
|
||||
<XMLDB PATH="mod/workshop/db" VERSION="20090908" COMMENT="XMLDB file for Moodle Number of errors subplugin"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="workshop_forms_noerrors" COMMENT="The assessment dimensions definitions of Number of errors grading strategy forms" NEXT="workshop_forms_noerrors_map">
|
||||
<TABLE NAME="workshopform_numerrors" COMMENT="The assessment dimensions definitions of Number of errors grading strategy forms" NEXT="workshopform_numerrors_map">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="description"/>
|
||||
<FIELD NAME="description" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="The description of the dimension" PREVIOUS="id" NEXT="descriptionformat"/>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="workshopid"/>
|
||||
<FIELD NAME="workshopid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Workshop ID" PREVIOUS="id" NEXT="sort"/>
|
||||
<FIELD NAME="sort" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Defines the dimension order within the assessment form" PREVIOUS="workshopid" NEXT="description"/>
|
||||
<FIELD NAME="description" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="The description of the dimension" PREVIOUS="sort" NEXT="descriptionformat"/>
|
||||
<FIELD NAME="descriptionformat" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the description field" PREVIOUS="description" NEXT="descriptiontrust"/>
|
||||
<FIELD NAME="descriptiontrust" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" PREVIOUS="descriptionformat" NEXT="grade0"/>
|
||||
<FIELD NAME="grade0" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false" COMMENT="The word describing the negative evaluation (like Poor, Missing, Absent, etc.). If NULL, it defaults to a translated string False" PREVIOUS="descriptiontrust" NEXT="grade1"/>
|
||||
@ -15,10 +17,11 @@
|
||||
<FIELD NAME="weight" TYPE="int" LENGTH="5" NOTNULL="false" UNSIGNED="false" DEFAULT="1" SEQUENCE="false" COMMENT="Weight of this dimension" PREVIOUS="grade1"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="workshop_fk"/>
|
||||
<KEY NAME="workshop_fk" TYPE="foreign" FIELDS="workshopid" REFTABLE="workshop" REFFIELDS="id" PREVIOUS="primary"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
<TABLE NAME="workshop_forms_noerrors_map" COMMENT="This maps the number of errors to a percentual grade for submission" PREVIOUS="workshop_forms_noerrors">
|
||||
<TABLE NAME="workshopform_numerrors_map" COMMENT="This maps the number of errors to a percentual grade for submission" PREVIOUS="workshopform_numerrors">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="workshopid"/>
|
||||
<FIELD NAME="workshopid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The id of the workshop" PREVIOUS="id" NEXT="nonegative"/>
|
@ -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);
|
@ -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);
|
||||
}
|
||||
}
|
@ -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));
|
@ -16,7 +16,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* 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 <david.mudrak@gmail.com>
|
||||
@ -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);
|
@ -1,31 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="mod/workshop/db" VERSION="20090831" COMMENT="XMLDB file for Moodle mod/workshop/grading/rubric"
|
||||
<XMLDB PATH="mod/workshop/db" VERSION="20090908" COMMENT="XMLDB file for workshop Rubric grading strategy"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="workshop_forms_rubric" COMMENT="The assessment dimensions definitions of Rubric grading strategy forms" PREVIOUS="workshop_forms_nograding" NEXT="workshop_forms_rubric_levels">
|
||||
<TABLE NAME="workshopform_rubric" COMMENT="The assessment dimensions definitions of Rubric grading strategy forms" NEXT="workshopform_rubric_levels">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="description"/>
|
||||
<FIELD NAME="description" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="The description of the dimension" PREVIOUS="id" NEXT="descriptionformat"/>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="workshopid"/>
|
||||
<FIELD NAME="workshopid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Workshop ID" PREVIOUS="id" NEXT="sort"/>
|
||||
<FIELD NAME="sort" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Defines the dimension order within the assessment form" PREVIOUS="workshopid" NEXT="description"/>
|
||||
<FIELD NAME="description" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="The description of the dimension" PREVIOUS="sort" NEXT="descriptionformat"/>
|
||||
<FIELD NAME="descriptionformat" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the description field" PREVIOUS="description"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="workshop_fk"/>
|
||||
<KEY NAME="workshop_fk" TYPE="foreign" FIELDS="workshopid" REFTABLE="workshop" REFFIELDS="id" PREVIOUS="primary"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
<TABLE NAME="workshop_forms_rubric_levels" COMMENT="The definition of rubric rating scales" PREVIOUS="workshop_forms_rubric">
|
||||
<TABLE NAME="workshopform_rubric_levels" COMMENT="The definition of rubric rating scales" PREVIOUS="workshopform_rubric">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="dimensionid"/>
|
||||
<FIELD NAME="dimensionid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Which criterion this level is part of" PREVIOUS="id" NEXT="grade"/>
|
||||
<FIELD NAME="grade" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Grade representing this level." PREVIOUS="dimensionid" NEXT="description"/>
|
||||
<FIELD NAME="grade" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" DECIMALS="5" COMMENT="Grade representing this level." PREVIOUS="dimensionid" NEXT="description"/>
|
||||
<FIELD NAME="description" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="The definition of this level" PREVIOUS="grade" NEXT="descriptionformat"/>
|
||||
<FIELD NAME="descriptionformat" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the description field" PREVIOUS="description"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="dimension_fk"/>
|
||||
<KEY NAME="dimension_fk" TYPE="foreign" FIELDS="dimensionid" REFTABLE="workshop_forms_rubric" REFFIELDS="id" PREVIOUS="primary"/>
|
||||
<KEY NAME="dimension_fk" TYPE="foreign" FIELDS="dimensionid" REFTABLE="workshopform_rubric" REFFIELDS="id" PREVIOUS="primary"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
</XMLDB>
|
@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="mod/workshop/db" VERSION="20090831" COMMENT="XMLDB file for Moodle mod/workshop/grading/nograding"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="workshop_forms_nograding" COMMENT="The assessment dimensions definitions of No grading strategy forms">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="description"/>
|
||||
<FIELD NAME="description" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="The description of the dimension" PREVIOUS="id" NEXT="descriptionformat"/>
|
||||
<FIELD NAME="descriptionformat" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the description field" PREVIOUS="description"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
@ -42,7 +42,6 @@ $string['allocatedetails'] = 'expected: $a->expected<br />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';
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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())) {
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user