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-2000: Added URL Wildcard Query with Criterion and Sort #301

Merged
merged 13 commits into from
May 25, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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
9 changes: 9 additions & 0 deletions eZ/Publish/API/Repository/URLWildcardService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use eZ\Publish\API\Repository\Values\Content\URLWildcard;
use eZ\Publish\API\Repository\Values\Content\URLWildcardTranslationResult;
use eZ\Publish\API\Repository\Values\Content\URLWildcardUpdateStruct;
use Ibexa\Contracts\Core\Repository\Values\Content\URLWildcard\SearchResult;
use Ibexa\Contracts\Core\Repository\Values\Content\URLWildcard\URLWildcardQuery;

/**
* URLAlias service.
Expand Down Expand Up @@ -84,6 +86,13 @@ public function load(int $id): UrlWildcard;
*/
public function loadAll(int $offset = 0, int $limit = -1): iterable;

/**
* Find URLWildcards.
*
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
*/
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
public function findUrlWildcards(URLWildcardQuery $query): SearchResult;

/**
* Translates an url to an existing uri resource based on the
* source/destination patterns of the url wildcard.
Expand Down
11 changes: 11 additions & 0 deletions eZ/Publish/Core/Persistence/Cache/UrlWildcardHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use eZ\Publish\Core\Base\Exceptions\NotFoundException;
use eZ\Publish\SPI\Persistence\Content\UrlWildcard;
use eZ\Publish\SPI\Persistence\Content\UrlWildcard\Handler as UrlWildcardHandlerInterface;
use Ibexa\Contracts\Core\Repository\Values\Content\URLWildcard\URLWildcardQuery;

class UrlWildcardHandler extends AbstractHandler implements UrlWildcardHandlerInterface
{
Expand Down Expand Up @@ -132,6 +133,16 @@ public function loadAll($offset = 0, $limit = -1)
return $this->persistenceHandler->urlWildcardHandler()->loadAll($offset, $limit);
}

/**
* @see \eZ\Publish\SPI\Persistence\Content\UrlWildcard\Handler::find
*/
public function find(URLWildcardQuery $query): array
{
$this->logger->logCall(__METHOD__, ['query' => $query]);

return $this->persistenceHandler->urlWildcardHandler()->find($query);
}

/**
* @see \eZ\Publish\SPI\Persistence\Content\UrlWildcard\Handler::lookup
*/
Expand Down
14 changes: 14 additions & 0 deletions eZ/Publish/Core/Persistence/Legacy/Content/UrlWildcard/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace eZ\Publish\Core\Persistence\Legacy\Content\UrlWildcard;

use eZ\Publish\SPI\Persistence\Content\UrlWildcard;
use Ibexa\Contracts\Core\Repository\Values\Content\URLWildcard\Query\Criterion;

/**
* UrlWildcard Gateway.
Expand Down Expand Up @@ -50,6 +51,19 @@ abstract public function loadUrlWildcardData(int $id): array;
*/
abstract public function loadUrlWildcardsData(int $offset = 0, int $limit = -1): array;

/**
* Selects URLWildcards matching specified criteria.
*
* @return array{
* "rows": mixed,
* "count": int|null,
* }
*
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
* @throws \eZ\Publish\API\Repository\Exceptions\NotImplementedException if Criterion is not applicable to its target
*/
abstract public function find(Criterion $criterion, int $offset, int $limit, array $sortClauses = [], bool $doCount = true): array;
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved

/**
* Load the UrlWildcard by source url $sourceUrl.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Query\QueryBuilder;
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
use eZ\Publish\Core\Persistence\Legacy\Content\UrlWildcard\Gateway;
use eZ\Publish\SPI\Persistence\Content\UrlWildcard;
use Ibexa\Contracts\Core\Repository\Values\Content\URLWildcard\Query\Criterion;
use Ibexa\Contracts\Core\Repository\Values\Content\URLWildcard\Query\SortClause;
use Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriteriaConverter;
use RuntimeException;

/**
* URL wildcard gateway implementation using the Doctrine database.
Expand All @@ -33,9 +38,22 @@ final class DoctrineDatabase extends Gateway
/** @var \Doctrine\DBAL\Connection */
private $connection;

public function __construct(Connection $connection)
/**
* Criteria converter.
*
* @var \Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriteriaConverter
*/
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
protected $criteriaConverter;

public const SORT_DIRECTION_MAP = [
SortClause::SORT_ASC => 'ASC',
SortClause::SORT_DESC => 'DESC',
];

public function __construct(Connection $connection, CriteriaConverter $criteriaConverter)
{
$this->connection = $connection;
$this->criteriaConverter = $criteriaConverter;
}

public function insertUrlWildcard(UrlWildcard $urlWildcard): int
Expand Down Expand Up @@ -159,6 +177,39 @@ public function loadUrlWildcardsData(int $offset = 0, int $limit = -1): array
return $stmt->fetchAll(FetchMode::ASSOCIATIVE);
}

