Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
c4fbe88
IBX-8176: Implemented routing language expression extension handling …
barw4 Jun 5, 2024
39bef0d
IBX-8176: CS
barw4 Jun 5, 2024
7226892
IBX-8176: Added unit tests
barw4 Jun 5, 2024
5d205b5
IBX-8176: Enable `strict_types`
barw4 Jun 5, 2024
03a201e
IBX-8176: Enable `strict_types`
barw4 Jun 5, 2024
9e28775
IBX-8176: Applied review remarks
barw4 Jun 5, 2024
a8797a1
IBX-8176: Fixed type
barw4 Jun 5, 2024
522182d
IBX-8176: Refactored solution
barw4 Jun 18, 2024
ad2477a
IBX-8176: Removed 'future' implementation
barw4 Jun 18, 2024
d6fc4e8
IBX-8176: Applied review remarks
barw4 Jun 19, 2024
3aca756
IBX-8176: Fix route definition
barw4 Jun 19, 2024
e0fa10a
IBX-8176: Refactoring
barw4 Jun 19, 2024
b00d871
IBX-8176: Rename the expression function
barw4 Jun 19, 2024
f6f1e07
IBX-8176: Applied review remark
barw4 Jun 23, 2024
0a70b8d
IBX-8176: Added generation of `options` route for newly added `condit…
barw4 Jun 27, 2024
c893545
IBX-8176: Fixed tests
barw4 Jun 28, 2024
ee28990
IBX-8176: Created new OpenAPI compatible location moving endpoint
barw4 May 20, 2024
f77bde7
IBX-8176: Removed deprecation
barw4 May 27, 2024
1477785
IBX-8176: Refactored routing to use the `is_content_type_compatible` …
barw4 Jun 6, 2024
4c1d771
IBX-8176: Applied review remarks
barw4 Jun 20, 2024
f425980
IBX-8176: Fixed routing definition
barw4 Jun 24, 2024
ba04ba7
IBX-8176: Added `options_route_suffix`
barw4 Jun 27, 2024
9ce1117
IBX-8176: Updated routing
barw4 Jun 28, 2024
b8d8ab7
IBX-8176: CS
barw4 Jul 2, 2024
8aa0b28
IBX-8176: Implemented routing language expression extension handling …
barw4 Jun 5, 2024
050b8d3
IBX-8176: Added unit tests
barw4 Jun 5, 2024
1a2dcd0
IBX-8176: Applied review remarks
barw4 Jun 5, 2024
4e6a696
IBX-8176: Refactored solution
barw4 Jun 18, 2024
86951ef
IBX-8176: Refactoring
barw4 Jun 19, 2024
0baa83b
IBX-8176: Rename the expression function
barw4 Jun 19, 2024
5c8cfd1
IBX-8180: Added integration test
barw4 Jun 7, 2024
ae16557
IBX-8180: Fixed routing
barw4 Jul 2, 2024
2fc7b69
IBX-8176: Implemented routing language expression extension handling …
barw4 Jun 5, 2024
d977b9a
IBX-8176: Added unit tests
barw4 Jun 5, 2024
591af40
IBX-8176: Applied review remarks
barw4 Jun 5, 2024
e303b2b
IBX-8176: Refactored solution
barw4 Jun 18, 2024
6c56e4e
IBX-8176: Applied review remarks
barw4 Jun 19, 2024
8d4e952
IBX-8176: Refactoring
barw4 Jun 19, 2024
c29e384
IBX-8176: Rename the expression function
barw4 Jun 19, 2024
5b3b0f2
IBX-8172: OpenAPI compatible location copy endpoint
barw4 Jun 23, 2024
b3cfd28
IBX-8172: Update functional tests
barw4 Jun 28, 2024
318b321
IBX-8172: Fixed routing
barw4 Jul 3, 2024
d3a627d
IBX-8172: Fixed routing
barw4 Jul 3, 2024
85ea622
IBX-8172: Applied review remark
barw4 Jul 3, 2024
0d9e993
IBX-8172: Updated routing and test
barw4 Jul 24, 2024
0393df9
IBX-8172: Updated `HttpOptionsTest`
barw4 Jul 24, 2024
57bc5c0
IBX-8172: Fixed routing
barw4 Jul 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/bundle/Resources/config/input_parsers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -890,3 +890,11 @@ services:
$validator: '@validator'
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.MoveUserGroupInput }

Ibexa\Rest\Server\Input\Parser\CopyLocationInput:
parent: Ibexa\Rest\Server\Common\Parser
arguments:
$locationService: '@ibexa.api.service.location'
$validator: '@validator'
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.CopyLocationInput }
10 changes: 10 additions & 0 deletions src/bundle/Resources/config/routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,16 @@ ibexa.rest.languages.view:

# Locations

ibexa.rest.location.copy:
path: /content/locations/{locationPath}
controller: Ibexa\Rest\Server\Controller\Location::copy
condition: 'ibexa_get_media_type(request) === "CopyLocationInput"'
methods: [POST]
options:
options_route_suffix: 'CopyLocationInput'
requirements:
locationPath: "[0-9/]+"

ibexa.rest.trash_location:
path: /content/locations/{locationPath}
controller: Ibexa\Rest\Server\Controller\Trash::trashLocation
Expand Down
28 changes: 28 additions & 0 deletions src/lib/Server/Controller/Location.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,34 @@ public function copySubtree($locationPath, Request $request)
);
}

/**
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
*/
public function copy(string $locationPath, Request $request): Values\ResourceCreated
{
$locationId = $this->extractLocationIdFromPath($locationPath);
$location = $this->locationService->loadLocation($locationId);

$destinationLocation = $this->inputDispatcher->parse(
new Message(
['Content-Type' => $request->headers->get('Content-Type')],
$request->getContent(),
),
);

$newLocation = $this->locationService->copySubtree($location, $destinationLocation);

return new Values\ResourceCreated(
$this->router->generate(
'ibexa.rest.load_location',
[
'locationPath' => trim($newLocation->pathString, '/'),
],
)
);
}

/**
* Moves a subtree to a new location.
*
Expand Down
22 changes: 22 additions & 0 deletions src/lib/Server/Input/Parser/CopyLocationInput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?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\Rest\Server\Input\Parser;

use Ibexa\Rest\Server\Validation\Builder\Input\Parser\BaseInputParserValidatorBuilder;
use Ibexa\Rest\Server\Validation\Builder\Input\Parser\CopyLocationInputValidatorBuilder;

final class CopyLocationInput extends AbstractDestinationLocationParser
{
protected const string PARSER = 'CopyLocationInput';

protected function getValidatorBuilder(): BaseInputParserValidatorBuilder
{
return new CopyLocationInputValidatorBuilder($this->validator);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?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\Rest\Server\Validation\Builder\Input\Parser;

use Ibexa\Rest\Server\Input\Parser\CopyLocationInput;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints as Assert;

final class CopyLocationInputValidatorBuilder extends BaseInputParserValidatorBuilder
{
protected function buildConstraint(): Constraint
{
return new Assert\Collection(
[
CopyLocationInput::DESTINATION_KEY => [
new Assert\NotBlank(),
new Assert\Type('string'),
new Assert\Regex('/^(\/\d+)+$/'),
],
],
);
}
}
1 change: 1 addition & 0 deletions tests/bundle/Functional/HttpOptionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public function providerForTestHttpOptions(): array
['/content/objectstategroups/1/objectstates/1', ['GET', 'PATCH', 'DELETE']],
['/content/objects/1/objectstates', ['GET', 'PATCH']],
['/content/locations', ['GET']],
['/content/locations/1/2', ['POST'], 'CopyLocationInput+json'],
['/content/locations/1/2', ['POST'], 'MoveLocationInput+json'],
['/content/locations/1/2', ['POST'], 'SwapLocationInput+json'],
['/content/locations/1/2', ['GET', 'PATCH', 'DELETE', 'COPY', 'MOVE', 'SWAP']],
Expand Down
19 changes: 19 additions & 0 deletions tests/bundle/Functional/LocationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -333,4 +333,23 @@ public function testSwap(string $locationHref): void

self::assertHttpResponseCodeEquals($response, 204);
}

/**
* @depends testMoveLocation
*/
public function testCopy(string $locationHref): void
{
$request = $this->createHttpRequest(
'POST',
$locationHref,
'CopyLocationInput+json',
'',
json_encode(['CopyLocationInput' => ['destination' => '/1/2']]) ?: '',
);

$response = $this->sendHttpRequest($request);

self::assertHttpResponseCodeEquals($response, 201);
self::assertHttpResponseHasHeader($response, 'Location');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function getCriteriaPayloads(): iterable
'is container' => [
'json',
$this->buildJsonCriterionQuery('"IsContainerCriterion": true'),
12,
13,
],
'is not container' => [
'json',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function getCriteriaPayloads(): iterable
'is not user based' => [
'json',
$this->buildJsonCriterionQuery('"IsUserBasedCriterion": false'),
12,
13,
],
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ public function getCriteriaPayloads(): iterable
'identifier with target group' => [
'json',
$this->buildJsonCriterionQuery('"ObjectStateIdentifierCriterion": {"value": "not_locked", "target": "ez_lock"}'),
14,
15,
],
'identifier without target group' => [
'json',
$this->buildJsonCriterionQuery('"ObjectStateIdentifierCriterion": {"value": "not_locked", "target": null}'),
14,
15,
],
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ public function getCriteriaPayloads(): iterable
'multiple Sections' => [
'json',
$this->buildJsonCriterionQuery('"SectionIdentifierCriterion": "users,standard"'),
// 2 users + 5 groups + 1 Home Folder
8,
// 2 users + 6 groups + 1 Home Folder
9,
],
];
}
Expand Down
45 changes: 45 additions & 0 deletions tests/lib/Server/Input/Parser/CopyLocationInputTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?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\Tests\Rest\Server\Input\Parser;

use Ibexa\Contracts\Core\Repository\LocationService;
use Ibexa\Rest\Server\Input\Parser\CopyLocationInput;
use Symfony\Component\Validator\Validation;

final class CopyLocationInputTest extends AbstractDestinationLocationInputTest
{
private const string PARSER = 'CopyLocationInput';

public function testParse(): void
{
$this->parse();
}

public function testParseExceptionOnMissingDestinationElement(): void
{
$this->parseExceptionOnMissingDestinationElement(self::PARSER);
}

public function testParseExceptionOnInvalidDestinationElement(): void
{
$this->parseExceptionOnInvalidDestinationElement(self::PARSER);
}

protected function internalGetParser(): CopyLocationInput
{
$locationService = $this->createMock(LocationService::class);
$this->locationService = $locationService;
$this->validator = Validation::createValidator();

return new CopyLocationInput(
$this->locationService,
$this->validator,
);
}
}