Skip to content

Commit

Permalink
IBX-6620: Added image search criterions (#284)
Browse files Browse the repository at this point in the history
Co-authored-by: Dawid Parafiński <dawid.parafinski@ez.no>
  • Loading branch information
ciastektk and ViniTou authored Nov 20, 2023
1 parent 2708c2e commit e88368c
Show file tree
Hide file tree
Showing 24 changed files with 1,072 additions and 6 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ jobs:
image: redis
ports:
- 6379:6379
options:
options:
--memory=60m
solr:
image: ghcr.io/ibexa/core/solr
Expand All @@ -210,7 +210,7 @@ jobs:
- '7.4'
- '8.0'
- '8.1'
steps:
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
Expand All @@ -220,10 +220,10 @@ jobs:
with:
php-version: ${{ matrix.php }}
coverage: none

- name: Add solr dependency
run: |
VERSION=$(jq -r '.extra | ."branch-alias" | ."dev-main"' < composer.json)
VERSION="dev-ibx-6620-added-image-criterion-visitors-for-ci as 4.6.x-dev"
composer require --no-update "ibexa/solr:$VERSION"
- uses: "ramsey/composer-install@v1"
Expand Down
4 changes: 3 additions & 1 deletion phpunit-integration-legacy-solr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
<env name="CORES_SETUP" value="dedicated" />
<env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/>
<ini name="error_reporting" value="-1" />
<env name="KERNEL_CLASS" value="Ibexa\Contracts\Core\Test\IbexaTestKernel"/>
<env name="KERNEL_CLASS" value="Ibexa\Contracts\Solr\Test\IbexaSolrTestKernel"/>
<env name="SEARCH_ENGINE" value="solr"/>
<env name="DATABASE_URL" value="sqlite://:memory:" />
</php>
<testsuites>
<!-- Search service is used all over the place, so we must run entire integration test suite -->
Expand Down
1 change: 1 addition & 0 deletions phpunit-integration-legacy.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<ini name="error_reporting" value="-1" />
<env name="DATABASE_URL" value="sqlite://:memory:" />
<env name="KERNEL_CLASS" value="Ibexa\Contracts\Core\Test\IbexaTestKernel"/>
<env name="SEARCH_ENGINE" value="legacy"/>
</php>
<testsuites>
<testsuite name="integration_core">
Expand Down
102 changes: 102 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,102 @@
<?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;

/**
* @phpstan-import-type Range from \Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\AbstractImageCompositeCriterion
*
* @phpstan-type ImageCriteria array{
* mimeTypes?: string|array<string>,
* size?: Range,
* width?: Range,
* height?: Range,
* orientation?: string|array<string>,
* }
*
* @template-extends \Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Image\AbstractImageCompositeCriterion<ImageCriteria>
*/
final class Image extends Criterion\Image\AbstractImageCompositeCriterion
{
public const IMAGE_SEARCH_CRITERIA = [
'mimeTypes',
'size',
'width',
'height',
'orientation',
];

protected function getSupportedCriteria(): array
{
return self::IMAGE_SEARCH_CRITERIA;
}

/**
* @phpstan-param ImageCriteria $data
*
* @return array<\Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion>
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
protected 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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?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;

/**
* @template TImageCriteria of array
*
* @phpstan-type Range array{
* min?: int|null,
* max?: int|null,
* }
*/
abstract class AbstractImageCompositeCriterion extends CompositeCriterion
{
/**
* @phpstan-param TImageCriteria $data
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
public function __construct(
string $fieldDefIdentifier,
array $data
) {
$this->validate($data, $this->getSupportedCriteria());

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

parent::__construct($criteria);
}

/**
* @phpstan-param TImageCriteria $data
*
* @return array<\Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion>
*/
abstract protected function buildCriteria(string $fieldDefIdentifier, array $data): array;

/**
* @return array<string>
*/
abstract protected function getSupportedCriteria(): array;

/**
* @phpstan-param TImageCriteria $data
*
* @param array<string> $supportedCriteria
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
protected function validate(
array $data,
array $supportedCriteria
): void {
if (empty($data)) {
throw new InvalidArgumentException(
'$data',
sprintf(
'At least one of the supported criteria should be passed: "%s"',
implode(', ', $supportedCriteria)
)
);
}

$notSupportedCriteria = array_diff(
array_keys($data),
$supportedCriteria
);

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

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

/**
* @param array{max?: int|null} $data
*/
protected function getMaxValue(array $data): ?int
{
return $data['max'] ?? null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?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;

abstract class AbstractImageRangeCriterion extends Criterion
{
/**
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
public function __construct(
string $fieldDefIdentifier,
int $minValue = 0,
?int $maxValue = null
) {
$this->validate($minValue, $maxValue);

$value[] = $minValue;
$operator = Operator::GTE;

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

parent::__construct(
$fieldDefIdentifier,
$operator,
$value
);
}

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
),
];
}

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

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

if (
null !== $maxValue
&& $minValue > $maxValue
) {
throw new InvalidArgumentException(
'$minValue',
'Value should be grater than' . $maxValue
);
}
}
}
Loading

0 comments on commit e88368c

Please sign in to comment.