]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-20236 overall codebase architecture cleanup and fixing regression
authorDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 18:05:48 +0000 (18:05 +0000)
committerDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 18:05:48 +0000 (18:05 +0000)
See the issue description for more details

35 files changed:
mod/workshop/allocation/manual/lib.php [moved from mod/workshop/allocation/manual/allocator.php with 84% similarity]
mod/workshop/allocation/random/lib.php [moved from mod/workshop/allocation/random/allocator.php with 98% similarity]
mod/workshop/allocation/random/settings_form.php
mod/workshop/allocation/random/simpletest/testallocator.php
mod/workshop/db/install.xml
mod/workshop/develtools.php
mod/workshop/editform.php
mod/workshop/form/accumulative/assessment_form.php [moved from mod/workshop/grading/accumulative/assessment_form.php with 89% similarity]
mod/workshop/form/accumulative/db/install.xml [moved from mod/workshop/grading/accumulative/db/install.xml with 58% similarity]
mod/workshop/form/accumulative/edit_form.php [moved from mod/workshop/grading/accumulative/edit_form.php with 89% similarity]
mod/workshop/form/accumulative/lang/en_utf8/workshopform_accumulative.php [moved from mod/workshop/grading/accumulative/lang/en_utf8/workshopgrading_accumulative.php with 100% similarity]
mod/workshop/form/accumulative/lib.php [moved from mod/workshop/grading/accumulative/strategy.php with 76% similarity]
mod/workshop/form/accumulative/simpletest/teststrategy.php [moved from mod/workshop/grading/accumulative/simpletest/teststrategy.php with 78% similarity]
mod/workshop/form/accumulative/version.php [moved from mod/workshop/grading/accumulative/version.php with 100% similarity]
mod/workshop/form/assessment_form.php [moved from mod/workshop/grading/assessment_form.php with 89% similarity]
mod/workshop/form/comments/db/install.xml [new file with mode: 0644]
mod/workshop/form/edit_form.php [moved from mod/workshop/grading/edit_form.php with 96% similarity]
mod/workshop/form/lib.php [moved from mod/workshop/grading/lib.php with 94% similarity]
mod/workshop/form/numerrors/assessment_form.php [moved from mod/workshop/grading/noerrors/assessment_form.php with 83% similarity]
mod/workshop/form/numerrors/db/install.xml [moved from mod/workshop/grading/noerrors/db/install.xml with 70% similarity]
mod/workshop/form/numerrors/edit_form.php [moved from mod/workshop/grading/noerrors/edit_form.php with 84% similarity]
mod/workshop/form/numerrors/lang/en_utf8/workshopform_numerrors.php [moved from mod/workshop/grading/noerrors/lang/en_utf8/workshopgrading_noerrors.php with 100% similarity]
mod/workshop/form/numerrors/lib.php [moved from mod/workshop/grading/noerrors/strategy.php with 70% similarity]
mod/workshop/form/numerrors/settings.php [moved from mod/workshop/grading/noerrors/settings.php with 62% similarity]
mod/workshop/form/numerrors/simpletest/teststrategy.php [moved from mod/workshop/grading/noerrors/simpletest/teststrategy.php with 85% similarity]
mod/workshop/form/numerrors/version.php [moved from mod/workshop/grading/noerrors/version.php with 100% similarity]
mod/workshop/form/rubric/db/install.xml [moved from mod/workshop/grading/rubric/db/install.xml with 53% similarity]
mod/workshop/grading/nograding/db/install.xml [deleted file]
mod/workshop/lang/en_utf8/workshop.php
mod/workshop/lib.php
mod/workshop/locallib.php
mod/workshop/settings.php
mod/workshop/styles.php
mod/workshop/tabs.php
mod/workshop/view.php

similarity index 84%
rename from mod/workshop/allocation/manual/allocator.php
rename to mod/workshop/allocation/manual/lib.php
index 739615c1cf08922d22cecfb546f1c76c2688e96d..2182cb6b2d48b4c7da4e217147fa596ecf1d868b 100644 (file)
@@ -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;
similarity index 98%
rename from mod/workshop/allocation/random/allocator.php
rename to mod/workshop/allocation/random/lib.php
index a6f345447457dc617d69dedda8587cfff8bcc438..cba20d52eb0f4b4e332a5be557ca4ae85aaf563a 100644 (file)
@@ -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();
 
