Skip to content

Commit

Permalink
IBX-6827: Aggregation API improvements (#287)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamwojs authored Dec 12, 2023
1 parent 51d0515 commit 9111b08
Show file tree
Hide file tree
Showing 18 changed files with 909 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

namespace Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Ranges\RangesGeneratorInterface;
use Traversable;

final class DateMetadataRangeAggregation extends AbstractRangeAggregation
{
public const MODIFIED = 'modified';
Expand All @@ -27,6 +30,19 @@ public function getType(): string
{
return $this->type;
}

public static function fromGenerator(
string $name,
string $type,
RangesGeneratorInterface $generator
): self {
$ranges = $generator->generate();
if ($ranges instanceof Traversable) {
$ranges = iterator_to_array($ranges);
}

return new self($name, $type, $ranges);
}
}

class_alias(DateMetadataRangeAggregation::class, 'eZ\Publish\API\Repository\Values\Content\Query\Aggregation\DateMetadataRangeAggregation');
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,24 @@

namespace Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Field;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Ranges\RangesGeneratorInterface;
use Traversable;

final class DateRangeAggregation extends AbstractFieldRangeAggregation
{
public static function fromGenerator(
string $name,
string $contentTypeIdentifier,
string $fieldDefinitionIdentifier,
RangesGeneratorInterface $generator
): self {
$ranges = $generator->generate();
if ($ranges instanceof Traversable) {
$ranges = iterator_to_array($ranges);
}

return new self($name, $contentTypeIdentifier, $fieldDefinitionIdentifier, $ranges);
}
}

class_alias(DateRangeAggregation::class, 'eZ\Publish\API\Repository\Values\Content\Query\Aggregation\Field\DateRangeAggregation');
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,24 @@

namespace Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Field;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Ranges\RangesGeneratorInterface;
use Traversable;

final class DateTimeRangeAggregation extends AbstractFieldRangeAggregation
{
public static function fromGenerator(
string $name,
string $contentTypeIdentifier,
string $fieldDefinitionIdentifier,
RangesGeneratorInterface $generator
): self {
$ranges = $generator->generate();
if ($ranges instanceof Traversable) {
$ranges = iterator_to_array($ranges);
}

return new self($name, $contentTypeIdentifier, $fieldDefinitionIdentifier, $ranges);
}
}

class_alias(DateTimeRangeAggregation::class, 'eZ\Publish\API\Repository\Values\Content\Query\Aggregation\Field\DateTimeRangeAggregation');
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,24 @@

namespace Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Field;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Ranges\RangesGeneratorInterface;
use Traversable;

final class FloatRangeAggregation extends AbstractFieldRangeAggregation
{
public static function fromGenerator(
string $name,
string $contentTypeIdentifier,
string $fieldDefinitionIdentifier,
RangesGeneratorInterface $generator
): self {
$ranges = $generator->generate();
if ($ranges instanceof Traversable) {
$ranges = iterator_to_array($ranges);
}

return new self($name, $contentTypeIdentifier, $fieldDefinitionIdentifier, $ranges);
}
}

class_alias(FloatRangeAggregation::class, 'eZ\Publish\API\Repository\Values\Content\Query\Aggregation\Field\FloatRangeAggregation');
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,24 @@

namespace Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Field;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Ranges\RangesGeneratorInterface;
use Traversable;

final class IntegerRangeAggregation extends AbstractFieldRangeAggregation
{
public static function fromGenerator(
string $name,
string $contentTypeIdentifier,
string $fieldDefinitionIdentifier,
RangesGeneratorInterface $generator
): self {
$ranges = $generator->generate();
if ($ranges instanceof Traversable) {
$ranges = iterator_to_array($ranges);
}

return new static($name, $contentTypeIdentifier, $fieldDefinitionIdentifier, $ranges);
}
}

class_alias(IntegerRangeAggregation::class, 'eZ\Publish\API\Repository\Values\Content\Query\Aggregation\Field\IntegerRangeAggregation');
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,24 @@

namespace Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Field;

use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Ranges\RangesGeneratorInterface;
use Traversable;

final class TimeRangeAggregation extends AbstractFieldRangeAggregation
{
public static function fromGenerator(
string $name,
string $contentTypeIdentifier,
string $fieldDefinitionIdentifier,
RangesGeneratorInterface $generator
): self {
$ranges = $generator->generate();
if ($ranges instanceof Traversable) {
$ranges = iterator_to_array($ranges);
}

return new self($name, $contentTypeIdentifier, $fieldDefinitionIdentifier, $ranges);
}
}

class_alias(TimeRangeAggregation::class, 'eZ\Publish\API\Repository\Values\Content\Query\Aggregation\Field\TimeRangeAggregation');
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

final class Range extends ValueObject
{
public const INF = null;

/**
* Beginning of the range (included).
*
Expand All @@ -27,12 +29,15 @@ final class Range extends ValueObject
*/
private $to;

public function __construct($from, $to)
private ?string $label;

public function __construct($from, $to, ?string $label = null)
{
parent::__construct();

$this->from = $from;
$this->to = $to;
$this->label = $label;
}

public function getFrom()
Expand All @@ -45,15 +50,39 @@ public function getTo()
return $this->to;
}

public function getLabel(): ?string
{
return $this->label;
}

public function setLabel(?string $label): void
{
$this->label = $label;
}

public function __toString(): string
{
if ($this->label !== null) {
return sprintf(
'%s:[%s;%s)',
$this->label,
$this->getRangeValueAsString($this->from),
$this->getRangeValueAsString($this->to)
);
}

return sprintf(
'[%s;%s)',
$this->getRangeValueAsString($this->from),
$this->getRangeValueAsString($this->to)
);
}

public function equalsTo(Range $value): bool
{
return $this->from == $value->from && $this->to == $value->to;
}

private function getRangeValueAsString($value): string
{
if ($value === null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?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\Aggregation\Ranges;

use DateInterval;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Range;

final class DateTimeStepRangesGenerator implements RangesGeneratorInterface
{
private DateTimeInterface $start;

private DateTimeInterface $end;

private DateInterval $step;

private bool $isLeftOpen = true;

private bool $isRightOpen = true;

public function __construct(DateTimeInterface $start, DateTimeInterface $end)
{
$this->start = $start;
$this->end = $end;
$this->step = new DateInterval('P1D');
}

public function getStart(): DateTimeInterface
{
return $this->start;
}

public function setStart(DateTimeInterface $start): self
{
$this->start = $start;

return $this;
}

public function getEnd(): DateTimeInterface
{
return $this->end;
}

public function setEnd(DateTimeInterface $end): self
{
$this->end = $end;

return $this;
}

public function getStep(): DateInterval
{
return $this->step;
}

public function setStep(DateInterval $step): self
{
$this->step = $step;

return $this;
}

public function isLeftOpen(): bool
{
return $this->isLeftOpen;
}

public function setLeftOpen(bool $isLeftOpen): void
{
$this->isLeftOpen = $isLeftOpen;
}

public function isRightOpen(): bool
{
return $this->isRightOpen;
}

public function setRightOpen(bool $isRightOpen): self
{
$this->isRightOpen = $isRightOpen;

return $this;
}

/**
* @return \Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Range[]
*/
public function generate(): array
{
if ($this->start == $this->end && $this->isLeftOpen && $this->isRightOpen) {
return [
new Range(Range::INF, Range::INF),
];
}

$ranges = [];

if ($this->isLeftOpen) {
$ranges[] = Range::ofDateTime(Range::INF, $this->start);
}

/** @var \DateTimeImmutable $current */
$current = $this->start;
if ($current instanceof DateTime) {
$current = DateTimeImmutable::createFromMutable($current);
}

while ($current < $this->end) {
$next = $current->add($this->step);
$ranges[] = Range::ofDateTime($current, $next);
$current = $next;
}

if ($this->isRightOpen) {
$ranges[] = Range::ofDateTime($this->end, Range::INF);
}

return $ranges;
}
}
Loading

0 comments on commit 9111b08

Please sign in to comment.