/** * @package block * @subpackage demostudent * @author Dominik Royko royko@ualberta.ca */ function xmldb_block_demostudent_install() { global $DB; $result = true; $systemcontext = context_system::instance(); // Create DemoStudent role. $contextlevels = array(CONTEXT_COURSE, CONTEXT_MODULE); if (!($demostudentrole = $DB->get_record('role', array('shortname' => 'demostudent')))) { if ($roleid = create_role(get_string('roledemostudentname', 'block_demostudent'), 'demostudent', get_string('roledemostudentdescription', 'block_demostudent'), 'student')) { $newrole = new stdClass(); $newrole->id = $roleid; // Set the capabilities to the archetype (student). // Caution: new capabilities un/set here can get clobbered by 'clonepermissionsfrom', // defined in access.php. reset_role_capabilities($roleid); // DemoStudent needs to see the DemoStudent block. $result = $result && assign_capability('block/demostudent:seedemostudentblock', CAP_ALLOW, $newrole->id, $systemcontext->id); // DemoStudent should be able to see hidden courses to facilitate testing. $result = $result && assign_capability('moodle/course:viewhiddencourses', CAP_ALLOW, $newrole->id, $systemcontext->id); // DemoStudent should NOT be able to add more demostudents! $result = $result && unassign_capability('block/demostudent:addinstance', $newrole->id); $systemcontext->mark_dirty(); set_role_contextlevels($newrole->id, $contextlevels); } else { $result = false; } } return $result; }
/** * Called from cron and update_instance. Not called from add_instance as the contexts are not set up yet. */ function qcreate_student_q_access_sync($qcreate, $cmcontext = null, $course = null, $forcesync = false) { //check if a check is needed $timenow = time(); $activityopen = ($qcreate->timeopen == 0 || $qcreate->timeopen < $timenow) && ($qcreate->timeclose == 0 || $qcreate->timeclose > $timenow); $activitywasopen = ($qcreate->timeopen == 0 || $qcreate->timeopen < $qcreate->timesync) && ($qcreate->timeclose == 0 || $qcreate->timeclose > $qcreate->timesync); $needsync = empty($qcreate->timesync) || $activitywasopen != $activityopen; if ($forcesync || $needsync) { if ($cmcontext == null) { $cm = get_coursemodule_from_instance('qcreate', $qcreate->id); $cmcontext = get_context_instance(CONTEXT_MODULE, $cm->id); } if ($course == null) { $course = get_record('course', 'id', $qcreate->course); } $studentrole = get_default_course_role($course); if ($activityopen) { $capabilitiestoassign = array(0 => array('moodle/question:add' => 1, 'moodle/question:usemine' => -1, 'moodle/question:viewmine' => -1, 'moodle/question:editmine' => -1), 1 => array('moodle/question:add' => 1, 'moodle/question:usemine' => 1, 'moodle/question:viewmine' => -1, 'moodle/question:editmine' => -1), 2 => array('moodle/question:add' => 1, 'moodle/question:usemine' => 1, 'moodle/question:viewmine' => 1, 'moodle/question:editmine' => -1), 3 => array('moodle/question:add' => 1, 'moodle/question:usemine' => 1, 'moodle/question:viewmine' => 1, 'moodle/question:editmine' => 1)); foreach ($capabilitiestoassign[$qcreate->studentqaccess] as $capability => $permission) { assign_capability($capability, $permission, $studentrole->id, $cmcontext->id, true); } } else { $capabilitiestounassign = array('moodle/question:add', 'moodle/question:usemine', 'moodle/question:viewmine', 'moodle/question:editmine'); foreach ($capabilitiestounassign as $capability) { unassign_capability($capability, $studentrole->id, $cmcontext->id); } } set_field('qcreate', 'timesync', $timenow, 'id', $qcreate->id); } }
/** * Unassign a capability to $USER * * @param string $capability capability name * @param int $contextid * @param int $roleid */ public static function unassignUserCapability($capability, $contextid, $roleid) { global $USER; unassign_capability($capability, $roleid, $contextid); accesslib_clear_all_caches_for_unit_testing(); }
/** * Unassign a capability to $USER. * * @param string $capability capability name. * @param int $contextid set the context id if you used assignUserCapability. * @param int $roleid set the role id if you used assignUserCapability. * @param int $courseid set the course id if you used getDataGenerator->enrol_users. * @param string $enrol set the enrol plugin name if you used getDataGenerator->enrol_users with a different plugin than 'manual'. */ public static function unassignUserCapability($capability, $contextid = null, $roleid = null, $courseid = null, $enrol = 'manual') { global $DB; if (!empty($courseid)) { // Retrieve the role id. $instances = $DB->get_records('enrol', array('courseid' => $courseid, 'enrol' => $enrol)); if (count($instances) != 1) { throw new coding_exception('No found enrol instance for courseid: ' . $courseid . ' and enrol: ' . $enrol); } $instance = reset($instances); if (is_null($roleid) and $instance->roleid) { $roleid = $instance->roleid; } } else { if (empty($contextid) or empty($roleid)) { throw new coding_exception('unassignUserCapaibility requires contextid/roleid or courseid'); } } unassign_capability($capability, $roleid, $contextid); accesslib_clear_all_caches_for_unit_testing(); }
public function setUp() { global $DB; $this->resetAfterTest(); $this->course = self::getDataGenerator()->create_course(); $this->student1 = $this->getDataGenerator()->create_user(); $this->student2 = $this->getDataGenerator()->create_user(); $this->teacher1 = $this->getDataGenerator()->create_user(); $this->teacher2 = $this->getDataGenerator()->create_user(); $this->teacher3 = $this->getDataGenerator()->create_user(); $this->studentrole = $DB->get_record('role', array('shortname' => 'student')); $this->teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); unassign_capability('moodle/site:accessallgroups', $this->teacherrole->id); $this->getDataGenerator()->enrol_user($this->student1->id, $this->course->id, $this->studentrole->id); $this->getDataGenerator()->enrol_user($this->student2->id, $this->course->id, $this->studentrole->id); $this->getDataGenerator()->enrol_user($this->teacher1->id, $this->course->id, $this->teacherrole->id); $this->getDataGenerator()->enrol_user($this->teacher2->id, $this->course->id, $this->teacherrole->id); $this->getDataGenerator()->enrol_user($this->teacher3->id, $this->course->id, $this->teacherrole->id); // Create the forum. $record = new stdClass(); $record->introformat = FORMAT_HTML; $record->course = $this->course->id; // Set Aggregate type = Average of ratings. $record->assessed = RATING_AGGREGATE_AVERAGE; $record->scale = 100; $this->forum = self::getDataGenerator()->create_module('forum', $record); $this->contextid = context_module::instance($this->forum->cmid)->id; // Add discussion to the forums. $record = new stdClass(); $record->course = $this->course->id; $record->userid = $this->student1->id; $record->forum = $this->forum->id; $this->discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); // Retrieve the first post. $this->post = $DB->get_record('forum_posts', array('discussion' => $this->discussion->id)); }
} if (empty($errors)) { // update normal role settings $role->id = $roleid; $role->name = $name; $role->shortname = $shortname; $role->description = $description; if (!update_record('role', $role)) { error('Could not update role!'); } // set proper legacy type foreach ($legacyroles as $ltype => $lcap) { if ($ltype == $legacytype) { assign_capability($lcap, CAP_ALLOW, $roleid, $sitecontext->id); } else { unassign_capability($lcap, $roleid); } } // edited a role sitewide... mark_context_dirty($sitecontext->path); add_to_log(SITEID, 'role', 'edit', 'admin/roles/manage.php?action=edit&roleid=' . $role->id, $role->name, '', $USER->id); redirect('manage.php'); } // edited a role sitewide - with errors, but still... mark_context_dirty($sitecontext->path); } break; case 'delete': if (in_array($roleid, $defaultroles)) { error('This role is used as one of the default system roles, it can not be deleted'); }
/** * Called from the settings form. Assigns or unassigns capabilities from Group Manager role. * Assumes that this role exists, and that capabilities have numeric values 1 and 2 from form. * * @param $settingname * @return unknown_type */ function fn_sg_set_user_capability($settingname) { global $CFG; $context = get_system_context(); $role = get_record('role', 'shortname', FNGRPMANROLESNAME); if ($settingname == 's__block_fn_site_groups_users') { $capsset = explode(',', $CFG->block_fn_site_groups_users); if (in_array(1, $capsset)) { assign_capability('block/fn_site_groups:assignowngroupusers', CAP_ALLOW, $role->id, $context->id); } else { unassign_capability('block/fn_site_groups:assignowngroupusers', $role->id, $context->id); } if (in_array(2, $capsset)) { assign_capability('block/fn_site_groups:assignallusers', CAP_ALLOW, $role->id, $context->id); } else { unassign_capability('block/fn_site_groups:assignallusers', $role->id, $context->id); } } else { if ($settingname == 's__block_fn_site_groups_creategroups') { if (!empty($CFG->block_fn_site_groups_creategroups)) { assign_capability('block/fn_site_groups:createnewgroups', CAP_ALLOW, $role->id, $context->id); } else { unassign_capability('block/fn_site_groups:createnewgroups', $role->id, $context->id); } } } return true; }
function xmldb_oublog_upgrade($oldversion = 0) { global $CFG, $THEME, $db; $result = true; if ($result && $oldversion < 2008022600) { /// Define field views to be added to oublog_instances $table = new XMLDBTable('oublog_instances'); $field = new XMLDBField('views'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'accesstoken'); /// Launch add field views $result = $result && add_field($table, $field); $table = new XMLDBTable('oublog'); $field = new XMLDBField('views'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'global'); /// Launch add field views $result = $result && add_field($table, $field); } if ($result && $oldversion < 2008022700) { /// Define field oublogid to be added to oublog_links $table = new XMLDBTable('oublog_links'); $field = new XMLDBField('oublogid'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'id'); /// Launch add field oublogid $result = $result && add_field($table, $field); /// Define key oublog_links_oublog_fk (foreign) to be added to oublog_links $table = new XMLDBTable('oublog_links'); $key = new XMLDBKey('oublog_links_oublog_fk'); $key->setAttributes(XMLDB_KEY_FOREIGN, array('oublogid'), 'oublog', array('id')); /// Launch add key oublog_links_oublog_fk $result = $result && add_key($table, $key); /// Changing nullability of field oubloginstancesid on table oublog_links to null $table = new XMLDBTable('oublog_links'); $field = new XMLDBField('oubloginstancesid'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'oublogid'); /// Launch change of nullability for field oubloginstancesid $result = $result && change_field_notnull($table, $field); } if ($result && $oldversion < 2008022701) { /// Define field sortorder to be added to oublog_links $table = new XMLDBTable('oublog_links'); $field = new XMLDBField('sortorder'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'url'); /// Launch add field sortorder $result = $result && add_field($table, $field); } if ($result && $oldversion < 2008030704) { /// Add search data require_once dirname(__FILE__) . '/../locallib.php'; require_once dirname(__FILE__) . '/../lib.php'; if (oublog_search_installed()) { global $db; $olddebug = $db->debug; $db->debug = false; print '<ul>'; oublog_ousearch_update_all(true); print '</ul>'; $db->debug = $olddebug; } } if ($result && $oldversion < 2008030707) { /// Define field lasteditedby to be added to oublog_posts $table = new XMLDBTable('oublog_posts'); $field = new XMLDBField('lasteditedby'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'visibility'); /// Launch add field lasteditedby $result = $result && add_field($table, $field); /// Transfer edit data to lasteditedby $result = $result && execute_sql("\r\nUPDATE {$CFG->prefix}oublog_posts SET lasteditedby=(\r\n SELECT userid FROM {$CFG->prefix}oublog_edits WHERE {$CFG->prefix}oublog_posts.id=postid ORDER BY id DESC LIMIT 1 \r\n) WHERE editsummary IS NOT NULL\r\n "); /// Define field editsummary to be dropped from oublog_posts $table = new XMLDBTable('oublog_posts'); $field = new XMLDBField('editsummary'); /// Launch drop field editsummary $result = $result && drop_field($table, $field); } if ($result && $oldversion < 2008073000) { /// Define field completionposts to be added to oublog $table = new XMLDBTable('oublog'); $field = new XMLDBField('completionposts'); $field->setAttributes(XMLDB_TYPE_INTEGER, '9', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'views'); /// Launch add field completionposts $result = $result && add_field($table, $field); /// Define field completioncomments to be added to oublog $field = new XMLDBField('completioncomments'); $field->setAttributes(XMLDB_TYPE_INTEGER, '9', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'completionposts'); /// Launch add field completioncomments $result = $result && add_field($table, $field); } if ($result && $oldversion < 2008121100) { // remove oublog:view from legacy:user roles $roles = get_roles_with_capability('moodle/legacy:user', CAP_ALLOW); foreach ($roles as $role) { $result = $result && unassign_capability('mod/oublog:view', $role->id); } } if ($result && $oldversion < 2009012600) { // Remove oublog:post and oublog:comment from legacy:user roles (if present) $roles = get_roles_with_capability('moodle/legacy:user', CAP_ALLOW); // Also from default user role if not already included if (!array_key_exists($CFG->defaultuserroleid, $roles)) { $roles[] = get_record('role', 'id', $CFG->defaultuserroleid); } print '<p><strong>Warning</strong>: The OU blog system capabilities have changed (again) in order to fix bugs and clarify access control. The system will automatically remove the capabilities <tt>mod/oublog:view</tt>, <tt>mod/oublog:post</tt>, and <tt>mod/oublog:comment</tt> from the following role(s):</p><ul>'; foreach ($roles as $role) { print '<li>' . htmlspecialchars($role->name) . '</li>'; $result = $result && unassign_capability('mod/oublog:view', $role->id); $result = $result && unassign_capability('mod/oublog:post', $role->id); $result = $result && unassign_capability('mod/oublog:comment', $role->id); } print '</ul><p>On a default Moodle installation this is the correct behaviour. Personal blog access is now controlled via the <tt>mod/oublog:viewpersonal</tt> and <tt>mod/oublog:contributepersonal</tt> capabilities. These capabilities have been added to the authenticated user role and any equivalent roles.</p> <p>If in doubt, please examine your role configuration with regard to these <tt>mod/oublog</tt> capabilities.</p>'; } if ($result && $oldversion < 2010031200) { /// Define field completionposts to be added to oublog $table = new XMLDBTable('oublog'); $field = new XMLDBField('individual'); $field->setAttributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'completioncomments'); /// Launch add field completioncomments $result = $result && add_field($table, $field); } if ($result && $oldversion < 2010062400) { /// Define table oublog_comments_moderated to be created $table = new XMLDBTable('oublog_comments_moderated'); /// Adding fields to table oublog_comments_moderated $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('postid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('title', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('message', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('timeposted', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('authorname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('ipaddress', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('approval', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $table->addFieldInfo('timeset', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null); $table->addFieldInfo('secretkey', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table oublog_comments_moderated $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addKeyInfo('postid', XMLDB_KEY_FOREIGN, array('postid'), 'oublog_posts', array('id')); /// Adding indexes to table oublog_comments_moderated $table->addIndexInfo('ipaddress', XMLDB_INDEX_NOTUNIQUE, array('ipaddress')); /// Launch create table for oublog_comments_moderated $result = $result && create_table($table); /// Changing nullability of field userid on table oublog_comments to null $table = new XMLDBTable('oublog_comments'); $field = new XMLDBField('userid'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'postid'); /// Launch change of nullability for field userid $result = $result && change_field_notnull($table, $field); /// Define field authorname to be added to oublog_comments $field = new XMLDBField('authorname'); $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'timedeleted'); /// Launch add field authorname $result = $result && add_field($table, $field); /// Define field authorip to be added to oublog_comments $field = new XMLDBField('authorip'); $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'authorname'); /// Launch add field authorip $result = $result && add_field($table, $field); /// Define field timeapproved to be added to oublog_comments $field = new XMLDBField('timeapproved'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'authorip'); /// Launch add field timeapproved $result = $result && add_field($table, $field); } if ($result && $oldversion < 2010062500) { // Change the 'allow comments' value to 2 on global blog, if it is // currently set to 1 $result = $result && set_field('oublog', 'allowcomments', 2, 'global', 1, 'allowcomments', 1); } if ($result && $oldversion < 2010063000) { /// Define index ipaddress (not unique) to be dropped form oublog_comments_moderated $table = new XMLDBTable('oublog_comments_moderated'); $index = new XMLDBIndex('ipaddress'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('ipaddress')); /// Launch drop index authorip $result = $result && drop_index($table, $index); /// Rename field ipaddress on table oublog_comments_moderated to authorip $field = new XMLDBField('ipaddress'); $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null, 'authorname'); /// Launch rename field ipaddress $result = $result && rename_field($table, $field, 'authorip'); /// Define index authorip (not unique) to be added to oublog_comments_moderated $table = new XMLDBTable('oublog_comments_moderated'); $index = new XMLDBIndex('authorip'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('authorip')); /// Launch add index authorip $result = $result && add_index($table, $index); } if ($result && $oldversion < 2010070101) { // Make cron start working - in some servers I found there was // 9999999999 in the lastcron field which caused it never to run; not // very helpful $result = $result && set_field('modules', 'lastcron', 1, 'name', 'oublog'); } return $result; }
/** * A small functional test of accesslib functions and classes. * @return void */ public function test_everything_in_accesslib() { global $USER, $SITE, $CFG, $DB, $ACCESSLIB_PRIVATE; $this->resetAfterTest(true); $generator = $this->getDataGenerator(); // Fill the site with some real data $testcategories = array(); $testcourses = array(); $testpages = array(); $testblocks = array(); $allroles = $DB->get_records_menu('role', array(), 'id', 'archetype, id'); $systemcontext = context_system::instance(); $frontpagecontext = context_course::instance(SITEID); // Add block to system context $bi = $generator->create_block('online_users'); context_block::instance($bi->id); $testblocks[] = $bi->id; // Some users $testusers = array(); for($i=0; $i<20; $i++) { $user = $generator->create_user(); $testusers[$i] = $user->id; $usercontext = context_user::instance($user->id); // Add block to user profile $bi = $generator->create_block('online_users', array('parentcontextid'=>$usercontext->id)); $testblocks[] = $bi->id; } // Deleted user - should be ignored everywhere, can not have context $generator->create_user(array('deleted'=>1)); // Add block to frontpage $bi = $generator->create_block('online_users', array('parentcontextid'=>$frontpagecontext->id)); $frontpageblockcontext = context_block::instance($bi->id); $testblocks[] = $bi->id; // Add a resource to frontpage $page = $generator->create_module('page', array('course'=>$SITE->id)); $testpages[] = $page->id; $frontpagepagecontext = context_module::instance($page->cmid); // Add block to frontpage resource $bi = $generator->create_block('online_users', array('parentcontextid'=>$frontpagepagecontext->id)); $frontpagepageblockcontext = context_block::instance($bi->id); $testblocks[] = $bi->id; // Some nested course categories with courses $manualenrol = enrol_get_plugin('manual'); $parentcat = 0; for($i=0; $i<5; $i++) { $cat = $generator->create_category(array('parent'=>$parentcat)); $testcategories[] = $cat->id; $catcontext = context_coursecat::instance($cat->id); $parentcat = $cat->id; if ($i >=4) { continue; } // Add resource to each category $bi = $generator->create_block('online_users', array('parentcontextid'=>$catcontext->id)); context_block::instance($bi->id); // Add a few courses to each category for($j=0; $j<6; $j++) { $course = $generator->create_course(array('category'=>$cat->id)); $testcourses[] = $course->id; $coursecontext = context_course::instance($course->id); if ($j >= 5) { continue; } // Add manual enrol instance $manualenrol->add_default_instance($DB->get_record('course', array('id'=>$course->id))); // Add block to each course $bi = $generator->create_block('online_users', array('parentcontextid'=>$coursecontext->id)); $testblocks[] = $bi->id; // Add a resource to each course $page = $generator->create_module('page', array('course'=>$course->id)); $testpages[] = $page->id; $modcontext = context_module::instance($page->cmid); // Add block to each module $bi = $generator->create_block('online_users', array('parentcontextid'=>$modcontext->id)); $testblocks[] = $bi->id; } } // Make sure all contexts were created properly $count = 1; //system $count += $DB->count_records('user', array('deleted'=>0)); $count += $DB->count_records('course_categories'); $count += $DB->count_records('course'); $count += $DB->count_records('course_modules'); $count += $DB->count_records('block_instances'); $this->assertEquals($DB->count_records('context'), $count); $this->assertEquals($DB->count_records('context', array('depth'=>0)), 0); $this->assertEquals($DB->count_records('context', array('path'=>NULL)), 0); // ====== context_helper::get_level_name() ================================ $levels = context_helper::get_all_levels(); foreach ($levels as $level=>$classname) { $name = context_helper::get_level_name($level); $this->assertFalse(empty($name)); } // ======= context::instance_by_id(), context_xxx::instance(); $context = context::instance_by_id($frontpagecontext->id); $this->assertSame($context->contextlevel, CONTEXT_COURSE); $this->assertFalse(context::instance_by_id(-1, IGNORE_MISSING)); try { context::instance_by_id(-1); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } $this->assertTrue(context_system::instance() instanceof context_system); $this->assertTrue(context_coursecat::instance($testcategories[0]) instanceof context_coursecat); $this->assertTrue(context_course::instance($testcourses[0]) instanceof context_course); $this->assertTrue(context_module::instance($testpages[0]) instanceof context_module); $this->assertTrue(context_block::instance($testblocks[0]) instanceof context_block); $this->assertFalse(context_coursecat::instance(-1, IGNORE_MISSING)); $this->assertFalse(context_course::instance(-1, IGNORE_MISSING)); $this->assertFalse(context_module::instance(-1, IGNORE_MISSING)); $this->assertFalse(context_block::instance(-1, IGNORE_MISSING)); try { context_coursecat::instance(-1); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } try { context_course::instance(-1); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } try { context_module::instance(-1); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } try { context_block::instance(-1); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } // ======= $context->get_url(), $context->get_context_name(), $context->get_capabilities() ========= $testcontexts = array(); $testcontexts[CONTEXT_SYSTEM] = context_system::instance(); $testcontexts[CONTEXT_COURSECAT] = context_coursecat::instance($testcategories[0]); $testcontexts[CONTEXT_COURSE] = context_course::instance($testcourses[0]); $testcontexts[CONTEXT_MODULE] = context_module::instance($testpages[0]); $testcontexts[CONTEXT_BLOCK] = context_block::instance($testblocks[0]); foreach ($testcontexts as $context) { $name = $context->get_context_name(true, true); $this->assertFalse(empty($name)); $this->assertTrue($context->get_url() instanceof moodle_url); $caps = $context->get_capabilities(); $this->assertTrue(is_array($caps)); foreach ($caps as $cap) { $cap = (array)$cap; $this->assertSame(array_keys($cap), array('id', 'name', 'captype', 'contextlevel', 'component', 'riskbitmask')); } } unset($testcontexts); // ===== $context->get_course_context() ========================================= $this->assertFalse($systemcontext->get_course_context(false)); try { $systemcontext->get_course_context(); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } $context = context_coursecat::instance($testcategories[0]); $this->assertFalse($context->get_course_context(false)); try { $context->get_course_context(); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } $this->assertSame($frontpagecontext->get_course_context(true), $frontpagecontext); $this->assertSame($frontpagepagecontext->get_course_context(true), $frontpagecontext); $this->assertSame($frontpagepageblockcontext->get_course_context(true), $frontpagecontext); // ======= $context->get_parent_context(), $context->get_parent_contexts(), $context->get_parent_context_ids() ======= $userid = reset($testusers); $usercontext = context_user::instance($userid); $this->assertSame($usercontext->get_parent_context(), $systemcontext); $this->assertSame($usercontext->get_parent_contexts(), array($systemcontext->id=>$systemcontext)); $this->assertSame($usercontext->get_parent_contexts(true), array($usercontext->id=>$usercontext, $systemcontext->id=>$systemcontext)); $this->assertSame($systemcontext->get_parent_contexts(), array()); $this->assertSame($systemcontext->get_parent_contexts(true), array($systemcontext->id=>$systemcontext)); $this->assertSame($systemcontext->get_parent_context_ids(), array()); $this->assertSame($systemcontext->get_parent_context_ids(true), array($systemcontext->id)); $this->assertSame($frontpagecontext->get_parent_context(), $systemcontext); $this->assertSame($frontpagecontext->get_parent_contexts(), array($systemcontext->id=>$systemcontext)); $this->assertSame($frontpagecontext->get_parent_contexts(true), array($frontpagecontext->id=>$frontpagecontext, $systemcontext->id=>$systemcontext)); $this->assertSame($frontpagecontext->get_parent_context_ids(), array($systemcontext->id)); $this->assertEquals($frontpagecontext->get_parent_context_ids(true), array($frontpagecontext->id, $systemcontext->id)); $this->assertSame($systemcontext->get_parent_context(), false); $frontpagecontext = context_course::instance($SITE->id); $parent = $systemcontext; foreach ($testcategories as $catid) { $catcontext = context_coursecat::instance($catid); $this->assertSame($catcontext->get_parent_context(), $parent); $parent = $catcontext; } $this->assertSame($frontpagepagecontext->get_parent_context(), $frontpagecontext); $this->assertSame($frontpageblockcontext->get_parent_context(), $frontpagecontext); $this->assertSame($frontpagepageblockcontext->get_parent_context(), $frontpagepagecontext); // ====== $context->get_child_contexts() ================================ $CFG->debug = 0; $children = $systemcontext->get_child_contexts(); $CFG->debug = DEBUG_DEVELOPER; $this->assertEquals(count($children)+1, $DB->count_records('context')); $context = context_coursecat::instance($testcategories[3]); $children = $context->get_child_contexts(); $countcats = 0; $countcourses = 0; $countblocks = 0; foreach ($children as $child) { if ($child->contextlevel == CONTEXT_COURSECAT) { $countcats++; } if ($child->contextlevel == CONTEXT_COURSE) { $countcourses++; } if ($child->contextlevel == CONTEXT_BLOCK) { $countblocks++; } } $this->assertEquals(count($children), 8); $this->assertEquals($countcats, 1); $this->assertEquals($countcourses, 6); $this->assertEquals($countblocks, 1); $context = context_course::instance($testcourses[2]); $children = $context->get_child_contexts(); $this->assertEquals(count($children), 7); // depends on number of default blocks $context = context_module::instance($testpages[3]); $children = $context->get_child_contexts(); $this->assertEquals(count($children), 1); $context = context_block::instance($testblocks[1]); $children = $context->get_child_contexts(); $this->assertEquals(count($children), 0); unset($children); unset($countcats); unset($countcourses); unset($countblocks); // ======= context_helper::reset_caches() ============================ context_helper::reset_caches(); $this->assertEquals(context_inspection::test_context_cache_size(), 0); context_course::instance($SITE->id); $this->assertEquals(context_inspection::test_context_cache_size(), 1); // ======= context preloading ======================================== context_helper::reset_caches(); $sql = "SELECT ".context_helper::get_preload_record_columns_sql('c')." FROM {context} c WHERE c.contextlevel <> ".CONTEXT_SYSTEM; $records = $DB->get_records_sql($sql); $firstrecord = reset($records); $columns = context_helper::get_preload_record_columns('c'); $firstrecord = (array)$firstrecord; $this->assertSame(array_keys($firstrecord), array_values($columns)); context_helper::reset_caches(); foreach ($records as $record) { context_helper::preload_from_record($record); $this->assertEquals($record, new stdClass()); } $this->assertEquals(context_inspection::test_context_cache_size(), count($records)); unset($records); unset($columns); context_helper::reset_caches(); context_helper::preload_course($SITE->id); $this->assertEquals(7, context_inspection::test_context_cache_size()); // depends on number of default blocks // ====== assign_capability(), unassign_capability() ==================== $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); $this->assertFalse($rc); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext->id); $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); $this->assertEquals($rc->permission, CAP_ALLOW); assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext->id); $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); $this->assertEquals($rc->permission, CAP_ALLOW); assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext, true); $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); $this->assertEquals($rc->permission, CAP_PREVENT); assign_capability('moodle/site:accessallgroups', CAP_INHERIT, $allroles['teacher'], $frontpagecontext); $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); $this->assertFalse($rc); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext); unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext, true); $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); $this->assertFalse($rc); unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext->id, true); unset($rc); accesslib_clear_all_caches(false); // must be done after assign_capability() // ======= role_assign(), role_unassign(), role_unassign_all() ============== $context = context_course::instance($testcourses[1]); $this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 0); role_assign($allroles['teacher'], $testusers[1], $context->id); role_assign($allroles['teacher'], $testusers[2], $context->id); role_assign($allroles['manager'], $testusers[1], $context->id); $this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 3); role_unassign($allroles['teacher'], $testusers[1], $context->id); $this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 2); role_unassign_all(array('contextid'=>$context->id)); $this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 0); unset($context); accesslib_clear_all_caches(false); // just in case // ====== has_capability(), get_users_by_capability(), role_switch(), reload_all_capabilities() and friends ======================== $adminid = get_admin()->id; $guestid = $CFG->siteguest; // Enrol some users into some courses $course1 = $DB->get_record('course', array('id'=>$testcourses[22]), '*', MUST_EXIST); $course2 = $DB->get_record('course', array('id'=>$testcourses[7]), '*', MUST_EXIST); $cms = $DB->get_records('course_modules', array('course'=>$course1->id), 'id'); $cm1 = reset($cms); $blocks = $DB->get_records('block_instances', array('parentcontextid'=>context_module::instance($cm1->id)->id), 'id'); $block1 = reset($blocks); $instance1 = $DB->get_record('enrol', array('enrol'=>'manual', 'courseid'=>$course1->id)); $instance2 = $DB->get_record('enrol', array('enrol'=>'manual', 'courseid'=>$course2->id)); for($i=0; $i<9; $i++) { $manualenrol->enrol_user($instance1, $testusers[$i], $allroles['student']); } $manualenrol->enrol_user($instance1, $testusers[8], $allroles['teacher']); $manualenrol->enrol_user($instance1, $testusers[9], $allroles['editingteacher']); for($i=10; $i<15; $i++) { $manualenrol->enrol_user($instance2, $testusers[$i], $allroles['student']); } $manualenrol->enrol_user($instance2, $testusers[15], $allroles['editingteacher']); // Add tons of role assignments - the more the better role_assign($allroles['coursecreator'], $testusers[11], context_coursecat::instance($testcategories[2])); role_assign($allroles['manager'], $testusers[12], context_coursecat::instance($testcategories[1])); role_assign($allroles['student'], $testusers[9], context_module::instance($cm1->id)); role_assign($allroles['teacher'], $testusers[8], context_module::instance($cm1->id)); role_assign($allroles['guest'], $testusers[13], context_course::instance($course1->id)); role_assign($allroles['teacher'], $testusers[7], context_block::instance($block1->id)); role_assign($allroles['manager'], $testusers[9], context_block::instance($block1->id)); role_assign($allroles['editingteacher'], $testusers[9], context_course::instance($course1->id)); role_assign($allroles['teacher'], $adminid, context_course::instance($course1->id)); role_assign($allroles['editingteacher'], $adminid, context_block::instance($block1->id)); // Add tons of overrides - the more the better assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpageblockcontext, true); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpageblockcontext, true); assign_capability('moodle/block:view', CAP_PROHIBIT, $allroles['guest'], $frontpageblockcontext, true); assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['user'], $frontpageblockcontext, true); assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['student'], $frontpageblockcontext, true); assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $CFG->defaultuserroleid, $frontpagepagecontext, true); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagepagecontext, true); assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $frontpagepagecontext, true); assign_capability('mod/page:view', CAP_ALLOW, $allroles['user'], $frontpagepagecontext, true); assign_capability('moodle/page:view', CAP_ALLOW, $allroles['student'], $frontpagepagecontext, true); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpagecontext, true); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagecontext, true); assign_capability('mod/page:view', CAP_ALLOW, $allroles['guest'], $frontpagecontext, true); assign_capability('mod/page:view', CAP_PROHIBIT, $allroles['user'], $frontpagecontext, true); assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $systemcontext, true); accesslib_clear_all_caches(false); // must be done after assign_capability() // Extra tests for guests and not-logged-in users because they can not be verified by cross checking // with get_users_by_capability() where they are ignored $this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, $guestid)); $this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, $guestid)); $this->assertTrue(has_capability('mod/page:view', $frontpagecontext, $guestid)); $this->assertFalse(has_capability('mod/page:view', $systemcontext, $guestid)); $this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, 0)); $this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, 0)); $this->assertTrue(has_capability('mod/page:view', $frontpagecontext, 0)); $this->assertFalse(has_capability('mod/page:view', $systemcontext, 0)); $this->assertFalse(has_capability('moodle/course:create', $systemcontext, $testusers[11])); $this->assertTrue(has_capability('moodle/course:create', context_coursecat::instance($testcategories[2]), $testusers[11])); $this->assertFalse(has_capability('moodle/course:create', context_course::instance($testcourses[1]), $testusers[11])); $this->assertTrue(has_capability('moodle/course:create', context_course::instance($testcourses[19]), $testusers[11])); $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[1]), $testusers[9])); $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[19]), $testusers[9])); $this->assertFalse(has_capability('moodle/course:update', $systemcontext, $testusers[9])); // Test the list of enrolled users $coursecontext = context_course::instance($course1->id); $enrolled = get_enrolled_users($coursecontext); $this->assertEquals(count($enrolled), 10); for($i=0; $i<10; $i++) { $this->assertTrue(isset($enrolled[$testusers[$i]])); } $enrolled = get_enrolled_users($coursecontext, 'moodle/course:update'); $this->assertEquals(count($enrolled), 1); $this->assertTrue(isset($enrolled[$testusers[9]])); unset($enrolled); // role switching $userid = $testusers[9]; $USER = $DB->get_record('user', array('id'=>$userid)); load_all_capabilities(); $coursecontext = context_course::instance($course1->id); $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); $this->assertFalse(is_role_switched($course1->id)); role_switch($allroles['student'], $coursecontext); $this->assertTrue(is_role_switched($course1->id)); $this->assertEquals($USER->access['rsw'][$coursecontext->path], $allroles['student']); $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); reload_all_capabilities(); $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); role_switch(0, $coursecontext); $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); $userid = $adminid; $USER = $DB->get_record('user', array('id'=>$userid)); load_all_capabilities(); $coursecontext = context_course::instance($course1->id); $blockcontext = context_block::instance($block1->id); $this->assertTrue(has_capability('moodle/course:update', $blockcontext)); role_switch($allroles['student'], $coursecontext); $this->assertEquals($USER->access['rsw'][$coursecontext->path], $allroles['student']); $this->assertFalse(has_capability('moodle/course:update', $blockcontext)); reload_all_capabilities(); $this->assertFalse(has_capability('moodle/course:update', $blockcontext)); load_all_capabilities(); $this->assertTrue(has_capability('moodle/course:update', $blockcontext)); // temp course role for enrol $DB->delete_records('cache_flags', array()); // this prevents problem with dirty contexts immediately resetting the temp role - this is a known problem... $userid = $testusers[5]; $roleid = $allroles['editingteacher']; $USER = $DB->get_record('user', array('id'=>$userid)); load_all_capabilities(); $coursecontext = context_course::instance($course1->id); $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); $this->assertFalse(isset($USER->access['ra'][$coursecontext->path][$roleid])); load_temp_course_role($coursecontext, $roleid); $this->assertEquals($USER->access['ra'][$coursecontext->path][$roleid], $roleid); $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); remove_temp_course_roles($coursecontext); $this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid)); load_temp_course_role($coursecontext, $roleid); reload_all_capabilities(); $this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid)); $USER = new stdClass(); $USER->id = 0; // Now cross check has_capability() with get_users_by_capability(), each using different code paths, // they have to be kept in sync, usually only one of them breaks, so we know when something is wrong, // at the same time validate extra restrictions (guest read only no risks, admin exception, non existent and deleted users) $contexts = $DB->get_records('context', array(), 'id'); $contexts = array_values($contexts); $capabilities = $DB->get_records('capabilities', array(), 'id'); $capabilities = array_values($capabilities); $roles = array($allroles['guest'], $allroles['user'], $allroles['teacher'], $allroles['editingteacher'], $allroles['coursecreator'], $allroles['manager']); $userids = array_values($testusers); $userids[] = get_admin()->id; if (!PHPUNIT_LONGTEST) { $contexts = array_slice($contexts, 0, 10); $capabilities = array_slice($capabilities, 0, 5); $userids = array_slice($userids, 0, 5); } // Random time! //srand(666); foreach($userids as $userid) { // no guest or deleted // each user gets 0-10 random roles $rcount = rand(0, 10); for($j=0; $j<$rcount; $j++) { $roleid = $roles[rand(0, count($roles)-1)]; $contextid = $contexts[rand(0, count($contexts)-1)]->id; role_assign($roleid, $userid, $contextid); } } $permissions = array(CAP_ALLOW, CAP_PREVENT, CAP_INHERIT, CAP_PREVENT); $maxoverrides = count($contexts)*10; for($j=0; $j<$maxoverrides; $j++) { $roleid = $roles[rand(0, count($roles)-1)]; $contextid = $contexts[rand(0, count($contexts)-1)]->id; $permission = $permissions[rand(0,count($permissions)-1)]; $capname = $capabilities[rand(0, count($capabilities)-1)]->name; assign_capability($capname, $permission, $roleid, $contextid, true); } unset($permissions); unset($roles); accesslib_clear_all_caches(false); // must be done after assign_capability() // Test time - let's set up some real user, just in case the logic for USER affects the others... $USER = $DB->get_record('user', array('id'=>$testusers[3])); load_all_capabilities(); $userids[] = $CFG->siteguest; $userids[] = 0; // not-logged-in user $userids[] = -1; // non-existent user foreach ($contexts as $crecord) { $context = context::instance_by_id($crecord->id); if ($coursecontext = $context->get_course_context(false)) { $enrolled = get_enrolled_users($context); } else { $enrolled = array(); } foreach ($capabilities as $cap) { $allowed = get_users_by_capability($context, $cap->name, 'u.id, u.username'); if ($enrolled) { $enrolledwithcap = get_enrolled_users($context, $cap->name); } else { $enrolledwithcap = array(); } foreach ($userids as $userid) { if ($userid == 0 or isguestuser($userid)) { if ($userid == 0) { $CFG->forcelogin = true; $this->assertFalse(has_capability($cap->name, $context, $userid)); unset($CFG->forcelogin); } if (($cap->captype === 'write') or ($cap->riskbitmask & (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))) { $this->assertFalse(has_capability($cap->name, $context, $userid)); } $this->assertFalse(isset($allowed[$userid])); } else { if (is_siteadmin($userid)) { $this->assertTrue(has_capability($cap->name, $context, $userid, true)); } $hascap = has_capability($cap->name, $context, $userid, false); $this->assertSame($hascap, isset($allowed[$userid]), "Capability result mismatch user:$userid, context:$context->id, $cap->name, hascap: ".(int)$hascap." "); if (isset($enrolled[$userid])) { $this->assertSame(isset($allowed[$userid]), isset($enrolledwithcap[$userid]), "Enrolment with capability result mismatch user:$userid, context:$context->id, $cap->name, hascap: ".(int)$hascap." "); } } } } } // Back to nobody $USER = new stdClass(); $USER->id = 0; unset($contexts); unset($userids); unset($capabilities); // Now let's do all the remaining tests that break our carefully prepared fake site // ======= $context->mark_dirty() ======================================= $DB->delete_records('cache_flags', array()); accesslib_clear_all_caches(false); $systemcontext->mark_dirty(); $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); $this->assertTrue(isset($dirty[$systemcontext->path])); $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$systemcontext->path])); // ======= $context->reload_if_dirty(); ================================= $DB->delete_records('cache_flags', array()); accesslib_clear_all_caches(false); load_all_capabilities(); $context = context_course::instance($testcourses[2]); $page = $DB->get_record('page', array('course'=>$testcourses[2])); $pagecontext = context_module::instance($page->id); $context->mark_dirty(); $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path])); $USER->access['test'] = true; $context->reload_if_dirty(); $this->assertFalse(isset($USER->access['test'])); $context->mark_dirty(); $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path])); $USER->access['test'] = true; $pagecontext->reload_if_dirty(); $this->assertFalse(isset($USER->access['test'])); // ======= context_helper::build_all_paths() ============================ $oldcontexts = $DB->get_records('context', array(), 'id'); $DB->set_field_select('context', 'path', NULL, "contextlevel <> ".CONTEXT_SYSTEM); $DB->set_field_select('context', 'depth', 0, "contextlevel <> ".CONTEXT_SYSTEM); context_helper::build_all_paths(); $newcontexts = $DB->get_records('context', array(), 'id'); $this->assertEquals($oldcontexts, $newcontexts); unset($oldcontexts); unset($newcontexts); // ======= $context->reset_paths() ====================================== $context = context_course::instance($testcourses[2]); $children = $context->get_child_contexts(); $context->reset_paths(false); $this->assertSame($DB->get_field('context', 'path', array('id'=>$context->id)), NULL); $this->assertEquals($DB->get_field('context', 'depth', array('id'=>$context->id)), 0); foreach ($children as $child) { $this->assertSame($DB->get_field('context', 'path', array('id'=>$child->id)), NULL); $this->assertEquals($DB->get_field('context', 'depth', array('id'=>$child->id)), 0); } $this->assertEquals(count($children)+1, $DB->count_records('context', array('depth'=>0))); $this->assertEquals(count($children)+1, $DB->count_records('context', array('path'=>NULL))); $context = context_course::instance($testcourses[2]); $context->reset_paths(true); $context = context_course::instance($testcourses[2]); $this->assertEquals($DB->get_field('context', 'path', array('id'=>$context->id)), $context->path); $this->assertEquals($DB->get_field('context', 'depth', array('id'=>$context->id)), $context->depth); $this->assertEquals(0, $DB->count_records('context', array('depth'=>0))); $this->assertEquals(0, $DB->count_records('context', array('path'=>NULL))); // ====== $context->update_moved(); ====================================== accesslib_clear_all_caches(false); $DB->delete_records('cache_flags', array()); $course = $DB->get_record('course', array('id'=>$testcourses[0])); $context = context_course::instance($course->id); $oldpath = $context->path; $miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}"); $categorycontext = context_coursecat::instance($miscid); $course->category = $miscid; $DB->update_record('course', $course); $context->update_moved($categorycontext); $context = context_course::instance($course->id); $this->assertEquals($context->get_parent_context(), $categorycontext); $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); $this->assertTrue(isset($dirty[$oldpath])); $this->assertTrue(isset($dirty[$context->path])); // ====== $context->delete_content() ===================================== context_helper::reset_caches(); $context = context_module::instance($testpages[3]); $this->assertTrue($DB->record_exists('context', array('id'=>$context->id))); $this->assertEquals(1, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); $context->delete_content(); $this->assertTrue($DB->record_exists('context', array('id'=>$context->id))); $this->assertEquals(0, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); // ====== $context->delete() ============================= context_helper::reset_caches(); $context = context_module::instance($testpages[4]); $this->assertTrue($DB->record_exists('context', array('id'=>$context->id))); $this->assertEquals(1, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); $bi = $DB->get_record('block_instances', array('parentcontextid'=>$context->id)); $bicontext = context_block::instance($bi->id); $DB->delete_records('cache_flags', array()); $context->delete(); // should delete also linked blocks $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); $this->assertTrue(isset($dirty[$context->path])); $this->assertFalse($DB->record_exists('context', array('id'=>$context->id))); $this->assertFalse($DB->record_exists('context', array('id'=>$bicontext->id))); $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_MODULE, 'instanceid'=>$testpages[4]))); $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_BLOCK, 'instanceid'=>$bi->id))); $this->assertEquals(0, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); context_module::instance($testpages[4]); // ====== context_helper::delete_instance() ============================= context_helper::reset_caches(); $lastcourse = array_pop($testcourses); $this->assertTrue($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$lastcourse))); $coursecontext = context_course::instance($lastcourse); $this->assertEquals(context_inspection::test_context_cache_size(), 1); $this->assertFalse($coursecontext->instanceid == CONTEXT_COURSE); $DB->delete_records('cache_flags', array()); context_helper::delete_instance(CONTEXT_COURSE, $lastcourse); $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); $this->assertTrue(isset($dirty[$coursecontext->path])); $this->assertEquals(context_inspection::test_context_cache_size(), 0); $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$lastcourse))); context_course::instance($lastcourse); // ======= context_helper::create_instances() ========================== $prevcount = $DB->count_records('context'); $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK)); context_helper::create_instances(null, true); $this->assertSame($DB->count_records('context'), $prevcount); $this->assertEquals($DB->count_records('context', array('depth'=>0)), 0); $this->assertEquals($DB->count_records('context', array('path'=>NULL)), 0); $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK)); $DB->delete_records('block_instances', array()); $prevcount = $DB->count_records('context'); $DB->delete_records_select('context', 'contextlevel <> '.CONTEXT_SYSTEM); context_helper::create_instances(null, true); $this->assertSame($DB->count_records('context'), $prevcount); $this->assertEquals($DB->count_records('context', array('depth'=>0)), 0); $this->assertEquals($DB->count_records('context', array('path'=>NULL)), 0); // ======= context_helper::cleanup_instances() ========================== $lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}"); $DB->delete_records('course', array('id'=>$lastcourse)); $lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}"); $DB->delete_records('course_categories', array('id'=>$lastcategory)); $lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0"); $DB->delete_records('user', array('id'=>$lastuser)); $DB->delete_records('block_instances', array('parentcontextid'=>$frontpagepagecontext->id)); $DB->delete_records('course_modules', array('id'=>$frontpagepagecontext->instanceid)); context_helper::cleanup_instances(); $count = 1; //system $count += $DB->count_records('user', array('deleted'=>0)); $count += $DB->count_records('course_categories'); $count += $DB->count_records('course'); $count += $DB->count_records('course_modules'); $count += $DB->count_records('block_instances'); $this->assertEquals($DB->count_records('context'), $count); // ======= context cache size restrictions ============================== $testusers= array(); for ($i=0; $i<CONTEXT_CACHE_MAX_SIZE + 100; $i++) { $user = $generator->create_user(); $testusers[$i] = $user->id; } context_helper::create_instances(null, true); context_helper::reset_caches(); for ($i=0; $i<CONTEXT_CACHE_MAX_SIZE + 100; $i++) { context_user::instance($testusers[$i]); if ($i == CONTEXT_CACHE_MAX_SIZE - 1) { $this->assertEquals(context_inspection::test_context_cache_size(), CONTEXT_CACHE_MAX_SIZE); } else if ($i == CONTEXT_CACHE_MAX_SIZE) { // once the limit is reached roughly 1/3 of records should be removed from cache $this->assertEquals(context_inspection::test_context_cache_size(), (int)(CONTEXT_CACHE_MAX_SIZE * (2/3) +102)); } } // We keep the first 100 cached $prevsize = context_inspection::test_context_cache_size(); for ($i=0; $i<100; $i++) { context_user::instance($testusers[$i]); $this->assertEquals(context_inspection::test_context_cache_size(), $prevsize); } context_user::instance($testusers[102]); $this->assertEquals(context_inspection::test_context_cache_size(), $prevsize+1); unset($testusers); // ================================================================= // ======= basic test of legacy functions ========================== // ================================================================= // note: watch out, the fake site might be pretty borked already $this->assertSame(get_system_context(), context_system::instance()); foreach ($DB->get_records('context') as $contextid=>$record) { $context = context::instance_by_id($contextid); $this->assertSame(get_context_instance_by_id($contextid), $context); $this->assertSame(get_context_instance($record->contextlevel, $record->instanceid), $context); $this->assertSame(get_parent_contexts($context), $context->get_parent_context_ids()); if ($context->id == SYSCONTEXTID) { $this->assertSame(get_parent_contextid($context), false); } else { $this->assertSame(get_parent_contextid($context), $context->get_parent_context()->id); } } $CFG->debug = 0; $children = get_child_contexts($systemcontext); $CFG->debug = DEBUG_DEVELOPER; $this->assertEquals(count($children), $DB->count_records('context')-1); unset($children); $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK)); create_contexts(); $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_BLOCK))); $DB->set_field('context', 'depth', 0, array('contextlevel'=>CONTEXT_BLOCK)); build_context_path(); $this->assertFalse($DB->record_exists('context', array('depth'=>0))); $lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}"); $DB->delete_records('course', array('id'=>$lastcourse)); $lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}"); $DB->delete_records('course_categories', array('id'=>$lastcategory)); $lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0"); $DB->delete_records('user', array('id'=>$lastuser)); $DB->delete_records('block_instances', array('parentcontextid'=>$frontpagepagecontext->id)); $DB->delete_records('course_modules', array('id'=>$frontpagepagecontext->instanceid)); cleanup_contexts(); $count = 1; //system $count += $DB->count_records('user', array('deleted'=>0)); $count += $DB->count_records('course_categories'); $count += $DB->count_records('course'); $count += $DB->count_records('course_modules'); $count += $DB->count_records('block_instances'); $this->assertEquals($DB->count_records('context'), $count); context_helper::reset_caches(); preload_course_contexts($SITE->id); $this->assertEquals(context_inspection::test_context_cache_size(), 1); context_helper::reset_caches(); list($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSECAT, 'ctx'); $sql = "SELECT c.id $select FROM {course_categories} c $join"; $records = $DB->get_records_sql($sql); foreach ($records as $record) { context_instance_preload($record); $record = (array)$record; $this->assertEquals(1, count($record)); // only id left } $this->assertEquals(count($records), context_inspection::test_context_cache_size()); accesslib_clear_all_caches(true); $DB->delete_records('cache_flags', array()); mark_context_dirty($systemcontext->path); $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); $this->assertTrue(isset($dirty[$systemcontext->path])); accesslib_clear_all_caches(false); $DB->delete_records('cache_flags', array()); $course = $DB->get_record('course', array('id'=>$testcourses[2])); $context = get_context_instance(CONTEXT_COURSE, $course->id); $oldpath = $context->path; $miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}"); $categorycontext = context_coursecat::instance($miscid); $course->category = $miscid; $DB->update_record('course', $course); context_moved($context, $categorycontext); $context = get_context_instance(CONTEXT_COURSE, $course->id); $this->assertEquals($context->get_parent_context(), $categorycontext); $this->assertTrue($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$testcourses[2]))); delete_context(CONTEXT_COURSE, $testcourses[2]); $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$testcourses[2]))); $name = get_contextlevel_name(CONTEXT_COURSE); $this->assertFalse(empty($name)); $context = get_context_instance(CONTEXT_COURSE, $testcourses[2]); $name = print_context_name($context); $this->assertFalse(empty($name)); $url = get_context_url($coursecontext); $this->assertFalse($url instanceof modole_url); $page = $DB->get_record('page', array('id'=>$testpages[7])); $context = get_context_instance(CONTEXT_MODULE, $page->id); $coursecontext = get_course_context($context); $this->assertEquals($coursecontext->contextlevel, CONTEXT_COURSE); $this->assertEquals(get_courseid_from_context($context), $page->course); $caps = fetch_context_capabilities($systemcontext); $this->assertTrue(is_array($caps)); unset($caps); }
/** * Deletes cached capabilities that are no longer needed by the component. * Also unassigns these capabilities from any roles that have them. * @param $component - examples: 'moodle', 'mod/forum', 'block/quiz_results' * @param $newcapdef - array of the new capability definitions that will be * compared with the cached capabilities * @return int - number of deprecated capabilities that have been removed */ function capabilities_cleanup($component, $newcapdef = NULL) { global $DB; $removedcount = 0; if ($cachedcaps = get_cached_capabilities($component)) { foreach ($cachedcaps as $cachedcap) { if (empty($newcapdef) || array_key_exists($cachedcap->name, $newcapdef) === false) { // Remove from capabilities cache. if (!$DB->delete_records('capabilities', array('name' => $cachedcap->name))) { print_error('cannotdeletecap', '', '', $cachedcap->name); } else { $removedcount++; } // Delete from roles. if ($roles = get_roles_with_capability($cachedcap->name)) { foreach ($roles as $role) { if (!unassign_capability($cachedcap->name, $role->id)) { print_error('cannotunassigncap', 'error', '', (object) array('cap' => $cachedcap->name, 'role' => $role->name)); } } } } // End if. } } return $removedcount; }
/** * Test workshop::check_group_membership() functionality. */ public function test_check_group_membership() { global $DB, $CFG; $this->resetAfterTest(); $courseid = $this->course->id; $generator = $this->getDataGenerator(); // Make test groups. $group1 = $generator->create_group(array('courseid' => $courseid)); $group2 = $generator->create_group(array('courseid' => $courseid)); $group3 = $generator->create_group(array('courseid' => $courseid)); // Revoke the accessallgroups from non-editing teachers (tutors). $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); unassign_capability('moodle/site:accessallgroups', $roleids['teacher']); // Create test use accounts. $teacher1 = $generator->create_user(); $tutor1 = $generator->create_user(); $tutor2 = $generator->create_user(); $student1 = $generator->create_user(); $student2 = $generator->create_user(); $student3 = $generator->create_user(); // Enrol the teacher (has the access all groups permission). $generator->enrol_user($teacher1->id, $courseid, $roleids['editingteacher']); // Enrol tutors (can not access all groups). $generator->enrol_user($tutor1->id, $courseid, $roleids['teacher']); $generator->enrol_user($tutor2->id, $courseid, $roleids['teacher']); // Enrol students. $generator->enrol_user($student1->id, $courseid, $roleids['student']); $generator->enrol_user($student2->id, $courseid, $roleids['student']); $generator->enrol_user($student3->id, $courseid, $roleids['student']); // Add users in groups. groups_add_member($group1, $tutor1); groups_add_member($group2, $tutor2); groups_add_member($group1, $student1); groups_add_member($group2, $student2); groups_add_member($group3, $student3); // Workshop with no groups. $workshopitem1 = $this->getDataGenerator()->create_module('workshop', ['course' => $courseid, 'groupmode' => NOGROUPS]); $cm = get_coursemodule_from_instance('workshop', $workshopitem1->id, $courseid, false, MUST_EXIST); $workshop1 = new testable_workshop($workshopitem1, $cm, $this->course); $this->setUser($teacher1); $this->assertTrue($workshop1->check_group_membership($student1->id)); $this->assertTrue($workshop1->check_group_membership($student2->id)); $this->assertTrue($workshop1->check_group_membership($student3->id)); $this->setUser($tutor1); $this->assertTrue($workshop1->check_group_membership($student1->id)); $this->assertTrue($workshop1->check_group_membership($student2->id)); $this->assertTrue($workshop1->check_group_membership($student3->id)); // Workshop in visible groups mode. $workshopitem2 = $this->getDataGenerator()->create_module('workshop', ['course' => $courseid, 'groupmode' => VISIBLEGROUPS]); $cm = get_coursemodule_from_instance('workshop', $workshopitem2->id, $courseid, false, MUST_EXIST); $workshop2 = new testable_workshop($workshopitem2, $cm, $this->course); $this->setUser($teacher1); $this->assertTrue($workshop2->check_group_membership($student1->id)); $this->assertTrue($workshop2->check_group_membership($student2->id)); $this->assertTrue($workshop2->check_group_membership($student3->id)); $this->setUser($tutor1); $this->assertTrue($workshop2->check_group_membership($student1->id)); $this->assertTrue($workshop2->check_group_membership($student2->id)); $this->assertTrue($workshop2->check_group_membership($student3->id)); // Workshop in separate groups mode. $workshopitem3 = $this->getDataGenerator()->create_module('workshop', ['course' => $courseid, 'groupmode' => SEPARATEGROUPS]); $cm = get_coursemodule_from_instance('workshop', $workshopitem3->id, $courseid, false, MUST_EXIST); $workshop3 = new testable_workshop($workshopitem3, $cm, $this->course); $this->setUser($teacher1); $this->assertTrue($workshop3->check_group_membership($student1->id)); $this->assertTrue($workshop3->check_group_membership($student2->id)); $this->assertTrue($workshop3->check_group_membership($student3->id)); $this->setUser($tutor1); $this->assertTrue($workshop3->check_group_membership($student1->id)); $this->assertFalse($workshop3->check_group_membership($student2->id)); $this->assertFalse($workshop3->check_group_membership($student3->id)); $this->setUser($tutor2); $this->assertFalse($workshop3->check_group_membership($student1->id)); $this->assertTrue($workshop3->check_group_membership($student2->id)); $this->assertFalse($workshop3->check_group_membership($student3->id)); }
public function test_remove_competency_from_template() { $syscontext = context_system::instance(); $this->setUser($this->creator); $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); // Create a template. $template = $this->create_template(1, true); // Create a competency. $framework = $lpg->create_framework(); $competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); // Add the competency. external::add_competency_to_template($template->id, $competency->get_id()); // Check that it was added. $this->assertEquals(1, external::count_competencies_in_template($template->id)); // Check that we can remove the competency. external::remove_competency_from_template($template->id, $competency->get_id()); // Check that it was removed. $this->assertEquals(0, external::count_competencies_in_template($template->id)); // Unassign capability. unassign_capability('moodle/competency:templatemanage', $this->creatorrole, $syscontext->id); accesslib_clear_all_caches_for_unit_testing(); // Check we can not remove the competency now. try { external::add_competency_to_template($template->id, $competency->get_id()); $this->fail('Exception expected due to not permissions to manage template competencies'); } catch (moodle_exception $e) { $this->assertEquals('nopermissions', $e->errorcode); } }
/** * Setup function- we will create a course and add an assign instance to it. */ protected function setUp() { global $DB; $this->resetAfterTest(true); // Create some users. $creator = $this->getDataGenerator()->create_user(); $user = $this->getDataGenerator()->create_user(); $catuser = $this->getDataGenerator()->create_user(); $catcreator = $this->getDataGenerator()->create_user(); $category = $this->getDataGenerator()->create_category(); $othercategory = $this->getDataGenerator()->create_category(); $syscontext = context_system::instance(); $catcontext = context_coursecat::instance($category->id); // Fetching default authenticated user role. $userroles = get_archetype_roles('user'); $this->assertCount(1, $userroles); $authrole = array_pop($userroles); // Reset all default authenticated users permissions. unassign_capability('moodle/competency:competencygrade', $authrole->id); unassign_capability('moodle/competency:competencymanage', $authrole->id); unassign_capability('moodle/competency:competencyview', $authrole->id); unassign_capability('moodle/competency:planmanage', $authrole->id); unassign_capability('moodle/competency:planmanagedraft', $authrole->id); unassign_capability('moodle/competency:planmanageown', $authrole->id); unassign_capability('moodle/competency:planview', $authrole->id); unassign_capability('moodle/competency:planviewdraft', $authrole->id); unassign_capability('moodle/competency:planviewown', $authrole->id); unassign_capability('moodle/competency:planviewowndraft', $authrole->id); unassign_capability('moodle/competency:templatemanage', $authrole->id); unassign_capability('moodle/competency:templateview', $authrole->id); unassign_capability('moodle/cohort:manage', $authrole->id); unassign_capability('moodle/competency:coursecompetencyconfigure', $authrole->id); // Creating specific roles. $this->creatorrole = create_role('Creator role', 'lpcreatorrole', 'learning plan creator role description'); $this->userrole = create_role('User role', 'lpuserrole', 'learning plan user role description'); assign_capability('moodle/competency:competencymanage', CAP_ALLOW, $this->creatorrole, $syscontext->id); assign_capability('moodle/competency:competencycompetencyconfigure', CAP_ALLOW, $this->creatorrole, $syscontext->id); assign_capability('moodle/competency:planmanage', CAP_ALLOW, $this->creatorrole, $syscontext->id); assign_capability('moodle/competency:planmanagedraft', CAP_ALLOW, $this->creatorrole, $syscontext->id); assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->creatorrole, $syscontext->id); assign_capability('moodle/competency:planview', CAP_ALLOW, $this->creatorrole, $syscontext->id); assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $this->creatorrole, $syscontext->id); assign_capability('moodle/competency:templatemanage', CAP_ALLOW, $this->creatorrole, $syscontext->id); assign_capability('moodle/competency:competencygrade', CAP_ALLOW, $this->creatorrole, $syscontext->id); assign_capability('moodle/cohort:manage', CAP_ALLOW, $this->creatorrole, $syscontext->id); assign_capability('moodle/competency:competencyview', CAP_ALLOW, $this->userrole, $syscontext->id); assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontext->id); assign_capability('moodle/competency:planviewown', CAP_ALLOW, $this->userrole, $syscontext->id); assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $this->userrole, $syscontext->id); role_assign($this->creatorrole, $creator->id, $syscontext->id); role_assign($this->creatorrole, $catcreator->id, $catcontext->id); role_assign($this->userrole, $user->id, $syscontext->id); role_assign($this->userrole, $catuser->id, $catcontext->id); $this->creator = $creator; $this->catcreator = $catcreator; $this->user = $user; $this->catuser = $catuser; $this->category = $category; $this->othercategory = $othercategory; accesslib_clear_all_caches_for_unit_testing(); }
/** * Test get_item_ratings */ public function test_get_item_ratings() { global $DB, $USER; $this->resetAfterTest(true); $course = self::getDataGenerator()->create_course(); $student = $this->getDataGenerator()->create_user(); $teacher1 = $this->getDataGenerator()->create_user(); $teacher2 = $this->getDataGenerator()->create_user(); $teacher3 = $this->getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname' => 'student')); $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); unassign_capability('moodle/site:accessallgroups', $teacherrole->id); $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($teacher1->id, $course->id, $teacherrole->id); $this->getDataGenerator()->enrol_user($teacher2->id, $course->id, $teacherrole->id); $this->getDataGenerator()->enrol_user($teacher3->id, $course->id, $teacherrole->id); // Create the forum. $record = new stdClass(); $record->introformat = FORMAT_HTML; $record->course = $course->id; // Set Aggregate type = Average of ratings. $record->assessed = RATING_AGGREGATE_AVERAGE; $forum = self::getDataGenerator()->create_module('forum', $record); $contextid = context_module::instance($forum->cmid)->id; // Add discussion to the forums. $record = new stdClass(); $record->course = $course->id; $record->userid = $student->id; $record->forum = $forum->id; $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); // Retrieve the first post. $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id)); // Rete the discussion as teacher1. $rating1 = new stdClass(); $rating1->contextid = $contextid; $rating1->component = 'mod_forum'; $rating1->ratingarea = 'post'; $rating1->itemid = $post->id; $rating1->rating = 90; $rating1->scaleid = 100; $rating1->userid = $teacher1->id; $rating1->timecreated = time(); $rating1->timemodified = time(); $rating1->id = $DB->insert_record('rating', $rating1); // Rete the discussion as teacher2. $rating2 = new stdClass(); $rating2->contextid = $contextid; $rating2->component = 'mod_forum'; $rating2->ratingarea = 'post'; $rating2->itemid = $post->id; $rating2->rating = 95; $rating2->scaleid = 100; $rating2->userid = $teacher2->id; $rating2->timecreated = time() + 1; $rating2->timemodified = time() + 1; $rating2->id = $DB->insert_record('rating', $rating2); // Delete teacher2, we must still receive the ratings. delete_user($teacher2); // Teachers can see all the ratings. $this->setUser($teacher1); $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'post', $post->id, 100, ''); // We need to execute the return values cleaning process to simulate the web service server. $ratings = external_api::clean_returnvalue(core_rating_external::get_item_ratings_returns(), $ratings); $this->assertCount(2, $ratings['ratings']); $indexedratings = array(); foreach ($ratings['ratings'] as $rating) { $indexedratings[$rating['id']] = $rating; } $this->assertEquals($rating1->rating . ' / ' . $rating1->scaleid, $indexedratings[$rating1->id]['rating']); $this->assertEquals($rating2->rating . ' / ' . $rating2->scaleid, $indexedratings[$rating2->id]['rating']); $this->assertEquals($rating1->userid, $indexedratings[$rating1->id]['userid']); $this->assertEquals($rating2->userid, $indexedratings[$rating2->id]['userid']); // Student can see ratings. $this->setUser($student); $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'post', $post->id, 100, ''); // We need to execute the return values cleaning process to simulate the web service server. $ratings = external_api::clean_returnvalue(core_rating_external::get_item_ratings_returns(), $ratings); $this->assertCount(2, $ratings['ratings']); // Invalid item. try { $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'post', 0, 100, ''); $this->fail('Exception expected due invalid itemid.'); } catch (moodle_exception $e) { $this->assertEquals('invalidrecord', $e->errorcode); } // Invalid area. try { $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'xyz', $post->id, 100, ''); $this->fail('Exception expected due invalid rating area.'); } catch (moodle_exception $e) { $this->assertEquals('invalidratingarea', $e->errorcode); } // Invalid context. invalid_parameter_exception. try { $ratings = core_rating_external::get_item_ratings('module', 0, 'mod_forum', 'post', $post->id, 100, ''); $this->fail('Exception expected due invalid context.'); } catch (invalid_parameter_exception $e) { $this->assertEquals('invalidparameter', $e->errorcode); } // Test for groupmode. set_coursemodule_groupmode($forum->cmid, SEPARATEGROUPS); $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); groups_add_member($group, $teacher1); $discussion->groupid = $group->id; $DB->update_record('forum_discussions', $discussion); // Error for teacher3 and 2 ratings for teacher1 should be returned. $this->setUser($teacher1); $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'post', $post->id, 100, ''); // We need to execute the return values cleaning process to simulate the web service server. $ratings = external_api::clean_returnvalue(core_rating_external::get_item_ratings_returns(), $ratings); $this->assertCount(2, $ratings['ratings']); $this->setUser($teacher3); try { $ratings = core_rating_external::get_item_ratings('module', $forum->cmid, 'mod_forum', 'post', $post->id, 100, ''); $this->fail('Exception expected due invalid group permissions.'); } catch (moodle_exception $e) { $this->assertEquals('noviewrate', $e->errorcode); } }
/** * Revokes the capability assignment. */ public function revoke() { foreach ($this->capability as $capability) { unassign_capability($capability, $this->roleid, $this->contextid); } accesslib_clear_all_caches_for_unit_testing(); }
/** * Deletes cached capabilities that are no longer needed by the component. * Also unassigns these capabilities from any roles that have them. * @param $component - examples: 'moodle', 'mod/forum', 'block/quiz_results' * @param $newcapdef - array of the new capability definitions that will be * compared with the cached capabilities * @return int - number of deprecated capabilities that have been removed */ function capabilities_cleanup($component, $newcapdef = NULL) { $removedcount = 0; if ($cachedcaps = get_cached_capabilities($component)) { foreach ($cachedcaps as $cachedcap) { if (empty($newcapdef) || array_key_exists($cachedcap->name, $newcapdef) === false) { // Remove from capabilities cache. if (!delete_records('capabilities', 'name', $cachedcap->name)) { error('Could not delete deprecated capability ' . $cachedcap->name); } else { $removedcount++; } // Delete from roles. if ($roles = get_roles_with_capability($cachedcap->name)) { foreach ($roles as $role) { if (!unassign_capability($cachedcap->name, $role->id)) { error('Could not unassign deprecated capability ' . $cachedcap->name . ' from role ' . $role->name); } } } } // End if. } } return $removedcount; }
public function test_reorder_template_competencies_permissions() { $this->resetAfterTest(true); $dg = $this->getDataGenerator(); $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); $cat = $dg->create_category(); $catcontext = context_coursecat::instance($cat->id); $syscontext = context_system::instance(); $user = $dg->create_user(); $role = $dg->create_role(); assign_capability('moodle/competency:templatemanage', CAP_ALLOW, $role, $syscontext->id, true); $dg->role_assign($role, $user->id, $syscontext->id); // Create a template. $template = $lpg->create_template(array('contextid' => $catcontext->id)); // Create a competency framework. $framework = $lpg->create_framework(array('contextid' => $catcontext->id)); // Create competencies. $competency1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); $competency2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); // Add the competencies. $lpg->create_template_competency(array('templateid' => $template->get_id(), 'competencyid' => $competency1->get_id())); $lpg->create_template_competency(array('templateid' => $template->get_id(), 'competencyid' => $competency2->get_id())); $this->setUser($user); // Can reorder competencies with system context permissions in category context. $result = api::reorder_template_competency($template->get_id(), $competency2->get_id(), $competency1->get_id()); $this->assertTrue($result); unassign_capability('moodle/competency:templatemanage', $role, $syscontext->id); accesslib_clear_all_caches_for_unit_testing(); try { api::reorder_template_competency($template->get_id(), $competency2->get_id(), $competency1->get_id()); $this->fail('Exception expected due to not permissions to manage template competencies'); } catch (required_capability_exception $e) { $this->assertEquals('nopermissions', $e->errorcode); } // Giving permissions in category context. assign_capability('moodle/competency:templatemanage', CAP_ALLOW, $role, $catcontext->id, true); $dg->role_assign($role, $user->id, $catcontext->id); // User with templatemanage capability in category context can reorder competencies in temple. $result = api::reorder_template_competency($template->get_id(), $competency1->get_id(), $competency2->get_id()); $this->assertTrue($result); // Removing templatemanage capability in category context. unassign_capability('moodle/competency:templatemanage', $role, $catcontext->id); accesslib_clear_all_caches_for_unit_testing(); try { api::reorder_template_competency($template->get_id(), $competency2->get_id(), $competency1->get_id()); $this->fail('Exception expected due to not permissions to manage template competencies'); } catch (required_capability_exception $e) { $this->assertEquals('nopermissions', $e->errorcode); } }
/** * When called resets all custom roles as per definition set down in /local/roles.php * * Note that this uses the non-core role.custom field to isolate roles to remove. * * Utilise the $path parameter to allow for localisation (i.e. different roles defintion than core). * * Sort order is reset based on the order listed in the defintion. * * WARNING: as long as you retain the same shortname existing user role assigments will * be retained. if you change the shortname they will be lost. * * KNOWN ISSUE: we rely on shortname being unique, but this is not enforced by the db. * this is more a problem with moodle. * * @param text $path * */ function tao_reset_custom_roles($path = 'local') { global $CFG; if (!get_site()) { // not finished installing, skip return true; } // get latest role definition from roles file $rolespath = $CFG->dirroot . '/' . $path . '/roles.php'; if (!file_exists($rolespath)) { debugging("Local caps reassignment called with invalid path {$path}"); return false; } require_once $rolespath; if (!isset($customroles)) { return true; // nothing to do. } $undeletableroles = array(); $undeletableroles[$CFG->notloggedinroleid] = 1; $undeletableroles[$CFG->guestroleid] = 1; $undeletableroles[$CFG->defaultuserroleid] = 1; $undeletableroles[$CFG->defaultcourseroleid] = 1; // If there is only one admin role, add that to $undeletableroles too. $adminroles = get_admin_roles(); if (count($adminroles) == 1) { $undeletableroles[reset($adminroles)->id] = 1; } // get recordset of existing custom roles $sql = "SELECT id, name, shortname, description, sortorder, custom\n FROM {$CFG->prefix}role\n WHERE custom IS NOT NULL"; $roles = get_records_sql($sql); // remove custom roles that are not in the latest definition foreach ($roles as $role) { // check whether this role is in the latest definition if (array_key_exists($role->shortname, $customroles)) { continue; } // extra safety: check undeletable roles if (isset($undeletableroles[$role->id])) { continue; } delete_role($role->id); } // hack to avoid sortorder unique constraint execute_sql("UPDATE {$CFG->prefix}role SET sortorder = (sortorder+1000) WHERE custom IS NOT NULL"); // set sortorder to current highest value $sortorder = get_field_sql("SELECT " . sql_max('sortorder') . " FROM {$CFG->prefix}role WHERE custom IS NULL"); // now loop through the new settings foreach ($customroles as $shortname => $role) { $sortorder++; // get the roleid $roleid = get_field('role', 'id', 'shortname', $shortname); // if exists then make updates if (!empty($roleid)) { // only update fields that have been set if (isset($role['name'])) { set_field('role', 'name', $role['name'], 'shortname', $shortname); } if (isset($role['description'])) { set_field('role', 'description', $role['description'], 'shortname', $shortname); } // reset sortorder set_field('role', 'sortorder', $sortorder, 'shortname', $shortname); // else create record } else { $newrole = new stdclass(); $newrole->name = $role['name']; $newrole->shortname = $shortname; $newrole->description = $role['description']; $newrole->sortorder = $sortorder; $newrole->custom = 1; $roleid = insert_record('role', $newrole); } // remove any previously set legacy roles $legacyroles = get_legacy_roles(); foreach ($legacyroles as $ltype => $lcap) { unassign_capability($lcap, $roleid); } // reset legacy role if (isset($role['legacy'])) { $legacycap = $legacyroles[$role['legacy']]; $context = get_context_instance(CONTEXT_SYSTEM); assign_capability($legacycap, CAP_ALLOW, $roleid, $context->id); } // update the context settings set_role_contextlevels($roleid, $role['context']); // e.g. array(CONTEXT_SYSTEM, CONTEXT_COURSECAT) // set allow assigns if (is_array($role['canassign'])) { // delete existing delete_records('role_allow_assign', 'allowassign', $roleid); foreach ($role['canassign'] as $canassign) { $canassignid = get_field('role', 'id', 'shortname', $canassign); allow_assign($canassignid, $roleid); } } } // reset custom capabilities to keep up with changes return tao_reset_capabilities(); }
public function test_get_notified_users() { global $CFG, $DB; $capability = 'mod/assign:receivegradernotifications'; $coursecontext = context_course::instance($this->course->id); $role = $DB->get_record('role', array('shortname' => 'teacher')); $this->create_extra_users(); $this->setUser($this->editingteachers[0]); // Create an assignment with no groups. $assign = $this->create_instance(); $this->assertCount(self::DEFAULT_TEACHER_COUNT + self::DEFAULT_EDITING_TEACHER_COUNT + self::EXTRA_TEACHER_COUNT + self::EXTRA_EDITING_TEACHER_COUNT, $assign->testable_get_notifiable_users($this->students[0]->id)); // Change nonediting teachers role to not receive grader notifications. assign_capability($capability, CAP_PROHIBIT, $role->id, $coursecontext); $this->assertCount(self::DEFAULT_EDITING_TEACHER_COUNT + self::EXTRA_EDITING_TEACHER_COUNT, $assign->testable_get_notifiable_users($this->students[0]->id)); // Reset nonediting teachers role to default. unassign_capability($capability, $role->id, $coursecontext); // Force create an assignment with SEPARATEGROUPS. $data = new stdClass(); $data->courseid = $this->course->id; $data->name = 'Grouping'; $groupingid = groups_create_grouping($data); groups_assign_grouping($groupingid, $this->groups[0]->id); $assign = $this->create_instance(array('groupingid' => $groupingid, 'groupmode' => SEPARATEGROUPS)); $this->setUser($this->students[1]); $this->assertCount(4, $assign->testable_get_notifiable_users($this->students[0]->id)); // Note the second student is in a group that is not in the grouping. // This means that we get all graders that are not in a group in the grouping. $this->assertCount(10, $assign->testable_get_notifiable_users($this->students[1]->id)); // Change nonediting teachers role to not receive grader notifications. assign_capability($capability, CAP_PROHIBIT, $role->id, $coursecontext); $this->assertCount(2, $assign->testable_get_notifiable_users($this->students[0]->id)); // Note the second student is in a group that is not in the grouping. // This means that we get all graders that are not in a group in the grouping. $this->assertCount(5, $assign->testable_get_notifiable_users($this->students[1]->id)); }
/** * Tests the user can't post a message without proper capability. */ public function test_can_post_message_without_cap() { global $DB; // Create some users. $user1 = self::getDataGenerator()->create_user(); $user2 = self::getDataGenerator()->create_user(); // Set as the user 1. $this->setUser($user1); // Remove the capability to send a message. $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); unassign_capability('moodle/site:sendmessage', $roleids['user'], context_system::instance()); // Check that we can not post a message without the capability. $this->assertFalse(\core_message\api::can_post_message($user2)); }
/** * Tests for mod_forum_rating_can_see_item_ratings(). * * @throws coding_exception * @throws rating_exception */ public function test_mod_forum_rating_can_see_item_ratings() { global $DB; $this->resetAfterTest(); // Setup test data. $course = new stdClass(); $course->groupmode = SEPARATEGROUPS; $course->groupmodeforce = true; $course = $this->getDataGenerator()->create_course($course); $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); $generator = self::getDataGenerator()->get_plugin_generator('mod_forum'); $cm = get_coursemodule_from_instance('forum', $forum->id); $context = context_module::instance($cm->id); // Create users. $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $user3 = $this->getDataGenerator()->create_user(); $user4 = $this->getDataGenerator()->create_user(); // Groups and stuff. $role = $DB->get_record('role', array('shortname' => 'teacher'), '*', MUST_EXIST); $this->getDataGenerator()->enrol_user($user1->id, $course->id, $role->id); $this->getDataGenerator()->enrol_user($user2->id, $course->id, $role->id); $this->getDataGenerator()->enrol_user($user3->id, $course->id, $role->id); $this->getDataGenerator()->enrol_user($user4->id, $course->id, $role->id); $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); groups_add_member($group1, $user1); groups_add_member($group1, $user2); groups_add_member($group2, $user3); groups_add_member($group2, $user4); $record = new stdClass(); $record->course = $forum->course; $record->forum = $forum->id; $record->userid = $user1->id; $record->groupid = $group1->id; $discussion = $generator->create_discussion($record); // Retrieve the first post. $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id)); $ratingoptions = new stdClass(); $ratingoptions->context = $context; $ratingoptions->ratingarea = 'post'; $ratingoptions->component = 'mod_forum'; $ratingoptions->itemid = $post->id; $ratingoptions->scaleid = 2; $ratingoptions->userid = $user2->id; $rating = new rating($ratingoptions); $rating->update_rating(2); // Now try to access it as various users. unassign_capability('moodle/site:accessallgroups', $role->id); $params = array('contextid' => 2, 'component' => 'mod_forum', 'ratingarea' => 'post', 'itemid' => $post->id, 'scaleid' => 2); $this->setUser($user1); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user2); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user3); $this->assertFalse(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user4); $this->assertFalse(mod_forum_rating_can_see_item_ratings($params)); // Now try with accessallgroups cap and make sure everything is visible. assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $role->id, $context->id); $this->setUser($user1); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user2); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user3); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user4); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); // Change group mode and verify visibility. $course->groupmode = VISIBLEGROUPS; $DB->update_record('course', $course); unassign_capability('moodle/site:accessallgroups', $role->id); $this->setUser($user1); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user2); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user3); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user4); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); }
/** * A small functional test of accesslib functions and classes. */ public function test_everything_in_accesslib() { global $USER, $SITE, $CFG, $DB, $ACCESSLIB_PRIVATE; // First of all finalize the session, we must not carry over any of this mess to the next page via SESSION!!! session_get_instance()->write_close(); // hack - this is going to take very long time set_time_limit(3600); // Get rid of current user that would not work anyway, // do NOT even think about using $this->switch_global_user_id()! if (!isset($this->accesslibprevuser)) { $this->accesslibprevuser = clone $USER; $USER = new stdClass(); $USER->id = 0; } // Backup $SITE global if (!isset($this->accesslibprevsite)) { $this->accesslibprevsite = $SITE; } // Switch DB, if it somehow fails or you specified wrong unittest prefix it will nuke real data, you have been warned! $this->switch_to_test_db(); // Let's switch the CFG $prevcfg = clone $CFG; $this->switch_to_test_cfg(); $CFG->config_php_settings = $prevcfg->config_php_settings; $CFG->noemailever = true; $CFG->admin = $prevcfg->admin; $CFG->lang = 'en'; $CFG->tempdir = $prevcfg->tempdir; $CFG->cachedir = $prevcfg->cachedir; $CFG->directorypermissions = $prevcfg->directorypermissions; $CFG->filepermissions = $prevcfg->filepermissions; // Reset all caches accesslib_clear_all_caches_for_unit_testing(); // Add some core tables - this is known to break constantly because we keep adding dependencies... $tablenames = array('config', 'config_plugins', 'modules', 'course', 'course_modules', 'course_sections', 'course_categories', 'mnet_host', 'mnet_application', 'capabilities', 'context', 'context_temp', 'role', 'role_capabilities', 'role_allow_switch', 'license', 'my_pages', 'block', 'block_instances', 'block_positions', 'role_allow_assign', 'role_allow_override', 'role_assignments', 'role_context_levels', 'enrol', 'user_enrolments', 'filter_active', 'filter_config', 'comments', 'user', 'groups_members', 'cache_flags', 'events_handlers', 'user_lastaccess', 'rating', 'files', 'role_names', 'user_preferences'); $this->create_test_tables($tablenames, 'lib'); // Create all core default records and default settings require_once "{$CFG->libdir}/db/install.php"; xmldb_main_install(); // installs the capabilities too // Fake mod_page install $tablenames = array('page'); $this->create_test_tables($tablenames, 'mod/page'); $module = new stdClass(); require $CFG->dirroot . '/mod/page/version.php'; $module->name = 'page'; $pagemoduleid = $DB->insert_record('modules', $module); update_capabilities('mod_page'); // Fake block_online_users install $plugin = new stdClass(); $plugin->version = NULL; $plugin->cron = 0; include $CFG->dirroot . '/blocks/online_users/version.php'; $plugin->name = 'online_users'; $onlineusersblockid = $DB->insert_record('block', $plugin); update_capabilities('block_online_users'); // Finish roles setup set_config('defaultfrontpageroleid', $DB->get_field('role', 'id', array('archetype' => 'frontpage'))); set_config('defaultuserroleid', $DB->get_field('role', 'id', array('archetype' => 'user'))); set_config('notloggedinroleid', $DB->get_field('role', 'id', array('archetype' => 'guest'))); set_config('rolesactive', 1); // Init manual enrol set_config('status', ENROL_INSTANCE_ENABLED, 'enrol_manual'); set_config('defaultperiod', 0, 'enrol_manual'); $manualenrol = enrol_get_plugin('manual'); // Fill the site with some real data $testcategories = array(); $testcourses = array(); $testpages = array(); $testblocks = array(); $allroles = $DB->get_records_menu('role', array(), 'id', 'archetype, id'); $systemcontext = context_system::instance(); $frontpagecontext = context_course::instance(SITEID); // Add block to system context $bi = new stdClass(); $bi->blockname = 'online_users'; $bi->parentcontextid = $systemcontext->id; $bi->showinsubcontexts = 1; $bi->pagetypepattern = ''; $bi->subpagepattern = ''; $bi->defaultregion = ''; $bi->defaultweight = 0; $bi->configdata = ''; $biid = $DB->insert_record('block_instances', $bi); context_block::instance($biid); $testblocks[] = $biid; // Some users $testusers = array(); for ($i = 0; $i < 20; $i++) { $user = new stdClass(); $user->auth = 'manual'; $user->firstname = 'user' . $i; $user->lastname = 'user' . $i; $user->username = '******' . $i; $user->password = '******'; $user->email = "user{$i}@example.com"; $user->confirmed = 1; $user->mnethostid = $CFG->mnet_localhost_id; $user->lang = $CFG->lang; $user->maildisplay = 1; $user->timemodified = time(); $user->deleted = 0; $user->lastip = '0.0.0.0'; $userid = $DB->insert_record('user', $user); $testusers[$i] = $userid; $usercontext = context_user::instance($userid); // Add block to user profile $bi->parentcontextid = $usercontext->id; $biid = $DB->insert_record('block_instances', $bi); context_block::instance($biid); $testblocks[] = $biid; } // Deleted user - should be ignored everywhere, can not have context $user = new stdClass(); $user->auth = 'manual'; $user->firstname = ''; $user->lastname = ''; $user->username = '******'; $user->password = ''; $user->email = ''; $user->confirmed = 1; $user->mnethostid = $CFG->mnet_localhost_id; $user->lang = $CFG->lang; $user->maildisplay = 1; $user->timemodified = time(); $user->deleted = 1; $user->lastip = '0.0.0.0'; $DB->insert_record('user', $user); unset($user); // Add block to frontpage $bi->parentcontextid = $frontpagecontext->id; $biid = $DB->insert_record('block_instances', $bi); $frontpageblockcontext = context_block::instance($biid); $testblocks[] = $biid; // Add a resource to frontpage $page = new stdClass(); $page->course = $SITE->id; $page->intro = '...'; $page->introformat = FORMAT_HTML; $page->content = '...'; $page->contentformat = FORMAT_HTML; $pageid = $DB->insert_record('page', $page); $testpages[] = $pageid; $cm = new stdClass(); $cm->course = $SITE->id; $cm->module = $pagemoduleid; $cm->section = 1; $cm->instance = $pageid; $cmid = $DB->insert_record('course_modules', $cm); $frontpagepagecontext = context_module::instance($cmid); // Add block to frontpage resource $bi->parentcontextid = $frontpagepagecontext->id; $biid = $DB->insert_record('block_instances', $bi); $frontpagepageblockcontext = context_block::instance($biid); $testblocks[] = $biid; // Some nested course categories with courses require_once "{$CFG->dirroot}/course/lib.php"; $path = ''; $parentcat = 0; for ($i = 0; $i < 5; $i++) { $cat = new stdClass(); $cat->name = 'category' . $i; $cat->parent = $parentcat; $cat->depth = $i + 1; $cat->sortorder = MAX_COURSES_IN_CATEGORY * ($i + 2); $cat->timemodified = time(); $catid = $DB->insert_record('course_categories', $cat); $path = $path . '/' . $catid; $DB->set_field('course_categories', 'path', $path, array('id' => $catid)); $parentcat = $catid; $testcategories[] = $catid; $catcontext = context_coursecat::instance($catid); if ($i >= 4) { continue; } // Add resource to each category $bi->parentcontextid = $catcontext->id; $biid = $DB->insert_record('block_instances', $bi); context_block::instance($biid); // Add a few courses to each category for ($j = 0; $j < 6; $j++) { $course = new stdClass(); $course->fullname = 'course' . $j; $course->shortname = 'c' . $j; $course->summary = 'bah bah bah'; $course->newsitems = 0; $course->numsections = 1; $course->category = $catid; $course->format = 'topics'; $course->timecreated = time(); $course->visible = 1; $course->timemodified = $course->timecreated; $courseid = $DB->insert_record('course', $course); $section = new stdClass(); $section->course = $courseid; $section->section = 0; $section->summaryformat = FORMAT_HTML; $DB->insert_record('course_sections', $section); $section->section = 1; $DB->insert_record('course_sections', $section); $testcourses[] = $courseid; $coursecontext = context_course::instance($courseid); if ($j >= 5) { continue; } // Add manual enrol instance $manualenrol->add_default_instance($DB->get_record('course', array('id' => $courseid))); // Add block to each course $bi->parentcontextid = $coursecontext->id; $biid = $DB->insert_record('block_instances', $bi); context_block::instance($biid); $testblocks[] = $biid; // Add a resource to each course $page->course = $courseid; $pageid = $DB->insert_record('page', $page); $testpages[] = $pageid; $cm->course = $courseid; $cm->instance = $pageid; $cm->id = $DB->insert_record('course_modules', $cm); $modcontext = context_module::instance($cm->id); // Add block to each module $bi->parentcontextid = $modcontext->id; $biid = $DB->insert_record('block_instances', $bi); context_block::instance($biid); $testblocks[] = $biid; } } // Make sure all contexts were created properly $count = 1; //system $count += $DB->count_records('user', array('deleted' => 0)); $count += $DB->count_records('course_categories'); $count += $DB->count_records('course'); $count += $DB->count_records('course_modules'); $count += $DB->count_records('block_instances'); $this->assertEqual($DB->count_records('context'), $count); $this->assertEqual($DB->count_records('context', array('depth' => 0)), 0); $this->assertEqual($DB->count_records('context', array('path' => NULL)), 0); // ====== context_helper::get_level_name() ================================ $levels = context_helper::get_all_levels(); foreach ($levels as $level => $classname) { $name = context_helper::get_level_name($level); $this->assertFalse(empty($name)); } // ======= context::instance_by_id(), context_xxx::instance(); $context = context::instance_by_id($frontpagecontext->id); $this->assertidentical($context->contextlevel, CONTEXT_COURSE); $this->assertFalse(context::instance_by_id(-1, IGNORE_MISSING)); try { context::instance_by_id(-1); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } $this->assertTrue(context_system::instance() instanceof context_system); $this->assertTrue(context_coursecat::instance($testcategories[0]) instanceof context_coursecat); $this->assertTrue(context_course::instance($testcourses[0]) instanceof context_course); $this->assertTrue(context_module::instance($testpages[0]) instanceof context_module); $this->assertTrue(context_block::instance($testblocks[0]) instanceof context_block); $this->assertFalse(context_coursecat::instance(-1, IGNORE_MISSING)); $this->assertFalse(context_course::instance(-1, IGNORE_MISSING)); $this->assertFalse(context_module::instance(-1, IGNORE_MISSING)); $this->assertFalse(context_block::instance(-1, IGNORE_MISSING)); try { context_coursecat::instance(-1); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } try { context_course::instance(-1); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } try { context_module::instance(-1); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } try { context_block::instance(-1); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } // ======= $context->get_url(), $context->get_context_name(), $context->get_capabilities() ========= $testcontexts = array(); $testcontexts[CONTEXT_SYSTEM] = context_system::instance(); $testcontexts[CONTEXT_COURSECAT] = context_coursecat::instance($testcategories[0]); $testcontexts[CONTEXT_COURSE] = context_course::instance($testcourses[0]); $testcontexts[CONTEXT_MODULE] = context_module::instance($testpages[0]); $testcontexts[CONTEXT_BLOCK] = context_block::instance($testblocks[0]); foreach ($testcontexts as $context) { $name = $context->get_context_name(true, true); $this->assertFalse(empty($name)); $this->assertTrue($context->get_url() instanceof moodle_url); $caps = $context->get_capabilities(); $this->assertTrue(is_array($caps)); foreach ($caps as $cap) { $cap = (array) $cap; $this->assertIdentical(array_keys($cap), array('id', 'name', 'captype', 'contextlevel', 'component', 'riskbitmask')); } } unset($testcontexts); // ===== $context->get_course_context() ========================================= $this->assertFalse($systemcontext->get_course_context(false)); try { $systemcontext->get_course_context(); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } $context = context_coursecat::instance($testcategories[0]); $this->assertFalse($context->get_course_context(false)); try { $context->get_course_context(); $this->fail('exception expected'); } catch (Exception $e) { $this->assertTrue(true); } $this->assertIdentical($frontpagecontext->get_course_context(true), $frontpagecontext); $this->assertIdentical($frontpagepagecontext->get_course_context(true), $frontpagecontext); $this->assertIdentical($frontpagepageblockcontext->get_course_context(true), $frontpagecontext); // ======= $context->get_parent_context(), $context->get_parent_contexts(), $context->get_parent_context_ids() ======= $userid = reset($testusers); $usercontext = context_user::instance($userid); $this->assertIdentical($usercontext->get_parent_context(), $systemcontext); $this->assertIdentical($usercontext->get_parent_contexts(), array($systemcontext->id => $systemcontext)); $this->assertIdentical($usercontext->get_parent_contexts(true), array($usercontext->id => $usercontext, $systemcontext->id => $systemcontext)); $this->assertIdentical($systemcontext->get_parent_contexts(), array()); $this->assertIdentical($systemcontext->get_parent_contexts(true), array($systemcontext->id => $systemcontext)); $this->assertIdentical($systemcontext->get_parent_context_ids(), array()); $this->assertIdentical($systemcontext->get_parent_context_ids(true), array($systemcontext->id)); $this->assertIdentical($frontpagecontext->get_parent_context(), $systemcontext); $this->assertIdentical($frontpagecontext->get_parent_contexts(), array($systemcontext->id => $systemcontext)); $this->assertIdentical($frontpagecontext->get_parent_contexts(true), array($frontpagecontext->id => $frontpagecontext, $systemcontext->id => $systemcontext)); $this->assertIdentical($frontpagecontext->get_parent_context_ids(), array($systemcontext->id)); $this->assertEqual($frontpagecontext->get_parent_context_ids(true), array($frontpagecontext->id, $systemcontext->id)); $this->assertIdentical($systemcontext->get_parent_context(), false); $frontpagecontext = context_course::instance($SITE->id); $parent = $systemcontext; foreach ($testcategories as $catid) { $catcontext = context_coursecat::instance($catid); $this->assertIdentical($catcontext->get_parent_context(), $parent); $parent = $catcontext; } $this->assertIdentical($frontpagepagecontext->get_parent_context(), $frontpagecontext); $this->assertIdentical($frontpageblockcontext->get_parent_context(), $frontpagecontext); $this->assertIdentical($frontpagepageblockcontext->get_parent_context(), $frontpagepagecontext); // ====== $context->get_child_contexts() ================================ $children = $systemcontext->get_child_contexts(); $this->assertEqual(count($children) + 1, $DB->count_records('context')); $context = context_coursecat::instance($testcategories[3]); $children = $context->get_child_contexts(); $countcats = 0; $countcourses = 0; $countblocks = 0; foreach ($children as $child) { if ($child->contextlevel == CONTEXT_COURSECAT) { $countcats++; } if ($child->contextlevel == CONTEXT_COURSE) { $countcourses++; } if ($child->contextlevel == CONTEXT_BLOCK) { $countblocks++; } } $this->assertEqual(count($children), 8); $this->assertEqual($countcats, 1); $this->assertEqual($countcourses, 6); $this->assertEqual($countblocks, 1); $context = context_course::instance($testcourses[2]); $children = $context->get_child_contexts(); $this->assertEqual(count($children), 3); $context = context_module::instance($testpages[3]); $children = $context->get_child_contexts(); $this->assertEqual(count($children), 1); $context = context_block::instance($testblocks[1]); $children = $context->get_child_contexts(); $this->assertEqual(count($children), 0); unset($children); unset($countcats); unset($countcourses); unset($countblocks); // ======= context_helper::reset_caches() ============================ context_helper::reset_caches(); $this->assertEqual(context_inspection::test_context_cache_size(), 0); context_course::instance($SITE->id); $this->assertEqual(context_inspection::test_context_cache_size(), 1); // ======= context preloading ======================================== context_helper::reset_caches(); $sql = "SELECT " . context_helper::get_preload_record_columns_sql('c') . "\n FROM {context} c\n WHERE c.contextlevel <> " . CONTEXT_SYSTEM; $records = $DB->get_records_sql($sql); $firstrecord = reset($records); $columns = context_helper::get_preload_record_columns('c'); $firstrecord = (array) $firstrecord; $this->assertIdentical(array_keys($firstrecord), array_values($columns)); context_helper::reset_caches(); foreach ($records as $record) { context_helper::preload_from_record($record); $this->assertIdentical($record, new stdClass()); } $this->assertEqual(context_inspection::test_context_cache_size(), count($records)); unset($records); unset($columns); context_helper::reset_caches(); context_helper::preload_course($SITE->id); $this->assertEqual(context_inspection::test_context_cache_size(), 4); // ====== assign_capability(), unassign_capability() ==================== $rc = $DB->get_record('role_capabilities', array('contextid' => $frontpagecontext->id, 'roleid' => $allroles['teacher'], 'capability' => 'moodle/site:accessallgroups')); $this->assertFalse($rc); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext->id); $rc = $DB->get_record('role_capabilities', array('contextid' => $frontpagecontext->id, 'roleid' => $allroles['teacher'], 'capability' => 'moodle/site:accessallgroups')); $this->assertEqual($rc->permission, CAP_ALLOW); assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext->id); $rc = $DB->get_record('role_capabilities', array('contextid' => $frontpagecontext->id, 'roleid' => $allroles['teacher'], 'capability' => 'moodle/site:accessallgroups')); $this->assertEqual($rc->permission, CAP_ALLOW); assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext, true); $rc = $DB->get_record('role_capabilities', array('contextid' => $frontpagecontext->id, 'roleid' => $allroles['teacher'], 'capability' => 'moodle/site:accessallgroups')); $this->assertEqual($rc->permission, CAP_PREVENT); assign_capability('moodle/site:accessallgroups', CAP_INHERIT, $allroles['teacher'], $frontpagecontext); $rc = $DB->get_record('role_capabilities', array('contextid' => $frontpagecontext->id, 'roleid' => $allroles['teacher'], 'capability' => 'moodle/site:accessallgroups')); $this->assertFalse($rc); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext); unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext, true); $rc = $DB->get_record('role_capabilities', array('contextid' => $frontpagecontext->id, 'roleid' => $allroles['teacher'], 'capability' => 'moodle/site:accessallgroups')); $this->assertFalse($rc); unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext->id, true); unset($rc); accesslib_clear_all_caches(false); // must be done after assign_capability() // ======= role_assign(), role_unassign(), role_unassign_all() ============== $context = context_course::instance($testcourses[1]); $this->assertEqual($DB->count_records('role_assignments', array('contextid' => $context->id)), 0); role_assign($allroles['teacher'], $testusers[1], $context->id); role_assign($allroles['teacher'], $testusers[2], $context->id); role_assign($allroles['manager'], $testusers[1], $context->id); $this->assertEqual($DB->count_records('role_assignments', array('contextid' => $context->id)), 3); role_unassign($allroles['teacher'], $testusers[1], $context->id); $this->assertEqual($DB->count_records('role_assignments', array('contextid' => $context->id)), 2); role_unassign_all(array('contextid' => $context->id)); $this->assertEqual($DB->count_records('role_assignments', array('contextid' => $context->id)), 0); unset($context); accesslib_clear_all_caches(false); // just in case // ====== has_capability(), get_users_by_capability(), role_switch(), reload_all_capabilities() and friends ======================== $adminid = get_admin()->id; $guestid = $CFG->siteguest; // Enrol some users into some courses $course1 = $DB->get_record('course', array('id' => $testcourses[22]), '*', MUST_EXIST); $course2 = $DB->get_record('course', array('id' => $testcourses[7]), '*', MUST_EXIST); $cms = $DB->get_records('course_modules', array('course' => $course1->id), 'id'); $cm1 = reset($cms); $blocks = $DB->get_records('block_instances', array('parentcontextid' => context_module::instance($cm1->id)->id), 'id'); $block1 = reset($blocks); $instance1 = $DB->get_record('enrol', array('enrol' => 'manual', 'courseid' => $course1->id)); $instance2 = $DB->get_record('enrol', array('enrol' => 'manual', 'courseid' => $course2->id)); for ($i = 0; $i < 9; $i++) { $manualenrol->enrol_user($instance1, $testusers[$i], $allroles['student']); } $manualenrol->enrol_user($instance1, $testusers[8], $allroles['teacher']); $manualenrol->enrol_user($instance1, $testusers[9], $allroles['editingteacher']); for ($i = 10; $i < 15; $i++) { $manualenrol->enrol_user($instance2, $testusers[$i], $allroles['student']); } $manualenrol->enrol_user($instance2, $testusers[15], $allroles['editingteacher']); // Add tons of role assignments - the more the better role_assign($allroles['coursecreator'], $testusers[11], context_coursecat::instance($testcategories[2])); role_assign($allroles['manager'], $testusers[12], context_coursecat::instance($testcategories[1])); role_assign($allroles['student'], $testusers[9], context_module::instance($cm1->id)); role_assign($allroles['teacher'], $testusers[8], context_module::instance($cm1->id)); role_assign($allroles['guest'], $testusers[13], context_course::instance($course1->id)); role_assign($allroles['teacher'], $testusers[7], context_block::instance($block1->id)); role_assign($allroles['manager'], $testusers[9], context_block::instance($block1->id)); role_assign($allroles['editingteacher'], $testusers[9], context_course::instance($course1->id)); role_assign($allroles['teacher'], $adminid, context_course::instance($course1->id)); role_assign($allroles['editingteacher'], $adminid, context_block::instance($block1->id)); // Add tons of overrides - the more the better assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpageblockcontext, true); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpageblockcontext, true); assign_capability('moodle/block:view', CAP_PROHIBIT, $allroles['guest'], $frontpageblockcontext, true); assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['user'], $frontpageblockcontext, true); assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['student'], $frontpageblockcontext, true); assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $CFG->defaultuserroleid, $frontpagepagecontext, true); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagepagecontext, true); assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $frontpagepagecontext, true); assign_capability('mod/page:view', CAP_ALLOW, $allroles['user'], $frontpagepagecontext, true); assign_capability('moodle/page:view', CAP_ALLOW, $allroles['student'], $frontpagepagecontext, true); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpagecontext, true); assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagecontext, true); assign_capability('mod/page:view', CAP_ALLOW, $allroles['guest'], $frontpagecontext, true); assign_capability('mod/page:view', CAP_PROHIBIT, $allroles['user'], $frontpagecontext, true); assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $systemcontext, true); accesslib_clear_all_caches(false); // must be done after assign_capability() // Extra tests for guests and not-logged-in users because they can not be verified by cross checking // with get_users_by_capability() where they are ignored $this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, $guestid)); $this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, $guestid)); $this->assertTrue(has_capability('mod/page:view', $frontpagecontext, $guestid)); $this->assertFalse(has_capability('mod/page:view', $systemcontext, $guestid)); $this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, 0)); $this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, 0)); $this->assertTrue(has_capability('mod/page:view', $frontpagecontext, 0)); $this->assertFalse(has_capability('mod/page:view', $systemcontext, 0)); $this->assertFalse(has_capability('moodle/course:create', $systemcontext, $testusers[11])); $this->assertTrue(has_capability('moodle/course:create', context_coursecat::instance($testcategories[2]), $testusers[11])); $this->assertFalse(has_capability('moodle/course:create', context_course::instance($testcourses[1]), $testusers[11])); $this->assertTrue(has_capability('moodle/course:create', context_course::instance($testcourses[19]), $testusers[11])); $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[1]), $testusers[9])); $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[19]), $testusers[9])); $this->assertFalse(has_capability('moodle/course:update', $systemcontext, $testusers[9])); // Test the list of enrolled users $coursecontext = context_course::instance($course1->id); $enrolled = get_enrolled_users($coursecontext); $this->assertEqual(count($enrolled), 10); for ($i = 0; $i < 10; $i++) { $this->assertTrue(isset($enrolled[$testusers[$i]])); } $enrolled = get_enrolled_users($coursecontext, 'moodle/course:update'); $this->assertEqual(count($enrolled), 1); $this->assertTrue(isset($enrolled[$testusers[9]])); unset($enrolled); // role switching $userid = $testusers[9]; $USER = $DB->get_record('user', array('id' => $userid)); load_all_capabilities(); $coursecontext = context_course::instance($course1->id); $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); $this->assertFalse(is_role_switched($course1->id)); role_switch($allroles['student'], $coursecontext); $this->assertTrue(is_role_switched($course1->id)); $this->assertEqual($USER->access['rsw'][$coursecontext->path], $allroles['student']); $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); reload_all_capabilities(); $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); role_switch(0, $coursecontext); $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); $userid = $adminid; $USER = $DB->get_record('user', array('id' => $userid)); load_all_capabilities(); $coursecontext = context_course::instance($course1->id); $blockcontext = context_block::instance($block1->id); $this->assertTrue(has_capability('moodle/course:update', $blockcontext)); role_switch($allroles['student'], $coursecontext); $this->assertEqual($USER->access['rsw'][$coursecontext->path], $allroles['student']); $this->assertFalse(has_capability('moodle/course:update', $blockcontext)); reload_all_capabilities(); $this->assertFalse(has_capability('moodle/course:update', $blockcontext)); load_all_capabilities(); $this->assertTrue(has_capability('moodle/course:update', $blockcontext)); // temp course role for enrol $DB->delete_records('cache_flags', array()); // this prevents problem with dirty contexts immediately resetting the temp role - this is a known problem... $userid = $testusers[5]; $roleid = $allroles['editingteacher']; $USER = $DB->get_record('user', array('id' => $userid)); load_all_capabilities(); $coursecontext = context_course::instance($course1->id); $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); $this->assertFalse(isset($USER->access['ra'][$coursecontext->path][$roleid])); load_temp_course_role($coursecontext, $roleid); $this->assertEqual($USER->access['ra'][$coursecontext->path][$roleid], $roleid); $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); remove_temp_course_roles($coursecontext); $this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid)); load_temp_course_role($coursecontext, $roleid); reload_all_capabilities(); $this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid)); $USER = new stdClass(); $USER->id = 0; // Now cross check has_capability() with get_users_by_capability(), each using different code paths, // they have to be kept in sync, usually only one of them breaks, so we know when something is wrong, // at the same time validate extra restrictions (guest read only no risks, admin exception, non existent and deleted users) $contexts = $DB->get_records('context', array(), 'id'); $contexts = array_values($contexts); $capabilities = $DB->get_records('capabilities', array(), 'id'); $capabilities = array_values($capabilities); $roles = array($allroles['guest'], $allroles['user'], $allroles['teacher'], $allroles['editingteacher'], $allroles['coursecreator'], $allroles['manager']); // Random time! srand(666); foreach ($testusers as $userid) { // no guest or deleted // each user gets 0-20 random roles $rcount = rand(0, 10); for ($j = 0; $j < $rcount; $j++) { $roleid = $roles[rand(0, count($roles) - 1)]; $contextid = $contexts[rand(0, count($contexts) - 1)]->id; role_assign($roleid, $userid, $contextid); } } $permissions = array(CAP_ALLOW, CAP_PREVENT, CAP_INHERIT, CAP_PREVENT); for ($j = 0; $j < 10000; $j++) { $roleid = $roles[rand(0, count($roles) - 1)]; $contextid = $contexts[rand(0, count($contexts) - 1)]->id; $permission = $permissions[rand(0, count($permissions) - 1)]; $capname = $capabilities[rand(0, count($capabilities) - 1)]->name; assign_capability($capname, $permission, $roleid, $contextid, true); } unset($permissions); unset($roles); unset($contexts); unset($users); unset($capabilities); accesslib_clear_all_caches(false); // must be done after assign_capability() // Test time - let's set up some real user, just in case the logic for USER affects the others... $USER = $DB->get_record('user', array('id' => $testusers[3])); load_all_capabilities(); $contexts = $DB->get_records('context', array(), 'id'); $users = $DB->get_records('user', array(), 'id', 'id'); $capabilities = $DB->get_records('capabilities', array(), 'id'); $users[0] = null; // not-logged-in user $users[-1] = null; // non-existent user foreach ($contexts as $crecord) { $context = context::instance_by_id($crecord->id); if ($coursecontext = $context->get_course_context(false)) { $enrolled = get_enrolled_users($context); } else { $enrolled = array(); } foreach ($capabilities as $cap) { $allowed = get_users_by_capability($context, $cap->name, 'u.id, u.username'); if ($enrolled) { $enrolledwithcap = get_enrolled_users($context, $cap->name); } else { $enrolledwithcap = array(); } foreach ($users as $userid => $unused) { if ($userid == 0 or isguestuser($userid)) { if ($userid == 0) { $CFG->forcelogin = true; $this->assertFalse(has_capability($cap->name, $context, $userid)); unset($CFG->forcelogin); } if ($cap->captype === 'write' or $cap->riskbitmask & (RISK_XSS | RISK_CONFIG | RISK_DATALOSS)) { $this->assertFalse(has_capability($cap->name, $context, $userid)); } $this->assertFalse(isset($allowed[$userid])); } else { if (is_siteadmin($userid)) { $this->assertTrue(has_capability($cap->name, $context, $userid, true)); } $hascap = has_capability($cap->name, $context, $userid, false); $this->assertIdentical($hascap, isset($allowed[$userid]), "Capability result mismatch user:{$userid}, context:{$context->id}, {$cap->name}, hascap: " . (int) $hascap . " "); if (isset($enrolled[$userid])) { $this->assertIdentical(isset($allowed[$userid]), isset($enrolledwithcap[$userid]), "Enrolment with capability result mismatch user:{$userid}, context:{$context->id}, {$cap->name}, hascap: " . (int) $hascap . " "); } } } } } // Back to nobody $USER = new stdClass(); $USER->id = 0; unset($contexts); unset($users); unset($capabilities); // Now let's do all the remaining tests that break our carefully prepared fake site // ======= $context->mark_dirty() ======================================= $DB->delete_records('cache_flags', array()); accesslib_clear_all_caches(false); $systemcontext->mark_dirty(); $dirty = get_cache_flags('accesslib/dirtycontexts', time() - 2); $this->assertTrue(isset($dirty[$systemcontext->path])); $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$systemcontext->path])); // ======= $context->reload_if_dirty(); ================================= $DB->delete_records('cache_flags', array()); accesslib_clear_all_caches(false); load_all_capabilities(); $context = context_course::instance($testcourses[2]); $page = $DB->get_record('page', array('course' => $testcourses[2])); $pagecontext = context_module::instance($page->id); $context->mark_dirty(); $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path])); $USER->access['test'] = true; $context->reload_if_dirty(); $this->assertFalse(isset($USER->access['test'])); $context->mark_dirty(); $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path])); $USER->access['test'] = true; $pagecontext->reload_if_dirty(); $this->assertFalse(isset($USER->access['test'])); // ======= context_helper::build_all_paths() ============================ $oldcontexts = $DB->get_records('context', array(), 'id'); $DB->set_field_select('context', 'path', NULL, "contextlevel <> " . CONTEXT_SYSTEM); $DB->set_field_select('context', 'depth', 0, "contextlevel <> " . CONTEXT_SYSTEM); context_helper::build_all_paths(); $newcontexts = $DB->get_records('context', array(), 'id'); $this->assertIdentical($oldcontexts, $newcontexts); unset($oldcontexts); unset($newcontexts); // ======= $context->reset_paths() ====================================== $context = context_course::instance($testcourses[2]); $children = $context->get_child_contexts(); $context->reset_paths(false); $this->assertIdentical($DB->get_field('context', 'path', array('id' => $context->id)), NULL); $this->assertEqual($DB->get_field('context', 'depth', array('id' => $context->id)), 0); foreach ($children as $child) { $this->assertIdentical($DB->get_field('context', 'path', array('id' => $child->id)), NULL); $this->assertEqual($DB->get_field('context', 'depth', array('id' => $child->id)), 0); } $this->assertEqual(count($children) + 1, $DB->count_records('context', array('depth' => 0))); $this->assertEqual(count($children) + 1, $DB->count_records('context', array('path' => NULL))); $context = context_course::instance($testcourses[2]); $context->reset_paths(true); $context = context_course::instance($testcourses[2]); $this->assertEqual($DB->get_field('context', 'path', array('id' => $context->id)), $context->path); $this->assertEqual($DB->get_field('context', 'depth', array('id' => $context->id)), $context->depth); $this->assertEqual(0, $DB->count_records('context', array('depth' => 0))); $this->assertEqual(0, $DB->count_records('context', array('path' => NULL))); // ====== $context->update_moved(); ====================================== accesslib_clear_all_caches(false); $DB->delete_records('cache_flags', array()); $course = $DB->get_record('course', array('id' => $testcourses[0])); $context = context_course::instance($course->id); $oldpath = $context->path; $miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}"); $categorycontext = context_coursecat::instance($miscid); $course->category = $miscid; $DB->update_record('course', $course); $context->update_moved($categorycontext); $context = context_course::instance($course->id); $this->assertIdentical($context->get_parent_context(), $categorycontext); $dirty = get_cache_flags('accesslib/dirtycontexts', time() - 2); $this->assertTrue(isset($dirty[$oldpath])); $this->assertTrue(isset($dirty[$context->path])); // ====== $context->delete_content() ===================================== context_helper::reset_caches(); $context = context_module::instance($testpages[3]); $this->assertTrue($DB->record_exists('context', array('id' => $context->id))); $this->assertEqual(1, $DB->count_records('block_instances', array('parentcontextid' => $context->id))); $context->delete_content(); $this->assertTrue($DB->record_exists('context', array('id' => $context->id))); $this->assertEqual(0, $DB->count_records('block_instances', array('parentcontextid' => $context->id))); // ====== $context->delete() ============================= context_helper::reset_caches(); $context = context_module::instance($testpages[4]); $this->assertTrue($DB->record_exists('context', array('id' => $context->id))); $this->assertEqual(1, $DB->count_records('block_instances', array('parentcontextid' => $context->id))); $bi = $DB->get_record('block_instances', array('parentcontextid' => $context->id)); $bicontext = context_block::instance($bi->id); $DB->delete_records('cache_flags', array()); $context->delete(); // should delete also linked blocks $dirty = get_cache_flags('accesslib/dirtycontexts', time() - 2); $this->assertTrue(isset($dirty[$context->path])); $this->assertFalse($DB->record_exists('context', array('id' => $context->id))); $this->assertFalse($DB->record_exists('context', array('id' => $bicontext->id))); $this->assertFalse($DB->record_exists('context', array('contextlevel' => CONTEXT_MODULE, 'instanceid' => $testpages[4]))); $this->assertFalse($DB->record_exists('context', array('contextlevel' => CONTEXT_BLOCK, 'instanceid' => $bi->id))); $this->assertEqual(0, $DB->count_records('block_instances', array('parentcontextid' => $context->id))); context_module::instance($testpages[4]); // ====== context_helper::delete_instance() ============================= context_helper::reset_caches(); $lastcourse = array_pop($testcourses); $this->assertTrue($DB->record_exists('context', array('contextlevel' => CONTEXT_COURSE, 'instanceid' => $lastcourse))); $coursecontext = context_course::instance($lastcourse); $this->assertEqual(context_inspection::test_context_cache_size(), 1); $this->assertFalse($coursecontext->instanceid == CONTEXT_COURSE); $DB->delete_records('cache_flags', array()); context_helper::delete_instance(CONTEXT_COURSE, $lastcourse); $dirty = get_cache_flags('accesslib/dirtycontexts', time() - 2); $this->assertTrue(isset($dirty[$coursecontext->path])); $this->assertEqual(context_inspection::test_context_cache_size(), 0); $this->assertFalse($DB->record_exists('context', array('contextlevel' => CONTEXT_COURSE, 'instanceid' => $lastcourse))); context_course::instance($lastcourse); // ======= context_helper::create_instances() ========================== $prevcount = $DB->count_records('context'); $DB->delete_records('context', array('contextlevel' => CONTEXT_BLOCK)); context_helper::create_instances(null, true); $this->assertIdentical($DB->count_records('context'), $prevcount); $this->assertEqual($DB->count_records('context', array('depth' => 0)), 0); $this->assertEqual($DB->count_records('context', array('path' => NULL)), 0); $DB->delete_records('context', array('contextlevel' => CONTEXT_BLOCK)); $DB->delete_records('block_instances', array()); $prevcount = $DB->count_records('context'); $DB->delete_records_select('context', 'contextlevel <> ' . CONTEXT_SYSTEM); context_helper::create_instances(null, true); $this->assertIdentical($DB->count_records('context'), $prevcount); $this->assertEqual($DB->count_records('context', array('depth' => 0)), 0); $this->assertEqual($DB->count_records('context', array('path' => NULL)), 0); // ======= context_helper::cleanup_instances() ========================== $lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}"); $DB->delete_records('course', array('id' => $lastcourse)); $lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}"); $DB->delete_records('course_categories', array('id' => $lastcategory)); $lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0"); $DB->delete_records('user', array('id' => $lastuser)); $DB->delete_records('block_instances', array('parentcontextid' => $frontpagepagecontext->id)); $DB->delete_records('course_modules', array('id' => $frontpagepagecontext->instanceid)); context_helper::cleanup_instances(); $count = 1; //system $count += $DB->count_records('user', array('deleted' => 0)); $count += $DB->count_records('course_categories'); $count += $DB->count_records('course'); $count += $DB->count_records('course_modules'); $count += $DB->count_records('block_instances'); $this->assertEqual($DB->count_records('context'), $count); // ======= context cache size restrictions ============================== $testusers = array(); for ($i = 0; $i < CONTEXT_CACHE_MAX_SIZE + 100; $i++) { $user = new stdClass(); $user->auth = 'manual'; $user->firstname = 'xuser' . $i; $user->lastname = 'xuser' . $i; $user->username = '******' . $i; $user->password = '******'; $user->email = "xuser{$i}@example.com"; $user->confirmed = 1; $user->mnethostid = $CFG->mnet_localhost_id; $user->lang = $CFG->lang; $user->maildisplay = 1; $user->timemodified = time(); $user->lastip = '0.0.0.0'; $userid = $DB->insert_record('user', $user); $testusers[$i] = $userid; } context_helper::create_instances(null, true); context_helper::reset_caches(); for ($i = 0; $i < CONTEXT_CACHE_MAX_SIZE + 100; $i++) { context_user::instance($testusers[$i]); if ($i == CONTEXT_CACHE_MAX_SIZE - 1) { $this->assertEqual(context_inspection::test_context_cache_size(), CONTEXT_CACHE_MAX_SIZE); } else { if ($i == CONTEXT_CACHE_MAX_SIZE) { // once the limit is reached roughly 1/3 of records should be removed from cache $this->assertEqual(context_inspection::test_context_cache_size(), (int) (CONTEXT_CACHE_MAX_SIZE * (2 / 3) + 102)); } } } // We keep the first 100 cached $prevsize = context_inspection::test_context_cache_size(); for ($i = 0; $i < 100; $i++) { context_user::instance($testusers[$i]); $this->assertEqual(context_inspection::test_context_cache_size(), $prevsize); } context_user::instance($testusers[102]); $this->assertEqual(context_inspection::test_context_cache_size(), $prevsize + 1); unset($testusers); // ================================================================= // ======= basic test of legacy functions ========================== // ================================================================= // note: watch out, the fake site might be pretty borked already $this->assertIdentical(get_system_context(), context_system::instance()); foreach ($DB->get_records('context') as $contextid => $record) { $context = context::instance_by_id($contextid); $this->assertIdentical(get_context_instance_by_id($contextid), $context); $this->assertIdentical(get_context_instance($record->contextlevel, $record->instanceid), $context); $this->assertIdentical(get_parent_contexts($context), $context->get_parent_context_ids()); if ($context->id == SYSCONTEXTID) { $this->assertIdentical(get_parent_contextid($context), false); } else { $this->assertIdentical(get_parent_contextid($context), $context->get_parent_context()->id); } } $children = get_child_contexts($systemcontext); $this->assertEqual(count($children), $DB->count_records('context') - 1); unset($children); $DB->delete_records('context', array('contextlevel' => CONTEXT_BLOCK)); create_contexts(); $this->assertFalse($DB->record_exists('context', array('contextlevel' => CONTEXT_BLOCK))); $DB->set_field('context', 'depth', 0, array('contextlevel' => CONTEXT_BLOCK)); build_context_path(); $this->assertFalse($DB->record_exists('context', array('depth' => 0))); $lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}"); $DB->delete_records('course', array('id' => $lastcourse)); $lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}"); $DB->delete_records('course_categories', array('id' => $lastcategory)); $lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0"); $DB->delete_records('user', array('id' => $lastuser)); $DB->delete_records('block_instances', array('parentcontextid' => $frontpagepagecontext->id)); $DB->delete_records('course_modules', array('id' => $frontpagepagecontext->instanceid)); cleanup_contexts(); $count = 1; //system $count += $DB->count_records('user', array('deleted' => 0)); $count += $DB->count_records('course_categories'); $count += $DB->count_records('course'); $count += $DB->count_records('course_modules'); $count += $DB->count_records('block_instances'); $this->assertEqual($DB->count_records('context'), $count); context_helper::reset_caches(); preload_course_contexts($SITE->id); $this->assertEqual(context_inspection::test_context_cache_size(), 1); context_helper::reset_caches(); list($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSECAT, 'ctx'); $sql = "SELECT c.id {$select} FROM {course_categories} c {$join}"; $records = $DB->get_records_sql($sql); foreach ($records as $record) { context_instance_preload($record); $record = (array) $record; $this->assertEqual(1, count($record)); // only id left } $this->assertEqual(count($records), context_inspection::test_context_cache_size()); accesslib_clear_all_caches(true); $DB->delete_records('cache_flags', array()); mark_context_dirty($systemcontext->path); $dirty = get_cache_flags('accesslib/dirtycontexts', time() - 2); $this->assertTrue(isset($dirty[$systemcontext->path])); accesslib_clear_all_caches(false); $DB->delete_records('cache_flags', array()); $course = $DB->get_record('course', array('id' => $testcourses[2])); $context = get_context_instance(CONTEXT_COURSE, $course->id); $oldpath = $context->path; $miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}"); $categorycontext = context_coursecat::instance($miscid); $course->category = $miscid; $DB->update_record('course', $course); context_moved($context, $categorycontext); $context = get_context_instance(CONTEXT_COURSE, $course->id); $this->assertIdentical($context->get_parent_context(), $categorycontext); $this->assertTrue($DB->record_exists('context', array('contextlevel' => CONTEXT_COURSE, 'instanceid' => $testcourses[2]))); delete_context(CONTEXT_COURSE, $testcourses[2]); $this->assertFalse($DB->record_exists('context', array('contextlevel' => CONTEXT_COURSE, 'instanceid' => $testcourses[2]))); $name = get_contextlevel_name(CONTEXT_COURSE); $this->assertFalse(empty($name)); $context = get_context_instance(CONTEXT_COURSE, $testcourses[2]); $name = print_context_name($context); $this->assertFalse(empty($name)); $url = get_context_url($coursecontext); $this->assertFalse($url instanceof modole_url); $page = $DB->get_record('page', array('id' => $testpages[7])); $context = get_context_instance(CONTEXT_MODULE, $page->id); $coursecontext = get_course_context($context); $this->assertEqual($coursecontext->contextlevel, CONTEXT_COURSE); $this->assertEqual(get_courseid_from_context($context), $page->course); $caps = fetch_context_capabilities($systemcontext); $this->assertTrue(is_array($caps)); unset($caps); }
/** * Tests for mod_data_rating_can_see_item_ratings(). * * @throws coding_exception * @throws rating_exception */ public function test_mod_data_rating_can_see_item_ratings() { global $DB; $this->resetAfterTest(); // Setup test data. $course = new stdClass(); $course->groupmode = SEPARATEGROUPS; $course->groupmodeforce = true; $course = $this->getDataGenerator()->create_course($course); $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id)); $cm = get_coursemodule_from_instance('data', $data->id); $context = context_module::instance($cm->id); // Create users. $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $user3 = $this->getDataGenerator()->create_user(); $user4 = $this->getDataGenerator()->create_user(); // Groups and stuff. $role = $DB->get_record('role', array('shortname' => 'teacher'), '*', MUST_EXIST); $this->getDataGenerator()->enrol_user($user1->id, $course->id, $role->id); $this->getDataGenerator()->enrol_user($user2->id, $course->id, $role->id); $this->getDataGenerator()->enrol_user($user3->id, $course->id, $role->id); $this->getDataGenerator()->enrol_user($user4->id, $course->id, $role->id); $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); groups_add_member($group1, $user1); groups_add_member($group1, $user2); groups_add_member($group2, $user3); groups_add_member($group2, $user4); // Add data. $field = data_get_field_new('text', $data); $fielddetail = new stdClass(); $fielddetail->name = 'Name'; $fielddetail->description = 'Some name'; $field->define_field($fielddetail); $field->insert_field(); // Add a record with a group id of zero (all participants). $recordid1 = data_add_record($data, 0); $datacontent = array(); $datacontent['fieldid'] = $field->field->id; $datacontent['recordid'] = $recordid1; $datacontent['content'] = 'Obelix'; $DB->insert_record('data_content', $datacontent); $recordid = data_add_record($data, $group1->id); $datacontent = array(); $datacontent['fieldid'] = $field->field->id; $datacontent['recordid'] = $recordid; $datacontent['content'] = 'Asterix'; $DB->insert_record('data_content', $datacontent); // Now try to access it as various users. unassign_capability('moodle/site:accessallgroups', $role->id); // Eveyone should have access to the record with the group id of zero. $params1 = array('contextid' => 2, 'component' => 'mod_data', 'ratingarea' => 'entry', 'itemid' => $recordid1, 'scaleid' => 2); $params = array('contextid' => 2, 'component' => 'mod_data', 'ratingarea' => 'entry', 'itemid' => $recordid, 'scaleid' => 2); $this->setUser($user1); $this->assertTrue(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); $this->setUser($user2); $this->assertTrue(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); $this->setUser($user3); $this->assertFalse(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); $this->setUser($user4); $this->assertFalse(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); // Now try with accessallgroups cap and make sure everything is visible. assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $role->id, $context->id); $this->setUser($user1); $this->assertTrue(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); $this->setUser($user2); $this->assertTrue(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); $this->setUser($user3); $this->assertTrue(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); $this->setUser($user4); $this->assertTrue(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); // Change group mode and verify visibility. $course->groupmode = VISIBLEGROUPS; $DB->update_record('course', $course); unassign_capability('moodle/site:accessallgroups', $role->id); $this->setUser($user1); $this->assertTrue(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); $this->setUser($user2); $this->assertTrue(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); $this->setUser($user3); $this->assertTrue(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); $this->setUser($user4); $this->assertTrue(mod_data_rating_can_see_item_ratings($params)); $this->assertTrue(mod_data_rating_can_see_item_ratings($params1)); }
public function save_changes() { global $DB; if (!$this->roleid) { // Creating role if (isset($this->legacyroles[$this->role->legacytype])) { $legacycap = $this->legacyroles[$this->role->legacytype]; } else { $legacycap = ''; } $this->role->id = create_role($this->role->name, $this->role->shortname, $this->role->description, $legacycap); $this->roleid = $this->role->id; // Needed to make the parent::save_changes(); call work. } else { // Updating role $DB->update_record('role', $this->role); // Legacy type foreach ($this->legacyroles as $type => $cap) { if ($type == $this->role->legacytype) { assign_capability($cap, CAP_ALLOW, $this->role->id, $this->context->id); } else { unassign_capability($cap, $this->role->id); } } } // Assignable contexts. set_role_contextlevels($this->role->id, $this->contextlevels); // Permissions. parent::save_changes(); }
/** * More user friendly role permission changing, * it should produce as few overrides as possible. * @param int $roleid * @param object $context * @param string $capname capability name * @param int $permission * @return void */ function role_change_permission($roleid, $context, $capname, $permission) { global $DB; if ($permission == CAP_INHERIT) { unassign_capability($capname, $roleid, $context->id); $context->mark_dirty(); return; } $ctxids = trim($context->path, '/'); // kill leading slash $ctxids = str_replace('/', ',', $ctxids); $params = array('roleid' => $roleid, 'cap' => $capname); $sql = "SELECT ctx.id, rc.permission, ctx.depth\n FROM {role_capabilities} rc\n JOIN {context} ctx ON ctx.id = rc.contextid\n WHERE rc.roleid = :roleid AND rc.capability = :cap AND ctx.id IN ({$ctxids})\n ORDER BY ctx.depth DESC"; if ($existing = $DB->get_records_sql($sql, $params)) { foreach ($existing as $e) { if ($e->permission == CAP_PROHIBIT) { // prohibit can not be overridden, no point in changing anything return; } } $lowest = array_shift($existing); if ($lowest->permission == $permission) { // permission already set in this context or parent - nothing to do return; } if ($existing) { $parent = array_shift($existing); if ($parent->permission == $permission) { // permission already set in parent context or parent - just unset in this context // we do this because we want as few overrides as possible for performance reasons unassign_capability($capname, $roleid, $context->id); $context->mark_dirty(); return; } } } else { if ($permission == CAP_PREVENT) { // nothing means role does not have permission return; } } // assign the needed capability assign_capability($capname, $permission, $roleid, $context->id, true); // force cap reloading $context->mark_dirty(); }
/** * Clears capabilities from all roles so that they may be reassigned as specified. */ public static function clear_capabilities_for_course($courseid) { $coursecontext = context_course::instance($courseid); // Get all roles for current course. $currentcourseroles = get_all_roles($coursecontext); // Remove publisher and creator capabilities from all roles. foreach ($currentcourseroles as $role) { unassign_capability('block/panopto:provision_aspublisher', $role->id, $coursecontext); unassign_capability('block/panopto:provision_asteacher', $role->id, $coursecontext); // Mark dirty (moodle standard for capability changes at context level). $coursecontext->mark_dirty(); } }