public function find(Criterion $criterion, int $offset, int $limit, array $sortClauses = [], bool $doCount = true): array
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
{
$count = $doCount ? $this->doCount($criterion) : null;
if (!$doCount && $limit === 0) {
throw new RuntimeException('Invalid query. Cannot disable count and request 0 items at the same time');
}

if ($limit === 0 || ($count !== null && $count <= $offset)) {
return [
'count' => $count,
'rows' => [],
];
}

$query = $this->buildLoadUrlWildcardDataQuery();
$query
->where($this->criteriaConverter->convertCriteria($query, $criterion))
->setMaxResults($limit > 0 ? $limit : PHP_INT_MAX)
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
->setFirstResult($offset);

foreach ($sortClauses as $sortClause) {
$column = sprintf('%s', $sortClause->target);
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
$query->addOrderBy($column, $this->getQuerySortingDirection($sortClause->direction));
}

$statement = $query->execute();

return [
'count' => $count,
'rows' => $statement->fetchAllAssociative(),
];
}

public function loadUrlWildcardBySourceUrl(string $sourceUrl): array
{
$query = $this->buildLoadUrlWildcardDataQuery();
Expand Down Expand Up @@ -186,6 +237,35 @@ public function countAll(): int
return (int) $query->execute()->fetchColumn();
}

/**
* @throws \eZ\Publish\API\Repository\Exceptions\NotImplementedException
*/
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
protected function doCount(Criterion $criterion): int
{
$query = $this->connection->createQueryBuilder();
$query
->select('COUNT(DISTINCT url_wildcard.id)')
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
->from(self::URL_WILDCARD_TABLE, 'url_wildcard')
->where($this->criteriaConverter->convertCriteria($query, $criterion));

return (int)$query->execute()->fetchColumn();
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
}

private function getQuerySortingDirection(string $direction): string
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
{
if (!isset(self::SORT_DIRECTION_MAP[$direction])) {
throw new InvalidArgumentException(
'$sortClause->direction',
sprintf(
'Unsupported "%s" sorting directions, use one of the SortClause::SORT_* constants instead',
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
$direction
)
);
}

return self::SORT_DIRECTION_MAP[$direction];
}

