]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-19870 Initial work on random allocator
authorDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 17:47:09 +0000 (17:47 +0000)
committerDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 17:47:09 +0000 (17:47 +0000)
Initial sketches of random allocator. Refactoring of the rest of the
module here and there. Also, this commit removes trailing whitespace and
running empty lines.

33 files changed:
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 [new file with mode: 0644]
mod/workshop/allocation/random/simpletest/testallocator.php [new file with mode: 0644]
mod/workshop/assessment.php
mod/workshop/db/access.php
mod/workshop/editform.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/noerrors/edit_form.php
mod/workshop/grading/noerrors/strategy.php
mod/workshop/grading/strategy.php
mod/workshop/index.php
mod/workshop/lang/en_utf8/workshop.php
mod/workshop/lib.php
mod/workshop/locallib.php
mod/workshop/mod_form.php
mod/workshop/renderer.php
mod/workshop/settings.php
mod/workshop/simpletest/testlib.php
mod/workshop/simpletest/testworkshopapi.php
mod/workshop/styles.php
mod/workshop/submission.php
mod/workshop/submission_form.php
mod/workshop/version.php
mod/workshop/view.php

index 1d055bdff97ac85f57c68b48370a443d1ee8eab9..049948c10ea2757b81b5fdfb2e0a604ef552870a 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * At this page, teachers allocate submissions to students for a review
  *
- * The allocation logic itself is delegated to allocators - subplugins in ./allocation 
+ * The allocation logic itself is delegated to allocators - subplugins in ./allocation
  * folder.
  *
  * @package   mod-workshop
@@ -48,11 +47,11 @@ require_capability('mod/workshop:allocate', $context);
 $PAGE->set_title($workshop->name);
 $PAGE->set_heading($course->fullname);
 //
-// todo navigation will be changed yet for Moodle 2.0
+// TODO navigation will be changed yet for Moodle 2.0
 $navigation = build_navigation(get_string('allocation', 'workshop'), $cm);
 
-$allocator = $workshop->allocator_instance($method);
-$allocator->init();
+$allocator  = $workshop->allocator_instance($method);
+$initresult = $allocator->init();
 
 //
 // Output starts here
@@ -67,5 +66,13 @@ foreach ($allocators as $methodid => $methodname) {
 }
 print_tabs(array($tabrow), $method);    // todo use $output call
 
-echo $OUTPUT->container($allocator->ui(), 'allocator-ui');
+if (!empty($initresult)) {
+    echo $OUTPUT->container_start('allocator-init-results');
+    echo $wsoutput->allocation_init_result($initresult);
+    echo $OUTPUT->container_end();
+} else {
+    echo $OUTPUT->container_start('allocator-ui');
+    $allocator->ui($wsoutput);
+    echo $OUTPUT->container_end();
+}
 echo $OUTPUT->footer();
index e7750824c8deec52ce16e53734cd73abf0b788ff..45a2862cc84351816749dd3a7854859b7471e587 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
-// This file is part of Moodle - http://moodle.org/  
-// 
+// 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
 // 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/>.
 
-
 /**
  * Code for the submissions allocation support is defined here
  *
 
 defined('MOODLE_INTERNAL') || die();
 
-
 /**
  * Allocators are responsible for assigning submissions to reviewers for assessments
  *
- * The task of the allocator is to assign the correct number of submissions to reviewers 
+ * The task of the allocator is to assign the correct number of submissions to reviewers
  * for assessment. Several allocation methods are expected and they can be combined. For
  * example, teacher can allocate several submissions manually (by 'manual' allocator) and
  * then let the other submissions being allocated randomly (by 'random' allocator).
@@ -38,27 +36,29 @@ defined('MOODLE_INTERNAL') || die();
  * workshop_assessments table.
  */
 interface workshop_allocator {
-    
+
     /**
      * Initialize the allocator and eventually process submitted data
      *
-     * This method is called soon after the allocator is constructed and before any output 
+     * This method is called soon after the allocator is constructed and before any output
      * is generated. Therefore is may process any data submitted and do other tasks.
      * It should not generate any output
      *
      * @throws moodle_workshop_exception
-     * @return void
+     * @return mixed void or optional HTML string
      */
     public function init();
 
-
     /**
-     * Returns HTML to be displayed as the user interface
+     * Print HTML to be displayed as the user interface
      *
-     * If a form is part of the UI, the caller should have call $PAGE->set_url(...)
-     * 
-     * @return string HTML to be displayed
+     * If a form is part of the UI, the caller should have called $PAGE->set_url(...)
+     * The methods must produce output instead of just returning it so mform->display() can
+     * be used there.
+     *
+     * @param object $wsoutput workshop module renderer can be used
+     * @return void
      */
-    public function ui();
+    public function ui(moodle_mod_workshop_renderer $wsoutput);
 
 }
index 0ed0fe33db8bfc04b92d4b3e760a41140b9b1429..975851aad4a3d88010db581ef2dd10bfb3a109e4 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
-// This file is part of Moodle - http://moodle.org/  
-// 
+// 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
 // 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/>.
 
-
 /**
  * Allows user to allocate the submissions manually
- * 
+ *
  * @package   mod-workshop
  * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -29,17 +28,15 @@ defined('MOODLE_INTERNAL') || die();
 require_once(dirname(dirname(__FILE__)) . '/lib.php');                  // interface definition
 require_once(dirname(dirname(dirname(__FILE__))) . '/locallib.php');    // workshop internal API
 
-
 /**
  * These constants are used to pass status messages between init() and ui()
  */
 define('WORKSHOP_ALLOCATION_MANUAL_MSG_ADDED',          1);
 define('WORKSHOP_ALLOCATION_MANUAL_MSG_NOSUBMISSION',   2);
 define('WORKSHOP_ALLOCATION_MANUAL_MSG_EXISTS',         3);
-define('WORKSHOP_ALLOCATION_MANUAL_MSG_WOSUBMISSION',   4);
-define('WORKSHOP_ALLOCATION_MANUAL_MSG_CONFIRM_DEL',    5);
-define('WORKSHOP_ALLOCATION_MANUAL_MSG_DELETED',        6);
-
+define('WORKSHOP_ALLOCATION_MANUAL_MSG_CONFIRM_DEL',    4);
+define('WORKSHOP_ALLOCATION_MANUAL_MSG_DELETED',        5);
+define('WORKSHOP_ALLOCATION_MANUAL_MSG_DELETE_ERROR',   6);
 
 /**
  * Allows users to allocate submissions for review manually
@@ -49,16 +46,13 @@ class workshop_manual_allocator implements workshop_allocator {
     /** workshop instance */
     protected $workshop;
 
-
     /**
      * @param stdClass $workshop Workshop record
      */
     public function __construct(workshop $workshop) {
-    
         $this->workshop = $workshop;
     }
 
-
     /**
      * Allocate submissions as requested by user
      */
