diff --git a/calendar/externallib.php b/calendar/externallib.php index eccd04eb896..d7f83479954 100644 --- a/calendar/externallib.php +++ b/calendar/externallib.php @@ -1371,4 +1371,82 @@ class core_calendar_external extends external_api { ] ); } + + /** + * Convert the specified dates into unix timestamps. + * + * @param array $datetimes Array of arrays containing date time details, each in the format: + * ['year' => a, 'month' => b, 'day' => c, + * 'hour' => d (optional), 'minute' => e (optional), 'key' => 'x' (optional)] + * @return array Provided array of dates converted to unix timestamps + * @throws moodle_exception If one or more of the dates provided does not convert to a valid timestamp. + */ + public static function get_timestamps($datetimes) { + $params = self::validate_parameters(self::get_timestamps_parameters(), ['data' => $datetimes]); + + $type = \core_calendar\type_factory::get_calendar_instance(); + $timestamps = ['timestamps' => []]; + + foreach ($params['data'] as $key => $datetime) { + $hour = $datetime['hour'] ?? 0; + $minute = $datetime['minute'] ?? 0; + + try { + $timestamp = $type->convert_to_timestamp( + $datetime['year'], $datetime['month'], $datetime['day'], $hour, $minute); + + $timestamps['timestamps'][] = [ + 'key' => $datetime['key'] ?? $key, + 'timestamp' => $timestamp, + ]; + + } catch (Exception $e) { + throw new moodle_exception('One or more of the dates provided were invalid'); + } + } + + return $timestamps; + } + + /** + * Describes the parameters for get_timestamps. + * + * @return external_function_parameters + */ + public static function get_timestamps_parameters() { + return new external_function_parameters ([ + 'data' => new external_multiple_structure( + new external_single_structure( + [ + 'key' => new external_value(PARAM_ALPHANUMEXT, 'key', VALUE_OPTIONAL), + 'year' => new external_value(PARAM_INT, 'year'), + 'month' => new external_value(PARAM_INT, 'month'), + 'day' => new external_value(PARAM_INT, 'day'), + 'hour' => new external_value(PARAM_INT, 'hour', VALUE_OPTIONAL), + 'minute' => new external_value(PARAM_INT, 'minute', VALUE_OPTIONAL), + ] + ) + ) + ]); + } + + /** + * Describes the timestamps return format. + * + * @return external_single_structure + */ + public static function get_timestamps_returns() { + return new external_single_structure( + [ + 'timestamps' => new external_multiple_structure( + new external_single_structure( + [ + 'key' => new external_value(PARAM_ALPHANUMEXT, 'Timestamp key'), + 'timestamp' => new external_value(PARAM_INT, 'Unix timestamp'), + ] + ) + ) + ] + ); + } } diff --git a/calendar/tests/externallib_test.php b/calendar/tests/externallib_test.php index d3a7cf9e779..810c25fdd20 100644 --- a/calendar/tests/externallib_test.php +++ b/calendar/tests/externallib_test.php @@ -2696,4 +2696,87 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { ); $this->assertEquals(['user', 'course', 'group'], $data['allowedeventtypes']); } + + /** + * Test get_timestamps with string keys, with and without optional hour/minute values. + */ + public function test_get_timestamps_string_keys() { + $this->resetAfterTest(true); + $this->setAdminUser(); + + $time1 = new DateTime('2018-12-30 00:00:00'); + $time2 = new DateTime('2019-03-27 23:59:00'); + + $dates = [ + [ + 'key' => 'from', + 'year' => $time1->format('Y'), + 'month' => $time1->format('m'), + 'day' => $time1->format('d'), + ], + [ + 'key' => 'to', + 'year' => $time2->format('Y'), + 'month' => (int) $time2->format('m'), + 'day' => $time2->format('d'), + 'hour' => $time2->format('H'), + 'minute' => $time2->format('i'), + ], + ]; + + $expectedtimestamps = [ + 'from' => $time1->getTimestamp(), + 'to' => $time2->getTimestamp(), + ]; + + $result = core_calendar_external::get_timestamps($dates); + + $this->assertEquals(['timestamps'], array_keys($result)); + $this->assertEquals(2, count($result['timestamps'])); + + foreach ($result['timestamps'] as $data) { + $this->assertTrue(in_array($data['key'], ['from', 'to'])); + $this->assertEquals($expectedtimestamps[$data['key']], $data['timestamp']); + } + } + + /** + * Test get_timestamps with no keys specified, with and without optional hour/minute values. + */ + public function test_get_timestamps_no_keys() { + $this->resetAfterTest(true); + $this->setAdminUser(); + + $time1 = new DateTime('2018-12-30 00:00:00'); + $time2 = new DateTime('2019-03-27 23:59:00'); + + $dates = [ + [ + 'year' => $time1->format('Y'), + 'month' => $time1->format('m'), + 'day' => $time1->format('d'), + ], + [ + 'year' => $time2->format('Y'), + 'month' => (int) $time2->format('m'), + 'day' => $time2->format('d'), + 'hour' => $time2->format('H'), + 'minute' => $time2->format('i'), + ], + ]; + + $expectedtimestamps = [ + 0 => $time1->getTimestamp(), + 1 => $time2->getTimestamp(), + ]; + + $result = core_calendar_external::get_timestamps($dates); + + $this->assertEquals(['timestamps'], array_keys($result)); + $this->assertEquals(2, count($result['timestamps'])); + + foreach ($result['timestamps'] as $data) { + $this->assertEquals($expectedtimestamps[$data['key']], $data['timestamp']); + } + } } diff --git a/calendar/upgrade.txt b/calendar/upgrade.txt index 7bfbeb1a4e5..2f4273a7a98 100644 --- a/calendar/upgrade.txt +++ b/calendar/upgrade.txt @@ -9,6 +9,8 @@ information provided here is intended especially for developers. * calendar_cron() * calendar_get_mini() * calendar_get_upcoming() +* Added core_calendar_external::get_timestamps(), which allows an array containing an arbitrary number of arrays of + date/time data to be converted and returned as timestamps, along with an optional key. === 3.6 === * calendar_get_default_courses() function now has optional $userid parameter. diff --git a/lib/db/services.php b/lib/db/services.php index 167e4314dbc..32a55429516 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -261,6 +261,14 @@ $functions = array( 'type' => 'read', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), ), + 'core_calendar_get_timestamps' => [ + 'classname' => 'core_calendar_external', + 'methodname' => 'get_timestamps', + 'description' => 'Fetch unix timestamps for given date times.', + 'classpath' => 'calendar/externallib.php', + 'type' => 'read', + 'ajax' => true, + ], 'core_cohort_add_cohort_members' => array( 'classname' => 'core_cohort_external', 'methodname' => 'add_cohort_members',