diff --git a/calendar/lib.php b/calendar/lib.php index 5376d8f4601..c675c658617 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -2956,6 +2956,14 @@ function calendar_add_subscription($sub) { if (empty($sub->id)) { $id = $DB->insert_record('event_subscriptions', $sub); // we cannot cache the data here because $sub is not complete. + $sub->id = $id; + // Trigger event, calendar subscription added. + $eventparams = array('objectid' => $sub->id, + 'context' => calendar_get_calendar_context($sub), + 'other' => array('eventtype' => $sub->eventtype, 'courseid' => $sub->courseid) + ); + $event = \core\event\calendar_subscription_created::create($eventparams); + $event->trigger(); return $id; } else { // Why are we doing an update here? @@ -3112,13 +3120,21 @@ function calendar_process_subscription_row($subscriptionid, $pollinterval, $acti function calendar_delete_subscription($subscription) { global $DB; - if (is_object($subscription)) { - $subscription = $subscription->id; + if (!is_object($subscription)) { + $subscription = $DB->get_record('event_subscriptions', array('id' => $subscription), '*', MUST_EXIST); } // Delete subscription and related events. - $DB->delete_records('event', array('subscriptionid' => $subscription)); - $DB->delete_records('event_subscriptions', array('id' => $subscription)); - cache_helper::invalidate_by_definition('core', 'calendar_subscriptions', array(), array($subscription)); + $DB->delete_records('event', array('subscriptionid' => $subscription->id)); + $DB->delete_records('event_subscriptions', array('id' => $subscription->id)); + cache_helper::invalidate_by_definition('core', 'calendar_subscriptions', array(), array($subscription->id)); + + // Trigger event, calendar subscription deleted. + $eventparams = array('objectid' => $subscription->id, + 'context' => calendar_get_calendar_context($subscription), + 'other' => array('courseid' => $subscription->courseid) + ); + $event = \core\event\calendar_subscription_deleted::create($eventparams); + $event->trigger(); } /** * From a URL, fetch the calendar and return an iCalendar object. @@ -3246,6 +3262,14 @@ function calendar_update_subscription($subscription) { // Update cache. $cache = cache::make('core', 'calendar_subscriptions'); $cache->set($subscription->id, $subscription); + // Trigger event, calendar subscription updated. + $eventparams = array('userid' => $subscription->userid, + 'objectid' => $subscription->id, + 'context' => calendar_get_calendar_context($subscription), + 'other' => array('eventtype' => $subscription->eventtype, 'courseid' => $subscription->courseid) + ); + $event = \core\event\calendar_subscription_updated::create($eventparams); + $event->trigger(); } /** @@ -3320,3 +3344,23 @@ function calendar_cron() { return true; } + +/** + * Helper function to determine the context of a calendar subscription. + * Subscriptions can be created in two contexts COURSE, or USER. + * + * @param stdClass $subscription + * @return context instance + */ +function calendar_get_calendar_context($subscription) { + + // Determine context based on calendar type. + if ($subscription->eventtype === 'site') { + $context = context_course::instance(SITEID); + } else if ($subscription->eventtype === 'group' || $subscription->eventtype === 'course') { + $context = context_course::instance($subscription->courseid); + } else { + $context = context_user::instance($subscription->userid); + } + return $context; +} diff --git a/calendar/tests/events_test.php b/calendar/tests/events_test.php index a0b39680569..207d66a6a4f 100644 --- a/calendar/tests/events_test.php +++ b/calendar/tests/events_test.php @@ -386,4 +386,95 @@ class core_calendar_events_testcase extends advanced_testcase { $this->assertContains('The \'timestart\' value must be set in other.', $e->getMessage()); } } + + /** + * Tests for calendar_subscription_added event. + */ + public function test_calendar_subscription_created() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'site'; + $subscription->name = 'test'; + $subscription->courseid = $this->course->id; + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + $id = calendar_add_subscription($subscription); + + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_created', $event); + $this->assertEquals($id, $event->objectid); + $this->assertEquals($subscription->courseid, $event->other['courseid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertDebuggingNotCalled(); + $sink->close(); + + } + + /** + * Tests for calendar_subscription_updated event. + */ + public function test_calendar_subscription_updated() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'site'; + $subscription->name = 'test'; + $subscription->courseid = $this->course->id; + $subscription->id = calendar_add_subscription($subscription); + // Now edit it. + $subscription->name = 'awesome'; + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + calendar_update_subscription($subscription); + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_updated', $event); + $this->assertEquals($subscription->id, $event->objectid); + $this->assertEquals($subscription->courseid, $event->other['courseid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertDebuggingNotCalled(); + $sink->close(); + + } + + /** + * Tests for calendar_subscription_deleted event. + */ + public function test_calendar_subscription_deleted() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'site'; + $subscription->name = 'test'; + $subscription->courseid = $this->course->id; + $subscription->id = calendar_add_subscription($subscription); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + calendar_delete_subscription($subscription); + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_deleted', $event); + $this->assertEquals($subscription->id, $event->objectid); + $this->assertEquals($subscription->courseid, $event->other['courseid']); + $this->assertDebuggingNotCalled(); + $sink->close(); + + } } diff --git a/calendar/tests/ical_test.php b/calendar/tests/ical_test.php index 2fc3c02b68c..d2223b538c2 100644 --- a/calendar/tests/ical_test.php +++ b/calendar/tests/ical_test.php @@ -57,14 +57,14 @@ class core_calendar_ical_testcase extends advanced_testcase { $id = calendar_add_subscription($subscription); $subscription = new stdClass(); - $subscription->id = $id; + $subscription = calendar_get_subscription($id); $subscription->name = 'awesome'; calendar_update_subscription($subscription); $sub = calendar_get_subscription($id); $this->assertEquals($subscription->name, $sub->name); $subscription = new stdClass(); - $subscription->id = $id; + $subscription = calendar_get_subscription($id); $subscription->name = 'awesome2'; $subscription->pollinterval = 604800; calendar_update_subscription($subscription); diff --git a/lang/en/calendar.php b/lang/en/calendar.php index 98583927982..f85bb34a59e 100644 --- a/lang/en/calendar.php +++ b/lang/en/calendar.php @@ -95,6 +95,9 @@ $string['eventview'] = 'Event details'; $string['eventcalendareventcreated'] = 'Calendar event created'; $string['eventcalendareventupdated'] = 'Calendar event updated'; $string['eventcalendareventdeleted'] = 'Calendar event deleted'; +$string['eventsubscriptioncreated'] = 'Calendar subscription created'; +$string['eventsubscriptionupdated'] = 'Calendar subscription updated'; +$string['eventsubscriptiondeleted'] = 'Calendar subscription deleted'; $string['expired'] = 'Expired'; $string['explain_site_timeformat'] = 'You can choose to see times in either 12 or 24 hour format for the whole site. If you choose "default", then the format will be automatically chosen according to the language you use in the site. This setting can be overridden by user preferences.'; $string['export'] = 'Export'; diff --git a/lib/classes/event/calendar_subscription_created.php b/lib/classes/event/calendar_subscription_created.php new file mode 100644 index 00000000000..4b2c6502cab --- /dev/null +++ b/lib/classes/event/calendar_subscription_created.php @@ -0,0 +1,119 @@ +. + +/** + * calendar subscription added event. + * + * @package core + * @copyright 2016 Stephen Bourget + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * Event triggered after a calendar subscription is added. + * + * @property-read array $other { + * Extra information about the event. + * + * - string eventtype: the type of events (site, course, group, user). + * - int courseid: The ID of the course (SITEID, User(0) or actual course) + * } + * + * @package core + * @since Moodle 3.2 + * @copyright 2016 Stephen Bourget + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class calendar_subscription_created extends base +{ + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'c'; + $this->data['edulevel'] = self::LEVEL_OTHER; + $this->data['objecttable'] = 'event_subscriptions'; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventsubscriptioncreated', 'calendar'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "User {$this->userid} has added a calendar + subscription with id {$this->objectid} of event type {$this->other['eventtype']}."; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + if (($this->other['courseid'] == SITEID) || ($this->other['courseid'] == 0)) { + return new \moodle_url('calendar/managesubscriptions.php'); + } else { + return new \moodle_url('calendar/managesubscriptions.php', array('course' => $this->other['courseid'])); + } + } + + /** + * Custom validations. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + if (!isset($this->context)) { + throw new \coding_exception('The \'context\' must be set.'); + } + if (!isset($this->objectid)) { + throw new \coding_exception('The \'objectid\' must be set.'); + } + if (!isset($this->other['eventtype'])) { + throw new \coding_exception('The \'eventtype\' value must be set in other.'); + } + if (!isset($this->other['courseid'])) { + throw new \coding_exception('The \'courseid\' value must be set in other.'); + } + } + + /** + * Returns mappings for restore + * + * @return array + */ + public static function get_objectid_mapping() { + return array('db' => 'event_subscriptions', 'restore' => 'event_subscriptions'); + } +} diff --git a/lib/classes/event/calendar_subscription_deleted.php b/lib/classes/event/calendar_subscription_deleted.php new file mode 100644 index 00000000000..0f7ab2ae997 --- /dev/null +++ b/lib/classes/event/calendar_subscription_deleted.php @@ -0,0 +1,115 @@ +. + +/** + * calendar subscription deleted event. + * + * @package core + * @copyright 2016 Stephen Bourget + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * Event triggered after a calendar subscription is deleted. + * + * @property-read array $other { + * Extra information about the event. + * + * - int courseid: The ID of the course (SITEID, User(0) or actual course) + * } + * + * @package core + * @since Moodle 3.2 + * @copyright 2016 Stephen Bourget + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class calendar_subscription_deleted extends base +{ + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'd'; + $this->data['edulevel'] = self::LEVEL_OTHER; + $this->data['objecttable'] = 'event_subscriptions'; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventsubscriptiondeleted', 'calendar'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "User {$this->userid} has deleted a calendar + subscription with id {$this->objectid}."; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + if (($this->other['courseid'] == SITEID) || ($this->other['courseid'] == 0)) { + return new \moodle_url('calendar/managesubscriptions.php'); + } else { + return new \moodle_url('calendar/managesubscriptions.php', array('course' => $this->other['courseid'])); + } + } + + /** + * Custom validations. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + if (!isset($this->context)) { + throw new \coding_exception('The \'context\' must be set.'); + } + if (!isset($this->objectid)) { + throw new \coding_exception('The \'objectid\' must be set.'); + } + if (!isset($this->other['courseid'])) { + throw new \coding_exception('The \'courseid\' value must be set in other.'); + } + } + + /** + * Returns mappings for restore + * + * @return array + */ + public static function get_objectid_mapping() { + return array('db' => 'event_subscriptions', 'restore' => 'event_subscriptions'); + } +} diff --git a/lib/classes/event/calendar_subscription_updated.php b/lib/classes/event/calendar_subscription_updated.php new file mode 100644 index 00000000000..eb610338e35 --- /dev/null +++ b/lib/classes/event/calendar_subscription_updated.php @@ -0,0 +1,119 @@ +. + +/** + * calendar subscription updated event. + * + * @package core + * @copyright 2016 Stephen Bourget + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * Event triggered after a calendar subscription is updated. + * + * @property-read array $other { + * Extra information about the event. + * + * - string eventtype: the type of events (site, course, group, user). + * - int courseid: The ID of the course (SITEID, User(0) or actual course) + * } + * + * @package core + * @since Moodle 3.2 + * @copyright 2016 Stephen Bourget + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class calendar_subscription_updated extends base +{ + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'u'; + $this->data['edulevel'] = self::LEVEL_OTHER; + $this->data['objecttable'] = 'event_subscriptions'; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventsubscriptionupdated', 'calendar'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "User {$this->userid} has updated a calendar + subscription with id {$this->objectid} of event type {$this->other['eventtype']}."; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + if (($this->other['courseid'] == SITEID) || ($this->other['courseid'] == 0)) { + return new \moodle_url('calendar/managesubscriptions.php'); + } else { + return new \moodle_url('calendar/managesubscriptions.php', array('course' => $this->other['courseid'])); + } + } + + /** + * Custom validations. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + if (!isset($this->context)) { + throw new \coding_exception('The \'context\' must be set.'); + } + if (!isset($this->objectid)) { + throw new \coding_exception('The \'objectid\' must be set.'); + } + if (!isset($this->other['eventtype'])) { + throw new \coding_exception('The \'eventtype\' value must be set in other.'); + } + if (!isset($this->other['courseid'])) { + throw new \coding_exception('The \'courseid\' value must be set in other.'); + } + } + + /** + * Returns mappings for restore + * + * @return array + */ + public static function get_objectid_mapping() { + return array('db' => 'event_subscriptions', 'restore' => 'event_subscriptions'); + } +} diff --git a/version.php b/version.php index 833749db8df..8d9fe81bb09 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2016080200.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2016080200.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.