Skip to content

Commit 3a69dc4

Browse files
committed
Cherrypicked GraphQL changes from 4.6
1 parent 133f6a6 commit 3a69dc4

4 files changed

Lines changed: 49 additions & 82 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
services:
2+
App\GraphQL\Schema\MyFieldDefinitionMapper:
3+
decorates: Ibexa\GraphQL\Schema\Domain\Content\Mapper\FieldDefinition\DecoratingFieldDefinitionMapper
4+
arguments:
5+
$innerMapper: '@.inner'

code_samples/api/graphql/src/GraphQL/Schema/MyCustomFieldDefinitionMapper.php

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\GraphQL\Schema;
4+
5+
use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType;
6+
use Ibexa\Contracts\Core\Repository\Values\ContentType\FieldDefinition;
7+
use Ibexa\Contracts\GraphQL\Schema\Domain\Content\Mapper\FieldDefinition\FieldDefinitionMapper;
8+
use Ibexa\GraphQL\Schema\Domain\Content\Mapper\FieldDefinition\DecoratingFieldDefinitionMapper;
9+
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
10+
11+
class MyFieldDefinitionMapper extends DecoratingFieldDefinitionMapper implements FieldDefinitionMapper
12+
{
13+
protected function getFieldTypeIdentifier(): string
14+
{
15+
return 'my_field_type';
16+
}
17+
18+
public function mapToFieldValueInputType(ContentType $contentType, FieldDefinition $fieldDefinition): ?string
19+
{
20+
if (!$this->canMap($fieldDefinition)) {
21+
return parent::mapToFieldValueInputType($contentType, $fieldDefinition);
22+
}
23+
24+
return $this->nameMyFieldInputType($contentType, $fieldDefinition);
25+
}
26+
27+
private function nameMyFieldInputType(ContentType $contentType, FieldDefinition $fieldDefinition): string
28+
{
29+
$converter = new CamelCaseToSnakeCaseNameConverter(null, false);
30+
31+
return sprintf(
32+
'%s%sInput',
33+
$converter->denormalize($contentType->identifier),
34+
$converter->denormalize($fieldDefinition->identifier)
35+
);
36+
}
37+
}

docs/api/graphql/graphql_custom_ft.md

Lines changed: 7 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,17 @@ The `FieldDefinitionMapper` API uses service decorators.
5050
To register your own mapper, make it decorate the `Ibexa\GraphQL\Schema\Domain\Content\Mapper\FieldDefinition\DecoratingFieldDefinitionMapper` service:
5151

5252
```yaml
53-
services:
54-
App\GraphQL\Schema\MyCustomFieldDefinitionMapper:
55-
decorates: Ibexa\GraphQL\Schema\Domain\Content\Mapper\FieldDefinition\DecoratingFieldDefinitionMapper
56-
arguments:
57-
$innerMapper: '@.inner'
53+
[[= include_file('code_samples/api/graphql/config/services.yaml') =]]
5854
```
5955

6056
The `$innerMapper` argument passes the decorated mapper to the constructor.
6157
You can use the `DecoratingFieldDefinitionMapper` from the `graphql` package.
6258
It requires that you implement the `getFieldTypeIdentifier` method to tell which field type is covered by the mapper.
6359

64-
Add `MyCustomFieldDefinitionMapper.php` mapper to `src/GraphQL/Schema`:
60+
Add `MyFieldDefinitionMapper.php` mapper to `src/GraphQL/Schema`:
6561

6662
``` php
67-
[[= include_file('code_samples/api/graphql/src/GraphQL/Schema/MyCustomFieldDefinitionMapper.php') =]]
63+
[[= include_file('code_samples/api/graphql/src/GraphQL/Schema/MyFieldDefinitionMapper.php', 0, 16) =]][[= include_file('code_samples/api/graphql/src/GraphQL/Schema/MyFieldDefinitionMapper.php', 36, 37) =]]
6864
```
6965

7066
The `FieldDefinitionMapper` interface defines following methods:
@@ -79,59 +75,12 @@ When a mapper method is decorated, you need to call the decorated service method
7975
To do that, you need to replace `mapXXX` by the method it's in:
8076

