getService(self::OPTION_ADVANCED_SEARCH_CLASS); } public function getDefaultSearch(): SearchInterface { $defaultSearch = $this->getService(self::OPTION_DEFAULT_SEARCH_CLASS); if ($defaultSearch) { return $defaultSearch; } throw new InvalidArgumentException(sprintf('Option %s is required', self::OPTION_DEFAULT_SEARCH_CLASS)); } public function withAdvancedSearch(SearchInterface $search): self { $this->setOption(self::OPTION_ADVANCED_SEARCH_CLASS, $search); return $this; } public function withDefaultSearch(SearchInterface $search): self { $this->setOption(self::OPTION_DEFAULT_SEARCH_CLASS, $search); return $this; } /** * @throws Exception */ public function searchByQuery(SearchQuery $query): array { $results = $this->executeSearch($query); return $this->getResultSetResponseNormalizer() ->normalize($query, $results, ''); } /** * @throws Exception */ public function search(ServerRequestInterface $request): array { $query = $this->getQueryFactory()->create($request); $queryParams = $request->getQueryParams(); $results = $this->executeSearch($query); return $this->getResultSetResponseNormalizer() ->normalize($query, $results, $queryParams['params']['structure']); } /** * @inheritDoc */ public function query($queryString, $type, $start = 0, $count = 10, $order = 'id', $dir = 'DESC') { return $this->getIndexSearch()->query($queryString, $type, $start, $count, $order, $dir); } /** * @inheritDoc */ public function flush() { return $this->getIndexSearch()->flush(); } /** * @inheritDoc */ public function index($documents) { return $this->getIndexSearch()->index($documents); } /** * @inheritDoc */ public function remove($resourceId) { return $this->getIndexSearch()->remove($resourceId); } /** * @inheritDoc */ public function supportCustomIndex() { return $this->getAdvancedSearch() !== null; } public function extendGenerisSearchWhiteList(array $whiteList): void { $this->setOption( self::OPTION_GENERIS_SEARCH_WHITELIST, array_merge( $this->getOption(self::OPTION_GENERIS_SEARCH_WHITELIST, []), $whiteList ) ); } public function removeFromGenerisSearchWhiteList(array $whiteList): void { $this->setOption( self::OPTION_GENERIS_SEARCH_WHITELIST, array_diff( $this->getOption(self::OPTION_GENERIS_SEARCH_WHITELIST, []), $whiteList ) ); } private function executeSearch(SearchQuery $query): ResultSet { if ($query->isEmptySearch()) { return new ResultSet([], 0); } if ($this->allowIdentifierSearch($query)) { $result = $this->getIdentifierSearcher()->search($query); if ($result->getTotalCount() > 0) { return $result; } } if ($this->isForcingDefaultSearch($query) || !$this->getAdvancedSearchChecker()->isEnabled()) { return $this->getDefaultSearch()->query( $query->getTerm(), $query->getParentClass(), $query->getStartRow(), $query->getRows() ); } return $this->getAdvancedSearch()->query( $this->getAdvancedSearchQueryString($query), $query->getRootClass(), $query->getStartRow(), $query->getRows() ); } private function getResultSetResponseNormalizer(): ResultSetResponseNormalizer { return $this->getServiceLocator()->get(ResultSetResponseNormalizer::class); } private function getAdvancedSearchChecker(): AdvancedSearchChecker { return $this->getServiceLocator()->get(AdvancedSearchChecker::class); } private function getIdentifierSearcher(): IdentifierSearcher { return $this->getServiceLocator()->get(IdentifierSearcher::class); } private function getQueryFactory(): SearchQueryFactory { return $this->getServiceLocator()->get(SearchQueryFactory::class); } private function isForcingDefaultSearch(SearchQuery $query): bool { $options = $this->getOption(self::OPTION_GENERIS_SEARCH_WHITELIST, []); $generisSearchWhitelist = array_merge(self::GENERIS_SEARCH_DEFAULT_WHITELIST, $options); return in_array($query->getParentClass(), $generisSearchWhitelist, true); } private function allowIdentifierSearch(SearchQuery $query): bool { return !in_array($query->getRootClass(), self::DISABLE_URI_SEARCH_FOR_ROOT_CLASSES, true); } private function getIndexSearch(): SearchInterface { return $this->getAdvancedSearchChecker()->isEnabled() ? $this->getAdvancedSearch() : $this->getDefaultSearch(); } private function getService(string $option): ?SearchInterface { if (!$this->hasOption($option)) { return null; } /** @var SearchInterface $search */ $search = $this->getOption($option); $this->propagate($search); return $search; } private function getAdvancedSearchQueryString(SearchQuery $query): string { return sprintf( '%s AND parent_classes: "%s"', $query->getTerm(), $query->getParentClass() ); } }