From 66c9894dbc27c74366128daec0c5c3d25cdc024a Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Mon, 4 Jan 2010 17:46:33 +0000 Subject: [PATCH] Manual allocator uses the new subrendering feature --- mod/workshop/allocation.php | 40 +--- mod/workshop/allocation/lib.php | 106 --------- mod/workshop/allocation/manual/allocator.php | 208 +++-------------- mod/workshop/allocation/manual/renderer.php | 228 +++++++++++++++++++ mod/workshop/allocation/manual/ui.css | 81 ------- mod/workshop/locallib.php | 90 ++++++-- mod/workshop/renderer.php | 62 +++++ mod/workshop/styles.php | 86 +++++++ mod/workshop/view.php | 52 ++--- 9 files changed, 499 insertions(+), 454 deletions(-) create mode 100644 mod/workshop/allocation/manual/renderer.php delete mode 100644 mod/workshop/allocation/manual/ui.css create mode 100644 mod/workshop/renderer.php create mode 100644 mod/workshop/styles.php diff --git a/mod/workshop/allocation.php b/mod/workshop/allocation.php index 8f61587667..1d055bdff9 100644 --- a/mod/workshop/allocation.php +++ b/mod/workshop/allocation.php @@ -34,54 +34,38 @@ require_once(dirname(__FILE__).'/allocation/lib.php'); $cmid = required_param('cmid', PARAM_INT); // course module $method = optional_param('method', 'manual', PARAM_ALPHA); // method to use -$PAGE->set_url('mod/workshop/allocation.php', array('cmid' => $cmid)); +$PAGE->set_url('mod/workshop/allocation.php', array('cmid' => $cmid, 'method' => $method)); -if (!$cm = get_coursemodule_from_id('workshop', $cmid)) { - print_error('invalidcoursemodule'); -} -if (!$course = $DB->get_record('course', array('id' => $cm->course))) { - print_error('coursemisconf'); -} -if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { - print_error('err_invalidworkshopid', 'workshop'); -} - -$workshop = new workshop_api($workshop, $cm); +$cm = get_coursemodule_from_id('workshop', $cmid, 0, false, MUST_EXIST); +$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); +$workshop = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST); +$workshop = new workshop_api($workshop, $cm); require_login($course, false, $cm); - $context = $PAGE->context; require_capability('mod/workshop:allocate', $context); $PAGE->set_title($workshop->name); $PAGE->set_heading($course->fullname); - +// // todo navigation will be changed yet for Moodle 2.0 $navigation = build_navigation(get_string('allocation', 'workshop'), $cm); -$allocator = workshop_allocator_instance($workshop, $method); -try { - $allocator->init(); -} -catch (moodle_workshop_exception $e) { - echo $OUTPUT->header($navigation); - throw $e; -} +$allocator = $workshop->allocator_instance($method); +$allocator->init(); // // Output starts here // +$wsoutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE); echo $OUTPUT->header($navigation); -$allocators = workshop_installed_allocators(); +$allocators = $workshop->installed_allocators(); $tabrow = array(); foreach ($allocators as $methodid => $methodname) { $tabrow[] = new tabobject($methodid, "allocation.php?cmid={$cmid}&method={$methodid}", $methodname); } -print_tabs(array($tabrow), $method); - -echo $OUTPUT->container_start('allocator allocator-' . $method); -echo $allocator->ui(); -echo $OUTPUT->container_end(); +print_tabs(array($tabrow), $method); // todo use $output call +echo $OUTPUT->container($allocator->ui(), 'allocator-ui'); echo $OUTPUT->footer(); diff --git a/mod/workshop/allocation/lib.php b/mod/workshop/allocation/lib.php index e65bc04447..e7750824c8 100644 --- a/mod/workshop/allocation/lib.php +++ b/mod/workshop/allocation/lib.php @@ -57,114 +57,8 @@ interface workshop_allocator { * * If a form is part of the UI, the caller should have call $PAGE->set_url(...) * - * @access public * @return string HTML to be displayed */ public function ui(); } - - -/** - * Return list of available allocation methods - * - * @access public - * @return array Array ['string' => 'string'] of localized allocation method names - */ -function workshop_installed_allocators() { - - $installed = get_list_of_plugins('mod/workshop/allocation'); - $forms = array(); - foreach ($installed as $allocation) { - $forms[$allocation] = get_string('allocation' . $allocation, 'workshop'); - } - // usability - make sure that manual allocation appears the first - if (isset($forms['manual'])) { - $m = array('manual' => $forms['manual']); - unset($forms['manual']); - $forms = array_merge($m, $forms); - } - return $forms; -} - - -/** - * Returns instance of submissions allocator - * - * @param object $workshop Workshop record - * @param object $method The name of the allocation method, must be PARAM_ALPHA - * @return object Instance of submissions allocator - */ -function workshop_allocator_instance(workshop $workshop, $method) { - - $allocationlib = dirname(__FILE__) . '/' . $method . '/allocator.php'; - if (is_readable($allocationlib)) { - require_once($allocationlib); - } else { - throw new moodle_exception('missingallocator', 'workshop'); - } - $classname = 'workshop_' . $method . '_allocator'; - return new $classname($workshop); -} - - -/** - * Returns the list of submissions and assessments allocated to them in the given workshop - * - * Submissions without allocated assessment are returned too, having assessment attributes null. - * This also fetches all other associated information (like details about the author and reviewer) - * needed to produce allocation reports. - * The returned structure is recordset of objects with following properties: - * [submissionid] [submissiontitle] [authorid] [authorfirstname] - * [authorlastname] [authorpicture] [authorimagealt] [assessmentid] - * [timeallocated] [reviewerid] [reviewerfirstname] [reviewerlastname] - * [reviewerpicture] [reviewerimagealt] - * - * @param object $workshop The workshop object - * @return object Recordset of allocations - */ -function workshop_get_allocations(workshop $workshop) { - global $DB; - - $sql = 'SELECT s.id AS submissionid, s.title AS submissiontitle, s.userid AS authorid, - author.firstname AS authorfirstname, author.lastname AS authorlastname, - author.picture AS authorpicture, author.imagealt AS authorimagealt, - 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 {workshop_submissions} s - LEFT JOIN {workshop_assessments} a ON (s.id = a.submissionid) - LEFT JOIN {user} author ON (s.userid = author.id) - LEFT JOIN {user} reviewer ON (a.userid = reviewer.id) - WHERE s.workshopid = ? - ORDER BY author.lastname,author.firstname,reviewer.lastname,reviewer.firstname'; - return $DB->get_recordset_sql($sql, array($workshop->id)); -} - - -/** - * Allocate a submission to a user for review - * - * @param object $workshop Workshop record - * @param object $submission Submission record - * @param int $reviewerid User ID - * @access public - * @return int ID of the new assessment or an error code - */ -function workshop_add_allocation(workshop $workshop, stdClass $submission, $reviewerid) { - global $DB; - - if ($DB->record_exists('workshop_assessments', array('submissionid' => $submission->id, 'userid' => $reviewerid))) { - return WORKSHOP_ALLOCATION_EXISTS; - } - - $now = time(); - $assessment = new stdClass(); - $assessment->submissionid = $submission->id; - $assessment->userid = $reviewerid; - $assessment->timecreated = $now; - $assessment->timemodified = $now; - - return $DB->insert_record('workshop_assessments', $assessment); -} - diff --git a/mod/workshop/allocation/manual/allocator.php b/mod/workshop/allocation/manual/allocator.php index 310fde1a65..0ed0fe33db 100644 --- a/mod/workshop/allocation/manual/allocator.php +++ b/mod/workshop/allocation/manual/allocator.php @@ -75,10 +75,10 @@ class workshop_manual_allocator implements workshop_allocator { $reviewerid = required_param('by', PARAM_INT); $authorid = required_param('of', PARAM_INT); $m = array(); // message object to be passed to the next page - $rs = $this->workshop->get_submissions($authorid); + $rs = $this->workshop->get_submissions_recordset($authorid); $submission = $rs->current(); $rs->close(); - if (!$submission) { + if (empty($submission->id)) { // nothing submitted by the given user $m[] = WORKSHOP_ALLOCATION_MANUAL_MSG_NOSUBMISSION; $m[] = $authorid; @@ -109,10 +109,10 @@ class workshop_manual_allocator implements workshop_allocator { } $assessmentid = required_param('what', PARAM_INT); $confirmed = optional_param('confirm', 0, PARAM_INT); - $rs = $this->workshop->get_assessments('all', $assessmentid); + $rs = $this->workshop->get_assessments_recordset('all', $assessmentid); $assessment = $rs->current(); $rs->close(); - if ($assessment) { + if (!empty($assessment)) { if (!$confirmed) { $m[] = WORKSHOP_ALLOCATION_MANUAL_MSG_CONFIRM_DEL; $m[] = $assessment->id; @@ -134,9 +134,6 @@ class workshop_manual_allocator implements workshop_allocator { } break; } - - // if we stay on this page, set the environment - $PAGE->requires->css('mod/workshop/allocation/manual/ui.css'); } @@ -146,71 +143,64 @@ class workshop_manual_allocator implements workshop_allocator { public function ui() { global $PAGE; - $o = ''; // output buffer - $hlauthorid = -1; // highlight this author - $hlreviewerid = -1; // highlight this reviewer - $msg = ''; // msg text - $sty = ''; // msg style - $m = optional_param('m', '', PARAM_ALPHANUMEXT); // message object + $hlauthorid = -1; // highlight this author + $hlreviewerid = -1; // highlight this reviewer + $msg = new stdClass; // message to render + $m = optional_param('m', '', PARAM_ALPHANUMEXT); // message object if ($m) { $m = explode('-', $m); // unserialize switch ($m[0]) { case WORKSHOP_ALLOCATION_MANUAL_MSG_ADDED: $hlauthorid = $m[1]; $hlreviewerid = $m[2]; - $msg = get_string('allocationadded', 'workshop'); - $sty = 'ok'; + $msg->text = get_string('allocationadded', 'workshop'); + $msg->sty = 'ok'; break; case WORKSHOP_ALLOCATION_MANUAL_MSG_EXISTS: $hlauthorid = $m[1]; $hlreviewerid = $m[2]; - $msg = get_string('allocationexists', 'workshop'); - $sty = 'info'; + $msg->text = get_string('allocationexists', 'workshop'); + $msg->sty = 'info'; break; case WORKSHOP_ALLOCATION_MANUAL_MSG_NOSUBMISSION: $hlauthorid = $m[1]; - $msg = get_string('nosubmissionfound', 'workshop'); - $sty = 'error'; + $msg->text = get_string('nosubmissionfound', 'workshop'); + $msg->sty = 'error'; break; case WORKSHOP_ALLOCATION_MANUAL_MSG_WOSUBMISSION: $hlauthorid = $m[1]; $hlreviewerid = $m[2]; - $msg = get_string('cantassesswosubmission', 'workshop'); - $sty = 'error'; + $msg->text = get_string('cantassesswosubmission', 'workshop'); + $sty->sty = 'error'; break; case WORKSHOP_ALLOCATION_MANUAL_MSG_CONFIRM_DEL: $hlauthorid = $m[2]; $hlreviewerid = $m[3]; if ($m[4] == 0) { - $msg = get_string('areyousuretodeallocate', 'workshop'); - $sty = 'info'; + $msg->text = get_string('areyousuretodeallocate', 'workshop'); + $msg->sty = 'info'; } else { - $msg = get_string('areyousuretodeallocategraded', 'workshop'); - $sty = 'error'; + $msg->text = get_string('areyousuretodeallocategraded', 'workshop'); + $msg->sty = 'error'; } break; case WORKSHOP_ALLOCATION_MANUAL_MSG_DELETED: $hlauthorid = $m[1]; $hlreviewerid = $m[2]; - $msg = get_string('assessmentdeleted', 'workshop'); - $sty = 'ok'; + $msg->text = get_string('assessmentdeleted', 'workshop'); + $msg->sty = 'ok'; break; } - $o .= '
'; - $o .= ' ' . $msg . ''; - $o .= ' '; if ($m[0] == WORKSHOP_ALLOCATION_MANUAL_MSG_CONFIRM_DEL) { $handler = $PAGE->url->out_action(); - $o .= print_single_button($handler, array('mode' => 'del', 'what' => $m[1], 'confirm' => 1), + $msg->extra = print_single_button($handler, array('mode' => 'del', 'what' => $m[1], 'confirm' => 1), get_string('iamsure', 'workshop'), 'post', '', true); } - $o .= '
'; } $peer = array(); // singular chosen due to readibility - $rs = $this->workshop->get_allocations(); + $rs = $this->workshop->get_allocations_recordset(); foreach ($rs as $allocation) { $currentuserid = $allocation->authorid; if (!isset($peer[$currentuserid])) { @@ -237,159 +227,19 @@ class workshop_manual_allocator implements workshop_allocator { foreach ($peer as $author) { foreach ($author->reviewedby as $reviewerid => $assessmentid) { - // example: "user with id 87 is reviewer of the work submitted by user id 45 in the assessment record 12" if (isset($peer[$reviewerid])) { + // example: "user with id 87 is reviewer of the work submitted by user id 45 in the assessment record 12" $peer[$reviewerid]->reviewerof[$author->id] = $assessmentid; } } } - if (empty($peer)) { - $o .= '
' . get_string('nosubmissions', 'workshop') . '
'; - } else { - $o .= '' . "\n"; - $o .= ''; - $o .= ''; - $o .= ''; - $o .= ''; - $o .= ''; - $counter = 0; - foreach ($peer as $user) { - $o .= '' . "\n"; - - if ($user->id == $hlauthorid) { - $highlight=' highlight'; - } else { - $highlight=''; - } - $o .= '' . "\n"; - $o .= '' . "\n"; - - if ($user->id == $hlreviewerid) { - $highlight=' highlight'; - } else { - $highlight=''; - } - $o .= '' . "\n"; - $o .= '' . "\n"; - $counter++; - } - $o .= '
' . get_string('participantreviewedby', 'workshop') . '' . get_string('participant', 'workshop') . '' . get_string('participantrevierof', 'workshop') . '
' . "\n"; - if (is_null($user->submissionid)) { - $o .= '' . "\n"; - $o .= get_string('nothingtoreview', 'workshop'); - $o .= '' . "\n"; - } else { - $handler = $PAGE->url->out_action() . '&mode=new&of=' . $user->id . '&by='; - $o .= popup_form($handler, $this->available_reviewers($user->id), 'addreviewof' . $user->id, '', - get_string('chooseuser', 'workshop'), '', '', true, 'self', get_string('addreviewer', 'workshop')); - } - $o .= '
    ' . "\n"; - foreach ($user->reviewedby as $reviewerid => $assessmentid) { - $o .= '
  • '; - $o .= print_user_picture($peer[$reviewerid], $this->workshop->course, null, 16, true); - $o .= fullname($peer[$reviewerid]); - - // delete - $handler = $PAGE->url->out_action(array('mode' => 'del', 'what' => $assessmentid)); - $o .= ' X '; // todo icon and link title - - $o .= '
  • '; - } - $o .= '
