Skip to content

Commit

Permalink
IBX-6620: Added image criterions rest input parsers (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
ciastektk authored Nov 20, 2023
1 parent 4a146e5 commit a1d6cbe
Show file tree
Hide file tree
Showing 17 changed files with 755 additions and 12 deletions.
12 changes: 1 addition & 11 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ parameters:

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

-
Expand Down Expand Up @@ -740,16 +740,6 @@ parameters:
count: 1
path: src/lib/Input/Parser/ContentObjectStates.php

-
message: "#^Instantiated class Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\User\\\\Limitation\\\\SiteaccessLimitation not found\\.$#"
count: 1
path: src/lib/Input/ParserTools.php

-
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\\.$#"
count: 1
path: src/lib/Input/ParserTools.php

-
message: "#^Method Ibexa\\\\Rest\\\\Input\\\\ParserTools\\:\\:isEmbeddedObject\\(\\) has parameter \\$objectElement with no value type specified in iterable type array\\.$#"
count: 1
Expand Down
35 changes: 35 additions & 0 deletions src/bundle/Resources/config/input_parsers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -814,3 +814,38 @@ services:
arguments:
- 'sectionId'
- 'Ibexa\Contracts\Core\Repository\Values\User\Limitation\SectionLimitation'

Ibexa\Rest\Server\Input\Parser\Criterion\ImageMimeType:
parent: Ibexa\Rest\Server\Common\Parser
arguments:
$validator: '@validator'
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.ImageMimeType }

Ibexa\Rest\Server\Input\Parser\Criterion\ImageFileSize:
parent: Ibexa\Rest\Server\Common\Parser
arguments:
$validator: '@validator'
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.ImageFileSize }

Ibexa\Rest\Server\Input\Parser\Criterion\ImageOrientation:
parent: Ibexa\Rest\Server\Common\Parser
arguments:
$validator: '@validator'
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.ImageOrientation }

Ibexa\Rest\Server\Input\Parser\Criterion\ImageDimensions:
parent: Ibexa\Rest\Server\Common\Parser
arguments:
$validator: '@validator'
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.ImageDimensions }

Ibexa\Rest\Server\Input\Parser\Criterion\Image:
parent: Ibexa\Rest\Server\Common\Parser
arguments:
$validator: '@validator'
tags:
- { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.internal.criterion.Image }
2 changes: 1 addition & 1 deletion src/lib/Input/ParserTools.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\ParentOwnerLimitation;
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\ParentUserGroupLimitation;
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\SectionLimitation;
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\SiteaccessLimitation;
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\SiteAccessLimitation;
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\SubtreeLimitation;
use Ibexa\Contracts\Core\Repository\Values\User\Limitation\UserGroupLimitation;
use Ibexa\Contracts\Rest\Exceptions;
Expand Down
32 changes: 32 additions & 0 deletions src/lib/Server/Exceptions/ValidationFailedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?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\Exceptions;

use Symfony\Component\Validator\ConstraintViolationListInterface;
use Throwable;

final class ValidationFailedException extends BadRequestException
{
private ConstraintViolationListInterface $errors;

public function __construct(
string $contextName,
ConstraintViolationListInterface $errors,
?Throwable $previous = null
) {
$this->errors = $errors;

parent::__construct("Input data validation failed for $contextName", 1, $previous);
}

public function getErrors(): ConstraintViolationListInterface
{
return $this->errors;
}
}
87 changes: 87 additions & 0 deletions src/lib/Server/Input/Parser/Criterion/Image.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?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\Criterion;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image as ImageCriterion;
use Ibexa\Contracts\Rest\Input\ParsingDispatcher;
use Ibexa\Rest\Input\BaseParser;
use Ibexa\Rest\Server\Exceptions\ValidationFailedException;
use Ibexa\Rest\Server\Validation\Builder\Input\Parser\Criterion\ImageCriterionValidatorBuilder;
use Symfony\Component\Validator\Validator\ValidatorInterface;

