<?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
$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
}
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();
<?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).
* 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);
}
<?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
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
/** workshop instance */
protected $workshop;
-
/**
* @param stdClass $workshop Workshop record
*/
public function __construct(workshop $workshop) {
-
$this->workshop = $workshop;
}
-
/**
* Allocate submissions as requested by user
*/
$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);
$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;
}
$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;
$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));
}
}
-
/**
* 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
$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];
$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();
}
}
- // 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);
}
-
}
<?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
*
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;
/**
* 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
$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
*/
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'));
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) {
if (isset($options[$user->id])) {
unset($options[$user->id]);
}
- }
+ }
$handler = $this->page->url->out_action() . '&mode=new&of=' . $user->id . '&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&by=' . $user->id . '&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&by=' . $user->id . '&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;
}
}
-
-
-
-
-
-
-
<?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) {
+ }
}
--- /dev/null
+<?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();
+ }
+}
--- /dev/null
+<?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);
+ }
+
+
+}
<?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
*
}
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);
//todo $formdata = $strategy->load_assessment($assessment);
-
-
// load the form to edit the grading strategy dimensions
$mform = $strategy->get_assessment_form($selfurl, $mode);
// 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');
}
<?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
*
'admin' => CAP_ALLOW
)
),
-
+
);
<?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
*
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);
// 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);
<?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
*
//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
*
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
*/
}
-
}
<?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.
*
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.
*
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
*/
$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;
$this->repeat_elements($repeated, $numofdisplaydimensions, $repeatedoptions, 'numofdimensions', 'adddimensions', $numofdimensionstoadd, get_string('addmoredimensionsaccumulative', 'workshop', $numofdimensionstoadd));
}
-
}
<?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
*
// 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
*/
}
-
class workshop_accumulative_strategy_test extends UnitTestCase {
/** workshop instance emulation */
/** setup testing environment */
public function setUp() {
-
+
$this->workshop = new stdClass;
$this->workshop->id = 42;
$this->workshop->strategy = 'accumulative';
}
-
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;
$this->assertEqual($cooked['weight[1]'], 1);
}
-
public function test_cook_form_data() {
$cooked = $this->strategy->_cook_form_data($this->rawform);
'weight' => 1,
));
}
-
+
}
<?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
*
require_once(dirname(dirname(__FILE__)) . '/strategy.php'); // parent class
-
/**
* Accumulative grading strategy logic.
*/
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
*/
return (object)$formdata;
}
-
/**
* Save the assessment dimensions into database
*
$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
*/
return $cook;
}
-
}
<?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
*
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 */
/**
* 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
*/
$mform->closeHeaderBefore('buttonar');
}
-
/**
* Add any strategy specific form fields.
*
<?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.
*
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
*/
$mform->closeHeaderBefore('buttonar');
}
-
/**
* Add any strategy specific form fields.
*
<?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.
*
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.
*
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
*/
$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;
$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]", '');
}
-
}
<?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
*
require_once(dirname(dirname(__FILE__)) . '/strategy.php'); // parent class
-
/**
* "Number of errors" grading strategy logic.
*/
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) {
return (object)$formdata;
}
-
/**
* Save the definition of a "Number of errors" grading form
*
}
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
} 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;
}
}
-
/**
* 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
*/
return $cook;
}
-
}
<?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
*
/**
* 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().
*/
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.
*/
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.
*
*/
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
*
protected $nodimensions;
/**
- * Constructor
- *
+ * Constructor
+ *
* @param object $workshop The workshop instance record
* @access public
* @return void
$this->nodimensions = null;
}
-
/**
* Factory method returning an instance of an assessment form editor class
*
*/
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);
}
-
/**
- * 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
*/
return $this->nodimensions;
}
-
/**
* Factory method returning an instance of an assessment form
*
*/
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);
}
-
}
<?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
*
'link' => '',
'type' => 'activity');
$navigation = build_navigation($navlinks);
-
+
echo $OUTPUT->header($navigation);
/// Get all the appropriate data
<?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
*
$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?';
$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';
$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';
$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';
$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';
<?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
define('WORKSHOP_EXAMPLES_BEFORE_SUBMISSION', 1);
define('WORKSHOP_EXAMPLES_BEFORE_ASSESSMENT', 2);
-
/**
* The internal codes of the required level of assessment similarity
*/
define('WORKSHOP_COMPARISON_HIGH', 3); /* f = 3.00 */
define('WORKSHOP_COMPARISON_VERYHIGH', 4); /* f = 5.00 */
-
/**
* The base class of workshop instances
*
$this->cm = $cm;
}
-
/**
* Saves a new instance of the workshop into the database
*
}
}
-
/**
* Given an object containing all the necessary data,
* (defined by the form in mod_form.php) this function
return workshop::add_instance($data);
}
-
/**
* Given an object containing all the necessary data,
* (defined by the form in mod_form.php) this function
return $DB->update_record('workshop', $workshop);
}
-
/**
* Given an ID of an instance of this module,
* this function will permanently delete the instance
return $result;
}
-
/**
* Return a small object with summary information about what a
* user has done with a given particular instance of this module
return $return;
}
-
/**
* Print a detailed representation of what a user has done with
* a given particular instance of this module, for user activity reports.
return true;
}
-
/**
* Given a course and a time, this module should find recent activity
* that has occurred in workshop activities and print it out.
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
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
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
return $return;
}
-
/**
* Checks if scale is being used by any instance of workshop.
* This function was added in 1.9
}
}
-
/**
* Execute post-install custom actions for the module
* This function was added in 1.9
return true;
}
-
/**
* Execute post-uninstall custom actions for the module
* This function was added in 1.9
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) //
/**
* 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
*/
return $grades;
}
-
/**
* Return an array of possible numbers of assessments to be done
*
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() {
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() {
return $weights;
}
-
/**
* Return an array of the localized grading strategy names
*
return $forms;
}
-
/**
* Return an array of available example assessment modes
*
return $modes;
}
-
/**
* Return array of assessment comparison levels
*
<?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
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.
*/
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;
}
}
+ /**
+ * 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
*/
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
*/
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)) {
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
* 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
*/
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
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');
}
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);
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) {
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.
}
}
-
-
<?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
$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);
$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 -----------------------------------------------
<?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;
/** 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
$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;
+ }
}
// 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
*
$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));
<?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 {
}
$this->assertTrue($values_are_integers, 'Array values must be integers');
}
-
+
}
<?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.
}
-
-/**
+/**
* Test cases for the internal workshop api
*/
class workshop_api_test extends UnitTestCase {
$this->workshop = null;
}
-
-
}
+/**
+ * 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;
-}
-
<?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
*
if (!$submission = workshop_get_user_submission($workshop, $USER->id)) {
$submission = new object();
$submission->id = null;
- }
+ }
}
unset($id); // not needed anymore
}
// 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
<?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
*
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);
}
$this->set_data($current);
}
-
function validation($data, $files) {
global $CFG, $USER, $DB;
<?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
<?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
*
// 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);