Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IBX-6620: Added Image criterion visitors #55

Merged
merged 6 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
},
"require-dev": {
"symfony/proxy-manager-bridge": "^5.4",
"symfony/phpunit-bridge": "^5.4",
"ibexa/doctrine-schema": "~4.6.0@dev",
"phpunit/phpunit": "^8.2",
"matthiasnoback/symfony-dependency-injection-test": "^4.1",
Expand Down
5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2249,8 +2249,3 @@ parameters:
message: "#^Parameter \\#1 \\$contentObjects of method Ibexa\\\\Solr\\\\Handler\\:\\:bulkIndexContent\\(\\) expects array\\<Ibexa\\\\Contracts\\\\Core\\\\Persistence\\\\Content\\>, iterable\\<Ibexa\\\\Contracts\\\\Core\\\\Persistence\\\\Content\\> given\\.$#"
count: 1
path: tests/lib/SetupFactory/LegacySetupFactory.php

-
message: "#^Parameter \\#1 \\$paths of class Symfony\\\\Component\\\\Config\\\\FileLocator constructor expects array\\<string\\>\\|string, string\\|false given\\.$#"
count: 2
path: tests/lib/SetupFactory/LegacySetupFactory.php
48 changes: 48 additions & 0 deletions src/contracts/Test/IbexaSolrTestKernel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?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\Solr\Test;

use Ibexa\Bundle\Solr\IbexaSolrBundle;
use Ibexa\Contracts\Core\Search\Handler;
use Ibexa\Contracts\Core\Test\IbexaTestKernel as BaseIbexaTestKernel;
use Ibexa\Solr\Handler as SolrHandler;
use Ibexa\Solr\Test\SolrTestContainerBuilder;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
* @internal
*
* Exposed in contracts to be able to run tests from ibexa/core.
*/
final class IbexaSolrTestKernel extends BaseIbexaTestKernel
{
public function registerBundles(): iterable
{
yield from parent::registerBundles();

yield new IbexaSolrBundle();
}

protected static function getExposedServicesById(): iterable
{
yield from parent::getExposedServicesById();

yield SolrHandler::class => Handler::class;
}

public function registerContainerConfiguration(LoaderInterface $loader): void
{
parent::registerContainerConfiguration($loader);

$loader->load(static function (ContainerBuilder $container): void {
(new SolrTestContainerBuilder())->loadSolrSettings($container);
});
}
}
32 changes: 32 additions & 0 deletions src/lib/Query/Image/CriterionVisitor/AbstractImageRangeVisitor.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\Solr\Query\Image\CriterionVisitor;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Solr\Query\CriterionVisitor;

abstract class AbstractImageRangeVisitor extends AbstractImageVisitor
{
public function visit(Criterion $criterion, CriterionVisitor $subVisitor = null): string
{
/** @var array{0: int, 1?: int|null} $criterionValue */
$criterionValue = $criterion->value;
$queries = [];

foreach ($this->getSearchFieldNames($criterion) as $fieldName) {
$queries[] = $fieldName . ':' . $this->getRange(
$criterion->operator,
$criterionValue[0],
$criterionValue[1] ?? null
);
}

return '(' . implode(' OR ', $queries) . ')';
}
}
36 changes: 36 additions & 0 deletions src/lib/Query/Image/CriterionVisitor/AbstractImageTermsVisitor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?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\Solr\Query\Image\CriterionVisitor;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Solr\Query\CriterionVisitor;

abstract class AbstractImageTermsVisitor extends AbstractImageVisitor
{
public function visit(Criterion $criterion, CriterionVisitor $subVisitor = null): string
{
$queries = [];
/** @var array<string>|string $criterionValue */
$criterionValue = $criterion->value;

foreach ($this->getSearchFieldNames($criterion) as $fieldName) {
if (is_array($criterionValue)) {
foreach ($criterionValue as $value) {
$queries[] = $fieldName . ':' . $value;
}
}

if (is_string($criterionValue)) {
$queries[] = $fieldName . ':' . $criterionValue;
}
}

return '(' . implode(' OR ', $queries) . ')';
}
}
58 changes: 58 additions & 0 deletions src/lib/Query/Image/CriterionVisitor/AbstractImageVisitor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?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\Solr\Query\Image\CriterionVisitor;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Solr\Query\CriterionVisitor;
use Ibexa\Core\Base\Exceptions\InvalidArgumentException;
use Ibexa\Core\FieldType\Image\Type;
use Ibexa\Core\Search\Common\FieldNameResolver;

abstract class AbstractImageVisitor extends CriterionVisitor
{
private FieldNameResolver $fieldNameResolver;

private Type $imageFieldType;

public function __construct(
FieldNameResolver $fieldNameResolver,
Type $imageFieldType
) {
$this->fieldNameResolver = $fieldNameResolver;
$this->imageFieldType = $imageFieldType;
}

abstract protected function getSearchFieldName(): string;

/**
* @return array<string>
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
protected function getSearchFieldNames(Criterion $criterion): array
{
$searchFieldNames = array_keys(
$this->fieldNameResolver->getFieldTypes(
$criterion,
$criterion->target,
$this->imageFieldType->getFieldTypeIdentifier(),
$this->getSearchFieldName()
)
);

if (empty($searchFieldNames)) {
throw new InvalidArgumentException(
'$criterion->target',
"No searchable Fields found for the provided Criterion target '{$criterion->target}'."
);
}

return $searchFieldNames;
}
}
31 changes: 31 additions & 0 deletions src/lib/Query/Image/CriterionVisitor/FileSize.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?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\Solr\Query\Image\CriterionVisitor;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator;

final class FileSize extends AbstractImageRangeVisitor
{
private const SEARCH_FIELD_FILE_SIZE = 'file_size';

public function canVisit(Criterion $criterion): bool
{
return $criterion instanceof Criterion\Image\FileSize
&& (
$criterion->operator === Operator::BETWEEN
|| $criterion->operator === Operator::GTE
);
}

protected function getSearchFieldName(): string
{
return self::SEARCH_FIELD_FILE_SIZE;
}
}
31 changes: 31 additions & 0 deletions src/lib/Query/Image/CriterionVisitor/Height.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?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\Solr\Query\Image\CriterionVisitor;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator;

final class Height extends AbstractImageRangeVisitor
{
private const SEARCH_FIELD_HEIGHT = 'height';

public function canVisit(Criterion $criterion): bool
{
return $criterion instanceof Criterion\Image\Height
&& (
$criterion->operator === Operator::BETWEEN
|| $criterion->operator === Operator::GTE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't also make sense to have Operator::LTE here?

);
}

protected function getSearchFieldName(): string
{
return self::SEARCH_FIELD_HEIGHT;
}
}
31 changes: 31 additions & 0 deletions src/lib/Query/Image/CriterionVisitor/MimeType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?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\Solr\Query\Image\CriterionVisitor;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator;

final class MimeType extends AbstractImageTermsVisitor
{
private const SEARCH_FIELD_MIME_TYPE = 'mime_type';

public function canVisit(Criterion $criterion): bool
{
return $criterion instanceof Criterion\Image\MimeType
&& (
$criterion->operator === Operator::EQ
|| $criterion->operator === Operator::IN
);
}

protected function getSearchFieldName(): string
{
return self::SEARCH_FIELD_MIME_TYPE;
}
}
31 changes: 31 additions & 0 deletions src/lib/Query/Image/CriterionVisitor/Orientation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?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\Solr\Query\Image\CriterionVisitor;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator;

final class Orientation extends AbstractImageTermsVisitor
{
private const SEARCH_FIELD_ORIENTATION = 'orientation';

public function canVisit(Criterion $criterion): bool
{
return $criterion instanceof Criterion\Image\Orientation
&& (
$criterion->operator === Operator::EQ
|| $criterion->operator === Operator::IN
);
}

protected function getSearchFieldName(): string
{
return self::SEARCH_FIELD_ORIENTATION;
}
}
31 changes: 31 additions & 0 deletions src/lib/Query/Image/CriterionVisitor/Width.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?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\Solr\Query\Image\CriterionVisitor;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator;

final class Width extends AbstractImageRangeVisitor
{
private const SEARCH_FIELD_WIDTH = 'width';

public function canVisit(Criterion $criterion): bool
{
return $criterion instanceof Criterion\Image\Width
&& (
$criterion->operator === Operator::BETWEEN
|| $criterion->operator === Operator::GTE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same remark as for Height.

);
}

protected function getSearchFieldName(): string
{
return self::SEARCH_FIELD_WIDTH;
}
}
10 changes: 8 additions & 2 deletions src/lib/Resources/config/container/solr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ services:
- '@ibexa.solr.query.content.facet_builder_visitor.aggregate'
- '@ibexa.solr.query.content.aggregation_result_extractor.dispatcher'
- '@Ibexa\Solr\Gateway\EndpointRegistry'
deprecated: 'The "%service_id%" service is deprecated since eZ Platform 3.2.0, to be removed in eZ Platform 4.0.0., use ezpublish.search.solr.result_extractor.content.native or ezpublish.search.solr.result_extractor.location.native instead.'
deprecated:
version: 'eZ Platform 3.2.0'
package: 'ibexa/solr'
message: 'The "%service_id%" service is deprecated since eZ Platform 3.2.0, to be removed in Ibexa DXP 5.0.0. Use ibexa.solr.result_extractor.content.native or ibexa.solr.result_extractor.location.native instead.'

ibexa.solr.result_extractor.content.native:
class: Ibexa\Solr\ResultExtractor\NativeResultExtractor
Expand All @@ -79,7 +82,10 @@ services:

ibexa.solr.result_extractor:
alias: ibexa.solr.result_extractor.native
deprecated: 'The "%alias_id%" alias is deprecated since eZ Platform 3.2.0, to be removed in eZ Platform 4.0.0. Use ezpublish.search.solr.result_extractor.content or ezpublish.search.solr.result_extractor.location instead'
deprecated:
version: 'eZ Platform 3.2.0'
package: 'ibexa/solr'
message: 'The "%alias_id%" alias is deprecated since eZ Platform 3.2.0, to be removed in Ibexa DXP 5.0.0. Use ibexa.solr.result_extractor.content or ibexa.solr.result_extractor.location instead'

ibexa.solr.result_extractor.content:
alias: ibexa.solr.result_extractor.content.native
Expand Down
Loading
Loading