Skip to content

Commit d965cfb

Browse files
committed
IBX-9266: Implemented fetching field definitions from an expression
1 parent 632ad6c commit d965cfb

File tree

14 files changed

+404
-0
lines changed

14 files changed

+404
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Bundle\AdminUi\Controller;
10+
11+
use Ibexa\AdminUi\REST\Value\ContentType\FieldDefinitionInfoList;
12+
use Ibexa\Contracts\AdminUi\ContentType\ContentTypeFieldsByExpressionServiceInterface;
13+
use Ibexa\Rest\Message;
14+
use Ibexa\Rest\Server\Controller as RestController;
15+
use Symfony\Component\HttpFoundation\Request;
16+
17+
final class ContentTypeFieldsByExpressionController extends RestController
18+
{
19+
private ContentTypeFieldsByExpressionServiceInterface $fieldsByExpressionService;
20+
21+
public function __construct(ContentTypeFieldsByExpressionServiceInterface $fieldsByExpressionService)
22+
{
23+
$this->fieldsByExpressionService = $fieldsByExpressionService;
24+
}
25+
26+
/**
27+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
28+
*/
29+
public function loadFieldDefinitionsFromExpression(Request $request): FieldDefinitionInfoList
30+
{
31+
/** @var \Ibexa\AdminUi\REST\Value\ContentType\FieldDefinitionExpression $input */
32+
$input = $this->inputDispatcher->parse(
33+
new Message(
34+
['Content-Type' => $request->headers->get('Content-Type')],
35+
$request->getContent()
36+
)
37+
);
38+
39+
return new FieldDefinitionInfoList(
40+
$this->fieldsByExpressionService->getFieldsFromExpression($input->expression),
41+
);
42+
}
43+
}

src/bundle/Resources/config/routing_rest.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,14 @@ ibexa.rest.image.download:
126126
methods: GET
127127
requirements:
128128
contentIdList: '^\d+(,\d+)*$'
129+
130+
#
131+
# Content type fields by expression
132+
#
133+
134+
ibexa.rest.content_type.load_field_definitions_from_expression:
135+
path: /content-type/load-field-definitions-from-expression
136+
controller: 'Ibexa\Bundle\AdminUi\Controller\ContentTypeFieldsByExpressionController::loadFieldDefinitionsFromExpression'
137+
methods: [POST]
138+
options:
139+
expose: true

src/bundle/Resources/config/services/controllers.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,11 @@ services:
258258
$imageMappings: '%ibexa.dam_widget.image.mappings%'
259259
tags:
260260
- controller.service_arguments
261+
262+
Ibexa\Bundle\AdminUi\Controller\ContentTypeFieldsByExpressionController:
263+
parent: Ibexa\Rest\Server\Controller
264+
autowire: true
265+
arguments:
266+
$fieldsByExpressionService: '@Ibexa\Contracts\AdminUi\ContentType\ContentTypeFieldsByExpressionServiceInterface'
267+
tags:
268+
- controller.service_arguments

src/bundle/Resources/config/services/rest.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,15 @@ services:
9696
Ibexa\AdminUi\REST\Input\Parser\CriterionProcessor:
9797
parent: Ibexa\Contracts\Rest\Input\Parser\Query\Criterion\BaseCriterionProcessor
9898