index da35a5a4c965668d3c378fec29ca1f4bae7a49b9..59d6e2b6ce58f044d8aeaadb30c11b52b205fcb6 100644 (file)
@@ -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();
index 894a6a9e6b39cdab2e4f580813305b6d4184ad26..4a5be21845a679496d7ce4426dcdcc635a36626e 100644 (file)
@@ -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
index 1efdff25ee4b427d6d3743ded2974d3a0a838536..71e39432cbbcb28de8313e3edb705082e33e059d 100644 (file)
@@ -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"
 >
         <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>
index 12a35891263a5a66791ab63e611e5d6398fa8d27..3f7672ac489ea4eb12bf8c929e90642b46ff119b 100644 (file)
@@ -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
index 63db56c06664c485484878386b494df5ac3b188e..b211f8afb2ab049e34360988567008e9be5c942f 100644 (file)
@@ -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();
 
similarity index 89%
rename from mod/workshop/grading/accumulative/assessment_form.php
rename to mod/workshop/form/accumulative/assessment_form.php
index 3d4c1ffa5066a4b61c0a0bca834c0058719d9a05..25d6a7e80daad7532f3eb8b9ec3b2cabe8abac10 100644 (file)
@@ -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));
         }
similarity index 58%
rename from mod/workshop/grading/accumulative/db/install.xml
rename to mod/workshop/form/accumulative/db/install.xml
index 5bfb1e7fce7985aa17259328b5b3778bbecf4690..075cf24521edfff6aa33157335c4570f4511e01e 100644 (file)
@@ -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>
\ No newline at end of file
similarity index 89%
rename from mod/workshop/grading/accumulative/edit_form.php
rename to mod/workshop/form/accumulative/edit_form.php
index dcb2a79e72942c7f8bdf4d04758ddecb5b9aa4f0..9643c91cc3d9b6b64a28b8565c008bb93c8fc171 100644 (file)
@@ -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);
similarity index 76%
rename from mod/workshop/grading/accumulative/strategy.php
rename to mod/workshop/form/accumulative/lib.php
index d85aafede7b1ddcdb00fec55e82ab6d713deda1a..609291ce2044be6967914c2c82c4917d18d0e63b 100644 (file)
@@ -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));
-
-        // 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;
-    }
+        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);
 
