Refactored the Workshop API class
[moodle.git] / mod / workshop / locallib.php
CommitLineData
de811c0c 1<?php
53fad4b9
DM
2
3// This file is part of Moodle - http://moodle.org/
4//
de811c0c
DM
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.
53fad4b9 14//
de811c0c
DM
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/>.
53fad4b9 17
de811c0c 18/**
6e309973 19 * Library of internal classes and functions for module workshop
de811c0c 20 *
53fad4b9 21 * All the workshop specific functions, needed to implement the module
6e309973 22 * logic, should go to here. Instead of having bunch of function named
53fad4b9 23 * workshop_something() taking the workshop instance as the first
a39d7d87 24 * parameter, we use a class workshop that provides all methods.
53fad4b9 25 *
de811c0c
DM
26 * @package mod-workshop
27 * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
28 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 */
30
31defined('MOODLE_INTERNAL') || die();
32
b13142da 33require_once(dirname(__FILE__).'/lib.php'); // we extend this library here
0968b1a3 34
b13142da
DM
35define('WORKSHOP_ALLOCATION_EXISTS', -1); // return status of {@link add_allocation}
36define('WORKSHOP_ALLOCATION_ERROR', -2); // can be passed to a workshop renderer method
37
38/** workshop phases */
39define('WORKSHOP_PHASE_SETUP', 10); // The moderator is setting up the workshop
40define('WORKSHOP_PHASE_SUBMISSION', 20); // Participants work on their submissions
41define('WORKSHOP_PHASE_ASSESSMENT', 30); //
42define('WORKSHOP_PHASE_EVALUATION', 40);
43define('WORKSHOP_PHASE_CLOSED', 50);
6e309973
DM
44
45/**
46 * Full-featured workshop API
47 *
a39d7d87 48 * This wraps the workshop database record with a set of methods that are called
6e309973 49 * from the module itself. The class should be initialized right after you get
a39d7d87 50 * $workshop, $cm and $course records at the begining of the script.
6e309973 51 */
a39d7d87
DM
52class workshop {
53
65ba104c 54 /** @var stdClass course module record */
a39d7d87
DM
55 public $cm = null;
56
65ba104c 57 /** @var stdClass course record */
a39d7d87 58 public $course = null;
6e309973 59
b13142da
DM
60 /** @var workshop_strategy grading strategy instance */
61 protected $strategyinstance = null;
62
63 /** @var stdClass underlying database record */
64 protected $dbrecord = null;
6e309973
DM
65
66 /**
65ba104c 67 * Initializes the workshop API instance using the data from DB
a39d7d87
DM
68 *
69 * Makes deep copy of all passed records properties. Replaces integer $course attribute
70 * with a full database record (course should not be stored in instances table anyway).
6e309973 71 *
b13142da 72 * @param stdClass $dbrecord Workshop instance data from {workshop} table
06d73dd5
DM
73 * @param stdClass $cm Course module record as returned by {@link get_coursemodule_from_id()}
74 * @param stdClass $course Course record from {course} table
0dc47fb9 75 */
b13142da
DM
76 public function __construct(stdClass $dbrecord, stdClass $cm, stdClass $course) {
77 $this->dbrecord = $dbrecord;
78 $this->cm = $cm;
79 $this->course = $course;
80 }
81
82 /**
83 * Magic method to retrieve the value of the underlying database record's field
84 *
85 * @throws coding_exception if the field does not exist
86 * @param mixed $key the name of the database field
87 * @return mixed|null the value of the field
88 */
89 public function __get($key) {
90 if (!isset($this->dbrecord->{$key})) {
91 throw new coding_exception('You are trying to get a non-existing property');
a39d7d87 92 }
b13142da 93 return $this->dbrecord->{$key};
6e309973
DM
94 }
95
6e309973
DM
96 /**
97 * Fetches all users with the capability mod/workshop:submit in the current context
98 *
3d2924e9 99 * The returned objects contain id, lastname and firstname properties and are ordered by lastname,firstname
53fad4b9
DM
100 *
101 * @param bool $musthavesubmission If true, return only users who have already submitted. All possible authors otherwise.
65ba104c 102 * @return array array[userid] => stdClass{->id ->lastname ->firstname}
6e309973 103 */
53fad4b9 104 public function get_peer_authors($musthavesubmission=true) {
66c9894d 105 global $DB;
6e309973 106
3d2924e9
DM
107 $context = get_context_instance(CONTEXT_MODULE, $this->cm->id);
108 $users = get_users_by_capability($context, 'mod/workshop:submit',
235b31c8 109 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true);
66c9894d 110
3d2924e9 111 if ($musthavesubmission) {
a39d7d87 112 $userswithsubmission = array();
235b31c8 113 $submissions = $DB->get_records_list('workshop_submissions', 'userid', array_keys($users),'', 'id,userid');
b8ead2e6
DM
114 foreach ($submissions as $submission) {
115 $userswithsubmission[$submission->userid] = null;
116 }
66c9894d
DM
117 $userswithsubmission = array_intersect_key($users, $userswithsubmission);
118 }
119
120 if ($musthavesubmission) {
121 return $userswithsubmission;
122 } else {
123 return $users;
124 }
6e309973
DM
125 }
126
6e309973
DM
127 /**
128 * Fetches all users with the capability mod/workshop:peerassess in the current context
129 *
b13142da 130 * The returned objects contain id, lastname and firstname properties and are ordered by lastname,firstname
53fad4b9
DM
131 *
132 * @param bool $musthavesubmission If true, return only users who have already submitted. All possible users otherwise.
65ba104c 133 * @return array array[userid] => stdClass{->id ->lastname ->firstname}
6e309973 134 */
53fad4b9 135 public function get_peer_reviewers($musthavesubmission=false) {
6e309973 136 global $DB;
3d2924e9
DM
137
138 $context = get_context_instance(CONTEXT_MODULE, $this->cm->id);
139 $users = get_users_by_capability($context, 'mod/workshop:peerassess',
235b31c8 140 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true);
3d2924e9
DM
141
142 if ($musthavesubmission) {
143 // users without their own submission can not be reviewers
235b31c8 144 $submissions = $DB->get_records_list('workshop_submissions', 'userid', array_keys($users),'', 'id,userid');
3d2924e9
DM
145 foreach ($submissions as $submission) {
146 $userswithsubmission[$submission->userid] = null;
6e309973 147 }
3d2924e9 148 $userswithsubmission = array_intersect_key($users, $userswithsubmission);
0968b1a3 149 }
3d2924e9 150
53fad4b9
DM
151 if ($musthavesubmission) {
152 return $userswithsubmission;
153 } else {
154 return $users;
155 }
0968b1a3
DM
156 }
157
b8ead2e6
DM
158 /**
159 * Groups the given users by the group membership
160 *
161 * This takes the module grouping settings into account. If "Available for group members only"
162 * is set, returns only groups withing the course module grouping. Always returns group [0] with
163 * all the given users.
164 *
65ba104c
DM
165 * @param array $users array[userid] => stdClass{->id ->lastname ->firstname}
166 * @return array array[groupid][userid] => stdClass{->id ->lastname ->firstname}
53fad4b9 167 */
3d2924e9 168 public function get_grouped($users) {
53fad4b9 169 global $DB;
3d2924e9 170 global $CFG;
53fad4b9 171
b8ead2e6
DM
172 $grouped = array(); // grouped users to be returned
173 if (empty($users)) {
174 return $grouped;
a7c5b918 175 }
3d2924e9 176 if (!empty($CFG->enablegroupings) and $this->cm->groupmembersonly) {
53fad4b9
DM
177 // Available for group members only - the workshop is available only
178 // to users assigned to groups within the selected grouping, or to
179 // any group if no grouping is selected.
180 $groupingid = $this->cm->groupingid;
b8ead2e6 181 // All users that are members of at least one group will be
53fad4b9 182 // added into a virtual group id 0
b8ead2e6 183 $grouped[0] = array();
53fad4b9
DM
184 } else {
185 $groupingid = 0;
b8ead2e6
DM
186 // there is no need to be member of a group so $grouped[0] will contain
187 // all users
188 $grouped[0] = $users;
53fad4b9 189 }
b8ead2e6 190 $gmemberships = groups_get_all_groups($this->cm->course, array_keys($users), $groupingid,
53fad4b9
DM
191 'gm.id,gm.groupid,gm.userid');
192 foreach ($gmemberships as $gmembership) {
b8ead2e6
DM
193 if (!isset($grouped[$gmembership->groupid])) {
194 $grouped[$gmembership->groupid] = array();
53fad4b9 195 }
b8ead2e6
DM
196 $grouped[$gmembership->groupid][$gmembership->userid] = $users[$gmembership->userid];
197 $grouped[0][$gmembership->userid] = $users[$gmembership->userid];
53fad4b9 198 }
b8ead2e6 199 return $grouped;
53fad4b9 200 }
6e309973
DM
201
202 /**
203 * Returns submissions from this workshop
204 *
205 * Fetches data from {workshop_submissions} and adds some useful information from other
206 * tables.
53fad4b9
DM
207 *
208 * @param mixed $userid int|array|'all' If set to [array of] integer, return submission[s] of the given user[s] only
209 * @param mixed $examples false|true|'all' Only regular submissions, only examples, all submissions
65ba104c 210 * @return stdClass moodle_recordset
6e309973 211 */
66c9894d 212 public function get_submissions_recordset($userid='all', $examples=false) {
6e309973
DM
213 global $DB;
214
235b31c8 215 $sql = 'SELECT s.*, u.lastname AS authorlastname, u.firstname AS authorfirstname
3d2924e9
DM
216 FROM {workshop_submissions} s
217 INNER JOIN {user} u ON (s.userid = u.id)
235b31c8 218 WHERE s.workshopid = :workshopid';
3d2924e9 219 $params = array('workshopid' => $this->id);
6e309973 220
b13142da
DM
221 if ('all' === $examples) {
222 // no additional conditions
223 } elseif ($examples === true) {
235b31c8 224 $sql .= ' AND example = 1';
b13142da 225 } elseif ($examples === false) {
235b31c8 226 $sql .= ' AND example = 0';
b13142da
DM
227 } else {
228 throw new coding_exception('Illegal parameter value: $examples may be false|true|"all"');
6e309973 229 }
3d2924e9
DM
230
231 if ('all' === $userid) {
232 // no additional conditions
233 } elseif (is_array($userid)) {
234 list($usql, $uparams) = $DB->get_in_or_equal($userid, SQL_PARAMS_NAMED);
235 $sql .= " AND userid $usql";
6e309973 236 $params = array_merge($params, $uparams);
3d2924e9 237 } else {
235b31c8 238 $sql .= ' AND userid = :userid';
3d2924e9 239 $params['userid'] = $userid;
6e309973
DM
240 }
241
242 return $DB->get_recordset_sql($sql, $params);
243 }
244
53fad4b9
DM
245 /**
246 * Returns a submission submitted by the given author or authors.
247 *
248 * This is intended for regular workshop participants, not for example submissions by teachers.
249 * If an array of authors is provided, returns array of stripped submission records so they do not
250 * include text fields (to prevent possible memory-lack issues).
251 *
252 * @param mixed $id integer|array author ID or IDs
65ba104c 253 * @return mixed false if not found, stdClass if $id is int, array if $id is array
53fad4b9
DM
254 */
255 public function get_submission_by_author($id) {
256 if (empty($id)) {
257 return false;
258 }
259 $rs = $this->get_submissions_recordset($id, false);
3d2924e9 260 if (is_array($id)) {
53fad4b9
DM
261 $submissions = array();
262 foreach ($rs as $submission) {
65ba104c 263 $submissions[$submission->id] = new stdClass();
53fad4b9
DM
264 foreach ($submission as $property => $value) {
265 // we do not want text fields here to prevent possible memory issues
266 if (in_array($property, array('id', 'workshopid', 'example', 'userid', 'authorlastname', 'authorfirstname',
267 'timecreated', 'timemodified', 'grade', 'gradeover', 'gradeoverby', 'gradinggrade'))) {
268 $submissions[$submission->id]->{$property} = $value;
269 }
270 }
271 }
272 return $submissions;
273 } else {
3d2924e9
DM
274 $submission = $rs->current();
275 $rs->close();
276 if (empty($submission->id)) {
277 return false;
278 } else {
279 return $submission;
280 }
53fad4b9
DM
281 }
282 }
6e309973
DM
283
284 /**
285 * Returns the list of assessments with some data added
286 *
287 * Fetches data from {workshop_assessments} and adds some useful information from other
288 * tables.
289 *
290 * @param mixed $reviewerid 'all'|int|array User ID of the reviewer
291 * @param mixed $id 'all'|int Assessment ID
65ba104c 292 * @return stdClass moodle_recordset
6e309973 293 */
66c9894d 294 public function get_assessments_recordset($reviewerid='all', $id='all') {
6e309973 295 global $DB;
53fad4b9 296
235b31c8 297 $sql = 'SELECT a.*,
3d2924e9
DM
298 reviewer.id AS reviewerid,reviewer.firstname AS reviewerfirstname,reviewer.lastname as reviewerlastname,
299 s.title,
300 author.id AS authorid, author.firstname AS authorfirstname,author.lastname as authorlastname
301 FROM {workshop_assessments} a
302 INNER JOIN {user} reviewer ON (a.userid = reviewer.id)
303 INNER JOIN {workshop_submissions} s ON (a.submissionid = s.id)
304 INNER JOIN {user} author ON (s.userid = author.id)
235b31c8 305 WHERE s.workshopid = :workshopid';
3d2924e9
DM
306 $params = array('workshopid' => $this->id);
307
308 if ('all' === $reviewerid) {
309 // no additional conditions
310 } elseif (is_array($reviewerid)) {
311 list($usql, $uparams) = $DB->get_in_or_equal($reviewerid, SQL_PARAMS_NAMED);
312 $sql .= " AND reviewer.id $usql";
6e309973 313 $params = array_merge($params, $uparams);
3d2924e9 314 } else {
235b31c8 315 $sql .= ' AND reviewer.id = :reviewerid';
3d2924e9 316 $params['reviewerid'] = $reviewerid;
6e309973 317 }
3d2924e9
DM
318
319 if ('all' === $id) {
320 // no additional conditions
321 } else {
235b31c8 322 $sql .= ' AND a.id = :assessmentid';
3d2924e9 323 $params['assessmentid'] = $id;
6e309973
DM
324 }
325
326 return $DB->get_recordset_sql($sql, $params);
327 }
328
53fad4b9
DM
329 /**
330 * Returns the list of assessments with some data added
331 *
332 * Fetches data from {workshop_assessments} and adds some useful information from other
333 * tables. The returned objects are lightweight version of those returned by get_assessments_recordset(),
334 * mainly they do not contain text fields.
335 *
336 * @param mixed $reviewerid 'all'|int|array User ID of the reviewer
b8ead2e6 337 * @param mixed $id 'all'|int Assessment ID
65ba104c 338 * @return array [assessmentid] => assessment stdClass
a39d7d87 339 * @see workshop::get_assessments_recordset() for the structure of returned objects
53fad4b9 340 */
b8ead2e6
DM
341 public function get_assessments($reviewerid='all', $id='all') {
342 $rs = $this->get_assessments_recordset($reviewerid, $id);
53fad4b9
DM
343 $assessments = array();
344 foreach ($rs as $assessment) {
345 // copy selected properties into the array to be returned. This is here mainly in order not
346 // to include text comments.
65ba104c 347 $assessments[$assessment->id] = new stdClass();
53fad4b9
DM
348 foreach ($assessment as $property => $value) {
349 if (in_array($property, array('id', 'submissionid', 'userid', 'timecreated', 'timemodified',
350 'timeagreed', 'grade', 'gradinggrade', 'gradinggradeover', 'gradinggradeoverby',
351 'reviewerid', 'reviewerfirstname', 'reviewerlastname', 'title', 'authorid',
352 'authorfirstname', 'authorlastname'))) {
353 $assessments[$assessment->id]->{$property} = $value;
354 }
355 }
356 }
357 $rs->close();
358 return $assessments;
359 }
360
361 /**
362 * Get the information about the given assessment
363 *
364 * @param int $id Assessment ID
a39d7d87 365 * @see workshop::get_assessments_recordset() for the structure of data returned
65ba104c 366 * @return mixed false if not found, stdClass otherwise
53fad4b9
DM
367 */
368 public function get_assessment_by_id($id) {
369 $rs = $this->get_assessments_recordset('all', $id);
370 $assessment = $rs->current();
371 $rs->close();
372 if (empty($assessment->id)) {
373 return false;
374 } else {
375 return $assessment;
376 }
377 }
378
379 /**
380 * Get the information about all assessments assigned to the given reviewer
381 *
382 * @param int $id Reviewer ID
a39d7d87 383 * @see workshop::get_assessments_recordset() for the structure of data returned
53fad4b9
DM
384 * @return array array of objects
385 */
386 public function get_assessments_by_reviewer($id) {
387 $rs = $this->get_assessments_recordset($id);
388 $assessments = array();
389 foreach ($rs as $assessment) {
390 $assessments[$assessment->id] = $assessment;
391 }
392 $rs->close();
393 return $assessment;
394 }
6e309973
DM
395
396 /**
397 * Returns the list of allocations in the workshop
398 *
399 * This returns the list of all users who can submit their work or review submissions (or both
400 * which is the common case). So basically this is to return list of all students participating
401 * in the workshop. For every participant, it adds information about their submission and their
53fad4b9 402 * reviews.
6e309973
DM
403 *
404 * The returned structure is recordset of objects with following properties:
405 * [authorid] [authorfirstname] [authorlastname] [authorpicture] [authorimagealt]
406 * [submissionid] [submissiontitle] [submissiongrade] [assessmentid]
53fad4b9 407 * [timeallocated] [reviewerid] [reviewerfirstname] [reviewerlastname]
6e309973
DM
408 * [reviewerpicture] [reviewerimagealt]
409 *
3d2924e9 410 * TODO This should be refactored when capability handling proposed by Petr is implemented so that
6e309973 411 * we can check capabilities directly in SQL joins.
53fad4b9
DM
412 * Note that the returned recordset includes participants without submission as well as those
413 * without any review allocated yet.
6e309973 414 *
65ba104c 415 * @return stdClass moodle_recordset
6e309973 416 */
66c9894d 417 public function get_allocations_recordset() {
6e309973 418 global $DB;
6e309973 419
3d2924e9
DM
420 $context = get_context_instance(CONTEXT_MODULE, $this->cm->id);
421 $users = get_users_by_capability($context, array('mod/workshop:submit', 'mod/workshop:peerassess'),
235b31c8 422 'u.id', 'u.lastname,u.firstname', '', '', '', '', false, false, true);
3d2924e9
DM
423
424 list($usql, $params) = $DB->get_in_or_equal(array_keys($users), SQL_PARAMS_NAMED);
425 $params['workshopid'] = $this->id;
426
1dbbccb7 427 $sql = "SELECT author.id AS authorid, author.firstname AS authorfirstname, author.lastname AS authorlastname,
3d2924e9
DM
428 author.picture AS authorpicture, author.imagealt AS authorimagealt,
429 s.id AS submissionid, s.title AS submissiontitle, s.grade AS submissiongrade,
430 a.id AS assessmentid, a.timecreated AS timeallocated, a.userid AS reviewerid,
431 reviewer.firstname AS reviewerfirstname, reviewer.lastname AS reviewerlastname,
432 reviewer.picture as reviewerpicture, reviewer.imagealt AS reviewerimagealt
433 FROM {user} author
434 LEFT JOIN {workshop_submissions} s ON (s.userid = author.id)
435 LEFT JOIN {workshop_assessments} a ON (s.id = a.submissionid)
436 LEFT JOIN {user} reviewer ON (a.userid = reviewer.id)
437 WHERE author.id $usql AND s.workshopid = :workshopid
1dbbccb7 438 ORDER BY author.lastname,author.firstname,reviewer.lastname,reviewer.firstname";
3d2924e9 439
6e309973
DM
440 return $DB->get_recordset_sql($sql, $params);
441 }
442
6e309973
DM
443 /**
444 * Allocate a submission to a user for review
53fad4b9 445 *
65ba104c 446 * @param stdClass $submission Submission record
6e309973 447 * @param int $reviewerid User ID
53fad4b9 448 * @param bool $bulk repeated inserts into DB expected
6e309973
DM
449 * @return int ID of the new assessment or an error code
450 */
65ba104c 451 public function add_allocation(stdClass $submission, $reviewerid, $bulk=false) {
6e309973
DM
452 global $DB;
453
454 if ($DB->record_exists('workshop_assessments', array('submissionid' => $submission->id, 'userid' => $reviewerid))) {
455 return WORKSHOP_ALLOCATION_EXISTS;
456 }
457
6e309973 458 $now = time();
65ba104c 459 $assessment = new stdClass();
53fad4b9 460 $assessment->submissionid = $submission->id;
6e309973
DM
461 $assessment->userid = $reviewerid;
462 $assessment->timecreated = $now;
463 $assessment->timemodified = $now;
464
235b31c8 465 return $DB->insert_record('workshop_assessments', $assessment, true, $bulk);
6e309973
DM
466 }
467
6e309973 468 /**
53fad4b9 469 * Delete assessment record or records
6e309973 470 *
53fad4b9
DM
471 * @param mixed $id int|array assessment id or array of assessments ids
472 * @return bool false if $id not a valid parameter, true otherwise
6e309973
DM
473 */
474 public function delete_assessment($id) {
475 global $DB;
476
477 // todo remove all given grades from workshop_grades;
6e309973 478
53fad4b9 479 if (is_array($id)) {
235b31c8 480 return $DB->delete_records_list('workshop_assessments', 'id', $id);
3d2924e9 481 } else {
235b31c8 482 return $DB->delete_records('workshop_assessments', array('id' => $id));
53fad4b9 483 }
53fad4b9 484 }
6e309973
DM
485
486 /**
487 * Returns instance of grading strategy class
53fad4b9 488 *
65ba104c 489 * @return stdClass Instance of a grading strategy
6e309973
DM
490 */
491 public function grading_strategy_instance() {
3d2924e9
DM
492 global $CFG; // because we require other libs here
493
3fd2b0e1 494 if (is_null($this->strategyinstance)) {
0dc47fb9 495 $strategylib = dirname(__FILE__) . '/grading/' . $this->strategy . '/strategy.php';
6e309973
DM
496 if (is_readable($strategylib)) {
497 require_once($strategylib);
498 } else {
a39d7d87 499 throw new moodle_exception('missingstrategy', 'workshop');
6e309973 500 }
0dc47fb9 501 $classname = 'workshop_' . $this->strategy . '_strategy';
3fd2b0e1
DM
502 $this->strategyinstance = new $classname($this);
503 if (!in_array('workshop_strategy', class_implements($this->strategyinstance))) {
a39d7d87 504 throw new moodle_exception('strategynotimplemented', 'workshop');
6e309973
DM
505 }
506 }
3fd2b0e1 507 return $this->strategyinstance;
6e309973
DM
508 }
509
66c9894d
DM
510 /**
511 * Return list of available allocation methods
512 *
513 * @return array Array ['string' => 'string'] of localized allocation method names
514 */
515 public function installed_allocators() {
ed597c77 516 $installed = get_plugin_list('workshopallocation');
66c9894d 517 $forms = array();
ed597c77
DM
518 foreach ($installed as $allocation => $allocationpath) {
519 if (file_exists($allocationpath . '/allocator.php')) {
520 $forms[$allocation] = get_string('pluginname', 'workshopallocation_' . $allocation);
521 }
66c9894d
DM
522 }
523 // usability - make sure that manual allocation appears the first
524 if (isset($forms['manual'])) {
525 $m = array('manual' => $forms['manual']);
526 unset($forms['manual']);
527 $forms = array_merge($m, $forms);
528 }
529 return $forms;
530 }
0968b1a3 531
66c9894d
DM
532 /**
533 * Returns instance of submissions allocator
53fad4b9 534 *
65ba104c
DM
535 * @param stdClass $method The name of the allocation method, must be PARAM_ALPHA
536 * @return stdClass Instance of submissions allocator
66c9894d
DM
537 */
538 public function allocator_instance($method) {
3d2924e9
DM
539 global $CFG; // because we require other libs here
540
66c9894d
DM
541 $allocationlib = dirname(__FILE__) . '/allocation/' . $method . '/allocator.php';
542 if (is_readable($allocationlib)) {
543 require_once($allocationlib);
544 } else {
a39d7d87 545 throw new coding_exception('Unable to find allocator.php');
66c9894d
DM
546 }
547 $classname = 'workshop_' . $method . '_allocator';
548 return new $classname($this);
549 }
550
b8ead2e6 551 /**
65ba104c 552 * @return stdClass {@link moodle_url} the URL of this workshop's view page
b8ead2e6
DM
553 */
554 public function view_url() {
555 global $CFG;
556 return new moodle_url($CFG->wwwroot . '/mod/workshop/view.php', array('id' => $this->cm->id));
557 }
558
559 /**
65ba104c 560 * @return stdClass {@link moodle_url} the URL of the page for editing this workshop's grading form
b8ead2e6
DM
561 */
562 public function editform_url() {
563 global $CFG;
564 return new moodle_url($CFG->wwwroot . '/mod/workshop/editform.php', array('cmid' => $this->cm->id));
565 }
566
567 /**
65ba104c 568 * @return stdClass {@link moodle_url} the URL of the page for previewing this workshop's grading form
b8ead2e6
DM
569 */
570 public function previewform_url() {
571 global $CFG;
572 return new moodle_url($CFG->wwwroot . '/mod/workshop/assessment.php', array('preview' => $this->cm->id));
573 }
574
575 /**
576 * @param int $assessmentid The ID of assessment record
65ba104c 577 * @return stdClass {@link moodle_url} the URL of the assessment page
b8ead2e6 578 */
a39d7d87 579 public function assess_url($assessmentid) {
b8ead2e6 580 global $CFG;
a39d7d87 581 return new moodle_url($CFG->wwwroot . '/mod/workshop/assessment.php', array('asid' => $assessmentid));
b8ead2e6
DM
582 }
583
39861053
DM
584 /**
585 * @return stdClass {@link moodle_url} the URL of the page to view own submission
586 */
587 public function submission_url() {
588 global $CFG;
589 return new moodle_url($CFG->wwwroot . '/mod/workshop/submission.php', array('cmid' => $this->cm->id));
590 }
591
b8ead2e6
DM
592 /**
593 * Returns an object containing all data to display the user's full name and picture
594 *
595 * @param int $id optional user id, defaults to the current user
65ba104c 596 * @return stdClass containing properties lastname, firstname, picture and imagealt
b8ead2e6
DM
597 */
598 public function user_info($id=null) {
599 global $USER, $DB;
600
601 if (is_null($id) || ($id == $USER->id)) {
602 return $USER;
603 } else {
604 return $DB->get_record('user', array('id' => $id), 'id,lastname,firstname,picture,imagealt', MUST_EXIST);
605 }
606 }
607
c1e883bb 608 /**
b13142da 609 * Are users allowed to create/edit their submissions?
c1e883bb
DM
610 *
611 * TODO: this depends on the workshop phase, phase deadlines, submitting after deadlines possibility
612 *
613 * @return bool
614 */
615 public function submitting_allowed() {
616 return true;
617 }
618
b13142da
DM
619 /**
620 * Returns the localized name of the grading strategy method to be displayed to the users
621 *
622 * @return string
623 */
624 public function strategy_name() {
625 return get_string('pluginname', 'workshopgrading_' . $this->strategy);
626 }
66c9894d 627}