Skip to content

Commit a1d6cbe

Browse files
authored
IBX-6620: Added image criterions rest input parsers (#76)
1 parent 4a146e5 commit a1d6cbe

17 files changed

+755
-12
lines changed

phpstan-baseline.neon

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ parameters:
292292

293293
-
294294
message: "#^Cannot access offset mixed on Ibexa\\\\Contracts\\\\Rest\\\\Input\\\\Parser\\.$#"
295-
count: 2
295+
count: 1
296296
path: src/contracts/Input/ParsingDispatcher.php
297297

298298
-
@@ -740,16 +740,6 @@ parameters:
740740
count: 1
741741
path: src/lib/Input/Parser/ContentObjectStates.php
742742

743-
-
744-
message: "#^Instantiated class Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\User\\\\Limitation\\\\SiteaccessLimitation not found\\.$#"
745-
count: 1
746-
path: src/lib/Input/ParserTools.php
747-
748-
-
749-
message: "#^Method Ibexa\\\\Rest\\\\Input\\\\ParserTools\\:\\:getLimitationByIdentifier\\(\\) should return Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\User\\\\Limitation but returns Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\User\\\\Limitation\\\\SiteaccessLimitation\\.$#"
750-
count: 1
751-
path: src/lib/Input/ParserTools.php
752-
753743
-
754744
message: "#^Method Ibexa\\\\Rest\\\\Input\\\\ParserTools\\:\\:isEmbeddedObject\\(\\) has parameter \\$objectElement with no value type specified in iterable type array\\.$#"
755745
count: 1

src/bundle/Resources/config/input_parsers.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,3 +814,38 @@ services:
814814
arguments:
815815
- 'sectionId'
816816
- 'Ibexa\Contracts\Core\Repository\Values\User\Limitation\SectionLimitation'
817+
818+
Ibexa\Rest\Server\Input\Parser\Criterion\ImageMimeType:
819+
parent: Ibexa\Rest\Server\Common\Parser
820+
arguments:
821+
$validator: '@validator'
822+
tags:
823+
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.ImageMimeType }
824+
825+
Ibexa\Rest\Server\Input\Parser\Criterion\ImageFileSize:
826+
parent: Ibexa\Rest\Server\Common\Parser
827+
arguments:
828+
$validator: '@validator'
829+
tags:
830+
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.ImageFileSize }
831+
832+
Ibexa\Rest\Server\Input\Parser\Criterion\ImageOrientation:
833+
parent: Ibexa\Rest\Server\Common\Parser
834+
arguments:
835+
$validator: '@validator'
836+
tags:
837+
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.ImageOrientation }
838+
839+
Ibexa\Rest\Server\Input\Parser\Criterion\ImageDimensions:
840+
parent: Ibexa\Rest\Server\Common\Parser
841+
arguments:
842+
$validator: '@validator'
843+
tags:
844+
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.ImageDimensions }
845+
846+
Ibexa\Rest\Server\Input\Parser\Criterion\Image:
847+
parent: Ibexa\Rest\Server\Common\Parser
848+
arguments:
849+
$validator: '@validator'
850+
tags:
851+
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.Image }

