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 9b3dc51 commit 2243a88
Show file tree
Hide file tree
Showing 17 changed files with 570 additions and 25 deletions.
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
36 changes: 32 additions & 4 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,21 @@ 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);
}
}
39 changes: 32 additions & 7 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
{
/**
* @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)
{
$query = new LocationQuery();
$this->mapInput($query, $inputArray);

return $query;
}

/**
* @return \eZ\Publish\API\Repository\Values\Content\Query
*/
public function mapInputToQuery(array $inputArray)
{
$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);
}
}
3 changes: 3 additions & 0 deletions src/GraphQL/Resolver/DomainContentResolver.php
Original file line number Diff line number Diff line change
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 2243a88

Please sign in to comment.