]> git.mjollnir.org Git - moodle.git/commitdiff
A lot of changes here and there
authorDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 17:49:01 +0000 (17:49 +0000)
committerDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 17:49:01 +0000 (17:49 +0000)
31 files changed:
mod/workshop/TODO.txt [new file with mode: 0644]
mod/workshop/allocation.php
mod/workshop/allocation/lib.php
mod/workshop/allocation/manual/allocator.php
mod/workshop/allocation/manual/renderer.php
mod/workshop/allocation/random/allocator.php
mod/workshop/allocation/random/settings_form.php
mod/workshop/allocation/random/simpletest/testallocator.php
mod/workshop/assessment.php
mod/workshop/db/install.xml
mod/workshop/develtools.php
mod/workshop/editform.php
mod/workshop/fileinfolib.php
mod/workshop/grading/accumulative/assessment_form.php
mod/workshop/grading/accumulative/edit_form.php
mod/workshop/grading/accumulative/simpletest/teststrategy.php
mod/workshop/grading/accumulative/strategy.php
mod/workshop/grading/assessment_form.php
mod/workshop/grading/edit_form.php
mod/workshop/grading/lib.php [new file with mode: 0644]
mod/workshop/grading/noerrors/edit_form.php
mod/workshop/grading/noerrors/strategy.php
mod/workshop/grading/strategy.php [deleted file]
mod/workshop/lang/en_utf8/workshop.php
mod/workshop/lib.php
mod/workshop/locallib.php
mod/workshop/renderer.php
mod/workshop/simpletest/testworkshopapi.php
mod/workshop/submission.php
mod/workshop/version.php
mod/workshop/view.php

