From 55056435e3ee23aaad607fb1d037b4c07da65523 Mon Sep 17 00:00:00 2001 From: Bertrand Dunogier Date: Wed, 3 Apr 2019 00:47:06 +0200 Subject: [PATCH] [perf] use the Content service for ID loading if possible When find or findSingle have one or more ids, and only ids, as a criterion, use the content service to load the items. It includes multi-load when applicable. Example: reloation list load --- .../DataLoader/SearchContentLoader.php | 57 ++++++++++++++++++- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/src/GraphQL/DataLoader/SearchContentLoader.php b/src/GraphQL/DataLoader/SearchContentLoader.php index f89da724..2abe200b 100644 --- a/src/GraphQL/DataLoader/SearchContentLoader.php +++ b/src/GraphQL/DataLoader/SearchContentLoader.php @@ -6,6 +6,7 @@ */ namespace EzSystems\EzPlatformGraphQL\GraphQL\DataLoader; +use eZ\Publish\API\Repository\ContentService; use EzSystems\EzPlatformGraphQL\GraphQL\DataLoader\Exception\NotFoundException; use eZ\Publish\API\Repository\Exceptions as ApiException; use eZ\Publish\API\Repository\SearchService; @@ -23,10 +24,15 @@ class SearchContentLoader implements ContentLoader * @var SearchService */ private $searchService; + /** + * @var \eZ\Publish\API\Repository\ContentService + */ + private $contentService; - public function __construct(SearchService $searchService) + public function __construct(SearchService $searchService, ContentService $contentService) { $this->searchService = $searchService; + $this->contentService = $contentService; } /** @@ -40,6 +46,10 @@ public function __construct(SearchService $searchService) */ public function find(Query $query): array { + if ($results = $this->runIdSearch($query)) { + return (array)$results; + } + return array_map( function (SearchHit $searchHit) { return $searchHit->valueObject; @@ -60,7 +70,11 @@ function (SearchHit $searchHit) { public function findSingle(Criterion $filter): Content { try { - return $this->searchService->findSingle($filter); + if ($results = $this->runIdSearch($filter)) { + return $results; + } else { + return $this->searchService->findSingle($filter); + } } catch (ApiException\InvalidArgumentException $e) { } catch (ApiException\NotFoundException $e) { throw new NotFoundException($e->getMessage(), $e->getCode(), $e); @@ -88,4 +102,41 @@ public function count(Query $query) throw new NotFoundException($e->getMessage(), $e->getCode(), $e); } } -} + + /** + * If $filter only contains an ID criterion, use the content service for loading. + * + * @param $filter + * + * @return \eZ\Publish\API\Repository\Values\Content\Content|\eZ\Publish\API\Repository\Values\Content\Content[] + * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException + * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException + */ + private function runIdSearch($filter) + { + if ($filter instanceof Criterion\ContentId) { + $idArgument = $filter->value; + if (is_array($idArgument) && count($idArgument) > 1) { + return $this->contentService->loadContentListByContentInfo( + $this->contentService->loadContentInfoList($idArgument) + ); + } else { + return $this->contentService->loadContent($this->getOneId($idArgument)); + } + } + } + + private function getOneId($value) + { + if (is_array($value)) { + if (count($value) === 1) { + return $value[0]; + } + throw new \InvalidArgumentException("the id argument is an array with more than one ids"); + } else if (is_numeric($value)) { + return [$this->contentService->loadContent($value)]; + } else { + throw new \InvalidArgumentException("the id argument is an array with more than one ids"); + } + } +} \ No newline at end of file