|
8 | 8 | */ |
9 | 9 | namespace OCP\Calendar; |
10 | 10 |
|
| 11 | +use DateTimeInterface; |
| 12 | + |
11 | 13 | /** |
12 | 14 | * Interface ICalendar |
13 | 15 | * |
14 | 16 | * @since 13.0.0 |
| 17 | + * |
| 18 | + * @psalm-type CalendarSearchOptions = array{ |
| 19 | + * timerange?: array{start?: DateTimeInterface, end?: DateTimeInterface}, |
| 20 | + * uid?: string, |
| 21 | + * types?: string[], |
| 22 | + * } |
15 | 23 | */ |
16 | 24 | interface ICalendar { |
17 | 25 | /** |
@@ -41,13 +49,63 @@ public function getDisplayName(): ?string; |
41 | 49 | public function getDisplayColor(): ?string; |
42 | 50 |
|
43 | 51 | /** |
44 | | - * @param string $pattern which should match within the $searchProperties |
45 | | - * @param array $searchProperties defines the properties within the query pattern should match |
46 | | - * @param array $options - optional parameters: |
47 | | - * ['timerange' => ['start' => new DateTime(...), 'end' => new DateTime(...)]] |
48 | | - * @param int|null $limit - limit number of search results |
49 | | - * @param int|null $offset - offset for paging of search results |
50 | | - * @return array an array of events/journals/todos which are arrays of key-value-pairs. the events are sorted by start date (closest first, furthest last) |
| 52 | + * Search the current calendar for matching events. |
| 53 | + * |
| 54 | + * This method searches for events in the calendar that match a given pattern within specified properties. |
| 55 | + * The search is case-insensitive. It supports optional parameters such as a time range, limit, and offset. |
| 56 | + * The results are sorted by start date, with the closest events appearing first. |
| 57 | + * |
| 58 | + * @param string $pattern A string to search for within the events. The search is done case-insensitive. |
| 59 | + * @param array $searchProperties Defines the properties within which the pattern should match. |
| 60 | + * @param array $options Optional parameters for the search: |
| 61 | + * - 'timerange' element that can have 'start' (DateTimeInterface), 'end' (DateTimeInterface), or both. |
| 62 | + * - 'uid' element to look for events with a given uid. |
| 63 | + * - 'types' element to only return events for a given type (e.g. VEVENT or VTODO) |
| 64 | + * @psalm-param CalendarSearchOptions $options |
| 65 | + * @param int|null $limit Limit the number of search results. |
| 66 | + * @param int|null $offset For paging of search results. |
| 67 | + * @return array An array of events/journals/todos which are arrays of key-value-pairs. The events are sorted by start date (closest first, furthest last). |
| 68 | + * |
| 69 | + * Implementation Details: |
| 70 | + * |
| 71 | + * An event can consist of many sub-events, typically the case for events with recurrence rules. On a database level, |
| 72 | + * there's only one event stored (with a matching first occurrence and last occurrence timestamp). Expanding an event |
| 73 | + * into sub-events is done on the backend level. Using limit, offset, and timerange comes with some drawbacks. |
| 74 | + * When asking the database for events, the result is ordered by the primary key to guarantee a stable order. |
| 75 | + * After expanding the events into sub-events, they are sorted by the date (closest to furthest). |
| 76 | + * |
| 77 | + * Usage Examples: |
| 78 | + * |
| 79 | + * 1) Find 7 events within the next two weeks: |
| 80 | + * |
| 81 | + * $dateTime = (new DateTimeImmutable())->setTimestamp($this->timeFactory->getTime()); |
| 82 | + * $inTwoWeeks = $dateTime->add(new DateInterval('P14D')); |
| 83 | + * |
| 84 | + * $calendar->search( |
| 85 | + * '', |
| 86 | + * [], |
| 87 | + * ['timerange' => ['start' => $dateTime, 'end' => $inTwoWeeks]], |
| 88 | + * 7 |
| 89 | + * ); |
| 90 | + * |
| 91 | + * Note: When combining timerange and limit, it's possible that the expected outcome is not in the order you would expect. |
| 92 | + * |
| 93 | + * Example: Create 7 events for tomorrow, starting from 11:00, 30 minutes each. Then create an 8th event for tomorrow at 10:00. |
| 94 | + * The above code will list the event at 11:00 first, missing the event at 10:00. The reason is the ordering by the primary key |
| 95 | + * and expanding on the backend level. This is a technical limitation. The easiest workaround is to fetch more events |
| 96 | + * than you actually need, with the downside of needing more resources. |
| 97 | + * |
| 98 | + * Related: |
| 99 | + * - https://github.com/nextcloud/server/pull/45222 |
| 100 | + * - https://github.com/nextcloud/server/issues/53002 |
| 101 | + * |
| 102 | + * 2) Find all events where the location property contains the string 'Berlin': |
| 103 | + * |
| 104 | + * $calendar->search( |
| 105 | + * 'Berlin', |
| 106 | + * ['LOCATION'] |
| 107 | + * ); |
| 108 | + * |
51 | 109 | * @since 13.0.0 |
52 | 110 | */ |
53 | 111 | public function search(string $pattern, array $searchProperties = [], array $options = [], ?int $limit = null, ?int $offset = null): array; |
|
0 commit comments