Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IBX-6957: Moved UDW endpoints to REST API #989

Merged
merged 12 commits into from
Nov 21, 2023
5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -945,11 +945,6 @@ parameters:
count: 1
path: src/bundle/Controller/URLWildcardController.php

-
message: "#^Method Ibexa\\\\Bundle\\\\AdminUi\\\\Controller\\\\UniversalDiscoveryController\\:\\:locationsAction\\(\\) has no return type specified\\.$#"
count: 1
path: src/bundle/Controller/UniversalDiscoveryController.php

-
message: "#^Cannot access property \\$languageCode on Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\Language\\|null\\.$#"
count: 1
Expand Down
140 changes: 68 additions & 72 deletions src/bundle/Controller/UniversalDiscoveryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@

namespace Ibexa\Bundle\AdminUi\Controller;

use Ibexa\Contracts\AdminUi\Controller\Controller;
use Ibexa\AdminUi\REST\Value\UniversalDiscovery\AccordionData;
use Ibexa\AdminUi\REST\Value\UniversalDiscovery\LocationData;
use Ibexa\AdminUi\REST\Value\UniversalDiscovery\LocationListData;
use Ibexa\AdminUi\REST\Value\UniversalDiscovery\RequestQuery;
use Ibexa\Contracts\AdminUi\UniversalDiscovery\Provider;
use Ibexa\Contracts\Core\Repository\Values\Content\Location;
use Ibexa\Contracts\Core\Repository\Values\Content\Query;
use Symfony\Component\HttpFoundation\JsonResponse;
use Ibexa\Rest\Server\Controller;
use Symfony\Component\HttpFoundation\Request;

class UniversalDiscoveryController extends Controller
Expand All @@ -26,9 +27,9 @@ public function __construct(
$this->provider = $provider;
}

