Skip to content

Commit

Permalink
Implemented Item resolvers
Browse files Browse the repository at this point in the history
  • Loading branch information
Bertrand Dunogier committed Nov 25, 2020
1 parent 35c4fef commit 5f919be
Show file tree
Hide file tree
Showing 20 changed files with 599 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@

namespace spec\EzSystems\EzPlatformGraphQL\GraphQL\InputMapper;

use eZ\Publish\API\Repository\Values\Content\Query\Criterion\Subtree;
use EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\ContentCollectionFilterBuilder;
use EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\SearchQueryMapper;
use eZ\Publish\API\Repository\Values\Content\Query;
use PhpSpec\ObjectBehavior;

class SearchQueryMapperSpec extends ObjectBehavior
{
function let(ContentCollectionFilterBuilder $filterBuilder)
{
$this->beConstructedWith($filterBuilder);

$filterBuilder->buildFilter()->willReturn(new SubTree('/1/2/'));
}

function it_is_initializable()
{
$this->shouldHaveType(SearchQueryMapper::class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use eZ\Publish\API\Repository\Values\Content\Query;
use EzSystems\EzPlatformGraphQL\GraphQL\DataLoader\ContentLoader;
use EzSystems\EzPlatformGraphQL\GraphQL\DataLoader\ContentTypeLoader;
use EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\SearchQueryMapper;
use EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\QueryMapper;
use EzSystems\EzPlatformGraphQL\GraphQL\Resolver\DomainContentResolver;
use eZ\Publish\API\Repository\Repository;
use eZ\Publish\Core\FieldType;
Expand All @@ -24,7 +24,7 @@ class DomainContentResolverSpec extends ObjectBehavior
function let(
Repository $repository,
TypeResolver $typeResolver,
SearchQueryMapper $queryMapper,
QueryMapper $queryMapper,
ContentLoader $contentLoader,
ContentTypeLoader $contentTypeLoader
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ function it_delegates_the_field_definition_type_to_the_inner_mapper(FieldDefinit
function it_maps_multi_selection_to_resolve_multiple()
{
$fieldDefinition = $this->createFieldDefinition(self::DEF_LIMIT_MULTI);
$this->mapToFieldValueResolver($fieldDefinition)->shouldReturn('@=resolver("DomainRelationFieldValue", [field, true])');
$this->mapToFieldValueResolver($fieldDefinition)->shouldReturn('@=resolver("ItemRelationFieldValue", [field, true])');
}

function it_maps_singl_selection_to_resolve_single()
function it_maps_single_selection_to_resolve_single()
{
$fieldDefinition = $this->createFieldDefinition(self::DEF_LIMIT_SINGLE);
$this->mapToFieldValueResolver($fieldDefinition)->shouldReturn('@=resolver("DomainRelationFieldValue", [field, false])');
$this->mapToFieldValueResolver($fieldDefinition)->shouldReturn('@=resolver("ItemRelationFieldValue", [field, false])');
}

private function createFieldDefinition($selectionLimit = 0, $selectionContentTypes = [])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function it_adds_a_collection_field_for_the_ContentType_to_the_ContentTypeGroup(
FieldArgument::hasName(self::CONNECTION_FIELD),
FieldArgument::hasType(self::TYPE_TYPE),
FieldArgument::hasDescription(self::TYPE_DESCRIPTION),
FieldArgument::withResolver('SearchContentOfTypeAsConnection')
FieldArgument::withResolver('ItemsOfTypeAsConnection')
)
)
->shouldBeCalled();
Expand Down
35 changes: 32 additions & 3 deletions src/GraphQL/DataLoader/SearchLocationLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
use eZ\Publish\API\Repository\URLAliasService;
use eZ\Publish\API\Repository\Values\Content\Location;
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\API\Repository\Values\Content\Search\SearchHit;
use eZ\Publish\API\Repository\Values\Content\URLAlias;
use eZ\Publish\Core\MVC\ConfigResolverInterface;
use eZ\Publish\Core\MVC\Symfony\Routing\Generator\UrlAliasGenerator;
use EzSystems\EzPlatformGraphQL\GraphQL\DataLoader\Exception\ArgumentsException;

/**
Expand All @@ -36,12 +37,22 @@ class SearchLocationLoader implements LocationLoader
* @var \eZ\Publish\API\Repository\URLAliasService
*/
private $urlAliasService;
/**
* @var \eZ\Publish\Core\MVC\ConfigResolverInterface
*/
private $configResolver;
/**
* @var \eZ\Publish\Core\MVC\Symfony\Routing\Generator\UrlAliasGenerator
*/
private $urlAliasGenerator;

public function __construct(SearchService $searchService, LocationService $locationService, URLAliasService $urlAliasService)
public function __construct(SearchService $searchService, LocationService $locationService, URLAliasService $urlAliasService, ConfigResolverInterface $configResolver, UrlAliasGenerator $urlAliasGenerator)
{
$this->searchService = $searchService;
$this->locationService = $locationService;
$this->urlAliasService = $urlAliasService;
$this->configResolver = $configResolver;
$this->urlAliasGenerator = $urlAliasGenerator;
}

public function find(LocationQuery $query): array
Expand Down Expand Up @@ -76,7 +87,7 @@ public function findByRemoteId($id): Location

public function findByUrlAlias(string $urlAlias): Location
{
$alias = $this->urlAliasService->lookup($urlAlias);
$alias = $this->getUrlAlias($urlAlias);

return ($alias->type == URLAlias::LOCATION)
? $this->locationService->loadLocation($alias->destination)
Expand Down Expand Up @@ -104,4 +115,22 @@ public function count(LocationQuery $query)
throw new ArgumentsException($e->getMessage(), $e->getCode(), $e);
}
}

protected function getUrlAlias($pathinfo): URLAlias
{
$rootLocationId = $this->configResolver->getParameter('content.tree_root.location_id');
$pathPrefix = $this->urlAliasGenerator->getPathPrefixByRootLocationId($rootLocationId);

if (
$rootLocationId !== null &&
!$this->urlAliasGenerator->isUriPrefixExcluded($pathinfo) &&
$pathPrefix !== '/'
) {
$urlAlias = $pathPrefix . $pathinfo;
} else {
$urlAlias = $pathinfo;
}

return $this->urlAliasService->lookup($urlAlias);
}
}
59 changes: 59 additions & 0 deletions src/GraphQL/InputMapper/ContentCollectionFilterBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformGraphQL\GraphQL\InputMapper;

use eZ\Publish\API\Repository\Repository;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion\Subtree;
use eZ\Publish\API\Repository\Values\Content\URLAlias;
use eZ\Publish\Core\MVC\ConfigResolverInterface;

/**
* Builds the base query used to retrieve locations collections.
*
* @internal
*/
class ContentCollectionFilterBuilder
{
/**
* @var \eZ\Publish\Core\MVC\ConfigResolverInterface
*/
private $configResolver;

/**
* @var \eZ\Publish\API\Repository\Repository
*/
private $repository;

public function __construct(ConfigResolverInterface $configResolver, Repository $repository)
{
$this->configResolver = $configResolver;
$this->repository = $repository;
}

/**
* Returns a criterion to be added as a global 'and' to a query's filters.
*/
public function buildFilter(): Criterion
{
$treeRootLocationId = $this->configResolver->getParameter('content.tree_root.location_id');
$rootLocation = $this->repository->getLocationService()->loadLocation($treeRootLocationId);

$includedSubtrees = [$rootLocation->pathString ?? '/'];

foreach ($this->configResolver->getParameter('content.tree_root.excluded_uri_prefixes') as $uriPrefix) {
$urlAlias = $this->repository->getURLAliasService()->lookup($uriPrefix);
if ($urlAlias->type === URLAlias::LOCATION) {
$includedSubtrees[] = $this->repository->getLocationService()->loadLocation($urlAlias->destination)->pathString;
}
}

return new SubTree($includedSubtrees);
}
}
17 changes: 17 additions & 0 deletions src/GraphQL/InputMapper/QueryMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
namespace EzSystems\EzPlatformGraphQL\GraphQL\InputMapper;

use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use eZ\Publish\API\Repository\Values\Content\Query;

interface QueryMapper
{
public function mapInputToLocationQuery(array $inputArray): LocationQuery;

public function mapInputToQuery(array $inputArray): Query;
}
41 changes: 33 additions & 8 deletions src/GraphQL/InputMapper/SearchQueryMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,53 @@
*/
namespace EzSystems\EzPlatformGraphQL\GraphQL\InputMapper;

use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use eZ\Publish\API\Repository\Values\Content\Query;
use InvalidArgumentException;

class SearchQueryMapper
final class SearchQueryMapper implements QueryMapper
{
/**
* @var \EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\ContentCollectionFilterBuilder
*/
private $filterBuilder;

public function __construct(ContentCollectionFilterBuilder $filterBuilder)
{
$this->filterBuilder = $filterBuilder;
}

/**
* @return \eZ\Publish\API\Repository\Values\Content\LocationQuery
*/
public function mapInputToLocationQuery(array $inputArray): LocationQuery
{
$query = new LocationQuery();
$this->mapInput($query, $inputArray);

return $query;
}

/**
* @return \eZ\Publish\API\Repository\Values\Content\Query
*/
public function mapInputToQuery(array $inputArray)
public function mapInputToQuery(array $inputArray): Query
{
$query = new Query();
$this->mapInput($query, $inputArray);

return $query;
}

private function mapInput($query, array $inputArray)
{
if (isset($inputArray['offset'])) {
$query->offset = $inputArray['offset'];
}
if (isset($inputArray['limit'])) {
$query->limit = $inputArray['limit'];
}
$criteria = [];
$criteria = [$this->filterBuilder->buildFilter()];

if (isset($inputArray['ContentTypeIdentifier'])) {
$criteria[] = new Query\Criterion\ContentTypeIdentifier($inputArray['ContentTypeIdentifier']);
Expand Down Expand Up @@ -92,11 +121,7 @@ function ($sortClauseClass) {
return $query;
}

if (count($criteria)) {
$query->filter = count($criteria) > 1 ? new Query\Criterion\LogicalAnd($criteria) : $criteria[0];
}

return $query;
$query->filter = new Query\Criterion\LogicalAnd($criteria);
}

/**
Expand Down
34 changes: 34 additions & 0 deletions src/GraphQL/ItemFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
namespace EzSystems\EzPlatformGraphQL\GraphQL;

use eZ\Publish\API\Repository\Values\Content\Content;
use eZ\Publish\API\Repository\Values\Content\Location;
use EzSystems\EzPlatformGraphQL\GraphQL\Value\Item;

class ItemFactory
{
/**
* @var \EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\LocationGuesser
*/
private $locationGuesser;

public function __construct(Resolver\LocationGuesser\LocationGuesser $locationGuesser)
{
$this->locationGuesser = $locationGuesser;
}

public function fromContent(Content $content): Item
{
return new Item($this->locationGuesser, null, $content);
}

public function fromLocation(Location $location)
{
return new Item($this->locationGuesser, $location, null);
}
}
7 changes: 5 additions & 2 deletions src/GraphQL/Resolver/DomainContentResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use eZ\Publish\Core\FieldType;
use EzSystems\EzPlatformGraphQL\GraphQL\DataLoader\ContentLoader;
use EzSystems\EzPlatformGraphQL\GraphQL\DataLoader\ContentTypeLoader;
use EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\SearchQueryMapper;
use EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\QueryMapper;
use EzSystems\EzPlatformGraphQL\GraphQL\Value\Field;
use GraphQL\Error\UserError;
use Overblog\GraphQLBundle\Definition\Argument;
Expand Down Expand Up @@ -53,7 +53,7 @@ class DomainContentResolver
public function __construct(
Repository $repository,
TypeResolver $typeResolver,
SearchQueryMapper $queryMapper,
QueryMapper $queryMapper,
ContentLoader $contentLoader,
ContentTypeLoader $contentTypeLoader)
{
Expand Down Expand Up @@ -131,6 +131,9 @@ public function resolveMainUrlAlias(Content $content)
return isset($aliases[0]->path) ? $aliases[0]->path : null;
}

/**
* @deprecated since v3.0, use ItemResolver::resolveItemFieldValue() instead.
*/
public function resolveDomainFieldValue(Content $content, $fieldDefinitionIdentifier)
{
return Field::fromField($content->getField($fieldDefinitionIdentifier));
Expand Down
Loading

0 comments on commit 5f919be

Please sign in to comment.