diff --git a/mod/workshop/TODO.txt b/mod/workshop/TODO.txt
new file mode 100644 (file)
index 0000000..6d87264
--- /dev/null
@@ -0,0 +1,3 @@
+- assessment form, dimension description - I want to have a single filearea
+  for all dimension descriptions within the given workshop. Does not work,
+  TBD with skodak
index b1954a56d9f12de3b5d6faf801c857983657db81..fb8d421bb5b88931c4d95b75e8881c1d7724fbd8 100644 (file)
@@ -38,7 +38,7 @@ $PAGE->set_url('mod/workshop/allocation.php', array('cmid' => $cmid, 'method' =>
 $cm         = get_coursemodule_from_id('workshop', $cmid, 0, false, MUST_EXIST);
 $course     = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
 $workshop   = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST);
-$workshop   = new workshop_api($workshop, $cm, $course);
+$workshop   = new workshop($workshop, $cm, $course);
 
 require_login($course, false, $cm);
 $context = $PAGE->context;
index 791a9e5b43e454e2670629fa5218e073ada2bb67..706f6362146d3199fea49c5b7cdd81e3a68b0226 100644 (file)
@@ -44,7 +44,7 @@ interface workshop_allocator {
      * is generated. Therefore is may process any data submitted and do other tasks.
      * It should not generate any output
      *
-     * @throws moodle_workshop_exception
+     * @throws moodle_exception
      * @return mixed void or optional HTML string
      */
     public function init();
index 975851aad4a3d88010db581ef2dd10bfb3a109e4..ff3f691f78a5f247f26cbdc6815d94beed4a151c 100644 (file)
@@ -64,7 +64,7 @@ class workshop_manual_allocator implements workshop_allocator {
         switch ($mode) {
         case 'new':
             if (!confirm_sesskey()) {
-                throw new moodle_workshop_exception($this->workshop, 'confirmsesskeybad');
+                throw new moodle_exception('confirmsesskeybad');
             }
             $reviewerid = required_param('by', PARAM_INT);
             $authorid   = required_param('of', PARAM_INT);
@@ -93,7 +93,7 @@ class workshop_manual_allocator implements workshop_allocator {
             break;
         case 'del':
             if (!confirm_sesskey()) {
-                throw new moodle_workshop_exception($this->workshop, 'confirmsesskeybad');
+                throw new moodle_exception('confirmsesskeybad');
             }
             $assessmentid   = required_param('what', PARAM_INT);
             $confirmed      = optional_param('confirm', 0, PARAM_INT);
index 3ceddae5b512117e47a3b9043c25a994872d317b..5178a4c9786f41a7ca7b0f3b243b4953436769fb 100644 (file)
@@ -41,7 +41,6 @@ class moodle_mod_workshop_allocation_manual_renderer extends moodle_renderer_bas
      *
      * @param mixed $page the page we are doing output for
      * @param mixed $output lower-level renderer, typically moodle_core_renderer
-     * @access public
      * @return void
      */
     public function __construct($page, $output) {
@@ -52,7 +51,7 @@ class moodle_mod_workshop_allocation_manual_renderer extends moodle_renderer_bas
     /**
      * Display the table of all current allocations and widgets to modify them
      *
-     * @param workshop $workshop workshop instance object
+     * @param workshop $workshop workshop API instance
      * @param array $peers prepared array of all allocations
      * @param int $hlauthorid highlight this author
      * @param int $hlreviewerid highlight this reviewer
@@ -122,11 +121,11 @@ class moodle_mod_workshop_allocation_manual_renderer extends moodle_renderer_bas
      * Returns information about the current reviewers of the given participant and a selector do add new one
      *
      * @param stdClass $user         participant data
-     * @param workshop_api $workshop workshop record
+     * @param workshop $workshop workshop record
      * @param array $peers           objects with properties to display picture and fullname
      * @return string html code
      */
-    protected function reviewers_of_participant(stdClass $user, workshop_api $workshop, &$peers) {
+    protected function reviewers_of_participant(stdClass $user, workshop $workshop, &$peers) {
         $o = '';
         if (is_null($user->submissionid)) {
             $o .= $this->output->output_tag('span', array('class' => 'info'), get_string('nothingtoreview', 'workshop'));
@@ -161,11 +160,11 @@ class moodle_mod_workshop_allocation_manual_renderer extends moodle_renderer_bas
      * Returns information about the current reviewees of the given participant and a selector do add new one
      *
      * @param stdClass $user         participant data
-     * @param workshop_api $workshop workshop record
+     * @param workshop $workshop workshop record
      * @param array $peers           objects with properties to display picture and fullname
      * @return string html code
      */
-    protected function reviewees_of_participant(stdClass $user, workshop_api $workshop, &$peers) {
+    protected function reviewees_of_participant(stdClass $user, workshop $workshop, &$peers) {
         $o = '';
         if (is_null($user->submissionid)) {
             $o .= $this->output->container(get_string('withoutsubmission', 'workshop'), 'info');
index d1268b06c47e7c4901f2d82b8150c3a623e88362..db8dada1989571bb1c9d60ac8e90d64be7dfb264 100644 (file)
@@ -74,7 +74,7 @@ class workshop_random_allocator implements workshop_allocator {
         } else if ($settings = $this->mform->get_data()) {
             // process validated data
             if (!confirm_sesskey()) {
-                throw new moodle_workshop_exception($this->workshop, 'confirmsesskeybad');
+                throw new moodle_exception('confirmsesskeybad');
             }
             $o                  = array();      // list of output messages
             $numofreviews       = required_param('numofreviews', PARAM_INT);
@@ -177,9 +177,9 @@ class workshop_random_allocator implements workshop_allocator {
      * If the submission has already been allocated, it is skipped. If the author is not found among
      * reviewers, the submission is not assigned.
      *
-     * @param array $authors as returned by {@see workshop_api::get_peer_authors_by_group()}
-     * @param array $reviewers as returned by {@see workshop_api::get_peer_reviewers_by_group()}
-     * @param array $assessments as returned by {@see workshop_api::get_assessments()}
+     * @param array $authors as returned by {@see workshop::get_peer_authors_by_group()}
+     * @param array $reviewers as returned by {@see workshop::get_peer_reviewers_by_group()}
+     * @param array $assessments as returned by {@see workshop::get_assessments()}
      * @return array of new allocations to be created, array of array(reviewerid => authorid)
      */
     protected function self_allocation($authors=array(), $reviewers=array(), $assessments=array()) {
@@ -225,7 +225,7 @@ class workshop_random_allocator implements workshop_allocator {
         foreach ($newallocations as $newallocation) {
             list($reviewerid, $authorid) = each($newallocation);
             if (!isset($submissions[$authorid])) {
-                throw new moodle_workshop_exception($this->workshop, 'unabletoallocateauthorwithoutsubmission');
+                throw new moodle_exception('unabletoallocateauthorwithoutsubmission', 'workshop');
             }
             $submission = $submissions[$authorid];
             $status = $this->workshop->add_allocation($submission, $reviewerid, true);
@@ -249,7 +249,7 @@ class workshop_random_allocator implements workshop_allocator {
         if (is_array($submissions)) {
             foreach ($submissions as $submissionid => $submission) {
                 if (isset($byauthor[$submission->userid])) {
-                    throw new moodle_workshop_exception($this->workshop, 'moresubmissionsbyauthor');
+                    throw new moodle_exception('moresubmissionsbyauthor', 'workshop');
                 }
                 $byauthor[$submission->userid] = $submission;
             }
@@ -354,7 +354,7 @@ class workshop_random_allocator implements workshop_allocator {
             // get current workload
             list($squarelinks, $circlelinks) = $this->convert_assessments_to_links($assessments);
         } else {
-            throw new moodle_workshop_exception($this->workshop, 'unknown user type passed');
+            throw new moodle_exception('unknownusertypepassed', 'workshop');
         }
         $o[] = 'debug::circle links = ' . json_encode($circlelinks);
         $o[] = 'debug::square links = ' . json_encode($squarelinks);
@@ -374,7 +374,7 @@ class workshop_random_allocator implements workshop_allocator {
         unset($squaregroupsworkload[0]);    // [0] is not real group, it contains all users
         $o[] = 'debug::square workload = ' . json_encode($squareworkload);
         $o[] = 'debug::square group workload = ' . json_encode($squaregroupsworkload);
-        $gmode = groups_get_activity_groupmode($this->workshop->cm, $this->workshop->courserecord);
+        $gmode = groups_get_activity_groupmode($this->workshop->cm, $this->workshop->course);
         if (SEPARATEGROUPS == $gmode) {
             // shuffle all groups but [0] which means "all users"
             $circlegroups = array_keys(array_diff_key($allcircles, array(0 => null)));
@@ -477,7 +477,7 @@ class workshop_random_allocator implements workshop_allocator {
     /**
      * Extracts the information about reviews from the authors' and reviewers' perspectives
      *
-     * @param array $assessments array of assessments as returned by {@link workshop_api::get_assessments()}
+     * @param array $assessments array of assessments as returned by {@link workshop::get_assessments()}
      * @return array of two arrays
      */
     protected function convert_assessments_to_links($assessments) {
index 7299343f888eeb8d000c4db24cc391ce0d3be227..787a6554dfe0412b010bfd20e918ca0b47dc093e 100644 (file)
@@ -46,7 +46,7 @@ class workshop_random_allocator_form extends moodleform {
 
         $mform->addElement('header', 'settings', get_string('allocationsettings', 'workshop'));
 
-        $gmode = groups_get_activity_groupmode($workshop->cm, $workshop->courserecord);
+        $gmode = groups_get_activity_groupmode($workshop->cm, $workshop->course);
         switch ($gmode) {
         case NOGROUPS:
             $grouplabel = get_string('groupsnone', 'group');
index c08f7b1f0b091c7984d5aea782ea35e3f7e668ca..d3acd13964eada3d557c03607c44571d38d2b92e 100644 (file)
@@ -67,7 +67,10 @@ class workshop_allocation_random_test extends UnitTestCase {
     protected $allocator;
 
     public function setUp() {
-        $this->workshop     = new workshop((object)array('id' => 42), new stdClass(), new stdClass());
+        $cm                 = (object)array('id' => 3);
+        $course             = (object)array('id' => 11);
+        $workshop           = (object)array('id' => 42);
+        $this->workshop     = new workshop($workshop, $cm, $course);
         $this->allocator    = new testable_workshop_random_allocator($this->workshop);
     }
 
@@ -141,7 +144,7 @@ class workshop_allocation_random_test extends UnitTestCase {
                 87 => (object)array('id' => 121, 'userid' => 3),
                 );
         // set expectation
-        $this->expectException('moodle_workshop_exception');
+        $this->expectException('moodle_exception');
         // exercise SUT
         $submissions = $this->allocator->index_submissions_by_authors($submissions);
     }
index b995d7700c43b9dee692dead7db99e13bf218d89..77ac63a2d757c94760b237c39da0a8a39312a590 100644 (file)
@@ -48,20 +48,21 @@ if ($preview = optional_param('preview', 0, PARAM_INT)) {
 }
 
 require_login($course, false, $cm);
-$workshop = new workshop_api($workshop, $cm, $course);
+if (isguestuser()) {
+    print_error('guestsarenotallowed');
+}
+$workshop = new workshop($workshop, $cm, $course);
 
 if ('preview' == $mode) {
     require_capability('mod/workshop:editdimensions', $PAGE->context);
-    // TODO logging add_to_log($course->id, "workshop", "view", "view.php?id=$cm->id", "$workshop->id");
     $PAGE->set_url($workshop->previewform_url());
     $PAGE->set_title($workshop->name);
     $PAGE->set_heading($course->fullname);
 
 } elseif ('assessment' == $mode) {
-    if (!(has_capability('mod/workshop:peerassess', $PAGE->context) || has_capability('mod/workshop:peerassess', $PAGE->context))) {
+    if (!has_any_capability(array('mod/workshop:peerassess', 'mod/workshop:assessallsubmissions'), $PAGE->context)) {
         print_error('nopermissions', '', $workshop->view_url());
     }
-    // TODO logging add_to_log($course->id, "workshop", "view", "view.php?id=$cm->id", "$workshop->id");
     $PAGE->set_url($workshop->assess_url($assessment->id));
     $PAGE->set_title($workshop->name);
     $PAGE->set_heading($course->fullname);
@@ -79,22 +80,20 @@ $strategy = $workshop->grading_strategy_instance();
 // load the form to edit the grading strategy dimensions
 $mform = $strategy->get_assessment_form($PAGE->url, $mode);
 
-// initialize form data
-//todo $mform->set_data($formdata);
-
 if ($mform->is_cancelled()) {
     redirect($returnurl);
 
 } elseif ($data = $mform->get_data()) {
     if (isset($data->backtoeditform)) {
+        // user wants to return from preview to form editing
         redirect($workshop->editform_url());
     }
-    $strategy->save_assessment($data);
+    $strategy->save_assessment($assessment, $data);
     if (isset($data->saveandclose)) {
         redirect($workshop->view_url());
     } else {
         // save and continue - redirect to self to prevent data being re-posted by pressing "Reload"
-        redirect($PAGE->url->out());
+        redirect($PAGE->url);
     }
 }
 
@@ -108,7 +107,7 @@ $navlinks[] = array('name' => format_string($workshop->name),
                     'type' => 'activityinstance');
 if ($mode == 'preview') {
     $navlinks[] = array('name' => get_string('editingassessmentform', 'workshop'),
-                        'link' => $workshop->editform_url(),
+                        'link' => $workshop->editform_url()->out(),
                         'type' => 'title');
     $navlinks[] = array('name' => get_string('previewassessmentform', 'workshop'),
                         'link' => '',
@@ -122,16 +121,20 @@ $navigation = build_navigation($navlinks);
 
 // Output starts here
 
-$wsoutput = $THEME->get_renderer('mod_workshop', $PAGE);    // workshop renderer
 echo $OUTPUT->header($navigation);
 echo $OUTPUT->heading(get_string('assessmentform', 'workshop'), 2);
-if (has_capability('mod/workshop:viewauthornames', $PAGE->context)) {
-    $showname   = true;
-    $author     = $workshop->user_info($submission->userid);
-} else {
-    $showname   = false;
-    $author     = null;
+
+if ('assessment' === $mode) {
+    if (has_capability('mod/workshop:viewauthornames', $PAGE->context)) {
+        $showname   = true;
+        $author     = $workshop->user_info($submission->userid);
+    } else {
+        $showname   = false;
+        $author     = null;
+    }
+    $wsoutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE);    // workshop renderer
+    echo $wsoutput->submission_full($submission, $showname, $author);
 }
-echo $wsoutput->submission_full($submission, $showname, $author);
+
 $mform->display();
 echo $OUTPUT->footer();
index a35f9f64df87f029c1f01353a30b8f8425a93e60..5e3fa5a4405e4be2e970a7d343f8c09de468922b 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/workshop/db" VERSION="20090727" COMMENT="XMLDB file for Moodle mod/workshop"
+<XMLDB PATH="mod/workshop/db" VERSION="20090731" COMMENT="XMLDB file for Moodle mod/workshop"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
 >
         <FIELD NAME="workshopid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The id of the Workshop instance where this dimension is used as a part of evaluation form." PREVIOUS="id" NEXT="sort"/>
         <FIELD NAME="sort" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The order of the dimension in the 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="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="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Can the content be trusted" PREVIOUS="descriptionformat" 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="descriptiontrust" 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>
       </KEYS>
     </TABLE>
   </TABLES>
-</XMLDB>
+</XMLDB>
\ No newline at end of file
index 734590884e2266a2cd96f6b8bd54c2c0dc0c35f2..1d2e74cd73ed85c7bd44e85362add9d96cca3e65 100644 (file)
@@ -39,7 +39,7 @@ has_capability('moodle/site:config', get_system_context()) || die('You are not a
 $cm         = get_coursemodule_from_id('workshop', $cmid, 0, false, MUST_EXIST);
 $course     = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
 $workshop   = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST);
-$workshop   = new workshop_api($workshop, $cm, $course); // wrap the record with a full API
+$workshop   = new workshop($workshop, $cm, $course); // wrap the record with a full API
 
 require_login($course, false, $cm);
 
@@ -48,15 +48,18 @@ $PAGE->set_title($workshop->name);
 $PAGE->set_heading($course->fullname);
 $PAGE->set_button(update_module_button($cm->id, $course->id, get_string('modulename', 'workshop')));
 
+$wsoutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE);
+
 $navigation = build_navigation('Development tools', $cm);
-$menu       = navmenu($course, $cm);
+// todo $menu       = navmenu($course, $cm);
 
 switch ($tool) {
 case 'mksubmissions':
     $authors                = $workshop->get_peer_authors(false);
     $authorswithsubmission  = $workshop->get_peer_authors(true);
     $authors                = array_diff_key($authors, $authorswithsubmission);
-    echo $OUTPUT->header($navigation, $menu);
+    echo $OUTPUT->header($navigation);
+    $c = 0; // counter
     foreach ($authors as $authorid => $author) {
         $timenow = time() - rand(0, 60 * 60 * 24 * 7); // submitted sometimes during last week
         $submission                 = new stdClass();
@@ -66,18 +69,46 @@ case 'mksubmissions':
         $submission->timecreated    = $timenow;
         $submission->timemodified   = $timenow;
         $submission->title          = $author->firstname . '\'s submission';
-        $submission->data           = '';
-        $submission->dataformat     = FORMAT_HTML;
-        $submission->datatrust      = 0;
+        $submission->content        = "<p>Pellentesque habitant morbi tristique " .
+                                    "senectus et netus et malesuada fames ac " .
+                                    "turpis egestas. Sed posuere volutpat nunc " .
+                                    "semper ultricies! Aenean elementum metus in  " .
+                                    "lorem volutpat eu volutpat neque vulputate? " .
+                                    "Pellentesque sit amet sem leo. In hac " .
+                                    "habitasse platea dictumst. Proin quis " .
+                                    "accumsan elit. Nulla quis libero ac nunc " .
+                                    "elementum commodo at et sem. Vestibulum " .
+                                    "eget euismod felis. Lorem ipsum dolor sit " .
+                                    "amet, consectetur adipiscing elit. Aliquam " .
+                                    "id tellus vel velit aliquet volutpat at " .
+                                    "quis arcu. Nulla laoreet tincidunt sodales. " .
+                                    "Suspendisse potenti. Curabitur sagittis " .
+                                    "arcu nec erat aliquet imperdiet. Aenean at " .
+                                    "mi ut est molestie posuere a vitae mauris.</p>";
+
+        $submission->contentformat  = FORMAT_HTML;
+        $submission->contenttrust   = 0;
         $submission->id = $DB->insert_record('workshop_submissions', $submission);
-        // todo print some info
+        echo "<pre>Added submission by " . fullname($author) . "</pre>\n";
+        $c++;
+    }
+    if ($c == 0) {
+        echo "<pre>No submission added</pre>\n";
     }
     echo $OUTPUT->continue_button($PAGE->url->out());
     echo $OUTPUT->footer();
-    exit;
+    exit();
+
+case 'menu':
+    // no break, skip to default
+default:
+    echo $OUTPUT->header($navigation);
+    echo $OUTPUT->heading('Workshop development tools', 1);
+    echo '<ul>';
+    echo '<li><a href="' . $PAGE->url->out(false, array('tool' => 'mksubmissions')) . '">Fake submissions</a></li>';
+    echo '<li><a href="' . $PAGE->url->out(false, array('tool' => 'rmsubmissions')) . '">Remove all submissions (TODO)</a></li>';
+    echo '</ul>';
+    echo $OUTPUT->footer();
 }
 
-echo $OUTPUT->header($navigation, $menu);
-echo $OUTPUT->heading('Workshop development tools', 1);
-echo '<a href="' . $PAGE->url->out(false, array('tool' => 'mksubmissions')) . '">Fake submissions</a>';
-echo $OUTPUT->footer();
+
index 3499056ceb1c2021c0b98943e49b6615a346ff58..989020f8a42a63856e987b2a44db52f0f8abbdb8 100644 (file)
@@ -35,7 +35,7 @@ require_login($course, false, $cm);
 require_capability('mod/workshop:editdimensions', $PAGE->context);
 
 $workshop   = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST);
-$workshop   = new workshop_api($workshop, $cm, $course);
+$workshop   = new workshop($workshop, $cm, $course);
 
 $PAGE->set_url($workshop->editform_url());
 $PAGE->set_title($workshop->name);
@@ -44,21 +44,13 @@ $PAGE->set_heading($course->fullname);
 // load the grading strategy logic
 $strategy = $workshop->grading_strategy_instance();
 
-// load the assessment form definition from the database
-// this must be called before get_edit_strategy_form() where we have to know
-// the number of repeating fieldsets
-$formdata = $strategy->load_form();
-
 // load the form to edit the grading strategy dimensions
 $mform = $strategy->get_edit_strategy_form($PAGE->url);
 
-// initialize form data
-$mform->set_data($formdata);
-
 if ($mform->is_cancelled()) {
     redirect($workshop->view_url());
 } elseif ($data = $mform->get_data()) {
-    $strategy->save_form($data);
+    $strategy->save_edit_strategy_form($data);
     if (isset($data->saveandclose)) {
         redirect($workshop->view_url());
     } elseif (isset($data->saveandpreview)) {
@@ -83,8 +75,9 @@ $navlinks[] = array('name' => get_string('editingassessmentform', 'workshop'),
 $navigation = build_navigation($navlinks);
 
 // OUTPUT STARTS HERE
+// todo use outputlib
 
-print_header_simple(format_string($workshop->name), '', $navigation, '', '', true, '', navmenu($course, $cm));
+print_header_simple(format_string($workshop->name), '', $navigation, '', '', true, '');
 
 print_heading(get_string('strategy' . $workshop->strategy, 'workshop'));
 
index fe41d9656beb9a0130401ae7d0c02b5a70ea4d50..994fdb878b1e0e5bf0b7a75b069d6a21c352f36f 100644 (file)
 defined('MOODLE_INTERNAL') || die();
 
 /**
- * Represents the nodes of the virtual directory tree that may be browsed in file manager
+ * Represents virtual root node for all submissions
  *
- * Here we create a virtual hierarchy of all submissions, sorted by their author.
+ * Workshop submission uses two fileareas: workshop_submission_content
+ * for editor's embeded media and workshop_submission_attachment for attachments.
+ * In both, the itemid represents the submission id.
  */
-class workshop_file_info extends file_info {
+class workshop_file_info_submissions_container extends file_info {
     protected $course;
     protected $cm;
     protected $areas;
@@ -90,7 +92,8 @@ class workshop_file_info extends file_info {
         global $DB;
 
         $children = array();
-        $itemids = $DB->get_records('files', array('contextid' => $this->context->id, 'filearea' => $this->filearea), 'itemid', "DISTINCT itemid");
+        $itemids = $DB->get_records('files', array('contextid' => $this->context->id, 'filearea' => $this->filearea),
+            'itemid', "DISTINCT itemid");
         foreach ($itemids as $itemid => $unused) {
             if ($child = $this->browser->get_file_info($this->context, $this->filearea, $itemid)) {
                 $children[] = $child;
index ea36b5bb443981d28bf621055cce5ba92d137ac7..99d9cbe8cc9ee54fe1ffe0f626fe2784e190af53 100644 (file)
@@ -25,7 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-//require_once(dirname(dirname(dirname(__FILE__))).'/lib.php');   // module library
 require_once(dirname(dirname(__FILE__)).'/assessment_form.php');    // parent class definition
 
 /**
@@ -40,32 +39,38 @@ class workshop_accumulative_assessment_form extends workshop_assessment_form {
      *
      * Called by the parent::definition()
      *
-     * @access protected
      * @return void
      */
     protected function definition_inner(&$mform) {
+        $fields = (array)$this->_customdata['fields'];
+        $nodims = $this->_customdata['nodims'];     // number of assessment dimensions
 
-        for ($i = 0; $i < $this->strategy->get_number_of_dimensions(); $i++) {
+        $mform->addElement('hidden', 'nodims', $nodims);
 
+        for ($i = 0; $i < $nodims; $i++) {
             // dimension header
-            $mform->addElement('header', "dimensionhdr[$i]",
-                                    str_replace('{no}', $i+1, get_string('dimensionnumberaccumulative', 'workshop', '{no}')));
+            $dimtitle = get_string('dimensionnumberaccumulative', 'workshop', $i+1);
+            $mform->addElement('header', "dimensionhdr__idx_$i", $dimtitle);
+
+            // dimension id
+            $mform->addElement('hidden', 'dimensionid__idx_'.$i, $fields['dimensionid__idx_'.$i]);
 
             // dimension description
-            $desc = '<div id="id_dim_'.$this->fields["dimensionid[$i]"] . '_desc" class="fitem description accumulative">' . "\n";
-            $desc .= format_text($this->fields["description[$i]"], $this->fields["descriptionformat[$i]"]);
+            $desc = '<div id="id_dim_'.$fields['dimensionid__idx_'.$i].'_desc" class="fitem description accumulative">'."\n";
+            $desc .= format_text($fields['description__idx_'.$i], $fields['descriptionformat__idx_'.$i]);
             $desc .= "\n</div>";
             $mform->addElement('html', $desc);
 
             // grade for this aspect
-            $label = 'Grade'; // todo
+            $label = 'Grade'; // todo i18n 
+            $label .= ' / ' . $fields['grade__idx_' . $i];
             $options = array(10,9,8,7,6,5,4,3,2,1,0); // todo
-            $mform->addElement('select', "grade[$i]", $label, $options);
+            $mform->addElement('select', 'grade__idx_' . $i, $label, $options);
 
             // comment
-            $label = 'Comment'; //todo
-            $mform->addElement('htmleditor', "comment[$i]", $label, array());
-
+            $label = 'Comment'; //todo i18n
+            //$mform->addElement('editor', 'peercomment__idx_' . $i, $label, null, array('maxfiles' => 0));
+            $mform->addElement('textarea', 'peercomment__idx_' . $i, $label, array('cols' => 60, 'rows' => 5));
         }
 
     }
index d530b66ac1deb691d48437948eb0d65b0c465574..13781ee91efd22468fd4426c102e91f060a2d89a 100644 (file)
@@ -40,34 +40,34 @@ class workshop_edit_accumulative_strategy_form extends workshop_edit_strategy_fo
      *
      * Called by the parent::definition()
      *
-     * @access protected
      * @return void
      */
     protected function definition_inner(&$mform) {
 
-        $gradeoptions = array(20 => 20, 10 => 10, 5 => 5);
-        $weights = workshop_get_dimension_weights();
+        $norepeats          = $this->_customdata['norepeats'];          // number of dimensions to display
+        $descriptionopts    = $this->_customdata['descriptionopts'];    // wysiwyg fields options
+        $current            = $this->_customdata['current'];            // current data to be set
+
+        $mform->addElement('hidden', 'norepeats', $norepeats);
+        // value not to be overridden by submitted value
+        $mform->setConstants(array('norepeats' => $norepeats));
 
-        $repeated = array();
-        $repeated[] =& $mform->createElement('hidden', 'dimensionid', 0);
-        $repeated[] =& $mform->createElement('header', 'dimension',
-                                                get_string('dimensionnumberaccumulative', 'workshop', '{no}'));
-        $repeated[] =& $mform->createElement('htmleditor', 'description',
-                                                get_string('dimensiondescription', 'workshop'), array());
-        $repeated[] =& $mform->createElement('select', 'grade', get_string('grade'), $gradeoptions);
-        $repeated[] =& $mform->createElement('select', 'weight', get_string('dimensionweight', 'workshop'), $weights);
+        $gradeoptions = array(20 => 20, 10 => 10, 8=>8, 5 => 5);
+        $weights = workshop_get_dimension_weights();
 
-        $repeatedoptions = array();
-        $repeatedoptions['description']['type'] = PARAM_CLEANHTML;
-        $repeatedoptions['description']['helpbutton'] = array('dimensiondescription',
-                                                            get_string('dimensiondescription', 'workshop'), 'workshop');
-        $repeatedoptions['grade']['default'] = 10;
-        $repeatedoptions['weight']['default'] = 1;
+        for ($i = 0; $i < $norepeats; $i++) {
+            $mform->addElement('header', 'dimension'.$i, get_string('dimensionnumberaccumulative', 'workshop', $i+1));
+            $mform->addElement('hidden', 'dimensionid__idx_'.$i);
+            $mform->addElement('editor', 'description__idx_'.$i.'_editor', get_string('dimensiondescription', 'workshop'),
+                                    array('cols' => 20), $descriptionopts);
+            $mform->addElement('select', 'grade__idx_'.$i, get_string('grade'), $gradeoptions);
+            $mform->addElement('select', 'weight__idx_'.$i, get_string('dimensionweight', 'workshop'), $weights);
+        }
 
-        $numofdimensionstoadd   = 2;
-        $numofinitialdimensions = 3;
-        $numofdisplaydimensions = max($this->strategy->get_number_of_dimensions() + $numofdimensionstoadd, $numofinitialdimensions);
-        $this->repeat_elements($repeated, $numofdisplaydimensions,  $repeatedoptions, 'numofdimensions', 'adddimensions', $numofdimensionstoadd, get_string('addmoredimensionsaccumulative', 'workshop', $numofdimensionstoadd));
+        $mform->registerNoSubmitButton('noadddims');
+        $mform->addElement('submit', 'noadddims', get_string('addmoredimensionsaccumulative', 'workshop',
+                                                                    WORKSHOP_STRATEGY_ADDDIMS));
+        $mform->closeHeaderBefore('noadddims');
+        $this->set_data($current);
     }
-
 }
index ff0b353b0636e59cc261654eb6791b8199956643..8bbbef52ec3b75d5ef173ec7840161d50fd65fd8 100644 (file)
@@ -32,15 +32,15 @@ require_once($CFG->dirroot . '/mod/workshop/grading/accumulative/strategy.php');
  * Test subclass that makes all the protected methods we want to test public
  */
 class testable_workshop_accumulative_strategy extends workshop_accumulative_strategy {
-
     public function _cook_dimension_records(array $raw) {
         return parent::_cook_dimension_records($raw);
     }
-
-    public function _cook_form_data(stdClass $raw) {
-        return parent::_cook_form_data($raw);
+    public function _cook_edit_form_data(stdClass $raw) {
+        return parent::_cook_edit_form_data($raw);
+    }
+    public function _cook_assessment_form_data(stdClass $assessment, stdClass $raw) {
+        return parent::_cook_assessment_form_data($assessment, $raw);
     }
-
 }
 
 class workshop_accumulative_strategy_test extends UnitTestCase {
@@ -59,11 +59,10 @@ class workshop_accumulative_strategy_test extends UnitTestCase {
 
     /** setup testing environment */
     public function setUp() {
-
-        $this->workshop             = new stdClass;
-        $this->workshop->id         = 42;
-        $this->workshop->strategy   = 'accumulative';
-
+        $cm             = (object)array('id' => 3);
+        $course         = (object)array('id' => 11);
+        $workshop       = (object)array('id' => 42, 'strategy' => 'accumulative');
+        $this->workshop = new workshop($workshop, $cm, $course);
         $this->strategy = new testable_workshop_accumulative_strategy($this->workshop);
 
         // emulate a form with 5 dimensions. The first three are already in DB, the forth is new and the
@@ -71,12 +70,27 @@ class workshop_accumulative_strategy_test extends UnitTestCase {
         $this->rawform = new stdClass;
         $this->rawform->workshopid          = 42;
         $this->rawform->strategy            = 'accumulative';
-        $this->rawform->numofdimensions     = 5;
-        $this->rawform->dimensionid         = array(0 => 3,       1=> 2,         2 => 1,       3 => 0,       4 => 0);
-        $this->rawform->description         = array(0 => 'First', 1 => 'Second', 2 => 'Third', 3 => 'Forth', 4 => '');
-        $this->rawform->descriptionformat   = array(0 => 1,       1 => 1,        2 => 1,       3 => 1,       4 => 1);
-        $this->rawform->grade               = array(0 => 10,      1 => 5,        2 => 5,       3 => 2,       4 => 10);
-        $this->rawform->weight              = array(0 => 1,       1 => 1,        2 => 2,       3 => 2,       4 => 1);
+        $this->rawform->norepeats           = 5;
+        $this->rawform->dimensionid__idx_0  = 3;
+        $this->rawform->dimensionid__idx_1  = 2;
+        $this->rawform->dimensionid__idx_2  = 1;
+        $this->rawform->dimensionid__idx_3  = 0;
+        $this->rawform->dimensionid__idx_4  = 0;
+        $this->rawform->description__idx_0_editor = array('text' => 'First', 'format' =>1, 'itemid' => 123456789);
+        $this->rawform->description__idx_1_editor = array('text' => 'Second', 'format' =>1, 'itemid' => 123456788);
+        $this->rawform->description__idx_2_editor = array('text' => 'Third', 'format' =>1, 'itemid' => 123456787);
+        $this->rawform->description__idx_3_editor = array('text' => 'Forth', 'format' =>1, 'itemid' => 123456786);
+        $this->rawform->description__idx_4_editor = array('text' => '', 'format' =>1, 'itemid' => 123456785);
+        $this->rawform->grade__idx_0  = 10;
+        $this->rawform->grade__idx_1  = 5;
+        $this->rawform->grade__idx_2  = 5;
+        $this->rawform->grade__idx_3  = 2;
+        $this->rawform->grade__idx_4  = 10;
+        $this->rawform->weight__idx_0 = 1;
+        $this->rawform->weight__idx_1 = 1;
+        $this->rawform->weight__idx_2 = 2;
+        $this->rawform->weight__idx_3 = 2;
+        $this->rawform->weight__idx_4 = 1;
 
         // emulate two assessment dimensions being stored in database
         $this->rawdb = array();
@@ -98,37 +112,57 @@ class workshop_accumulative_strategy_test extends UnitTestCase {
         $this->rawdb[7]->grade              = 10;
         $this->rawdb[7]->weight             = 1;
 
+        // emulate the filled assessment form
+        $this->rawass->nodims               = 5;
+        $this->rawass->strategyname         = 'accumulative';
+        $this->rawass->dimensionid__idx_0   = 3;
+        $this->rawass->grade__idx_0         = 10;
+        $this->rawass->peercomment__idx_0   = 'Great';
+        $this->rawass->dimensionid__idx_1   = 2;
+        $this->rawass->grade__idx_1         = 4;
+        $this->rawass->peercomment__idx_1   = 'Hmm';
+        $this->rawass->dimensionid__idx_2   = 1;
+        $this->rawass->grade__idx_2         = 1;
+        $this->rawass->peercomment__idx_2   = 'Uch';
+        $this->rawass->dimensionid__idx_3   = 4;
+        $this->rawass->grade__idx_3         = 0;
+        $this->rawass->peercomment__idx_3   = 'Grrr';
+        $this->rawass->dimensionid__idx_4   = 5;
+        $this->rawass->grade__idx_4         = 7;
+        $this->rawass->peercomment__idx_4   = 'Bye';
     }
 
     public function tearDown() {
+        $this->workshop = null;
         $this->strategy = null;
         $this->rawform  = null;
         $this->rawdb    = null;
     }
 
     public function test_cook_dimension_records() {
-
+        // excersise SUT
         $cooked = $this->strategy->_cook_dimension_records($this->rawdb);
+        // verify
         $this->assertIsA($cooked, 'stdClass');
-        $cooked = (array)$cooked;
-
-        $this->assertEqual($cooked['dimensionid[0]'], 3);
-        $this->assertEqual($cooked['description[0]'], 'First');
-        $this->assertEqual($cooked['descriptionformat[0]'], 1);
-        $this->assertEqual($cooked['grade[0]'], 20);
-        $this->assertEqual($cooked['weight[0]'], 16);
-
-        $this->assertEqual($cooked['dimensionid[1]'], 7);
-        $this->assertEqual($cooked['description[1]'], 'Second');
-        $this->assertEqual($cooked['descriptionformat[1]'], 1);
-        $this->assertEqual($cooked['grade[1]'], 10);
-        $this->assertEqual($cooked['weight[1]'], 1);
+
+        $this->assertEqual($cooked->dimensionid__idx_0, 3);
+        $this->assertEqual($cooked->description__idx_0, 'First');
+        $this->assertEqual($cooked->descriptionformat__idx_0, 1);
+        $this->assertEqual($cooked->grade__idx_0, 20);
+        $this->assertEqual($cooked->weight__idx_0, 16);
+
+        $this->assertEqual($cooked->dimensionid__idx_1, 7);
+        $this->assertEqual($cooked->description__idx_1, 'Second');
+        $this->assertEqual($cooked->descriptionformat__idx_1, 1);
+        $this->assertEqual($cooked->grade__idx_1, 10);
+        $this->assertEqual($cooked->weight__idx_1, 1);
     }
 
-    public function test_cook_form_data() {
+    public function test_cook_edit_form_data() {
 
-        $cooked = $this->strategy->_cook_form_data($this->rawform);
+        $cooked = $this->strategy->_cook_edit_form_data($this->rawform);
         $this->assertIsA($cooked, 'Array');
+        $this->assertEqual(count($cooked), 5);
         $this->assertEqual($cooked[2], (object)array(
                             'id'                => 1,
                             'workshopid'        => 42,
@@ -158,4 +192,40 @@ class workshop_accumulative_strategy_test extends UnitTestCase {
                             ));
     }
 
+    public function test__cook_assessment_form_data() {
+        // fixture set-up
+        $assessment = new stdClass();
+        $assessment->id = 90;
+
+        // exercise SUT
+        $cooked = $this->strategy->_cook_assessment_form_data($assessment, $this->rawass);
+
+        // verify
+        $this->assertIsA($cooked, 'Array');
+        $this->assertEqual(count($cooked), 5);
+        $this->assertEqual($cooked[0], (object)array(
+                            'assessmentid'  => 90,
+                            'strategy'      => 'accumulative',
+                            'dimensionid'   => 3,
+                            'grade'         => 10,
+                            'peercomment'   => 'Great',
+                            'peercommentformat' => FORMAT_HTML,
+                        ));
+        $this->assertEqual($cooked[2], (object)array(
+                            'assessmentid'  => 90,
+                            'strategy'      => 'accumulative',
+                            'dimensionid'   => 1,
+                            'grade'         => 1,
+                            'peercomment'   => 'Uch',
+                            'peercommentformat' => FORMAT_HTML,
+                        ));
+        $this->assertEqual($cooked[3], (object)array(
+                            'assessmentid'  => 90,
+                            'strategy'      => 'accumulative',
+                            'dimensionid'   => 4,
+                            'grade'         => 0,
+                            'peercomment'   => 'Grrr',
+                            'peercommentformat' => FORMAT_HTML,
+                        ));
+    }
 }
index 2aa4fbf2748eb108fb57c693c9143f07e36d96d4..b14d550e22f81b6728d03a4161a3ddf62c0d5a78 100644 (file)
 
 defined('MOODLE_INTERNAL') || die();
 
-require_once(dirname(dirname(__FILE__)) . '/strategy.php'); // parent class
+require_once(dirname(dirname(__FILE__)) . '/lib.php');  // interface definition
 
 /**
  * Accumulative grading strategy logic.
  */
-class workshop_accumulative_strategy extends workshop_base_strategy {
+class workshop_accumulative_strategy implements workshop_strategy {
 
-    public function load_form() {
+    /** @var workshop the parent workshop instance */
+    protected $workshop;
+
+    /** @var int number of dimensions defined in database, must be set in {@link load_fields()} */
+    protected $nodimensions=null;
+
+    /** @var array options for dimension description fields */
+    protected $descriptionopts;
+
+    /**
+     * Constructor
+     *
+     * @param object $workshop The workshop instance record
+     * @return void
+     */
+    public function __construct($workshop) {
+        $this->workshop         = $workshop;
+        $this->descriptionopts  = array('trusttext' => true, 'subdirs' => true, 'maxfiles' => -1);
+    }
+
+    /**
+     * @return string
+     */
+    public function name() {
+        return 'accumulative';
+    }
+
+    /**
+     * Factory method returning an instance of an assessment form editor class
+     *
+     * @param $actionurl URL of form handler, defaults to auto detect the current url
+     */
+    public function get_edit_strategy_form($actionurl=null) {
+        global $CFG;    // needed because the included files use it
+        global $PAGE;
+
+        require_once(dirname(__FILE__) . '/edit_form.php');
+
+        $fields = $this->load_fields();
+        if (is_null($this->nodimensions)) {
+            throw new coding_exception('You forgot to set the number of dimensions in load_fields()');
+        }
+        $norepeatsdefault   = max($this->nodimensions + WORKSHOP_STRATEGY_ADDDIMS, WORKSHOP_STRATEGY_MINDIMS);
+        $norepeats          = optional_param('norepeats', $norepeatsdefault, PARAM_INT);    // number of dimensions
+        $noadddims          = optional_param('noadddims', '', PARAM_ALPHA);                 // shall we add more?
+        if ($noadddims) {
+            $norepeats += WORKSHOP_STRATEGY_ADDDIMS;
+        }
+
+        for ($i = 0; $i < $norepeats; $i++) {
+            // prepare all editor elements
+            $fields = file_prepare_standard_editor($fields, 'description__idx_'.$i, $this->descriptionopts,
+                                                   $PAGE->context, 'workshop_dimension_description', 0);
+        }
+        $customdata = array();
+        $customdata['workshop'] = $this->workshop;
+        $customdata['strategy'] = $this;
+        $customdata['norepeats'] = $norepeats;
+        $customdata['descriptionopts'] = $this->descriptionopts;
+        $customdata['current']  = $fields;
+        $attributes = array('class' => 'editstrategyform');
+
+        return new workshop_edit_accumulative_strategy_form($actionurl, $customdata, 'post', '', $attributes);
+    }
+
+    /**
+     * Returns the fields of the assessment form and sets {@var nodimensions}
+     */
+    protected function load_fields() {
         global $DB;
 
-        $dims = $DB->get_records('workshop_forms_' . $this->name, array('workshopid' => $this->workshop->id), 'sort');
+        $dims = $DB->get_records('workshop_forms_' . $this->name(), array('workshopid' => $this->workshop->id), 'sort');
         $this->nodimensions = count($dims);
-        return $this->_cook_dimension_records($dims);
+        $fields = $this->_cook_dimension_records($dims);
+        return $fields;
     }
 
     /**
-     * Transpones the dimension data from DB so the assessment form editor can be populated by set_data
+     * Maps the data from DB to their form fields
      *
      * Called internally from load_form(). Could be private but keeping protected
      * for unit testing purposes.
@@ -54,14 +123,15 @@ class workshop_accumulative_strategy extends workshop_base_strategy {
         $formdata = array();
         $key = 0;
         foreach ($raw as $dimension) {
-            $formdata['dimensionid[' . $key . ']']       = $dimension->id;
-            $formdata['description[' . $key . ']']       = $dimension->description;
-            $formdata['descriptionformat[' . $key . ']'] = $dimension->descriptionformat;
-            $formdata['grade[' . $key . ']']             = $dimension->grade;
-            $formdata['weight[' . $key . ']']            = $dimension->weight;
+            $formdata['dimensionid__idx_' . $key]       = $dimension->id;
+            $formdata['description__idx_' . $key]       = $dimension->description;
+            $formdata['descriptionformat__idx_' . $key] = $dimension->descriptionformat;
+            $formdata['grade__idx_' . $key]             = $dimension->grade;
+            $formdata['weight__idx_' . $key]            = $dimension->weight;
             $key++;
         }
-        return (object)$formdata;
+        $cooked = (object)$formdata;
+        return $cooked;
     }
 
     /**
@@ -74,18 +144,17 @@ class workshop_accumulative_strategy extends workshop_base_strategy {
      *
      * @uses $DB
      * @param object $data Raw data returned by the dimension editor form
-     * @access public
      * @return void
      */
-    public function save_form(stdClass $data) {
+    public function save_edit_strategy_form(stdClass $data) {
         global $DB;
 
-        if (!isset($data->strategyname) || ($data->strategyname != $this->name)) {
+        if (!isset($data->strategyname) || ($data->strategyname != $this->name())) {
             // the workshop strategy has changed since the form was opened for editing
             throw new moodle_exception('strategyhaschanged', 'workshop');
         }
 
-        $data = $this->_cook_form_data($data);
+        $data = $this->_cook_edit_form_data($data);
         $todelete = array();
         foreach ($data as $record) {
             if (empty($record->description)) {
@@ -97,41 +166,135 @@ class workshop_accumulative_strategy extends workshop_base_strategy {
             }
             if (empty($record->id)) {
                 // new field
-                $record->id = $DB->insert_record('workshop_forms_' . $this->name, $record);
+                $record->id = $DB->insert_record('workshop_forms_' . $this->name(), $record);
             } else {
                 // exiting field
-                $DB->update_record('workshop_forms_' . $this->name, $record);
+                $DB->update_record('workshop_forms_' . $this->name(), $record);
             }
         }
-        $DB->delete_records_list('workshop_forms_' . $this->name, 'id', $todelete);
+        $DB->delete_records_list('workshop_forms_' . $this->name(), 'id', $todelete);
     }
 
     /**
-     * Prepares data returned by mform so they can be saved into database
+     * Prepares data returned by {@link workshop_edit_accumulative_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.
-     * Called internally from save_form() only. Could be private but
+     * Called internally from {@link save_edit_strategy_form()} only. Could be private but
      * keeping protected for unit testing purposes.
      *
      * @param object $raw Raw data returned by mform
      * @return array Array of objects to be inserted/updated in DB
      */
-    protected function _cook_form_data(stdClass $raw) {
+    protected function _cook_edit_form_data(stdClass $raw) {
+        global $PAGE;
 
         $cook = array();
-
-        for ($k = 0; $k < $raw->numofdimensions; $k++) {
-            $cook[$k]                    = new stdClass();
-            $cook[$k]->id                = isset($raw->dimensionid[$k]) ? $raw->dimensionid[$k] : null;
-            $cook[$k]->workshopid        = $this->workshop->id;
-            $cook[$k]->sort              = $k + 1;
-            $cook[$k]->description       = isset($raw->description[$k]) ? $raw->description[$k] : null;
-            $cook[$k]->descriptionformat = FORMAT_HTML;
-            $cook[$k]->grade             = isset($raw->grade[$k]) ? $raw->grade[$k] : null;
-            $cook[$k]->weight            = isset($raw->weight[$k]) ? $raw->weight[$k] : null;
+        for ($i = 0; $i < $raw->norepeats; $i++) {
+            $raw = file_postupdate_standard_editor($raw, 'description__idx_'.$i, $this->descriptionopts,
+                                                    $PAGE->context, 'workshop_dimension_description', 0);
+            $cook[$i]                    = new stdClass();
+            $fieldname                   = 'dimensionid__idx_'.$i;
+            $cook[$i]->id                = isset($raw->$fieldname) ? $raw->$fieldname : null;
+            $cook[$i]->workshopid        = $this->workshop->id;
+            $cook[$i]->sort              = $i + 1;
+            $fieldname                   = 'description__idx_'.$i;
+            $cook[$i]->description       = isset($raw->$fieldname) ? $raw->$fieldname : null;
+            $fieldname                   = 'description__idx_'.$i.'format';
+            $cook[$i]->descriptionformat = isset($raw->$fieldname) ? $raw->$fieldname : FORMAT_HTML;
+            $fieldname                   = 'grade__idx_'.$i;
+            $cook[$i]->grade             = isset($raw->$fieldname) ? $raw->$fieldname : null;
+            $fieldname                   = 'weight__idx_'.$i;
+            $cook[$i]->weight            = isset($raw->$fieldname) ? $raw->$fieldname : null;
         }
         return $cook;
     }
 
+    /**
+     * Factory method returning an instance of an assessment form
+     *
+     * @param moodle_url $actionurl URL of form handler, defaults to auto detect the current url
+     * @param string $mode          Mode to open the form in: preview/assessment
+     */
+    public function get_assessment_form(moodle_url $actionurl=null, $mode='preview') {
+        global $CFG;    // needed because the included files use it
+        require_once(dirname(__FILE__) . '/assessment_form.php');
+
+        $fields = $this->load_fields();
+        if (is_null($this->nodimensions)) {
+            throw new coding_exception('You forgot to set the number of dimensions in load_fields()');
+        }
+
+        // set up the required custom data common for all strategies
+        $customdata['strategy'] = $this;
+        $customdata['mode']     = $mode;
+
+        // set up strategy-specific custom data
+        $customdata['nodims']   = $this->nodimensions;
+        $customdata['fields']   = $fields;
+        $attributes = array('class' => 'assessmentform accumulative');
+
+        return new workshop_accumulative_assessment_form($actionurl, $customdata, 'post', '', $attributes);
+    }
+
+    /**
+     * Saves the filled assessment
+     *
+     * This method processes data submitted using the form returned by {@link get_assessment_form()}
+     *
+     * @param object $assessment Assessment being filled
+     * @param object $data       Raw data as returned by the assessment form
+     * @return void
+     */
+    public function save_assessment(stdClass $assessment, stdClass $data) {
+        global $DB;
+
+        if (!isset($data->strategyname) || ($data->strategyname != $this->name())) {
+            // the workshop strategy has changed since the form was opened for editing
+            throw new moodle_exception('strategyhaschanged', 'workshop');
+        }
+        if (!isset($data->nodims)) {
+            throw coding_expection('You did not send me the number of assessment dimensions to process');
+        }
+
+        foreach ($this->_cook_assessment_form_data($assessment, $data) as $cooked) {
+            $cooked->id = $DB->get_field('workshop_grades', 'id', array('assessmentid' => $cooked->assessmentid,
+                                                                        'strategy' => 'accumulative',
+                                                                        'dimensionid' => $cooked->dimensionid));
+            if (false === $cooked->id) {
+                // not found - new grade
+                $cooked->id = $DB->insert_record('workshop_grades', $cooked);
+            } else {
+                 // update existing grade
+                $DB->update_record('workshop_grades', $cooked);
+            }
+        }
+        // todo recalculate grades
+    }
+
+    /**
+     * Prepares data returned by {@link workshop_accumulative_assessment_form} so they can be saved into database
+     *
+     * Called internally from {@link save_assessment()} only. Could be private but
+     * keeping protected for unit testing purposes.
+     *
+     * @param object $raw Raw data returned by mform
+     * @return array Array of objects to be inserted/updated in DB
+     */
+    protected function _cook_assessment_form_data(stdClass $assessment, stdClass $raw) {
+        $raw = (array)$raw;
+        $cooked = array();
+        for ($i = 0; $i < $raw['nodims']; $i++) {
+            $grade = new stdClass();
+            $grade->assessmentid = $assessment->id;
+            $grade->strategy = $raw['strategyname'];
+            $grade->dimensionid = $raw['dimensionid__idx_' . $i];
+            $grade->grade = $raw['grade__idx_' . $i];
+            $grade->peercomment = $raw['peercomment__idx_' . $i];
+            $grade->peercommentformat = FORMAT_HTML;
+            $cooked[$i] = $grade;
+        }
+        return $cooked;
+    }
+
 }
index 0599923fb5d4ec6a2f9547bb62c7a9bc6118b78c..10569256e2f6d26d5ff87ec30d4d40f0e023fa9e 100644 (file)
@@ -38,15 +38,6 @@ require_once($CFG->libdir . '/formslib.php'); // parent class definition
  */
 class workshop_assessment_form extends moodleform {
 
-    /** object Strategy logic instance */
-    protected $strategy;
-
-    /** array Assessment form fields defined by teacher */
-    protected $fields = array();
-
-    /** string The mode of the form: "preview" or "assessment" */
-    protected $mode = 'preview';
-
     /**
      * Add the fields that are common for all grading strategies.
      *
@@ -55,19 +46,18 @@ class workshop_assessment_form extends moodleform {
      * $mform->removeElement().
      * Strategy subclassess should define their own fields in definition_inner()
      *
-     * @access public
      * @return void
      */
     public function definition() {
         global $CFG;
 
-        $mform = $this->_form;
-        $this->strategy = $this->_customdata['strategy'];
-        $this->fields   = (array)$this->_customdata['fields'];
-        $this->mode     = $this->_customdata['mode'];
+        $mform          = $this->_form;
+        $this->mode     = $this->_customdata['mode'];       // influences the save buttons
+        $this->strategy = $this->_customdata['strategy'];   // strategy name sends back for cross check
 
-        $mform->addElement('hidden', 'strategyname', $this->strategy->name);
+        $mform->addElement('hidden', 'strategyname', $this->strategy->name());
 
+        // add the strategy-specific fields
         $this->definition_inner($mform);
 
         $buttonarray = array();
index 57f6fae6f6785e1a17c1654648102af769d6c1b6..2fe1dcab6fc0f191f8083326409dc94e49ee3cd7 100644 (file)
@@ -49,16 +49,17 @@ class workshop_edit_strategy_form extends moodleform {
      * $mform->removeElement().
      * Stretegy subclassess should define their own fields in definition_inner()
      *
-     * @access public
      * @return void
      */
     public function definition() {
         global $CFG;
 
         $mform = $this->_form;
+        $this->workshop = $this->_customdata['workshop'];
         $this->strategy = $this->_customdata['strategy'];
 
-        $mform->addElement('hidden', 'strategyname', $this->strategy->name);
+        $mform->addElement('hidden', 'workshopid', $this->workshop->id);
+        $mform->addElement('hidden', 'strategyname', $this->strategy->name());
 
         $this->definition_inner($mform);
 
diff --git a/mod/workshop/grading/lib.php b/mod/workshop/grading/lib.php
new file mode 100644 (file)
index 0000000..b76cf02
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file defines interface of all grading strategy logic classes
+ *
+ * @package   mod-workshop
+ * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+define('WORKSHOP_STRATEGY_MINDIMS', 3);    // default number of dimensions to show
+define('WORKSHOP_STRATEGY_ADDDIMS', 2);    // number of dimensions to add
+
+/**
+ * Strategy interface defines all methods that strategy subplugins has to implement
+ */
+interface workshop_strategy {
+
+    /**
+     * Returns name of the strategy
+     *
+     * The name may be used to generate table names, class names, paths etc.
+     *
+     * @return string
+     */
+    public function name();
+
+    /**
+     * Factory method returning a form that is used to define the assessment form
+     *
+     * @param string $actionurl URL of the action handler script, defaults to auto detect
+     * @return object The instance of the assessment form editor class
+     */
+    public function get_edit_strategy_form($actionurl=null);
+
+    /**
+     * Saves the assessment dimensions and other grading form elements
+     *
+     * 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.
+     *
+     * @param object $data Raw data as returned by the form editor
+     * @return void
+     */
+    public function save_edit_strategy_form(stdClass $data);
+
+    /**
+     * Factory method returning an instance of an assessment form
+     *
+     * @param moodle_url $actionurl URL of form handler, defaults to auto detect the current url
+     * @param string $mode          Mode to open the form in: preview or assessment
+     */
+    public function get_assessment_form(moodle_url $actionurl=null, $mode='preview');
+
+    /**
+     * Saves the filled assessment
+     *
+     * This method processes data submitted using the form returned by {@link get_assessment_form()}
+     *
+     * @param object $assessment Assessment being filled
+     * @param object $data       Raw data as returned by the assessment form
+     * @return void
+     */
+    public function save_assessment(stdClass $assessment, stdClass $data);
+}
index b3634ba598794c941a4cb871e481a170f5a7aa92..42e58caadf1720aea0b8670fe08e26cefecd1729 100644 (file)
@@ -40,7 +40,6 @@ class workshop_edit_noerrors_strategy_form extends workshop_edit_strategy_form {
      *
      * Called by the parent::definition()
      *
-     * @access protected
      * @return void
      */
     protected function definition_inner(&$mform) {
index 149e2a2b5edf79312c404857770302ecd468151a..292ed4b027bc8637b74de7d1ef3e8304ae14a33f 100644 (file)
@@ -35,7 +35,7 @@ class workshop_noerrors_strategy extends workshop_base_strategy {
     public function load_form() {
         global $DB;
 
-        $dims = $DB->get_records('workshop_forms_' . $this->name, array('workshopid' => $this->workshop->id), 'sort');
+        $dims = $DB->get_records('workshop_forms_' . $this->name(), array('workshopid' => $this->workshop->id), 'sort');
         $maps = $DB->get_records('workshop_forms_noerrors_map', array('workshopid' => $this->workshop->id), 'nonegative');
         $this->nodimensions = count($dims);
         return $this->_cook_database_records($dims, $maps);
@@ -88,7 +88,7 @@ class workshop_noerrors_strategy extends workshop_base_strategy {
     public function save_form(stdClass $data) {
         global $DB;
 
-        if (!isset($data->strategyname) || ($data->strategyname != $this->name)) {
+        if (!isset($data->strategyname) || ($data->strategyname != $this->name())) {
             // the workshop strategy has changed since the form was opened for editing
             throw new moodle_exception('strategyhaschanged', 'workshop');
         }
@@ -106,14 +106,14 @@ class workshop_noerrors_strategy extends workshop_base_strategy {
             }
             if (empty($record->id)) {
                 // new field
-                $record->id = $DB->insert_record('workshop_forms_' . $this->name, $record);
+                $record->id = $DB->insert_record('workshop_forms_' . $this->name(), $record);
             } else {
                 // exiting field
-                $DB->update_record('workshop_forms_' . $this->name, $record);
+                $DB->update_record('workshop_forms_' . $this->name(), $record);
             }
         }
         // delete dimensions if the teacher removed the description
-        $DB->delete_records_list('workshop_forms_' . $this->name, 'id', $todelete);
+        $DB->delete_records_list('workshop_forms_' . $this->name(), 'id', $todelete);
 
         // re-save the mappings
         $current  = array();
diff --git a/mod/workshop/grading/strategy.php b/mod/workshop/grading/strategy.php
deleted file mode 100644 (file)
index 290363d..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-<?php
-
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * This file defines a base class for all grading strategy logic
- *
- * @package   mod-workshop
- * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Strategy interface defines all methods that strategy subplugins has to implemens
- */
-interface workshop_strategy {
-
-    /**
-     * Factory method returning an instance of an assessment form editor class
-     *
-     * The returned class will probably expand the base workshop_edit_strategy_form. The number of
-     * dimensions that will be passed by set_data() must be already known here becase the
-     * definition() of the form has to know the number and it is called before set_data().
-     *
-     * @param string $actionurl URL of the action handler script, defaults to auto detect
-     * @access public
-     * @return object The instance of the assessment form editor class
-     */
-    public function get_edit_strategy_form($actionurl=null);
-
-    /**
-     * Load the assessment dimensions and other grading form elements
-     *
-     * 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.
-     * The returned object is passed to the mform set_data() method.
-     *
-     * @access public
-     * @return object Object representing the form fields values
-     */
-    public function load_form();
-
-    /**
-     * Save the assessment dimensions and other grading form elements
-     *
-     * 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.
-     *
-     * @access public
-     * @param object $data Raw data as returned by the form editor
-     * @return void
-     */
-    public function save_form(stdClass $data);
-
-    /**
-     * Return the number of assessment dimensions defined in the instance of the strategy
-     *
-     * @return int Zero or positive integer
-     */
-    public function get_number_of_dimensions();
-
-}
-
-/**
- * Base class for grading strategy logic
- *
- * This base class implements the default behaviour that should be suitable for the most
- * of simple grading strategies.
- */
-abstract class workshop_base_strategy implements workshop_strategy {
-
-    /** the name of the strategy */
-    public $name;
-
-    /** the parent workshop instance */
-    protected $workshop;
-
-    /** number of dimensions defined in database */
-    protected $nodimensions;
-
-    /**
-     * Constructor
-     *
-     * @param object $workshop The workshop instance record
-     * @access public
-     * @return void
-     */
-    public function __construct($workshop) {
-
-        $this->name         = $workshop->strategy;
-        $this->workshop     = $workshop;
-        $this->nodimensions = null;
-    }
-
-    /**
-     * Factory method returning an instance of an assessment form editor class
-     *
-     * By default, the class is defined in grading/{strategy}/edit_form.php and is named
-     * workshop_edit_{strategy}_strategy_form
-     *
-     * @param $actionurl URL of form handler, defaults to auto detect the current url
-     */
-    public function get_edit_strategy_form($actionurl=null) {
-        global $CFG;    // needed because the included files use it
-
-        $strategyform = dirname(__FILE__) . '/' . $this->name . '/edit_form.php';
-        if (file_exists($strategyform)) {
-            require_once($strategyform);
-        } else {
-            throw new moodle_exception('errloadingstrategyform', 'workshop');
-        }
-        $classname = 'workshop_edit_' . $this->name . '_strategy_form';
-
-        $customdata = new stdClass;
-        $customdata = array(
-                        'strategy'      => $this,
-                        );
-        $attributes = array('class' => 'editstrategyform');
-
-        return new $classname($actionurl, $customdata, 'post', '', $attributes);
-
-    }
-
-    /**
-     * By default, the number of loaded dimensions is set by load_form()
-     *
-     * @access public
-     * @return Array of records
-     */
-    public function get_number_of_dimensions() {
-        return $this->nodimensions;
-    }
-
-    /**
-     * Factory method returning an instance of an assessment form
-     *
-     * By default, the class is defined in grading/{strategy}/assessment_form.php and is named
-     * workshop_{strategy}_assessment_form
-     *
-     * @param moodle_url $actionurl URL of form handler, defaults to auto detect the current url
-     * @param string $mode Mode to open the form in: preview/assessment
-     */
-    public function get_assessment_form(moodle_url $actionurl=null, $mode='preview') {
-        global $CFG;    // needed because the included files use it
-
-        $assessmentform = dirname(__FILE__) . '/' . $this->name . '/assessment_form.php';
-        if (is_readable($assessmentform)) {
-            require_once($assessmentform);
-        } else {
-            throw new moodle_exception('errloadingassessmentform', 'workshop');
-        }
-        $classname = 'workshop_' . $this->name . '_assessment_form';
-
-        $customdata = new stdClass;
-        $customdata = array(
-                        'strategy'  => $this,
-                        'fields'    => $this->load_form(),
-                        'mode'      => $mode,
-                        );
-        $attributes = array('class' => 'assessmentform');
-
-        return new $classname($actionurl, $customdata, 'post', '', $attributes);
-
-    }
-
-}
index 194ba51691c593c2e793a600d0163fccb62f8a3b..d3be7e0568acef7c16c4899f96246c44b6409b21 100644 (file)
 
 defined('MOODLE_INTERNAL') || die();
 
-$string['userdatecreated'] = 'submitted on <span>$a</span>';
-$string['userdatemodified'] = 'modified on <span>$a</span>';
-$string['byfullname'] = 'by <a href=\"{$a->url}\">{$a->name}</a>';
-$string[''] = '';
+$string['strategyhaschanged'] = 'The workshop grading strategy has changed since the form was opened for editing.';
 $string[''] = '';
 $string[''] = '';
 $string[''] = '';
@@ -59,6 +56,7 @@ $string['allocationrandom'] = 'Random allocation';
 $string['allocationsettings'] = 'Allocation settings';
 $string['allocation'] = 'Submission allocation';
 $string['allocationview'] = 'View current allocations';
+$string['areadimensiondescription'] = 'Assessment dimensions';
 $string['areasubmissionattachment'] = 'Submission attachments';
 $string['areasubmissioncontent'] = 'Submission texts';
 $string['areyousuretodeallocate'] = 'Are you sure you want deallocate the selected assessment?';
@@ -74,6 +72,7 @@ $string['assessmentsettings'] = 'Assessment settings';
 $string['assessmentstart'] = 'Start of assessment phase';
 $string['assesswosubmission'] = 'Users can assess without their own submission';
 $string['backtoeditform'] = 'Back to editing form';
+$string['byfullname'] = 'by <a href=\"{$a->url}\">{$a->name}</a>';
 $string['comparisonhigh'] = 'High';
 $string['comparisonlow'] = 'Low';
 $string['comparisonnormal'] = 'Normal';
@@ -164,6 +163,8 @@ $string['useexamplesdesc'] = 'Users practise evaluating on example submissions';
 $string['useexamples'] = 'Use examples';
 $string['usepeerassessmentdesc'] = 'Users perform peer assessment of others\' work';
 $string['usepeerassessment'] = 'Use peer assessment';
+$string['userdatecreated'] = 'submitted on <span>$a</span>';
+$string['userdatemodified'] = 'modified on <span>$a</span>';
 $string['useselfassessmentdesc'] = 'Users perform self assessment of their own work';
 $string['useselfassessment'] = 'Use self assessment';
 $string['withoutsubmission'] = 'Warning - reviewer without own submission';
index 0dc0c277d3e0eea2ae0fbed52fc1dc352ed0f3a7..67654b704c406239b12891281e71bd40193fd1f7 100644 (file)
@@ -48,79 +48,24 @@ define('WORKSHOP_COMPARISON_HIGH',      3);     /* f = 3.00 */
 define('WORKSHOP_COMPARISON_VERYHIGH',  4);     /* f = 5.00 */
 
 /**
- * The base class of workshop instances
+ * Saves a new instance of the workshop into the database
  *
- * It defines methods that are part of any activity module API and may be called by Moodle core.
- * The class just wraps the database record from the {workshop} table and adds some
- * methods that implement the compulsory activity module API.
- * For full-featured workshop class see {@link workshop_api}.
- */
-class workshop {
-
-    /** @var object course module record */
-    public $cm;
-
-    /** @var object course record */
-    public $courserecord;
-
-    /**
-     *
-     * Initializes the object using the data from DB. Makes deep copy of all $dbrecord properties.
-     * Please do not confuse $this->course (integer property from the database record) and
-     * $this->courserecord (object containing the whole course record).
-     *
-     * @param object $instance     The instance data row from {workshop} table
-     * @param object $cm           Course module record
-     * @param object $courserecord Course record
-     */
-    public function __construct(stdClass $instance, stdClass $cm, stdClass $courserecord) {
-        foreach ($instance as $key => $val) {
-            if (is_object($val) || (is_array($val))) {
-                // this should not happen if the $dbrecord is really just the record returned by $DB
-                $this->{$key} = unserialize(serialize($val));
-            } else {
-                $this->{$key} = $val;
-            }
-        }
-        $this->cm = $cm;
-        $this->courserecord = $courserecord;
-    }
-
-    /**
-     * Saves a new instance of the workshop into the database
-     *
-     * Given an object containing all the necessary data,
-     * (defined by the form in mod_form.php) this function
-     * will save a new instance and return the id number
-     * of the new instance.
-     *
-     * @param object $data An object from the form in mod_form.php
-     * @return int The id of the newly inserted workshop record
-     */
-    public static function add_instance($data) {
-        global $DB;
-
-        $data->timecreated = time();
-        $data->timemodified = $data->timecreated;
-
-        return $DB->insert_record('workshop', $data);
-    }
-}
-
-/**
  * Given an object containing all the necessary data,
  * (defined by the form in mod_form.php) this function
- * will create a new instance and return the id number
+ * will save a new instance and return the id number
  * of the new instance.
  *
  * @param object $data An object from the form in mod_form.php
  * @return int The id of the newly inserted workshop record
  */
 function workshop_add_instance($data) {
-    return workshop::add_instance($data);
-}
+    global $DB;
 
-// TODO convert following functions into workshop methods
+    $data->timecreated = time();
+    $data->timemodified = $data->timecreated;
+
+    return $DB->insert_record('workshop', $data);
+}
 
 /**
  * Given an object containing all the necessary data,
@@ -320,6 +265,27 @@ function workshop_get_extra_capabilities() {
 // File API                                                                   //
 ////////////////////////////////////////////////////////////////////////////////
 
+/**
+ * Returns the lists of all browsable file areas within the given module context
+ *
+ * The file area workshop_intro for the activity introduction field is added automatically
+ * by {@link file_browser::get_file_info_module()}
+ *
+ * @param object $course
+ * @param object $cm
+ * @param object $context
+ * @return array of [(string)filearea] => (string)description
+ */
+function workshop_get_file_areas($course, $cm, $context) {
+    $areas = array();
+    if (has_capability('moodle/course:managefiles', $context)) {
+        $areas['workshop_dimension_description']    = get_string('areadimensiondescription', 'workshop');
+        $areas['workshop_submission_content']       = get_string('areasubmissioncontent', 'workshop');
+        $areas['workshop_submission_attachment']    = get_string('areasubmissionattachment', 'workshop');
+    }
+    return $areas;
+}
+
 /**
  * Serves the files from the workshop file areas
  *
@@ -344,7 +310,7 @@ function workshop_pluginfile($course, $cminfo, $context, $filearea, $args, $forc
         return false;
     }
 
-    $fileareas = array('workshop_submission_content', 'workshop_submission_attachment');
+    $fileareas = array('workshop_submission_content', 'workshop_submission_attachment', 'workshop_dimension_description');
     if (!in_array($filearea, $fileareas)) {
         return false;
     }
@@ -371,31 +337,17 @@ function workshop_pluginfile($course, $cminfo, $context, $filearea, $args, $forc
     if ((!$file = $fs->get_file_by_hash(sha1($fullpath))) || ($file->is_directory())) {
         return false;
     }
-    // TODO MDL-19941 make sure the user is allowed to see the submission
+    // TODO make sure the user is allowed to see the file
 
     // finally send the file
-    send_stored_file($file, 0, 0, true); // download MUST be forced - security!
-}
+    if ('workshop_dimension_description' == $filearea) {
+        // media embedded by teacher into the dimension description
+        send_stored_file($file);
 
-/**
- * Returns the lists of all browsable file areas within the given module context
- *
- * The file area workshop_intro for the activity introduction field is added automatically
- * by {@link file_browser::get_file_info_module()}
- *
- * @param object $course
- * @param object $cm
- * @param object $context
- * @return array of [(string)filearea] => (string)description
- */
-function workshop_get_file_areas($course, $cm, $context) {
-    $areas = array();
-    // todo re-think capability checking
-    if (has_capability('mod/workshop:submit', $context) || has_capability('mod/workshop:submitexamples', $context)) {
-        $areas['workshop_submission_content']       = get_string('areasubmissioncontent', 'workshop');
-        $areas['workshop_submission_attachment']    = get_string('areasubmissionattachment', 'workshop');
+    } else {
+        // files uploaded by students in their attachments - forcing download for security reasons
+        send_stored_file($file, 0, 0, true);
     }
-    return $areas;
 }
 
 /**
@@ -416,33 +368,66 @@ function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filea
     global $CFG, $DB;
     static $authors=null;    // cache for submission authors
 
-    if (!($filearea == 'workshop_submission_content' || $filearea == 'workshop_submission_attachment')) {
+    if (!has_capability('moodle/course:managefiles', $context)) {
         return null;
     }
-    if (is_null($itemid)) {
-        require_once($CFG->dirroot . '/mod/workshop/fileinfolib.php');
-        return new workshop_file_info($browser, $course, $cm, $context, $areas, $filearea);
-    }
 
     $fs = get_file_storage();
-    $filepath = is_null($filepath) ? '/' : $filepath;
-    $filename = is_null($filename) ? '.' : $filename;
-    if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
-        return null;
+
+    if ($filearea === 'workshop_submission_content' or $filearea === 'workshop_submission_attachment') {
+
+        if (is_null($itemid)) {
+            require_once($CFG->dirroot . '/mod/workshop/fileinfolib.php');
+            return new workshop_file_info_submissions_container($browser, $course, $cm, $context, $areas, $filearea);
+        }
+
+        // we are inside the submission container
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+
+        if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($context->id, $filearea, $itemid);
+            } else {
+                // not found
+                return null;
+            }
+        }
+
+        // let us display the author's name instead of itemid (submission id)
+
+        if (is_null($authors)) {
+            $sql = 'SELECT s.id, u.lastname, u.firstname
+                    FROM {workshop_submissions} s
+                    JOIN {user} u ON (s.userid = u.id)
+                    WHERE s.workshopid = ?';
+            $params[0] = $cm->instance;
+            $authors = $DB->get_records_sql($sql, $params);
+        }
+        $urlbase        = $CFG->wwwroot . '/pluginfile.php';
+        $topvisiblename = fullname($authors[$itemid]);
+        // do not allow manual modification of any files!
+        return new file_info_stored($browser, $context, $storedfile, $urlbase, $topvisiblename, true, true, false, false);
     }
 
-    if (is_null($authors)) {
-        $sql = 'SELECT s.id, u.lastname, u.firstname
-                FROM {workshop_submissions} s
-                JOIN {user} u ON (s.userid = u.id)
-                WHERE s.workshopid = ?';
-        $params[0] = $cm->instance;
-        $authors = $DB->get_records_sql($sql, $params);
+    if ($filearea === 'workshop_dimension_description') {
+        // always only itemid 0
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($context->id, $filearea, 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+        return new file_info_stored($browser, $context, $storedfile, $urlbase, $areas[$filearea], false, true, true, false);
     }
-    $urlbase        = $CFG->wwwroot . '/pluginfile.php';
-    $topvisiblename = fullname($authors[$itemid]);
-    // do not allow manual modification of any files!
-    return new file_info_stored($browser, $context, $storedfile, $urlbase, $topvisiblename, true, true, false, false);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -458,7 +443,6 @@ function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filea
  * assessment are defined via a HTML select form element. By default it returns
  * an array 0, 1, 2, ..., 98, 99, 100.
  *
- * @access public
  * @return array Array of integers
  */
 function workshop_get_maxgrades() {
@@ -516,7 +500,6 @@ function workshop_get_dimension_weights() {
 /**
  * Return an array of the localized grading strategy names
  *
- * @access public
  * $return array Array ['string' => 'string']
  */
 function workshop_get_strategies() {
index ca44945987d7395f7d227d9a838b05b51ee2fb59..e40ba9519d5b2731ed9eb597a594419ce2614e20 100644 (file)
@@ -21,7 +21,7 @@
  * All the workshop specific functions, needed to implement the module
  * logic, should go to here. Instead of having bunch of function named
  * workshop_something() taking the workshop instance as the first
- * parameter, we use a class workshop_api that provides all methods.
+ * parameter, we use a class workshop that provides all methods.
  *
  * @package   mod-workshop
  * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
@@ -37,24 +37,42 @@ define('WORKSHOP_ALLOCATION_EXISTS',        -1);    // return status of {@link a
 /**
  * Full-featured workshop API
  *
- * This extends the module base API and adds the internal methods that are called
+ * This wraps the workshop database record with a set of methods that are called
  * from the module itself. The class should be initialized right after you get
- * $workshop and $cm records at the begining of the script.
+ * $workshop, $cm and $course records at the begining of the script.
  */
-class workshop_api extends workshop {
+class workshop {
+
+    /** @var object course module record */
+    public $cm = null;
+
+    /** @var object course record */
+    public $course = null;
 
     /** grading strategy instance */
-    protected $strategy_api=null;
+    private $_strategyinstance = null;
 
     /**
-     * Initialize the object using the data from DB
+     * Initializes the object using the data from DB
+     *
+     * Makes deep copy of all passed records properties. Replaces integer $course attribute
+     * with a full database record (course should not be stored in instances table anyway).
      *
-     * @param object $instance     The instance data row from {workshop} table
-     * @param object $cm           Course module record
-     * @param object $courserecord Course record
+     * @param object $instance Workshop instance data from {workshop} table
+     * @param object $cm       Course module record as returned by {@link get_coursemodule_from_id()}
+     * @param object $course   Course record from {course} table
      */
-    public function __construct($instance, $cm, $courserecord) {
-        parent::__construct($instance, $cm, $courserecord);
+    public function __construct(stdClass $instance, stdClass $cm, stdClass $course) {
+        foreach ($instance as $key => $val) {
+            if (is_object($val) || (is_array($val))) {
+                // this should not happen if the $instance is really just the record returned by $DB
+                $this->{$key} = unserialize(serialize($val));   // makes deep copy of referenced variables
+            } else {
+                $this->{$key} = $val;
+            }
+        }
+        $this->cm     = unserialize(serialize($cm));
+        $this->course = unserialize(serialize($course));
     }
 
     /**
@@ -78,6 +96,7 @@ class workshop_api extends workshop {
         }
 
         if ($musthavesubmission && is_null($userswithsubmission)) {
+            $userswithsubmission = array();
             $submissions = $DB->get_records_list('workshop_submissions', 'userid', array_keys($users),'', 'id,userid');
             foreach ($submissions as $submission) {
                 $userswithsubmission[$submission->userid] = null;
@@ -268,7 +287,7 @@ class workshop_api extends workshop {
             }
             return $submissions;
         } else {
-            throw new moodle_workshop_exception($this, 'wrongparameter');
+            throw new moodle_exception('wrongparameter');
         }
     }
 
@@ -322,7 +341,7 @@ class workshop_api extends workshop {
      * @param mixed $reviewerid 'all'|int|array User ID of the reviewer
      * @param mixed $id         'all'|int Assessment ID
      * @return array [assessmentid] => assessment object
-     * @see workshop_api::get_assessments_recordset() for the structure of returned objects
+     * @see workshop::get_assessments_recordset() for the structure of returned objects
      */
     public function get_assessments($reviewerid='all', $id='all') {
         $rs = $this->get_assessments_recordset($reviewerid, $id);
@@ -348,7 +367,7 @@ class workshop_api extends workshop {
      * Get the information about the given assessment
      *
      * @param int $id Assessment ID
-     * @see workshop_api::get_assessments_recordset() for the structure of data returned
+     * @see workshop::get_assessments_recordset() for the structure of data returned
      * @return mixed false if not found, object otherwise
      */
     public function get_assessment_by_id($id) {
@@ -366,7 +385,7 @@ class workshop_api extends workshop {
      * Get the information about all assessments assigned to the given reviewer
      *
      * @param int $id Reviewer ID
-     * @see workshop_api::get_assessments_recordset() for the structure of data returned
+     * @see workshop::get_assessments_recordset() for the structure of data returned
      * @return array array of objects
      */
     public function get_assessments_by_reviewer($id) {
@@ -479,20 +498,20 @@ class workshop_api extends workshop {
      * @return object Instance of a grading strategy
      */
     public function grading_strategy_instance() {
-        if (is_null($this->strategy_api)) {
+        if (is_null($this->_strategyinstance)) {
             $strategylib = dirname(__FILE__) . '/grading/' . $this->strategy . '/strategy.php';
             if (is_readable($strategylib)) {
                 require_once($strategylib);
             } else {
-                throw new moodle_workshop_exception($this, 'missingstrategy');
+                throw new moodle_exception('missingstrategy', 'workshop');
             }
             $classname = 'workshop_' . $this->strategy . '_strategy';
-            $this->strategy_api = new $classname($this);
-            if (!in_array('workshop_strategy', class_implements($this->strategy_api))) {
-                throw new moodle_workshop_exception($this, 'strategynotimplemented');
+            $this->_strategyinstance = new $classname($this);
+            if (!in_array('workshop_strategy', class_implements($this->_strategyinstance))) {
+                throw new moodle_exception('strategynotimplemented', 'workshop');
             }
         }
-        return $this->strategy_api;
+        return $this->_strategyinstance;
     }
 
     /**
@@ -526,7 +545,7 @@ class workshop_api extends workshop {
         if (is_readable($allocationlib)) {
             require_once($allocationlib);
         } else {
-            throw new moodle_workshop_exception($this, 'missingallocator');
+            throw new coding_exception('Unable to find allocator.php');
         }
         $classname = 'workshop_' . $method . '_allocator';
         return new $classname($this);
@@ -560,9 +579,9 @@ class workshop_api extends workshop {
      * @param int $assessmentid The ID of assessment record
      * @return object {@link moodle_url} the URL of the assessment page
      */
-    public function assess_url() {
+    public function assess_url($assessmentid) {
         global $CFG;
-        return new moodle_url($CFG->wwwroot . '/mod/workshop/assessment.php', array('asid' => $this->cm->id));
+        return new moodle_url($CFG->wwwroot . '/mod/workshop/assessment.php', array('asid' => $assessmentid));
     }
 
     /**
@@ -582,30 +601,3 @@ class workshop_api extends workshop {
     }
 
 }
-
-/**
- * Class for workshop exceptions. Just saves a couple of arguments of the
- * constructor for a moodle_exception.
- *
- * @param object $workshop Should be workshop or its subclass
- * @param string $errorcode
- * @param mixed $a Object/variable to pass to get_string
- * @param string $link URL to continue after the error notice
- * @param $debuginfo
- */
-class moodle_workshop_exception extends moodle_exception {
-
-    function __construct($workshop, $errorcode, $a = NULL, $link = '', $debuginfo = null) {
-        global $CFG;
-
-        if (!$link) {
-            $link = $CFG->wwwroot . '/mod/workshop/view.php?a=' . $workshop->id;
-        }
-        if ('confirmsesskeybad' == $errorcode) {
-            $module = '';
-        } else {
-            $module = 'workshop';
-        }
-        parent::__construct($errorcode, $module, $link, $a, $debuginfo);
-    }
-}
index fed52729277110e7dc1f48474c3e07118d9f7e68..c615ab441669c445107d0caa50a69060e90cc70e 100644 (file)
@@ -44,7 +44,6 @@ class moodle_mod_workshop_renderer extends moodle_renderer_base {
      *
      * @param mixed $page the page we are doing output for
      * @param mixed $output lower-level renderer, typically moodle_core_renderer
-     * @access public
      * @return void
      */
     public function __construct($page, $output) {
index 50d6931d555ba2ca93857928be108d98806979bd..a85100fc914a73fdcba20f13d73f9c72fe6a2997 100644 (file)
@@ -16,7 +16,7 @@
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Unit tests for workshop_api class defined in mod/workshop/locallib.php
+ * Unit tests for workshop class defined in mod/workshop/locallib.php
  *
  * @package   mod-workshop
  * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
@@ -32,25 +32,24 @@ require_once($CFG->dirroot . '/mod/workshop/locallib.php'); // Include the code
  * Test subclass that makes all the protected methods we want to test public.
  * Also re-implements bridging methods so we can test more easily.
  */
-class testable_workshop_api extends workshop_api {
+class testable_workshop extends workshop {
 
 }
 
 /**
  * Test cases for the internal workshop api
  */
-class workshop_api_test extends UnitTestCase {
+class workshop_internal_api_test extends UnitTestCase {
 
     /** workshop instance emulation */
     protected $workshop;
 
     /** setup testing environment */
     public function setUp() {
-        $workshoprecord         = new stdClass;
-        $workshoprecord->id     = 42;
-
-        $cm                     = new stdClass;
-        $this->workshop = new testable_workshop_api($workshoprecord, $cm);
+        $cm                 = (object)array('id' => 3);
+        $course             = (object)array('id' => 11);
+        $workshop           = (object)array('id' => 42);
+        $this->workshop     = new testable_workshop($workshop, $cm, $course);
     }
 
     public function tearDown() {
index f2857108e525ba03bcb791008ff432a77290e7fb..a676db763e32582eda84b1c62c07d3a7835ef57d 100644 (file)
@@ -41,7 +41,7 @@ if (isguestuser()) {
 }
 
 $workshop   = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST);
-$workshop   = new workshop_api($workshop, $cm, $course);
+$workshop   = new workshop($workshop, $cm, $course);
 
 if ($id) { // submission is specified
     $submission = $DB->get_record('workshop_submissions', array('id' => $id, 'workshopid' => $workshop->id), '*', MUST_EXIST);
@@ -101,9 +101,9 @@ $PAGE->set_heading($course->fullname);
 
 $stredit    = empty($submission->id) ? get_string('editingsubmission', 'workshop') : get_string('edit');
 $navigation = build_navigation($stredit, $cm);
-$menu       = navmenu($course, $cm);
+// todo $menu       = navmenu($course, $cm);
 
-echo $OUTPUT->header($navigation, $menu);
+echo $OUTPUT->header($navigation);
 echo $OUTPUT->heading(format_string($workshop->name), 2);
 $mform->display();
 echo $OUTPUT->footer();
index 3a08cce692d831a57b4264e1cfd67cb4f9d58d76..bb42f6c459b7d302dd6fa1ffb43115906a9a2a22 100644 (file)
@@ -28,6 +28,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$module->version  = 2009070500;
-$module->requires = 2009050619;  // Requires this Moodle version
+$module->version  = 2009073100;
+$module->requires = 2009073000;  // Requires this Moodle version
 $module->cron     = 60;
index c9b9bf79c51b2c4ff66c1010a47ac51fa58a14f1..e078cbb07685ce36d01c6fbe7bd9a00c54e5dd43 100644 (file)
@@ -29,8 +29,9 @@
 require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
 require_once(dirname(__FILE__).'/locallib.php');
 
-$id = optional_param('id', 0, PARAM_INT); // course_module ID, or
-$w  = optional_param('w', 0, PARAM_INT);  // workshop instance ID
+$id     = optional_param('id', 0, PARAM_INT); // course_module ID, or
+$w      = optional_param('w', 0, PARAM_INT);  // workshop instance ID
+$edit   = optional_param('edit', null, PARAM_BOOL);
 
 if ($id) {
     $cm         = get_coursemodule_from_id('workshop', $id, 0, false, MUST_EXIST);
@@ -43,7 +44,7 @@ if ($id) {
 }
 
 require_login($course, true, $cm);
-$workshop = new workshop_api($workshop, $cm, $course);
+$workshop = new workshop($workshop, $cm, $course);
 
 // todo has_capability() check using something like
 // if (!(($workshop->is_open() && has_capability('mod/workshop:view')) || has_capability(...) || has_capability(...))) {
@@ -52,10 +53,23 @@ $workshop = new workshop_api($workshop, $cm, $course);
 
 // todo logging add_to_log($course->id, "workshop", "view", "view.php?id=$cm->id", "$workshop->id");
 
+if (!is_null($edit) && $PAGE->user_allowed_editing()) {
+    $USER->editing = $edit;
+}
+
 $PAGE->set_url($workshop->view_url());
 $PAGE->set_title($workshop->name);
 $PAGE->set_heading($course->fullname);
-$PAGE->set_button(update_module_button($cm->id, $course->id, get_string('modulename', 'workshop')));
+$buttons = array();
+if ($PAGE->user_allowed_editing()) {
+    $editblocks                 = new html_form();
+    $editblocks->method         = 'get';
+    $editblocks->button->text   = get_string($PAGE->user_is_editing() ? 'blockseditoff' : 'blocksediton');
+    $editblocks->url            = new moodle_url($PAGE->url, array('edit' => $PAGE->user_is_editing() ? 'off' : 'on'));
+    $buttons[] = $OUTPUT->button($editblocks);
+}
+$buttons[] = update_module_button($cm->id, $course->id, get_string('modulename', 'workshop'));
+$PAGE->set_button(implode('', $buttons));
 
 // todo navigation will be changed yet for Moodle 2.0
 $navlinks   = array();
@@ -66,39 +80,29 @@ $navlinks[] = array('name' => format_string($workshop->name),
                     'link' => '',
                     'type' => 'activityinstance');
 $navigation = build_navigation($navlinks);
-$menu       = navmenu($course, $cm);
+//$menu       = navmenu($course, $cm); todo
 
 /// Output starts here
 
-echo $OUTPUT->header($navigation, $menu);
+echo $OUTPUT->header($navigation);
 
 /// Print the main part of the page - todo these are just links to help during development
-echo $OUTPUT->heading('Workshop administration tools', 3);
-echo $OUTPUT->box_start();
-echo $OUTPUT->heading('Workshop administration tools', 3);
-echo '<ul>';
-echo '<li><a href="' . $workshop->editform_url()->out()  . '">Edit grading form (' . get_string('strategy' . $workshop->strategy, 'workshop') . ')</a></li>';
-echo "<li><a href=\"allocation.php?cmid={$cm->id}\">Allocate submissions</a></li>";
-echo "<li><a href=\"develtools.php?cmid={$cm->id}\">Development tools</a></li>";
-echo '</ul>';
-echo $OUTPUT->box_end();
-
 echo $OUTPUT->box_start();
-echo $OUTPUT->heading(get_string('submission', 'workshop'), 3);
-echo "<a href=\"submission.php?cmid={$cm->id}\">My submission</a>";
-echo $OUTPUT->box_end();
-
-echo $OUTPUT->box_start();
-echo $OUTPUT->heading(get_string('assessment', 'workshop'), 3);
-
-$rs = $workshop->get_assessments_recordset($USER->id);
-echo "You are expected to assess following submissions:";
-echo "<ul>";
-foreach ($rs as $assessment) {
-    echo "<li><a href=\"assessment.php?asid={$assessment->id}\">Assessment of '{$assessment->title}' by {$assessment->authorid}</a></li>";
+echo $OUTPUT->heading('Workshop testing', 1);
+echo "<ol>\n";
+echo '<li><a href="' . $workshop->editform_url()->out()  . '">Edit grading form (' . get_string('strategy' . $workshop->strategy, 'workshop') . ')</a></li>' . "\n";
+echo "<li><a href=\"submission.php?cmid={$cm->id}\">View/edit your own submission</a></li>\n";
+echo "<li><a href=\"develtools.php?tool=mksubmissions&amp;cmid={$cm->id}\">Fake others' submissions</a></li>\n";
+echo "<li><a href=\"allocation.php?cmid={$cm->id}\">Allocate submissions</a></li>\n";
+
+$assessments = $workshop->get_assessments($USER->id);
+echo "<li>Assess submissions\n";
+echo "<ol>\n";
+foreach ($assessments as $assessment) {
+    echo "<li><a href=\"assessment.php?asid={$assessment->id}\">Assessment of '{$assessment->title}' by {$assessment->authorid}</a></li>" . "\n";
 }
-echo "</ul>";
-$rs->close();
+echo "</ol></li>" . "\n";
+echo "</ol>\n";
 echo $OUTPUT->box_end();
 
 echo $OUTPUT->footer();