From 01f7456a96cfe35dc126828fa087fee261649dbb Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 10 Jul 2024 12:06:49 +0800 Subject: [PATCH] MDL-82427 core_filters: Final deprecation of text_filtering_hash --- .upgradenotes/MDL-82427-2024071003570291.yml | 7 + filter/classes/filter_manager.php | 8 - filter/classes/null_filter_manager.php | 10 - filter/classes/text_filter.php | 7 - .../get_available_in_context_test.php | 257 ++++++++++++++++++ 5 files changed, 264 insertions(+), 25 deletions(-) create mode 100644 .upgradenotes/MDL-82427-2024071003570291.yml create mode 100644 filter/tests/external/get_available_in_context_test.php diff --git a/.upgradenotes/MDL-82427-2024071003570291.yml b/.upgradenotes/MDL-82427-2024071003570291.yml new file mode 100644 index 00000000000..1819f8dbb45 --- /dev/null +++ b/.upgradenotes/MDL-82427-2024071003570291.yml @@ -0,0 +1,7 @@ +issueNumber: MDL-82427 +notes: + core_filters: + - message: >- + The `filter_manager::text_filtering_hash` method has been finally + deprecated and removed. + type: deprecated diff --git a/filter/classes/filter_manager.php b/filter/classes/filter_manager.php index e0febc60507..615c52d1d80 100644 --- a/filter/classes/filter_manager.php +++ b/filter/classes/filter_manager.php @@ -18,7 +18,6 @@ namespace core_filters; use core\context; use core\context\system as context_system; -use core\exception\coding_exception; use moodle_page; /** @@ -233,13 +232,6 @@ class filter_manager { return $this->apply_filter_chain($string, $this->get_string_filters($context), ['stage' => 'string']); } - /** - * @deprecated Since Moodle 3.0 MDL-50491. This was used by the old text filtering system, but no more. - */ - public function text_filtering_hash() { - throw new coding_exception('filter_manager::text_filtering_hash() can not be used any more'); - } - /** * Setup page with filters requirements and other prepare stuff. * diff --git a/filter/classes/null_filter_manager.php b/filter/classes/null_filter_manager.php index 6accad67def..018be83f4d2 100644 --- a/filter/classes/null_filter_manager.php +++ b/filter/classes/null_filter_manager.php @@ -17,7 +17,6 @@ namespace core_filters; use core\context; -use core\exception\coding_exception; /** * Filter manager subclass that does nothing. Having this simplifies the logic @@ -52,15 +51,6 @@ class null_filter_manager { public function filter_string($string, $context) { return $string; } - - /** - * As for the equivalent {@link filter_manager} method. - * - * @deprecated Since Moodle 3.0 MDL-50491. - */ - public function text_filtering_hash() { - throw new coding_exception('filter_manager::text_filtering_hash() can not be used any more'); - } } // Alias this class to the old name. diff --git a/filter/classes/text_filter.php b/filter/classes/text_filter.php index ab08c9e660d..f9914a3d91d 100644 --- a/filter/classes/text_filter.php +++ b/filter/classes/text_filter.php @@ -46,13 +46,6 @@ abstract class text_filter { $this->localconfig = $localconfig; } - /** - * @deprecated Since Moodle 3.0 MDL-50491. This was used by the old text filtering system, but no more. - */ - public function hash() { - throw new coding_exception('moodle_text_filter::hash() can not be used any more'); - } - /** * Setup page with filter requirements and other prepare stuff. * diff --git a/filter/tests/external/get_available_in_context_test.php b/filter/tests/external/get_available_in_context_test.php new file mode 100644 index 00000000000..95792d10b5c --- /dev/null +++ b/filter/tests/external/get_available_in_context_test.php @@ -0,0 +1,257 @@ +. + +/** + * External filter functions unit tests. + * + * @package core_filters + * @category external + * @copyright 2017 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 3.4 + */ + +namespace core_filters\external; + +use core_external\external_api; +use externallib_advanced_testcase; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; + +require_once($CFG->dirroot . '/webservice/tests/helpers.php'); + +/** + * External filter functions unit tests. + * + * @package core_filters + * @category external + * @copyright 2017 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 3.4 + * @covers \core_filters\external\get_available_in_context + */ +final class get_available_in_context_test extends externallib_advanced_testcase { + /** + * Test execute + */ + public function test_get_available_in_context_system(): void { + global $DB; + + $this->resetAfterTest(true); + $this->setAdminUser(); + + $this->expectException('moodle_exception'); + get_available_in_context::execute(array(array('contextlevel' => 'system', 'instanceid' => 0))); + } + + /** + * Test get_available_in_context_category + */ + public function test_get_available_in_context_category(): void { + global $DB; + + $this->resetAfterTest(true); + $this->setAdminUser(); + + $category = self::getDataGenerator()->create_category(); + + // Get all filters and disable them all globally. + $allfilters = filter_get_all_installed(); + foreach ($allfilters as $filter => $filtername) { + filter_set_global_state($filter, TEXTFILTER_DISABLED); + } + + $result = get_available_in_context::execute(array(array('contextlevel' => 'coursecat', 'instanceid' => $category->id))); + $result = external_api::clean_returnvalue(get_available_in_context::execute_returns(), $result); + $this->assertEmpty($result['filters']); // No filters, all disabled. + $this->assertEmpty($result['warnings']); + + // Enable one filter at global level. + reset($allfilters); + $firstfilter = key($allfilters); + filter_set_global_state($firstfilter, TEXTFILTER_ON); + + $result = get_available_in_context::execute(array(array('contextlevel' => 'coursecat', 'instanceid' => $category->id))); + $result = external_api::clean_returnvalue(get_available_in_context::execute_returns(), $result); + $this->assertEmpty($result['warnings']); + $this->assertEquals($firstfilter, $result['filters'][0]['filter']); // OK, the filter is enabled. + $this->assertEquals(TEXTFILTER_INHERIT, $result['filters'][0]['localstate']); // Inherits the parent context status. + $this->assertEquals(TEXTFILTER_ON, $result['filters'][0]['inheritedstate']); // In the parent context is available. + + // Set off the same filter at local context level. + filter_set_local_state($firstfilter, \context_coursecat::instance($category->id)->id, TEXTFILTER_OFF); + $result = get_available_in_context::execute(array(array('contextlevel' => 'coursecat', 'instanceid' => $category->id))); + $result = external_api::clean_returnvalue(get_available_in_context::execute_returns(), $result); + $this->assertEmpty($result['warnings']); + $this->assertEquals($firstfilter, $result['filters'][0]['filter']); // OK, the filter is enabled globally. + $this->assertEquals(TEXTFILTER_OFF, $result['filters'][0]['localstate']); // It is not available in this context. + $this->assertEquals(TEXTFILTER_ON, $result['filters'][0]['inheritedstate']); // In the parent context is available. + } + + /** + * Test get_available_in_context_course + */ + public function test_get_available_in_context_course(): void { + global $DB; + + $this->resetAfterTest(true); + $this->setAdminUser(); + + $course = self::getDataGenerator()->create_course(); + + // Get all filters and disable them all globally. + $allfilters = filter_get_all_installed(); + foreach ($allfilters as $filter => $filtername) { + filter_set_global_state($filter, TEXTFILTER_DISABLED); + } + + $result = get_available_in_context::execute(array(array('contextlevel' => 'course', 'instanceid' => $course->id))); + $result = external_api::clean_returnvalue(get_available_in_context::execute_returns(), $result); + $this->assertEmpty($result['filters']); // No filters, all disabled at global level. + $this->assertEmpty($result['warnings']); + + // Enable one filter at global level. + reset($allfilters); + $firstfilter = key($allfilters); + filter_set_global_state($firstfilter, TEXTFILTER_ON); + + $result = get_available_in_context::execute(array(array('contextlevel' => 'course', 'instanceid' => $course->id))); + $result = external_api::clean_returnvalue(get_available_in_context::execute_returns(), $result); + $this->assertEmpty($result['warnings']); + $this->assertEquals($firstfilter, $result['filters'][0]['filter']); // OK, the filter is enabled. + $this->assertEquals(TEXTFILTER_INHERIT, $result['filters'][0]['localstate']); // Inherits the parent context status. + $this->assertEquals(TEXTFILTER_ON, $result['filters'][0]['inheritedstate']); // In the parent context is available. + + // Set off the same filter at local context level. + filter_set_local_state($firstfilter, \context_course::instance($course->id)->id, TEXTFILTER_OFF); + $result = get_available_in_context::execute(array(array('contextlevel' => 'course', 'instanceid' => $course->id))); + $result = external_api::clean_returnvalue(get_available_in_context::execute_returns(), $result); + $this->assertEmpty($result['warnings']); + $this->assertEquals($firstfilter, $result['filters'][0]['filter']); // OK, the filter is enabled globally. + $this->assertEquals(TEXTFILTER_OFF, $result['filters'][0]['localstate']); // It is not available in this context. + $this->assertEquals(TEXTFILTER_ON, $result['filters'][0]['inheritedstate']); // In the parent context is available. + } + + /** + * Test get_available_in_context_module + */ + public function test_get_available_in_context_module(): void { + global $DB; + + $this->resetAfterTest(true); + $this->setAdminUser(); + + // Create one activity. + $course = self::getDataGenerator()->create_course(); + $forum = self::getDataGenerator()->create_module('forum', (object) array('course' => $course->id)); + + // Get all filters and disable them all globally. + $allfilters = filter_get_all_installed(); + foreach ($allfilters as $filter => $filtername) { + filter_set_global_state($filter, TEXTFILTER_DISABLED); + } + + $result = get_available_in_context::execute(array(array('contextlevel' => 'module', 'instanceid' => $forum->cmid))); + $result = external_api::clean_returnvalue(get_available_in_context::execute_returns(), $result); + $this->assertEmpty($result['filters']); // No filters, all disabled at global level. + $this->assertEmpty($result['warnings']); + + // Enable one filter at global level. + reset($allfilters); + $firstfilter = key($allfilters); + filter_set_global_state($firstfilter, TEXTFILTER_ON); + + $result = get_available_in_context::execute(array(array('contextlevel' => 'module', 'instanceid' => $forum->cmid))); + $result = external_api::clean_returnvalue(get_available_in_context::execute_returns(), $result); + $this->assertEmpty($result['warnings']); + $this->assertEquals($firstfilter, $result['filters'][0]['filter']); // OK, the filter is enabled. + $this->assertEquals(TEXTFILTER_INHERIT, $result['filters'][0]['localstate']); // Inherits the parent context status. + $this->assertEquals(TEXTFILTER_ON, $result['filters'][0]['inheritedstate']); // In the parent context is available. + + // Set off the same filter at local context level. + filter_set_local_state($firstfilter, \context_module::instance($forum->cmid)->id, TEXTFILTER_OFF); + $result = get_available_in_context::execute(array(array('contextlevel' => 'module', 'instanceid' => $forum->cmid))); + $result = external_api::clean_returnvalue(get_available_in_context::execute_returns(), $result); + $this->assertEmpty($result['warnings']); + $this->assertEquals($firstfilter, $result['filters'][0]['filter']); // OK, the filter is enabled globally. + $this->assertEquals(TEXTFILTER_OFF, $result['filters'][0]['localstate']); // It is not available in this context. + $this->assertEquals(TEXTFILTER_ON, $result['filters'][0]['inheritedstate']); // In the parent context is available. + + // Try user without permission, warning expected. + $user = $this->getDataGenerator()->create_user(); + $this->setUser($user); + $result = get_available_in_context::execute(array(array('contextlevel' => 'module', 'instanceid' => $forum->cmid))); + $result = external_api::clean_returnvalue(get_available_in_context::execute_returns(), $result); + $this->assertNotEmpty($result['warnings']); + $this->assertEquals('context', $result['warnings'][0]['item']); + $this->assertEquals($forum->cmid, $result['warnings'][0]['itemid']); + } + + /** + * Test get_all_states + * @covers \core_filters\external\get_all_states::execute + */ + public function test_get_all_states(): void { + $this->resetAfterTest(true); + $this->setAdminUser(); + + // Get all filters and disable them all globally except for the first. + $allfilters = filter_get_all_installed(); + reset($allfilters); + $firstfilter = key($allfilters); + foreach ($allfilters as $filter => $filterdata) { + if ($filter == $firstfilter) { + filter_set_global_state($filter, TEXTFILTER_ON); + continue; + } + filter_set_global_state($filter, TEXTFILTER_DISABLED); + } + + // Set some filters at particular levels. + $course = self::getDataGenerator()->create_course(); + filter_set_local_state($firstfilter, \context_course::instance($course->id)->id, TEXTFILTER_ON); + $forum = self::getDataGenerator()->create_module('forum', (object) ['course' => $course->id]); + filter_set_local_state($firstfilter, \context_module::instance($forum->cmid)->id, TEXTFILTER_OFF); + + $result = get_all_states::execute(); + $result = external_api::clean_returnvalue(get_all_states::execute_returns(), $result); + + $totalcount = count($allfilters) + 2; // All filters plus two local states. + $this->assertCount($totalcount, $result['filters']); + + $customfound = 0; + foreach ($result['filters'] as $filter) { + if ($filter['contextlevel'] == 'course' && $filter['instanceid'] == $course->id) { + $this->assertEquals($firstfilter, $filter['filter']); + $this->assertEquals(TEXTFILTER_ON, $filter['state']); + $customfound++; + } else if ($filter['contextlevel'] == 'module' && $filter['instanceid'] == $forum->cmid) { + $this->assertEquals($firstfilter, $filter['filter']); + $this->assertEquals(TEXTFILTER_OFF, $filter['state']); + $customfound++; + } else if ($filter['filter'] == $firstfilter) { + $this->assertEquals($firstfilter, $filter['filter']); + $this->assertEquals(TEXTFILTER_ON, $filter['state']); + $this->assertEquals(1, $filter['sortorder']); + } else { + $this->assertEquals(TEXTFILTER_DISABLED, $filter['state']); + } + } + $this->assertEquals(2, $customfound); // Both custom states found. + } +}