99+
#
100+
# Content type
101+
#
102+
Ibexa\AdminUi\REST\Input\Parser\ContentType\FieldDefinitionExpression:
103+
parent: Ibexa\Rest\Server\Common\Parser
104+
tags:
105+
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.FieldDefinitionExpression }
106+
107+
Ibexa\AdminUi\REST\Output\ValueObjectVisitor\ContentType\FieldDefinitionInfoList:
108+
parent: Ibexa\Contracts\Rest\Output\ValueObjectVisitor
109+
tags:
110+
- { name: ibexa.rest.output.value_object.visitor, type: Ibexa\AdminUi\REST\Value\ContentType\FieldDefinitionInfoList }
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\AdminUi\REST\Input\Parser\ContentType;
10+
11+
use Ibexa\AdminUi\REST\Value\ContentType\FieldDefinitionExpression as FieldDefinitionExpressionValue;
12+
use Ibexa\Contracts\Rest\Exceptions;
13+
use Ibexa\Contracts\Rest\Input\ParsingDispatcher;
14+
use Ibexa\Rest\Input\BaseParser;
15+
16+
final class FieldDefinitionExpression extends BaseParser
17+
{
18+
public function parse(array $data, ParsingDispatcher $parsingDispatcher): FieldDefinitionExpressionValue
19+
{
20+
if (!array_key_exists('expression', $data) || !is_string($data['expression'])) {
21+
throw new Exceptions\Parser(
22+
sprintf("Missing or invalid 'expression' property for %s.", FieldDefinitionExpressionValue::class)
23+
);
24+
}
25+
26+
return new FieldDefinitionExpressionValue($data['expression']);
27+
}
28+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\AdminUi\REST\Output\ValueObjectVisitor\ContentType;
10+
11+
use Ibexa\Contracts\Rest\Output\Generator;
12+
use Ibexa\Contracts\Rest\Output\Visitor;
13+
use Ibexa\Rest\Server\Output\ValueObjectVisitor\RestContentTypeBase;
14+
15+
final class FieldDefinitionInfoList extends RestContentTypeBase
16+
{
17+
/**
18+
* @param \Ibexa\AdminUi\REST\Value\ContentType\FieldDefinitionInfoList $data
19+
*/
20+
public function visit(Visitor $visitor, Generator $generator, $data): void
21+
{
22+
$fieldDefinitionList = $data;
23+
24+
$generator->startObjectElement('FieldDefinitions', 'FieldDefinitionInfoList');
25+
$visitor->setHeader('Content-Type', $generator->getMediaType('FieldDefinitionInfoList'));
26+
27+
$generator->startList('FieldDefinitionInfo');
28+
foreach ($fieldDefinitionList->fieldDefinitions as $fieldDefinition) {
29+
$generator->startObjectElement('FieldDefinitionInfo');
30+
31+
$generator->startValueElement('id', $fieldDefinition->id);
32+
$generator->endValueElement('id');
33+
34+
$generator->startValueElement('identifier', $fieldDefinition->identifier);
35+
$generator->endValueElement('identifier');
36+
37+
$generator->startValueElement('position', $fieldDefinition->position);
38+
$generator->endValueElement('position');
39+
40+
$this->visitNamesList($generator, $fieldDefinition->getNames());
41+
42+
$generator->endObjectElement('FieldDefinitionInfo');
43+
}
44+
$generator->endList('FieldDefinitionInfo');
45+
46+
$generator->endObjectElement('FieldDefinitions');
47+
}
48+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\AdminUi\REST\Value\ContentType;
10+
11+
use Ibexa\Rest\Value as RestValue;
12+
13+
final class FieldDefinitionExpression extends RestValue
14+
{
15+
public string $expression;
16+
17+
public function __construct(string $expression)
18+
{
19+
$this->expression = $expression;
20+
}
21+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\AdminUi\REST\Value\ContentType;
10+
11+
use Ibexa\Rest\Value as RestValue;
12+
13+
final class FieldDefinitionInfoList extends RestValue
14+
{
15+
/** @var \Ibexa\Contracts\Core\Repository\Values\ContentType\FieldDefinition[] */
16+
public array $fieldDefinitions;
17+
18+
/**
19+
* @param \Ibexa\Contracts\Core\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
20+
*/
21+
public function __construct(array $fieldDefinitions)
22+
{
23+
$this->fieldDefinitions = $fieldDefinitions;
24+
}
25+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\Integration\AdminUi\REST;
10+
11+
use Ibexa\Contracts\Test\Rest\Input\PayloadLoader;
12+
use Ibexa\Contracts\Test\Rest\Request\Value\EndpointRequestDefinition;
13+
14+
/**
15+
* Coverage for /content-type/load-field-definitions-from-expression REST endpoint.
16+
*/
17+
final class PostLoadFieldDefinitionsFromExpression extends BaseAdminUiRestWebTestCase
18+
{
19+
private const INPUT_MEDIA_TYPE = 'FieldDefinitionExpression';
20+
21+
/**
22+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
23+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
24+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ForbiddenException
25+
*/
26+
protected function setUp(): void
27+
{
28+
parent::setUp();
29+
30+
// to create a new user before logging-in via REST
31+
$this->getIbexaTestCore()->setAdministratorUser();
32+
33+
$this->loginAsUser(
34+
$this->createUserWithPolicies(
35+
'editor',
36+
[
37+
'user/login' => [],
38+
'content/read' => [],
39+
'content/versionread' => [],
40+
]
41+
)
42+
);
43+
}
44+
45+
protected static function getEndpointsToTest(): iterable
46+
{
47+
$payloadLoader = new PayloadLoader(dirname(__DIR__) . '/Resources/REST/InputPayloads');
48+
49+
foreach (self::REQUIRED_FORMATS as $format) {
50+
yield new EndpointRequestDefinition(
51+
'POST',
52+
'/api/ibexa/v2/content-type/load-field-definitions-from-expression',
53+
'FieldDefinitionInfoList',
54+
"application/vnd.ibexa.api.FieldDefinitionInfoList+$format",
55+
['HTTP_X-SiteAccess' => 'admin'],
56+
$payloadLoader->loadPayload(self::INPUT_MEDIA_TYPE, 'json'),
57+
null,
58+
'FieldDefinitionInfoList'
59+
);
60+
}
61+
}
62+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"FieldDefinitionExpression": {
3+
"expression": "{Content}/{folder}/{name}"
4+
}
5+
}

0 commit comments

Comments
 (0)