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-7653: IsContainer criterion added #333

Merged
merged 15 commits into from
May 16, 2024
2 changes: 1 addition & 1 deletion .sonarcloud.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sonar.exclusions=**/Tests/**/_fixtures/*
sonar.exclusions=tests/**/_fixtures/**/*
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\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\Operator\Specifications;
use Ibexa\Contracts\Core\Repository\Values\Filter\FilteringCriterion;

final class IsContainer extends Criterion implements FilteringCriterion
{
public function __construct(bool $value = true)
{
parent::__construct(null, null, $value);
}

public function getSpecifications(): array
{
return [
new Specifications(
Operator::EQ,
Specifications::FORMAT_SINGLE,
Specifications::TYPE_BOOLEAN
),
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?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\Core\Persistence\Legacy\Filter\CriterionQueryBuilder\Content;

use Doctrine\DBAL\ParameterType;
use Ibexa\Contracts\Core\Persistence\Filter\Doctrine\FilteringQueryBuilder;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\IsContainer;
use Ibexa\Contracts\Core\Repository\Values\Filter\CriterionQueryBuilder;
use Ibexa\Contracts\Core\Repository\Values\Filter\FilteringCriterion;
use Ibexa\Core\Persistence\Legacy\Content\Type\Gateway;

/**
* @internal for internal use by Repository Filtering
*/
final class IsContainerQueryBuilder implements CriterionQueryBuilder
{
public function accepts(FilteringCriterion $criterion): bool
{
return $criterion instanceof IsContainer;
}

/**
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\IsContainer $criterion
*/
public function buildQueryConstraint(
FilteringQueryBuilder $queryBuilder,
FilteringCriterion $criterion
): ?string {
$queryBuilder
->joinOnce(
'content',
Gateway::CONTENT_TYPE_TABLE,
'content_type',
'content.contentclass_id = content_type.id',
);

/** @var array{bool} $criterionValue */
$criterionValue = $criterion->value;
$isContainer = reset($criterionValue);

return $queryBuilder->expr()->in(
'content_type.is_container',
$queryBuilder->createNamedParameter((int)$isContainer, ParameterType::INTEGER)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ services:
- {name: ibexa.search.legacy.gateway.criterion_handler.content}
- {name: ibexa.search.legacy.gateway.criterion_handler.location}

Ibexa\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler\IsContainer:
parent: Ibexa\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler
tags:
- {name: ibexa.search.legacy.gateway.criterion_handler.content}
- {name: ibexa.search.legacy.gateway.criterion_handler.location}

Ibexa\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler\LanguageCode:
class: Ibexa\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler\LanguageCode
parent: Ibexa\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?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\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler;

use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Query\QueryBuilder;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Core\Persistence\Legacy\Content\Type\Gateway as ContentTypeGateway;
use Ibexa\Core\Search\Legacy\Content\Common\Gateway\CriteriaConverter;
use Ibexa\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler;

final class IsContainer extends CriterionHandler
{
public function accept(Criterion $criterion): bool
{
return $criterion instanceof Criterion\IsContainer;
}

/**
* @phpstan-param array{languages: string[]} $languageSettings
*/
public function handle(
CriteriaConverter $converter,
QueryBuilder $queryBuilder,
Criterion $criterion,
array $languageSettings
) {
/** @var array{bool} $criterionValue */
$criterionValue = $criterion->value;
$isContainer = reset($criterionValue);

$subSelect = $this->connection->createQueryBuilder();
$subSelect
->select(
'id'
)->from(
ContentTypeGateway::CONTENT_TYPE_TABLE
)->where(
$queryBuilder->expr()->eq(
'is_container',
$queryBuilder->createNamedParameter((int)$isContainer, ParameterType::INTEGER)
)
);

return $queryBuilder->expr()->in(
'c.contentclass_id',
$subSelect->getSQL()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ public function getCriteriaForInitialData(): iterable
Criterion\Operator::BETWEEN,
[1080220197, 1448889046]
);
yield 'IsContainer=true' => new Criterion\IsContainer(true);
yield 'IsContainer=false' => new Criterion\IsContainer(false);
yield 'IsUserBased=true' => new Criterion\IsUserBased(true);
yield 'IsUserBased=false' => new Criterion\IsUserBased(false);
yield 'IsUserEnabled=true' => new Criterion\IsUserEnabled();
Expand Down
16 changes: 16 additions & 0 deletions tests/integration/Core/Repository/SearchServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,22 @@ public function getContentQuerySearches()
],
$fixtureDir . 'Visibility.php',
],
[
[
'query' => new Criterion\IsContainer(true),
'sortClauses' => [new SortClause\ContentId()],
'limit' => 5,
],
$fixtureDir . 'IsContainerTrue.php',
],
[
[
'query' => new Criterion\IsContainer(false),
'sortClauses' => [new SortClause\ContentId()],
'limit' => 5,
],
$fixtureDir . 'IsContainerFalse.php',
],
[
[
'query' => new Criterion\IsUserEnabled(true),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
use Ibexa\Contracts\Core\Repository\Values\Content\Search\SearchHit;
use Ibexa\Contracts\Core\Repository\Values\Content\Search\SearchResult;

return new SearchResult([
'facets' => [],
'searchHits' => [
new SearchHit([
'valueObject' => [
'id' => 10,
'title' => 'Anonymous User',
],
'score' => null,
'index' => null,
'highlight' => null,
'matchedTranslation' => 'eng-US',
]),
new SearchHit([
'valueObject' => [
'id' => 14,
'title' => 'Administrator User',
],
'score' => null,
'index' => null,
'highlight' => null,
'matchedTranslation' => 'eng-US',
]),
new SearchHit([
'valueObject' => [
'id' => 52,
'title' => 'Common INI settings',
],
'score' => null,
'index' => null,
'highlight' => null,
'matchedTranslation' => 'eng-US',
]),
new SearchHit([
'valueObject' => [
'id' => 54,
'title' => 'Ibexa Demo Design (without demo content)',
],
'score' => null,
'index' => null,
'highlight' => null,
'matchedTranslation' => 'eng-US',
]),
],
'spellSuggestion' => null,
'time' => 1,
'timedOut' => null,
'maxScore' => null,
'totalCount' => 4,
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
use Ibexa\Contracts\Core\Repository\Values\Content\Search\SearchHit;
use Ibexa\Contracts\Core\Repository\Values\Content\Search\SearchResult;

return new SearchResult([
'facets' => [],
'searchHits' => [
new SearchHit([
'valueObject' => [
'id' => 4,
'title' => 'Users',
],
'score' => null,
'index' => null,
'highlight' => null,
'matchedTranslation' => 'eng-US',
]),
new SearchHit([
'valueObject' => [
'id' => 11,
'title' => 'Members',
],
'score' => null,
'index' => null,
'highlight' => null,
'matchedTranslation' => 'eng-US',
]),
new SearchHit([
'valueObject' => [
'id' => 12,
'title' => 'Administrator users',
],
'score' => null,
'index' => null,
'highlight' => null,
'matchedTranslation' => 'eng-US',
]),
new SearchHit([
'valueObject' => [
'id' => 13,
'title' => 'Editors',
],
'score' => null,
'index' => null,
'highlight' => null,
'matchedTranslation' => 'eng-US',
]),
new SearchHit([
'valueObject' => [
'id' => 41,
'title' => 'Media',
],
'score' => null,
'index' => null,
'highlight' => null,
'matchedTranslation' => 'eng-US',
]),
],
'spellSuggestion' => null,
'time' => 1,
'timedOut' => null,
'maxScore' => null,
'totalCount' => 14,
]);
Loading