final class Image extends BaseParser
{
public const IMAGE_CRITERION = 'ImageCriterion';
public const FIELD_DEF_IDENTIFIER_KEY = 'fieldDefIdentifier';
public const MIME_TYPES_KEY = 'mimeTypes';

private ValidatorInterface $validator;

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

/**
* @param array<mixed> $data
*
* @return \Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidCriterionArgumentException
*/
public function parse(array $data, ParsingDispatcher $parsingDispatcher): ImageCriterion
{
$this->validateInputArray($data);

$criterionData = $data[self::IMAGE_CRITERION];

return new ImageCriterion(
$criterionData[self::FIELD_DEF_IDENTIFIER_KEY],
$this->extractImageCriteria($criterionData)
);
}

/**
* @param array<mixed> $data
*/
private function validateInputArray(array $data): void
{
$validatorBuilder = new ImageCriterionValidatorBuilder($this->validator);
$validatorBuilder->validateInputArray($data);
$violations = $validatorBuilder->build()->getViolations();

if ($violations->count() > 0) {
throw new ValidationFailedException(
self::IMAGE_CRITERION,
$violations
);
}
}

/**
* @param array<mixed> $data
*
* @return array{
* mimeTypes?: string|array<string>,
* size?: array{min?: int|null, max?: int|null},
* width?: array{min?: int|null, max?: int|null},
* height?: array{min?: int|null, max?: int|null},
* orientation?: string|array<string>,
* }
*/
private function extractImageCriteria(array $data): array
{
return array_filter(
$data,
static fn (string $criteria): bool => self::FIELD_DEF_IDENTIFIER_KEY !== $criteria,
ARRAY_FILTER_USE_KEY
);
}
}
82 changes: 82 additions & 0 deletions src/lib/Server/Input/Parser/Criterion/ImageDimensions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?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\Criterion;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\Dimensions as ImageDimensionsCriterion;
use Ibexa\Contracts\Rest\Input\ParsingDispatcher;
use Ibexa\Rest\Input\BaseParser;
use Ibexa\Rest\Server\Exceptions\ValidationFailedException;
use Ibexa\Rest\Server\Validation\Builder\Input\Parser\Criterion\ImageDimensionsCriterionValidatorBuilder;
use Symfony\Component\Validator\Validator\ValidatorInterface;

final class ImageDimensions extends BaseParser
{
public const IMAGE_DIMENSIONS_CRITERION = 'ImageDimensionsCriterion';
public const FIELD_DEF_IDENTIFIER_KEY = 'fieldDefIdentifier';
public const WIDTH_KEY = 'width';
public const HEIGHT_KEY = 'height';

private ValidatorInterface $validator;

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

/**
* @param array<mixed> $data
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
public function parse(array $data, ParsingDispatcher $parsingDispatcher): ImageDimensionsCriterion
{
$this->validateInputArray($data);

$criterionData = $data[self::IMAGE_DIMENSIONS_CRITERION];

return new ImageDimensionsCriterion(
$criterionData[self::FIELD_DEF_IDENTIFIER_KEY],
$this->extractImageCriteria($criterionData)
);
}

/**
* @param array<mixed> $data
*/
private function validateInputArray(array $data): void
{
$validatorBuilder = new ImageDimensionsCriterionValidatorBuilder($this->validator);
$validatorBuilder->validateInputArray($data);
$violations = $validatorBuilder->build()->getViolations();

if ($violations->count() > 0) {
throw new ValidationFailedException(
self::IMAGE_DIMENSIONS_CRITERION,
$violations
);
}
}

/**
* @param array<mixed> $data
*
* @return array{
* width?: array{min?: int|null, max?: int|null},
* height?: array{min?: int|null, max?: int|null},
* }
*/
private function extractImageCriteria(array $data): array
{
return array_filter(
$data,
static fn (string $criteria): bool => self::FIELD_DEF_IDENTIFIER_KEY !== $criteria,
ARRAY_FILTER_USE_KEY
);
}
}
72 changes: 72 additions & 0 deletions src/lib/Server/Input/Parser/Criterion/ImageFileSize.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?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\Criterion;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\FileSize as ImageFileSizeCriterion;
use Ibexa\Contracts\Rest\Input\ParsingDispatcher;
use Ibexa\Rest\Input\BaseParser;
use Ibexa\Rest\Server\Exceptions\ValidationFailedException;
use Ibexa\Rest\Server\Validation\Builder\Input\Parser\Criterion\ImageFileSizeCriterionValidatorBuilder;
use Symfony\Component\Validator\Validator\ValidatorInterface;

final class ImageFileSize extends BaseParser
{
public const IMAGE_FILE_SIZE_CRITERION = 'ImageFileSizeCriterion';
public const FIELD_DEF_IDENTIFIER_KEY = 'fieldDefIdentifier';
public const SIZE_KEY = 'size';

private ValidatorInterface $validator;

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

/**
* @param array<mixed> $data
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
public function parse(array $data, ParsingDispatcher $parsingDispatcher): ImageFileSizeCriterion
{
$this->validateInputArray($data);

$sizeData = $data[self::IMAGE_FILE_SIZE_CRITERION][self::SIZE_KEY];
$minFileSize = isset($sizeData['min'])
? (int) $sizeData['min']
: 0;

$maxFileSize = isset($sizeData['max'])
? (int) $sizeData['max']
: null;

return new ImageFileSizeCriterion(
$data[self::IMAGE_FILE_SIZE_CRITERION][self::FIELD_DEF_IDENTIFIER_KEY],
$minFileSize,
$maxFileSize,
);
}

/**
* @param array<mixed> $data
*/
private function validateInputArray(array $data): void
{
$validatorBuilder = new ImageFileSizeCriterionValidatorBuilder($this->validator);
$validatorBuilder->validateInputArray($data);
$violations = $validatorBuilder->build()->getViolations();

if ($violations->count() > 0) {
throw new ValidationFailedException(
self::IMAGE_FILE_SIZE_CRITERION,
$violations
);
}
}
}
Loading

0 comments on commit a1d6cbe

Please sign in to comment.