$wsoutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE);
echo $OUTPUT->header();
-$allocators = $workshop->installed_allocators();
+$allocators = workshop::installed_allocators();
$currenttab = 'allocation';
include(dirname(__FILE__) . '/tabs.php');
*/
class workshop_manual_allocator implements workshop_allocator {
+ /** participants per page */
+ const PERPAGE = 30;
+
/** constants that are used to pass status messages between init() and ui() */
const MSG_ADDED = 1;
const MSG_NOSUBMISSION = 2;
* Prints user interface - current allocation and a form to edit it
*/
public function ui() {
- global $PAGE, $OUTPUT;
+ global $PAGE, $OUTPUT, $DB;
+ $pagingvar = 'page';
+ $page = optional_param($pagingvar, 0, PARAM_INT);
$hlauthorid = -1; // highlight this author
$hlreviewerid = -1; // highlight this reviewer
$msg = new stdClass(); // message to render
- $m = optional_param('m', '', PARAM_ALPHANUMEXT); // message stdClass
+ $m = optional_param('m', '', PARAM_ALPHANUMEXT); // message code
if ($m) {
- $m = explode('-', $m); // unserialize
+ $m = explode('-', $m);
switch ($m[0]) {
case self::MSG_ADDED:
$hlauthorid = $m[1];
}
}
- $peers = array();
- $rs = $this->workshop->get_allocations_recordset();
- if (!is_null($rs)) {
- foreach ($rs as $allocation) {
- $currentuserid = $allocation->authorid;
- if (!isset($peers[$currentuserid])) {
- $peers[$currentuserid] = new stdClass();
- $peers[$currentuserid]->id = $allocation->authorid;
- $peers[$currentuserid]->firstname = $allocation->authorfirstname;
- $peers[$currentuserid]->lastname = $allocation->authorlastname;
- $peers[$currentuserid]->picture = $allocation->authorpicture;
- $peers[$currentuserid]->imagealt = $allocation->authorimagealt;
- $peers[$currentuserid]->submissionid = $allocation->submissionid;
- $peers[$currentuserid]->submissiontitle = $allocation->submissiontitle;
- $peers[$currentuserid]->submissiongrade = $allocation->submissiongrade;
- $peers[$currentuserid]->reviewedby = array(); // users who are reviewing this user's submission
- $peers[$currentuserid]->reviewerof = array(); // users whom submission is being reviewed by this user
- }
- if (!empty($allocation->reviewerid)) {
- // example: "submission of user with id 45 is reviewed by user with id 87 in the assessment record 12"
- $peers[$currentuserid]->reviewedby[$allocation->reviewerid] = $allocation->assessmentid;
+ if ($hlauthorid > 0 and $hlreviewerid > 0) {
+ // display just those users, no pagination
+ $participants = get_users_by_capability($PAGE->context, array('mod/workshop:submit', 'mod/workshop:peerassess'),
+ 'u.id,u.lastname,u.firstname,u.picture,u.imagealt', 'u.lastname,u.firstname,u.id',
+ '', '', '', '', false, false, true);
+ $participants = array_intersect_key($participants, array($hlauthorid => null, $hlreviewerid => null));
+ } else {
+ // the paginated list of users to be displayed in the middle column ("Participant")
+ $participants = get_users_by_capability($PAGE->context, array('mod/workshop:submit', 'mod/workshop:peerassess'),
+ 'u.id,u.lastname,u.firstname,u.picture,u.imagealt', 'u.lastname,u.firstname,u.id',
+ $page * self::PERPAGE, self::PERPAGE, '', '', false, false, true);
+ }
+
+
+ // this will hold the information needed to display user names and pictures
+ $userinfo = $participants;
+
+ // load the participants' submissions
+ $submissions = $this->workshop->get_submissions(array_keys($participants), false);
+
+ // get current reviewers
+ $reviewers = array();
+ if ($submissions) {
+ list($submissionids, $params) = $DB->get_in_or_equal(array_keys($submissions), SQL_PARAMS_NAMED);
+ $sql = "SELECT a.id AS assessmentid, a.submissionid,
+ r.id AS reviewerid, r.lastname, r.firstname, r.picture, r.imagealt,
+ s.id AS submissionid, s.userid AS authorid
+ FROM {workshop_assessments} a
+ JOIN {user} r ON (a.userid = r.id)
+ JOIN {workshop_submissions} s ON (a.submissionid = s.id)
+ WHERE a.submissionid $submissionids";
+ $reviewers = $DB->get_records_sql($sql, $params);
+ foreach ($reviewers as $reviewer) {
+ if (!isset($userinfo[$reviewer->reviewerid])) {
+ $userinfo[$reviewer->reviewerid] = new stdClass();
+ $userinfo[$reviewer->reviewerid]->id = $reviewer->reviewerid;
+ $userinfo[$reviewer->reviewerid]->firstname = $reviewer->firstname;
+ $userinfo[$reviewer->reviewerid]->lastname = $reviewer->lastname;
+ $userinfo[$reviewer->reviewerid]->picture = $reviewer->picture;
+ $userinfo[$reviewer->reviewerid]->imagealt = $reviewer->imagealt;
+ $userinfo[$reviewer->reviewerid]->firstname = $reviewer->firstname;
}
}
- $rs->close();
}
- foreach ($peers as $author) {
- foreach ($author->reviewedby as $reviewerid => $assessmentid) {
- if (isset($peers[$reviewerid])) {
- // example: "user with id 87 is reviewer of the work submitted by user id 45 in the assessment record 12"
- $peers[$reviewerid]->reviewerof[$author->id] = $assessmentid;
- }
+ // get current reviewees
+ list($participantids, $params) = $DB->get_in_or_equal(array_keys($participants), SQL_PARAMS_NAMED);
+ $params['workshopid'] = $this->workshop->id;
+ $sql = "SELECT a.id AS assessmentid, a.submissionid,
+ u.id AS reviewerid,
+ s.id AS submissionid,
+ r.id AS revieweeid, r.lastname, r.firstname, r.picture, r.imagealt
+ FROM {user} u
+ JOIN {workshop_assessments} a ON (a.userid = u.id)
+ JOIN {workshop_submissions} s ON (a.submissionid = s.id)
+ JOIN {user} r ON (s.userid = r.id)
+ WHERE u.id $participantids AND s.workshopid = :workshopid";
+ $reviewees = $DB->get_records_sql($sql, $params);
+ foreach ($reviewees as $reviewee) {
+ if (!isset($userinfo[$reviewee->revieweeid])) {
+ $userinfo[$reviewee->revieweeid] = new stdClass();
+ $userinfo[$reviewee->revieweeid]->id = $reviewee->revieweeid;
+ $userinfo[$reviewee->revieweeid]->firstname = $reviewee->firstname;
+ $userinfo[$reviewee->revieweeid]->lastname = $reviewee->lastname;
+ $userinfo[$reviewee->revieweeid]->picture = $reviewee->picture;
+ $userinfo[$reviewee->revieweeid]->imagealt = $reviewee->imagealt;
+ $userinfo[$reviewee->revieweeid]->firstname = $reviewee->firstname;
}
}
+ // the information about the allocations
+ $allocations = array();
+
+ foreach ($participants as $participant) {
+ $allocations[$participant->id] = new stdClass;
+ $allocations[$participant->id]->userid = $participant->id;
+ $allocations[$participant->id]->submissionid = null;
+ $allocations[$participant->id]->reviewedby = array();
+ $allocations[$participant->id]->reviewerof = array();
+ }
+ unset($participants);
+ foreach ($submissions as $submission) {
+ $allocations[$submission->authorid]->submissionid = $submission->id;
+ $allocations[$submission->authorid]->submissiontitle = $submission->title;
+ $allocations[$submission->authorid]->submissiongrade = $submission->grade;
+ }
+ unset($submissions);
+ foreach($reviewers as $reviewer) {
+ $allocations[$reviewer->authorid]->reviewedby[$reviewer->reviewerid] = $reviewer->assessmentid;
+ }
+ unset($reviewers);
+ foreach($reviewees as $reviewee) {
+ $allocations[$reviewee->reviewerid]->reviewerof[$reviewee->revieweeid] = $reviewee->assessmentid;
+ }
+ unset($reviewees);
+
// we have all data, let us pass it to the renderer and return the output
$wsoutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE);
$uioutput = $PAGE->theme->get_renderer('workshopallocation_manual', $PAGE);
+
// prepare data to be displayed
- $data = new stdClass();
- $data->wsoutput = $wsoutput;
- $data->peers = $peers;
- $data->authors = $this->workshop->get_potential_authors($PAGE->context);
- $data->reviewers = $this->workshop->get_potential_reviewers($PAGE->context);
- $data->hlauthorid = $hlauthorid;
- $data->hlreviewerid = $hlreviewerid;
- $data->msg = $msg;
- $data->useselfassessment = $this->workshop->useselfassessment;
-
- return $uioutput->display_allocations($data);
+ $data = new stdClass();
+ $data->wsoutput = $wsoutput;
+ $data->allocations = $allocations;
+ $data->userinfo = $userinfo;
+ $data->authors = $this->workshop->get_potential_authors($PAGE->context);
+ $data->reviewers = $this->workshop->get_potential_reviewers($PAGE->context);
+ $data->hlauthorid = $hlauthorid;
+ $data->hlreviewerid = $hlreviewerid;
+ $data->selfassessment = $this->workshop->useselfassessment;
+
+ // prepare paging bar
+ $pagingbar = new moodle_paging_bar();
+ $pagingbar->totalcount = count($data->authors);
+ $pagingbar->page = $page;
+ $pagingbar->perpage = self::PERPAGE;
+ $pagingbar->baseurl = $PAGE->url;
+ $pagingbar->pagevar = $pagingvar;
+ $pagingbar->nocurr = true;
+
+ $pagingbarout = $OUTPUT->paging_bar($pagingbar);
+
+ return $pagingbarout . $wsoutput->status_message($msg) . $uioutput->display_allocations($data) . $pagingbarout;
}
+ /**
+ * Returns the list of all allocations where the given users are involved
+ *
+ * We must use recordset here because we do not have any unique identifier available
+ *
+ * @param array [userid] => whatever
+ * @return moodle_recordset|null
+ */
+ protected function get_allocations_recordset(array $users) {
+ global $DB, $PAGE;
+
+ if (empty($users)) {
+ return null;
+ }
+ if (count($users) > 9999) {
+ throw coding_exception('two many users');
+ }
+
+ list($authorids, $authorparams) = $DB->get_in_or_equal(array_keys($users), SQL_PARAMS_NAMED, 'a0000');
+ list($reviewerids, $reviewerparams) = $DB->get_in_or_equal(array_keys($users), SQL_PARAMS_NAMED, 'r0000');
+ $params = array_merge($authorparams, $reviewerparams);
+ $params['workshopid'] = $this->workshop->id;
+
+ $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,
+ reviewer.firstname AS reviewerfirstname, reviewer.lastname AS reviewerlastname,
+ reviewer.picture as reviewerpicture, reviewer.imagealt AS reviewerimagealt
+ FROM {user} author
+ LEFT JOIN {workshop_submissions} s ON (s.userid = author.id)
+ LEFT JOIN {workshop_assessments} a ON (s.id = a.submissionid)
+ LEFT JOIN {user} reviewer ON (a.userid = reviewer.id)
+ WHERE (author.id $authorids OR reviewer.id $reviewerids) AND (s.id IS NULL OR s.workshopid = :workshopid)
+ ORDER BY author.lastname,author.firstname,author.id,reviewer.lastname,reviewer.firstname,reviewer.id";
+
+ return $DB->get_recordset_sql($sql, $params);
+ }
+
+
+
}
*/
public function display_allocations(stdClass $data) {
$wsoutput = $data->wsoutput; // moodle_mod_workshop_renderer
- $peers = $data->peers; // array prepared array of all allocations data
- $authors = $data->authors; // array submission authors
+ $allocations = $data->allocations; // array prepared array of all allocations data
+ $userinfo = $data->userinfo; // names and pictures of all required users
+ $authors = $data->authors; // array potential reviewees
$reviewers = $data->reviewers; // array potential submission reviewers
$hlauthorid = $data->hlauthorid; // int id of the author to highlight
$hlreviewerid = $data->hlreviewerid; // int id of the reviewer to highlight
- $useselfassessment = $data->useselfassessment; // bool is the self-assessment allowed in this workshop?
- $msg = $data->msg; // stdClass message to display
+ $selfassessment = $data->selfassessment; // bool is the self-assessment allowed in this workshop?
$wsoutput = $this->page->theme->get_renderer('mod_workshop', $this->page);
- if (empty($peers)) {
+ if (empty($allocations)) {
return $wsoutput->status_message((object)array('text' => get_string('nosubmissions', 'workshop')));
}
$table->rowclasses = array();
$table->colclasses = array('reviewedby', 'peer', 'reviewerof');
$table->data = array();
- foreach ($peers as $user) {
+ foreach ($allocations as $allocation) {
$row = array();
- $row[] = $this->reviewers_of_participant($user, $peers, $reviewers, $useselfassessment);
- $row[] = $this->participant($user);
- $row[] = $this->reviewees_of_participant($user, $peers, $authors, $useselfassessment);
+ $row[] = $this->reviewers_of_participant($allocation, $userinfo, $reviewers, $selfassessment);
+ $row[] = $this->participant($allocation, $userinfo);
+ $row[] = $this->reviewees_of_participant($allocation, $userinfo, $authors, $selfassessment);
$thisrowclasses = array();
- if ($user->id == $hlauthorid) {
+ if ($allocation->userid == $hlauthorid) {
$thisrowclasses[] = 'highlightreviewedby';
}
- if ($user->id == $hlreviewerid) {
+ if ($allocation->userid == $hlreviewerid) {
$thisrowclasses[] = 'highlightreviewerof';
}
$table->rowclasses[] = implode(' ', $thisrowclasses);
$table->data[] = $row;
}
- return $this->output->container($wsoutput->status_message($msg) . $this->output->table($table), 'manual-allocator');
+ return $this->output->container($this->output->table($table), 'manual-allocator');
}
/**
* Returns information about the workshop participant
*
- * @param stdClass $user participant data
- * @param workshop API
* @return string HTML code
*/
- protected function participant(stdClass $user) {
- $o = $this->output->user_picture($user, $this->page->course->id);
- $o .= fullname($user);
+ protected function participant(stdClass $allocation, array $userinfo) {
+ $o = $this->output->user_picture($userinfo[$allocation->userid], $this->page->course->id);
+ $o .= fullname($userinfo[$allocation->userid]);
$o .= $this->output->container_start(array('submission'));
- if (is_null($user->submissionid)) {
+ if (is_null($allocation->submissionid)) {
$o .= $this->output->container(get_string('nosubmissionfound', 'workshop'), 'info');
} else {
- $o .= $this->output->container(format_string($user->submissiontitle), 'title');
- if (is_null($user->submissiongrade)) {
+ $o .= $this->output->container(format_string($allocation->submissiontitle), 'title');
+ if (is_null($allocation->submissiongrade)) {
$o .= $this->output->container(get_string('nogradeyet', 'workshop'), array('grade', 'missing'));
} else {
$o .= $this->output->container(get_string('alreadygraded', 'workshop'), array('grade', 'missing'));
/**
* Returns information about the current reviewers of the given participant and a selector do add new one
*
- * @param stdClass $user participant data
- * @param array $peers objects with properties to display picture and fullname
- * @param array $reviewers potential reviewers
- * @param bool $useselfassessment shall a user be offered as a reviewer of him/herself
* @return string html code
*/
- protected function reviewers_of_participant(stdClass $user, array $peers, array $reviewers, $useselfassessment) {
+ protected function reviewers_of_participant(stdClass $allocation, array $userinfo, array $reviewers, $selfassessment) {
$o = '';
- if (is_null($user->submissionid)) {
+ if (is_null($allocation->submissionid)) {
$o .= $this->output->container(get_string('nothingtoreview', 'workshop'), 'info');
} else {
$exclude = array();
- if (! $useselfassessment) {
- $exclude[$user->id] = true;
+ if (! $selfassessment) {
+ $exclude[$allocation->userid] = true;
}
// todo add an option to exclude users without own submission
$options = $this->users_to_menu_options($reviewers, $exclude);
if ($options) {
- $handler = new moodle_url($this->page->url, array('mode' => 'new', 'of' => $user->id, 'sesskey' => sesskey()));
- $select = html_select::make_popup_form($handler, 'by', $options, 'addreviewof' . $user->id, '',
- get_string('addreviewer', 'workshopallocation_manual'));
+ $handler = new moodle_url($this->page->url,
+ array('mode' => 'new', 'of' => $allocation->userid, 'sesskey' => sesskey()));
+ $select = html_select::make_popup_form($handler, 'by', $options, 'addreviewof' . $allocation->userid, '',
+ get_string('addreviewer', 'workshopallocation_manual'));
$select->nothinglabel = get_string('chooseuser', 'workshop');
$select->set_label(get_string('addreviewer', 'workshopallocation_manual'), $select->id);
$o .= $this->output->select($select);
}
}
$o .= $this->output->output_start_tag('ul', array());
- foreach ($user->reviewedby as $reviewerid => $assessmentid) {
+ foreach ($allocation->reviewedby as $reviewerid => $assessmentid) {
$o .= $this->output->output_start_tag('li', array());
- $userpic = new moodle_user_picture();
- $userpic->user = $peers[$reviewerid];
- $userpic->courseid = $this->page->course->id;
- $userpic->size = 16;
- $o .= $this->output->user_picture($userpic);
- $o .= fullname($peers[$reviewerid]);
+ $allocationpic = new moodle_user_picture();
+ $allocationpic->user = $userinfo[$reviewerid];
+ $allocationpic->courseid = $this->page->course->id;
+ $allocationpic->size = 16;
+ $o .= $this->output->user_picture($allocationpic);
+ $o .= fullname($userinfo[$reviewerid]);
// delete icon
$handler = new moodle_url($this->page->url, array('mode' => 'del', 'what' => $assessmentid, 'sesskey' => sesskey()));
/**
* Returns information about the current reviewees of the given participant and a selector do add new one
*
- * @param stdClass $user participant data
- * @param array $peers objects with properties to display picture and fullname
- * @param array $authors potential authors to be reviewed
- * @param bool $useselfassessment shall a user be offered as a reviewer of him/herself
* @return string html code
*/
- protected function reviewees_of_participant(stdClass $user, array $peers, array $authors, $useselfassessment) {
+ protected function reviewees_of_participant(stdClass $allocation, array $userinfo, array $authors, $selfassessment) {
$o = '';
- if (is_null($user->submissionid)) {
+ if (is_null($allocation->submissionid)) {
$o .= $this->output->container(get_string('withoutsubmission', 'workshop'), 'info');
}
$exclude = array();
- if (! $useselfassessment) {
- $exclude[$user->id] = true;
+ if (! $selfassessment) {
+ $exclude[$allocation->userid] = true;
$o .= $this->output->container(get_string('selfassessmentdisabled', 'workshop'), 'info');
}
// todo add an option to exclude users without own submission
$options = $this->users_to_menu_options($authors, $exclude);
if ($options) {
- $handler = new moodle_url($this->page->url, array('mode' => 'new', 'by' => $user->id, 'sesskey' => sesskey()));
- $select = html_select::make_popup_form($handler, 'of', $options, 'addreviewby' . $user->id, '',
- get_string('addreviewee', 'workshopallocation_manual'));
+ $handler = new moodle_url($this->page->url,
+ array('mode' => 'new', 'by' => $allocation->userid, 'sesskey' => sesskey()));
+ $select = html_select::make_popup_form($handler, 'of', $options, 'addreviewby' . $allocation->userid, '',
+ get_string('addreviewee', 'workshopallocation_manual'));
$select->nothinglabel = get_string('chooseuser', 'workshop');
$select->set_label(get_string('addreviewee', 'workshopallocation_manual'), $select->id);
$o .= $this->output->select($select);
$o .= $this->output->container(get_string('nothingtoreview', 'workshop'), 'info');
}
$o .= $this->output->output_start_tag('ul', array());
- foreach ($user->reviewerof as $authorid => $assessmentid) {
+ foreach ($allocation->reviewerof as $authorid => $assessmentid) {
$o .= $this->output->output_start_tag('li', array());
- $userpic = new moodle_user_picture();
- $userpic->user = $peers[$authorid];
- $userpic->courseid = $this->page->course->id;
- $userpic->size = 16;
- $o .= $this->output->user_picture($userpic, $this->page->course->id);
- $o .= fullname($peers[$authorid]);
+ $allocationpic = new moodle_user_picture();
+ $allocationpic->user = $userinfo[$authorid];
+ $allocationpic->courseid = $this->page->course->id;
+ $allocationpic->size = 16;
+ $o .= $this->output->user_picture($allocationpic, $this->page->course->id);
+ $o .= fullname($userinfo[$authorid]);
// delete icon
$handler = new moodle_url($this->page->url, array('mode' => 'del', 'what' => $assessmentid, 'sesskey' => sesskey()));
return $this->output->action_icon($icon);
}
-
-
}
// 3rd normal form with no real performance gain
}
+ ////////////////////////////////////////////////////////////////////////////////
+ // Static methods //
+ ////////////////////////////////////////////////////////////////////////////////
+
/**
- * Given a list of user ids, returns the filtered one containing just ids of users with own submission
- *
- * Example submissions are ignored.
+ * Return list of available allocation methods
*
- * @param array $userids
- * @return array
+ * @return array Array ['string' => 'string'] of localized allocation method names
*/
- protected function users_with_submission(array $userids) {
- global $DB;
-
- if (empty($userids)) {
- return array();
+ public static function installed_allocators() {
+ $installed = get_plugin_list('workshopallocation');
+ $forms = array();
+ foreach ($installed as $allocation => $allocationpath) {
+ if (file_exists($allocationpath . '/lib.php')) {
+ $forms[$allocation] = get_string('pluginname', 'workshopallocation_' . $allocation);
+ }
}
- $userswithsubmission = array();
- list($usql, $uparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
- $sql = "SELECT id,userid
- FROM {workshop_submissions}
- WHERE example = 0 AND workshopid = :workshopid AND userid $usql";
- $params = array('workshopid' => $this->id);
- $params = array_merge($params, $uparams);
- $submissions = $DB->get_records_sql($sql, $params);
- foreach ($submissions as $submission) {
- $userswithsubmission[$submission->userid] = null;
+ // 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;
+ }
- return $userswithsubmission;
+ /**
+ * Returns an array of options for the editors that are used for submitting and assessing instructions
+ *
+ * @param stdClass $context
+ * @return array
+ */
+ public static function instruction_editors_options(stdClass $context) {
+ return array('subdirs' => 1, 'maxbytes' => 0, 'maxfiles' => EDITOR_UNLIMITED_FILES,
+ 'changeformat' => 1, 'context' => $context, 'noclean' => 1, 'trusttext' => 0);
}
+ ////////////////////////////////////////////////////////////////////////////////
+ // Workshop API //
+ ////////////////////////////////////////////////////////////////////////////////
+
/**
* Fetches all users with the capability mod/workshop:submit in the current context
*
* The returned objects contain id, lastname and firstname properties and are ordered by lastname,firstname
*
+ * @todo handle with limits and groups
* @param stdClass $context
* @param bool $musthavesubmission If true, return only users who have already submitted. All possible authors otherwise.
* @return array array[userid] => stdClass{->id ->lastname ->firstname}
*/
public function get_potential_authors(stdClass $context, $musthavesubmission=true) {
$users = get_users_by_capability($context, 'mod/workshop:submit',
- 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true);
+ 'u.id,u.lastname,u.firstname', 'u.lastname,u.firstname,u.id', 0, 1000, '', '', false, false, true);
if ($musthavesubmission) {
$users = array_intersect_key($users, $this->users_with_submission(array_keys($users)));
}
*
* The returned objects contain id, lastname and firstname properties and are ordered by lastname,firstname
*
+ * @todo handle with limits and groups
* @param stdClass $context
* @param bool $musthavesubmission If true, return only users who have already submitted. All possible users otherwise.
* @return array array[userid] => stdClass{->id ->lastname ->firstname}
*/
public function get_potential_reviewers(stdClass $context, $musthavesubmission=false) {
$users = get_users_by_capability($context, 'mod/workshop:peerassess',
- 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true);
+ 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname,u.id', 0, 1000, '', '', false, false, true);
if ($musthavesubmission) {
// users without their own submission can not be reviewers
$users = array_intersect_key($users, $this->users_with_submission(array_keys($users)));
return $grouped;
}
+ /**
+ * Returns the list of all allocations (it est assigned assessments) in the workshop
+ *
+ * Assessments of example submissions are ignored
+ *
+ * @return array
+ */
+ public function get_allocations() {
+ global $DB;
+
+ $sql = 'SELECT a.id, a.submissionid, a.userid AS reviewerid,
+ s.userid AS authorid
+ FROM {workshop_assessments} a
+ INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id)
+ WHERE s.example = 0 AND s.workshopid = :workshopid';
+ $params = array('workshopid' => $this->id);
+
+ return $DB->get_records_sql($sql, $params);
+ }
+
/**
* Returns submissions from this workshop
*
return $DB->get_records_sql($sql, $params);
}
- /**
- * 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, if such information is available (null elsewhere).
- *
- * The returned structure is recordset of objects with following properties:
- * [authorid] [authorfirstname] [authorlastname] [authorpicture] [authorimagealt]
- * [submissionid] [submissiontitle] [submissiongrade] [assessmentid]
- * [timeallocated] [reviewerid] [reviewerfirstname] [reviewerlastname]
- * [reviewerpicture] [reviewerimagealt]
- *
- * TODO 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 null|stdClass moodle_recordset
- */
- public function get_allocations_recordset() {
- global $DB, $PAGE;
-
- $users = get_users_by_capability($PAGE->context, array('mod/workshop:submit', 'mod/workshop:peerassess'),
- 'u.id', 'u.lastname,u.firstname', '', '', '', '', false, false, true);
-
- if (empty($users)) {
- return null;
- }
-
- list($usql, $params) = $DB->get_in_or_equal(array_keys($users), SQL_PARAMS_NAMED);
- $params['workshopid'] = $this->id;
-
- $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,
- reviewer.firstname AS reviewerfirstname, reviewer.lastname AS reviewerlastname,
- reviewer.picture as reviewerpicture, reviewer.imagealt AS reviewerimagealt
- FROM {user} author
- LEFT JOIN {workshop_submissions} s ON (s.userid = author.id)
- LEFT JOIN {workshop_assessments} a ON (s.id = a.submissionid)
- LEFT JOIN {user} reviewer ON (a.userid = reviewer.id)
- WHERE author.id $usql AND (s.id IS NULL OR s.workshopid = :workshopid)
- ORDER BY author.lastname,author.firstname,reviewer.lastname,reviewer.firstname";
-
- return $DB->get_recordset_sql($sql, $params);
- }
-
/**
* Allocate a submission to a user for review
*
return $this->evaluationinstance;
}
- /**
- * Return list of available allocation methods
- *
- * @return array Array ['string' => 'string'] of localized allocation method names
- */
- public function installed_allocators() {
- $installed = get_plugin_list('workshopallocation');
- $forms = array();
- foreach ($installed as $allocation => $allocationpath) {
- if (file_exists($allocationpath . '/lib.php')) {
- $forms[$allocation] = get_string('pluginname', 'workshopallocation_' . $allocation);
- }
- }
- // 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
*
$task->link = $this->allocation_url();
$authors = array();
$allocations = array(); // 'submissionid' => isallocated
- $rs = $this->get_allocations_recordset();
- if (!is_null($rs)) {
- foreach ($rs as $allocation) {
- if (!isset($authors[$allocation->authorid])) {
- $authors[$allocation->authorid] = true;
+ $records = $this->get_allocations();
+ foreach ($records as $allocation) {
+ if (!isset($authors[$allocation->authorid])) {
+ $authors[$allocation->authorid] = true;
+ }
+ if (isset($allocation->submissionid)) {
+ if (!isset($allocations[$allocation->submissionid])) {
+ $allocations[$allocation->submissionid] = false;
}
- if (isset($allocation->submissionid)) {
- if (!isset($allocations[$allocation->submissionid])) {
- $allocations[$allocation->submissionid] = false;
- }
- if (!empty($allocation->reviewerid)) {
- $allocations[$allocation->submissionid] = true;
- }
+ if (!empty($allocation->reviewerid)) {
+ $allocations[$allocation->submissionid] = true;
}
}
- $rs->close();
}
$numofauthors = count($authors);
$numofsubmissions = count($allocations);
return $this->grading_strategy_instance()->form_ready();
}
- /**
- * @return array of available workshop phases
- */
- protected function available_phases() {
- return array(
- self::PHASE_SETUP => true,
- self::PHASE_SUBMISSION => true,
- self::PHASE_ASSESSMENT => true,
- self::PHASE_EVALUATION => true,
- self::PHASE_CLOSED => true,
- );
- }
-
/**
* Switch to a new workshop phase
*
return $grade;
}
-// Static methods
+ ////////////////////////////////////////////////////////////////////////////////
+ // Internal methods (implementation details) //
+ ////////////////////////////////////////////////////////////////////////////////
/**
- * Returns an array of options for the editors that are used for submitting and assessing instructions
+ * Given a list of user ids, returns the filtered one containing just ids of users with own submission
*
- * @param stdClass $context
+ * Example submissions are ignored.
+ *
+ * @param array $userids
* @return array
*/
- public static function instruction_editors_options(stdClass $context) {
- return array('subdirs' => 1, 'maxbytes' => 0, 'maxfiles' => EDITOR_UNLIMITED_FILES,
- 'changeformat' => 1, 'context' => $context, 'noclean' => 1, 'trusttext' => 0);
+ protected function users_with_submission(array $userids) {
+ global $DB;
+
+ if (empty($userids)) {
+ return array();
+ }
+ $userswithsubmission = array();
+ list($usql, $uparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
+ $sql = "SELECT id,userid
+ FROM {workshop_submissions}
+ WHERE example = 0 AND workshopid = :workshopid AND userid $usql";
+ $params = array('workshopid' => $this->id);
+ $params = array_merge($params, $uparams);
+ $submissions = $DB->get_records_sql($sql, $params);
+ foreach ($submissions as $submission) {
+ $userswithsubmission[$submission->userid] = null;
+ }
+
+ return $userswithsubmission;
}
+ /**
+ * @return array of available workshop phases
+ */
+ protected function available_phases() {
+ return array(
+ self::PHASE_SETUP => true,
+ self::PHASE_SUBMISSION => true,
+ self::PHASE_ASSESSMENT => true,
+ self::PHASE_EVALUATION => true,
+ self::PHASE_CLOSED => true,
+ );
+ }
+
+
}