src/lib/Input/ParserTools.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\ParentOwnerLimitation;
1818
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\ParentUserGroupLimitation;
1919
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\SectionLimitation;
20-
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\SiteaccessLimitation;
20+
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\SiteAccessLimitation;
2121
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\SubtreeLimitation;
2222
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\UserGroupLimitation;
2323
use Ibexa\Contracts\Rest\Exceptions;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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\Rest\Server\Exceptions;
10+
11+
use Symfony\Component\Validator\ConstraintViolationListInterface;
12+
use Throwable;
13+
14+
final class ValidationFailedException extends BadRequestException
15+
{
16+
private ConstraintViolationListInterface $errors;
17+
18+
public function __construct(
19+
string $contextName,
20+
ConstraintViolationListInterface $errors,
21+
?Throwable $previous = null
22+
) {
23+
$this->errors = $errors;
24+
25+
parent::__construct("Input data validation failed for $contextName", 1, $previous);
26+
}
27+
28+
public function getErrors(): ConstraintViolationListInterface
29+
{
30+
return $this->errors;
31+
}
32+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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\Rest\Server\Input\Parser\Criterion;
10+
11+
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image as ImageCriterion;
12+
use Ibexa\Contracts\Rest\Input\ParsingDispatcher;
13+
use Ibexa\Rest\Input\BaseParser;
14+
use Ibexa\Rest\Server\Exceptions\ValidationFailedException;
15+
use Ibexa\Rest\Server\Validation\Builder\Input\Parser\Criterion\ImageCriterionValidatorBuilder;
16+
use Symfony\Component\Validator\Validator\ValidatorInterface;
17+
18+
final class Image extends BaseParser
19+
{
20+
public const IMAGE_CRITERION = 'ImageCriterion';
21+
public const FIELD_DEF_IDENTIFIER_KEY = 'fieldDefIdentifier';
22+
public const MIME_TYPES_KEY = 'mimeTypes';
23+
24+
private ValidatorInterface $validator;
25+
26+
public function __construct(ValidatorInterface $validator)
27+
{
28+
$this->validator = $validator;
29+
}
30+
31+
/**
32+
* @param array<mixed> $data
33+
*
34+
* @return \Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image
35+
*
36+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
37+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidCriterionArgumentException
38+
*/
39+
public function parse(array $data, ParsingDispatcher $parsingDispatcher): ImageCriterion
40+
{
41+
$this->validateInputArray($data);
42+
43+
$criterionData = $data[self::IMAGE_CRITERION];
44+
45+
return new ImageCriterion(
46+
$criterionData[self::FIELD_DEF_IDENTIFIER_KEY],
47+
$this->extractImageCriteria($criterionData)
48+
);
49+
}
50+
51+
/**
52+
* @param array<mixed> $data
53+
*/
54+
private function validateInputArray(array $data): void
55+
{
56+
$validatorBuilder = new ImageCriterionValidatorBuilder($this->validator);
57+
$validatorBuilder->validateInputArray($data);
58+
$violations = $validatorBuilder->build()->getViolations();
59+
60+
if ($violations->count() > 0) {
61+
throw new ValidationFailedException(
62+
self::IMAGE_CRITERION,
63+
$violations
64+
);
65+
}
66+
}
67+
68+
/**
69+
* @param array<mixed> $data
70+
*
71+
* @return array{
72+
* mimeTypes?: string|array<string>,
73+
* size?: array{min?: int|null, max?: int|null},
74+
* width?: array{min?: int|null, max?: int|null},
75+
* height?: array{min?: int|null, max?: int|null},
76+
* orientation?: string|array<string>,
77+
* }
78+
*/
79+
private function extractImageCriteria(array $data): array
80+
{
81+
return array_filter(
82+
$data,
83+
static fn (string $criteria): bool => self::FIELD_DEF_IDENTIFIER_KEY !== $criteria,
84+
ARRAY_FILTER_USE_KEY
85+
);
86+
}
87+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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\Rest\Server\Input\Parser\Criterion;
10+
11+
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\Dimensions as ImageDimensionsCriterion;
12+
use Ibexa\Contracts\Rest\Input\ParsingDispatcher;
13+
use Ibexa\Rest\Input\BaseParser;
14+
use Ibexa\Rest\Server\Exceptions\ValidationFailedException;
15+
use Ibexa\Rest\Server\Validation\Builder\Input\Parser\Criterion\ImageDimensionsCriterionValidatorBuilder;
16+
use Symfony\Component\Validator\Validator\ValidatorInterface;
17+
18+
final class ImageDimensions extends BaseParser
19+
{
20+
public const IMAGE_DIMENSIONS_CRITERION = 'ImageDimensionsCriterion';
21+
public const FIELD_DEF_IDENTIFIER_KEY = 'fieldDefIdentifier';
22+
public const WIDTH_KEY = 'width';
23+
public const HEIGHT_KEY = 'height';
24+
25+
private ValidatorInterface $validator;
26+
27+
public function __construct(ValidatorInterface $validator)
28+
{
29+
$this->validator = $validator;
30+
}
31+
32+
/**
33+
* @param array<mixed> $data
34+
*
35+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
36+
*/
37+
public function parse(array $data, ParsingDispatcher $parsingDispatcher): ImageDimensionsCriterion
38+
{
39+
$this->validateInputArray($data);
40+
41+
$criterionData = $data[self::IMAGE_DIMENSIONS_CRITERION];
42+
43+
return new ImageDimensionsCriterion(
44+
$criterionData[self::FIELD_DEF_IDENTIFIER_KEY],
45+
$this->extractImageCriteria($criterionData)
46+
);
47+
}
48+
49+
/**
50+
* @param array<mixed> $data
51+
*/
52+
private function validateInputArray(array $data): void
53+
{
54+
$validatorBuilder = new ImageDimensionsCriterionValidatorBuilder($this->validator);
55+
$validatorBuilder->validateInputArray($data);
56+
$violations = $validatorBuilder->build()->getViolations();
57+
58+
if ($violations->count() > 0) {
59+
throw new ValidationFailedException(
60+
self::IMAGE_DIMENSIONS_CRITERION,
61+
$violations
62+
);
63+
}
64+
}
65+
66+
/**
67+
* @param array<mixed> $data
68+
*
69+
* @return array{
70+
* width?: array{min?: int|null, max?: int|null},
71+
* height?: array{min?: int|null, max?: int|null},
72+
* }
73+
*/
74+
private function extractImageCriteria(array $data): array
75+
{
76+
return array_filter(
77+
$data,
78+
static fn (string $criteria): bool => self::FIELD_DEF_IDENTIFIER_KEY !== $criteria,
79+
ARRAY_FILTER_USE_KEY
80+
);
81+
}
82+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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\Rest\Server\Input\Parser\Criterion;
10+
11+
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\FileSize as ImageFileSizeCriterion;
12+
use Ibexa\Contracts\Rest\Input\ParsingDispatcher;
13+
use Ibexa\Rest\Input\BaseParser;
14+
use Ibexa\Rest\Server\Exceptions\ValidationFailedException;
15+
use Ibexa\Rest\Server\Validation\Builder\Input\Parser\Criterion\ImageFileSizeCriterionValidatorBuilder;
16+
use Symfony\Component\Validator\Validator\ValidatorInterface;
17+
18+
final class ImageFileSize extends BaseParser
19+
{
20+
public const IMAGE_FILE_SIZE_CRITERION = 'ImageFileSizeCriterion';
21+
public const FIELD_DEF_IDENTIFIER_KEY = 'fieldDefIdentifier';
22+
public const SIZE_KEY = 'size';
23+
24+
private ValidatorInterface $validator;
25+
26+
public function __construct(ValidatorInterface $validator)
27+
{
28+
$this->validator = $validator;
29+
}
30+
31+
/**
32+
* @param array<mixed> $data
33+
*
34+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
35+
*/
36+
public function parse(array $data, ParsingDispatcher $parsingDispatcher): ImageFileSizeCriterion
37+
{
38+
$this->validateInputArray($data);
39+
40+
$sizeData = $data[self::IMAGE_FILE_SIZE_CRITERION][self::SIZE_KEY];
41+
$minFileSize = isset($sizeData['min'])
42+
? (int) $sizeData['min']
43+
: 0;
44+
45+
$maxFileSize = isset($sizeData['max'])
46+
? (int) $sizeData['max']
47+
: null;
48+
49+
return new ImageFileSizeCriterion(
50+
$data[self::IMAGE_FILE_SIZE_CRITERION][self::FIELD_DEF_IDENTIFIER_KEY],
51+
$minFileSize,
52+
$maxFileSize,
53+
);
54+
}
55+
56+
/**
57+
* @param array<mixed> $data
58+
*/
59+
private function validateInputArray(array $data): void
60+
{
61+
$validatorBuilder = new ImageFileSizeCriterionValidatorBuilder($this->validator);
62+
$validatorBuilder->validateInputArray($data);
63+
$violations = $validatorBuilder->build()->getViolations();
64+
65+
if ($violations->count() > 0) {
66+
throw new ValidationFailedException(
67+
self::IMAGE_FILE_SIZE_CRITERION,
68+
$violations
69+
);
70+
}
71+
}
72+
}

0 commit comments

Comments
 (0)