From 05f6da14f76c320cfe0115b990edb25adb7c0232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0koda?= Date: Wed, 24 Oct 2012 09:52:31 +0800 Subject: [PATCH] MDL-33017 add new function for quickly finding out if user sees at least on course This will be used in navigation. --- enrol/tests/enrollib_test.php | 253 ++++++++++++++++++++++++++++++++++ lib/enrollib.php | 50 +++++++ 2 files changed, 303 insertions(+) create mode 100644 enrol/tests/enrollib_test.php diff --git a/enrol/tests/enrollib_test.php b/enrol/tests/enrollib_test.php new file mode 100644 index 00000000000..edbb97ee8b9 --- /dev/null +++ b/enrol/tests/enrollib_test.php @@ -0,0 +1,253 @@ +. + +/** + * Test non-plugin enrollib parts. + * + * @package core + * @category phpunit + * @copyright 2012 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + + +/** + * Test non-plugin enrollib parts. + * + * @package core + * @category phpunit + * @copyright 2012 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_enrol_testcase extends advanced_testcase { + + public function test_enrol_get_all_users_courses() { + global $DB, $CFG; + + $this->resetAfterTest(); + + $studentrole = $DB->get_record('role', array('shortname'=>'student')); + $this->assertNotEmpty($studentrole); + $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); + $this->assertNotEmpty($teacherrole); + + $admin = get_admin(); + $user1 = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $user3 = $this->getDataGenerator()->create_user(); + $user4 = $this->getDataGenerator()->create_user(); + $user5 = $this->getDataGenerator()->create_user(); + + $category1 = $this->getDataGenerator()->create_category(array('visible'=>0)); + $category2 = $this->getDataGenerator()->create_category(); + $course1 = $this->getDataGenerator()->create_course(array('category'=>$category1->id)); + $course2 = $this->getDataGenerator()->create_course(array('category'=>$category2->id)); + $course3 = $this->getDataGenerator()->create_course(array('category'=>$category2->id, 'visible'=>0)); + $course4 = $this->getDataGenerator()->create_course(array('category'=>$category2->id)); + + $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$maninstance1->id)); + $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $maninstance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $maninstance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST); + + $manual = enrol_get_plugin('manual'); + $this->assertNotEmpty($manual); + + $manual->enrol_user($maninstance1, $user1->id, $teacherrole->id); + $manual->enrol_user($maninstance1, $user2->id, $studentrole->id); + $manual->enrol_user($maninstance1, $user4->id, $teacherrole->id, 0, 0, ENROL_USER_SUSPENDED); + $manual->enrol_user($maninstance1, $admin->id, $studentrole->id); + + $manual->enrol_user($maninstance2, $user1->id); + $manual->enrol_user($maninstance2, $user2->id); + $manual->enrol_user($maninstance2, $user3->id, 0, 1, time()+(60*60)); + + $manual->enrol_user($maninstance3, $user1->id); + $manual->enrol_user($maninstance3, $user2->id); + $manual->enrol_user($maninstance3, $user3->id, 0, 1, time()-(60*60)); + $manual->enrol_user($maninstance3, $user4->id, 0, 0, 0, ENROL_USER_SUSPENDED); + + + $courses = enrol_get_all_users_courses($CFG->siteguest); + $this->assertSame(array(), $courses); + + $courses = enrol_get_all_users_courses(0); + $this->assertSame(array(), $courses); + + // Results are sorted by visibility, sortorder by default (in our case order of creation) + + $courses = enrol_get_all_users_courses($admin->id); + $this->assertCount(1, $courses); + $this->assertEquals(array($course1->id), array_keys($courses)); + + $courses = enrol_get_all_users_courses($admin->id, true); + $this->assertCount(0, $courses); + $this->assertEquals(array(), array_keys($courses)); + + $courses = enrol_get_all_users_courses($user1->id); + $this->assertCount(3, $courses); + $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses)); + + $courses = enrol_get_all_users_courses($user1->id, true); + $this->assertCount(2, $courses); + $this->assertEquals(array($course2->id, $course3->id), array_keys($courses)); + + $courses = enrol_get_all_users_courses($user2->id); + $this->assertCount(3, $courses); + $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses)); + + $courses = enrol_get_all_users_courses($user2->id, true); + $this->assertCount(2, $courses); + $this->assertEquals(array($course2->id, $course3->id), array_keys($courses)); + + $courses = enrol_get_all_users_courses($user3->id); + $this->assertCount(2, $courses); + $this->assertEquals(array($course2->id, $course3->id), array_keys($courses)); + + $courses = enrol_get_all_users_courses($user3->id, true); + $this->assertCount(1, $courses); + $this->assertEquals(array($course2->id), array_keys($courses)); + + $courses = enrol_get_all_users_courses($user4->id); + $this->assertCount(2, $courses); + $this->assertEquals(array($course1->id, $course3->id), array_keys($courses)); + + $courses = enrol_get_all_users_courses($user4->id, true); + $this->assertCount(0, $courses); + $this->assertEquals(array(), array_keys($courses)); + + // Make sure sorting and columns work. + + $basefields = array('id', 'category', 'sortorder', 'shortname', 'fullname', 'idnumber', + 'startdate', 'visible', 'groupmode', 'groupmodeforce'); + + $courses = enrol_get_all_users_courses($user2->id, true); + $course = reset($courses); + context_helper::preload_from_record($course); + $course = (array)$course; + $this->assertEquals($basefields, array_keys($course), '', 0, 10, true); + + $courses = enrol_get_all_users_courses($user2->id, false, 'modinfo'); + $course = reset($courses); + $this->assertTrue(property_exists($course, 'modinfo')); + + $courses = enrol_get_all_users_courses($user2->id, false, null, 'id DESC'); + $this->assertEquals(array($course3->id, $course2->id, $course1->id), array_keys($courses)); + } + + public function test_enrol_user_sees_own_courses() { + global $DB, $CFG; + + $this->resetAfterTest(); + + $studentrole = $DB->get_record('role', array('shortname'=>'student')); + $this->assertNotEmpty($studentrole); + $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); + $this->assertNotEmpty($teacherrole); + + $admin = get_admin(); + $user1 = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $user3 = $this->getDataGenerator()->create_user(); + $user4 = $this->getDataGenerator()->create_user(); + $user5 = $this->getDataGenerator()->create_user(); + $user6 = $this->getDataGenerator()->create_user(); + + $category1 = $this->getDataGenerator()->create_category(array('visible'=>0)); + $category2 = $this->getDataGenerator()->create_category(); + $course1 = $this->getDataGenerator()->create_course(array('category'=>$category1->id)); + $course2 = $this->getDataGenerator()->create_course(array('category'=>$category2->id)); + $course3 = $this->getDataGenerator()->create_course(array('category'=>$category2->id, 'visible'=>0)); + $course4 = $this->getDataGenerator()->create_course(array('category'=>$category2->id)); + + $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$maninstance1->id)); + $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $maninstance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST); + $maninstance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST); + + $manual = enrol_get_plugin('manual'); + $this->assertNotEmpty($manual); + + $manual->enrol_user($maninstance1, $admin->id, $studentrole->id); + + $manual->enrol_user($maninstance3, $user1->id, $teacherrole->id); + + $manual->enrol_user($maninstance2, $user2->id, $studentrole->id); + + $manual->enrol_user($maninstance1, $user3->id, $studentrole->id, 1, time()+(60*60)); + $manual->enrol_user($maninstance2, $user3->id, 0, 1, time()-(60*60)); + $manual->enrol_user($maninstance3, $user2->id, $studentrole->id); + $manual->enrol_user($maninstance4, $user2->id, 0, 0, 0, ENROL_USER_SUSPENDED); + + $manual->enrol_user($maninstance1, $user4->id, $teacherrole->id, 0, 0, ENROL_USER_SUSPENDED); + $manual->enrol_user($maninstance3, $user4->id, 0, 0, 0, ENROL_USER_SUSPENDED); + + + $this->assertFalse(enrol_user_sees_own_courses($CFG->siteguest)); + $this->assertFalse(enrol_user_sees_own_courses(0)); + $this->assertFalse(enrol_user_sees_own_courses($admin)); + $this->assertFalse(enrol_user_sees_own_courses(-222)); // Nonexistent user. + + $this->assertTrue(enrol_user_sees_own_courses($user1)); + $this->assertTrue(enrol_user_sees_own_courses($user2->id)); + $this->assertFalse(enrol_user_sees_own_courses($user3->id)); + $this->assertFalse(enrol_user_sees_own_courses($user4)); + $this->assertFalse(enrol_user_sees_own_courses($user5)); + + $this->setAdminUser(); + $this->assertFalse(enrol_user_sees_own_courses()); + + $this->setGuestUser(); + $this->assertFalse(enrol_user_sees_own_courses()); + + $this->setUser(0); + $this->assertFalse(enrol_user_sees_own_courses()); + + $this->setUser($user1); + $this->assertTrue(enrol_user_sees_own_courses()); + + $this->setUser($user2); + $this->assertTrue(enrol_user_sees_own_courses()); + + $this->setUser($user3); + $this->assertFalse(enrol_user_sees_own_courses()); + + $this->setUser($user4); + $this->assertFalse(enrol_user_sees_own_courses()); + + $this->setUser($user5); + $this->assertFalse(enrol_user_sees_own_courses()); + + $user1 = $DB->get_record('user', array('id'=>$user1->id)); + $this->setUser($user1); + $reads = $DB->perf_get_reads(); + $this->assertTrue(enrol_user_sees_own_courses()); + $this->assertGreaterThan($reads, $DB->perf_get_reads()); + + $user1 = $DB->get_record('user', array('id'=>$user1->id)); + $this->setUser($user1); + require_login($course3); + $reads = $DB->perf_get_reads(); + $this->assertTrue(enrol_user_sees_own_courses()); + $this->assertEquals($reads, $DB->perf_get_reads()); + } +} diff --git a/lib/enrollib.php b/lib/enrollib.php index c86dd231469..a045d77e7d2 100644 --- a/lib/enrollib.php +++ b/lib/enrollib.php @@ -710,6 +710,56 @@ function enrol_get_users_courses($userid, $onlyactive = false, $fields = NULL, $ } +/** + * Can user access at least one enrolled course? + * + * Cheat if necessary, but find out as fast as possible! + * + * @param int|stdClass $user null means use current user + * @return bool + */ +function enrol_user_sees_own_courses($user = null) { + global $USER; + + if ($user === null) { + $user = $USER; + } + $userid = is_object($user) ? $user->id : $user; + + // Guest account does not have any courses + if (isguestuser($userid) or empty($userid)) { + return false; + } + + // Let's cheat here if this is the current user, + // if user accessed any course recently, then most probably + // we do not need to query the database at all. + if ($USER->id == $userid) { + if (!empty($USER->enrol['enrolled'])) { + foreach ($USER->enrol['enrolled'] as $until) { + if ($until > time()) { + return true; + } + } + } + } + + // Now the slow way. + $courses = enrol_get_all_users_courses($userid, true); + foreach($courses as $course) { + if ($course->visible) { + return true; + } + context_helper::preload_from_record($course); + $context = context_course::instance($course->id); + if (has_capability('moodle/course:viewhiddencourses', $context, $user)) { + return true; + } + } + + return false; +} + /** * Returns list of courses user is enrolled into without any capability checks * - $fields is an array of fieldnames to ADD