Renamed a param to handle block editing mode
[moodle.git] / mod / workshop / lib.php
CommitLineData
4eab2e7f 1<?php
53fad4b9
DM
2
3// This file is part of Moodle - http://moodle.org/
4//
4eab2e7f
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//
4eab2e7f
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
4eab2e7f
DM
18/**
19 * Library of interface functions and constants for module workshop
20 *
53fad4b9 21 * All the core Moodle functions, neeeded to allow the module to work
4eab2e7f 22 * integrated in Moodle should be placed here.
4eab2e7f
DM
23 *
24 * @package mod-workshop
25 * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 */
28
6867e05d 29defined('MOODLE_INTERNAL') || die();
4eab2e7f 30
b761e6d9
DM
31/**
32 * Returns the information if the module supports a feature
33 *
34 * @see plugin_supports() in lib/moodlelib.php
35 * @param string $feature FEATURE_xx constant for requested feature
36 * @return mixed true if the feature is supported, null if unknown
37 */
38function workshop_supports($feature) {
39 switch($feature) {
40 case FEATURE_GRADE_HAS_GRADE: return true;
41 case FEATURE_GROUPS: return true;
42 case FEATURE_GROUPINGS: return true;
43 case FEATURE_GROUPMEMBERSONLY: return true;
44 case FEATURE_MOD_INTRO: return true;
45 case FEATURE_MOD_SUBPLUGINS: return array(
f05c168d 46 'workshopform' => 'mod/workshop/form',
f55650e6
DM
47 'workshopallocation' => 'mod/workshop/allocation',
48 'workshopeval' => 'mod/workshop/eval',
b761e6d9
DM
49 );
50 default: return null;
51 }
52}
53
6e309973 54/**
a39d7d87 55 * Saves a new instance of the workshop into the database
6e309973 56 *
4eab2e7f
DM
57 * Given an object containing all the necessary data,
58 * (defined by the form in mod_form.php) this function
a39d7d87 59 * will save a new instance and return the id number
4eab2e7f
DM
60 * of the new instance.
61 *
65ba104c 62 * @param stdClass $data An object from the form in mod_form.php
4eab2e7f
DM
63 * @return int The id of the newly inserted workshop record
64 */
6e309973 65function workshop_add_instance($data) {
454e8dd9
DM
66 global $CFG, $DB;
67 require_once(dirname(__FILE__) . '/locallib.php');
4eab2e7f 68
454e8dd9
DM
69 $data->phase = workshop::PHASE_SETUP;
70 $data->timecreated = time();
a39d7d87
DM
71 $data->timemodified = $data->timecreated;
72
6516b9e9
DM
73 // insert the new record so we get the id
74 $data->id = $DB->insert_record('workshop', $data);
75
76 // we need to use context now, so we need to make sure all needed info is already in db
77 $cmid = $data->coursemodule;
78 $DB->set_field('course_modules', 'instance', $data->id, array('id' => $cmid));
79 $context = get_context_instance(CONTEXT_MODULE, $cmid);
80
81 // process the custom wysiwyg editors
82 if ($draftitemid = $data->instructauthorseditor['itemid']) {
83 $data->instructauthors = file_save_draft_area_files($draftitemid, $context->id, 'workshop_instructauthors',
dbb3c728 84 0, workshop::instruction_editors_options($context), $data->instructauthorseditor['text']);
6516b9e9
DM
85 $data->instructauthorsformat = $data->instructauthorseditor['format'];
86 }
87
15d12b54
DM
88 if ($draftitemid = $data->instructreviewerseditor['itemid']) {
89 $data->instructreviewers = file_save_draft_area_files($draftitemid, $context->id, 'workshop_instructreviewers',
90 0, workshop::instruction_editors_options($context), $data->instructreviewerseditor['text']);
91 $data->instructreviewersformat = $data->instructreviewerseditor['format'];
92 }
93
6516b9e9
DM
94 // re-save the record with the replaced URLs in editor fields
95 $DB->update_record('workshop', $data);
96
97 return $data->id;
a39d7d87 98}
a7c5b918 99
4eab2e7f
DM
100/**
101 * Given an object containing all the necessary data,
102 * (defined by the form in mod_form.php) this function
103 * will update an existing instance with new data.
104 *
6516b9e9
DM
105 * @param stdClass $data An object from the form in mod_form.php
106 * @return bool success
4eab2e7f 107 */
6516b9e9
DM
108function workshop_update_instance($data) {
109 global $CFG, $DB;
110 require_once(dirname(__FILE__) . '/locallib.php');
111
112 $data->timemodified = time();
113 $data->id = $data->instance;
4eab2e7f 114
f05c168d
DM
115 // todo - if the grading strategy is being changed, we must replace all aggregated peer grades with nulls
116 // todo - if maximum grades are being changed, we should probably recalculate or invalidate them
117
6516b9e9
DM
118 $DB->update_record('workshop', $data);
119 $context = get_context_instance(CONTEXT_MODULE, $data->coursemodule);
4eab2e7f 120
6516b9e9
DM
121 // process the custom wysiwyg editors
122 if ($draftitemid = $data->instructauthorseditor['itemid']) {
123 $data->instructauthors = file_save_draft_area_files($draftitemid, $context->id, 'workshop_instructauthors',
dbb3c728 124 0, workshop::instruction_editors_options($context), $data->instructauthorseditor['text']);
6516b9e9
DM
125 $data->instructauthorsformat = $data->instructauthorseditor['format'];
126 }
127
15d12b54
DM
128 if ($draftitemid = $data->instructreviewerseditor['itemid']) {
129 $data->instructreviewers = file_save_draft_area_files($draftitemid, $context->id, 'workshop_instructreviewers',
130 0, workshop::instruction_editors_options($context), $data->instructreviewerseditor['text']);
131 $data->instructreviewersformat = $data->instructreviewerseditor['format'];
132 }
133
6516b9e9
DM
134 // re-save the record with the replaced URLs in editor fields
135 return $DB->update_record('workshop', $data);
4eab2e7f
DM
136}
137
4eab2e7f
DM
138/**
139 * Given an ID of an instance of this module,
140 * this function will permanently delete the instance
141 * and any data that depends on it.
142 *
143 * @param int $id Id of the module instance
144 * @return boolean Success/Failure
145 */
146function workshop_delete_instance($id) {
147 global $DB;
148
149 if (! $workshop = $DB->get_record('workshop', array('id' => $id))) {
150 return false;
151 }
8a1ba8ac
DM
152 // delete all associated aggregations
153 $DB->delete_records('workshop_aggregations', array('workshopid' => $workshop->id));
154 // get the list of ids of all submissions
155 $submissions = $DB->get_records('workshop_submissions', array('workshopid' => $workshop->id), '', 'id');
156 // get the list of all allocated assessments
157 $assessments = $DB->get_records_list('workshop_assessments', 'submissionid', array_keys($submissions), '', 'id');
158 // delete the associated records from the workshop core tables
159 $DB->delete_records_list('workshop_grades', 'assessmentid', array_keys($assessments));
160 $DB->delete_records_list('workshop_assessments', 'id', array_keys($assessments));
161 $DB->delete_records_list('workshop_submissions', 'id', array_keys($submissions));
162 // todo call the static clean-up methods of all available subplugins
163 // ...
164 // finally remove the workshop record itself
165 $DB->delete_records('workshop', array('id' => $workshop->id));
4eab2e7f 166
8a1ba8ac 167 return true;
4eab2e7f
DM
168}
169
4eab2e7f
DM
170/**
171 * Return a small object with summary information about what a
172 * user has done with a given particular instance of this module
173 * Used for user activity reports.
174 * $return->time = the time they did it
175 * $return->info = a short text description
176 *
177 * @return null
178 * @todo Finish documenting this function
179 */
180function workshop_user_outline($course, $user, $mod, $workshop) {
65ba104c 181 $return = new stdClass();
4eab2e7f
DM
182 $return->time = 0;
183 $return->info = '';
184 return $return;
185}
186
4eab2e7f
DM
187/**
188 * Print a detailed representation of what a user has done with
189 * a given particular instance of this module, for user activity reports.
190 *
191 * @return boolean
192 * @todo Finish documenting this function
193 */
194function workshop_user_complete($course, $user, $mod, $workshop) {
195 return true;
196}
197
4eab2e7f
DM
198/**
199 * Given a course and a time, this module should find recent activity
200 * that has occurred in workshop activities and print it out.
201 * Return true if there was output, or false is there was none.
202 *
203 * @return boolean
204 * @todo Finish documenting this function
205 */
206function workshop_print_recent_activity($course, $isteacher, $timestart) {
207 return false; // True if anything was printed, otherwise false
208}
209
4eab2e7f
DM
210/**
211 * Function to be run periodically according to the moodle cron
212 * This function searches for things that need to be done, such
213 * as sending out mail, toggling flags etc ...
214 *
215 * @return boolean
216 * @todo Finish documenting this function
217 **/
218function workshop_cron () {
219 return true;
220}
221
4eab2e7f
DM
222/**
223 * Must return an array of user records (all data) who are participants
224 * for a given instance of workshop. Must include every user involved
225 * in the instance, independient of his role (student, teacher, admin...)
226 * See other modules as example.
227 *
228 * @param int $workshopid ID of an instance of this module
229 * @return mixed boolean/array of students
230 */
231function workshop_get_participants($workshopid) {
232 return false;
233}
234
4eab2e7f
DM
235/**
236 * This function returns if a scale is being used by one workshop
237 * if it has support for grading and scales. Commented code should be
238 * modified if necessary. See forum, glossary or journal modules
239 * as reference.
240 *
241 * @param int $workshopid ID of an instance of this module
242 * @return mixed
243 * @todo Finish documenting this function
244 */
245function workshop_scale_used($workshopid, $scaleid) {
246 $return = false;
247
248 //$rec = get_record("workshop","id","$workshopid","scale","-$scaleid");
249 //
250 //if (!empty($rec) && !empty($scaleid)) {
251 // $return = true;
252 //}
253
254 return $return;
255}
256
4eab2e7f
DM
257/**
258 * Checks if scale is being used by any instance of workshop.
259 * This function was added in 1.9
260 *
261 * This is used to find out if scale used anywhere
262 * @param $scaleid int
263 * @return boolean True if the scale is used by any workshop
264 */
265function workshop_scale_used_anywhere($scaleid) {
266 if ($scaleid and record_exists('workshop', 'grade', -$scaleid)) {
267 return true;
268 } else {
269 return false;
270 }
271}
272
4eab2e7f
DM
273/**
274 * Execute post-install custom actions for the module
275 * This function was added in 1.9
276 *
277 * @return boolean true if success, false on error
278 */
279function workshop_install() {
280 return true;
281}
282
0dc47fb9
DM
283/**
284 * Returns all other caps used in the module
285 *
286 * @return array
287 */
288function workshop_get_extra_capabilities() {
289 return array('moodle/site:accessallgroups');
290}
291
b8ead2e6
DM
292////////////////////////////////////////////////////////////////////////////////
293// File API //
294////////////////////////////////////////////////////////////////////////////////
0dc47fb9 295
a39d7d87
DM
296/**
297 * Returns the lists of all browsable file areas within the given module context
298 *
299 * The file area workshop_intro for the activity introduction field is added automatically
300 * by {@link file_browser::get_file_info_module()}
301 *
65ba104c
DM
302 * @param stdClass $course
303 * @param stdClass $cm
304 * @param stdClass $context
a39d7d87
DM
305 * @return array of [(string)filearea] => (string)description
306 */
307function workshop_get_file_areas($course, $cm, $context) {
308 $areas = array();
309 if (has_capability('moodle/course:managefiles', $context)) {
6516b9e9 310 $areas['workshop_instructauthors'] = get_string('areainstructauthors', 'workshop');
a39d7d87
DM
311 $areas['workshop_submission_content'] = get_string('areasubmissioncontent', 'workshop');
312 $areas['workshop_submission_attachment'] = get_string('areasubmissionattachment', 'workshop');
313 }
314 return $areas;
315}
316
0dc47fb9 317/**
b8ead2e6 318 * Serves the files from the workshop file areas
0dc47fb9 319 *
b8ead2e6
DM
320 * Apart from module intro (handled by pluginfile.php automatically), workshop files may be
321 * media inserted into submission content (like images) and submission attachments. For these two,
322 * the fileareas workshop_submission_content and workshop_submission_attachment are used.
323 * The access rights to the files are checked here. The user must be either a peer-reviewer
324 * of the submission or have capability ... (todo) to access the submission files.
6516b9e9
DM
325 * Besides that, areas workshop_instructauthors and workshop_instructreviewers contain the media
326 * embedded using the mod_form.php.
0dc47fb9 327 *
65ba104c
DM
328 * @param stdClass $course
329 * @param stdClass $cminfo
330 * @param stdClass $context
0dc47fb9
DM
331 * @param string $filearea
332 * @param array $args
333 * @param bool $forcedownload
6516b9e9 334 * @return void this should never return to the caller
0dc47fb9 335 */
6516b9e9 336function workshop_pluginfile($course, $cminfo, $context, $filearea, array $args, $forcedownload) {
0dc47fb9
DM
337 global $DB;
338
339 if (!$cminfo->uservisible) {
6516b9e9 340 send_file_not_found();
0dc47fb9 341 }
0dc47fb9 342 if (!$cm = get_coursemodule_from_instance('workshop', $cminfo->instance, $course->id)) {
6516b9e9
DM
343 send_file_not_found();
344 }
345 require_login($course, true, $cm);
346
347 if ($filearea === 'workshop_instructauthors') {
348 // submission instructions may contain sensitive data
349 if (!has_any_capability(array('moodle/course:manageactivities', 'mod/workshop:submit'), $context)) {
350 send_file_not_found();
351 }
352
353 array_shift($args); // we do not use itemids here
354 $relativepath = '/' . implode('/', $args);
355 $fullpath = $context->id . $filearea . '0' . $relativepath; // beware, slashes are not used here!
356
357 $fs = get_file_storage();
358 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
15d12b54
DM
359 send_file_not_found();
360 }
361
362 $lifetime = isset($CFG->filelifetime) ? $CFG->filelifetime : 86400;
363
364 // finally send the file
365 send_stored_file($file, $lifetime, 0);
366 }
367
368 if ($filearea === 'workshop_instructreviewers') {
369 // submission instructions may contain sensitive data
370 if (!has_any_capability(array('moodle/course:manageactivities', 'mod/workshop:peerassess'), $context)) {
371 send_file_not_found();
372 }
373
374 array_shift($args); // we do not use itemids here
375 $relativepath = '/' . implode('/', $args);
376 $fullpath = $context->id . $filearea . '0' . $relativepath; // beware, slashes are not used here!
377
378 $fs = get_file_storage();
379 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
6516b9e9
DM
380 send_file_not_found();
381 }
382
383 $lifetime = isset($CFG->filelifetime) ? $CFG->filelifetime : 86400;
384
385 // finally send the file
386 send_stored_file($file, $lifetime, 0);
0dc47fb9 387 }
0dc47fb9 388
dbb3c728
DM
389 // the following file areas are for the files embedded into the assessment forms
390 if (in_array($filearea, array(
391 'workshopform_comments_description',
392 'workshopform_accumulative_description',
393 'workshopform_numerrors_description',
394 'workshopform_rubric_description',
395 ))) {
396 $itemid = (int)array_shift($args); // the id of the assessment form dimension
d524173e 397 if (!$workshop = $DB->get_record('workshop', array('id' => $cminfo->instance))) {
dbb3c728 398 send_file_not_found();
18cbfe9b 399 }
d524173e
DM
400 switch ($filearea) {
401 case 'workshopform_comments_description':
402 $dimension = $DB->get_record('workshopform_comments', array('id' => $itemid));
403 break;
404 case 'workshopform_accumulative_description':
405 $dimension = $DB->get_record('workshopform_accumulative', array('id' => $itemid));
406 break;
407 case 'workshopform_numerrors_description':
408 $dimension = $DB->get_record('workshopform_numerrors', array('id' => $itemid));
409 break;
410 case 'workshopform_rubric_description':
411 $dimension = $DB->get_record('workshopform_rubric', array('id' => $itemid));
412 break;
413 default:
414 $dimension = false;
415 }
416 if (empty($dimension)) {
dbb3c728 417 send_file_not_found();
18cbfe9b 418 }
d524173e 419 if ($workshop->id != $dimension->workshopid) {
18cbfe9b 420 // this should never happen but just in case
dbb3c728 421 send_file_not_found();
18cbfe9b
DM
422 }
423 // TODO now make sure the user is allowed to see the file
dbb3c728 424 // (media embedded into the dimension description)
18cbfe9b
DM
425 $fs = get_file_storage();
426 $relativepath = '/' . implode('/', $args);
427 $fullpath = $context->id . $filearea . $itemid . $relativepath;
428 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
429 return false;
430 }
431 // finally send the file
a39d7d87 432 send_stored_file($file);
18cbfe9b 433 }
0dc47fb9 434
d524173e 435 if ($filearea == 'workshop_submission_content' or $filearea == 'workshop_submission_attachment') {
18cbfe9b
DM
436 $itemid = (int)array_shift($args);
437 if (!$submission = $DB->get_record('workshop_submissions', array('id' => $itemid))) {
438 return false;
439 }
440 if (!$workshop = $DB->get_record('workshop', array('id' => $cminfo->instance))) {
441 return false;
442 }
443 // TODO now make sure the user is allowed to see the file
444 $fs = get_file_storage();
445 $relativepath = '/' . implode('/', $args);
446 $fullpath = $context->id . $filearea . $itemid . $relativepath;
447 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
448 return false;
449 }
450 // finally send the file
451 // these files are uploaded by students - forcing download for security reasons
a39d7d87 452 send_stored_file($file, 0, 0, true);
0dc47fb9 453 }
18cbfe9b
DM
454
455 return false;
0dc47fb9
DM
456}
457
458/**
459 * File browsing support for workshop file areas
460 *
65ba104c
DM
461 * @param stdClass $browser
462 * @param stdClass $areas
463 * @param stdClass $course
464 * @param stdClass $cm
465 * @param stdClass $context
0dc47fb9
DM
466 * @param string $filearea
467 * @param int $itemid
468 * @param string $filepath
469 * @param string $filename
65ba104c 470 * @return stdClass file_info instance or null if not found
0dc47fb9
DM
471 */
472function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
473 global $CFG, $DB;
0dc47fb9 474
a39d7d87 475 if (!has_capability('moodle/course:managefiles', $context)) {
0dc47fb9
DM
476 return null;
477 }
0dc47fb9
DM
478
479 $fs = get_file_storage();
a39d7d87
DM
480
481 if ($filearea === 'workshop_submission_content' or $filearea === 'workshop_submission_attachment') {
482
483 if (is_null($itemid)) {
484 require_once($CFG->dirroot . '/mod/workshop/fileinfolib.php');
485 return new workshop_file_info_submissions_container($browser, $course, $cm, $context, $areas, $filearea);
486 }
487
488 // we are inside the submission container
489
490 $filepath = is_null($filepath) ? '/' : $filepath;
491 $filename = is_null($filename) ? '.' : $filename;
492
493 if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
494 if ($filepath === '/' and $filename === '.') {
495 $storedfile = new virtual_root_file($context->id, $filearea, $itemid);
496 } else {
497 // not found
498 return null;
499 }
500 }
501
502 // let us display the author's name instead of itemid (submission id)
fa159f43
DM
503 // todo some sort of caching should happen here
504
235b31c8 505 $sql = 'SELECT s.id, u.lastname, u.firstname
fa159f43 506 FROM {workshop_submissions} s
00aca3c1 507 INNER JOIN {user} u ON (s.authorid = u.id)
235b31c8 508 WHERE s.workshopid = ?';
fa159f43
DM
509 $params = array($cm->instance);
510 $authors = $DB->get_records_sql($sql, $params);
a39d7d87
DM
511 $urlbase = $CFG->wwwroot . '/pluginfile.php';
512 $topvisiblename = fullname($authors[$itemid]);
513 // do not allow manual modification of any files!
514 return new file_info_stored($browser, $context, $storedfile, $urlbase, $topvisiblename, true, true, false, false);
0dc47fb9
DM
515 }
516
f05c168d 517 /* todo was replaced by subplugins' areas
a39d7d87 518 if ($filearea === 'workshop_dimension_description') {
6516b9e9
DM
519 // always only itemid 0 - TODO not true, review
520
521 $filepath = is_null($filepath) ? '/' : $filepath;
522 $filename = is_null($filename) ? '.' : $filename;
523
524 $urlbase = $CFG->wwwroot.'/pluginfile.php';
525 if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
526 if ($filepath === '/' and $filename === '.') {
527 $storedfile = new virtual_root_file($context->id, $filearea, 0);
528 } else {
529 // not found
530 return null;
531 }
532 }
533 return new file_info_stored($browser, $context, $storedfile, $urlbase, $areas[$filearea], false, true, true, false);
534 }
f05c168d 535 */
6516b9e9
DM
536
537 if ($filearea === 'workshop_instructauthors') {
a39d7d87
DM
538 // always only itemid 0
539
540 $filepath = is_null($filepath) ? '/' : $filepath;
541 $filename = is_null($filename) ? '.' : $filename;
542
543 $urlbase = $CFG->wwwroot.'/pluginfile.php';
544 if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
545 if ($filepath === '/' and $filename === '.') {
546 $storedfile = new virtual_root_file($context->id, $filearea, 0);
547 } else {
548 // not found
549 return null;
550 }
551 }
552 return new file_info_stored($browser, $context, $storedfile, $urlbase, $areas[$filearea], false, true, true, false);
0dc47fb9 553 }
0dc47fb9
DM
554}
555
6516b9e9
DM
556////////////////////////////////////////////////////////////////////////////////
557// Navigation API //
558////////////////////////////////////////////////////////////////////////////////
559
39861053
DM
560/**
561 * Extends the global navigation tree by adding workshop nodes if there is a relevant content
562 *
b761e6d9
DM
563 * This can be called by an AJAX request so do not rely on $PAGE as it might not be set up properly.
564 *
39861053
DM
565 * @param navigation_node $navref An object representing the navigation tree node of the workshop module instance
566 * @param stdClass $course
567 * @param stdClass $module
568 * @param stdClass $cm
569 */
570function workshop_extend_navigation(navigation_node $navref, stdClass $course, stdClass $module, stdClass $cm) {
571 global $CFG;
572
573 if (has_capability('mod/workshop:submit', $cm->context)) {
574 $url = new moodle_url($CFG->wwwroot.'/mod/workshop/submission.php', array('cmid' => $cm->id));
b761e6d9
DM
575 $mysubmissionkey = $navref->add(get_string('mysubmission', 'workshop'), $url);
576 $navref->get($mysubmissionkey)->mainnavonly = true;
39861053
DM
577 }
578}
579
580/**
581 * Extends the settings navigation with the Workshop settings
582
b761e6d9
DM
583 * This function is called when the context for the page is a workshop module. This is not called by AJAX
584 * so it is safe to rely on the $PAGE.
39861053
DM
585 *
586 * @param settings_navigation $settingsnav {@link settings_navigation}
587 * @param stdClass $module
588 * @return void|mixed The key to the modules branch
589 */
590function workshop_extend_settings_navigation(settings_navigation $settingsnav, stdClass $module=null) {
591 global $CFG, $PAGE;
592
593 $workshopkey = $settingsnav->add(get_string('workshopadministration', 'workshop'));
594 $workshopnode = $settingsnav->get($workshopkey);
595 $workshopnode->forceopen = true;
596 //$workshopobject = $DB->get_record("workshop", array("id" => $PAGE->cm->instance));
597
b761e6d9 598 if (has_capability('mod/workshop:editdimensions', $PAGE->cm->context)) {
39861053 599 $url = new moodle_url($CFG->wwwroot . '/mod/workshop/editform.php', array('cmid' => $PAGE->cm->id));
b761e6d9 600 $workshopnode->add(get_string('editassessmentform', 'workshop'), $url, settings_navigation::TYPE_SETTING);
39861053
DM
601 }
602 if (has_capability('mod/workshop:allocate', $PAGE->context)) {
603 $url = new moodle_url($CFG->wwwroot . '/mod/workshop/allocation.php', array('cmid' => $PAGE->cm->id));
b761e6d9 604 $workshopnode->add(get_string('allocate', 'workshop'), $url, settings_navigation::TYPE_SETTING);
39861053
DM
605 }
606}