Skip to content

Commit

Permalink
Reworked IsBookmarked criterion
Browse files Browse the repository at this point in the history
  • Loading branch information
ciastektk committed Aug 16, 2024
1 parent f4a3dd9 commit 28fd67f
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Location;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator\Specifications;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Value\IsBookmarkedValue;
use Ibexa\Contracts\Core\Repository\Values\Filter\FilteringCriterion;

final class IsBookmarked extends Location implements FilteringCriterion
{
public function __construct(int $userId)
public function __construct(bool $value, ?int $userId = null)
{
parent::__construct(null, Operator::EQ, $userId);
$valueData = new IsBookmarkedValue($userId);

parent::__construct(
null,
Operator::EQ,
$value,
$valueData
);
}

public function getSpecifications(): array
Expand All @@ -24,7 +32,7 @@ public function getSpecifications(): array
new Specifications(
Operator::EQ,
Specifications::FORMAT_SINGLE,
Specifications::TYPE_INTEGER
Specifications::TYPE_BOOLEAN
),
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,8 @@ services:

Ibexa\Core\Search\Legacy\Content\Location\Gateway\CriterionHandler\Location\IsBookmarked:
parent: Ibexa\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler
arguments:
$connection: '@ibexa.persistence.connection'
$permissionResolver: '@Ibexa\Contracts\Core\Repository\PermissionResolver'
tags:
- { name: ibexa.search.legacy.gateway.criterion_handler.location }
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,29 @@
*/
namespace Ibexa\Core\Search\Legacy\Content\Location\Gateway\CriterionHandler\Location;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\DBAL\Types\Types;
use Ibexa\Contracts\Core\Exception\InvalidArgumentException;
use Ibexa\Contracts\Core\Repository\PermissionResolver;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Core\Persistence\Legacy\Bookmark\Gateway\DoctrineDatabase;
use Ibexa\Core\Search\Legacy\Content\Common\Gateway\CriteriaConverter;
use Ibexa\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler;

final class IsBookmarked extends CriterionHandler
{
private PermissionResolver $permissionResolver;

public function __construct(
Connection $connection,
PermissionResolver $permissionResolver
) {
parent::__construct($connection);

$this->permissionResolver = $permissionResolver;
}

public function accept(Criterion $criterion): bool
{
return $criterion instanceof Criterion\Location\IsBookmarked
Expand All @@ -23,13 +37,17 @@ public function accept(Criterion $criterion): bool

/**
* @param array{languages: string[]} $languageSettings
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
*/
public function handle(
CriteriaConverter $converter,
QueryBuilder $queryBuilder,
Criterion $criterion,
array $languageSettings
) {
$userId = $this->getUserId($criterion);

$subQueryBuilder = $this->connection->createQueryBuilder();
$subQueryBuilder
->select(DoctrineDatabase::COLUMN_LOCATION_ID)
Expand All @@ -40,15 +58,37 @@ public function handle(
->eq(
DoctrineDatabase::COLUMN_USER_ID,
$queryBuilder->createNamedParameter(
$criterion->value[0],
$userId,
Types::INTEGER
)
)
);

return $queryBuilder->expr()->in(
't.node_id',
$subQueryBuilder->getSQL()
);
$expressionBuilder = $queryBuilder->expr();
if ($criterion->value[0]) {
return $expressionBuilder->in('t.node_id', $subQueryBuilder->getSQL());
}

return $expressionBuilder->notIn('t.node_id', $subQueryBuilder->getSQL());
}

/**
* @throws \Ibexa\Contracts\Core\Exception\InvalidArgumentException
*/
private function getUserId(Criterion $criterion): int
{
$valueData = $criterion->valueData;
if (!$valueData instanceof Criterion\Value\IsBookmarkedValue) {
throw new InvalidArgumentException(
'$criterion->valueData',
sprintf(
'Is expected to be of type: "%s", got "%s"',
Criterion\Value\IsBookmarkedValue::class,
get_debug_type($valueData)
)
);
}

return $valueData->getUserId() ?? $this->permissionResolver->getCurrentUserReference()->getUserId();
}
}
24 changes: 20 additions & 4 deletions tests/integration/Core/Repository/SearchServiceBookmarkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,31 +56,47 @@ public function provideDataForTestCriterion(): iterable
yield 'All bookmarked locations' => [
6,
[
new Query\Criterion\Location\IsBookmarked(self::ADMIN_USER_ID),
new Query\Criterion\Location\IsBookmarked(true, self::ADMIN_USER_ID),
],
];

yield 'All bookmarked locations limited to folder content type' => [
1,
[
new Query\Criterion\ContentTypeIdentifier(self::FOLDER_CONTENT_TYPE_IDENTIFIER),
new Query\Criterion\Location\IsBookmarked(self::ADMIN_USER_ID),
new Query\Criterion\Location\IsBookmarked(true, self::ADMIN_USER_ID),
],
];

yield 'All bookmarked locations limited to user group content type' => [
4,
[
new Query\Criterion\ContentTypeIdentifier('user_group'),
new Query\Criterion\Location\IsBookmarked(self::ADMIN_USER_ID),
new Query\Criterion\Location\IsBookmarked(true, self::ADMIN_USER_ID),
],
];

yield 'All bookmarked locations limited to user content type' => [
1,
[
new Query\Criterion\ContentTypeIdentifier('user'),
new Query\Criterion\Location\IsBookmarked(self::ADMIN_USER_ID),
new Query\Criterion\Location\IsBookmarked(true),
],
];

yield 'No bookmarked locations for user with id 10' => [
0,
[
new Query\Criterion\ContentTypeIdentifier('user'),
new Query\Criterion\Location\IsBookmarked(true, 10),
],
];

yield 'All no bookmarked locations for content type user_group' => [
2,
[
new Query\Criterion\ContentTypeIdentifier('user_group'),
new Query\Criterion\Location\IsBookmarked(false),
],
];
}
Expand Down

0 comments on commit 28fd67f

Please sign in to comment.