From 64b5d44abcb57fee2ef42eab0c348680c9391c9b Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Thu, 5 Apr 2018 00:17:40 +1000 Subject: [PATCH] MDL-58768 coursecat: coursecat::get to accept a $user parameter --- lib/coursecatlib.php | 14 +++--- lib/tests/coursecatlib_test.php | 77 +++++++++++++++++++++++++++++++++ lib/upgrade.txt | 2 + 3 files changed, 87 insertions(+), 6 deletions(-) diff --git a/lib/coursecatlib.php b/lib/coursecatlib.php index 5ad20b73ac5..8833387190a 100644 --- a/lib/coursecatlib.php +++ b/lib/coursecatlib.php @@ -212,7 +212,7 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate { /** * Returns coursecat object for requested category * - * If category is not visible to user it is treated as non existing + * If category is not visible to the given user, it is treated as non existing * unless $alwaysreturnhidden is set to true * * If id is 0, the pseudo object for root category is returned (convenient @@ -226,10 +226,11 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate { * returned even if this category is not visible to the current user * (category is hidden and user does not have * 'moodle/category:viewhiddencategories' capability). Use with care! + * @param int|stdClass $user The user id or object. By default (null) checks the visibility to the current user. * @return null|coursecat * @throws moodle_exception */ - public static function get($id, $strictness = MUST_EXIST, $alwaysreturnhidden = false) { + public static function get($id, $strictness = MUST_EXIST, $alwaysreturnhidden = false, $user = null) { if (!$id) { if (!isset(self::$coursecat0)) { $record = new stdClass(); @@ -251,7 +252,7 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate { $coursecatrecordcache->set($id, $coursecat); } } - if ($coursecat && ($alwaysreturnhidden || $coursecat->is_uservisible())) { + if ($coursecat && ($alwaysreturnhidden || $coursecat->is_uservisible($user))) { return $coursecat; } else { if ($strictness == MUST_EXIST) { @@ -580,17 +581,18 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate { } /** - * Checks if this course category is visible to current user + * Checks if this course category is visible to a user. * * Please note that methods coursecat::get (without 3rd argumet), * coursecat::get_children(), etc. return only visible categories so it is * usually not needed to call this function outside of this class * + * @param int|stdClass $user The user id or object. By default (null) checks the visibility to the current user. * @return bool */ - public function is_uservisible() { + public function is_uservisible($user = null) { return !$this->id || $this->visible || - has_capability('moodle/category:viewhiddencategories', $this->get_context()); + has_capability('moodle/category:viewhiddencategories', $this->get_context(), $user); } /** diff --git a/lib/tests/coursecatlib_test.php b/lib/tests/coursecatlib_test.php index 54b10995477..1b7e280cbff 100644 --- a/lib/tests/coursecatlib_test.php +++ b/lib/tests/coursecatlib_test.php @@ -797,6 +797,83 @@ class core_coursecatlib_testcase extends advanced_testcase { $this->assertEquals("{$cat1name} / {$cat2name} / {$cat4name}", $category4->get_nested_name(false)); } + public function test_coursecat_is_uservisible() { + global $USER; + + // Create category 1 as visible. + $category1 = coursecat::create(array('name' => 'Cat1', 'visible' => 1)); + // Create category 2 as hidden. + $category2 = coursecat::create(array('name' => 'Cat2', 'visible' => 0)); + + $this->assertTrue($category1->is_uservisible()); + $this->assertFalse($category2->is_uservisible()); + + $this->assign_capability('moodle/category:viewhiddencategories'); + + $this->assertTrue($category1->is_uservisible()); + $this->assertTrue($category2->is_uservisible()); + + // First, store current user's id, then login as another user. + $userid = $USER->id; + $this->setUser($this->getDataGenerator()->create_user()); + + // User $user should still have the moodle/category:viewhiddencategories capability. + $this->assertTrue($category1->is_uservisible($userid)); + $this->assertTrue($category2->is_uservisible($userid)); + + $this->assign_capability('moodle/category:viewhiddencategories', CAP_INHERIT); + + $this->assertTrue($category1->is_uservisible()); + $this->assertFalse($category2->is_uservisible()); + } + + public function test_current_user_coursecat_get() { + $this->assign_capability('moodle/category:viewhiddencategories'); + + // Create category 1 as visible. + $category1 = coursecat::create(array('name' => 'Cat1', 'visible' => 1)); + // Create category 2 as hidden. + $category2 = coursecat::create(array('name' => 'Cat2', 'visible' => 0)); + + $this->assertEquals($category1->id, coursecat::get($category1->id)->id); + $this->assertEquals($category2->id, coursecat::get($category2->id)->id); + + // Login as another user to test coursecat::get. + $this->setUser($this->getDataGenerator()->create_user()); + $this->assertEquals($category1->id, coursecat::get($category1->id)->id); + + // Expecting to get an exception as this new user does not have the moodle/category:viewhiddencategories capability. + $this->expectException('moodle_exception'); + $this->expectExceptionMessage('unknowncategory'); + coursecat::get($category2->id); + } + + public function test_another_user_coursecat_get() { + global $USER; + + $this->assign_capability('moodle/category:viewhiddencategories'); + + // Create category 1 as visible. + $category1 = coursecat::create(array('name' => 'Cat1', 'visible' => 1)); + // Create category 2 as hidden. + $category2 = coursecat::create(array('name' => 'Cat2', 'visible' => 0)); + + // First, store current user's object, then login as another user. + $user1 = $USER; + $user2 = $this->getDataGenerator()->create_user(); + $this->setUser($user2); + + $this->assertEquals($category1->id, coursecat::get($category1->id, MUST_EXIST, false, $user1)->id); + $this->assertEquals($category2->id, coursecat::get($category2->id, MUST_EXIST, false, $user1)->id); + + $this->setUser($user1); + + $this->assertEquals($category1->id, coursecat::get($category1->id, MUST_EXIST, false, $user2)->id); + $this->expectException('moodle_exception'); + $this->expectExceptionMessage('unknowncategory'); + coursecat::get($category2->id, MUST_EXIST, false, $user2); + } + /** * Creates a draft area for current user and fills it with fake files * diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 40b424b3378..3d33af04334 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -6,6 +6,8 @@ information provided here is intended especially for developers. * Custom AJAX handlers for the form autocomplete fields can now optionally return string in their processResults() callback. If a string is returned, it is displayed instead of the list if suggested items. This can be used, for example, to inform the user that there are too many items matching the current search criteria. +* coursecat::get() now has optional $user parameter. +* coursecat::is_uservisible() now has optional $user parameter. === 3.5 ===