Changes to string format for capabilities
[moodle.git] / lib / accesslib.php
CommitLineData
bbbf2d40 1<?php
2 /* capability session information format
3 * 2 x 2 array
4 * [context][capability]
5 * where context is the context id of the table 'context'
6 * and capability is a string defining the capability
7 * e.g.
8 *
9 * [Capabilities] => [26][mod/forum:viewpost] = 1
10 * [26][mod/forum:startdiscussion] = -8990
11 * [26][mod/forum:editallpost] = -1
12 * [273][moodle:blahblah] = 1
13 * [273][moodle:blahblahblah] = 2
14 */
15
16
17// permission definitions
18define('CAP_ALLOW', 1);
19define('CAP_PREVENT', -1);
20define('CAP_PROHIBIT', -1000);
21
22
23// context definitions
24define('CONTEXT_SYSTEM', 10);
25define('CONTEXT_PERSONAL', 20);
26define('CONTEXT_USERID', 30);
27define('CONTEXT_COURSECAT', 40);
28define('CONTEXT_COURSE', 50);
29define('CONTEXT_GROUP', 60);
30define('CONTEXT_MODULE', 70);
31define('CONTEXT_BLOCK', 80);
32
33
34/**
35 * This functions get all the course categories in proper order
36 * @param int $contextid
37 * @param int $type
38 * @return array of contextids
39 */
40function get_parent_cats($contextid, $type) {
98882637 41
42 $parents = array();
43 $context = get_record('context', 'id', $contextid);
44
45 switch($type) {
46
47 case CONTEXT_COURSECAT:
48
49 $cat = get_record('course_categories','id',$context->instanceid);
50 while ($cat->parent) {
51
52 $context = get_context_instance(CONTEXT_COURSECAT, $cat->parent);
53 $parents[] = $context->id;
54 $cat = get_record('course_categories','id',$cat->parent);
55 }
56
57 break;
58
59 case CONTEXT_COURSE:
60
61 $course = get_record('course', 'id', $context->instanceid);
62 $cat = get_record('course_categories','id',$course->category);
63 $catinstance = get_context_instance(CONTEXT_COURSECAT, $course->category);
64 $parents[] = $catinstance->id;
65
66 // what to do with cat 0?
67 while ($cat->parent) {
68 $context = get_context_instance(CONTEXT_COURSECAT, $cat->parent);
69 $parents[] = $context->id;
70 $cat = get_record('course_categories','id',$cat->parent);
71 }
72 break;
73
74 default:
75 break;
76
77 }
78
79 return array_reverse($parents);
bbbf2d40 80}
81
82
83/* Functions for Roles & Capabilites */
84
85
86/**
87 * This function returns whether the current user has the capability of performing a function
88 * For example, we can do has_capability('mod/forum:replypost',$cm) in forum
89 * only one of the 4 (moduleinstance, courseid, site, userid) would be set at 1 time
90 * This is a recursive funciton.
91 * Might change to require_capability, and throw an error if not authorized.
92 * @uses $USER
93 * @param string $capability - name of the capability
94 * @param int $contextid
95 * @param kill bool - if set, kill when the user has no capability
96 * @return bool
97 */
98function has_capability($capability, $contextid, $kill=false, $userid=NULL) {
99
98882637 100 global $USER;
bbbf2d40 101
98882637 102 if ($userid && $userid != $USER->id) { // loading other user's capability
103 $capabilities = load_user_capability($capability, $contextid, $userid);
104 } else {
105 $capabilities = $USER->capabilities;
106 }
bbbf2d40 107
98882637 108 $context = get_record('context','id',$contextid);
bbbf2d40 109
98882637 110 // Check site
111 $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
112 if (isset($capabilities[$sitecontext->id]['moodle/site:doanything'])) {
113 return ($capabilities[$sitecontext->id]['moodle/site:doanything']);
114 }
115
116 switch (context_level($contextid)) {
bbbf2d40 117
118 case CONTEXT_COURSECAT:
98882637 119 // Check parent cats.
120 $parentcats = get_parent_cats($contextid, CONTEXT_COURSECAT);
121 foreach ($parentcats as $parentcat) {
122 if (isset($capabilities[$parentcat]['moodle/site:doanything'])) {
123 return ($capabilities[$parentcat]['moodle/site:doanything']);
124 }
125 }
bbbf2d40 126 break;
127
128 case CONTEXT_COURSE:
98882637 129 // Check parent cat.
130 $parentcats = get_parent_cats($contextid, CONTEXT_COURSE);
131
132 foreach ($parentcats as $parentcat) {
133 if (isset($capabilities[$parentcat]['do_anything'])) {
134 return ($capabilities[$parentcat]['do_anything']);
135 }
136 }
bbbf2d40 137 break;
138
139 case CONTEXT_GROUP:
98882637 140 // Find course.
141 $group = get_record('groups','id',$context->instanceid);
bbbf2d40 142 $courseinstance = get_context_instance(CONTEXT_COURSE, $group->courseid);
98882637 143
144 $parentcats = get_parent_cats($courseinstance->id, CONTEXT_COURSE);
145 foreach ($parentcats as $parentcat) {
146 if (isset($capabilities[$parentcat->id]['do_anything'])) {
147 return ($capabilities[$parentcat->id]['do_anything']);
148 }
149 }
150
151 $coursecontext = '';
152 if (isset($capabilities[$courseinstance->id]['do_anything'])) {
153 return ($capabilities[$courseinstance->id]['do_anything']);
154 }
155
bbbf2d40 156 break;
157
158 case CONTEXT_MODULE:
159 // Find course.
160 $cm = get_record('course_modules', 'id', $context->instanceid);
98882637 161 $courseinstance = get_context_instance(CONTEXT_COURSE, $cm->course);
bbbf2d40 162
98882637 163 if ($parentcats = get_parent_cats($courseinstance->id, CONTEXT_COURSE)) {
164 foreach ($parentcats as $parentcat) {
165 if (isset($capabilities[$parentcat]['do_anything'])) {
166 return ($capabilities[$parentcat]['do_anything']);
167 }
168 }
169 }
170
171 if (isset($capabilities[$courseinstance->id]['do_anything'])) {
172 return ($capabilities[$courseinstance->id]['do_anything']);
173 }
bbbf2d40 174
175 break;
176
177 case CONTEXT_BLOCK:
178 // 1 to 1 to course.
179 // Find course.
180 $block = get_record('block_instance','id',$context->instanceid);
181 $courseinstance = get_context_instance(CONTEXT_COURSE, $block->pageid); // needs check
98882637 182
183 $parentcats = get_parent_cats($courseinstance->id, CONTEXT_COURSE);
184 foreach ($parentcats as $parentcat) {
185 if (isset($capabilities[$parentcat]['do_anything'])) {
186 return ($capabilities[$parentcat]['do_anything']);
187 }
188 }
189
190 if (isset($capabilities[$courseinstance->id]['do_anything'])) {
191 return ($capabilities[$courseinstance->id]['do_anything']);
192 }
bbbf2d40 193 break;
194
195 default:
196 // CONTEXT_SYSTEM: CONTEXT_PERSONAL: CONTEXT_USERID:
197 // Do nothing.
198 break;
98882637 199 }
bbbf2d40 200
98882637 201 // Last: check self.
202 if (isset($capabilities[$contextid]['do_anything'])) {
203 return ($capabilities[$contextid]['do_anything']);
204 }
205
206 // do_anything has not been set, we now look for it the normal way.
207 return capability_search($capability, $contextid, $kill, $capabilities);
bbbf2d40 208
209}
210
211
212/**
213 * In a separate function so that we won't have to deal with do_anything.
214 * again. Used by function has_capability.
215 * @param $capability - capability string
216 * @param $contextid - the context id
217 * @param $kill - boolean. Error out and exit if the user doesn't have the
218 * capability?
219 * @param $capabilities - either $USER->capability or loaded array
220 * @return permission (int)
221 */
222function capability_search($capability, $contextid, $kill=false, $capabilities) {
223 global $USER, $CFG;
224
225 if ($CFG->debug) {
98882637 226 notify("We are looking for $capability in context $contextid", 'notifytiny');
bbbf2d40 227 }
228
229 if (isset($capabilities[$contextid][$capability])) {
230 return ($capabilities[$contextid][$capability]);
231 }
232
233 /* Then, we check the cache recursively */
234 $context = get_record('context','id',$contextid); // shared
98882637 235 $permission = 0;
236
bbbf2d40 237 switch (context_level($contextid)) {
238
239 case CONTEXT_SYSTEM: // by now it's a definite an inherit
240 $permission = 0;
241 break;
242
243 case CONTEXT_PERSONAL:
244 $parent = get_context_instance(CONTEXT_SYSTEM, SITEID);
245 $permission = (capability_search($capability, $parent->id, false, $capabilities));
246 break;
247
248 case CONTEXT_USERID:
249 $parent = get_context_instance(CONTEXT_SYSTEM, SITEID);
250 $permission = (capability_search($capability, $parent->id, false, $capabilities));
251 break;
252
253 case CONTEXT_COURSECAT: // Coursecat -> coursecat or site
254 $coursecat = get_record('course_categories','id',$context->instanceid);
255 if ($coursecat->parent) { // return parent value if exist
256 $parent = get_context_instance(CONTEXT_COURSECAT, $coursecat->parent);
257 } else { // else return site value
258 $parent = get_context_instance(CONTEXT_SYSTEM, SITEID);
259 }
260 $permission = (capability_search($capability, $parent->id, false, $capabilities));
261 break;
262
263 case CONTEXT_COURSE: // 1 to 1 to course cat
264 // find the course cat, and return its value
265 $course = get_record('course','id',$context->instanceid);
266 $parent = get_context_instance(CONTEXT_COURSECAT, $course->category);
267 $permission = (capability_search($capability, $parent->id, false, $capabilities));
268 break;
269
270 case CONTEXT_GROUP: // 1 to 1 to course
271 $group = get_record('groups','id',$context->instanceid);
272 $parent = get_context_instance(CONTEXT_COURSE, $group->courseid);
273 $permission = (capability_search($capability, $parent->id, false, $capabilities));
274 break;
275
276 case CONTEXT_MODULE: // 1 to 1 to course
277 $cm = get_record('course_modules','id',$context->instanceid);
278 $parent = get_context_instance(CONTEXT_COURSE, $cm->course);
279 $permission = (capability_search($capability, $parent->id, false, $capabilities));
280 break;
281
282 case CONTEXT_BLOCK: // 1 to 1 to course
283 $block = get_record('block_instance','id',$context->instanceid);
284 $parent = get_context_instance(CONTEXT_COURSE, $block->pageid); // needs check
285 $permission = (capability_search($capability, $parent->id, false, $capabilities));
286 break;
287
288 default:
289 error ('This is an unknown context!');
290 return false;
291 }
292
293 if ($kill && ($permission <= 0)) {
98882637 294 error ('You do not have the required capability '.$capability);
295 }
296 return $permission;
bbbf2d40 297}
298
299
300/**
301 * This function should be called immediately after a login, when $USER is set.
302 * It will build an array of all the capabilities at each level
303 * i.e. site/metacourse/course_category/course/moduleinstance
304 * Note we should only load capabilities if they are explicitly assigned already,
305 * we should not load all module's capability!
306 * @param $userid - the id of the user whose capabilities we want to load
307 * @return array
308 * possible just s simple 2D array with [contextid][capabilityname]
309 * [Capabilities] => [26][forum_post] = 1
310 * [26][forum_start] = -8990
311 * [26][forum_edit] = -1
312 * [273][blah blah] = 1
313 * [273][blah blah blah] = 2
314 */
315function load_user_capability($capability='', $contextid ='', $userid='') {
316
98882637 317 global $USER, $CFG;
bbbf2d40 318
319 if (empty($userid)) {
320 $userid = $USER->id;
321 } else {
98882637 322 $otheruserid = $userid;
bbbf2d40 323 }
324
325 if ($capability) {
98882637 326 $capsearch = ' AND rc.capability = '.$capability.' ';
bbbf2d40 327 } else {
98882637 328 $capsearch ='';
bbbf2d40 329 }
330 // First we generate a list of all relevant contexts of the user
331
98882637 332 if ($contextid) { // if context is specified
333 $context = get_record('context', 'id', $contextid);
334
335 $usercontexts = get_parent_contexts($context->id);
336 $listofcontexts = '('.implode(',', $usercontexts).')';
337 } else { // else, we load everything
338 $usercontexts = get_records('role_assignments','userid',$userid);
339 $listofcontexts = '(';
340 foreach ($usercontexts as $usercontext) {
341 $listofcontexts .= $usercontext->contextid;
342 $listofcontexts .= ',';
343 }
344 $listofcontexts = rtrim ($listofcontexts, ",");
345 $listofcontexts .= ')';
bbbf2d40 346 }
347
348 // Then we use 1 giant SQL to bring out all relevant capabilities.
349 // The first part gets the capabilities of orginal role.
350 // The second part gets the capabilities of overriden roles.
351
98882637 352 $siteinstance = get_context_instance(CONTEXT_SYSTEM, SITEID);
bbbf2d40 353
41811960 354 $SQL = " SELECT rc.capability, c1.id, (c1.level * 100) AS aggregatelevel,
bbbf2d40 355 SUM(rc.permission) AS sum
356 FROM
171948fd 357 {$CFG->prefix}role_assignments AS ra,
358 {$CFG->prefix}role_capabilities AS rc,
359 {$CFG->prefix}context AS c1
bbbf2d40 360 WHERE
171948fd 361 ra.contextid=c1.id AND
362 ra.roleid=rc.roleid AND
bbbf2d40 363 ra.userid=$userid AND
364 c1.id IN $listofcontexts AND
365 rc.contextid=$siteinstance->id
98882637 366 $capsearch
bbbf2d40 367 GROUP BY
41811960 368 rc.capability,aggregatelevel,c1.id
bbbf2d40 369 HAVING
41811960 370 SUM(rc.permission) != 0
bbbf2d40 371 UNION
372
41811960 373 SELECT rc.capability, c1.id, (c1.level * 100 + c2.level) AS aggregatelevel,
bbbf2d40 374 SUM(rc.permission) AS sum
375 FROM
171948fd 376 {$CFG->prefix}role_assignments AS ra,
377 {$CFG->prefix}role_capabilities AS rc,
378 {$CFG->prefix}context AS c1,
379 {$CFG->prefix}context AS c2
bbbf2d40 380 WHERE
171948fd 381 ra.contextid=c1.id AND
382 ra.roleid=rc.roleid AND
383 ra.userid=$userid AND
384 rc.contextid=c2.id AND
bbbf2d40 385 c1.id IN $listofcontexts AND
386 c2.id IN $listofcontexts AND rc.contextid != $siteinstance->id
387 $capsearch
388
389 GROUP BY
41811960 390 rc.capability, aggregatelevel, c1.id
bbbf2d40 391 HAVING
41811960 392 SUM(rc.permission) != 0
bbbf2d40 393 ORDER BY
41811960 394 aggregatelevel ASC
bbbf2d40 395 ";
396
bbbf2d40 397
98882637 398 $capabilities = array(); // Reinitialize.
399 $rs = get_recordset_sql($SQL);
400
bbbf2d40 401 if ($rs && $rs->RecordCount() > 0) {
402 while (!$rs->EOF) {
98882637 403 $array = $rs->fields;
404 $temprecord = new object;
405
406 foreach ($array as $key=>$val) {
407 $temprecord->{$key} = $val;
408 }
bbbf2d40 409 $capabilities[] = $temprecord;
410 $rs->MoveNext();
411 }
412 }
413
414 /* so up to this point we should have somethign like this
41811960 415 * $capabilities[1] ->aggregatelevel = 1000
bbbf2d40 416 ->module = SITEID
417 ->capability = do_anything
418 ->id = 1 (id is the context id)
419 ->sum = 0
420
41811960 421 * $capabilities[2] ->aggregatelevel = 1000
bbbf2d40 422 ->module = SITEID
423 ->capability = post_messages
424 ->id = 1
425 ->sum = -9000
426
41811960 427 * $capabilittes[3] ->aggregatelevel = 3000
bbbf2d40 428 ->module = course
429 ->capability = view_course_activities
430 ->id = 25
431 ->sum = 1
432
41811960 433 * $capabilittes[4] ->aggregatelevel = 3000
bbbf2d40 434 ->module = course
435 ->capability = view_course_activities
436 ->id = 26
437 ->sum = 0 (this is another course)
438
41811960 439 * $capabilities[5] ->aggregatelevel = 3050
bbbf2d40 440 ->module = course
441 ->capability = view_course_activities
442 ->id = 25 (override in course 25)
443 ->sum = -1
444 * ....
445 * now we proceed to write the session array, going from top to bottom
446 * at anypoint, we need to go up and check parent to look for prohibit
447 */
448 // print_object($capabilities);
449
450 /* This is where we write to the actualy capabilities array
451 * what we need to do from here on is
452 * going down the array from lowest level to highest level
453 * 1) recursively check for prohibit,
454 * if any, we write prohibit
455 * else, we write the value
456 * 2) at an override level, we overwrite current level
457 * if it's not set to prohibit already, and if different
458 * ........ that should be it ........
459 */
98882637 460 $usercap = array(); // for other user's capabilities
bbbf2d40 461 foreach ($capabilities as $capability) {
462
41811960 463 if (!empty($otheruserid)) { // we are pulling out other user's capabilities, do not write to session
98882637 464
465 if (capability_prohibits($capability->capability, $capability->id, $capability->sum, $usercap)) {
466 $usercap[$capability->id][$capability->capability] = -9000;
467 continue;
468 }
469
470 $usercap[$capability->id][$capability->capability] = $capability->sum;
471
472 } else {
473
474 if (capability_prohibits($capability->capability, $capability->id, $capability->sum)) { // if any parent or parent's parent is set to prohibit
475 $USER->capabilities[$capability->id][$capability->capability] = -9000;
476 continue;
477 }
478
479 // if no parental prohibit set
480 // just write to session, i am not sure this is correct yet
481 // since 3050 shows up after 3000, and 3070 shows up after 3050,
482 // it should be ok just to overwrite like this, provided that there's no
483 // parental prohibits
484 // no point writing 0, since 0 = inherit
485 // we need to write even if it's 0, because it could be an inherit override
486 $USER->capabilities[$capability->id][$capability->capability] = $capability->sum;
487 }
bbbf2d40 488 }
489
490 // now we don't care about the huge array anymore, we can dispose it.
491 unset($capabilities);
492
41811960 493 if (!empty($otheruseid)) {
98882637 494 return $usercap; // return the array
bbbf2d40 495 }
496 // see array in session to see what it looks like
497
498}
499
500
501/**
502 * This is a recursive function that checks whether the capability in this
503 * context, or the parent capabilities are set to prohibit.
504 *
505 * At this point, we can probably just use the values already set in the
506 * session variable, since we are going down the level. Any prohit set in
507 * parents would already reflect in the session.
508 *
509 * @param $capability - capability name
510 * @param $sum - sum of all capabilities values
511 * @param $contextid - the context id
512 * @param $array - when loading another user caps, their caps are not stored in session but an array
513 */
514function capability_prohibits($capability, $contextid, $sum='', $array='') {
515 global $USER;
516 if ($sum < -8000) {
517 // If this capability is set to prohibit.
518 return true;
519 }
520
521 if (isset($array)) {
522 if (isset($array[$contextid][$capability])
523 && $array[$contextid][$capability] < -8000) {
98882637 524 return true;
525 }
bbbf2d40 526 } else {
98882637 527 // Else if set in session.
528 if (isset($USER->capabilities[$contextid][$capability])
bbbf2d40 529 && $USER->capabilities[$contextid][$capability] < -8000) {
98882637 530 return true;
531 }
bbbf2d40 532 }
533 $context = get_record('context', 'id', $contextid);
534 switch (context_level($contextid)) {
535
536 case CONTEXT_SYSTEM:
537 // By now it's a definite an inherit.
538 return 0;
539 break;
540
541 case CONTEXT_PERSONAL:
542 $parent = get_context_instance(CONTEXT_SYSTEM, SITEID);
543 return (capability_prohibits($capability, $parent->id));
544 break;
545
546 case CONTEXT_USERID:
547 $parent = get_context_instance(CONTEXT_SYSTEM, SITEID);
548 return (capability_prohibits($capability, $parent->id));
549 break;
550
551 case CONTEXT_COURSECAT:
552 // Coursecat -> coursecat or site.
553 $coursecat = get_record('course_categories','id',$context->instanceid);
41811960 554 if (!empty($coursecat->parent)) {
bbbf2d40 555 // return parent value if exist.
556 $parent = get_context_instance(CONTEXT_COURSECAT, $coursecat->parent);
557 } else {
558 // Return site value.
559 $parent = get_context_instance(CONTEXT_SYSTEM, SITEID);
560 }
561 return (capability_prohibits($capability, $parent->id));
562 break;
563
564 case CONTEXT_COURSE:
565 // 1 to 1 to course cat.
566 // Find the course cat, and return its value.
567 $course = get_record('course','id',$context->instanceid);
568 $parent = get_context_instance(CONTEXT_COURSECAT, $course->category);
569 return (capability_prohibits($capability, $parent->id));
570 break;
571
572 case CONTEXT_GROUP:
573 // 1 to 1 to course.
574 $group = get_record('groups','id',$context->instanceid);
575 $parent = get_context_instance(CONTEXT_COURSE, $group->courseid);
576 return (capability_prohibits($capability, $parent->id));
577 break;
578
579 case CONTEXT_MODULE:
580 // 1 to 1 to course.
581 $cm = get_record('course_modules','id',$context->instanceid);
582 $parent = get_context_instance(CONTEXT_COURSE, $cm->course);
583 return (capability_prohibits($capability, $parent->id));
584 break;
585
586 case CONTEXT_BLOCK:
587 // 1 to 1 to course.
588 $block = get_record('block_instance','id',$context->instanceid);
589 $parent = get_context_instance(CONTEXT_COURSE, $block->pageid); // needs check
590 return (capability_prohibits($capability, $parent->id));
591 break;
592
593 default:
594 error ('This is an unknown context!');
595 return false;
596 }
597}
598
599
600/**
601 * A print form function. This should either grab all the capabilities from
602 * files or a central table for that particular module instance, then present
603 * them in check boxes. Only relevant capabilities should print for known
604 * context.
605 * @param $mod - module id of the mod
606 */
607function print_capabilities($modid=0) {
608 global $CFG;
609
610 $capabilities = array();
611
612 if ($modid) {
613 // We are in a module specific context.
614
615 // Get the mod's name.
616 // Call the function that grabs the file and parse.
617 $cm = get_record('course_modules', 'id', $modid);
618 $module = get_record('modules', 'id', $cm->module);
619
620 } else {
621 // Print all capabilities.
622 foreach ($capabilities as $capability) {
623 // Prints the check box component.
624 }
625 }
626}
627
628
629/**
1afecc03 630 * Installs the roles system.
631 * This function runs on a fresh install as well as on an upgrade from the old
632 * hard-coded student/teacher/admin etc. roles to the new roles system.
bbbf2d40 633 */
1afecc03 634function moodle_install_roles() {
bbbf2d40 635
1afecc03 636 global $CFG, $db;
637
bbbf2d40 638 // Create a system wide context for assignemnt.
639 $systemcontext = $context = get_context_instance(CONTEXT_SYSTEM, SITEID);
640
1afecc03 641
642 // Create default/legacy roles and capabilities.
643 // (1 legacy capability per legacy role at system level).
bbbf2d40 644 $adminrole = create_role(get_string('administrator'), get_string('administratordescription'), 'moodle/legacy:admin');
98882637 645 if (!assign_capability('moodle/site:doanything', CAP_ALLOW, $adminrole, $systemcontext->id)) {
bbbf2d40 646 error('Could not assign moodle/site:doanything to the admin role');
647 }
648 $coursecreatorrole = create_role(get_string('coursecreators'), get_string('coursecreatorsdescription'), 'moodle/legacy:coursecreator');
98882637 649 $noneditteacherrole = create_role(get_string('noneditingteacher'), get_string('noneditingteacherdescription'), 'moodle/legacy:teacher');
650 $editteacherrole = create_role(get_string('defaultcourseteacher'), get_string('defaultcourseteacherdescription'), 'moodle/legacy:editingteacher');
651 $studentrole = create_role(get_string('defaultcoursestudent'), get_string('defaultcoursestudentdescription'), 'moodle/legacy:student');
bbbf2d40 652 $guestrole = create_role(get_string('guest'), get_string('guestdescription'), 'moodle/legacy:guest');
1afecc03 653
654
655 // Look inside user_admin, user_creator, user_teachers, user_students and
656 // assign above new roles. If a user has both teacher and student role,
657 // only teacher role is assigned. The assignment should be system level.
658 $dbtables = $db->MetaTables('TABLES');
bbbf2d40 659
1afecc03 660
98882637 661 /**
bbbf2d40 662 * Upgrade the admins.
1afecc03 663 * Sort using id ASC, first one is primary admin.
bbbf2d40 664 */
1afecc03 665 if (in_array($CFG->prefix.'user_admins', $dbtables)) {
666 if ($useradmins = get_records_sql('SELECT * from '.$CFG->prefix.'user_admins ORDER BY ID ASC')) {
667 foreach ($useradmins as $admin) {
668 role_assign($adminrole, $admin->userid, 0, $systemcontext->id);
669 }
670 }
671 } else {
672 // This is a fresh install.
bbbf2d40 673 }
1afecc03 674
675
bbbf2d40 676 /**
677 * Upgrade course creators.
678 */
1afecc03 679 if (in_array($CFG->prefix.'user_coursecreators', $dbtables)) {
680 if ($usercoursecreators = get_records('user_coursecreators')) {
681 foreach ($usercoursecreators as $coursecreator) {
682 role_assign($$coursecreatorrole, $coursecreator->userid, 0, $systemcontext->id);
683 }
684 }
bbbf2d40 685 }
686
1afecc03 687
bbbf2d40 688 /**
689 * Upgrade editting teachers and non-editting teachers.
690 */
1afecc03 691 if (in_array($CFG->prefix.'user_teachers', $dbtables)) {
692 if ($userteachers = get_records('user_teachers')) {
693 foreach ($userteachers as $teacher) {
694 $coursecontext = get_context_instance(CONTEXT_COURSE, $teacher->course); // needs cache
695 if ($teacher->editall) { // editting teacher
696 role_assign($editteacherrole, $teacher->userid, 0, $coursecontext->id);
697 } else {
698 role_assign($noneditteacherrole, $teacher->userid, 0, $coursecontext->id);
699 }
700 }
bbbf2d40 701 }
702 }
1afecc03 703
704
bbbf2d40 705 /**
706 * Upgrade students.
707 */
1afecc03 708 if (in_array($CFG->prefix.'user_students', $dbtables)) {
709 if ($userstudents = get_records('user_students')) {
710 foreach ($userstudents as $student) {
711 $coursecontext = get_context_instance(CONTEXT_COURSE, $student->course);
712 role_assign($studentrole, $student->userid, 0, $coursecontext->id);
713 }
714 }
bbbf2d40 715 }
1afecc03 716
717
bbbf2d40 718 /**
719 * Upgrade guest (only 1 entry).
720 */
1afecc03 721 if ($guestuser = get_record('user', 'username', 'guest')) {
722 role_assign($guestrole, $guestuser->id, 0, $systemcontext->id);
723 }
724
725
726 // Should we delete the tables after we are done? Not yet.
bbbf2d40 727}
728
729
730/**
731 * Assign the defaults found in this capabality definition to roles that have
732 * the corresponding legacy capabilities assigned to them.
733 * @param $legacyperms - an array in the format (example):
734 * 'guest' => CAP_PREVENT,
735 * 'student' => CAP_ALLOW,
736 * 'teacher' => CAP_ALLOW,
737 * 'editingteacher' => CAP_ALLOW,
738 * 'coursecreator' => CAP_ALLOW,
739 * 'admin' => CAP_ALLOW
740 * @return boolean - success or failure.
741 */
742function assign_legacy_capabilities($capability, $legacyperms) {
743
744 foreach ($legacyperms as $type => $perm) {
745
746 $systemcontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
747
748 // The legacy capabilities are:
749 // 'moodle/legacy:guest'
750 // 'moodle/legacy:student'
751 // 'moodle/legacy:teacher'
752 // 'moodle/legacy:editingteacher'
753 // 'moodle/legacy:coursecreator'
754 // 'moodle/legacy:admin'
755
756 if (!$roles = get_roles_with_capability('moodle/legacy:'.$type, CAP_ALLOW)) {
757 return false;
758 }
759
760 foreach ($roles as $role) {
761 // Assign a site level capability.
762 if(!assign_capability($capability, $perm, $role->id, $systemcontext->id)) {
763 return false;
764 }
765 }
766 }
767 return true;
768}
769
770
771// checks to see if a capability is a legacy capability, returns bool
772function islegacy($capabilityname) {
98882637 773 if (strstr($capabilityname, 'legacy') === false) {
774 return false;
775 } else {
776 return true;
777 }
bbbf2d40 778}
779
780/************************************
781 * Context Manipulation functions *
782 **********************************/
783
784
785/**
786 * This should be called prolly everytime a user, group, module, course,
787 * coursecat or site is set up maybe?
788 * @param $level
789 * @param $instanceid
790 */
791function create_context($level, $instanceid) {
792 if (!get_record('context','level',$level,'instanceid',$instanceid)) {
793 $context = new object;
794 $context->level = $level;
795 $context->instanceid = $instanceid;
796 return insert_record('context',$context);
797 }
798}
799
800
801/**
802 * Get the context instance as an object. This function will create the
803 * context instance if it does not exist yet.
804 * @param $level
805 * @param $instance
806 */
807function get_context_instance($level, $instance=SITEID) {
808 // echo "getting level $level instance $instance";
809
810 // XXX TODO Add caching here
98882637 811 if (!$context = get_record('context', 'level', $level, 'instanceid', $instance)) {
812 //echo "creating ...";
813 create_context($level, $instance);
814 $context = get_record('context', 'level', $level, 'instanceid', $instance);
815 }
bbbf2d40 816 return $context;
817}
818
819
820/**
821 * Looks up the context level.
822 * @param int $contextid
823 * @return int
824 */
825function context_level($contextid) {
826 $context = get_record('context','id',$contextid);
827 return ($context->level);
828}
829
830
831
832/************************************
833 * DB TABLE RELATED FUNCTIONS *
834 ************************************/
835
836/**********************************************
837 * function that creates a role
838 * @param name - role name
839 * @param description - role description
840 * @param legacy - optional legacy capability
841 * @return id or false
842 */
843function create_role($name, $description, $legacy='') {
98882637 844
845 // check for duplicate role name
846
847 if ($role = get_record('role','name', $name)) {
848 print_object($role);
849 error('there is already a role with this name!');
850 }
851
852 $role->name = $name;
853 $role->description = $description;
854
855 if ($id = insert_record('role', $role)) {
1afecc03 856 if ($legacy) {
857 $context = get_context_instance(CONTEXT_SYSTEM, SITEID);
858 assign_capability($legacy, CAP_ALLOW, $id, $context->id);
98882637 859 }
860 return $id;
861 } else {
862 return false;
863 }
bbbf2d40 864
865}
866
867/**
868 * Function to write context specific overrides, or default capabilities.
869 * @param module - string name
870 * @param capability - string name
871 * @param contextid - context id
872 * @param roleid - role id
873 * @param permission - int 1,-1 or -1000
874 */
875function assign_capability($capability, $permission, $roleid, $contextid) {
98882637 876
877 global $USER;
878
879 if (empty($permission) || $permission == 0) { // if permission is not set
880 unassign_capability($capability, $roleid, $contextid);
881 }
bbbf2d40 882
883 $cap = new object;
884 $cap->contextid = $contextid;
885 $cap->roleid = $roleid;
886 $cap->capability = $capability;
887 $cap->permission = $permission;
888 $cap->timemodified = time();
1afecc03 889 if ($USER->id) {
890 $cap->modifierid = $USER->id;
891 } else {
892 $cap->modifierid = -1; // Happens during fresh install or Moodle.
893 }
bbbf2d40 894
895 return insert_record('role_capabilities', $cap);
896}
897
898
899/**
900 * Unassign a capability from a role.
901 * @param $roleid - the role id
902 * @param $capability - the name of the capability
903 * @return boolean - success or failure
904 */
905function unassign_capability($capability, $roleid, $contextid=NULL) {
98882637 906
907 if (isset($contextid)) {
908 $status = delete_records('role_capabilities', 'capability', $capability,
909 'roleid', $roleid, 'contextid', $contextid);
910 } else {
911 $status = delete_records('role_capabilities', 'capability', $capability,
912 'roleid', $roleid);
913 }
914 return $status;
bbbf2d40 915}
916
917
918/**
919 * Get the roles that have a given capability.
920 * @param $capability - capability name (string)
921 * @param $permission - optional, the permission defined for this capability
922 * either CAP_ALLOW, CAP_PREVENT or CAP_PROHIBIT
923 * @return array or role objects
924 */
925function get_roles_with_capability($capability, $permission=NULL) {
926
927 global $CFG;
928
929 $selectroles = "SELECT r.*
930 FROM {$CFG->prefix}role AS r,
931 {$CFG->prefix}role_capabilities AS rc
932 WHERE rc.capability = '$capability'
933 AND rc.roleid = r.id";
934
935 if (isset($permission)) {
936 $selectroles .= " AND rc.permission = '$permission'";
937 }
938 return get_records_sql($selectroles);
939}
940
941
942/**
943 * This function makes a role-assignment (user to a role)
944 * @param $roleid - the role of the id
945 * @param $userid - userid
946 * @param $groupid - group id
947 * @param $contextid - id of the context
948 * @param $timestart - time this assignment becomes effective
949 * @param $timeend - time this assignemnt ceases to be effective
950 * @uses $USER
951 * @return id - new id of the assigment
952 */
953function role_assign($roleid, $userid, $groupid, $contextid, $timestart=0, $timeend=0, $hidden=0) {
aa311411 954 global $USER, $CFG;
bbbf2d40 955
aa311411 956 if ($CFG->debug) {
98882637 957 notify("Assign roleid $roleid userid $userid contextid $contextid", 'notifytiny');
aa311411 958 }
bbbf2d40 959
960 if (empty($roleid)) {
961 error ('you need to select a role');
962 }
963
964 if (empty($userid) && empty($groupid)) {
965 error ('you need to assign this role to a user or a group');
966 }
967
968 if (empty($contextid)) {
969 error ('you need to assign this role to a context, e.g. a course, or an activity');
970 }
971
972 $ra = new object;
973 $ra->roleid = $roleid;
974 $ra->contextid = $contextid;
975 $ra->userid = $userid;
976 $ra->hidden = $hidden;
977 $ra->groupid = $groupid;
978 $ra->timestart = $timestart;
979 $ra->timeend = $timeend;
980 $ra->timemodified = time();
981 $ra->modifier = $USER->id;
982
983 return insert_record('role_assignments', $ra);
984
985}
986
987
988/**
989 * Deletes a role assignment.
990 * @param $roleid
991 * @param $userid
992 * @param $groupid
993 * @param $contextid
994 * @return boolean - success or failure
995 */
996function role_unassign($roleid, $userid, $groupid, $contextid) {
98882637 997 if ($groupid) {
998 // do nothing yet as this is not implemented
999 }
1000 else {
1001 return delete_records('role_assignments', 'userid', $userid,
1002 'roleid', $roleid, 'contextid', $contextid);
1003 }
bbbf2d40 1004}
1005
1006
1007/**
1008 * Loads the capability definitions for the component (from file). If no
1009 * capabilities are defined for the component, we simply return an empty array.
1010 * @param $component - examples: 'moodle', 'mod/forum', 'block/quiz_results'
1011 * @return array of capabilities
1012 */
1013function load_capability_def($component) {
1014 global $CFG;
1015
1016 if ($component == 'moodle') {
1017 $defpath = $CFG->libdir.'/db/access.php';
1018 $varprefix = 'moodle';
1019 } else {
1020 $defpath = $CFG->dirroot.'/'.$component.'/db/access.php';
1021 $varprefix = str_replace('/', '_', $component);
1022 }
1023 $capabilities = array();
1024
1025 if (file_exists($defpath)) {
1026 require_once($defpath);
1027 $capabilities = ${$varprefix.'_capabilities'};
1028 }
1029 return $capabilities;
1030}
1031
1032
1033/**
1034 * Gets the capabilities that have been cached in the database for this
1035 * component.
1036 * @param $component - examples: 'moodle', 'mod/forum', 'block/quiz_results'
1037 * @return array of capabilities
1038 */
1039function get_cached_capabilities($component='moodle') {
1040 if ($component == 'moodle') {
1041 $storedcaps = get_records_select('capabilities',
1042 "name LIKE 'moodle/%:%'");
1043 } else {
1044 $storedcaps = get_records_select('capabilities',
1045 "name LIKE '$component:%'");
1046 }
1047 return $storedcaps;
1048}
1049
1050
1051/**
1052 * Updates the capabilities table with the component capability definitions.
1053 * If no parameters are given, the function updates the core moodle
1054 * capabilities.
1055 *
1056 * Note that the absence of the db/access.php capabilities definition file
1057 * will cause any stored capabilities for the component to be removed from
1058 * the database.
1059 *
1060 * @param $component - examples: 'moodle', 'mod/forum', 'block/quiz_results'
1061 * @return boolean
1062 */
1063function update_capabilities($component='moodle') {
1064
1065 $storedcaps = array();
1066 $filecaps = array();
1067
1068 $cachedcaps = get_cached_capabilities($component);
1069 if ($cachedcaps) {
1070 foreach ($cachedcaps as $cachedcap) {
1071 array_push($storedcaps, $cachedcap->name);
1072 }
1073 }
1074
1075 $filecaps = load_capability_def($component);
1076
1077 // Are there new capabilities in the file definition?
1078 $newcaps = array();
1079
1080 foreach ($filecaps as $filecap => $def) {
1081 if (!$storedcaps ||
1082 ($storedcaps && in_array($filecap, $storedcaps) === false)) {
1083 $newcaps[$filecap] = $def;
1084 }
1085 }
1086 // Add new capabilities to the stored definition.
1087 foreach ($newcaps as $capname => $capdef) {
1088 $capability = new object;
1089 $capability->name = $capname;
1090 $capability->captype = $capdef['captype'];
1091 $capability->contextlevel = $capdef['contextlevel'];
1092 $capability->component = $component;
1093
1094 if (!insert_record('capabilities', $capability, false, 'id')) {
1095 return false;
1096 }
1097 // Do we need to assign the new capabilities to roles that have the
1098 // legacy capabilities moodle/legacy:* as well?
1099 if (isset($capdef['legacy']) && is_array($capdef['legacy']) &&
1100 !assign_legacy_capabilities($capname, $capdef['legacy'])) {
1101 error('Could not assign legacy capabilities');
1102 return false;
1103 }
1104 }
1105 // Are there any capabilities that have been removed from the file
1106 // definition that we need to delete from the stored capabilities and
1107 // role assignments?
1108 capabilities_cleanup($component, $filecaps);
1109
1110 return true;
1111}
1112
1113
1114/**
1115 * Deletes cached capabilities that are no longer needed by the component.
1116 * Also unassigns these capabilities from any roles that have them.
1117 * @param $component - examples: 'moodle', 'mod/forum', 'block/quiz_results'
1118 * @param $newcapdef - array of the new capability definitions that will be
1119 * compared with the cached capabilities
1120 * @return int - number of deprecated capabilities that have been removed
1121 */
1122function capabilities_cleanup($component, $newcapdef=NULL) {
1123
1124 $removedcount = 0;
1125
1126 if ($cachedcaps = get_cached_capabilities($component)) {
1127 foreach ($cachedcaps as $cachedcap) {
1128 if (empty($newcapdef) ||
1129 array_key_exists($cachedcap->name, $newcapdef) === false) {
1130
1131 // Remove from capabilities cache.
1132 if (!delete_records('capabilities', 'name', $cachedcap->name)) {
1133 error('Could not delete deprecated capability '.$cachedcap->name);
1134 } else {
1135 $removedcount++;
1136 }
1137 // Delete from roles.
1138 if($roles = get_roles_with_capability($cachedcap->name)) {
1139 foreach($roles as $role) {
1140 if (!unassign_capability($role->id, $cachedcap->name)) {
1141 error('Could not unassign deprecated capability '.
1142 $cachedcap->name.' from role '.$role->name);
1143 }
1144 }
1145 }
1146 } // End if.
1147 }
1148 }
1149 return $removedcount;
1150}
1151
1152
1153
1154
1155/************************************************************
1156 * * UI FUNCTIONS * *
1157 ************************************************************/
1158
1159
1160/**
1161 * prints human readable context identifier.
1162 */
1163function print_context_name($contextid) {
1164
ec0810ee 1165 $name = '';
1166
98882637 1167 $context = get_record('context', 'id', $contextid);
ec0810ee 1168
98882637 1169 switch ($context->level) {
1170
bbbf2d40 1171 case CONTEXT_SYSTEM: // by now it's a definite an inherit
ec0810ee 1172 $name = get_string('site');
bbbf2d40 1173 break;
1174
1175 case CONTEXT_PERSONAL:
ec0810ee 1176 $name = get_string('personal');
bbbf2d40 1177 break;
1178
1179 case CONTEXT_USERID:
ec0810ee 1180 if ($user = get_record('user', 'id', $context->instanceid)) {
1181 $name = get_string('user').': '.fullname($user);
1182 }
bbbf2d40 1183 break;
1184
1185 case CONTEXT_COURSECAT: // Coursecat -> coursecat or site
ec0810ee 1186 if ($category = get_record('course_categories', 'id', $context->instanceid)) {
1187 $name = get_string('category').': '.$category->name;
1188 }
bbbf2d40 1189 break;
1190
1191 case CONTEXT_COURSE: // 1 to 1 to course cat
ec0810ee 1192 if ($course = get_record('course', 'id', $context->instanceid)) {
1193 $name = get_string('course').': '.$course->fullname;
1194 }
bbbf2d40 1195 break;
1196
1197 case CONTEXT_GROUP: // 1 to 1 to course
ec0810ee 1198 if ($group = get_record('groups', 'id', $context->instanceid)) {
1199 $name = get_string('group').': '.$group->name;
1200 }
bbbf2d40 1201 break;
1202
1203 case CONTEXT_MODULE: // 1 to 1 to course
98882637 1204 if ($cm = get_record('course_modules','id',$context->instanceid)) {
1205 if ($module = get_record('modules','id',$cm->module)) {
1206 if ($mod = get_record($module->name, 'id', $cm->instance)) {
ec0810ee 1207 $name = get_string('activitymodule').': '.$mod->name;
98882637 1208 }
ec0810ee 1209 }
1210 }
bbbf2d40 1211 break;
1212
1213 case CONTEXT_BLOCK: // 1 to 1 to course
98882637 1214 if ($blockinstance = get_record('block_instance','id',$context->instanceid)) {
1215 if ($block = get_record('block','id',$blockinstance->blockid)) {
ec0810ee 1216 $name = get_string('blocks').': '.get_string($block->name, 'block_'.$block->name);
1217 }
1218 }
bbbf2d40 1219 break;
1220
1221 default:
1222 error ('This is an unknown context!');
1223 return false;
98882637 1224
1225 }
bbbf2d40 1226
98882637 1227 return $name;
bbbf2d40 1228}
1229
1230
1231/**
1232 * Extracts the relevant capabilities given a contextid.
1233 * All case based, example an instance of forum context.
1234 * Will fetch all forum related capabilities, while course contexts
1235 * Will fetch all capabilities
1236 * @param int contextid
1237 * @return array();
1238 *
1239 * capabilities
1240 * `name` varchar(150) NOT NULL,
1241 * `captype` varchar(50) NOT NULL,
1242 * `contextlevel` int(10) NOT NULL,
1243 * `component` varchar(100) NOT NULL,
1244 */
1245function fetch_context_capabilities($contextid) {
98882637 1246
1247 global $CFG;
bbbf2d40 1248
1249 $sort = 'ORDER BY contextlevel,component,id'; // To group them sensibly for display
98882637 1250
bbbf2d40 1251 switch (context_level($contextid)) {
1252
98882637 1253 case CONTEXT_SYSTEM: // all
1254 $SQL = "select * from {$CFG->prefix}capabilities";
bbbf2d40 1255 break;
1256
1257 case CONTEXT_PERSONAL:
1258 break;
1259
1260 case CONTEXT_USERID:
1261 break;
1262
1263 case CONTEXT_COURSECAT: // all
98882637 1264 $SQL = "select * from {$CFG->prefix}capabilities";
bbbf2d40 1265 break;
1266
1267 case CONTEXT_COURSE: // all
98882637 1268 $SQL = "select * from {$CFG->prefix}capabilities";
bbbf2d40 1269 break;
1270
1271 case CONTEXT_GROUP: // group caps
1272 break;
1273
1274 case CONTEXT_MODULE: // mod caps
98882637 1275 $context = get_record('context','id',$contextid);
1276 $cm = get_record('course_modules', 'id', $context->instanceid);
1277 $module = get_record('modules', 'id', $cm->module);
bbbf2d40 1278
98882637 1279 $SQL = "select * from {$CFG->prefix}capabilities where contextlevel = ".CONTEXT_MODULE."
1280 and component = 'mod/$module->name'";
bbbf2d40 1281 break;
1282
1283 case CONTEXT_BLOCK: // block caps
1284 $context = get_record('context','id',$contextid);
98882637 1285 $cb = get_record('block_instance', 'id', $context->instanceid);
1286 $block = get_record('block', 'id', $cb->blockid);
bbbf2d40 1287
98882637 1288 $SQL = "select * from {$CFG->prefix}capabilities where contextlevel = ".CONTEXT_BLOCK."
1289 and component = 'block/$block->name'";
bbbf2d40 1290 break;
1291
1292 default:
1293 return false;
1294 }
1295
1296 $records = get_records_sql($SQL.' '.$sort);
1297 return $records;
1298
1299}
1300
1301
1302/**
1303 * This function pulls out all the resolved capabilities (overrides and
1304 * defaults) of a role used in capability overrieds in contexts at a given
1305 * context.
1306 * @param int $contextid
1307 * @param int $roleid
1308 * @return array
1309 */
1310function role_context_capabilities($roleid, $contextid) {
98882637 1311 global $CFG;
1312
1313 $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
1314 if ($sitecontext->id == $contextid) {
1315 return array();
1316 }
1317
1318 // first of all, figure out all parental contexts
1319 $context = get_record('context', 'id', $contextid);
1320 $contexts = array_reverse(get_parent_contexts($context));
1321 $contexts = '('.implode(',', $contexts).')';
1322
1323 $SQL = "SELECT rc.* FROM {$CFG->prefix}role_capabilities rc, {$CFG->prefix}context c
1324 where rc.contextid in $contexts
1325 and rc.roleid = $roleid
1326 and rc.contextid = c.id
1327 ORDER BY c.level DESC, rc.capability DESC";
1328
1329 $records = get_records_sql($SQL);
1330
1331 $capabilities = array();
1332
1333 // We are traversing via reverse order.
1334 foreach ($records as $record) {
1335 // If not set yet (i.e. inherit or not set at all), or currently we have a prohibit
1336 if (!isset($capabilities[$record->capability]) || $record->permission<-500) {
1337 $capabilities[$record->capability] = $record->permission;
1338 }
1339 }
1340 return $capabilities;
bbbf2d40 1341}
1342
1343
1344/**
1345 * Recursive function which, given a contextid, find all parent context ids,
1346 * and return the array in reverse order, i.e. parent first, then grand
1347 * parent, etc.
1348 * @param object $context
1349 * @return array()
1350 */
1351
1352
1353function get_parent_contexts($context) {
1354
1355 switch (context_level($context->id)) {
1356
1357 case CONTEXT_SYSTEM: // no parent
98882637 1358 return null;
bbbf2d40 1359 break;
1360
1361 case CONTEXT_PERSONAL:
1362 $parent = get_context_instance(CONTEXT_SYSTEM, SITEID);
1363 return array($parent->id);
1364 break;
1365
1366 case CONTEXT_USERID:
1367 $parent = get_context_instance(CONTEXT_SYSTEM, SITEID);
1368 return array($parent->id);
1369 break;
1370
1371 case CONTEXT_COURSECAT: // Coursecat -> coursecat or site
1372 $coursecat = get_record('course_categories','id',$context->instanceid);
1373 if ($coursecat->parent) { // return parent value if exist
1374 $parent = get_context_instance(CONTEXT_COURSECAT, $coursecat->parent);
1375 return array_merge(array($parent->id), get_parent_contexts($parent));
1376 } else { // else return site value
1377 $parent = get_context_instance(CONTEXT_SYSTEM, SITEID);
1378 return array($parent->id);
1379 }
1380 break;
1381
1382 case CONTEXT_COURSE: // 1 to 1 to course cat
1383 // find the course cat, and return its value
1384 $course = get_record('course','id',$context->instanceid);
1385 $parent = get_context_instance(CONTEXT_COURSECAT, $course->category);
1386 return array_merge(array($parent->id), get_parent_contexts($parent));
1387 break;
1388
1389 case CONTEXT_GROUP: // 1 to 1 to course
1390 $group = get_record('groups','id',$context->instanceid);
1391 $parent = get_context_instance(CONTEXT_COURSE, $group->courseid);
1392 return array_merge(array($parent->id), get_parent_contexts($parent));
1393 break;
1394
1395 case CONTEXT_MODULE: // 1 to 1 to course
1396 $cm = get_record('course_modules','id',$context->instanceid);
1397 $parent = get_context_instance(CONTEXT_COURSE, $cm->course);
1398 return array_merge(array($parent->id), get_parent_contexts($parent));
1399 break;
1400
1401 case CONTEXT_BLOCK: // 1 to 1 to course
1402 $block = get_record('block_instance','id',$context->instanceid);
1403 $parent = get_context_instance(CONTEXT_COURSE, $block->pageid); // needs check
1404 return array_merge(array($parent->id), get_parent_contexts($parent));
1405 break;
1406
1407 default:
1408 error ('This is an unknown context!');
1409 return false;
1410 }
1411
1412}
1413
1414
1415/**
1416 * This function gets the capability of a role in a given context.
1417 * It is needed when printing override forms.
1418 * @param int $contextid
1419 * @param int $roleid // no need? since role is used in extraction in $capability
1420 * @param string $capability
1421 * @param array $capabilities - array loaded using role_context_capabilities
1422 * @return int (allow, prevent, prohibit, inherit)
1423 */
1424
1425
1426function get_role_context_capability($contextid, $capability, $capabilities) {
98882637 1427 return $capabilities[$contextid][$capability];
bbbf2d40 1428}
1429
1430
1431// a big switch statement
ceb83c70 1432function get_capability_string($capabilityname) {
bbbf2d40 1433
ceb83c70 1434 // Typical capabilityname is: mod/choice:readresponses
1435
1436 $names = split('/', $capabilityname);
1437 $stringname = $names[1]; // choice:readresponses
1438 $components = split(':', $stringname);
1439 $componentname = $components[0]; // choice
98882637 1440
1441 switch ($names[0]) {
1442 case 'mod':
ceb83c70 1443 $string = get_string($stringname, $componentname);
98882637 1444 break;
1445
1446 case 'block':
ceb83c70 1447 $string = get_string($stringname, 'block_'.$componentname);
98882637 1448 break;
ceb83c70 1449
98882637 1450 case 'moodle':
ceb83c70 1451 $string = get_string($stringname, 'role');
98882637 1452 break;
1453
1454 case 'enrol':
ceb83c70 1455 $string = get_string($stringname, 'enrol_'.$componentname);
1456 break;
98882637 1457
1458 default:
ceb83c70 1459 $string = get_string($stringname);
98882637 1460 break;
98882637 1461
1462 }
1463
ceb83c70 1464 return $string;
bbbf2d40 1465}
1466
1467
1468// this gets the mod/block/course/core etc strings
1469function get_component_string($component, $contextlevel) {
1470
98882637 1471 switch ($contextlevel) {
bbbf2d40 1472
98882637 1473 case CONTEXT_SYSTEM:
ceb83c70 1474 $string = get_string('coresystem');
bbbf2d40 1475 break;
1476
1477 case CONTEXT_PERSONAL:
98882637 1478 $string = get_string('personal');
bbbf2d40 1479 break;
1480
1481 case CONTEXT_USERID:
98882637 1482 $string = get_string('users');
bbbf2d40 1483 break;
1484
1485 case CONTEXT_COURSECAT:
98882637 1486 $string = get_string('categories');
bbbf2d40 1487 break;
1488
1489 case CONTEXT_COURSE:
98882637 1490 $string = get_string('course');
bbbf2d40 1491 break;
1492
1493 case CONTEXT_GROUP:
98882637 1494 $string = get_string('group');
bbbf2d40 1495 break;
1496
1497 case CONTEXT_MODULE:
98882637 1498 $string = get_string('modulename', basename($component));
bbbf2d40 1499 break;
1500
1501 case CONTEXT_BLOCK:
98882637 1502 $string = get_string('blockname', 'block_'.$component.'.php');
bbbf2d40 1503 break;
1504
1505 default:
1506 error ('This is an unknown context!');
1507 return false;
98882637 1508
1509 }
1510
1511 return $string;
bbbf2d40 1512
1513}
ceb83c70 1514?>