Skip to content

Commit

Permalink
Added image search criterions
Browse files Browse the repository at this point in the history
  • Loading branch information
ciastektk committed Oct 19, 2023
1 parent 3a2be98 commit 5618488
Show file tree
Hide file tree
Showing 8 changed files with 755 additions and 0 deletions.
171 changes: 171 additions & 0 deletions src/contracts/Repository/Values/Content/Query/Criterion/Image.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?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\Contracts\Core\Repository\Values\Content\Query\Criterion;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\FileSize;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\Height;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\MimeType;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\Orientation;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\Width;
use Ibexa\Core\Base\Exceptions\InvalidArgumentException;

/**
* @phpstan-type Range array{
* min?: int|null,
* max?: int|null,
* }
*
* @phpstan-type ImageCriteria array{
* mimeTypes?: string|array<string>,
* size?: Range,
* width?: Range,
* height?: Range,
* orientation?: string|array<string>,
* }
*/
final class Image extends CompositeCriterion
{
public const SUPPORTED_IMAGE_SEARCH_CRITERIA = [
'mimeTypes',
'size',
'width',
'height',
'orientation',
];

/**
* @phpstan-param ImageCriteria $data
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidCriterionArgumentException
*/
public function __construct(
string $fieldDefIdentifier,
array $data
) {
$this->validate($data);

$criteria = new Criterion\LogicalAnd(
$this->buildCriteria($fieldDefIdentifier, $data)
);

parent::__construct($criteria);
}

/**
* @phpstan-param ImageCriteria $data
*
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentException
*/
private function validate(array $data): void
{
if (empty($data)) {
throw new InvalidArgumentException(
'$data',
sprintf(
'At least one of the supported criteria should be passed: "%s"',
implode(', ', self::SUPPORTED_IMAGE_SEARCH_CRITERIA)
)
);
}

$notSupportedCriteria = array_diff(
array_keys($data),
array_merge(
self::SUPPORTED_IMAGE_SEARCH_CRITERIA,
['fieldDefIdentifier']
)
);

if (!empty($notSupportedCriteria)) {
throw new InvalidArgumentException(
'$data',
sprintf(
'Given criteria are not supported: "%s". Supported image criteria: "%s"',
implode(', ', $notSupportedCriteria),
implode(', ', self::SUPPORTED_IMAGE_SEARCH_CRITERIA)
)
);
}
}

/**
* @phpstan-param ImageCriteria $data
*
* @return array<\Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion>
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
private function buildCriteria(
string $fieldDefIdentifier,
array $data
): array {
$criteria = [];

if (isset($data['mimeTypes'])) {
$criteria[] = new MimeType(
$fieldDefIdentifier,
$data['mimeTypes']
);
}

if (isset($data['size'])) {
$size = $data['size'];
$criteria[] = new FileSize(
$fieldDefIdentifier,
$this->getMinValue($size),
$this->getMaxValue($size),
);
}

if (isset($data['width'])) {
$width = $data['width'];
$criteria[] = new Width(
$fieldDefIdentifier,
$this->getMinValue($width),
$this->getMaxValue($width)
);
}

if (isset($data['height'])) {
$height = $data['height'];
$criteria[] = new Height(
$fieldDefIdentifier,
$this->getMinValue($height),
$this->getMaxValue($height)
);
}

if (isset($data['orientation'])) {
$criteria[] = new Orientation(
$fieldDefIdentifier,
$data['orientation']
);
}

return $criteria;
}

/**
* @param array{min?: int|null} $data
*/
private function getMinValue(array $data): int
{
return $data['min'] ?? 0;
}

/**
* @param array{max?: int|null} $data
*/
private function getMaxValue(array $data): ?int
{
return $data['max'] ?? null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?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\Contracts\Core\Repository\Values\Content\Query\Criterion\Image;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\CompositeCriterion;
use Ibexa\Core\Base\Exceptions\InvalidArgumentException;

/**
* @phpstan-type ImageDimensions array{
* width?: array{min?: int|null, max?: int|null},
* height?: array{min?: int|null, max?: int|null},
* }
*/
final class Dimensions extends CompositeCriterion
{
public const SUPPORTED_IMAGE_DIMENSIONS_CRITERIA = [
'width',
'height',
];

/**
* @phpstan-param ImageDimensions $data
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
public function __construct(
string $fieldDefIdentifier,
array $data
) {
$this->validate($data);

$criteria = new Criterion\LogicalAnd(
$this->buildCriteria(
$fieldDefIdentifier,
$data
)
);

parent::__construct($criteria);
}

/**
* @phpstan-param ImageDimensions $data
*
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentException
*/
private function validate(array $data): void
{
if (empty($data)) {
throw new InvalidArgumentException(
'$data',
sprintf(
'At least one of the supported criteria should be passed: "%s"',
implode(', ', self::SUPPORTED_IMAGE_DIMENSIONS_CRITERIA)
)
);
}

$notSupportedCriteria = array_diff(
array_keys($data),
self::SUPPORTED_IMAGE_DIMENSIONS_CRITERIA
);

if (!empty($notSupportedCriteria)) {
throw new InvalidArgumentException(
'$data',
sprintf(
'Given criteria are not supported: "%s". Supported image criteria: "%s"',
implode(', ', $notSupportedCriteria),
implode(', ', self::SUPPORTED_IMAGE_DIMENSIONS_CRITERIA)
)
);
}
}

/**
* @phpstan-param ImageDimensions $data
*
* @return array<\Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion>
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
private function buildCriteria(
string $fieldDefIdentifier,
array $data
): array {
$criteria = [];

if (isset($data['width'])) {
$width = $data['width'];
$criteria[] = new Width(
$fieldDefIdentifier,
$width['min'] ?? 0,
$width['max'] ?? null,
);
}

if (isset($data['height'])) {
$height = $data['height'];
$criteria[] = new Height(
$fieldDefIdentifier,
$height['min'] ?? 0,
$height['max'] ?? null,
);
}

return $criteria;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?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\Contracts\Core\Repository\Values\Content\Query\Criterion\Image;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator\Specifications;
use Ibexa\Core\Base\Exceptions\InvalidArgumentException;

final class FileSize extends Criterion
{
private string $fieldDefIdentifier;

/**
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
public function __construct(
string $fieldDefIdentifier,
int $minFileSize = 0,
?int $maxFileSize = null
) {
$this->validate($minFileSize, $maxFileSize);

$value[] = $minFileSize * 1024 * 1024;
$operator = Operator::GTE;

if ($maxFileSize >= 1) {
$operator = Operator::BETWEEN;
$value[] = $maxFileSize * 1024 * 1024;
}

parent::__construct(
null,
$operator,
$value
);

$this->fieldDefIdentifier = $fieldDefIdentifier;
}

public function getSpecifications(): array
{
return [
new Specifications(
Operator::BETWEEN,
Specifications::FORMAT_ARRAY,
Specifications::TYPE_INTEGER
),
new Specifications(
Operator::GTE,
Specifications::FORMAT_ARRAY,
Specifications::TYPE_INTEGER
),
];
}

public function getFieldDefIdentifier(): string
{
return $this->fieldDefIdentifier;
}

/**
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
private function validate(
int $minFileSize,
?int $maxFileSize
): void {
if ($minFileSize < 0) {
throw new InvalidArgumentException(
'$minFileSize',
'Value should be grater or equal 0'
);
}

if (
null !== $maxFileSize
&& $maxFileSize < 1
) {
throw new InvalidArgumentException(
'$maxFileSize',
'Value should be grater or equal 1'
);
}

if ($minFileSize > $maxFileSize) {
throw new InvalidArgumentException(
'$minFileSize',
'Value should be grater than' . $maxFileSize
);
}
}
}
Loading

0 comments on commit 5618488

Please sign in to comment.