diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/dav/lib/Search/EventsSearchProvider.php | 92 | ||||
-rw-r--r-- | apps/dav/tests/unit/Search/EventsSearchProviderTest.php | 12 |
2 files changed, 86 insertions, 18 deletions
diff --git a/apps/dav/lib/Search/EventsSearchProvider.php b/apps/dav/lib/Search/EventsSearchProvider.php index 22c87b1f854..4a2447c25f9 100644 --- a/apps/dav/lib/Search/EventsSearchProvider.php +++ b/apps/dav/lib/Search/EventsSearchProvider.php @@ -29,19 +29,24 @@ namespace OCA\DAV\Search; use OCA\DAV\CalDAV\CalDavBackend; use OCP\IUser; +use OCP\Search\IFilteringProvider; use OCP\Search\ISearchQuery; use OCP\Search\SearchResult; use OCP\Search\SearchResultEntry; use Sabre\VObject\Component; use Sabre\VObject\DateTimeParser; use Sabre\VObject\Property; +use function array_combine; +use function array_fill; +use function array_key_exists; +use function array_map; /** * Class EventsSearchProvider * * @package OCA\DAV\Search */ -class EventsSearchProvider extends ACalendarSearchProvider { +class EventsSearchProvider extends ACalendarSearchProvider implements IFilteringProvider { /** * @var string[] */ @@ -106,22 +111,60 @@ class EventsSearchProvider extends ACalendarSearchProvider { $calendarsById = $this->getSortedCalendars($principalUri); $subscriptionsById = $this->getSortedSubscriptions($principalUri); - $searchResults = $this->backend->searchPrincipalUri( - $principalUri, - $query->getFilter('term')?->get() ?? '', - [self::$componentType], - self::$searchProperties, - self::$searchParameters, - [ - 'limit' => $query->getLimit(), - 'offset' => $query->getCursor(), - 'timerange' => [ - 'start' => $query->getFilter('since')?->get(), - 'end' => $query->getFilter('until')?->get(), + /** @var string|null $term */ + $term = $query->getFilter('term')?->get(); + if ($term === null) { + $searchResults = []; + } else { + $searchResults = $this->backend->searchPrincipalUri( + $principalUri, + $term, + [self::$componentType], + self::$searchProperties, + self::$searchParameters, + [ + 'limit' => $query->getLimit(), + 'offset' => $query->getCursor(), + 'timerange' => [ + 'start' => $query->getFilter('since')?->get(), + 'end' => $query->getFilter('until')?->get(), + ], + ] + ); + } + /** @var IUser|null $person */ + $person = $query->getFilter('person')?->get(); + $personDisplayName = $person?->getDisplayName(); + if ($personDisplayName !== null) { + $attendeeSearchResults = $this->backend->searchPrincipalUri( + $principalUri, + $personDisplayName, + [self::$componentType], + ['ATTENDEE'], + self::$searchParameters, + [ + 'limit' => $query->getLimit(), + 'offset' => $query->getCursor(), + 'timerange' => [ + 'start' => $query->getFilter('since')?->get(), + 'end' => $query->getFilter('until')?->get(), + ], ], - ] - ); - $formattedResults = \array_map(function (array $eventRow) use ($calendarsById, $subscriptionsById):SearchResultEntry { + ); + + $searchResultIndex = array_combine( + array_map(fn($event) => $event['calendarid'] . '-' . $event['uri'], $searchResults), + array_fill(0, count($searchResults), null), + ); + foreach ($attendeeSearchResults as $attendeeResult) { + if (array_key_exists($attendeeResult['calendarid'] . '-' . $attendeeResult['uri'], $searchResultIndex)) { + // Duplicate + continue; + } + $searchResults[] = $attendeeResult; + } + } + $formattedResults = \array_map(function (array $eventRow) use ($calendarsById, $subscriptionsById): SearchResultEntry { $component = $this->getPrimaryComponent($eventRow['calendardata'], self::$componentType); $title = (string)($component->SUMMARY ?? $this->l10n->t('Untitled event')); $subline = $this->generateSubline($component); @@ -228,4 +271,21 @@ class EventsSearchProvider extends ACalendarSearchProvider { ): bool { return $dtStart->format('Y-m-d') === $dtEnd->format('Y-m-d'); } + + public function getSupportedFilters(): array { + return [ + 'term', + 'person', + 'since', + 'until', + ]; + } + + public function getAlternateIds(): array { + return []; + } + + public function getCustomFilters(): array { + return []; + } } diff --git a/apps/dav/tests/unit/Search/EventsSearchProviderTest.php b/apps/dav/tests/unit/Search/EventsSearchProviderTest.php index ef1288b0850..f012c4a44be 100644 --- a/apps/dav/tests/unit/Search/EventsSearchProviderTest.php +++ b/apps/dav/tests/unit/Search/EventsSearchProviderTest.php @@ -32,6 +32,7 @@ use OCP\App\IAppManager; use OCP\IL10N; use OCP\IURLGenerator; use OCP\IUser; +use OCP\Search\IFilter; use OCP\Search\ISearchQuery; use OCP\Search\SearchResult; use OCP\Search\SearchResultEntry; @@ -293,7 +294,14 @@ class EventsSearchProviderTest extends TestCase { $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn('john.doe'); $query = $this->createMock(ISearchQuery::class); - $query->method('getTerm')->willReturn('search term'); + $seachTermFilter = $this->createMock(IFilter::class); + $query->method('getFilter')->willReturnCallback(function($name) use ($seachTermFilter) { + return match ($name) { + 'term' => $seachTermFilter, + default => null, + }; + }); + $seachTermFilter->method('get')->willReturn('search term'); $query->method('getLimit')->willReturn(5); $query->method('getCursor')->willReturn(20); $this->appManager->expects($this->once()) @@ -328,7 +336,7 @@ class EventsSearchProviderTest extends TestCase { ]); $this->backend->expects($this->once()) ->method('searchPrincipalUri') - ->with('principals/users/john.doe', '', ['VEVENT'], + ->with('principals/users/john.doe', 'search term', ['VEVENT'], ['SUMMARY', 'LOCATION', 'DESCRIPTION', 'ATTENDEE', 'ORGANIZER', 'CATEGORIES'], ['ATTENDEE' => ['CN'], 'ORGANIZER' => ['CN']], ['limit' => 5, 'offset' => 20, 'timerange' => ['start' => null, 'end' => null]]) |