private function trimUrl(string $url): string
{
return trim($url, '/');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use eZ\Publish\Core\Base\Exceptions\DatabaseException;
use eZ\Publish\Core\Persistence\Legacy\Content\UrlWildcard\Gateway;
use eZ\Publish\SPI\Persistence\Content\UrlWildcard;
use Ibexa\Contracts\Core\Repository\Values\Content\URLWildcard\Query\Criterion;
use PDOException;

/**
Expand Down Expand Up @@ -90,6 +91,15 @@ public function loadUrlWildcardsData(int $offset = 0, int $limit = -1): array
}
}

public function find(Criterion $criterion, int $offset, int $limit, array $sortClauses = [], bool $doCount = true): array
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
{
try {
return $this->innerGateway->find($criterion, $offset, $limit, $sortClauses, $doCount);
} catch (DBALException | PDOException $e) {
throw DatabaseException::wrap($e);
}
}

public function loadUrlWildcardBySourceUrl(string $sourceUrl): array
{
try {
Expand Down
20 changes: 20 additions & 0 deletions eZ/Publish/Core/Persistence/Legacy/Content/UrlWildcard/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use eZ\Publish\Core\Base\Exceptions\NotFoundException;
use eZ\Publish\SPI\Persistence\Content\UrlWildcard;
use eZ\Publish\SPI\Persistence\Content\UrlWildcard\Handler as BaseUrlWildcardHandler;
use Ibexa\Contracts\Core\Repository\Values\Content\URLWildcard\URLWildcardQuery;

/**
* The UrlWildcard Handler provides nice urls with wildcards management.
Expand Down Expand Up @@ -139,6 +140,25 @@ public function loadAll($offset = 0, $limit = -1)
);
}

/**
* {@inheritdoc}
*/
public function find(URLWildcardQuery $query): array
{
$results = $this->gateway->find(
$query->filter,
$query->offset,
$query->limit,
$query->sortClauses,
$query->performCount
);

return [
'count' => $results['count'],
'items' => $this->mapper->extractUrlWildcardsFromRows($results['rows']),
];
}

/**
* Performs lookup for given URL.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use eZ\Publish\Core\Persistence\Legacy\Content\UrlWildcard\Gateway\DoctrineDatabase;
use eZ\Publish\Core\Persistence\Legacy\Tests\TestCase;
use eZ\Publish\SPI\Persistence\Content\UrlWildcard;
use Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriteriaConverter;
use Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\MatchAll;

/**
* Test case for eZ\Publish\Core\Persistence\Legacy\Content\UrlWildcard\Gateway\DoctrineDatabase.
Expand Down Expand Up @@ -178,7 +180,8 @@ public function testDeleteUrlWildcard()
protected function getGateway(): DoctrineDatabase
{
if (!isset($this->gateway)) {
$this->gateway = new DoctrineDatabase($this->getDatabaseConnection());
$criteriaConverter = new CriteriaConverter([new MatchAll()]);
$this->gateway = new DoctrineDatabase($this->getDatabaseConnection(), $criteriaConverter);
}

return $this->gateway;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
use eZ\Publish\Core\Persistence\Legacy\Content\UrlWildcard\Mapper;
use eZ\Publish\Core\Persistence\Legacy\Tests\TestCase;
use eZ\Publish\SPI\Persistence\Content\UrlWildcard;
use Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriteriaConverter;
use Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\MatchAll;

/**
* Test case for UrlWildcard Handler.
Expand Down Expand Up @@ -245,7 +247,8 @@ public function testLoadAllWithOffsetAndLimit()
protected function getHandler(): UrlWildcard\Handler
{
if (!isset($this->urlWildcardHandler)) {
$this->gateway = new DoctrineDatabase($this->getDatabaseConnection());
$criteriaConverter = new CriteriaConverter([new MatchAll()]);
$this->gateway = new DoctrineDatabase($this->getDatabaseConnection(), $criteriaConverter);
$this->mapper = new Mapper();

$this->urlWildcardHandler = new Handler(
Expand Down
29 changes: 29 additions & 0 deletions eZ/Publish/Core/Repository/URLWildcardService.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
use eZ\Publish\API\Repository\Values\Content\URLWildcardUpdateStruct;
use eZ\Publish\Core\Base\Exceptions\ContentValidationException;
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue;
use eZ\Publish\Core\Base\Exceptions\UnauthorizedException;
use eZ\Publish\SPI\Persistence\Content\UrlWildcard as SPIUrlWildcard;
use eZ\Publish\SPI\Persistence\Content\UrlWildcard\Handler;
use Ibexa\Contracts\Core\Repository\Values\Content\URLWildcard\SearchResult;
use Ibexa\Contracts\Core\Repository\Values\Content\URLWildcard\URLWildcardQuery;

/**
* URLAlias service.
Expand Down Expand Up @@ -207,6 +210,32 @@ public function loadAll(int $offset = 0, int $limit = -1): iterable
return $urlWildcards;
}

/**
* {@inheritdoc}
*/
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
public function findUrlWildcards(URLWildcardQuery $query): SearchResult
{
if ($query->offset !== null && !is_numeric($query->offset)) {
throw new InvalidArgumentValue('offset', $query->offset);
}

if ($query->limit !== null && !is_numeric($query->limit)) {
throw new InvalidArgumentValue('limit', $query->limit);
}

$results = $this->urlWildcardHandler->find($query);

$items = [];
foreach ($results['items'] as $urlWildcard) {
$items[] = $this->buildUrlWildcardDomainObject($urlWildcard);
}

return new SearchResult([
'totalCount' => $results['count'],
'items' => $items,
]);
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ services:
class: eZ\Publish\Core\Persistence\Legacy\Content\UrlWildcard\Gateway\DoctrineDatabase
arguments:
- '@ezpublish.api.storage_engine.legacy.connection'
- '@Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriteriaConverter'

ezpublish.persistence.legacy.url_wildcard.gateway.exception_conversion:
class: eZ\Publish\Core\Persistence\Legacy\Content\UrlWildcard\Gateway\ExceptionConversion
Expand All @@ -22,3 +23,6 @@ services:
- "@ezpublish.persistence.legacy.url_wildcard.gateway"
- "@ezpublish.persistence.legacy.url_wildcard.mapper"
lazy: true

Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriteriaConverter:
class: Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriteriaConverter
mateuszdebinski marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
services:
ibexa.persistence.legacy.url_wildcard.criterion_handler.base:
abstract: true

Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\LogicalAnd:
parent: ibexa.persistence.legacy.url_wildcard.criterion_handler.base
class: Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\LogicalAnd
tags:
- { name: ibexa.storage.legacy.url_wildcard.criterion.handler }

Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\LogicalOr:
parent: ibexa.persistence.legacy.url_wildcard.criterion_handler.base
class: Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\LogicalOr
tags:
- { name: ibexa.storage.legacy.url_wildcard.criterion.handler }

Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\LogicalNot:
parent: ibexa.persistence.legacy.url_wildcard.criterion_handler.base
class: Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\LogicalNot
tags:
- { name: ibexa.storage.legacy.url_wildcard.criterion.handler }

Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\MatchAll:
parent: ibexa.persistence.legacy.url_wildcard.criterion_handler.base
class: Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\MatchAll
tags:
- { name: ibexa.storage.legacy.url_wildcard.criterion.handler }

Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\MatchNone:
parent: ibexa.persistence.legacy.url_wildcard.criterion_handler.base
class: Ibexa\Core\Persistence\Legacy\Content\URLWildcard\Query\CriterionHandler\MatchNone
tags:
- { name: ibexa.storage.legacy.url_wildcard.criterion.handler }
Loading