' . "\n"; - - $o .= '
' . "\n"; - $o .= print_user_picture($user, $this->workshop->course, null, 35, true); - $o .= fullname($user); - $o .= '
' . "\n"; - if (is_null($user->submissionid)) { - $o .= '' . get_string('nosubmissionfound', 'workshop'); - } else { - $o .= ''; - if (is_null($user->submissiongrade)) { - $o .= '
' . get_string('nogradeyet', 'workshop') . '
'; - } else { - $o .= '
' . s($user->submissiongrade) . '
'; // todo calculate - } - } - $o .= '
' . "\n"; - $o .= '
' . "\n"; - if (!($this->workshop->assesswosubmission) && is_null($user->submissionid)) { - $o .= '' . "\n"; - $o .= get_string('cantassesswosubmission', 'workshop'); - $o .= '' . "\n"; - } else { - $handler = $PAGE->url->out_action() . '&mode=new&by=' . $user->id . '&of='; - $o .= popup_form($handler, $this->available_reviewees($user->id), 'addreviewby' . $user->id, '', - get_string('chooseuser', 'workshop'), '', '', true, 'self', get_string('addreviewee', 'workshop')); - $o .= '
    ' . "\n"; - foreach ($user->reviewerof as $authorid => $assessmentid) { - $o .= '
  • '; - $o .= print_user_picture($peer[$authorid], $this->workshop->course, null, 16, true); - $o .= fullname($peer[$authorid]); - - // delete - $handler = $PAGE->url->out_action(array('mode' => 'del', 'what' => $assessmentid)); - $o .= ' X '; // todo icon and link title - - $o .= '
  • '; - } - $o .= '