@@ -75,14 +69,12 @@ class workshop_manual_allocator implements workshop_allocator {
             $reviewerid = required_param('by', PARAM_INT);
             $authorid   = required_param('of', PARAM_INT);
             $m          = array();  // message object to be passed to the next page
-            $rs         = $this->workshop->get_submissions_recordset($authorid);
-            $submission = $rs->current();
-            $rs->close();
-            if (empty($submission->id)) {
+            $submission = $this->workshop->get_submission_by_author($authorid);
+            if (!$submission) {
                 // nothing submitted by the given user
                 $m[] = WORKSHOP_ALLOCATION_MANUAL_MSG_NOSUBMISSION;
                 $m[] = $authorid;
-                
+
             } else {
                 // ok, we have the submission
                 $res = $this->workshop->add_allocation($submission, $reviewerid);
@@ -90,10 +82,6 @@ class workshop_manual_allocator implements workshop_allocator {
                     $m[] = WORKSHOP_ALLOCATION_MANUAL_MSG_EXISTS;
                     $m[] = $submission->userid;
                     $m[] = $reviewerid;
-                } elseif ($res == WORKSHOP_ALLOCATION_WOSUBMISSION) {
-                    $m[] = WORKSHOP_ALLOCATION_MANUAL_MSG_WOSUBMISSION;
-                    $m[] = $submission->userid;
-                    $m[] = $reviewerid;
                 } else {
                     $m[] = WORKSHOP_ALLOCATION_MANUAL_MSG_ADDED;
                     $m[] = $submission->userid;
@@ -109,10 +97,8 @@ class workshop_manual_allocator implements workshop_allocator {
             }
             $assessmentid   = required_param('what', PARAM_INT);
             $confirmed      = optional_param('confirm', 0, PARAM_INT);
-            $rs             = $this->workshop->get_assessments_recordset('all', $assessmentid);
-            $assessment     = $rs->current();
-            $rs->close();
-            if (!empty($assessment)) {
+            $assessment     = $this->workshop->get_assessment_by_id($assessmentid);
+            if ($assessment) {
                 if (!$confirmed) {
                     $m[] = WORKSHOP_ALLOCATION_MANUAL_MSG_CONFIRM_DEL;
                     $m[] = $assessment->id;
@@ -124,10 +110,15 @@ class workshop_manual_allocator implements workshop_allocator {
                         $m[] = 1;
                     }
                 } else {
-                    $res = $this->workshop->delete_assessment($assessment->id);
-                    $m[] = WORKSHOP_ALLOCATION_MANUAL_MSG_DELETED;
-                    $m[] = $assessment->authorid;
-                    $m[] = $assessment->reviewerid;
+                    if($this->workshop->delete_assessment($assessment->id)) {
+                        $m[] = WORKSHOP_ALLOCATION_MANUAL_MSG_DELETED;
+                        $m[] = $assessment->authorid;
+                        $m[] = $assessment->reviewerid;
+                    } else {
+                        $m[] = WORKSHOP_ALLOCATION_MANUAL_MSG_DELETE_ERROR;
+                        $m[] = $assessment->authorid;
+                        $m[] = $assessment->reviewerid;
+                    }
                 }
                 $m = implode('-', $m);  // serialize message object to be passed via URL
                 redirect($PAGE->url->out(false, array('m' => $m), false));
@@ -136,11 +127,10 @@ class workshop_manual_allocator implements workshop_allocator {
         }
     }
 
-
     /**
      * Prints user interface - current allocation and a form to edit it
      */
-    public function ui() {
+    public function ui(moodle_mod_workshop_renderer $wsoutput) {
         global $PAGE;
 
         $hlauthorid     = -1;           // highlight this author
@@ -168,12 +158,6 @@ class workshop_manual_allocator implements workshop_allocator {
                 $msg->text      = get_string('nosubmissionfound', 'workshop');
                 $msg->sty       = 'error';
                 break;
-            case WORKSHOP_ALLOCATION_MANUAL_MSG_WOSUBMISSION:
-                $hlauthorid     = $m[1];
-                $hlreviewerid   = $m[2];
-                $msg->text      = get_string('cantassesswosubmission', 'workshop');
-                $sty->sty       = 'error';
-                break;
             case WORKSHOP_ALLOCATION_MANUAL_MSG_CONFIRM_DEL:
                 $hlauthorid     = $m[2];
                 $hlreviewerid   = $m[3];
@@ -191,6 +175,12 @@ class workshop_manual_allocator implements workshop_allocator {
                 $msg->text      = get_string('assessmentdeleted', 'workshop');
                 $msg->sty       = 'ok';
                 break;
+            case WORKSHOP_ALLOCATION_MANUAL_MSG_DELETE_ERROR:
+                $hlauthorid     = $m[1];
+                $hlreviewerid   = $m[2];
+                $msg->text      = get_string('assessmentnotdeleted', 'workshop');
+                $msg->sty       = 'error';
+                break;
             }
             if ($m[0] == WORKSHOP_ALLOCATION_MANUAL_MSG_CONFIRM_DEL) {
                 $handler = $PAGE->url->out_action();
@@ -234,12 +224,12 @@ class workshop_manual_allocator implements workshop_allocator {
             }
         }
 
-        // ok, we have all data. Let it pass to the renderer and return the output
+        // We have all data. Let it pass to the renderer and return the output
+        // Here, we do not use neither the core renderer nor the workshop one but use an own one
         require_once(dirname(__FILE__) . '/renderer.php');
         $uioutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE, 'allocation_manual');
-        return $uioutput->display_allocations($this->workshop, $peer, $hlauthorid, $hlreviewerid, $msg);
+        echo $uioutput->display_allocations($this->workshop, $peer, $hlauthorid, $hlreviewerid, $msg);
     }
 
-
 }
 
index 12244cfd913793c4f14217fac85af74f002ee32c..5effbc76069ec6d6479303958ebeb35b8d3d368d 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * Renderer class for the manual allocation UI is defined here
  *
@@ -27,9 +26,9 @@
 defined('MOODLE_INTERNAL') || die();
 
 /**
- * Manual allocation renderer class 
+ * Manual allocation renderer class
  */
-class moodle_mod_workshop_allocation_manual_renderer  {
+class moodle_mod_workshop_allocation_manual_renderer extends moodle_renderer_base  {
 
     /** the underlying renderer to use */
     protected $output;
@@ -39,7 +38,7 @@ class moodle_mod_workshop_allocation_manual_renderer  {
 
     /**
      * Workshop renderer constructor
-     * 
+     *
      * @param mixed $page the page we are doing output for
      * @param mixed $output lower-level renderer, typically moodle_core_renderer
      * @access public
@@ -50,11 +49,10 @@ class moodle_mod_workshop_allocation_manual_renderer  {
         $this->output = $output;
     }
 
-
     /**
      * Display the table of all current allocations and widgets to modify them
-     * 
-     * @param workshop $workshop workshop instance object 
+     *
+     * @param workshop $workshop workshop instance object
      * @param array $peers prepared array of all allocations
      * @param int $hlauthorid highlight this author
      * @param int $hlreviewerid highlight this reviewer
@@ -63,12 +61,13 @@ class moodle_mod_workshop_allocation_manual_renderer  {
      */
     public function display_allocations(workshop $workshop, &$peers, $hlauthorid=null, $hlreviewerid=null, $msg=null) {
 
+        $wsoutput = $this->page->theme->get_renderer('mod_workshop', $this->page);
         if (empty($peers)) {
-            return $this->status_message((object)array('text' => get_string('nosubmissions', 'workshop')));
+            return $wsoutput->status_message((object)array('text' => get_string('nosubmissions', 'workshop')));
         }
 
         $table              = new html_table();
-        $table->set_classes = array('allocations');
+        $table->set_classes('allocations');
         $table->head        = array(get_string('participantreviewedby', 'workshop'),
                                     get_string('participant', 'workshop'),
                                     get_string('participantrevierof', 'workshop'));
@@ -87,68 +86,53 @@ class moodle_mod_workshop_allocation_manual_renderer  {
             if ($user->id == $hlreviewerid) {
                 $thisrowclasses[] = 'highlightreviewerof';
             }
-            $table->rowclass[] = implode(' ', $thisrowclasses);
+            $table->rowclasses[] = implode(' ', $thisrowclasses);
             $table->data[] = $row;
         }
 
-        return $this->output->container($this->status_message($msg) . $this->output->table($table), 'manual-allocator');
+        return $this->output->container($wsoutput->status_message($msg) . $this->output->table($table), 'manual-allocator');
     }
 
-
     /**
-     * Returns html code for a status message 
-     * 
-     * @param string $message to display
-     * @return string html
+     * Returns information about the workshop participant
+     *
+     * @param stdClass $user participant data
+     * @return string HTML code
      */
-    protected function status_message(stdClass $message) {
-
-        if (empty($message->text)) {
-            return '';
-        }
-        $sty = $message->sty ? $message->sty : 'info';
-
-        $o = '<span>' . $message->text . '</span>';
-        $closer = '<a href="' . $this->page->url->out() . '">' . get_string('messageclose', 'workshop') . '</a>';
-        $o .= $this->output->container($closer, 'status-message-closer');
-        if (isset($message->extra)) {
-            $o .= $message->extra;
-        }
-        return $this->output->container($o, array('status-message', $sty));
-    }
-
-
     protected function participant(stdClass $user) {
-
         $o  = print_user_picture($user, $this->page->course->id, null, 35, true);
         $o .= fullname($user);
-        $o .= '<div class="submission">' . "\n";
+        $o .= $this->output->container_start(array('submission'));
         if (is_null($user->submissionid)) {
-            $o .= '<span class="info">' . get_string('nosubmissionfound', 'workshop');
+            $o .= $this->output->output_tag('span', array('class' => 'info'), get_string('nosubmissionfound', 'workshop'));
         } else {
-            $o .= '<div class="title"><a href="#">' . s($user->submissiontitle) . '</a></div>';
+            $submlink = $this->output->output_tag('a', array('href' => '#'), s($user->submissiontitle));
+            $o .= $this->output->container($submlink, array('title'));
             if (is_null($user->submissiongrade)) {
-                $o .= '<div class="grade missing">' . get_string('nogradeyet', 'workshop') . '</div>';
+                $o .= $this->output->container(get_string('nogradeyet', 'workshop'), array('grade', 'missing'));
             } else {
-                $o .= '<div class="grade">' . s($user->submissiongrade) . '</div>'; // todo calculate
+                $o .= $this->output->container(s($user->submissiongrade), array('grade')); // TODO calculate grade
             }
         }
-        $o .= '</div>' . "\n";
-    
+        $o .= $this->output->container_end();
         return $o;
     }
 
-
-    protected function reviewers_of_participant(stdClass $user, workshop $workshop, &$peers) {
-
+    /**
+     * 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 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) {
         $o = '';
         if (is_null($user->submissionid)) {
-            $o .= '<span class="info">' . "\n";
-            $o .= get_string('nothingtoreview', 'workshop');
-            $o .= '</span>' . "\n";
+            $o .= $this->output->output_tag('span', array('class' => 'info'), get_string('nothingtoreview', 'workshop'));
         } else {
             $options = array();
-            foreach ($workshop->get_peer_reviewers() as $reviewer) {
+            foreach ($workshop->get_peer_reviewers(!$workshop->assesswosubmission) as $reviewer) {
                 $options[$reviewer->id] = fullname($reviewer);
             }
             if (!$workshop->useselfassessment) {
@@ -156,73 +140,66 @@ class moodle_mod_workshop_allocation_manual_renderer  {
                 if (isset($options[$user->id])) {
                     unset($options[$user->id]);
                 }
-            }   
+            }
             $handler = $this->page->url->out_action() . '&amp;mode=new&amp;of=' . $user->id . '&amp;by=';
             $o .= popup_form($handler, $options, 'addreviewof' . $user->id, '',
                      get_string('chooseuser', 'workshop'), '', '', true, 'self', get_string('addreviewer', 'workshop'));
         }
-        $o .= '<ul>' . "\n";
+        $o .= $this->output->output_start_tag('ul', array());
         foreach ($user->reviewedby as $reviewerid => $assessmentid) {
-            $o .= '<li>';
+            $o .= $this->output->output_start_tag('li', array());
             $o .= print_user_picture($peers[$reviewerid], $this->page->course->id, null, 16, true);
             $o .= fullname($peers[$reviewerid]);
 
             $handler = $this->page->url->out_action(array('mode' => 'del', 'what' => $assessmentid));
-            $o .= '<a class="action" href="' . $handler . '"> X </a>';
+            $o .= $this->output->output_tag('a', array('href' => $handler), ' X ');
 
-            $o .= '</li>';
+            $o .= $this->output->output_end_tag('li');
         }
-        $o .= '</ul>' . "\n";
-
+        $o .= $this->output->output_end_tag('ul');
         return $o;
     }
 
-
-    protected function reviewees_of_participant(stdClass $user, workshop $workshop, &$peers) {
-
+    /**
+     * 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 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) {
         $o = '';
-        if (!$workshop->assesswosubmission && is_null($user->submissionid)) {
-            $o .= '<span class="info">' . "\n";
-            $o .= get_string('cantassesswosubmission', 'workshop');
-            $o .= '</span>' . "\n";
-        } else {
-            $options = array();
-            foreach ($workshop->get_peer_authors(true) as $author) {
-                $options[$author->id] = fullname($author);
-            }
-            if (!$workshop->useselfassessment) {
-                // students can not be reviewed by themselves in this workshop
-                if (isset($options[$user->id])) {
-                    unset($options[$user->id]);
-                }
-            }
-
-            $handler = $this->page->url->out_action() . '&mode=new&amp;by=' . $user->id . '&amp;of=';
-            $o .= popup_form($handler, $options, 'addreviewby' . $user->id, '', 
-                        get_string('chooseuser', 'workshop'), '', '', true, 'self', get_string('addreviewee', 'workshop'));
-            $o .= '<ul>' . "\n";
-            foreach ($user->reviewerof as $authorid => $assessmentid) {
-                $o .= '<li>';
-                $o .= print_user_picture($peers[$authorid], $this->page->course->id, null, 16, true);
-                $o .= fullname($peers[$authorid]);
-
-                // delete
-                $handler = $this->page->url->out_action(array('mode' => 'del', 'what' => $assessmentid));
-                $o .= '<a class="action" href="' . $handler . '"> X </a>'; // todo icon and link title
-
-                $o .= '</li>';
+        if (is_null($user->submissionid)) {
+            $o .= $this->output->container(get_string('withoutsubmission', 'workshop'), 'info');
+        }
+        $options = array();
+        foreach ($workshop->get_peer_authors() as $author) {
+            $options[$author->id] = fullname($author);
+        }
+        if (!$workshop->useselfassessment) {
+            // students can not be reviewed by themselves in this workshop
+            if (isset($options[$user->id])) {
+                unset($options[$user->id]);
             }
-            $o .= '</ul>' . "\n";
         }
+        $handler = $this->page->url->out_action() . '&mode=new&amp;by=' . $user->id . '&amp;of=';
+        $o .= popup_form($handler, $options, 'addreviewby' . $user->id, '',
+                    get_string('chooseuser', 'workshop'), '', '', true, 'self', get_string('addreviewee', 'workshop'));
+        $o .= $this->output->output_start_tag('ul', array());
+        foreach ($user->reviewerof as $authorid => $assessmentid) {
+            $o .= $this->output->output_start_tag('li', array());
+            $o .= print_user_picture($peers[$authorid], $this->page->course->id, null, 16, true);
+            $o .= fullname($peers[$authorid]);
+
+            // delete
+            $handler = $this->page->url->out_action(array('mode' => 'del', 'what' => $assessmentid));
+            $o .= $this->output->output_tag('a', array('href' => $handler), ' X ');
 
+            $o .= $this->output->output_end_tag('li');
+        }
+        $o .= $this->output->output_end_tag('ul');
         return $o;
     }
 
 }
-
-
-
-
-
-
-
index 228824d8b5f22b2040db33e23f6451c290a6fb93..7ceca1c9b83dccad8098adcb1b759304a172c120 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
-// This file is part of Moodle - http://moodle.org/  
-// 
+// 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
 // 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/>.
 
-
 /**
  * Allocates the submissions randomly
- * 
+ *
  * @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();
 
-require_once(dirname(dirname(__FILE__)) . '/lib.php');  // interface definition
+global $CFG;    // access to global variables during unit test
+
+require_once(dirname(dirname(__FILE__)) . '/lib.php');                  // interface definition
+require_once(dirname(dirname(dirname(__FILE__))) . '/locallib.php');    // workshop internal API
+require_once(dirname(__FILE__) . '/settings_form.php');                 // settings form
+
+/**
+ * Constants used to pass status messages between init() and ui()
+ */
+define('WORKSHOP_ALLOCATION_RANDOM_MSG_SUCCESS',    1);
 
+/**
+ * Constants used in allocation settings form
+ */
+define('WORKSHOP_USERTYPE_AUTHOR',                  1);
+define('WORKSHOP_USERTYPE_REVIEWER',                2);
 
+/**
+ * Allocates the submissions randomly
+ */
 class workshop_random_allocator implements workshop_allocator {
 
     /** workshop instance */
     protected $workshop;
 
-    /** array of allocations */
-    protected $allocation = array();
-
-    public function __construct(stdClass $workshop) {
-        global $DB, $USER;
+    /** mform with settings */
+    protected $mform;
 
+    /**
+     * @param stdClass $workshop Workshop record
+     */
+    public function __construct(workshop $workshop) {
         $this->workshop = $workshop;
+    }
 
-        // submissions to be allocated
-        $submissions = $DB->get_records('workshop_submissions', array('workshopid' => $this->workshop->id, 'example' => 0),
-                                         '', 'id,userid,title');
+    /**
+     * Allocate submissions as requested by user
+     */
+    public function init() {
+        global $PAGE;
 
+        $customdata = array();
+        // $customdata['workshop'] = $this->workshop;
+        $this->mform = new workshop_random_allocator_form($PAGE->url, $customdata);
+        if ($this->mform->is_cancelled()) {
+            redirect($PAGE->url->out(false, array(), false));
+        } else if ($settings = $this->mform->get_data()) {
+            // process validated data
+            if (!confirm_sesskey()) {
+                throw new moodle_workshop_exception($this->workshop, 'confirmsesskeybad');
+            }
+            $o                  = array();      // list of output messages
+            $numofreviews       = required_param('numofreviews', PARAM_INT);
+            $numper             = required_param('numper', PARAM_INT);
+            $removecurrent      = required_param('removecurrent', PARAM_INT);
+            $assesswosubmission = required_param('assesswosubmission', PARAM_INT);
+            $musthavesubmission = empty($assesswosubmission);
+            $addselfassessment  = required_param('addselfassessment', PARAM_INT);
 
-        // dummy allocation - allocate all submissions to the current USER
-        foreach ($submissions as $submissionid => $submission) {
-            $this->allocation[$submissionid]                = new stdClass;
-            $this->allocation[$submissionid]->submissionid  = $submissionid;
-            $this->allocation[$submissionid]->title         = $submission->title;
-            $this->allocation[$submissionid]->authorid      = $submission->userid;
-            $this->allocation[$submissionid]->reviewerid    = $USER->id;
-            $this->allocation[$submissionid]->assessmentid  = NULL;
+            $authors            = $this->workshop->get_peer_authors_by_group();
+            $reviewers          = $this->workshop->get_peer_reviewers_by_group($musthavesubmission);
+            $assessments        = $this->workshop->get_assessments();
+
+            $newallocations     = array();      // array of (reviewer,reviewee) tuples
+
+            if ($numofreviews) {
+                $randomallocations  = $this->random_allocation($authors, $reviewers, $assessments, $numofreviews, $numper);
+                $newallocations     = array_merge($newallocations, $randomallocations);
+                $o[] = 'ok::' . get_string('numofrandomlyallocatedsubmissions', 'workshop', count($randomallocations));
+                unset($randomallocations);
+            }
+            if ($addselfassessment) {
+                $selfallocations    = $this->self_allocation($authors, $reviewers, $assessments);
+                $newallocations     = array_merge($newallocations, $selfallocations);
+                $o[] = 'ok::' . get_string('numofselfallocatedsubmissions', 'workshop', count($selfallocations));
+                unset($selfallocations);
+            }
+            if (empty($newallocations)) {
+                $o[] = 'info::' . get_string('noallocationtoadd', 'workshop');
+            } else {
+                $this->add_new_allocations($newallocations, $authors, $reviewers);
+                foreach ($newallocations as $newallocation) {
+                    list($reviewerid, $authorid) = each($newallocation);
+                    $a                  = new stdClass();
+                    $a->reviewername    = fullname($reviewers[0][$reviewerid]);
+                    $a->authorname      = fullname($authors[0][$authorid]);
+                    $o[] = 'ok::ident::' . get_string('allocationaddeddetail', 'workshop', $a);
+                }
+            }
+            if ($removecurrent) {
+                $delassessments = $this->get_unkept_assessments($assessments, $newallocations, $addselfassessment);
+                // random allocator should not be able to delete assessments that have already been graded
+                // by reviewer
+                $o[] = 'info::' . get_string('numofdeallocatedassessment', 'workshop', count($delassessments));
+                foreach ($delassessments as $delassessmentid) {
+                    $a = new stdClass();
+                    $a->authorname      = fullname((object)array(
+                            'lastname'  => $assessments[$delassessmentid]->authorlastname,
+                            'firstname' => $assessments[$delassessmentid]->authorfirstname));
+                    $a->reviewername    = fullname((object)array(
+                            'lastname'  => $assessments[$delassessmentid]->reviewerlastname,
+                            'firstname' => $assessments[$delassessmentid]->reviewerfirstname));
+                    if (!is_null($assessments[$delassessmentid]->grade)) {
+                        $o[] = 'error::ident::' . get_string('allocationdeallocategraded', 'workshop', $a);
+                        unset($delassessments[$delassessmentid]);
+                    } else {
+                        $o[] = 'info::ident::' . get_string('assessmentdeleteddetail', 'workshop', $a);
+                    }
+                }
+                $this->workshop->delete_assessment($delassessments);
+            }
+            return $o;
+        } else {
+            // this branch is executed if the form is submitted but the data
+            // doesn't validate and the form should be redisplayed
+            // or on the first display of the form.
         }
+    }
 
-        // already created assessments
-        $assessments = $DB->get_records_list('workshop_assessments', 'submissionid', array_keys($submissions),
-                                                '', 'id,submissionid,userid');
-        
-        foreach ($assessments as $assessmentid => $assessment) {
-            $this->allocation[$assessment->submissionid]->assessmentid  = $assessmentid;
+    /**
+     * Prints user interface
+     */
+    public function ui(moodle_mod_workshop_renderer $wsoutput) {
+        global $OUTPUT;
+
+        $m = optional_param('m', null, PARAM_INT);  // status message code
+        $msg = new stdClass();
+        if ($m == WORKSHOP_ALLOCATION_RANDOM_MSG_SUCCESS) {
+            $msg = (object)array('text' => get_string('randomallocationdone', 'workshop'), 'sty' => 'ok');
+        }
+
+        echo $OUTPUT->container_start('random-allocator');
+        echo $wsoutput->status_message($msg);
+        $this->mform->display();
+        echo $OUTPUT->container_end();
+    }
+
+    /**
+     * Allocates submissions to their authors for review
+     *
+     * 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()}
+     * @return array of new allocations to be created, array of array(reviewerid => authorid)
+     */
+    protected function self_allocation($authors=array(), $reviewers=array(), $assessments=array()) {
+        if (!isset($authors[0]) || !isset($reviewers[0])) {
+            // no authors or no reviewers
+            return array();
         }
+        $alreadyallocated = array();
+        foreach ($assessments as $assessment) {
+            if ($assessment->authorid == $assessment->reviewerid) {
+                $alreadyallocated[$assessment->authorid] = 1;
+            }
+        }
+        $add = array(); // list of new allocations to be created
+        foreach ($authors[0] as $authorid => $author) {
+            // for all authors in all groups
+            if (isset($reviewers[0][$authorid])) {
+                // if the author can be reviewer
+                if (!isset($alreadyallocated[$authorid])) {
+                    // and the allocation does not exist yet, then
+                    $add[] = array($authorid => $authorid);
+                }
+            }
+        }
+        return $add;
     }
 
+    /**
+     * Creates new assessment records
+     *
+     * @param array $newallocations pairs 'reviewerid' => 'authorid'
+     * @param array $dataauthors    authors by group, group [0] contains all authors
+     * @param array $datareviewers  reviewers by group, group [0] contains all reviewers
+     * @return bool
+     */
+    protected function add_new_allocations($newallocations, $dataauthors, $datareviewers) {
+        global $DB;
 
-    public function init() {
+        $newallocations = $this->get_unique_allocations($newallocations);
+        $authorids      = $this->get_author_ids($newallocations);
+        $submissions    = $this->workshop->get_submission_by_author($authorids);
+        $submissions    = $this->index_submissions_by_authors($submissions);
+        foreach ($newallocations as $newallocation) {
+            list($reviewerid, $authorid) = each($newallocation);
+            if (!isset($submissions[$authorid])) {
+                throw new moodle_workshop_exception($this->workshop, 'unabletoallocateauthorwithoutsubmission');
+            }
+            $submission = $submissions[$authorid];
+            $status = $this->workshop->add_allocation($submission, $reviewerid, true);
+            if (WORKSHOP_ALLOCATION_EXISTS == $status) {
+                debugging('newallocations array contains existing allocation, this should not happen');
+            }
+        }
     }
 
+    /**
+     * Flips the structure of submission so it is indexed by userid attribute
+     *
+     * It is the caller's responsibility to make sure the submissions are not teacher
+     * examples so no user is the author of more submissions.
+     *
+     * @param string $submissions array indexed by submission id
+     * @return array indexed by author id
+     */
+    protected function index_submissions_by_authors($submissions) {
+        $byauthor = array();
+        if (is_array($submissions)) {
+            foreach ($submissions as $submissionid => $submission) {
+                if (isset($byauthor[$submission->userid])) {
+                    throw new moodle_workshop_exception($this->workshop, 'moresubmissionsbyauthor');
+                }
+                $byauthor[$submission->userid] = $submission;
+            }
+        }
+        return $byauthor;
+    }
 
-    public function ui() {
-        return 'TODO';
+    /**
+     * Extracts unique list of authors' IDs from the structure of new allocations
+     *
+     * @param array $newallocations of pairs 'reviewerid' => 'authorid'
+     * @return array of authorids
+     */
+    protected function get_author_ids($newallocations) {
+        $authors = array();
+        foreach ($newallocations as $newallocation) {
+            $authorid = reset($newallocation);
+            if (!in_array($authorid, $authors)) {
+                $authors[] = $authorid;
+            }
+        }
+        return $authors;
     }
 
+    /**
+     * Removes duplicate allocations
+     *
+     * @param mixed $newallocations array of 'reviewerid' => 'authorid' pairs
+     * @return array
+     */
+    protected function get_unique_allocations($newallocations) {
+        return array_merge(array_map('unserialize', array_unique(array_map('serialize', $newallocations))));
+    }
+
+    /**
+     * Returns the list of assessments to remove
+     *
+     * If user selects "removecurrentallocations", we should remove all current assessment records
+     * and insert new ones. But this would needlessly waste table ids. Instead, let us find only those
+     * assessments that have not been re-allocated in this run of allocation. So, the once-allocated
+     * submissions are kept with their original id.
+     *
+     * @param array $assessments         list of current assessments
+     * @param mixed $newallocations      array of 'reviewerid' => 'authorid' pairs
+     * @param bool  $keepselfassessments do not remove already allocated self assessments
+     * @return array of assessments ids to be removed
+     */
+    protected function get_unkept_assessments($assessments, $newallocations, $keepselfassessments) {
+        $keepids = array(); // keep these assessments
+        foreach ($assessments as $assessmentid => $assessment) {
+            $aaid = $assessment->authorid;
+            $arid = $assessment->reviewerid;
+            if (($keepselfassessments) && ($aaid == $arid)) {
+                $keepids[$assessmentid] = null;
+                continue;
+            }
+            foreach ($newallocations as $newallocation) {
+                list($nrid, $naid) = each($newallocation);
+                if (array($arid, $aaid) == array($nrid, $naid)) {
+                    // re-allocation found - let us continue with the next assessment
+                    $keepids[$assessmentid] = null;
+                    continue 2;
+                }
+            }
+        }
+        return array_keys(array_diff_key($assessments, $keepids));
+    }
+
+    /**
+     * TODO: short description.
+     *
+     * @param array    $authors      
+     * @param resource $reviewers    
+     * @param array    $assessments  
+     * @param mixed    $numofreviews 
+     * @param mixed    $numper       
+     * @return TODO
+     */
+    protected function random_allocation($authors, $reviewers, $assessments, $numofreviews, $numper) {
+    }
 
 }
diff --git a/mod/workshop/allocation/random/settings_form.php b/mod/workshop/allocation/random/settings_form.php
new file mode 100644 (file)
index 0000000..291c4bd
--- /dev/null
@@ -0,0 +1,70 @@
+<?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/>.
+
+/**
+ * Random allocator settings form
+ *
+ * @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();
+
+require_once($CFG->dirroot.'/lib/formslib.php');
+
+/**
+ * Allocator settings form
+ *
+ * This is used by {@see workshop_random_allocator::ui()} to set up allocation paramters.
+ *
+ * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class workshop_random_allocator_form extends moodleform {
+
+    /**
+     * Definition of the setting form elements
+     */
+    public function definition() {
+        $mform      = $this->_form;
+        //$workshop   = $this->_customdata['workshop'];
+
+        $mform->addElement('header', 'settings', get_string('allocationsettings', 'workshop'));
+
+        $options_numofreviewes = array(0=>0,1=>1, 2=>2, 3=>2, 4=>4);
+        $options_numper = array(WORKSHOP_USERTYPE_AUTHOR    => get_string('numperauthor', 'workshop'),
+                                WORKSHOP_USERTYPE_REVIEWER  => get_string('numperreviewer', 'workshop'));
+        $grpnumofreviews = array();
+        $grpnumofreviews[] =& $mform->createElement('select', 'numofreviews', '', $options_numofreviewes);
+        $mform->setDefault('numofreviews', 0);
+        $grpnumofreviews[] =& $mform->createElement('select', 'numper', '', $options_numper);
+        $mform->setDefault('numper', WORKSHOP_USERTYPE_AUTHOR);
+        $mform->addGroup($grpnumofreviews, 'grpnumofreviews', get_string('numofreviews', 'workshop'), array(' '), false);
+
+        $mform->addElement('advcheckbox', 'removecurrent', get_string('removecurrentallocations', 'workshop'));
+        $mform->setDefault('removecurrent', 0);
+
+        $mform->addElement('advcheckbox', 'assesswosubmission', get_string('assesswosubmission', 'workshop'));
+        $mform->setDefault('assesswosubmission', 0);
+
+        $mform->addElement('advcheckbox', 'addselfassessment', get_string('addselfassessment', 'workshop'));
+        $mform->setDefault('addselfassessment', 0);
+
+        $this->add_action_buttons();
+    }
+}
diff --git a/mod/workshop/allocation/random/simpletest/testallocator.php b/mod/workshop/allocation/random/simpletest/testallocator.php
new file mode 100644 (file)
index 0000000..50c1dbc
--- /dev/null
@@ -0,0 +1,181 @@
+<?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/>.
+
+/**
+ * Unit tests for mod/workshop/allocation/random/allocator.php
+ *
+ * @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();
+
+// Include the code to test
+require_once($CFG->dirroot . '/mod/workshop/allocation/random/allocator.php');
+
+/**
+ * Make protected methods we want to test public
+ */
+class testable_workshop_random_allocator extends workshop_random_allocator {
+    public function self_allocation($authors=array(), $reviewers=array(), $assessments=array()) {
+        return parent::self_allocation($authors, $reviewers, $assessments);
+    }
+    public function get_author_ids($newallocations) {
+        return parent::get_author_ids($newallocations);
+    }
+    public function index_submissions_by_authors($submissions) {
+        return parent::index_submissions_by_authors($submissions);
+    }
+    public function get_unique_allocations($newallocations) {
+        return parent::get_unique_allocations($newallocations);
+    }
+    public function get_unkept_assessments($assessments, $newallocations, $keepselfassessments) {
+        return parent::get_unkept_assessments($assessments, $newallocations, $keepselfassessments);
+    }
+}
+
+class workshop_allocation_random_test extends UnitTestCase {
+
+    /** workshop instance emulation */
+    protected $workshop;
+
+    /** allocator instance */
+    protected $allocator;
+
+    public function setUp() {
+        $this->workshop     = new workshop((object)array('id' => 42), new stdClass());
+        $this->allocator    = new testable_workshop_random_allocator($this->workshop);
+    }
+
+    public function tearDown() {
+        $this->allocator    = null;
+        $this->workshop     = null;
+    }
+
+    public function test_self_allocation_empty_values() {
+        // fixture setup & exercise SUT & verify
+        $this->assertEqual(array(), $this->allocator->self_allocation());
+    }
+
+    public function test_self_allocation_equal_user_groups() {
+        // fixture setup
+        $authors    = array(0 => array_fill_keys(array(4, 6, 10), new stdClass()));
+        $reviewers  = array(0 => array_fill_keys(array(4, 6, 10), new stdClass()));
+        // exercise SUT
+        $newallocations = $this->allocator->self_allocation($authors, $reviewers);
+        // verify
+        $this->assertEqual(array(array(4 => 4), array(6 => 6), array(10 => 10)), $newallocations);
+    }
+
+    public function test_self_allocation_different_user_groups() {
+        // fixture setup
+        $authors    = array(0 => array_fill_keys(array(1, 4, 5, 10, 13), new stdClass()));
+        $reviewers  = array(0 => array_fill_keys(array(4, 7, 10), new stdClass()));
+        // exercise SUT
+        $newallocations = $this->allocator->self_allocation($authors, $reviewers);
+        // verify
+        $this->assertEqual(array(array(4 => 4), array(10 => 10)), $newallocations);
+    }
+
+    public function test_self_allocation_skip_existing() {
+        // fixture setup
+        $authors        = array(0 => array_fill_keys(array(3, 4, 10), new stdClass()));
+        $reviewers      = array(0 => array_fill_keys(array(3, 4, 10), new stdClass()));
+        $assessments    = array(23 => (object)array('authorid' => 3, 'reviewerid' => 3));
+        // exercise SUT
+        $newallocations = $this->allocator->self_allocation($authors, $reviewers, $assessments);
+        // verify
+        $this->assertEqual(array(array(4 => 4), array(10 => 10)), $newallocations);
+    }
+
+    public function test_get_author_ids() {
+        // fixture setup
+        $newallocations = array(array(1 => 3), array(2 => 1), array(3 => 1));
+        // exercise SUT & verify
+        $this->assertEqual(array(3, 1), $this->allocator->get_author_ids($newallocations));
+    }
+
+    public function test_index_submissions_by_authors() {
+        // fixture setup
+        $submissions = array(
+                676 => (object)array('id' => 676, 'userid' => 23),
+                121 => (object)array('id' => 121, 'userid' => 56),
+                );
+        // exercise SUT
+        $submissions = $this->allocator->index_submissions_by_authors($submissions);
+        // verify
+        $this->assertEqual(array(
+                23 => (object)array('id' => 676, 'userid' => 23),
+                56 => (object)array('id' => 121, 'userid' => 56),
+                ), $submissions);
+    }
+
+    public function test_index_submissions_by_authors_duplicate_author() {
+        // fixture setup
+        $submissions = array(
+                14 => (object)array('id' => 676, 'userid' => 3),
+                87 => (object)array('id' => 121, 'userid' => 3),
+                );
+        // set expectation
+        $this->expectException('moodle_workshop_exception');
+        // exercise SUT
+        $submissions = $this->allocator->index_submissions_by_authors($submissions);
+    }
+
+    public function test_get_unique_allocations() {
+        // fixture setup
+        $newallocations = array(array(4 => 5), array(6 => 6), array(1 => 16), array(4 => 5), array(16 => 1));
+        // exercise SUT
+        $newallocations = $this->allocator->get_unique_allocations($newallocations);
+        // verify
+        $this->assertEqual(array(array(4 => 5), array(6 => 6), array(1 => 16), array(16 => 1)), $newallocations);
+    }
+
+    public function test_get_unkept_assessments_no_keep_selfassessments() {
+        // fixture setup
+        $assessments = array(
+                23 => (object)array('authorid' => 3, 'reviewerid' => 3),
+                45 => (object)array('authorid' => 5, 'reviewerid' => 11),
+                12 => (object)array('authorid' => 6, 'reviewerid' => 3),
+                );
+        $newallocations = array(array(4 => 5), array(11 => 5), array(1 => 16), array(4 => 5), array(16 => 1));
+        // exercise SUT
+        $delassessments = $this->allocator->get_unkept_assessments($assessments, $newallocations, false);
+        // verify
+        // we want to keep $assessments[45] because it has been re-allocated
+        $this->assertEqual(array(23, 12), $delassessments);
+    }
+
+    public function test_get_unkept_assessments_keep_selfassessments() {
+        // fixture setup
+        $assessments = array(
+                23 => (object)array('authorid' => 3, 'reviewerid' => 3),
+                45 => (object)array('authorid' => 5, 'reviewerid' => 11),
+                12 => (object)array('authorid' => 6, 'reviewerid' => 3),
+                );
+        $newallocations = array(array(4 => 5), array(11 => 5), array(1 => 16), array(4 => 5), array(16 => 1));
+        // exercise SUT
+        $delassessments = $this->allocator->get_unkept_assessments($assessments, $newallocations, true);
+        // verify
+        // we want to keep $assessments[45] because it has been re-allocated
+        // we want to keep $assessments[23] because if is self assessment
+        $this->assertEqual(array(12), $delassessments);
+    }
+
+
+}
index 9b926434c31389f3332a721bab17da00efb6df1a..7968eec80f02de816eaed91fb79ceddc743ec221 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * Assess a submission or preview the assessment form
  *
@@ -57,10 +56,10 @@ if ($preview = optional_param('preview', 0, PARAM_INT)) {
     }
     if (!$cm = get_coursemodule_from_instance('workshop', $workshop->id, $workshop->course)) {
         print_error('invalidcoursemodule');
-    }   
+    }
     if (!$course = $DB->get_record('course', array('id' => $cm->course))) {
         print_error('coursemisconf');
-    }   
+    }
 }
 
 require_login($course, false, $cm);
@@ -93,8 +92,6 @@ $strategy = $workshop->grading_strategy_instance();
 
 //todo $formdata = $strategy->load_assessment($assessment);
 
-
-
 // load the form to edit the grading strategy dimensions
 $mform = $strategy->get_assessment_form($selfurl, $mode);
 
@@ -118,21 +115,21 @@ if ($mform->is_cancelled()) {
 
 // build the navigation and the header
 $navlinks = array();
-$navlinks[] = array('name' => get_string('modulenameplural', 'workshop'), 
-                    'link' => "index.php?id=$course->id", 
+$navlinks[] = array('name' => get_string('modulenameplural', 'workshop'),
+                    'link' => "index.php?id=$course->id",
                     'type' => 'activity');
-$navlinks[] = array('name' => format_string($workshop->name), 
+$navlinks[] = array('name' => format_string($workshop->name),
                     'link' => "view.php?id=$cm->id",
                     'type' => 'activityinstance');
 if ($mode == 'preview') {
-    $navlinks[] = array('name' => get_string('editingassessmentform', 'workshop'),       
+    $navlinks[] = array('name' => get_string('editingassessmentform', 'workshop'),
                         'link' => $editurl,
                         'type' => 'title');
-    $navlinks[] = array('name' => get_string('previewassessmentform', 'workshop'), 
+    $navlinks[] = array('name' => get_string('previewassessmentform', 'workshop'),
                         'link' => '',
                         'type' => 'title');
 } elseif ($mode == 'assessment') {
-    $navlinks[] = array('name' => get_string('assessingsubmission', 'workshop'), 
+    $navlinks[] = array('name' => get_string('assessingsubmission', 'workshop'),
                         'link' => '',
                         'type' => 'title');
 }
index 1adddd0e82c98bdd6433e702cafe3dc800019d5b..13caa3a70ab82495ff26bb1da80daea8ab32fd61 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
-// This file is part of Moodle - http://moodle.org/  
-// 
+// 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
 // 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/>.
 
-
 /**
  * Capability definitions for the workshop module
  *
@@ -192,5 +191,5 @@ $mod_workshop_capabilities = array(
             'admin' => CAP_ALLOW
         )
     ),
-    
+
 );
index 87b9030b8c03471d7cc9b6ca5a70f756810aeca7..eabdbe9ade4a1d896ced4cbc5f9b249aa60003ca 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * Edit grading form in for a particular instance of workshop
  *
@@ -28,14 +27,14 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
 require_once(dirname(__FILE__).'/locallib.php');
 
 $cmid = required_param('cmid', PARAM_INT);            // course module id
-        
+
 if (!$cm = get_coursemodule_from_id('workshop', $cmid)) {
     print_error('invalidcoursemodule');
-}   
-        
+}
+
 if (!$course = $DB->get_record('course', array('id' => $cm->course))) {
     print_error('coursemisconf');
-}   
+}
 
 require_login($course, false, $cm);
 
@@ -88,13 +87,13 @@ if ($mform->is_cancelled()) {
 
 // build the navigation and the header
 $navlinks = array();
-$navlinks[] = array('name' => get_string('modulenameplural', 'workshop'), 
-                    'link' => "index.php?id=$course->id", 
+$navlinks[] = array('name' => get_string('modulenameplural', 'workshop'),
+                    'link' => "index.php?id=$course->id",
                     'type' => 'activity');
-$navlinks[] = array('name' => format_string($workshop->name), 
+$navlinks[] = array('name' => format_string($workshop->name),
                     'link' => "view.php?id=$cm->id",
                     'type' => 'activityinstance');
-$navlinks[] = array('name' => get_string('editingassessmentform', 'workshop'), 
+$navlinks[] = array('name' => get_string('editingassessmentform', 'workshop'),
                     'link' => '',
                     'type' => 'title');
 $navigation = build_navigation($navlinks);
index f4b10bd21b015c0b63c0b57d6507820e1a74d8e9..ea36b5bb443981d28bf621055cce5ba92d137ac7 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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 an mform to assess a submission by accumulative grading strategy
  *
@@ -29,7 +28,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
 
-
 /**
  * Class representing a form for assessing submissions by accumulative grading strategy
  *
@@ -38,10 +36,10 @@ require_once(dirname(dirname(__FILE__)).'/assessment_form.php');    // parent cl
 class workshop_accumulative_assessment_form extends workshop_assessment_form {
 
     /**
-     * Define the elements to be displayed at the form 
+     * Define the elements to be displayed at the form
      *
      * Called by the parent::definition()
-     * 
+     *
      * @access protected
      * @return void
      */
@@ -72,5 +70,4 @@ class workshop_accumulative_assessment_form extends workshop_assessment_form {
 
     }
 
-
 }
index 71f8d19c8b28d6f87eb0f616ee5aa7280e0ea677..d530b66ac1deb691d48437948eb0d65b0c465574 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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 an mform to edit accumulative grading strategy forms.
  *
@@ -29,7 +28,6 @@ defined('MOODLE_INTERNAL') || die();
 require_once(dirname(dirname(dirname(__FILE__))).'/lib.php');   // module library
 require_once(dirname(dirname(__FILE__)).'/edit_form.php');    // parent class definition
 
-
 /**
  * Class for editing accumulative grading strategy forms.
  *
@@ -38,10 +36,10 @@ require_once(dirname(dirname(__FILE__)).'/edit_form.php');    // parent class de
 class workshop_edit_accumulative_strategy_form extends workshop_edit_strategy_form {
 
     /**
-     * Define the elements to be displayed at the form 
+     * Define the elements to be displayed at the form
      *
      * Called by the parent::definition()
-     * 
+     *
      * @access protected
      * @return void
      */
@@ -52,16 +50,16 @@ class workshop_edit_accumulative_strategy_form extends workshop_edit_strategy_fo
 
         $repeated = array();
         $repeated[] =& $mform->createElement('hidden', 'dimensionid', 0);
-        $repeated[] =& $mform->createElement('header', 'dimension', 
+        $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);
-        
+
         $repeatedoptions = array();
         $repeatedoptions['description']['type'] = PARAM_CLEANHTML;
-        $repeatedoptions['description']['helpbutton'] = array('dimensiondescription', 
+        $repeatedoptions['description']['helpbutton'] = array('dimensiondescription',
                                                             get_string('dimensiondescription', 'workshop'), 'workshop');
         $repeatedoptions['grade']['default'] = 10;
         $repeatedoptions['weight']['default'] = 1;
@@ -72,5 +70,4 @@ class workshop_edit_accumulative_strategy_form extends workshop_edit_strategy_fo
         $this->repeat_elements($repeated, $numofdisplaydimensions,  $repeatedoptions, 'numofdimensions', 'adddimensions', $numofdimensionstoadd, get_string('addmoredimensionsaccumulative', 'workshop', $numofdimensionstoadd));
     }
 
-
 }
index 180f7041151c01c005138b97328bb056868ceafe..ff0b353b0636e59cc261654eb6791b8199956643 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * Unit tests for (some of) mod/workshop/grading/accumulative/strategy.php
  *
@@ -29,7 +28,6 @@ defined('MOODLE_INTERNAL') || die();
 // Include the code to test
 require_once($CFG->dirroot . '/mod/workshop/grading/accumulative/strategy.php');
 
-
 /**
  * Test subclass that makes all the protected methods we want to test public
  */
@@ -45,7 +43,6 @@ class testable_workshop_accumulative_strategy extends workshop_accumulative_stra
 
 }
 
-
 class workshop_accumulative_strategy_test extends UnitTestCase {
 
     /** workshop instance emulation */
@@ -62,7 +59,7 @@ 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';
@@ -103,16 +100,14 @@ class workshop_accumulative_strategy_test extends UnitTestCase {
 
     }
 
-
     public function tearDown() {
         $this->strategy = null;
         $this->rawform  = null;
         $this->rawdb    = null;
     }
 
-    
     public function test_cook_dimension_records() {
-        
+
         $cooked = $this->strategy->_cook_dimension_records($this->rawdb);
         $this->assertIsA($cooked, 'stdClass');
         $cooked = (array)$cooked;
@@ -130,7 +125,6 @@ class workshop_accumulative_strategy_test extends UnitTestCase {
         $this->assertEqual($cooked['weight[1]'], 1);
     }
 
-    
     public function test_cook_form_data() {
 
         $cooked = $this->strategy->_cook_form_data($this->rawform);
@@ -163,5 +157,5 @@ class workshop_accumulative_strategy_test extends UnitTestCase {
                             'weight'            => 1,
                             ));
     }
-    
+
 }
index 3c1ac32eae7131d04d64c1d4ac23797cc67f0ab8..2aa4fbf2748eb108fb57c693c9143f07e36d96d4 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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 class with accumulative grading strategy logic
  *
@@ -28,7 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 
 require_once(dirname(dirname(__FILE__)) . '/strategy.php'); // parent class
 
-
 /**
  * Accumulative grading strategy logic.
  */
@@ -42,13 +40,12 @@ class workshop_accumulative_strategy extends workshop_base_strategy {
         return $this->_cook_dimension_records($dims);
     }
 
-
     /**
      * Transpones the dimension data from DB so the assessment form editor can be populated by set_data
      *
      * Called internally from load_form(). Could be private but keeping protected
      * for unit testing purposes.
-     * 
+     *
      * @param array $raw Array of raw dimension records as fetched by get_record()
      * @return array Array of fields data to be used by the mform set_data
      */
@@ -67,7 +64,6 @@ class workshop_accumulative_strategy extends workshop_base_strategy {
         return (object)$formdata;
     }
 
-
     /**
      * Save the assessment dimensions into database
      *
@@ -110,15 +106,14 @@ class workshop_accumulative_strategy extends workshop_base_strategy {
         $DB->delete_records_list('workshop_forms_' . $this->name, 'id', $todelete);
     }
 
-
     /**
      * Prepares data returned by mform so they can be saved into database
      *
-     * It automatically adds some columns into every record. The sorting is 
+     * 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
      * 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
      */
@@ -139,5 +134,4 @@ class workshop_accumulative_strategy extends workshop_base_strategy {
         return $cook;
     }
 
-
 }
index bedb1d47384b5b6a89e82adfa8c6e0fbc97400ee..0599923fb5d4ec6a2f9547bb62c7a9bc6118b78c 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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 assessment forms
  *
@@ -28,19 +27,18 @@ defined('MOODLE_INTERNAL') || die();
 
 require_once($CFG->libdir . '/formslib.php'); // parent class definition
 
-
 /**
  * Base class for all assessment forms
  *
- * This defines the common fields that all assessment forms need. 
- * Strategies should define their own class that inherits from this one, and 
+ * This defines the common fields that all assessment forms need.
+ * Strategies should define their own class that inherits from this one, and
  * implements the definition_inner() method.
- * 
+ *
  * @uses moodleform
  */
 class workshop_assessment_form extends moodleform {
 
-    /** object Strategy logic instance */ 
+    /** object Strategy logic instance */
     protected $strategy;
 
     /** array Assessment form fields defined by teacher */
@@ -52,11 +50,11 @@ class workshop_assessment_form extends moodleform {
     /**
      * Add the fields that are common for all grading strategies.
      *
-     * If the strategy does not support all these fields, then you can override 
-     * this method and remove the ones you don't want with 
+     * If the strategy does not support all these fields, then you can override
+     * this method and remove the ones you don't want with
      * $mform->removeElement().
      * Strategy subclassess should define their own fields in definition_inner()
-     * 
+     *
      * @access public
      * @return void
      */
@@ -85,7 +83,6 @@ class workshop_assessment_form extends moodleform {
         $mform->closeHeaderBefore('buttonar');
     }
 
-
     /**
      * Add any strategy specific form fields.
      *
index ac5ebabfdfb25dde50e0f7d94a6020b5ca8961d7..57f6fae6f6785e1a17c1654648102af769d6c1b6 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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 editing forms.
  *
@@ -28,29 +27,28 @@ defined('MOODLE_INTERNAL') || die();
 
 require_once($CFG->libdir . '/formslib.php'); // parent class definition
 
-
 /**
  * Base class for editing all the strategy grading forms.
  *
- * This defines the common fields that all strategy grading forms need. 
- * Strategies should define their own  class that inherits from this one, and 
+ * This defines the common fields that all strategy grading forms need.
+ * Strategies should define their own  class that inherits from this one, and
  * implements the definition_inner() method.
- * 
+ *
  * @uses moodleform
  */
 class workshop_edit_strategy_form extends moodleform {
 
-    /** strategy logic instance that this class is editor of */ 
+    /** strategy logic instance that this class is editor of */
     protected $strategy;
 
     /**
      * Add the fields that are common for all grading strategies.
      *
-     * If the strategy does not support all these fields, then you can override 
-     * this method and remove the ones you don't want with 
+     * If the strategy does not support all these fields, then you can override
+     * this method and remove the ones you don't want with
      * $mform->removeElement().
      * Stretegy subclassess should define their own fields in definition_inner()
-     * 
+     *
      * @access public
      * @return void
      */
@@ -78,7 +76,6 @@ class workshop_edit_strategy_form extends moodleform {
         $mform->closeHeaderBefore('buttonar');
     }
 
-
     /**
      * Add any strategy specific form fields.
      *
index cc7403444fdaaa9874eb1797675aadc0fc9a0462..b3634ba598794c941a4cb871e481a170f5a7aa92 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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 an mform to edit "Number of errors" grading strategy forms.
  *
@@ -29,7 +28,6 @@ defined('MOODLE_INTERNAL') || die();
 require_once(dirname(dirname(dirname(__FILE__))).'/lib.php');   // module library
 require_once(dirname(dirname(__FILE__)).'/edit_form.php');    // parent class definition
 
-
 /**
  * Class for editing "Number of errors" grading strategy forms.
  *
@@ -38,10 +36,10 @@ require_once(dirname(dirname(__FILE__)).'/edit_form.php');    // parent class de
 class workshop_edit_noerrors_strategy_form extends workshop_edit_strategy_form {
 
     /**
-     * Define the elements to be displayed at the form 
+     * Define the elements to be displayed at the form
      *
      * Called by the parent::definition()
-     * 
+     *
      * @access protected
      * @return void
      */
@@ -52,17 +50,17 @@ class workshop_edit_noerrors_strategy_form extends workshop_edit_strategy_form {
 
         $repeated = array();
         $repeated[] =& $mform->createElement('hidden', 'dimensionid', 0);
-        $repeated[] =& $mform->createElement('header', 'dimension', 
+        $repeated[] =& $mform->createElement('header', 'dimension',
                                                 get_string('dimensionnumbernoerrors', 'workshop', '{no}'));
         $repeated[] =& $mform->createElement('htmleditor', 'description',
                                                 get_string('dimensiondescription', 'workshop'), array());
         $repeated[] =& $mform->createElement('text', 'grade0', get_string('noerrorsgrade0', 'workshop'), array('size'=>'15'));
         $repeated[] =& $mform->createElement('text', 'grade1', get_string('noerrorsgrade1', 'workshop'), array('size'=>'15'));
         $repeated[] =& $mform->createElement('select', 'weight', get_string('dimensionweight', 'workshop'), $weights);
-        
+
         $repeatedoptions = array();
         $repeatedoptions['description']['type'] = PARAM_CLEANHTML;
-        $repeatedoptions['description']['helpbutton'] = array('dimensiondescription', 
+        $repeatedoptions['description']['helpbutton'] = array('dimensiondescription',
                                                             get_string('dimensiondescription', 'workshop'), 'workshop');
         $repeatedoptions['grade0']['type'] = PARAM_TEXT;
         $repeatedoptions['grade0']['default'] = $workshopconfig->noerrorsgrade0;
@@ -72,25 +70,25 @@ class workshop_edit_noerrors_strategy_form extends workshop_edit_strategy_form {
 
         $numofdimensionstoadd   = 2;
         $numofinitialdimensions = 3;
-        $numofdisplaydimensions = max($this->strategy->get_number_of_dimensions() + $numofdimensionstoadd, 
+        $numofdisplaydimensions = max($this->strategy->get_number_of_dimensions() + $numofdimensionstoadd,
                                                                                             $numofinitialdimensions);
-        $numofdisplaydimensions = $this->repeat_elements($repeated, $numofdisplaydimensions,  $repeatedoptions, 
+        $numofdisplaydimensions = $this->repeat_elements($repeated, $numofdisplaydimensions,  $repeatedoptions,
                                                     'numofdimensions', 'adddimensions', $numofdimensionstoadd,
-                                                    get_string('addmoredimensionsnoerrors', 'workshop', $numofdimensionstoadd)); 
+                                                    get_string('addmoredimensionsnoerrors', 'workshop', $numofdimensionstoadd));
         $mform->addElement('header', 'mappingheader', get_string('noerrorsgrademapping', 'workshop'));
-        $mform->addElement('static', 'mappinginfo', get_string('noerrorsmaperror', 'workshop'), 
+        $mform->addElement('static', 'mappinginfo', get_string('noerrorsmaperror', 'workshop'),
                                                             get_string('noerrorsmapgrade', 'workshop'));
         $percents = array();
         $percents[''] = '';
         for ($i = 100; $i >= 0; $i--) {
             $percents[$i] = get_string('percents', 'workshop', $i);
         }
-        $mform->addElement('static', 'mappingzero', 0, get_string('percents', 'workshop', 100)); 
+        $mform->addElement('static', 'mappingzero', 0, get_string('percents', 'workshop', 100));
         $mform->addElement('hidden', 'map[0]', 100);
         for ($i = 1; $i <= $numofdisplaydimensions; $i++) {
             $selects = array();
             $selects[] =& $mform->createElement('select', "map[$i]", $i, $percents);
-            $selects[] =& $mform->createElement('static', "mapdefault[$i]", '', 
+            $selects[] =& $mform->createElement('static', "mapdefault[$i]", '',
                                         get_string('percents', 'workshop', floor(100 - $i * 100 / $numofdisplaydimensions)));
             $mform->addGroup($selects, "grademapping$i", $i, array(' '), false);
             $mform->setDefault("map[$i]", '');
@@ -98,5 +96,4 @@ class workshop_edit_noerrors_strategy_form extends workshop_edit_strategy_form {
 
     }
 
-
 }
index 0243f9e91cf70267cf4dc94dfb677de673f56c01..149e2a2b5edf79312c404857770302ecd468151a 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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 class with "Number of errors" grading strategy logic
  *
@@ -28,7 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 
 require_once(dirname(dirname(__FILE__)) . '/strategy.php'); // parent class
 
-
 /**
  * "Number of errors" grading strategy logic.
  */
@@ -43,15 +41,14 @@ class workshop_noerrors_strategy extends workshop_base_strategy {
         return $this->_cook_database_records($dims, $maps);
     }
 
-
     /**
      * Transpones the dimension data from DB so the assessment form editor can be populated by set_data
      *
      * Called internally from load_form(). Could be private but keeping protected
      * for unit testing purposes.
-     * 
+     *
      * @param array $dims Array of raw dimension records as fetched by get_record()
-     * @param array $maps Array of grade mappings 
+     * @param array $maps Array of grade mappings
      * @return array Object to be used by the mform set_data
      */
     protected function _cook_database_records(array $dims, array $maps) {
@@ -78,7 +75,6 @@ class workshop_noerrors_strategy extends workshop_base_strategy {
         return (object)$formdata;
     }
 
-
     /**
      * Save the definition of a "Number of errors" grading form
      *
@@ -127,7 +123,7 @@ class workshop_noerrors_strategy extends workshop_base_strategy {
         }
         unset($currentx);
         $todelete = array();
-        
+
         foreach ($data->map as $nonegative => $grade) {
             if ($nonegative == 0) {
                 // no negative response automatically maps to 100%, do not save such mapping
@@ -153,7 +149,7 @@ class workshop_noerrors_strategy extends workshop_base_strategy {
         } else {
             list($insql, $params) = array('', array());
         }
-        $sql = 'DELETE FROM {workshop_forms_noerrors_map} 
+        $sql = 'DELETE FROM {workshop_forms_noerrors_map}
                 WHERE ((' . $insql . 'nonegative > ?) AND (workshopid = ?))';
         $params[] = count($data->map) - 1;
         $params[] = $this->workshop->id;
@@ -162,15 +158,14 @@ class workshop_noerrors_strategy extends workshop_base_strategy {
         }
     }
 
-
     /**
      * Prepares dimensions data returned by mform so they can be saved into database
      *
-     * It automatically adds some columns into every record. The sorting is 
+     * 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
      * 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
      */
@@ -192,5 +187,4 @@ class workshop_noerrors_strategy extends workshop_base_strategy {
         return $cook;
     }
 
-
 }
index 22afba24366889568d353ff1f3bfe83b278a9761..e5f5185912eccb8c8cf04cbdc597ac9536dfb76a 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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
  *
@@ -33,7 +32,7 @@ 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().
@@ -44,11 +43,10 @@ interface workshop_strategy {
      */
     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 
+     *
+     * 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.
@@ -58,11 +56,10 @@ interface workshop_strategy {
      */
     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 
+     * 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.
      *
@@ -72,18 +69,15 @@ interface workshop_strategy {
      */
     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
  *
@@ -102,8 +96,8 @@ abstract class workshop_base_strategy implements workshop_strategy {
     protected $nodimensions;
 
     /**
-     * Constructor 
-     * 
+     * Constructor
+     *
      * @param object $workshop The workshop instance record
      * @access public
      * @return void
@@ -115,7 +109,6 @@ abstract class workshop_base_strategy implements workshop_strategy {
         $this->nodimensions = null;
     }
 
-
     /**
      * Factory method returning an instance of an assessment form editor class
      *
@@ -126,7 +119,7 @@ abstract class workshop_base_strategy implements workshop_strategy {
      */
     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);
@@ -145,10 +138,9 @@ abstract class workshop_base_strategy implements workshop_strategy {
 
     }
 
-
     /**
-     * By default, the number of loaded dimensions is set by load_form() 
-     * 
+     * By default, the number of loaded dimensions is set by load_form()
+     *
      * @access public
      * @return Array of records
      */
@@ -156,7 +148,6 @@ abstract class workshop_base_strategy implements workshop_strategy {
         return $this->nodimensions;
     }
 
-
     /**
      * Factory method returning an instance of an assessment form
      *
@@ -168,7 +159,7 @@ abstract class workshop_base_strategy implements workshop_strategy {
      */
     public function get_assessment_form($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);
@@ -189,5 +180,4 @@ abstract class workshop_base_strategy implements workshop_strategy {
 
     }
 
-
 }
index a4d3ac984c7b3a771f58e3b72ce354796a21284a..c1decbbde70b3055a02644292c1785fb949bf6bc 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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 is a one-line short description of the file
  *
@@ -54,7 +53,7 @@ $navlinks[] = array('name' => get_string('modulenameplural', 'workshop'),
                     'link' => '',
                     'type' => 'activity');
 $navigation = build_navigation($navlinks);
-        
+
 echo $OUTPUT->header($navigation);
 
 /// Get all the appropriate data
index 67c7ee1461cb66a40e844347e3b7f2a86cf1c473..aa94d6f9c4ffef4393080042f47312590219deb8 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
-// This file is part of Moodle - http://moodle.org/  
-// 
+// 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
 // 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/>.
 
-
 /**
  * English strings for Workshop module
  *
@@ -40,18 +39,28 @@ $string[''] = '';
 $string[''] = '';
 $string[''] = '';
 $string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
 $string['accesscontrol'] = 'Access control';
 $string['addmoredimensionsaccumulative'] = 'Blanks for $a more aspects';
 $string['addmoredimensionsnoerrors'] = 'Blanks for $a more assertions';
 $string['addreviewee'] = 'Add reviewee';
 $string['addreviewer'] = 'Add reviewer';
+$string['addselfassessment'] = 'Add self-assessments';
 $string['addsubmissiontoreview'] = 'Assign submission';
 $string['agreeassessments'] = 'Assessments must be agreed';
 $string['agreeassessmentsdesc'] = 'Authors may comment assessments of their work and agree/disagree with it';
+$string['allocationaddeddetail'] = 'New assessment to be done: <strong>$a->reviewername</strong> is reviewer of <strong>$a->authorname</strong>';
 $string['allocationadded'] = 'The submission has been successfully allocated';
+$string['allocationdeallocategraded'] = 'Unable to deallocate already graded assessment: reviewer <strong>$a->reviewername</strong>, submission author: <strong>$a->authorname</strong>';
 $string['allocationexists'] = 'The allocation already exists';
 $string['allocationmanual'] = 'Manual allocation';
 $string['allocationrandom'] = 'Random allocation';
+$string['allocationsettings'] = 'Allocation settings';
 $string['allocation'] = 'Submission allocation';
 $string['allocationview'] = 'View current allocations';
 $string['areyousuretodeallocate'] = 'Are you sure you want deallocate the selected assessment?';
@@ -59,15 +68,14 @@ $string['areyousuretodeallocategraded'] = 'You are going to remove the assessmen
 $string['assessallexamples'] = 'Assess all examples';
 $string['assessingsubmission'] = 'Assessing submission';
 $string['assessmentcomps'] = 'Required level of assessments similarity';
-$string['assessmentdeleted'] = 'Submission deallocated and assessment deleted';
+$string['assessmentdeleted'] = 'Assessment deallocated';
+$string['assessmentdeleteddetail'] = 'Assessment deallocated: <strong>$a->reviewername</strong> is no longer reviewer of <strong>$a->authorname</strong>';
 $string['assessmentend'] = 'End of assessment phase';
 $string['assessmentform'] = 'Assessment form';
 $string['assessmentsettings'] = 'Assessment settings';
 $string['assessmentstart'] = 'Start of assessment phase';
-$string['assesswosubmission'] = 'Assess without submission';
-$string['assesswosubmissiondesc'] = 'Users can assess peers even without their own submission';
+$string['assesswosubmission'] = 'Users can assess without their own submission';
 $string['backtoeditform'] = 'Back to editing form';
-$string['cantassesswosubmission'] = 'Users can\'t assess without own submission in this workshop';
 $string['comparisonhigh'] = 'High';
 $string['comparisonlow'] = 'Low';
 $string['comparisonnormal'] = 'Normal';
@@ -109,6 +117,7 @@ $string['modulenameplural'] = 'Workshops';
 $string['modulename'] = 'Workshop';
 $string['nattachments'] = 'Maximum number of submission attachments';
 $string['nexassessments'] = 'Number of required assessments of examples';
+$string['noallocationtoadd'] = 'No allocations to add';
 $string['noerrorsgrademapping'] = 'Grade mapping table';
 $string['noerrorsgrade0default'] = 'No';
 $string['noerrorsgrade0'] = 'Word for the error';
@@ -121,12 +130,19 @@ $string['nosubmissionfound'] = 'No submission found for this user';
 $string['nosubmissions'] = 'No submissions yet in this workshop';
 $string['nothingtoreview'] = 'Nothing to review';
 $string['nsassessments'] = 'Number of required assessments of other users\' work';
+$string['numofdeallocatedassessment'] = 'Deallocating $a assessment(s)';
+$string['numofreviews'] = 'Number of reviews';
+$string['numofselfallocatedsubmissions'] = 'Self-allocating $a submission(s)';
+$string['numperauthor'] = 'per submission';
+$string['numperreviewer'] = 'per reviewer';
 $string['participant'] = 'Participant';
 $string['participantrevierof'] = 'Participant is reviewer of';
 $string['participantreviewedby'] = 'Participant is reviewed by';
 $string['percents'] = '$a%';
 $string['previewassessmentform'] = 'Preview';
+$string['randomallocationdone'] = 'Random allocation done';
 $string['releasegrades'] = 'Push final grades into the gradebook';
+$string['removecurrentallocations'] = 'Remove current allocations';
 $string['requirepassword'] = 'Require password';
 $string['saveandclose'] = 'Save and close';
 $string['saveandcontinue'] = 'Save and continue editing';
@@ -150,5 +166,6 @@ $string['usepeerassessmentdesc'] = 'Users perform peer assessment of others\' wo
 $string['usepeerassessment'] = 'Use peer assessment';
 $string['useselfassessmentdesc'] = 'Users perform self assessment of their own work';
 $string['useselfassessment'] = 'Use self assessment';
+$string['withoutsubmission'] = 'Warning - reviewer without own submission';
 $string['workshopfeatures'] = 'Workshop features';
 $string['workshopname'] = 'Workshop name';
index 73b6aac4f8b28bc2644864be56b13ff0366cb262..3b719c258b2927928b8f40aec598dca7bdd2fae3 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * Library of interface functions and constants for module workshop
  *
- * All the core Moodle functions, neeeded to allow the module to work 
+ * All the core Moodle functions, neeeded to allow the module to work
  * integrated in Moodle should be placed here.
- * All the workshop specific functions, needed to implement all the module 
- * logic, should go to locallib.php. This will help to save some memory when 
+ * All the workshop specific functions, needed to implement all the module
+ * logic, should go to locallib.php. This will help to save some memory when
  * Moodle is performing actions across all modules.
  *
  * @package   mod-workshop
@@ -39,7 +38,6 @@ define('WORKSHOP_EXAMPLES_VOLUNTARY',           0);
 define('WORKSHOP_EXAMPLES_BEFORE_SUBMISSION',   1);
 define('WORKSHOP_EXAMPLES_BEFORE_ASSESSMENT',   2);
 
-
 /**
  * The internal codes of the required level of assessment similarity
  */
@@ -49,7 +47,6 @@ define('WORKSHOP_COMPARISON_NORMAL',    2);     /* f = 2.50 */
 define('WORKSHOP_COMPARISON_HIGH',      3);     /* f = 3.00 */
 define('WORKSHOP_COMPARISON_VERYHIGH',  4);     /* f = 5.00 */
 
-
 /**
  * The base class of workshop instances
  *
@@ -83,7 +80,6 @@ class workshop {
         $this->cm = $cm;
     }
 
-
     /**
      * Saves a new instance of the workshop into the database
      *
@@ -105,7 +101,6 @@ class workshop {
     }
 }
 
-
 /**
  * Given an object containing all the necessary data,
  * (defined by the form in mod_form.php) this function
@@ -119,7 +114,6 @@ function workshop_add_instance($data) {
     return workshop::add_instance($data);
 }
 
-
 /**
  * Given an object containing all the necessary data,
  * (defined by the form in mod_form.php) this function
@@ -137,7 +131,6 @@ function workshop_update_instance($workshop) {
     return $DB->update_record('workshop', $workshop);
 }
 
-
 /**
  * Given an ID of an instance of this module,
  * this function will permanently delete the instance
@@ -164,7 +157,6 @@ function workshop_delete_instance($id) {
     return $result;
 }
 
-
 /**
  * Return a small object with summary information about what a
  * user has done with a given particular instance of this module
@@ -182,7 +174,6 @@ function workshop_user_outline($course, $user, $mod, $workshop) {
     return $return;
 }
 
-
 /**
  * Print a detailed representation of what a user has done with
  * a given particular instance of this module, for user activity reports.
@@ -194,7 +185,6 @@ function workshop_user_complete($course, $user, $mod, $workshop) {
     return true;
 }
 
-
 /**
  * Given a course and a time, this module should find recent activity
  * that has occurred in workshop activities and print it out.
@@ -207,7 +197,6 @@ function workshop_print_recent_activity($course, $isteacher, $timestart) {
     return false;  //  True if anything was printed, otherwise false
 }
 
-
 /**
  * Function to be run periodically according to the moodle cron
  * This function searches for things that need to be done, such
@@ -220,7 +209,6 @@ function workshop_cron () {
     return true;
 }
 
-
 /**
  * Must return an array of user records (all data) who are participants
  * for a given instance of workshop. Must include every user involved
@@ -234,7 +222,6 @@ function workshop_get_participants($workshopid) {
     return false;
 }
 
-
 /**
  * This function returns if a scale is being used by one workshop
  * if it has support for grading and scales. Commented code should be
@@ -257,7 +244,6 @@ function workshop_scale_used($workshopid, $scaleid) {
     return $return;
 }
 
-
 /**
  * Checks if scale is being used by any instance of workshop.
  * This function was added in 1.9
@@ -274,7 +260,6 @@ function workshop_scale_used_anywhere($scaleid) {
     }
 }
 
-
 /**
  * Execute post-install custom actions for the module
  * This function was added in 1.9
@@ -285,7 +270,6 @@ function workshop_install() {
     return true;
 }
 
-
 /**
  * Execute post-uninstall custom actions for the module
  * This function was added in 1.9
@@ -296,6 +280,25 @@ function workshop_uninstall() {
     return true;
 }
 
+/**
+ * Returns the information if the module supports a feature
+ *
+ * @see plugin_supports() in lib/moodlelib.php
+ * @todo review and add features
+ * @param string $feature FEATURE_xx constant for requested feature
+ * @return mixed true if the feature is supported, null if unknown
+ */
+function workshop_supports($feature) {
+    switch($feature) {
+        case FEATURE_GROUPS:            return true;
+        case FEATURE_GROUPINGS:         return true;
+        case FEATURE_GROUPMEMBERSONLY:  return true;
+        case FEATURE_MOD_INTRO:         return true;
+        case FEATURE_GRADE_HAS_GRADE:   return true;
+        default:                        return null;
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Other functions needed by Moodle core follows. They can't be put into      //
 // locallib.php because they are used by some core scripts (like modedit.php) //
@@ -305,10 +308,10 @@ function workshop_uninstall() {
 /**
  * Return an array of numeric values that can be used as maximum grades
  *
- * Used at several places where maximum grade for submission and grade for 
+ * Used at several places where maximum grade for submission and grade for
  * 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
  */
@@ -321,7 +324,6 @@ function workshop_get_maxgrades() {
     return $grades;
 }
 
-
 /**
  * Return an array of possible numbers of assessments to be done
  *
@@ -341,10 +343,9 @@ function workshop_get_numbers_of_assessments() {
     return $options;
 }
 
-
 /**
  * Return an array of possible values for weight of teacher assessment
- * 
+ *
  * @return array Array of integers 0, 1, 2, ..., 10
  */
 function workshop_get_teacher_weights() {
@@ -356,10 +357,9 @@ function workshop_get_teacher_weights() {
     return $weights;
 }
 
-
 /**
  * Return an array of possible values of assessment dimension weight
- * 
+ *
  * @return array Array of integers 0, 1, 2, ..., 16
  */
 function workshop_get_dimension_weights() {
@@ -371,7 +371,6 @@ function workshop_get_dimension_weights() {
     return $weights;
 }
 
-
 /**
  * Return an array of the localized grading strategy names
  *
@@ -389,7 +388,6 @@ function workshop_get_strategies() {
     return $forms;
 }
 
-
 /**
  * Return an array of available example assessment modes
  *
@@ -405,7 +403,6 @@ function workshop_get_example_modes() {
     return $modes;
 }
 
-
 /**
  * Return array of assessment comparison levels
  *
index 079c9bee7bf46a9b8ea12965ae1652aa3c226063..015fb88bc8b58b64758f3c557cce9bc76c1b6148 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * Library of internal classes and functions for module workshop
  *
- * All the workshop specific functions, needed to implement the module 
+ * 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 
+ * workshop_something() taking the workshop instance as the first
  * parameter, we use a class workshop_api that provides all methods.
- * 
+ *
  * @package   mod-workshop
  * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -34,13 +33,11 @@ defined('MOODLE_INTERNAL') || die();
 require_once(dirname(__FILE__).'/lib.php'); // we extend this library here
 
 define('WORKSHOP_ALLOCATION_EXISTS',        -1);    // return status of {@link add_allocation}
-define('WORKSHOP_ALLOCATION_WOSUBMISSION',  -2);    // return status of {@link add_allocation}
-
 
 /**
  * Full-featured workshop API
  *
- * This extends the module base API and adds the internal methods that are called 
+ * This extends the module base API and adds the internal 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.
  */
@@ -60,17 +57,16 @@ class workshop_api extends workshop {
         parent::__construct($instance, $cm);
     }
 
-
     /**
      * Fetches all users with the capability mod/workshop:submit in the current context
      *
      * Static variables used to cache the results. The returned objects contain id, lastname
      * and firstname properties and are ordered by lastname,firstname
-     * 
-     * @param bool $musthavesubmission If true, returns only users with existing submission. All possible authors otherwise.
-     * @return array Array of '(int)userid => (stdClass)userinfo'
+     *
+     * @param bool $musthavesubmission If true, return only users who have already submitted. All possible authors otherwise.
+     * @return array array[userid] => stdClass{->id ->lastname ->firstname}
      */
-    public function get_peer_authors($musthavesubmission=false) {
+    public function get_peer_authors($musthavesubmission=true) {
         global $DB;
         static $users               = null;
         static $userswithsubmission = null;
@@ -93,42 +89,125 @@ class workshop_api extends workshop {
         }
     }
 
+    /**
+     * Returns all users with the capability mod/workshop:submit sorted by groups
+     *
+     * This takes the module grouping settings into account. If "Available for group members only"
+     * is set, returns only groups withing the course module grouping.
+     *
+     * @param bool $musthavesubmission If true, return only users who have already submitted. All possible authors otherwise.
+     * @return array array[groupid][userid] => stdClass{->id ->lastname ->firstname}
+     */
+    public function get_peer_authors_by_group($musthavesubmission=true) {
+        global $DB;
+
+        $authors    = $this->get_peer_authors($musthavesubmission);
+        $gauthors   = array();  // grouped authors to be returned
+        if ($this->cm->groupmembersonly) {
+            // Available for group members only - the workshop is available only
+            // to users assigned to groups within the selected grouping, or to
+            // any group if no grouping is selected.
+            $groupingid = $this->cm->groupingid;
+            // All authors that are members of at least one group will be
+            // added into a virtual group id 0
+            $gauthors[0] = array();
+        } else {
+            $groupingid = 0;
+            // there is no need to be member of a group so $gauthors[0] will contain
+            // all authors with a submission
+            $gauthors[0] = $authors;
+        }
+        $gmemberships = groups_get_all_groups($this->cm->course, array_keys($authors), $groupingid,
+                            'gm.id,gm.groupid,gm.userid');
+        foreach ($gmemberships as $gmembership) {
+            if (!isset($gauthors[$gmembership->groupid])) {
+                $gauthors[$gmembership->groupid] = array();
+            }
+            $gauthors[$gmembership->groupid][$gmembership->userid]  = $authors[$gmembership->userid];
+            $gauthors[0][$gmembership->userid]                      = $authors[$gmembership->userid];
+        }
+        return $gauthors;
+    }
 
     /**
      * Fetches all users with the capability mod/workshop:peerassess in the current context
      *
      * Static variable used to cache the results. The returned objects contain id, lastname
      * and firstname properties and are ordered by lastname,firstname
-     * 
-     * @param object $context The context instance where the capability should be checked
-     * @return array Array of '(int)userid => (stdClass)userinfo'
+     *
+     * @param bool $musthavesubmission If true, return only users who have already submitted. All possible users otherwise.
+     * @return array array[userid] => stdClass{->id ->lastname ->firstname}
      */
-    public function get_peer_reviewers() {
+    public function get_peer_reviewers($musthavesubmission=false) {
         global $DB;
-        static $users=null;
+        static $users               = null;
+        static $userswithsubmission = null;
 
         if (is_null($users)) {
             $context = get_context_instance(CONTEXT_MODULE, $this->cm->id);
             $users = get_users_by_capability($context, 'mod/workshop:peerassess',
                         'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true);
-            if (!$this->assesswosubmission) {
+            if ($musthavesubmission && is_null($userswithsubmission)) {
                 // users without their own submission can not be reviewers
-                $withsubmission = $DB->get_records_list('workshop_submissions', 'userid', array_keys($users),'', 'userid');
-                $users = array_intersect_key($users, $withsubmission);
+                $userswithsubmission = $DB->get_records_list('workshop_submissions', 'userid', array_keys($users),'', 'userid');
+                $userswithsubmission = array_intersect_key($users, $userswithsubmission);
             }
         }
-        return $users;
+        if ($musthavesubmission) {
+            return $userswithsubmission;
+        } else {
+            return $users;
+        }
     }
 
+    /**
+     * Returns all users with the capability mod/workshop:peerassess sorted by groups
+     *
+     * This takes the module grouping settings into account. If "Available for group members only"
+     * is set, returns only groups withing the course module grouping.
+     *
+     * @param bool $musthavesubmission If true, return only users who have already submitted. All possible users otherwise.
+     * @return array array[groupid][userid] => stdClass{->id ->lastname ->firstname}
+     */
+    public function get_peer_reviewers_by_group($musthavesubmission=false) {
+        global $DB;
+
+        $reviewers  = $this->get_peer_reviewers($musthavesubmission);
+        $greviewers = array();  // grouped reviewers to be returned
+        if ($this->cm->groupmembersonly) {
+            // Available for group members only - the workshop is available only
+            // to users assigned to groups within the selected grouping, or to
+            // any group if no grouping is selected.
+            $groupingid = $this->cm->groupingid;
+            // All reviewers that are members of at least one group will be
+            // added into a virtual group id 0
+            $greviewers[0] = array();
+        } else {
+            $groupingid = 0;
+            // there is no need to be member of a group so $greviewers[0] will contain
+            // all reviewers
+            $greviewers[0] = $reviewers;
+        }
+        $gmemberships = groups_get_all_groups($this->cm->course, array_keys($reviewers), $groupingid,
+                            'gm.id,gm.groupid,gm.userid');
+        foreach ($gmemberships as $gmembership) {
+            if (!isset($greviewers[$gmembership->groupid])) {
+                $greviewers[$gmembership->groupid] = array();
+            }
+            $greviewers[$gmembership->groupid][$gmembership->userid] = $reviewers[$gmembership->userid];
+            $greviewers[0][$gmembership->userid] = $reviewers[$gmembership->userid];
+        }
+        return $greviewers;
+    }
 
     /**
      * Returns submissions from this workshop
      *
      * Fetches data from {workshop_submissions} and adds some useful information from other
      * tables.
-     * 
-     * @param mixed $userid If set to integer ID, return submission of the given user only
-     * @param mixed $examples false|true|all Only regular submissions, only examples, all submissions
+     *
+     * @param mixed $userid int|array|'all' If set to [array of] integer, return submission[s] of the given user[s] only
+     * @param mixed $examples false|true|'all' Only regular submissions, only examples, all submissions
      * @todo unittest
      * @return object moodle_recordset
      */
@@ -160,6 +239,46 @@ class workshop_api extends workshop {
         return $DB->get_recordset_sql($sql, $params);
     }
 
+    /**
+     * Returns a submission submitted by the given author or authors.
+     *
+     * This is intended for regular workshop participants, not for example submissions by teachers.
+     * If an array of authors is provided, returns array of stripped submission records so they do not
+     * include text fields (to prevent possible memory-lack issues).
+     *
+     * @param mixed $id integer|array author ID or IDs
+     * @return mixed false if not found, object if $id is int, array if $id is array
+     */
+    public function get_submission_by_author($id) {
+        if (empty($id)) {
+            return false;
+        }
+        $rs = $this->get_submissions_recordset($id, false);
+        if (is_int($id)) {
+            $submission = $rs->current();
+            $rs->close();
+            if (empty($submission->id)) {
+                return false;
+            } else {
+                return $submission;
+            }
+        } elseif (is_array($id)) {
+            $submissions = array();
+            foreach ($rs as $submission) {
+                $submissions[$submission->id] = new stdClass();
+                foreach ($submission as $property => $value) {
+                    // we do not want text fields here to prevent possible memory issues
+                    if (in_array($property, array('id', 'workshopid', 'example', 'userid', 'authorlastname', 'authorfirstname',
+                            'timecreated', 'timemodified', 'grade', 'gradeover', 'gradeoverby', 'gradinggrade'))) {
+                        $submissions[$submission->id]->{$property} = $value;
+                    }
+                }
+            }
+            return $submissions;
+        } else {
+            throw new moodle_workshop_exception($this, 'wrongparameter');
+        }
+    }
 
     /**
      * Returns the list of assessments with some data added
@@ -173,15 +292,15 @@ class workshop_api extends workshop {
      */
     public function get_assessments_recordset($reviewerid='all', $id='all') {
         global $DB;
-        
+
         $sql = 'SELECT  a.*,
                         reviewer.id AS reviewerid,reviewer.firstname AS reviewerfirstname,reviewer.lastname as reviewerlastname,
                         s.title,
                         author.id AS authorid, author.firstname AS authorfirstname,author.lastname as authorlastname
                 FROM {workshop_assessments} a
-                LEFT JOIN {user} reviewer ON (a.userid = reviewer.id)
-                LEFT JOIN {workshop_submissions} s ON (a.submissionid = s.id)
-                LEFT JOIN {user} author ON (s.userid = author.id)
+                INNER JOIN {user} reviewer ON (a.userid = reviewer.id)
+                INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id)
+                INNER JOIN {user} author ON (s.userid = author.id)
                 WHERE s.workshopid = ?';
         $params = array($this->id);
         if (is_int($reviewerid)) {
@@ -201,6 +320,71 @@ class workshop_api extends workshop {
         return $DB->get_recordset_sql($sql, $params);
     }
 
+    /**
+     * Returns the list of assessments with some data added
+     *
+     * Fetches data from {workshop_assessments} and adds some useful information from other
+     * tables. The returned objects are lightweight version of those returned by get_assessments_recordset(),
+     * mainly they do not contain text fields.
+     *
+     * @param mixed $reviewerid 'all'|int|array User ID of the reviewer
+     * @return array of objects
+     * @see workshop_api::get_assessments_recordset() for the structure of returned objects
+     */
+    public function get_assessments($reviewerid='all') {
+        $rs = $this->get_assessments_recordset($reviewerid, 'all');
+        $assessments = array();
+        foreach ($rs as $assessment) {
+            // copy selected properties into the array to be returned. This is here mainly in order not
+            // to include text comments.
+            $assessments[$assessment->id] = new stdClass;
+            foreach ($assessment as $property => $value) {
+                if (in_array($property, array('id', 'submissionid', 'userid', 'timecreated', 'timemodified',
+                        'timeagreed', 'grade', 'gradinggrade', 'gradinggradeover', 'gradinggradeoverby',
+                        'reviewerid', 'reviewerfirstname', 'reviewerlastname', 'title', 'authorid',
+                        'authorfirstname', 'authorlastname'))) {
+                    $assessments[$assessment->id]->{$property} = $value;
+                }
+            }
+        }
+        $rs->close();
+        return $assessments;
+    }
+
+    /**
+     * Get the information about the given assessment
+     *
+     * @param int $id Assessment ID
+     * @see workshop_api::get_assessments_recordset() for the structure of data returned
+     * @return mixed false if not found, object otherwise
+     */
+    public function get_assessment_by_id($id) {
+        $rs         = $this->get_assessments_recordset('all', $id);
+        $assessment = $rs->current();
+        $rs->close();
+        if (empty($assessment->id)) {
+            return false;
+        } else {
+            return $assessment;
+        }
+    }
+
+    /**
+     * 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
+     * @return array array of objects
+     */
+    public function get_assessments_by_reviewer($id) {
+        $rs = $this->get_assessments_recordset($id);
+        $assessments = array();
+        foreach ($rs as $assessment) {
+            $assessments[$assessment->id] = $assessment;
+        }
+        $rs->close();
+        return $assessment;
+    }
 
     /**
      * Returns the list of allocations in the workshop
@@ -208,17 +392,18 @@ class workshop_api extends workshop {
      * This returns the list of all users who can submit their work or review submissions (or both
      * which is the common case). So basically this is to return list of all students participating
      * in the workshop. For every participant, it adds information about their submission and their
-     * reviews. This is mainly intended for allocation reports and originally was written for 
-     * manula allocation ui.
+     * reviews.
      *
      * The returned structure is recordset of objects with following properties:
      * [authorid] [authorfirstname] [authorlastname] [authorpicture] [authorimagealt]
      * [submissionid] [submissiontitle] [submissiongrade] [assessmentid]
-     * [timeallocated] [reviewerid] [reviewerfirstname] [reviewerlastname] 
+     * [timeallocated] [reviewerid] [reviewerfirstname] [reviewerlastname]
      * [reviewerpicture] [reviewerimagealt]
      *
      * This should be refactored when capability handling proposed by Petr is implemented so that
      * we can check capabilities directly in SQL joins.
+     * Note that the returned recordset includes participants without submission as well as those
+     * without any review allocated yet.
      *
      * @return object moodle_recordset
      */
@@ -235,10 +420,10 @@ class workshop_api extends workshop {
         list($usql, $params) = $DB->get_in_or_equal(array_keys($users));
         $params[] = $this->id;
 
-        $sql = 'SELECT  author.id AS authorid, author.firstname AS authorfirstname, author.lastname AS authorlastname, 
+        $sql = 'SELECT  author.id AS authorid, author.firstname AS authorfirstname, author.lastname AS authorlastname,
                         author.picture AS authorpicture, author.imagealt AS authorimagealt,
-                        s.id AS submissionid, s.title AS submissiontitle, s.grade AS submissiongrade, 
-                        a.id AS assessmentid, a.timecreated AS timeallocated, a.userid AS reviewerid, 
+                        s.id AS submissionid, s.title AS submissiontitle, s.grade AS submissiongrade,
+                        a.id AS assessmentid, a.timecreated AS timeallocated, a.userid AS reviewerid,
                         reviewer.firstname AS reviewerfirstname, reviewer.lastname AS reviewerlastname,
                         reviewer.picture as reviewerpicture, reviewer.imagealt AS reviewerimagealt
                 FROM {user} author
@@ -250,61 +435,58 @@ class workshop_api extends workshop {
         return $DB->get_recordset_sql($sql, $params);
     }
 
-
     /**
      * Allocate a submission to a user for review
-     * 
+     *
      * @param object $submission Submission record
      * @param int $reviewerid User ID
+     * @param bool $bulk repeated inserts into DB expected
      * @return int ID of the new assessment or an error code
      */
-    public function add_allocation(stdClass $submission, $reviewerid) {
+    public function add_allocation(stdClass $submission, $reviewerid, $bulk=false) {
         global $DB;
 
         if ($DB->record_exists('workshop_assessments', array('submissionid' => $submission->id, 'userid' => $reviewerid))) {
             return WORKSHOP_ALLOCATION_EXISTS;
         }
 
-        if (!$this->assesswosubmission) {
-            // reviewer must have submitted his own work
-            if (!$DB->record_exists('workshop_submissions', array('workshopid' => $this->id, 'userid' => $reviewerid))) {
-                return WORKSHOP_ALLOCATION_WOSUBMISSION;
-            }
-        }
-
         $now = time();
         $assessment = new stdClass();
-        $assessment->submissionid = $submission->id;
+        $assessment->submissionid   = $submission->id;
         $assessment->userid         = $reviewerid;
         $assessment->timecreated    = $now;
         $assessment->timemodified   = $now;
 
-        return $DB->insert_record('workshop_assessments', $assessment);
+        return $DB->insert_record('workshop_assessments', $assessment, true, $bulk);
     }
 
-
     /**
-     * delete_assessment 
+     * Delete assessment record or records
      *
-     * @todo finish and document this method
-     * 
+     * @param mixed $id int|array assessment id or array of assessments ids
+     * @return bool false if $id not a valid parameter, true otherwise
      */
     public function delete_assessment($id) {
         global $DB;
 
         // todo remove all given grades from workshop_grades;
-        return $DB->delete_records('workshop_assessments', array('id' => $id));
-    }
 
+        if (is_numeric($id)) {
+            return $DB->delete_records('workshop_assessments', array('id' => $id));
+        }
+        if (is_array($id)) {
+            return $DB->delete_records_list('workshop_assessments', 'id', $id);
+        }
+        return false;
+    }
 
     /**
      * Returns instance of grading strategy class
-     * 
+     *
      * @param object $workshop Workshop record
      * @return object Instance of a grading strategy
      */
     public function grading_strategy_instance() {
-
         if (!($this->strategy === clean_param($workshop->strategy, PARAM_ALPHA))) {
             throw new moodle_workshop_exception($this, 'invalidstrategyname');
         }
@@ -314,7 +496,7 @@ class workshop_api extends workshop {
             if (is_readable($strategylib)) {
                 require_once($strategylib);
             } else {
-                throw new moodle_exception('missingstrategy', 'workshop');
+                throw new moodle_workshop_exception($this, 'missingstrategy');
             }
             $classname = 'workshop_' . $workshop->strategy . '_strategy';
             $this->strategy_api = new $classname($this);
@@ -326,14 +508,12 @@ class workshop_api extends workshop {
         return $this->strategy_api;
     }
 
-
     /**
      * Return list of available allocation methods
      *
      * @return array Array ['string' => 'string'] of localized allocation method names
      */
     public function installed_allocators() {
-
         $installed = get_list_of_plugins('mod/workshop/allocation');
         $forms = array();
         foreach ($installed as $allocation) {
@@ -348,29 +528,25 @@ class workshop_api extends workshop {
         return $forms;
     }
 
-
     /**
      * Returns instance of submissions allocator
-     * 
+     *
      * @param object $method The name of the allocation method, must be PARAM_ALPHA
      * @return object Instance of submissions allocator
      */
     public function allocator_instance($method) {
-
         $allocationlib = dirname(__FILE__) . '/allocation/' . $method . '/allocator.php';
         if (is_readable($allocationlib)) {
             require_once($allocationlib);
         } else {
-            throw new moodle_exception('missingallocator', 'workshop');
+            throw new moodle_workshop_exception($this, 'missingallocator');
         }
         $classname = 'workshop_' . $method . '_allocator';
         return new $classname($this);
     }
 
-
 }
 
-
 /**
  * Class for workshop exceptions. Just saves a couple of arguments of the
  * constructor for a moodle_exception.
@@ -398,5 +574,3 @@ class moodle_workshop_exception extends moodle_exception {
     }
 }
 
-
-
index 8ead07b0b8afa9352a7447f499985bc3ceca9bef..804285e03d5359f990bfcc65e7c98cb178b536d2 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * The main workshop configuration form
  *
  * The UI mockup has been proposed in MDL-18688
- * It uses the standard core Moodle formslib. For more info about them, please 
+ * It uses the standard core Moodle formslib. For more info about them, please
  * visit: http://docs.moodle.org/en/Development:lib/formslib.php
  *
  * @package   mod-workshop
@@ -115,7 +114,7 @@ class mod_workshop_mod_form extends moodleform_mod {
         $mform->setHelpButton('nattachments', array('nattachments', $label, 'workshop'));
         $mform->setAdvanced('nattachments');
 
-        $options = get_max_upload_sizes($CFG->maxbytes, $COURSE->maxbytes); 
+        $options = get_max_upload_sizes($CFG->maxbytes, $COURSE->maxbytes);
         $options[0] = get_string('courseuploadlimit') . ' ('.display_size($COURSE->maxbytes).')';
         $mform->addElement('select', 'maxbytes', get_string('maximumsize', 'assignment'), $options);
         $mform->setDefault('maxbytes', $workshopconfig->maxbytes);
@@ -209,9 +208,10 @@ class mod_workshop_mod_form extends moodleform_mod {
         $mform->setHelpButton('password', array('requirepassword', $label, 'workshop'));
         $mform->setAdvanced('password');
 
-
 /// Common module settinga, Restrict availability, Activity completion etc. ----
-        // add standard elements, common to all modules
+        $features = array('groups'=>true, 'groupings'=>true, 'groupmembersonly'=>true,
+                'outcomes'=>true, 'gradecat'=>false, 'idnumber'=>false);
+
         $this->standard_coursemodule_elements();
 
 /// Save and close, Save, Cancel -----------------------------------------------
index 6250f9cf94032d10f7ead671167499147c176fa8..423d8ac983e1008fb5778f3d339a7d6c60856d51 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * All workshop module renderers are defined here
  *
 defined('MOODLE_INTERNAL') || die();
 
 /**
- * Workshop module renderer class 
- * 
- * @package 
- * @version $Id$
- * @copyright 
- * @author David Mudrak <david.mudrak@gmail.com> 
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * Workshop module renderer class
+ *
+ * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class moodle_mod_workshop_renderer  {
+class moodle_mod_workshop_renderer extends moodle_renderer_base {
 
     /** the underlying renderer to use */
     protected $output;
@@ -43,10 +39,9 @@ class moodle_mod_workshop_renderer  {
     /** the page we are doing output for */
     protected $page;
 
-
     /**
      * Workshop renderer constructor
-     * 
+     *
      * @param mixed $page the page we are doing output for
      * @param mixed $output lower-level renderer, typically moodle_core_renderer
      * @access public
@@ -57,6 +52,60 @@ class moodle_mod_workshop_renderer  {
         $this->output = $output;
     }
 
+    /**
+     * Returns html code for a status message
+     *
+     * This should be replaced by a core system of displaying messages, as for example Mahara has.
+     *
+     * @param string $message to display
+     * @return string html
+     */
+    public function status_message(stdClass $message) {
+        if (empty($message->text)) {
+            return '';
+        }
+        $sty = $message->sty ? $message->sty : 'info';
+
+        $o = $this->output->output_tag('span', array(), $message->text);
+        $closer = $this->output->output_tag('a', array('href' => $this->page->url->out()),
+                    get_string('messageclose', 'workshop'));
+        $o .= $this->output->container($closer, 'status-message-closer');
+        if (isset($message->extra)) {
+            $o .= $message->extra;
+        }
+        return $this->output->container($o, array('status-message', $sty));
+    }
 
+    /**
+     * Wraps html code returned by the allocator init() method
+     *
+     * Supplied argument can be either integer status code or an array of string messages. Messages
+     * in a array can have optional prefix or prefixes, using '::' as delimiter. Prefixes determine
+     * the type of the message and may influence its visualisation.
+     *
+     * @param mixed $result int|array returned by init()
+     * @return string $html to be echoed
+     */
+    public function allocation_init_result($result='') {
+        $msg = new stdClass();
+        if ($result === 'WORKSHOP_ALLOCATION_RANDOM_ERROR') {
+            $msg = (object)array('text' => get_string('randomallocationerror', 'workshop'), 'sty' => 'error');
+        } else {
+            $msg = (object)array('text' => get_string('randomallocationdone', 'workshop'), 'sty' => 'ok');
+        }
+        $o = $this->status_message($msg);
+        if (is_array($result)) {
+            $o .= $this->output->output_start_tag('ul', array('class' => 'allocation-init-results'));
+            foreach ($result as $message) {
+                $parts  = explode('::', $message);
+                $text   = array_pop($parts);
+                $class  = implode(' ', $parts);
+                $o .= $this->output->output_tag('li', array('class' => $class), $text);
+            }
+            $o .= $this->output->output_end_tag('ul');
+            $o .= $this->output->continue_button($this->page->url->out());
+        }
+        return $o;
+    }
 
 }
index 8f1412234ff6c86e275aac98575be41b4a6f1d3d..6ae78675e15b2b244cb9f8516caf9ab31e4885ac 100644 (file)
@@ -15,7 +15,6 @@
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
-
 /**
  * The workshop module configuration variables
  *
@@ -66,11 +65,11 @@ foreach (workshop_get_comparison_levels() as $code => $level) {
 $settings->add(new admin_setting_configselect('workshop/assessmentcomps', get_string('assessmentcomps', 'workshop'),
                     get_string('configassessmentcomps', 'workshop'), WORKSHOP_COMPARISON_NORMAL, $levels));
 
-$settings->add(new admin_setting_configtext('workshop/noerrorsgrade0', get_string('noerrorsgrade0', 'workshop'), 
+$settings->add(new admin_setting_configtext('workshop/noerrorsgrade0', get_string('noerrorsgrade0', 'workshop'),
                     get_string('confignoerrorsgrade0', 'workshop'), get_string('noerrorsgrade0default', 'workshop'),
                     $paramtype=PARAM_TEXT, $size=15));
 
-$settings->add(new admin_setting_configtext('workshop/noerrorsgrade1', get_string('noerrorsgrade1', 'workshop'), 
+$settings->add(new admin_setting_configtext('workshop/noerrorsgrade1', get_string('noerrorsgrade1', 'workshop'),
                     get_string('confignoerrorsgrade1', 'workshop'), get_string('noerrorsgrade1default', 'workshop'),
                     $paramtype=PARAM_TEXT, $size=15));
 
index 7496308564a43cf53b74c8a4c42dd3cec612ce62..6ac80f0399e935ef4d7a7769a45bc494c9e49885 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * Unit tests for (some of) mod/workshop/lib.php
  *
  */
 
 defined('MOODLE_INTERNAL') || die();
+
 // Make sure the code being tested is accessible.
 require_once($CFG->dirroot . '/mod/workshop/lib.php'); // Include the code to test
-/** 
+
+/**
  * Test cases for the functions in lib.php
  */
 class workshop_lib_test extends UnitTestCase {
@@ -46,5 +45,5 @@ class workshop_lib_test extends UnitTestCase {
         }
         $this->assertTrue($values_are_integers, 'Array values must be integers');
     }
+
 }
index 3777d8c6fad0374c5a9fa672e45393bf25a288db..50d6931d555ba2ca93857928be108d98806979bd 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * Unit tests for workshop_api class defined in mod/workshop/locallib.php
  *
  */
 
 defined('MOODLE_INTERNAL') || die();
+
 // Make sure the code being tested is accessible.
 require_once($CFG->dirroot . '/mod/workshop/locallib.php'); // Include the code to test
 
 /**
  * Test subclass that makes all the protected methods we want to test public.
@@ -38,8 +36,7 @@ class testable_workshop_api extends workshop_api {
 
 }
 
-
-/** 
+/**
  * Test cases for the internal workshop api
  */
 class workshop_api_test extends UnitTestCase {
@@ -60,6 +57,4 @@ class workshop_api_test extends UnitTestCase {
         $this->workshop = null;
     }
 
-
 }
index b3dd88c0a5e258339a651c6aa99d360e305ba85e..49eb4ea62d72412793773474c8eef31936c4ddf4 100644 (file)
+/**
+ * Elements generated by the workshop renderer
+ */
+.mod-workshop .status-message {
+    padding: 5px 5em 5px 15px;
+    margin: 0px auto 20px auto;
+    width: 60%;
+    font-size: 80%;
+    position: relative;
+}
+
+.mod-workshop .status-message-closer {
+    font-weight: bold;
+    position: absolute;
+    top: 5px;
+    right: 15px;
+}
+
+.mod-workshop .status-message.ok {
+    color: #547c22;
+    background-color: #e7f1c3;
+}
+
+.mod-workshop .status-message.error {
+    color: #dd0221;
+    background-color: #ffd3d9;
+}
+
+.mod-workshop .status-message.info {
+    color: #1666a9;
+    background-color: #d2ebff;
+}
+
+/**
+ * Allocators
+ */
+
+.mod-workshop .allocation-init-results {
+    margin: 10px auto;
+    width: 60%;
+    font-size: 80%;
+}
+
+.mod-workshop .allocation-init-results .ident {
+    margin-left: 20px;
+}
+
+.mod-workshop .allocation-init-results .ok {
+    color: #547c22;
+    background-color: #e7f1c3;
+}
+
+.mod-workshop .allocation-init-results .error {
+    color: #dd0221;
+    background-color: #ffd3d9;
+}
+
+.mod-workshop .allocation-init-results .info {
+    color: #1666a9;
+    background-color: #d2ebff;
+}
+
 /**
  * Manual allocator
  */
 
-.manual-allocator .allocations {
+.mod-workshop .manual-allocator .allocations {
     margin: 0px auto;
 }
 
-.manual-allocator .allocations .r0 {
+.mod-workshop .manual-allocator .allocations .r0 {
     background-color: #eee;
 }
 
-.manual-allocator .allocations .highlightreviewedby .reviewedby,
-.manual-allocator .allocations .highlightreviewerof .reviewerof {
+.mod-workshop .manual-allocator .allocations .highlightreviewedby .reviewedby,
+.mod-workshop .manual-allocator .allocations .highlightreviewerof .reviewerof {
     background-color: #fff3d2;
 }
 
-.manual-allocator .allocations tr td {
+.mod-workshop .manual-allocator .allocations tr td {
     vertical-align: top;
     padding: 5px;
 }
 
-.manual-allocator .allocations tr td.peer {
+.mod-workshop .manual-allocator .allocations tr td.peer {
     border-left: 1px solid #ccc;
     border-right: 1px solid #ccc;
 }
 
-.manual-allocator .allocations .reviewedby .info,
-.manual-allocator .allocations .peer .info,
-.manual-allocator .allocations .reviewerof .info {
+.mod-workshop .manual-allocator .allocations .reviewedby .info,
+.mod-workshop .manual-allocator .allocations .peer .info,
+.mod-workshop .manual-allocator .allocations .reviewerof .info {
     font-size: 80%;
     color: #888;
     font-style: italic;
 }
 
-.manual-allocator .allocations .reviewedby img.userpicture,
-.manual-allocator .allocations .reviewerof img.userpicture {
+.mod-workshop .manual-allocator .allocations .reviewedby img.userpicture,
+.mod-workshop .manual-allocator .allocations .reviewerof img.userpicture {
     height: 16px;
     width: 16px;
     margin-right: 3px;
     vertical-align: middle;
 }
 
-.manual-allocator .allocations .peer img.userpicture {
+.mod-workshop .manual-allocator .allocations .peer img.userpicture {
     height: 35px;
     width: 35px;
     vertical-align: middle;
     margin-right: 5px;
 }
 
-.manual-allocator .allocations .peer .submission {
+.mod-workshop .manual-allocator .allocations .peer .submission {
     font-size: 90%;
     margin-top: 1em;
 }
 
-.manual-allocator .status-message {
-    padding: 5px 5em 5px 15px;
-    margin: 0px auto 20px auto;
-    width: 60%;
-    font-size: 80%;
-    position: relative;
-}
-
-.manual-allocator .status-message-closer {
-    font-weight: bold;
-    position: absolute;
-    top: 5px;
-    right: 15px;
-}
-
-.manual-allocator .status-message.ok {
-    color: #547c22;
-    background-color: #e7f1c3;
-}
-
-.manual-allocator .status-message.error {
-    color: #dd0221;
-    background-color: #ffd3d9;
-}
-
-.manual-allocator .status-message.info {
-    color: #1666a9;
-    background-color: #d2ebff;
-}
-
 
index 766051e32408447932f6b241513a5055c43a1baa..0ff7fe06af9c1fc8fb351a8ea61973b62246e756 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
-// This file is part of Moodle - http://moodle.org/  
-// 
+// 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
 // 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/>.
 
-
 /**
  * Submit an assignment or edit the already submitted work
  *
@@ -64,7 +63,7 @@ if ($id) { // submission is specified
     if (!$submission = workshop_get_user_submission($workshop, $USER->id)) {
         $submission = new object();
         $submission->id = null;
-    } 
+    }
 }
 unset($id); // not needed anymore
 
@@ -109,9 +108,9 @@ if ($mform->is_cancelled()) {
     }
 
     // save and relink embedded images and save attachments
-    $submission = file_postupdate_standard_editor($submission, 'data', $dataoptions, $context, 
+    $submission = file_postupdate_standard_editor($submission, 'data', $dataoptions, $context,
                                                     'workshop_submission', $submission->id);
-    $submission = file_postupdate_standard_filemanager($submission, 'attachment', $attachmentoptions, $context, 
+    $submission = file_postupdate_standard_filemanager($submission, 'attachment', $attachmentoptions, $context,
                                                     'workshop_attachment', $submission->id);
 
     // store the updated values or re-save the new submission
index 45be3e62b530bc29f0917be9bc664c4c58521fef..41a356adb2b5401eb382835f6feae19acec0e80d 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
-// This file is part of Moodle - http://moodle.org/  
-// 
+// 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
 // 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/>.
 
-
 /**
  * Submit an assignment or edit the already submitted work
  *
@@ -51,7 +50,7 @@ class workshop_submission_form extends moodleform {
 
         if ($workshop->nattachments > 0) {
             $mform->addElement('static', 'filemanagerinfo', get_string('nattachments', 'workshop'), $workshop->nattachments);
-            $mform->addElement('filemanager', 'attachment_filemanager', get_string('submissionattachment', 'workshop'), 
+            $mform->addElement('filemanager', 'attachment_filemanager', get_string('submissionattachment', 'workshop'),
                                 null, $attachmentoptions);
         }
 
@@ -63,7 +62,6 @@ class workshop_submission_form extends moodleform {
         $this->set_data($current);
     }
 
-
     function validation($data, $files) {
         global $CFG, $USER, $DB;
 
index f316497fe3b7f7d685df5af30d4785d1cfd9fb70..3a08cce692d831a57b4264e1cfd67cb4f9d58d76 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
 
-
 /**
  * Defines the version of workshop
  *
- * This code fragment is called by moodle_needs_upgrading() and 
+ * This code fragment is called by moodle_needs_upgrading() and
  * /admin/index.php
  *
  * @package   mod-workshop
index eb583ab7a5766371e83a166ac9112116b8fb444d..027cdeaff261969a7c54b8841c6f5016fcc0f9ce 100644 (file)
@@ -1,7 +1,7 @@
 <?php
-// This file is part of Moodle - http://moodle.org/  
-// 
+
+// 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
 // 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/>.
+
 /**
  * Prints a particular instance of workshop
  *
@@ -61,10 +60,10 @@ $PAGE->set_button(update_module_button($cm->id, $course->id, get_string('modulen
 
 // todo navigation will be changed yet for Moodle 2.0
 $navlinks   = array();
-$navlinks[] = array('name' => get_string('modulenameplural', 'workshop'), 
-                    'link' => "index.php?id=$course->id", 
+$navlinks[] = array('name' => get_string('modulenameplural', 'workshop'),
+                    'link' => "index.php?id=$course->id",
                     'type' => 'activity');
-$navlinks[] = array('name' => format_string($workshop->name), 
+$navlinks[] = array('name' => format_string($workshop->name),
                     'link' => '',
                     'type' => 'activityinstance');
 $navigation = build_navigation($navlinks);