From c6fb9310882101090ee030bfdd08ae569e8097f8 Mon Sep 17 00:00:00 2001 From: Ryan Wyllie Date: Thu, 17 Aug 2017 06:26:37 +0000 Subject: [PATCH] MDL-59393 calendar: add update_event_start_day external function --- calendar/externallib.php | 69 +++++++++++++++++++++++++ calendar/tests/externallib_test.php | 80 +++++++++++++++++++++++++++++ lib/db/services.php | 9 ++++ version.php | 2 +- 4 files changed, 159 insertions(+), 1 deletion(-) diff --git a/calendar/externallib.php b/calendar/externallib.php index b8ba417c083..b7f7e55856d 100644 --- a/calendar/externallib.php +++ b/calendar/externallib.php @@ -906,4 +906,73 @@ class core_calendar_external extends external_api { public static function get_calendar_monthly_view_returns() { return \core_calendar\external\month_exporter::get_read_structure(); } + + /** + * Returns description of method parameters. + * + * @return external_function_parameters + */ + public static function update_event_start_day_parameters() { + return new external_function_parameters( + [ + 'eventId' => new external_value(PARAM_INT, 'Id of event to be updated', VALUE_REQUIRED), + 'dayTimestamp' => new external_value(PARAM_INT, 'Timestamp for the new start day', VALUE_REQUIRED), + ] + ); + } + + /** + * Change the start day for the given calendar event to the day that + * corresponds with the provided timestamp. + * + * The timestamp only needs to be anytime within the desired day as only + * the date data is extracted from it. + * + * The event's original time of day is maintained, only the date is shifted. + * + * @param int $eventId Id of event to be updated + * @param int $dayTimestamp Timestamp for the new start day + * @return array + */ + public static function update_event_start_day($eventId, $dayTimestamp) { + global $USER, $PAGE; + + // Parameter validation. + $params = self::validate_parameters(self::update_event_start_day_parameters(), [ + 'eventId' => $eventId, + 'dayTimestamp' => $dayTimestamp, + ]); + + $context = \context_user::instance($USER->id); + self::validate_context($context); + + $vault = event_container::get_event_vault(); + $event = $vault->get_event_by_id($eventId); + $newdate = usergetdate($dayTimestamp); + $startdatestring = implode('-', [$newdate['year'], $newdate['mon'], $newdate['mday']]); + $startdate = new DateTimeImmutable($startdatestring); + $event = local_api::update_event_start_day($event, $startdate); + $cache = new events_related_objects_cache([$event]); + $relatedobjects = [ + 'context' => $cache->get_context($event), + 'course' => $cache->get_course($event), + ]; + $exporter = new event_exporter($event, $relatedobjects); + $renderer = $PAGE->get_renderer('core_calendar'); + + return array('event' => $exporter->export($renderer)); + } + + /** + * Returns description of method result value. + * + * @return external_description + */ + public static function update_event_start_day_returns() { + return new external_single_structure( + array( + 'event' => event_exporter::get_read_structure() + ) + ); + } } diff --git a/calendar/tests/externallib_test.php b/calendar/tests/externallib_test.php index 6f2ad09b832..a1919bc091b 100644 --- a/calendar/tests/externallib_test.php +++ b/calendar/tests/externallib_test.php @@ -1290,4 +1290,84 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $this->expectException('moodle_exception'); core_calendar_external::delete_calendar_events($params); } + + /** + * Updating the event start day should change the date value but leave + * the time of day unchanged. + */ + public function test_update_event_start_day() { + $generator = $this->getDataGenerator(); + $user = $generator->create_user(); + $roleid = $generator->create_role(); + $context = \context_system::instance(); + $originalStartTime = new DateTimeImmutable('2017-01-1T15:00:00+08:00'); + $newStartDate = new DateTimeImmutable('2018-02-2T10:00:00+08:00'); + $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00'); + + $generator->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true); + + $this->setUser($user); + $this->resetAfterTest(true); + + $event = $this->create_calendar_event( + 'Test event', + $user->id, + 'user', + 0, + null, + [ + 'courseid' => 0, + 'timestart' => $originalStartTime->getTimestamp() + ] + ); + + $result = core_calendar_external::update_event_start_day($event->id, $newStartDate->getTimestamp()); + $result = external_api::clean_returnvalue( + core_calendar_external::update_event_start_day_returns(), + $result + ); + + $this->assertEquals($expected->getTimestamp(), $result['event']['timestart']); + } + + /** + * Updating the event start day should change the date value but leave + * the time of day unchanged. + */ + public function test_update_event_start_day_no_permission() { + $generator = $this->getDataGenerator(); + $user = $generator->create_user(); + $roleid = $generator->create_role(); + $context = \context_system::instance(); + $originalStartTime = new DateTimeImmutable('2017-01-1T15:00:00+08:00'); + $newStartDate = new DateTimeImmutable('2018-02-2T10:00:00+08:00'); + $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00'); + + $generator->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true); + + $this->setUser($user); + $this->resetAfterTest(true); + + $event = $this->create_calendar_event( + 'Test event', + $user->id, + 'user', + 0, + null, + [ + 'courseid' => 0, + 'timestart' => $originalStartTime->getTimestamp() + ] + ); + + assign_capability('moodle/calendar:manageownentries', CAP_PROHIBIT, $roleid, $context, true); + $this->expectException('moodle_exception'); + $result = core_calendar_external::update_event_start_day($event->id, $newStartDate->getTimestamp()); + $result = external_api::clean_returnvalue( + core_calendar_external::update_event_start_day_returns(), + $result + ); + } } diff --git a/lib/db/services.php b/lib/db/services.php index e37d54e7747..b1f29b6500f 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -68,6 +68,15 @@ $functions = array( 'ajax' => true, 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), ), + 'core_calendar_update_event_start_day' => array( + 'classname' => 'core_calendar_external', + 'methodname' => 'update_event_start_day', + 'description' => 'Update the start day (but not time) for an event.', + 'classpath' => 'calendar/externallib.php', + 'type' => 'write', + 'capabilities' => 'moodle/calendar:manageentries, moodle/calendar:manageownentries, moodle/calendar:managegroupentries', + 'ajax' => true, + ), 'core_calendar_create_calendar_events' => array( 'classname' => 'core_calendar_external', 'methodname' => 'create_calendar_events', diff --git a/version.php b/version.php index 6c1203dd80a..b63e633e85d 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2017081700.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2017082100.00; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.