Skip to content

Commit

Permalink
IBX-6827: Ranges generators
Browse files Browse the repository at this point in the history
  • Loading branch information
adamwojs committed Nov 3, 2023
1 parent 73f42bb commit ba3b21f
Show file tree
Hide file tree
Showing 6 changed files with 376 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

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

abstract class AbstractFieldRangeAggregation extends AbstractRangeAggregation implements FieldAggregation
{
Expand All @@ -26,6 +28,20 @@ public function __construct(
$this->contentTypeIdentifier = $contentTypeIdentifier;
$this->fieldDefinitionIdentifier = $fieldDefinitionIdentifier;
}

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);

Check failure on line 43 in src/contracts/Repository/Values/Content/Query/Aggregation/Field/AbstractFieldRangeAggregation.php

View workflow job for this annotation

GitHub Actions / Unit tests & SQLite integration tests (7.4)

Unsafe usage of new static().

Check failure on line 43 in src/contracts/Repository/Values/Content/Query/Aggregation/Field/AbstractFieldRangeAggregation.php

View workflow job for this annotation

GitHub Actions / Unit tests & SQLite integration tests (8.0)

Unsafe usage of new static().

Check failure on line 43 in src/contracts/Repository/Values/Content/Query/Aggregation/Field/AbstractFieldRangeAggregation.php

View workflow job for this annotation

GitHub Actions / Unit tests & SQLite integration tests (8.1)

Unsafe usage of new static().
}
}

class_alias(AbstractFieldRangeAggregation::class, 'eZ\Publish\API\Repository\Values\Content\Query\Aggregation\Field\AbstractFieldRangeAggregation');
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ public function __toString(): string
);
}

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,125 @@
<?php

Check warning on line 1 in src/contracts/Repository/Values/Content/Query/Aggregation/Ranges/DateTimeStepRangesGenerator.php

View workflow job for this annotation

GitHub Actions / Run code style check (8.0)

Found violation(s) of type: class_attributes_separation

Check warning on line 1 in src/contracts/Repository/Values/Content/Query/Aggregation/Ranges/DateTimeStepRangesGenerator.php

View workflow job for this annotation

GitHub Actions / Run code style check (8.0)

Found violation(s) of type: no_unused_imports

/**
* @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 eZ\Publish\API\Repository\Values\Content\Query\Aggregation\Field\DateRangeAggregation;
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
{
$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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?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 Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Range;

final class FloatStepRangesGenerator implements RangesGeneratorInterface
{
private float $start;

private float $end;

private float $step = 1;

private bool $isLeftOpen = true;

private bool $isRightOpen = true;

public function __construct(float $start, float $end)
{
$this->start = $start;
$this->end = $end;
}

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

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

return $this;
}

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

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

return $this;
}

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

public function setStep(float $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
{
$ranges = [];

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

$values = range($this->start, $this->end, $this->step);
for ($i = 1; $i < count($values); ++$i) {
$ranges[] = Range::ofFloat($values[$i - 1], $values[$i]);
}

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

return $ranges;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?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 Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Range;

final class IntegerStepRangesGenerator implements RangesGeneratorInterface
{
private int $start;

private int $end;

private int $step = 1;

private bool $isLeftOpen = true;

private bool $isRightOpen = true;

public function __construct(int $start, int $end)
{
$this->start = $start;
$this->end = $end;
}

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

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

return $this;
}

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

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

return $this;
}

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

public function setStep(int $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(): \Generator

Check failure on line 92 in src/contracts/Repository/Values/Content/Query/Aggregation/Ranges/IntegerStepRangesGenerator.php

View workflow job for this annotation

GitHub Actions / Unit tests & SQLite integration tests (7.4)

PHPDoc tag @return with type array<Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Range> is incompatible with native type Generator.

Check failure on line 92 in src/contracts/Repository/Values/Content/Query/Aggregation/Ranges/IntegerStepRangesGenerator.php

View workflow job for this annotation

GitHub Actions / Unit tests & SQLite integration tests (8.0)

PHPDoc tag @return with type array<Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Range> is incompatible with native type Generator.

Check failure on line 92 in src/contracts/Repository/Values/Content/Query/Aggregation/Ranges/IntegerStepRangesGenerator.php

View workflow job for this annotation

GitHub Actions / Unit tests & SQLite integration tests (8.1)

PHPDoc tag @return with type array<Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Range> is incompatible with native type Generator.
{
if ($this->isLeftOpen) {
yield Range::ofInt(Range::INF, $this->start);
}

$values = range($this->start, $this->end, $this->step);
for ($i = 1; $i < count($values); ++$i) {
yield Range::ofInt($values[$i - 1], $values[$i]);
}

if ($this->isRightOpen) {
yield Range::ofInt($this->end, Range::INF);
}
}
}
Loading

0 comments on commit ba3b21f

Please sign in to comment.