Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Command/GeneratePlatformSchemaCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class GeneratePlatformSchemaCommand extends Command
*/
private $generator;

const TYPES_DIRECTORY = "src/AppBundle/Resources/config/graphql";
const TYPES_DIRECTORY = "app/config/graphql";

public function __construct(Repository $repository, SchemaGenerator $generator)
{
Expand Down
2 changes: 1 addition & 1 deletion DependencyInjection/BDEzPlatformGraphQLExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/
class BDEzPlatformGraphQLExtension extends Extension implements PrependExtensionInterface
{
const DOMAIN_SCHEMA_FILE = __DIR__. '/../../../../src/AppBundle/Resources/config/graphql/Domain.types.yml';
const DOMAIN_SCHEMA_FILE = __DIR__. '/../../../../app/config/graphql/Domain.types.yml';

/**
* {@inheritdoc}
Expand Down
6 changes: 6 additions & 0 deletions DomainContent/NameHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,17 @@ public function domainContentCollectionField(ContentType $contentType)
{
return $this->pluralize(lcfirst($this->toCamelCase($contentType->identifier)));
}

public function domainContentName(ContentType $contentType)
{
return ucfirst($this->toCamelCase($contentType->identifier)) . 'Content';
}

public function domainContentConnection($contentType)
{
return ucfirst($this->toCamelCase($contentType->identifier)) . 'ContentConnection';
}

public function domainContentTypeName(ContentType $contentType)
{
return ucfirst($this->toCamelCase($contentType->identifier)) . 'ContentType';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,21 @@ public function work(array &$schema, array $args)
[$this->getGroupName($contentTypeGroup)]
['config']['fields']
[$this->getContentCollectionField($contentType)] = [
'type' => sprintf("[%s]", $this->getContentName($contentType)),
// @todo Improve description to mention that it is a collection ?
'type' => $this->getNameHelper()->domainContentConnection($contentType),
'description' => isset($descriptions['eng-GB']) ? $descriptions['eng-GB'] : 'No description available',
'resolve' => sprintf(
'@=resolver("DomainContentItemsByTypeIdentifier", ["%s", args])',
$contentType->identifier
),
'argsBuilder' => 'Relay::Connection',
'args' => [
'query' => [
'type' => "ContentSearchQuery",
'description' => "A Content query used to filter results"
],
'sortBy' => [
'type' => 'SortByOptions'
],
],
];

Expand All @@ -46,10 +49,11 @@ public function work(array &$schema, array $args)
[$this->getContentField($contentType)] = [
'type' => $this->getContentName($contentType),
'description' => isset($descriptions['eng-GB']) ? $descriptions['eng-GB'] : 'No description available',
'resolve' => sprintf('@=resolver("DomainContentItem", [args, "%s"])', $contentType->identifier),
'resolve' => sprintf(
'@=resolver("DomainContentItem", [args, "%s"])',
$contentType->identifier
),
'args' => [
// @todo How do we constraint this so that it only takes an id of an item of that type ?
// same approach than GlobalId ? (<type>-<id>)
'id' => [
'type' => 'Int',
'description' => sprintf('A %s content id', $contentType->identifier),
Expand Down
10 changes: 9 additions & 1 deletion DomainContent/SchemaWorker/ContentType/DefineDomainContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function work(array &$schema, array $args)
'inherits' => ['AbstractDomainContent'],
'config' => [
'fields' => [],
'interfaces' => ['DomainContent'],
'interfaces' => ['DomainContent', 'Node'],
]
];

Expand All @@ -35,6 +35,14 @@ public function work(array &$schema, array $args)
'fields' => []
],
];

$schema[$this->getNameHelper()->domainContentConnection($contentType)] = [
'type' => 'relay-connection',
'config' => [
'nodeType' => $this->getDomainContentName($contentType),
'inherits' => ['DomainContentByIdentifierConnection'],
]
];
}

public function canWork(array $schema, array $args)
Expand Down
11 changes: 11 additions & 0 deletions GraphQL/InputMapper/SearchQueryMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@
class SearchQueryMapper
{
/**
* @param array $inputArray
* @return \eZ\Publish\API\Repository\Values\Content\Query
*/
public function mapInputToQuery(array $inputArray)
{
$query = new Query();
if (isset($inputArray['offset'])) {
$query->offset = $inputArray['offset'];
}
if (isset($inputArray['limit'])) {
$query->limit = $inputArray['limit'];
}
$criteria = [];

if (isset($inputArray['ContentTypeIdentifier'])) {
Expand Down Expand Up @@ -59,6 +66,10 @@ public function mapInputToQuery(array $inputArray)
$query->filter = count($criteria) > 1 ? new Query\Criterion\LogicalAnd($criteria) : $criteria[0];
}

if (isset($inputArray['sortBy'])) {
$query->sortClauses = [new $inputArray['sortBy']];
}

return $query;
}

Expand Down
17 changes: 17 additions & 0 deletions GraphQL/Relay/DomainConnectionBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php
/**
* Created by PhpStorm.
* User: bdunogier
* Date: 29/10/2018
* Time: 12:39
*/

namespace BD\EzPlatformGraphQLBundle\GraphQL\Relay;


use Overblog\GraphQLBundle\Relay\Connection\Output\ConnectionBuilder;

class DomainConnectionBuilder extends ConnectionBuilder
{
const PREFIX = 'DomainContent:';
}
75 changes: 75 additions & 0 deletions GraphQL/Relay/NodeResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace BD\EzPlatformGraphQLBundle\GraphQL\Relay;

use BD\EzPlatformGraphQLBundle\DomainContent\NameHelper;
use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\API\Repository\ContentTypeService;
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
use Overblog\GraphQLBundle\Relay\Node\GlobalId;
use Overblog\GraphQLBundle\Resolver\TypeResolver;

class NodeResolver
{
/**
* @var ContentService
*/
private $contentService;

/**
* @var TypeResolver
*/
private $typeResolver;

/**
* @var ContentTypeService
*/
private $contentTypeService;
/**
* @var NameHelper
*/
private $nameHelper;

public function __construct(ContentService $contentService, TypeResolver $typeResolver, ContentTypeService $contentTypeService, NameHelper $nameHelper)
{
$this->contentService = $contentService;
$this->typeResolver = $typeResolver;
$this->contentTypeService = $contentTypeService;
$this->nameHelper = $nameHelper;
}

/**
* @param $globalId
*
* @return null|\eZ\Publish\API\Repository\Values\Content\ContentInfo
*
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
*/
public function resolveNode($globalId)
{
$params = GlobalId::fromGlobalId($globalId);

if (in_array($params['type'], ['Content', 'DomainContent'])) {
return $this->contentService->loadContentInfo($params['id']);
}

return null;
}

/**
* @param $object
*
* @return \GraphQL\Type\Definition\Type
*/
public function resolveType($object)
{
if ($object instanceof ContentInfo) {
return $this->typeResolver->resolve(
$this->nameHelper->domainContentName(
$this->contentTypeService->loadContentType($object->contentTypeId)
)
);
}
}
}
70 changes: 70 additions & 0 deletions GraphQL/Relay/SearchResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php
namespace BD\EzPlatformGraphQLBundle\GraphQL\Relay;

use eZ\Publish\API\Repository\SearchService;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\API\Repository\Values\Content\Search\SearchHit;
use Overblog\GraphQLBundle\Relay\Connection\Output\Connection;
use Overblog\GraphQLBundle\Relay\Connection\Output\ConnectionBuilder;

class SearchResolver
{
/**
* @var SearchService
*/
private $searchService;

public function __construct(SearchService $searchService)
{
$this->searchService = $searchService;
}

/**
* @param $args
* @return Connection
*
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
*/
public function searchContent($args)
{
$queryArg = $args['query'];

$query = new Query();
$criteria = [];

if (isset($queryArg['ContentTypeIdentifier'])) {
$criteria[] = new Query\Criterion\ContentTypeIdentifier($queryArg['ContentTypeIdentifier']);
}

if (isset($queryArg['Text'])) {
foreach ($queryArg['Text'] as $text) {
$criteria[] = new Query\Criterion\FullText($text);
}
}

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

$contentItems = array_map(
function (SearchHit $hit) {
return $hit->valueObject;
},
$searchResult->searchHits
);

$connection = ConnectionBuilder::connectionFromArraySlice(
$contentItems,
$args,
[
'sliceStart' => 0,
'arrayLength' => $searchResult->totalCount,
]
);
$connection->sliceSize = count($contentItems);

return $connection;
}
}
Loading