-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
41 changed files
with
1,579 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/vendor/ | ||
composer.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
language: php | ||
|
||
php: | ||
- 7.1 | ||
|
||
branches: | ||
only: | ||
- master | ||
- dev | ||
|
||
env: | ||
matrix: | ||
- TARGET="phpspec" | ||
|
||
before_script: | ||
- COMPOSER_MEMORY_LIMIT=-1 composer install | ||
|
||
script: | ||
- if [ "$TARGET" == "phpspec" ] ; then ./vendor/bin/phpspec run -n; fi | ||
|
||
notification: | ||
email: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# eZ Platform Query Field Type | ||
|
||
This Field Type will let a content manager map an executable Repository Query to a Field. | ||
|
||
Example use-cases: | ||
- a `place.nearby_places` field that returns Place items less than X kilometers away | ||
from the current content, based on its own `location` field | ||
- a `gallery.images` field that returns Image items that are children of the current | ||
gallery item's main location | ||
|
||
The idea is to move content and structure logic implemented in controllers and templates | ||
to the repository itself. | ||
|
||
## Installation | ||
Add the package's repository to `composer.json`: | ||
|
||
```json | ||
{ | ||
"repositories": [ | ||
{ | ||
"type": "git", | ||
"url": "https://github.com/ezsystems/ezplatform-query-fieldtype.git" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Add the package to the requirements: | ||
``` | ||
composer require ezsystems/ezplatform-query-fieldtype:dev-master | ||
``` | ||
|
||
Add the package to `app/AppKernel.php`: | ||
```php | ||
$bundles = [ | ||
// ... | ||
new EzSystems\EzPlatformQueryFieldType\Symfony\EzSystemsEzPlatformQueryFieldTypeBundle(), | ||
] | ||
``` | ||
|
||
## Usage | ||
Add a `query` field to a content type. | ||
|
||
In the Field Definition settings, select a Query Type out of the ones defined in the system. Parameters are a JSON structure, with the key being the parameter's name, and the value either a scalar, or an [expression](https://symfony.com/doc/current/components/expression_language.html). | ||
|
||
See the [`examples`](examples/) directory for full examples. | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "ezsystems/ezplatform-query-fieldtype", | ||
"description": "An eZ Platform Field Type that defines a query.", | ||
"type": "ezplatform-bundle", | ||
"license": "GPL-2.0", | ||
"authors": [ | ||
{ | ||
"name": "Bertrand Dunogier", | ||
"homepage": "[email protected]" | ||
}, | ||
{ | ||
"name": "eZ Systems", | ||
"homepage": "https://github.com/ezsystems/ezplatform-query-fieldtype/contributors" | ||
} | ||
], | ||
"minimum-stability": "stable", | ||
"require": { | ||
"php": ">=7.1", | ||
"ezsystems/ezplatform-graphql": "^1.0||^2.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"EzSystems\\EzPlatformQueryFieldType\\": "src" | ||
} | ||
}, | ||
"require-dev": { | ||
"phpspec/phpspec": "^5.1" | ||
}, | ||
"extra": { | ||
"branch-alias": { | ||
"dev-master": "1.0.x-dev" | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
/** | ||
* Created by PhpStorm. | ||
* User: bdunogier | ||
* Date: 29/09/2018 | ||
* Time: 16:46 | ||
*/ | ||
|
||
namespace AppBundle\QueryType; | ||
|
||
use eZ\Publish\API\Repository\Values\Content\Query; | ||
use eZ\Publish\API\Repository\Values\Content\Query\Criterion; | ||
use eZ\Publish\Core\QueryType\QueryType; | ||
|
||
class NearbyPlacesQueryType implements QueryType | ||
{ | ||
public function getQuery(array $parameters = []) | ||
{ | ||
return new Query([ | ||
'filter' => new Criterion\LogicalAnd([ | ||
new Criterion\ContentTypeIdentifier('place'), | ||
new Criterion\MapLocationDistance( | ||
'location', | ||
Criterion\Operator::LTE, | ||
$parameters['distance'], | ||
$parameters['latitude'], | ||
$parameters['longitude'] | ||
) | ||
]), | ||
]); | ||
} | ||
|
||
public function getSupportedParameters() | ||
{ | ||
return ['distance', 'latitude', 'longitude']; | ||
} | ||
|
||
public static function getName() | ||
{ | ||
return 'NearbyPlaces'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
### Nearby places query field | ||
|
||
A field that lists Place items located close to the current item. | ||
|
||
#### Content type configuration | ||
The following assumes a "place" content item with a "location" map location | ||
field definition. | ||
|
||
##### Query type | ||
"Nearby places" (see [NearbyPlacesQueryType](NearbyPlacesQueryType.php). | ||
|
||
##### Parameters | ||
```json | ||
{ | ||
"distance": 3, | ||
"latitude": "@=content.getFieldValue('location').latitude", | ||
"longitude": "@=content.getFieldValue('location').longitude", | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
formatter.name: pretty | ||
|
||
suites: | ||
default: | ||
psr4_prefix: EzSystems\EzPlatformQueryFieldType | ||
namespace: EzSystems\EzPlatformQueryFieldType |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<?php | ||
|
||
namespace spec\EzSystems\EzPlatformQueryFieldType\API; | ||
|
||
use EzSystems\EzPlatformQueryFieldType\API\QueryFieldService; | ||
use EzSystems\EzPlatformQueryFieldType\FieldType\Query; | ||
use eZ\Publish\API\Repository\ContentTypeService; | ||
use eZ\Publish\API\Repository\SearchService; | ||
use eZ\Publish\API\Repository\Values\Content\ContentInfo; | ||
use eZ\Publish\API\Repository\Values\Content\Query as ApiQuery; | ||
use eZ\Publish\API\Repository\Values\Content\Search\SearchResult; | ||
use eZ\Publish\Core\QueryType\QueryType; | ||
use eZ\Publish\Core\QueryType\QueryTypeRegistry; | ||
use eZ\Publish\Core\Repository\Values; | ||
use EzSystems\EzPlatformGraphQL\GraphQL\Value\Field; | ||
use PhpSpec\ObjectBehavior; | ||
use Prophecy\Argument; | ||
|
||
class QueryFieldServiceSpec extends ObjectBehavior | ||
{ | ||
const CONTENT_TYPE_ID = 1; | ||
const QUERY_TYPE_IDENTIFIER = 'query_type_identifier'; | ||
const FIELD_DEFINITION_IDENTIFIER = 'test'; | ||
|
||
private $searchResult; | ||
private $searchHits; | ||
|
||
function let( | ||
SearchService $searchService, | ||
ContentTypeService $contentTypeService, | ||
QueryTypeRegistry $queryTypeRegistry, | ||
QueryType $queryType | ||
) { | ||
$this->searchHits = []; | ||
$this->searchResult = new SearchResult(['searchHits' => $this->searchHits]); | ||
|
||
$parameters = json_encode([ | ||
'param1' => 'value1', | ||
'param2' => 'value2', | ||
]); | ||
|
||
$contentType = new Values\ContentType\ContentType([ | ||
'fieldDefinitions' => [ | ||
new Values\ContentType\FieldDefinition([ | ||
'identifier' => self::FIELD_DEFINITION_IDENTIFIER, | ||
'fieldTypeIdentifier' => 'query', | ||
'fieldSettings' => [ | ||
'ReturnedType' => 'folder', | ||
'QueryType' => self::QUERY_TYPE_IDENTIFIER, | ||
'Parameters' => $parameters, | ||
] | ||
]), | ||
], | ||
]); | ||
|
||
$contentTypeService->loadContentType(self::CONTENT_TYPE_ID)->willReturn($contentType); | ||
$queryTypeRegistry->getQueryType(self::QUERY_TYPE_IDENTIFIER)->willReturn($queryType); | ||
$queryType->getQuery(Argument::any())->willReturn(new ApiQuery()); | ||
// @todo this should fail. It does not. | ||
$searchService->findContent(Argument::any())->willReturn($this->searchResult); | ||
$this->beConstructedWith($searchService, $contentTypeService, $queryTypeRegistry); | ||
} | ||
|
||
function it_is_initializable() | ||
{ | ||
$this->shouldHaveType(QueryFieldService::class); | ||
} | ||
|
||
function it_loads_data_from_a_query_field_for_a_given_content_item() | ||
{ | ||
$this->loadFieldData($this->getContent(), self::FIELD_DEFINITION_IDENTIFIER)->shouldBe($this->searchHits); | ||
} | ||
|
||
/** | ||
* @return \eZ\Publish\Core\Repository\Values\Content\Content | ||
*/ | ||
private function getContent(): Values\Content\Content | ||
{ | ||
return new Values\Content\Content([ | ||
'versionInfo' => new Values\Content\VersionInfo([ | ||
'contentInfo' => new ContentInfo(['contentTypeId' => self::CONTENT_TYPE_ID]), | ||
]) | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php | ||
|
||
namespace spec\EzSystems\EzPlatformQueryFieldType\GraphQL; | ||
|
||
use EzSystems\EzPlatformQueryFieldType\GraphQL\QueryFieldDefinitionMapper; | ||
use eZ\Publish\API\Repository\ContentTypeService; | ||
use eZ\Publish\Core\QueryType\QueryTypeRegistry; | ||
use eZ\Publish\Core\Repository\Values\ContentType\ContentType; | ||
use eZ\Publish\Core\Repository\Values\ContentType\FieldDefinition; | ||
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Mapper\FieldDefinition\FieldDefinitionMapper; | ||
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\NameHelper; | ||
use PhpSpec\ObjectBehavior; | ||
|
||
class QueryFieldDefinitionMapperSpec extends ObjectBehavior | ||
{ | ||
const FIELD_IDENTIFIER = 'test'; | ||
const FIELD_TYPE_IDENTIFIER = 'query'; | ||
const RETURNED_CONTENT_TYPE_IDENTIFIER = 'folder'; | ||
const GRAPHQL_TYPE = 'FolderContent'; | ||
|
||
function let( | ||
FieldDefinitionMapper $innerMapper, | ||
NameHelper $nameHelper, | ||
ContentTypeService $contentTypeService | ||
) | ||
{ | ||
$contentType = new ContentType(['identifier' => self::RETURNED_CONTENT_TYPE_IDENTIFIER]); | ||
|
||
$contentTypeService | ||
->loadContentTypeByIdentifier(self::RETURNED_CONTENT_TYPE_IDENTIFIER) | ||
->willReturn($contentType); | ||
|
||
$nameHelper | ||
->domainContentName($contentType) | ||
->willReturn(self::GRAPHQL_TYPE); | ||
|
||
$this->beConstructedWith($innerMapper, $nameHelper, $contentTypeService); | ||
} | ||
|
||
function it_is_initializable() | ||
{ | ||
$this->shouldHaveType(QueryFieldDefinitionMapper::class); | ||
$this->shouldHaveType(FieldDefinitionMapper::class); | ||
} | ||
|
||
function it_returns_as_value_type_the_configured_ContentType_for_query_field_definitions(FieldDefinitionMapper $innerMapper) | ||
{ | ||
$fieldDefinition = $this->fieldDefinition(); | ||
$innerMapper->mapToFieldValueType($fieldDefinition)->shouldNotBeCalled(); | ||
$this | ||
->mapToFieldValueType($fieldDefinition) | ||
->shouldBe('[' . self::GRAPHQL_TYPE . ']'); | ||
} | ||
|
||
function it_delegates_value_type_to_the_inner_mapper_for_a_non_query_field_definition(FieldDefinitionMapper $innerMapper) | ||
{ | ||
$fieldDefinition = new FieldDefinition(['fieldTypeIdentifier' => 'lambda']); | ||
$innerMapper->mapToFieldValueType($fieldDefinition)->willReturn('SomeType'); | ||
$this | ||
->mapToFieldValueType($fieldDefinition) | ||
->shouldBe('SomeType'); | ||
} | ||
|
||
function it_delegates_the_definition_type_to_the_parent_mapper(FieldDefinitionMapper $innerMapper) | ||
{ | ||
$fieldDefinition = $this->fieldDefinition(); | ||
$innerMapper->mapToFieldDefinitionType($fieldDefinition)->willReturn('FieldValue'); | ||
$this | ||
->mapToFieldDefinitionType($fieldDefinition) | ||
->shouldBe('FieldValue'); | ||
} | ||
|
||
function it_delegates_the_value_resolver_to_the_parent_mapper(FieldDefinitionMapper $innerMapper) | ||
{ | ||
$fieldDefinition = $this->fieldDefinition(); | ||
$innerMapper->mapToFieldValueResolver($fieldDefinition)->willReturn('resolver'); | ||
$this | ||
->mapToFieldValueResolver($fieldDefinition) | ||
->shouldBe('resolver'); | ||
} | ||
|
||
/** | ||
* @return FieldDefinition | ||
*/ | ||
private function fieldDefinition(): FieldDefinition | ||
{ | ||
return new FieldDefinition([ | ||
'identifier' => self::FIELD_IDENTIFIER, | ||
'fieldTypeIdentifier' => self::FIELD_TYPE_IDENTIFIER, | ||
'fieldSettings' => ['ReturnedType' => self::RETURNED_CONTENT_TYPE_IDENTIFIER] | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
namespace spec\EzSystems\EzPlatformQueryFieldType\GraphQL; | ||
|
||
use EzSystems\EzPlatformQueryFieldType\API\QueryFieldService; | ||
use EzSystems\EzPlatformQueryFieldType\GraphQL\QueryFieldResolver; | ||
use eZ\Publish\Core\Repository\Values\Content\Content; | ||
use EzSystems\EzPlatformGraphQL\GraphQL\Value\Field; | ||
use PhpSpec\ObjectBehavior; | ||
|
||
class QueryFieldResolverSpec extends ObjectBehavior | ||
{ | ||
const FIELD_DEFINITION_IDENTIFIER = 'test'; | ||
|
||
function let(QueryFieldService $queryFieldService) | ||
{ | ||
$this->beConstructedWith($queryFieldService); | ||
} | ||
|
||
function it_is_initializable() | ||
{ | ||
$this->shouldHaveType(QueryFieldResolver::class); | ||
} | ||
|
||
function it_resolves_a_query_field(QueryFieldService $queryFieldService) | ||
{ | ||
$content = new Content(); | ||
$field = new Field(['fieldDefIdentifier' => self::FIELD_DEFINITION_IDENTIFIER, 'value' => new \stdClass()]); | ||
$queryFieldService->loadFieldData($content, self::FIELD_DEFINITION_IDENTIFIER)->willReturn([]); | ||
$this->resolveQueryField($field, $content)->shouldReturn([]); | ||
} | ||
} |
Oops, something went wrong.