8177
```php
82-
if (!$this->canMap($fieldDefinition)) {
83-
return parent::mapToFieldValueType($fieldDefinition);
84-
}
78+
[[= include_file('code_samples/api/graphql/src/GraphQL/Schema/MyFieldDefinitionMapper.php', 19, 22, remove_indent=True) =]]
8579
```
8680

8781
It's required for every implemented method, so that other mappers are called for the other field types.
8882

89-
The [`RelationFieldDefinitionMapper`](https://github.com/ibexa/graphql/blob/main/src/lib/Schema/Domain/Content/Mapper/FieldDefinition/RelationFieldDefinitionMapper.php) example:
90-
91-
```php hl_lines="14"
92-
class RelationFieldDefinitionMapper extends DecoratingFieldDefinitionMapper implements FieldDefinitionMapper
93-
{
94-
public function mapToFieldValueType(FieldDefinition $fieldDefinition): ?string
95-
{
96-
if (!$this->canMap($fieldDefinition)) {
97-
return parent::mapToFieldValueType($fieldDefinition);
98-
}
99-
$settings = $fieldDefinition->getFieldSettings();
100-
101-
if (count($settings['selectionContentTypes']) === 1) {
102-
$contentType = $this->contentTypeService->loadContentTypeByIdentifier($settings['selectionContentTypes'][0]);
103-
$type = $this->nameHelper->itemName($contentType);
104-
} else {
105-
$type = 'Item';
106-
}
107-
108-
if (this->isMultiple(fieldDefinition)) {
109-
type = "[type]";
110-
}
111-
112-
return $type;
113-
}
114-
115-
public function mapToFieldValueResolver(FieldDefinition $fieldDefinition): ?string
116-
{
117-
if (!$this->canMap($fieldDefinition)) {
118-
return parent::mapToFieldValueResolver($fieldDefinition);
119-
}
120-
121-
isMultiple = this->isMultiple($fieldDefinition) ? 'true' : 'false';
122-
123-
return sprintf('@=resolver("DomainRelationFieldValue", [field, %s])', $isMultiple);
124-
}
125-
126-
private function isMultiple(FieldDefinition $fieldDefinition)
127-
{
128-
$constraints = $fieldDefinition->getValidatorConfiguration();
129-
130-
return isset(constraints['RelationListValueValidator'])
131-
&& constraints'RelationListValueValidator' !== 1;
132-
}
133-
}
134-
```
83+
For an example implementation, look at the [`RelationFieldDefinitionMapper`](https://github.com/ibexa/graphql/blob/main/src/lib/Schema/Domain/Content/Mapper/FieldDefinition/RelationFieldDefinitionMapper.php) class.
13584

13685
The value type depends on the field definition allowed content types setting:
13786

@@ -147,20 +96,10 @@ The cardinality (single or collection) depends on the selection limit setting:
14796
The `mapToFieldValueInputType` method is used to document what input type is expected by field types that require a more complex input value.
14897
For example, `ibexa_matrix` generates its own input types depending on the configured columns.
14998

150-
Example of a `MyCustomFieldDefinitionMapper` mapper for a complex field type:
99+
Example of a `MyFieldDefinitionMapper` mapper for a complex field type:
151100

152101
```php
153-
class MyFieldDefinitionMapper extends DecoratingFieldDefinitionMapper implements FieldDefinitionMapper
154-
{
155-
public function mapToFieldValueInputType(ContentType contentType, FieldDefinition fieldDefinition): ?string
156-
{
157-
if (!this->canMap(fieldDefinition)) {
158-
return parent::mapToFieldValueInputType($fieldDefinition);
159-
}
160-
161-
return this->nameMyFieldType(fieldDefinition);
162-
}
163-
}
102+
[[= include_file('code_samples/api/graphql/src/GraphQL/Schema/MyFieldDefinitionMapper.php') =]]
164103
```
165104

166105
## Resolver expressions

0 commit comments

Comments
 (0)