-    /**
-     * 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);
     }
 
     /**
similarity index 78%
rename from mod/workshop/grading/accumulative/simpletest/teststrategy.php
rename to mod/workshop/form/accumulative/simpletest/teststrategy.php
index 72577a7520f3102650b1e73f47d99a8fe287f62c..b8888d17567b476c62b565f08bb6512030c5aebd 100644 (file)
@@ -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
similarity index 89%
rename from mod/workshop/grading/assessment_form.php
rename to mod/workshop/form/assessment_form.php
index 77754a82f3fc3060d0917f5bfd7ed95df33d3057..16dd0691786b174ac4a8a58408424ddd48de0569 100644 (file)
@@ -53,7 +53,11 @@ class workshop_assessment_form extends moodleform {
 
         $mform          = $this->_form;
         $this->mode     = $this->_customdata['mode'];       // influences the save buttons
-        $this->strategy = $this->_customdata['strategy'];   // strategy name sends back for cross check
+        $this->strategy = $this->_customdata['strategy'];   // instance of the strategy api class
+        $this->workshop = $this->_customdata['workshop'];   // instance of the workshop api class
+
+        // add the data common for all subplugins
+        $mform->addElement('hidden', 'strategy', $this->workshop->strategy);
 
         // add the strategy-specific fields
         $this->definition_inner($mform);
diff --git a/mod/workshop/form/comments/db/install.xml b/mod/workshop/form/comments/db/install.xml
new file mode 100644 (file)
index 0000000..191ae1a
--- /dev/null
@@ -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>
\ No newline at end of file
similarity index 96%
rename from mod/workshop/grading/edit_form.php
rename to mod/workshop/form/edit_form.php
index dc552e5fc875d4aa497f0580083444a638c113cf..daac75a113f0d0bf8d17091eafd9bc3e9a7015bb 100644 (file)
@@ -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);
 
similarity index 94%
rename from mod/workshop/grading/lib.php
rename to mod/workshop/form/lib.php
index 1efde373350120fff367b563a09da8f4ccbf8c72..bd5239c7c1aab4c82ab72018c42fc88c3df175d6 100644 (file)
@@ -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
similarity index 83%
rename from mod/workshop/grading/noerrors/assessment_form.php
rename to mod/workshop/form/numerrors/assessment_form.php
index 56d6685b5bacb258ca71d75c1a340f4022f649e8..6d92199a12a9c8668d97e37fc9beaaba50d0012d 100644 (file)
@@ -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);
similarity index 70%
rename from mod/workshop/grading/noerrors/db/install.xml
rename to mod/workshop/form/numerrors/db/install.xml
index 57c2b7213dafec9965d3b8de46bd8c762d12a1af..0107271b96c083364195e2f085462f8ddef5cc36 100644 (file)
@@ -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"/>
         <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"/>
similarity index 84%
rename from mod/workshop/grading/noerrors/edit_form.php
rename to mod/workshop/form/numerrors/edit_form.php
index 9f78138aae08b0dbec7eae38a25482ec2938eee7..a4c0731f4df5d1641fb4e0ac96a8bad14bcfc19c 100644 (file)
@@ -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);
similarity index 70%
rename from mod/workshop/grading/noerrors/strategy.php
rename to mod/workshop/form/numerrors/lib.php
index 77e9021610ec32bb62826363645ac2f8c24b4a8b..5a6e494fd16343c6d371da609209a9b925b50b9e 100644 (file)
 
 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);
     }
 }
similarity index 62%
rename from mod/workshop/grading/noerrors/settings.php
rename to mod/workshop/form/numerrors/settings.php
index 6567b9a39e43fe8cead834f8df7129914b46bb88..e1b4ee74701a9c8420fd8e1ddcb72a954ea88ee3 100644 (file)
 
 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));
similarity index 85%
rename from mod/workshop/grading/noerrors/simpletest/teststrategy.php
rename to mod/workshop/form/numerrors/simpletest/teststrategy.php
index eba908076471a84df2e8a40f00304856e4a48489..943be186d5334f4bb00018a60ae1591eeaefd83d 100644 (file)
@@ -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);
similarity index 53%
rename from mod/workshop/grading/rubric/db/install.xml
rename to mod/workshop/form/rubric/db/install.xml
index 3ddfa85a791a00577dbe3c5599ce60f3bfc06cd1..baec8b2eb4af15ab7ae28cc0383531bccfcdcba1 100644 (file)
@@ -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>
\ No newline at end of file
diff --git a/mod/workshop/grading/nograding/db/install.xml b/mod/workshop/grading/nograding/db/install.xml
deleted file mode 100644 (file)
index c0989a8..0000000
+++ /dev/null
@@ -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>
index 42a93803b245daf8cd4ad5cdd10cf3c7e6377656..9dfe3020089a979fb2122632f2b2457a5ba90c85 100644 (file)
@@ -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';
index 94edbd1e323ab6952da75f9603c05717bca56d5e..27fa35b1091f3ca01c47d7a988b035b6a51aa99f 100644 (file)
@@ -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;
index 8581a98cd6409f00b0aa9940414ec0ab3137d258..87b067af248ea9688eec981a71002ed82f7ad4ea 100644 (file)
@@ -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();
index 972ebb0c5317447a9b84823187e40420bb61405c..3ea3befa30dde8cd8e6dd8de5363576218559878 100644 (file)
@@ -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);
     }
 }
index 95d3644885b9db65c0996bf2e8096da5db1fa532..223a274911d24a6cf087df2100372c6ec657d944 100644 (file)
@@ -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;
 /**
  * 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;
 }
 
     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%;
 }
 /**
  * Assessment
  */
-.assessment-summary.graded {
+.mod-workshop .assessment-summary.graded {
     background-color: #e7f1c3;
 }
 
+.mod-workshop .assessmentform .description {
+    margin: 0px 1em;
+}
index 22b6268ccb8faea30f41b05afdeaa4f5363c5b4a..cf8b11a04d3bb643d38101ea7021d3e6043d64f8 100644 (file)
@@ -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())) {
index d04fc15336c68a2267b7fd5c47d653575bde0d42..91aedb135ab664186bdb638d737d523f5f35b859 100644 (file)
@@ -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: