See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
1 <?php 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 18 /** 19 * Allows user to allocate the submissions manually 20 * 21 * @package workshopallocation 22 * @subpackage manual 23 * @copyright 2009 David Mudrak <david.mudrak@gmail.com> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once (__DIR__ . '/../lib.php'); // interface definition 30 require_once (__DIR__ . '/../../locallib.php'); // workshop internal API 31 32 /** 33 * Allows users to allocate submissions for review manually 34 */ 35 class workshop_manual_allocator implements workshop_allocator { 36 37 /** constants that are used to pass status messages between init() and ui() */ 38 const MSG_ADDED = 1; 39 const MSG_NOSUBMISSION = 2; 40 const MSG_EXISTS = 3; 41 const MSG_CONFIRM_DEL = 4; 42 const MSG_DELETED = 5; 43 const MSG_DELETE_ERROR = 6; 44 45 /** @var workshop instance */ 46 protected $workshop; 47 48 /** 49 * @param workshop $workshop Workshop API object 50 */ 51 public function __construct(workshop $workshop) { 52 $this->workshop = $workshop; 53 } 54 55 /** 56 * Allocate submissions as requested by user 57 * 58 * @return workshop_allocation_result 59 */ 60 public function init() { 61 global $PAGE; 62 63 $mode = optional_param('mode', 'display', PARAM_ALPHA); 64 $perpage = optional_param('perpage', null, PARAM_INT); 65 66 if ($perpage and $perpage > 0 and $perpage <= 1000) { 67 require_sesskey(); 68 set_user_preference('workshopallocation_manual_perpage', $perpage); 69 redirect($PAGE->url); 70 } 71 72 $result = new workshop_allocation_result($this); 73 74 switch ($mode) { 75 case 'new': 76 if (!confirm_sesskey()) { 77 throw new moodle_exception('confirmsesskeybad'); 78 } 79 $reviewerid = required_param('by', PARAM_INT); 80 $authorid = required_param('of', PARAM_INT); 81 $m = array(); // message object to be passed to the next page 82 $submission = $this->workshop->get_submission_by_author($authorid); 83 if (!$submission) { 84 // nothing submitted by the given user 85 $m[] = self::MSG_NOSUBMISSION; 86 $m[] = $authorid; 87 88 } else { 89 // ok, we have the submission 90 $res = $this->workshop->add_allocation($submission, $reviewerid); 91 if ($res == workshop::ALLOCATION_EXISTS) { 92 $m[] = self::MSG_EXISTS; 93 $m[] = $submission->authorid; 94 $m[] = $reviewerid; 95 } else { 96 $m[] = self::MSG_ADDED; 97 $m[] = $submission->authorid; 98 $m[] = $reviewerid; 99 } 100 } 101 $m = implode('-', $m); // serialize message object to be passed via URL 102 redirect($PAGE->url->out(false, array('m' => $m))); 103 break; 104 case 'del': 105 if (!confirm_sesskey()) { 106 throw new moodle_exception('confirmsesskeybad'); 107 } 108 $assessmentid = required_param('what', PARAM_INT); 109 $confirmed = optional_param('confirm', 0, PARAM_INT); 110 $assessment = $this->workshop->get_assessment_by_id($assessmentid); 111 if ($assessment) { 112 if (!$confirmed) { 113 $m[] = self::MSG_CONFIRM_DEL; 114 $m[] = $assessment->id; 115 $m[] = $assessment->authorid; 116 $m[] = $assessment->reviewerid; 117 if (is_null($assessment->grade)) { 118 $m[] = 0; 119 } else { 120 $m[] = 1; 121 } 122 } else { 123 if($this->workshop->delete_assessment($assessment->id)) { 124 $m[] = self::MSG_DELETED; 125 $m[] = $assessment->authorid; 126 $m[] = $assessment->reviewerid; 127 } else { 128 $m[] = self::MSG_DELETE_ERROR; 129 $m[] = $assessment->authorid; 130 $m[] = $assessment->reviewerid; 131 } 132 } 133 $m = implode('-', $m); // serialize message object to be passed via URL 134 redirect($PAGE->url->out(false, array('m' => $m))); 135 } 136 break; 137 } 138 139 $result->set_status(workshop_allocation_result::STATUS_VOID); 140 return $result; 141 } 142 143 /** 144 * Prints user interface - current allocation and a form to edit it 145 */ 146 public function ui() { 147 global $PAGE, $DB; 148 149 $output = $PAGE->get_renderer('workshopallocation_manual'); 150 151 $page = optional_param('page', 0, PARAM_INT); 152 $perpage = get_user_preferences('workshopallocation_manual_perpage', 10); 153 $groupid = groups_get_activity_group($this->workshop->cm, true); 154 155 $hlauthorid = -1; // highlight this author 156 $hlreviewerid = -1; // highlight this reviewer 157 158 $message = new workshop_message(); 159 160 $m = optional_param('m', '', PARAM_ALPHANUMEXT); // message code 161 if ($m) { 162 $m = explode('-', $m); 163 switch ($m[0]) { 164 case self::MSG_ADDED: 165 $hlauthorid = $m[1]; 166 $hlreviewerid = $m[2]; 167 $message = new workshop_message(get_string('allocationadded', 'workshopallocation_manual'), 168 workshop_message::TYPE_OK); 169 break; 170 case self::MSG_EXISTS: 171 $hlauthorid = $m[1]; 172 $hlreviewerid = $m[2]; 173 $message = new workshop_message(get_string('allocationexists', 'workshopallocation_manual'), 174 workshop_message::TYPE_INFO); 175 break; 176 case self::MSG_NOSUBMISSION: 177 $hlauthorid = $m[1]; 178 $message = new workshop_message(get_string('nosubmissionfound', 'workshop'), 179 workshop_message::TYPE_ERROR); 180 break; 181 case self::MSG_CONFIRM_DEL: 182 $hlauthorid = $m[2]; 183 $hlreviewerid = $m[3]; 184 if ($m[4] == 0) { 185 $message = new workshop_message(get_string('areyousuretodeallocate', 'workshopallocation_manual'), 186 workshop_message::TYPE_INFO); 187 } else { 188 $message = new workshop_message(get_string('areyousuretodeallocategraded', 'workshopallocation_manual'), 189 workshop_message::TYPE_ERROR); 190 } 191 $url = new moodle_url($PAGE->url, array('mode' => 'del', 'what' => $m[1], 'confirm' => 1, 'sesskey' => sesskey())); 192 $label = get_string('iamsure', 'workshop'); 193 $message->set_action($url, $label); 194 break; 195 case self::MSG_DELETED: 196 $hlauthorid = $m[1]; 197 $hlreviewerid = $m[2]; 198 $message = new workshop_message(get_string('assessmentdeleted', 'workshop'), 199 workshop_message::TYPE_OK); 200 break; 201 case self::MSG_DELETE_ERROR: 202 $hlauthorid = $m[1]; 203 $hlreviewerid = $m[2]; 204 $message = new workshop_message(get_string('assessmentnotdeleted', 'workshop'), 205 workshop_message::TYPE_ERROR); 206 break; 207 } 208 } 209 210 // fetch the list of ids of all workshop participants 211 $numofparticipants = $this->workshop->count_participants(false, $groupid); 212 $participants = $this->workshop->get_participants(false, $groupid, $perpage * $page, $perpage); 213 214 if ($hlauthorid > 0 and $hlreviewerid > 0) { 215 // display just those two users 216 $participants = array_intersect_key($participants, array($hlauthorid => null, $hlreviewerid => null)); 217 $button = $output->single_button($PAGE->url, get_string('showallparticipants', 'workshopallocation_manual'), 'get'); 218 } else { 219 $button = ''; 220 } 221 222 // this will hold the information needed to display user names and pictures 223 $userinfo = $participants; 224 225 // load the participants' submissions 226 $submissions = $this->workshop->get_submissions(array_keys($participants)); 227 $allnames = \core_user\fields::get_name_fields(); 228 foreach ($submissions as $submission) { 229 if (!isset($userinfo[$submission->authorid])) { 230 $userinfo[$submission->authorid] = new stdclass(); 231 $userinfo[$submission->authorid]->id = $submission->authorid; 232 $userinfo[$submission->authorid]->picture = $submission->authorpicture; 233 $userinfo[$submission->authorid]->imagealt = $submission->authorimagealt; 234 $userinfo[$submission->authorid]->email = $submission->authoremail; 235 foreach ($allnames as $addname) { 236 $temp = 'author' . $addname; 237 $userinfo[$submission->authorid]->$addname = $submission->$temp; 238 } 239 } 240 } 241 242 // get current reviewers 243 $reviewers = array(); 244 if ($submissions) { 245 list($submissionids, $params) = $DB->get_in_or_equal(array_keys($submissions), SQL_PARAMS_NAMED); 246 $userfieldsapi = \core_user\fields::for_userpic(); 247 $picturefields = $userfieldsapi->get_sql('r', false, '', 'reviewerid', false)->selects; 248 $sql = "SELECT a.id AS assessmentid, a.submissionid, $picturefields, 249 s.id AS submissionid, s.authorid 250 FROM {workshop_assessments} a 251 JOIN {user} r ON (a.reviewerid = r.id) 252 JOIN {workshop_submissions} s ON (a.submissionid = s.id) 253 WHERE a.submissionid $submissionids"; 254 $reviewers = $DB->get_records_sql($sql, $params); 255 foreach ($reviewers as $reviewer) { 256 if (!isset($userinfo[$reviewer->reviewerid])) { 257 $userinfo[$reviewer->reviewerid] = new stdclass(); 258 $userinfo[$reviewer->reviewerid]->id = $reviewer->reviewerid; 259 $userinfo[$reviewer->reviewerid]->picture = $reviewer->picture; 260 $userinfo[$reviewer->reviewerid]->imagealt = $reviewer->imagealt; 261 $userinfo[$reviewer->reviewerid]->email = $reviewer->email; 262 foreach ($allnames as $addname) { 263 $userinfo[$reviewer->reviewerid]->$addname = $reviewer->$addname; 264 } 265 } 266 } 267 } 268 269 // get current reviewees 270 $reviewees = array(); 271 if ($participants) { 272 list($participantids, $params) = $DB->get_in_or_equal(array_keys($participants), SQL_PARAMS_NAMED); 273 $userfieldsapi = \core_user\fields::for_name(); 274 $namefields = $userfieldsapi->get_sql('e', false, '', '', false)->selects; 275 $params['workshopid'] = $this->workshop->id; 276 $sql = "SELECT a.id AS assessmentid, a.submissionid, 277 u.id AS reviewerid, 278 s.id AS submissionid, 279 e.id AS revieweeid, e.lastname, e.firstname, $namefields, e.picture, e.imagealt, e.email 280 FROM {user} u 281 JOIN {workshop_assessments} a ON (a.reviewerid = u.id) 282 JOIN {workshop_submissions} s ON (a.submissionid = s.id) 283 JOIN {user} e ON (s.authorid = e.id) 284 WHERE u.id $participantids AND s.workshopid = :workshopid AND s.example = 0"; 285 $reviewees = $DB->get_records_sql($sql, $params); 286 foreach ($reviewees as $reviewee) { 287 if (!isset($userinfo[$reviewee->revieweeid])) { 288 $userinfo[$reviewee->revieweeid] = new stdclass(); 289 $userinfo[$reviewee->revieweeid]->id = $reviewee->revieweeid; 290 $userinfo[$reviewee->revieweeid]->firstname = $reviewee->firstname; 291 $userinfo[$reviewee->revieweeid]->lastname = $reviewee->lastname; 292 $userinfo[$reviewee->revieweeid]->picture = $reviewee->picture; 293 $userinfo[$reviewee->revieweeid]->imagealt = $reviewee->imagealt; 294 $userinfo[$reviewee->revieweeid]->email = $reviewee->email; 295 foreach ($allnames as $addname) { 296 $userinfo[$reviewee->revieweeid]->$addname = $reviewee->$addname; 297 } 298 } 299 } 300 } 301 302 // the information about the allocations 303 $allocations = array(); 304 305 foreach ($participants as $participant) { 306 $allocations[$participant->id] = new stdClass(); 307 $allocations[$participant->id]->userid = $participant->id; 308 $allocations[$participant->id]->submissionid = null; 309 $allocations[$participant->id]->reviewedby = array(); 310 $allocations[$participant->id]->reviewerof = array(); 311 } 312 unset($participants); 313 314 foreach ($submissions as $submission) { 315 $allocations[$submission->authorid]->submissionid = $submission->id; 316 $allocations[$submission->authorid]->submissiontitle = $submission->title; 317 $allocations[$submission->authorid]->submissiongrade = $submission->grade; 318 } 319 unset($submissions); 320 foreach($reviewers as $reviewer) { 321 $allocations[$reviewer->authorid]->reviewedby[$reviewer->reviewerid] = $reviewer->assessmentid; 322 } 323 unset($reviewers); 324 foreach($reviewees as $reviewee) { 325 $allocations[$reviewee->reviewerid]->reviewerof[$reviewee->revieweeid] = $reviewee->assessmentid; 326 } 327 unset($reviewees); 328 329 // prepare data to be rendered 330 $data = new workshopallocation_manual_allocations(); 331 $data->workshop = $this->workshop; 332 $data->allocations = $allocations; 333 $data->userinfo = $userinfo; 334 $data->authors = $this->workshop->get_potential_authors(); 335 $data->reviewers = $this->workshop->get_potential_reviewers(); 336 $data->hlauthorid = $hlauthorid; 337 $data->hlreviewerid = $hlreviewerid; 338 $data->selfassessment = $this->workshop->useselfassessment; 339 340 // prepare the group selector 341 $groupselector = $output->container(groups_print_activity_menu($this->workshop->cm, $PAGE->url, true), 'groupwidget'); 342 343 // prepare paging bar 344 $pagingbar = new paging_bar($numofparticipants, $page, $perpage, $PAGE->url, 'page'); 345 $pagingbarout = $output->render($pagingbar); 346 $perpageselector = $output->perpage_selector($perpage); 347 348 return $groupselector . $pagingbarout . $output->render($message) . $output->render($data) . $button . $pagingbarout . $perpageselector; 349 } 350 351 /** 352 * Delete all data related to a given workshop module instance 353 * 354 * This plugin does not store any data. 355 * 356 * @see workshop_delete_instance() 357 * @param int $workshopid id of the workshop module instance being deleted 358 * @return void 359 */ 360 public static function delete_instance($workshopid) { 361 return; 362 } 363 } 364 365 /** 366 * Contains all information needed to render current allocations and the allocator UI 367 * 368 * @see workshop_manual_allocator::ui() 369 */ 370 class workshopallocation_manual_allocations implements renderable { 371 372 /** @var workshop module instance */ 373 public $workshop; 374 375 /** @var array of stdClass, indexed by userid, properties userid, submissionid, (array)reviewedby, (array)reviewerof */ 376 public $allocations; 377 378 /** @var array of stdClass contains the data needed to display the user name and picture */ 379 public $userinfo; 380 381 /* var array of stdClass potential authors */ 382 public $authors; 383 384 /* var array of stdClass potential reviewers */ 385 public $reviewers; 386 387 /* var int the id of the user to highlight as the author */ 388 public $hlauthorid; 389 390 /* var int the id of the user to highlight as the reviewer */ 391 public $hlreviewerid; 392 393 /* var bool should the selfassessment be allowed */ 394 public $selfassessment; 395 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body