' . "\n"; - } - $o .= '
' . "\n"; - } - return $o; - } - - - /** - * Return a list of reviewers that can review a submission - * - * @param int $authorid User ID of the submission author - * @return array Select options - */ - protected function available_reviewers($authorid) { - - $users = $this->workshop->get_peer_reviewers(); - $options = array(); - foreach ($users as $user) { - $options[$user->id] = fullname($user); - } - if (0 == $this->workshop->useselfassessment) { - // students can not review their own submissions in this workshop - if (isset($options[$authorid])) { - unset($options[$authorid]); - } - } - - return $options; + // ok, we have all data. Let it pass to the renderer and return the output + 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); } - /** - * Return a list of reviewees whom work can be reviewed by a given user - * - * @param int $reviewerid User ID of the reviewer - * @return array Select options - */ - protected function available_reviewees($reviewerid) { - - $rs = $this->workshop->get_submissions(); - $options = array(); - foreach ($rs as $submission) { - $options[$submission->userid] = fullname((object)array('firstname' => $submission->authorfirstname, - 'lastname' => $submission->authorlastname)); - } - $rs->close(); - if (0 == $this->workshop->useselfassessment) { - // students can not be reviewed by themselves in this workshop - if (isset($options[$reviewerid])) { - unset($options[$reviewerid]); - } - } - - return $options; - } - } diff --git a/mod/workshop/allocation/manual/renderer.php b/mod/workshop/allocation/manual/renderer.php new file mode 100644 index 0000000000..d679bd8295 --- /dev/null +++ b/mod/workshop/allocation/manual/renderer.php @@ -0,0 +1,228 @@ +. + + +/** + * Renderer class for the manual allocation UI is defined here + * + * @package mod-workshop + * @copyright 2009 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Manual allocation renderer class + */ +class moodle_mod_workshop_allocation_manual_renderer { + + /** 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 + * @return void + */ + public function __construct($page, $output) { + $this->page = $page; + $this->output = $output; + } + + + /** + * Display the table of all current allocations and widgets to modify them + * + * @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 + * @param object message to display + * @return string html code + */ + public function display_allocations(workshop $workshop, &$peers, $hlauthorid=null, $hlreviewerid=null, $msg=null) { + + if (empty($peers)) { + return $this->status_message((object)array('text' => get_string('nosubmissions', 'workshop'))); + } + + $table = new stdClass(); + $table->class = 'allocations'; + $table->head = array(get_string('participantreviewedby', 'workshop'), + get_string('participant', 'workshop'), + get_string('participantrevierof', 'workshop')); + $table->rowclass = array(); + $table->colclasses = array('reviewedby', 'peer', 'reviewerof'); + $table->data = array(); + foreach ($peers as $user) { + $row = array(); + $row[] = $this->reviewers_of_participant($user, $workshop, $peers); + $row[] = $this->participant($user); + $row[] = $this->reviewees_of_participant($user, $workshop, $peers); + $thisrowclasses = array(); + if ($user->id == $hlauthorid) { + $thisrowclasses[] = 'highlightreviewedby'; + } + if ($user->id == $hlreviewerid) { + $thisrowclasses[] = 'highlightreviewerof'; + } + $table->rowclass[] = implode(' ', $thisrowclasses); + $table->data[] = $row; + } + + return $this->output->container($this->status_message($msg) . print_table($table, true), 'manual-allocator'); + } + + + /** + * Returns html code for a status message + * + * @param string $message to display + * @return string html + */ + protected function status_message(stdClass $message) { + + if (empty($message->text)) { + return ''; + } + $sty = $message->sty ? $message->sty : 'info'; + + $o = '' . $message->text . ''; + $closer = '' . 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)); + } + + + protected function participant(stdClass $user) { + + $o = print_user_picture($user, $this->page->course->id, null, 35, true); + $o .= fullname($user); + $o .= '
' . "\n"; + if (is_null($user->submissionid)) { + $o .= '' . get_string('nosubmissionfound', 'workshop'); + } else { + $o .= ''; + if (is_null($user->submissiongrade)) { + $o .= '
' . get_string('nogradeyet', 'workshop') . '
'; + } else { + $o .= '
' . s($user->submissiongrade) . '
'; // todo calculate + } + } + $o .= '
' . "\n"; + + return $o; + } + + + protected function reviewers_of_participant(stdClass $user, workshop $workshop, &$peers) { + + $o = ''; + if (is_null($user->submissionid)) { + $o .= '' . "\n"; + $o .= get_string('nothingtoreview', 'workshop'); + $o .= '' . "\n"; + } else { + $options = array(); + foreach ($workshop->get_peer_reviewers() as $reviewer) { + $options[$reviewer->id] = fullname($reviewer); + } + if (!$workshop->useselfassessment) { + // students can not review their own submissions in this workshop + 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 .= '' . "\n"; + + return $o; + } + + + protected function reviewees_of_participant(stdClass $user, workshop $workshop, &$peers) { + + $o = ''; + if (!$workshop->assesswosubmission && is_null($user->submissionid)) { + $o .= '' . "\n"; + $o .= get_string('cantassesswosubmission', 'workshop'); + $o .= '' . "\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 .= '' . "\n"; + } + + return $o; + } + +} + + + + + + + diff --git a/mod/workshop/allocation/manual/ui.css b/mod/workshop/allocation/manual/ui.css deleted file mode 100644 index 1439d6749b..0000000000 --- a/mod/workshop/allocation/manual/ui.css +++ /dev/null @@ -1,81 +0,0 @@ -.allocations { - margin: 0px auto; -} - -.allocations .r0 { - background-color: #eee; -} - -.allocations .highlight { - background-color: #fff3d2; -} - -.allocations tr td { - vertical-align: top; - padding: 5px; -} - -.allocations tr td.peer { - border-left: 1px solid #ccc; - border-right: 1px solid #ccc; -} - -.allocations .reviewedby .info, -.allocations .peer .info, -.allocations .reviewerof .info { - font-size: 80%; - color: #888; - font-style: italic; -} - -.allocations .reviewedby img.userpicture, -.allocations .reviewerof img.userpicture { - height: 16px; - width: 16px; - margin-right: 3px; - vertical-align: middle; -} - -.allocations .peer img.userpicture { - height: 35px; - width: 35px; - vertical-align: middle; - margin-right: 5px; -} - -.allocations .peer .submission { - font-size: 90%; - margin-top: 1em; -} - -#message { - padding: 5px 5em 5px 15px; - margin: 0px auto 20px auto; - width: 60%; - font-size: 80%; - position: relative; -} - -#message-close { - font-weight: bold; - position: absolute; - top: 5px; - right: 15px; -} - -#message.ok { - color: #547c22; - background-color: #e7f1c3; -} - -#message.error { - color: #dd0221; - background-color: #ffd3d9; -} - -#message.info { - color: #1666a9; - background-color: #d2ebff; -} - - diff --git a/mod/workshop/locallib.php b/mod/workshop/locallib.php index 8d31faf6e7..079c9bee7b 100644 --- a/mod/workshop/locallib.php +++ b/mod/workshop/locallib.php @@ -56,6 +56,7 @@ class workshop_api extends workshop { * @param object $md Course module record */ public function __construct($instance, $cm) { + parent::__construct($instance, $cm); } @@ -63,21 +64,33 @@ class workshop_api extends workshop { /** * Fetches all users with the capability mod/workshop:submit in the current context * - * Static variable used to cache the results. The returned objects contain id, lastname + * Static variables 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 + * @param bool $musthavesubmission If true, returns only users with existing submission. All possible authors otherwise. * @return array Array of '(int)userid => (stdClass)userinfo' */ - public function get_peer_authors() { - static $users=null; + public function get_peer_authors($musthavesubmission=false) { + global $DB; + 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:submit', 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true); } - return $users; + + if ($musthavesubmission && is_null($userswithsubmission)) { + $userswithsubmission = $DB->get_records_list('workshop_submissions', 'userid', array_keys($users),'', 'userid'); + $userswithsubmission = array_intersect_key($users, $userswithsubmission); + } + + if ($musthavesubmission) { + return $userswithsubmission; + } else { + return $users; + } } @@ -98,24 +111,13 @@ class workshop_api extends workshop { $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) { - $userswithsubmission = array(); - // users without their own submission can not be reviewers - $rs = $DB->get_recordset_list('workshop_submissions', 'userid', array_keys($users),'', 'id,userid'); - foreach ($rs as $submission) { - if (isset($users[$submission->userid])) { - $userswithsubmission[$submission->userid] = 'submission_exists'; - } else { - // this is a submission by a user who does not have mod/workshop:peerassess - // this is either bug or workshop capabilities have been overridden after the submission - } + if (!$this->assesswosubmission) { + // 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); } - $rs->close(); - return array_intersect_key($users, $userswithsubmission); - } else { - return $users; } + return $users; } @@ -130,7 +132,7 @@ class workshop_api extends workshop { * @todo unittest * @return object moodle_recordset */ - public function get_submissions($userid='all', $examples=false) { + public function get_submissions_recordset($userid='all', $examples=false) { global $DB; $sql = 'SELECT s.*, u.lastname AS authorlastname, u.firstname AS authorfirstname @@ -169,7 +171,7 @@ class workshop_api extends workshop { * @param mixed $id 'all'|int Assessment ID * @return object moodle_recordset */ - public function get_assessments($reviewerid='all', $id='all') { + public function get_assessments_recordset($reviewerid='all', $id='all') { global $DB; $sql = 'SELECT a.*, @@ -220,7 +222,7 @@ class workshop_api extends workshop { * * @return object moodle_recordset */ - public function get_allocations() { + public function get_allocations_recordset() { global $DB; static $users=null; @@ -325,10 +327,48 @@ class workshop_api extends workshop { } + /** + * 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) { + $forms[$allocation] = get_string('allocation' . $allocation, 'workshop'); + } + // usability - make sure that manual allocation appears the first + if (isset($forms['manual'])) { + $m = array('manual' => $forms['manual']); + unset($forms['manual']); + $forms = array_merge($m, $forms); + } + 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'); + } + $classname = 'workshop_' . $method . '_allocator'; + return new $classname($this); + } + + +} /** diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php new file mode 100644 index 0000000000..6250f9cf94 --- /dev/null +++ b/mod/workshop/renderer.php @@ -0,0 +1,62 @@ +. + + +/** + * All workshop module renderers are defined here + * + * @package mod-workshop + * @copyright 2009 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Workshop module renderer class + * + * @package + * @version $Id$ + * @copyright + * @author David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class moodle_mod_workshop_renderer { + + /** 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 + * @return void + */ + public function __construct($page, $output) { + $this->page = $page; + $this->output = $output; + } + + + +} diff --git a/mod/workshop/styles.php b/mod/workshop/styles.php new file mode 100644 index 0000000000..b3dd88c0a5 --- /dev/null +++ b/mod/workshop/styles.php @@ -0,0 +1,86 @@ +/** + * Manual allocator + */ + +.manual-allocator .allocations { + margin: 0px auto; +} + +.manual-allocator .allocations .r0 { + background-color: #eee; +} + +.manual-allocator .allocations .highlightreviewedby .reviewedby, +.manual-allocator .allocations .highlightreviewerof .reviewerof { + background-color: #fff3d2; +} + +.manual-allocator .allocations tr td { + vertical-align: top; + padding: 5px; +} + +.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 { + font-size: 80%; + color: #888; + font-style: italic; +} + +.manual-allocator .allocations .reviewedby img.userpicture, +.manual-allocator .allocations .reviewerof img.userpicture { + height: 16px; + width: 16px; + margin-right: 3px; + vertical-align: middle; +} + +.manual-allocator .allocations .peer img.userpicture { + height: 35px; + width: 35px; + vertical-align: middle; + margin-right: 5px; +} + +.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; +} + + diff --git a/mod/workshop/view.php b/mod/workshop/view.php index 871c167f28..eb583ab7a5 100644 --- a/mod/workshop/view.php +++ b/mod/workshop/view.php @@ -31,56 +31,34 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); require_once(dirname(__FILE__).'/locallib.php'); $id = optional_param('id', 0, PARAM_INT); // course_module ID, or -$a = optional_param('a', 0, PARAM_INT); // workshop instance ID +$w = optional_param('w', 0, PARAM_INT); // workshop instance ID if ($id) { - if (! $cm = get_coursemodule_from_id('workshop', $id)) { - error('Course Module ID was incorrect'); - } - - if (! $course = $DB->get_record('course', array('id' => $cm->course))) { - error('Course is misconfigured'); - } - - if (! $workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { - error('Course module is incorrect'); - } - -} else if ($a) { - if (! $workshop = $DB->get_record('workshop', array('id' => $a))) { - error('Course module is incorrect'); - } - if (! $course = $DB->get_record('course', array('id' => $workshop->course))) { - error('Course is misconfigured'); - } - if (! $cm = get_coursemodule_from_instance('workshop', $workshop->id, $course->id)) { - error('Course Module ID was incorrect'); - } - + $cm = get_coursemodule_from_id('workshop', $id, 0, false, MUST_EXIST); + $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); + $workshop = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST); } else { - error('You must specify a course_module ID or an instance ID'); + $workshop = $DB->get_record('workshop', array('id' => $w), '*', MUST_EXIST); + $course = $DB->get_record('course', array('id' => $workshop->course), '*', MUST_EXIST); + $cm = get_coursemodule_from_instance('workshop', $workshop->id, $course->id, false, MUST_EXIST); } +$workshop = new workshop_api($workshop, $cm); require_login($course, true, $cm); - $context = $PAGE->context; -$workshop = new workshop_api($workshop, $cm); -// todo has_capability() check +// todo has_capability() check using something like +// if (!(($workshop->is_open() && has_capability('mod/workshop:view')) || has_capability(...) || has_capability(...))) { +// unable to view this page +// add_to_log($course->id, "workshop", "view", "view.php?id=$cm->id", "$workshop->id"); -/// Print the page header - $PAGE->set_url('mod/workshop/view.php', array('id' => $cm->id)); $PAGE->set_title($workshop->name); $PAGE->set_heading($course->fullname); $PAGE->set_button(update_module_button($cm->id, $course->id, get_string('modulename', 'workshop'))); -// other things you may want to set - remove if not needed -//$PAGE->set_cacheable(false); -//$PAGE->set_focuscontrol('some-html-id'); - // todo navigation will be changed yet for Moodle 2.0 $navlinks = array(); $navlinks[] = array('name' => get_string('modulenameplural', 'workshop'), @@ -92,8 +70,12 @@ $navlinks[] = array('name' => format_string($workshop->name), $navigation = build_navigation($navlinks); $menu = navmenu($course, $cm); +$output = $THEME->get_renderer('mod_workshop', $PAGE); + echo $OUTPUT->header($navigation, $menu); +echo $OUTPUT->heading('Workshop administration tools', 3); + /// Print the main part of the page - todo these are just links to help during development echo $OUTPUT->box_start(); @@ -112,7 +94,7 @@ echo $OUTPUT->box_end(); echo $OUTPUT->box_start(); echo $OUTPUT->heading(get_string('assessment', 'workshop'), 3); -$rs = $workshop->get_assessments($USER->id); +$rs = $workshop->get_assessments_recordset($USER->id); echo "You are expected to assess following submissions:"; echo "
    "; foreach ($rs as $assessment) { -- 2.39.5