From 3aa7b0df78f358f97829d74685887876c48e60c7 Mon Sep 17 00:00:00 2001 From: Neill Magill Date: Fri, 9 Aug 2019 11:27:40 +0100 Subject: [PATCH 1/2] MDL-65443 core: Log when a context is locked or unlocked --- lang/en/access.php | 2 + lib/accesslib.php | 9 ++ lib/classes/event/context_locked.php | 85 ++++++++++++++++++ lib/classes/event/context_unlocked.php | 85 ++++++++++++++++++ lib/tests/event_context_locked_test.php | 109 ++++++++++++++++++++++++ 5 files changed, 290 insertions(+) create mode 100644 lib/classes/event/context_locked.php create mode 100644 lib/classes/event/context_unlocked.php create mode 100644 lib/tests/event_context_locked_test.php diff --git a/lang/en/access.php b/lang/en/access.php index 6fe361641fe..ae8e241fb74 100644 --- a/lang/en/access.php +++ b/lang/en/access.php @@ -29,6 +29,8 @@ $string['accessstatement'] = 'Accessibility statement'; $string['activitynext'] = 'Next activity'; $string['activityprev'] = 'Previous activity'; $string['breadcrumb'] = 'Navigation bar'; +$string['eventcontextlocked'] = 'Context frozen'; +$string['eventcontextunlocked'] = 'Context unfrozen'; $string['hideblocka'] = 'Hide {$a} block'; $string['showblocka'] = 'Show {$a} block'; $string['sitemap'] = 'Site map'; diff --git a/lib/accesslib.php b/lib/accesslib.php index e80ba19c445..b3f9a41356c 100644 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -5254,6 +5254,15 @@ abstract class context extends stdClass implements IteratorAggregate { $this->_locked = $locked; $DB->set_field('context', 'locked', (int) $locked, ['id' => $this->id]); $this->mark_dirty(); + + if ($locked) { + $eventname = '\\core\\event\\context_locked'; + } else { + $eventname = '\\core\\event\\context_unlocked'; + } + $event = $eventname::create(['context' => $this, 'objectid' => $this->id]); + $event->trigger(); + self::reset_caches(); return $this; diff --git a/lib/classes/event/context_locked.php b/lib/classes/event/context_locked.php new file mode 100644 index 00000000000..1ea9b64d293 --- /dev/null +++ b/lib/classes/event/context_locked.php @@ -0,0 +1,85 @@ +. + +/** + * Context locked event. + * + * @package core_access + * @copyright 2019 University of Nottingham + * @author Neill Magill + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core\event; + +defined('MOODLE_INTERNAL') || die(); + +/** + * Context locked event class. + * + * @package core_access + * @since Moodle 3.8 + * @copyright 2019 University of Nottingham + * @author Neill Magill + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class context_locked extends base { + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The user with id '$this->userid' locked the context with id '$this->objectid' "; + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventcontextlocked', 'access'); + } + + /** + * Get URL related to the action + * + * @return \moodle_url + */ + public function get_url() { + // Try to get the url for the context. + try { + $context = \context::instance_by_id($this->objectid); + $url = $context->get_url(); + } catch (\dml_missing_record_exception $e) { + // The context no longer exists, give them the system url instead. + $url = \context_system::instance()->get_url(); + } + return $url; + } + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'u'; + $this->data['edulevel'] = self::LEVEL_OTHER; + $this->data['objecttable'] = 'context'; + } +} diff --git a/lib/classes/event/context_unlocked.php b/lib/classes/event/context_unlocked.php new file mode 100644 index 00000000000..855a2f2b51e --- /dev/null +++ b/lib/classes/event/context_unlocked.php @@ -0,0 +1,85 @@ +. + +/** + * Context unlocked event. + * + * @package core_access + * @copyright 2019 University of Nottingham + * @author Neill Magill + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core\event; + +defined('MOODLE_INTERNAL') || die(); + +/** + * Context locked event class. + * + * @package core_access + * @since Moodle 3.8 + * @copyright 2019 University of Nottingham + * @author Neill Magill + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class context_unlocked extends base { + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The user with id '$this->userid' unlocked the context with id '$this->objectid' "; + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventcontextunlocked', 'access'); + } + + /** + * Get URL related to the action + * + * @return \moodle_url + */ + public function get_url() { + // Try to get the url for the context. + try { + $context = \context::instance_by_id($this->objectid); + $url = $context->get_url(); + } catch (\dml_missing_record_exception $e) { + // The context no longer exists, give them the system url instead. + $url = \context_system::instance()->get_url(); + } + return $url; + } + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'u'; + $this->data['edulevel'] = self::LEVEL_OTHER; + $this->data['objecttable'] = 'context'; + } +} diff --git a/lib/tests/event_context_locked_test.php b/lib/tests/event_context_locked_test.php new file mode 100644 index 00000000000..2a7a43532c8 --- /dev/null +++ b/lib/tests/event_context_locked_test.php @@ -0,0 +1,109 @@ +. + +/** + * Unit tests for the context locking events. + * + * @package core + * @category test + * @copyright 2019 University of Nottingham + * @author Neill Magill + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use core\event\context_locked; +use core\event\context_unlocked; + +defined('MOODLE_INTERNAL') || die(); + +/** + * Unit tests for the context_locked and context_unlocked events. + * + * @package core + * @category test + * @copyright 2019 University of Nottingham + * @author Neill Magill + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_event_context_locked_testcase extends \advanced_testcase { + /** + * Locks an unlocked context and checks that a core\event\context_locked event is created. + * + * @param \context $context + */ + protected function lock_context(\context $context) { + self::assertFalse($context->is_locked()); + + $locksink = $this->redirectEvents(); + $context->set_locked(true); + // This second call should not create an event as the lock status has not changed. + $context->set_locked(true); + $lockevents = $locksink->get_events(); + $locksink->close(); + + self::assertCount(1, $lockevents); + self::assertContainsOnlyInstancesOf('core\event\context_locked', $lockevents); + self::assertEquals($context->id, $lockevents[0]->objectid); + $this->assertSame('context', $lockevents[0]->objecttable); + $this->assertEquals($context, $lockevents[0]->get_context()); + } + + /** + * Tests that events are created when contexts are locked and unlocked. + */ + public function test_creation() { + $this->resetAfterTest(); + + $category = self::getDataGenerator()->create_category(); + $catcontext = \context_coursecat::instance($category->id); + $course = self::getDataGenerator()->create_course(['category' => $category->id]); + $coursecontext = \context_course::instance($course->id); + $activitygenerator = self::getDataGenerator()->get_plugin_generator('mod_forum'); + $activity = $activitygenerator->create_instance(['course' => $course->id]); + $activitycontext = \context_module::instance($activity->cmid); + + $this->lock_context($catcontext); + $this->unlock_context($catcontext); + + $this->lock_context($coursecontext); + $this->unlock_context($coursecontext); + + $this->lock_context($activitycontext); + $this->unlock_context($activitycontext); + } + + /** + * Unlocks a locked context and checks that a core\event\context_unlocked event is created. + * + * @param \context $context + */ + protected function unlock_context(\context $context) { + self::assertTrue($context->is_locked()); + + $unlocksink = $this->redirectEvents(); + $context->set_locked(false); + // This second call should not create an event as the lock status has not changed. + $context->set_locked(false); + $unlockevents = $unlocksink->get_events(); + $unlocksink->close(); + + self::assertCount(1, $unlockevents); + self::assertContainsOnlyInstancesOf('core\event\context_unlocked', $unlockevents); + self::assertEquals($context->id, $unlockevents[0]->objectid); + $this->assertSame('context', $unlockevents[0]->objecttable); + $this->assertEquals($context, $unlockevents[0]->get_context()); + } +} From 8b0bf17160d99d54e9c38904f30d818f43f054a0 Mon Sep 17 00:00:00 2001 From: Neill Magill Date: Wed, 21 Aug 2019 09:02:03 +0100 Subject: [PATCH 2/2] MDL-65443 core: Improve class descriptions for locking events --- lib/classes/event/context_locked.php | 2 +- lib/classes/event/context_unlocked.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/classes/event/context_locked.php b/lib/classes/event/context_locked.php index 1ea9b64d293..f4bf9904c0b 100644 --- a/lib/classes/event/context_locked.php +++ b/lib/classes/event/context_locked.php @@ -28,7 +28,7 @@ namespace core\event; defined('MOODLE_INTERNAL') || die(); /** - * Context locked event class. + * Event triggered after a context has been frozen. * * @package core_access * @since Moodle 3.8 diff --git a/lib/classes/event/context_unlocked.php b/lib/classes/event/context_unlocked.php index 855a2f2b51e..92e6ece1c5c 100644 --- a/lib/classes/event/context_unlocked.php +++ b/lib/classes/event/context_unlocked.php @@ -28,7 +28,7 @@ namespace core\event; defined('MOODLE_INTERNAL') || die(); /** - * Context locked event class. + * Event triggered after a context has been unfrozen. * * @package core_access * @since Moodle 3.8