public function locationsAction(Request $request)
public function locationsAction(Request $request): LocationListData
{
return new JsonResponse(
return new LocationListData(
$this->provider->getLocations(
explode(
',',
Expand All @@ -38,87 +39,82 @@ public function locationsAction(Request $request)
);
}

public function locationAction(
Request $request,
int $locationId
): JsonResponse {
$offset = $request->query->getInt('offset', 0);
$limit = $request->query->getInt('limit', 25);
$sortClauseName = $request->query->getAlpha('sortClause', Provider::SORT_CLAUSE_DATE_PUBLISHED);
$sortOrder = $request->query->getAlpha('sortOrder', Query::SORT_ASC);

$sortClause = $this->provider->getSortClause($sortClauseName, $sortOrder);
public function locationAction(RequestQuery $requestQuery): LocationData
{
$data = $this->provider->getLocationData(
$requestQuery->getLocationId(),
$requestQuery->getOffset(),
$requestQuery->getLimit(),
$requestQuery->getSortClause()
);

return new JsonResponse(
$this->provider->getLocationData($locationId, $offset, $limit, $sortClause)
return new LocationData(
$data['subitems'],
$data['location'] ?? null,
$data['bookmarked'] ?? null,
$data['permissions'] ?? null,
$data['version'] ?? null,
);
}

public function locationGridViewAction(
Request $request,
int $locationId
): JsonResponse {
$offset = $request->query->getInt('offset', 0);
$limit = $request->query->getInt('limit', 25);
$sortClauseName = $request->query->getAlpha('sortClause', Provider::SORT_CLAUSE_DATE_PUBLISHED);
$sortOrder = $request->query->getAlpha('sortOrder', Query::SORT_ASC);

$sortClause = $this->provider->getSortClause($sortClauseName, $sortOrder);
public function locationGridViewAction(RequestQuery $requestQuery): LocationData
{
$data = $this->provider->getLocationGridViewData(
$requestQuery->getLocationId(),
$requestQuery->getOffset(),
$requestQuery->getLimit(),
$requestQuery->getSortClause()
);

return new JsonResponse(
$this->provider->getLocationGridViewData($locationId, $offset, $limit, $sortClause)
return new LocationData(
$data['subitems'],
$data['location'] ?? null,
$data['bookmarked'] ?? null,
$data['permissions'] ?? null,
$data['version'] ?? null,
);
}

public function accordionAction(
Request $request,
int $locationId
): JsonResponse {
$limit = $request->query->getInt('limit', 25);
$sortClauseName = $request->query->getAlpha('sortClause', Provider::SORT_CLAUSE_DATE_PUBLISHED);
$sortOrder = $request->query->getAlpha('sortOrder', Query::SORT_ASC);
$rootLocationId = $request->query->getInt('rootLocationId', Provider::ROOT_LOCATION_ID);
public function accordionAction(RequestQuery $requestQuery): AccordionData
{
$locationId = $requestQuery->getLocationId();
$rootLocationId = $requestQuery->getRootLocationId();

$sortClause = $this->provider->getSortClause($sortClauseName, $sortOrder);
$breadcrumbLocations = $locationId !== $rootLocationId
? $this->provider->getBreadcrumbLocations($locationId, $rootLocationId)
: [];

$columns = $this->provider->getColumns($locationId, $limit, $sortClause, false, $rootLocationId);

return new JsonResponse([
'breadcrumb' => array_map(
function (Location $location) {
return $this->provider->getRestFormat($location);
},
$breadcrumbLocations
),
'columns' => $columns,
]);
$columns = $this->provider->getColumns(
$requestQuery->getLocationId(),
$requestQuery->getLimit(),
$requestQuery->getSortClause(),
false,
$rootLocationId
);

return new AccordionData(
$breadcrumbLocations,
$columns
);
}

public function accordionGridViewAction(
Request $request,
int $locationId
): JsonResponse {
$limit = $request->query->getInt('limit', 25);
$sortClauseName = $request->query->getAlpha('sortClause', Provider::SORT_CLAUSE_DATE_PUBLISHED);
$sortOrder = $request->query->getAlpha('sortOrder', Query::SORT_ASC);
$rootLocationId = $request->query->getInt('rootLocationId', Provider::ROOT_LOCATION_ID);

$sortClause = $this->provider->getSortClause($sortClauseName, $sortOrder);

$columns = $this->provider->getColumns($locationId, $limit, $sortClause, true, $rootLocationId);

return new JsonResponse([
'breadcrumb' => array_map(
function (Location $location) {
return $this->provider->getRestFormat($location);
},
$this->provider->getBreadcrumbLocations($locationId)
),
'columns' => $columns,
]);
public function accordionGridViewAction(RequestQuery $requestQuery): AccordionData
{
$locationId = $requestQuery->getLocationId();
$rootLocationId = $requestQuery->getRootLocationId();

$columns = $this->provider->getColumns(
$locationId,
$requestQuery->getLimit(),
$requestQuery->getSortClause(),
true,
$rootLocationId
);

return new AccordionData(
$this->provider->getBreadcrumbLocations($locationId),
$columns
);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Bundle\AdminUi\ControllerArgumentResolver;

use Ibexa\AdminUi\Exception\ValidationFailedException;
use Ibexa\AdminUi\REST\Value\UniversalDiscovery\RequestQuery;
use Ibexa\AdminUi\Validator\Builder\REST\UniversalDiscoveryRequestValidatorBuilder;
use Ibexa\Contracts\AdminUi\UniversalDiscovery\Provider;
use Ibexa\Contracts\Core\Repository\Values\Content\Query;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
use Symfony\Component\Validator\Validator\ValidatorInterface;

final class UniversalDiscoveryRequestQueryArgumentResolver implements ArgumentValueResolverInterface
{
private Provider $provider;

private ValidatorInterface $validator;

public function __construct(
Provider $provider,
ValidatorInterface $validator
) {
$this->provider = $provider;
$this->validator = $validator;
}

public function supports(Request $request, ArgumentMetadata $argument): bool
{
return RequestQuery::class === $argument->getType()
&& 'requestQuery' === $argument->getName();
}

/**
* @return iterable<\Ibexa\AdminUi\REST\Value\UniversalDiscovery\RequestQuery>
*/
public function resolve(Request $request, ArgumentMetadata $argument): iterable
{
$this->validate($request);

$query = $request->query;

yield new RequestQuery(
$request->attributes->getInt('locationId'),
$query->getInt('offset'),
$query->getInt('limit', 25),
$this->getSortClause($query),
$query->getInt('rootLocationId', Provider::ROOT_LOCATION_ID)
);
}

private function validate(Request $request): void
{
$validatorBuilder = new UniversalDiscoveryRequestValidatorBuilder($this->validator);
$validatorBuilder->validateLocationId($request);

$errors = $validatorBuilder->build()->getViolations();
if ($errors->count() > 0) {
throw new ValidationFailedException('request', $errors);
}
}

private function getSortClause(ParameterBag $query): Query\SortClause
{
return $this->provider->getSortClause(
$query->getAlpha('sortClause', Provider::SORT_CLAUSE_DATE_PUBLISHED),
$query->getAlpha('sortOrder', Query::SORT_ASC)
);
}
}
39 changes: 0 additions & 39 deletions src/bundle/Resources/config/routing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -842,45 +842,6 @@ ibexa.object_state.content_state.update:
defaults:
_controller: 'Ibexa\Bundle\AdminUi\Controller\ObjectStateController::updateContentStateAction'

#
# Universal Discovery Widget
#

ibexa.udw.location.data:
path: /module/universal-discovery/location/{locationId}
options:
expose: true
defaults:
_controller: 'Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController::locationAction'

ibexa.udw.locations.data:
path: /module/universal-discovery/locations
options:
expose: true
defaults:
_controller: 'Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController::locationsAction'

ibexa.udw.location.gridview.data:
path: /module/universal-discovery/location/{locationId}/gridview
options:
expose: true
defaults:
_controller: 'Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController::locationGridViewAction'

ibexa.udw.accordion.data:
path: /module/universal-discovery/accordion/{locationId}
options:
expose: true
defaults:
_controller: 'Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController::accordionAction'

ibexa.udw.accordion.gridview.data:
path: /module/universal-discovery/accordion/{locationId}/gridview
options:
expose: true
defaults:
_controller: 'Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController::accordionGridViewAction'

#
# Bookmark manager
#
Expand Down
39 changes: 39 additions & 0 deletions src/bundle/Resources/config/routing_rest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,42 @@ ibexa.content_type.field_definition.reorder:
controller: 'Ibexa\Bundle\AdminUi\Controller\FieldDefinitionController::reorderFieldDefinitionsAction'
requirements:
contentTypeGroupId: \d+

#
# Universal Discovery Widget
#

ibexa.udw.location.data:
path: /module/universal-discovery/location/{locationId}
controller: 'Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController::locationAction'
methods: [GET]
options:
expose: true

ibexa.udw.location.gridview.data:
path: /module/universal-discovery/location/{locationId}/gridview
controller: 'Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController::locationGridViewAction'
methods: [GET]
options:
expose: true

ibexa.udw.locations.data:
path: /module/universal-discovery/locations
controller: 'Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController::locationsAction'
methods: [GET]
options:
expose: true

ibexa.udw.accordion.data:
path: /module/universal-discovery/accordion/{locationId}
controller: 'Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController::accordionAction'
methods: [GET]
options:
expose: true

ibexa.udw.accordion.gridview.data:
path: /module/universal-discovery/accordion/{locationId}/gridview
controller: 'Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController::accordionGridViewAction'
methods: [GET]
options:
expose: true
1 change: 1 addition & 0 deletions src/bundle/Resources/config/services.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
imports:
- { resource: services/service_aliases.yaml }
- { resource: services/config.yaml }
- { resource: services/controller_argument_resolvers.yaml }
- { resource: services/controllers.yaml }
- { resource: services/tabs.yaml }
- { resource: services/menu.yaml }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false

Ibexa\Bundle\AdminUi\ControllerArgumentResolver\UniversalDiscoveryRequestQueryArgumentResolver:
tags:
- { name: controller.argument_value_resolver, priority: 50 }
2 changes: 1 addition & 1 deletion src/bundle/Resources/config/services/controllers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ services:
- controller.service_arguments

Ibexa\Bundle\AdminUi\Controller\UniversalDiscoveryController:
parent: Ibexa\Contracts\AdminUi\Controller\Controller
parent: Ibexa\Rest\Server\Controller
autowire: true
tags:
- controller.service_arguments
Expand Down
Loading
Loading