Skip to content

Commit 43e13b9

Browse files
committed
Merged branch '4.6'
2 parents 85833bf + afd71af commit 43e13b9

File tree

12 files changed

+303
-0
lines changed

12 files changed

+303
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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\SiteAccess;
10+
11+
use Ibexa\AdminUi\REST\Value\SiteAccess\SiteAccessesList;
12+
use Ibexa\Contracts\Core\Repository\Values\Content\Location;
13+
use Ibexa\Rest\Server\Controller as RestController;
14+
use Ibexa\Rest\Server\Exceptions\BadRequestException;
15+
use Psr\Container\NotFoundExceptionInterface;
16+
use Symfony\Component\DependencyInjection\ServiceLocator;
17+
use Symfony\Component\HttpFoundation\Request;
18+
19+
final class SiteAccessController extends RestController
20+
{
21+
/**
22+
* @phpstan-param \Symfony\Component\DependencyInjection\ServiceLocator<\Ibexa\AdminUi\Siteaccess\SiteaccessResolverInterface> $siteAccessResolvers
23+
*/
24+
public function __construct(
25+
private readonly ServiceLocator $siteAccessResolvers
26+
) {
27+
}
28+
29+
/**
30+
* @throws \Psr\Container\ContainerExceptionInterface
31+
* @throws \Psr\Container\NotFoundExceptionInterface
32+
*/
33+
public function loadForLocation(Request $request, Location $location): SiteAccessesList
34+
{
35+
$resolverType = $request->query->get('resolver_type', 'non_admin');
36+
37+
try {
38+
$siteAccessResolver = $this->siteAccessResolvers->get($resolverType);
39+
} catch (NotFoundExceptionInterface $e) {
40+
throw new BadRequestException($e->getMessage(), $e->getCode(), $e);
41+
}
42+
43+
return new SiteAccessesList($siteAccessResolver->getSiteAccessesListForLocation($location));
44+
}
45+
}

src/bundle/Resources/config/routing_rest.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,14 @@ ibexa.rest.content_type.load_field_definitions_from_expression:
152152
methods: [POST]
153153
options:
154154
expose: true
155+
156+
#
157+
# Site Access
158+
#
159+
160+
ibexa.rest.site_access.load_for_location:
161+
path: /site-access/by-location/{locationId}
162+
controller: 'Ibexa\Bundle\AdminUi\Controller\SiteAccess\SiteAccessController::loadForLocation'
163+
methods: [GET]
164+
options:
165+
expose: true

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,13 @@ services:
268268
$fieldsByExpressionService: '@Ibexa\Contracts\AdminUi\ContentType\ContentTypeFieldsByExpressionServiceInterface'
269269
tags:
270270
- controller.service_arguments
271+
272+
Ibexa\Bundle\AdminUi\Controller\SiteAccess\SiteAccessController:
273+
parent: Ibexa\Rest\Server\Controller
274+
autowire: true
275+
arguments:
276+
$siteAccessResolvers: !tagged_locator
277+
tag: 'ibexa.site_access.resolver'
278+
index_by: type
279+
tags:
280+
- controller.service_arguments

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,10 @@ services:
141141
parent: Ibexa\Contracts\Rest\Output\ValueObjectVisitor
142142
tags:
143143
- { name: ibexa.rest.output.value_object.visitor, type: Ibexa\AdminUi\REST\Value\ContentType\FieldDefinitionInfoList }
144+
#
145+
# Site Accesses
146+
#
147+
Ibexa\AdminUi\REST\Output\ValueObjectVisitor\SiteAccess\SiteAccessesListVisitor:
148+
parent: Ibexa\Contracts\Rest\Output\ValueObjectVisitor
149+
tags:
150+
- { name: ibexa.rest.output.value_object.visitor, type: Ibexa\AdminUi\REST\Value\SiteAccess\SiteAccessesList }

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ services:
1818
Ibexa\AdminUi\Siteaccess\NonAdminSiteaccessResolver:
1919
arguments:
2020
$siteAccessGroups: '%ibexa.site_access.groups%'
21+
tags:
22+
- { name: 'ibexa.site_access.resolver', type: 'non_admin' }
2123

