mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 04:30:15 +01:00
MDL-19717 workshop manual allocator - pagination support and performance issues
This commit is contained in:
parent
87a5368df1
commit
aa40adbf9f
@ -57,7 +57,7 @@ $initresult = $allocator->init();
|
||||
$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');
|
||||
|
||||
|
@ -33,6 +33,9 @@ require_once(dirname(dirname(dirname(__FILE__))) . '/locallib.php'); // works
|
||||
*/
|
||||
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;
|
||||
@ -129,15 +132,17 @@ class workshop_manual_allocator implements workshop_allocator {
|
||||
* 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];
|
||||
@ -190,56 +195,170 @@ class workshop_manual_allocator implements workshop_allocator {
|
||||
}
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
// prepare data to be displayed
|
||||
$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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -56,16 +56,16 @@ class moodle_workshopallocation_manual_renderer extends moodle_renderer_base {
|
||||
*/
|
||||
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')));
|
||||
}
|
||||
|
||||
@ -77,41 +77,39 @@ class moodle_workshopallocation_manual_renderer extends moodle_renderer_base {
|
||||
$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'));
|
||||
@ -124,41 +122,38 @@ class moodle_workshopallocation_manual_renderer extends moodle_renderer_base {
|
||||
/**
|
||||
* 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()));
|
||||
@ -173,28 +168,25 @@ class moodle_workshopallocation_manual_renderer extends moodle_renderer_base {
|
||||
/**
|
||||
* 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);
|
||||
@ -202,14 +194,14 @@ class moodle_workshopallocation_manual_renderer extends moodle_renderer_base {
|
||||
$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()));
|
||||
@ -252,6 +244,4 @@ class moodle_workshopallocation_manual_renderer extends moodle_renderer_base {
|
||||
return $this->output->action_icon($icon);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -91,47 +91,60 @@ class workshop {
|
||||
// 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
|
||||
* Return list of available allocation methods
|
||||
*
|
||||
* Example submissions are ignored.
|
||||
* @return array Array ['string' => 'string'] of localized allocation method names
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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 an array of options for the editors that are used for submitting and assessing instructions
|
||||
*
|
||||
* @param array $userids
|
||||
* @param stdClass $context
|
||||
* @return array
|
||||
*/
|
||||
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;
|
||||
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)));
|
||||
}
|
||||
@ -143,13 +156,14 @@ class workshop {
|
||||
*
|
||||
* 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)));
|
||||
@ -201,6 +215,26 @@ class workshop {
|
||||
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
|
||||
*
|
||||
@ -365,56 +399,6 @@ class 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
|
||||
*
|
||||
@ -506,28 +490,6 @@ class workshop {
|
||||
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
|
||||
*
|
||||
@ -761,22 +723,19 @@ class workshop {
|
||||
$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);
|
||||
@ -914,19 +873,6 @@ class workshop {
|
||||
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
|
||||
*
|
||||
@ -966,17 +912,51 @@ class workshop {
|
||||
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,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user