2224
Ibexa\AdminUi\Siteaccess\AdminSiteaccessPreviewVoter:
2325
arguments:
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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\SiteAccess;
10+
11+
use Ibexa\Contracts\Rest\Output\Generator;
12+
use Ibexa\Contracts\Rest\Output\ValueObjectVisitor;
13+
use Ibexa\Contracts\Rest\Output\Visitor;
14+
15+
final class SiteAccessesListVisitor extends ValueObjectVisitor
16+
{
17+
/**
18+
* @param \Ibexa\AdminUi\REST\Value\SiteAccess\SiteAccessesList $data
19+
*/
20+
public function visit(Visitor $visitor, Generator $generator, $data): void
21+
{
22+
$generator->startObjectElement('SiteAccessesList');
23+
$visitor->setHeader('Content-Type', $generator->getMediaType('SiteAccessesList'));
24+
25+
$generator->startList('values');
26+
foreach ($data->getSiteAccesses() as $siteAccess) {
27+
$generator->startObjectElement('SiteAccess');
28+
29+
$generator->valueElement('name', $siteAccess->name);
30+
31+
$generator->endObjectElement('SiteAccess');
32+
}
33+
$generator->endList('values');
34+
35+
$generator->endObjectElement('SiteAccessesList');
36+
}
37+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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\SiteAccess;
10+
11+
use Ibexa\Rest\Value as RestValue;
12+
13+
final class SiteAccessesList extends RestValue
14+
{
15+
/**
16+
* @param \Ibexa\Core\MVC\Symfony\SiteAccess[] $siteAccesses
17+
*/
18+
public function __construct(
19+
private readonly array $siteAccesses = []
20+
) {
21+
}
22+
23+
/**
24+
* @return \Ibexa\Core\MVC\Symfony\SiteAccess[]
25+
*/
26+
public function getSiteAccesses(): array
27+
{
28+
return $this->siteAccesses;
29+
}
30+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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\Request\Value\EndpointRequestDefinition;
12+
13+
/**
14+
* Coverage for /site-access/by-location/{locationId} REST endpoint.
15+
*/
16+
final class GetSiteAccessesListTest extends BaseAdminUiRestWebTestCase
17+
{
18+
/**
19+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
20+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
21+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ForbiddenException
22+
*/
23+
protected function setUp(): void
24+
{
25+
parent::setUp();
26+
27+
// to create a new user before logging-in via REST
28+
$this->getIbexaTestCore()->setAdministratorUser();
29+
30+
$this->loginAsUser(
31+
$this->createUserWithPolicies(
32+
'editor',
33+
[
34+
'user/login' => [],
35+
'content/read' => [],
36+
'content/versionread' => [],
37+
]
38+
)
39+
);
40+
}
41+
42+
protected static function getEndpointsToTest(): iterable
43+
{
44+
foreach (self::REQUIRED_FORMATS as $format) {
45+
yield new EndpointRequestDefinition(
46+
'GET',
47+
'/api/ibexa/v2/site-access/by-location/2?resolver_type=non_admin',
48+
'SiteAccessesList',
49+
"application/vnd.ibexa.api.SiteAccessesList+$format",
50+
['HTTP_X-SiteAccess' => 'admin'],
51+
null,
52+
null,
53+
'SiteAccessesList'
54+
);
55+
}
56+
}
57+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-04/schema#",
3+
"type": "object",
4+
"properties": {
5+
"SiteAccessesList": {
6+
"type": "object",
7+
"properties": {
8+
"_media-type": {
9+
"type": "string"
10+
},
11+
"values": {
12+
"type": "array",
13+
"items": [
14+
{
15+
"type": "object",
16+
"properties": {
17+
"_media-type": {
18+
"type": "string"
19+
},
20+
"name": {
21+
"type": "string"
22+
}
23+
},
24+
"required": [
25+
"_media-type",
26+
"name"
27+
]
28+
}
29+
]
30+
}
31+
},
32+
"required": [
33+
"_media-type",
34+
"values"
35+
]
36+
}
37+
},
38+
"required": [
39+
"SiteAccessesList"
40+
]
41+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
3+
<xs:element name="SiteAccessesList">
4+
<xs:complexType>
5+
<xs:sequence>
6+
<xs:element name="SiteAccess" maxOccurs="unbounded" minOccurs="0">
7+
<xs:complexType>
8+
<xs:sequence>
9+
<xs:element name="name" type="xs:string" />
10+
</xs:sequence>
11+
<xs:attribute name="media-type" type="xs:string" use="required" />
12+
</xs:complexType>
13+
</xs:element>
14+
</xs:sequence>
15+
<xs:attribute name="media-type" type="xs:string" use="required" />
16+
</xs:complexType>
17+
</xs:element>
18+
</xs:schema>

0 commit comments

Comments
 (0)