Skip to content

Commit

Permalink
Fixes (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerych1984 committed May 29, 2022
1 parent f36ff7e commit 8f0ed75
Show file tree
Hide file tree
Showing 30 changed files with 682 additions and 322 deletions.
7 changes: 7 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,11 @@
<projectFiles>
<directory name="src" />
</projectFiles>
<issueHandlers>
<PropertyNotSetInConstructor>
<errorLevel type="suppress">
<file name="src/Filter/*.php" />
</errorLevel>
</PropertyNotSetInConstructor>
</issueHandlers>
</psalm>
39 changes: 39 additions & 0 deletions src/ColumnFormatterTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db;

use InvalidArgumentException;
use Yiisoft\Db\Expression\ExpressionInterface;

trait ColumnFormatterTrait
{
/**
* @var ExpressionInterface|string
*/
protected $column;

/**
* @param mixed $column
* @param string|null $table
*
* @throws InvalidArgumentException
*/
private function setColumn($column, ?string $table = null): void
{
if (\is_string($column)) {
if ($table) {
$this->column = $table . '.' . $column;
} else {
$this->column = $column;
}
} elseif ($column instanceof ExpressionInterface) {
$this->column = $column;
} else {
$type = \is_object($column) ? \get_class($column) : \gettype($column);

throw new InvalidArgumentException('Column must be string or instance of "' . ExpressionInterface::class . '". "' . $type . '" given.');
}
}
}
12 changes: 9 additions & 3 deletions src/Filter/Between.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Yiisoft\Data\Db\Filter;

use InvalidArgumentException;
use function count;

final class Between extends CompareFilter
{
Expand Down Expand Up @@ -43,15 +44,20 @@ public function toArray(): array
$isEndEmpty = self::isEmpty($end);

if (!$isStartEmpty && !$isEndEmpty) {
return [self::getOperator(), $this->column, $start, $end];
return [
self::getOperator(),
$this->column,
$this->formatValue($start),
$this->formatValue($end),
];
}

if (!$isStartEmpty) {
return [GreaterThanOrEqual::getOperator(), $this->column, $start];
return (new GreaterThanOrEqual($this->column, $start))->toArray();
}

if (!$isEndEmpty) {
return [LessThanOrEqual::getOperator(), $this->column, $end];
return (new LessThanOrEqual($this->column, $end))->toArray();
}

return [];
Expand Down
79 changes: 48 additions & 31 deletions src/Filter/CompareFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,23 @@

namespace Yiisoft\Data\Db\Filter;

use InvalidArgumentException;
use DateTimeInterface;
use Yiisoft\Data\Db\ColumnFormatterTrait;
use Yiisoft\Data\Reader\Filter\FilterInterface;
use Yiisoft\Db\Expression\ExpressionInterface;

abstract class CompareFilter implements FilterInterface
{
/**
* @var ExpressionInterface|string
*/
protected $column;
use ColumnFormatterTrait;

public static string $mainDateTimeFormat = 'Y-m-d H:i:s';

/**
* @var array|bool|float|int|string|null
* @var mixed
*/
protected $value;

/**
* @var bool
*/
protected bool $ignoreNull = false;
protected ?string $dateTimeFormat = null;

/**
* @param mixed $column
Expand All @@ -32,43 +29,63 @@ abstract class CompareFilter implements FilterInterface
public function __construct($column, $value, ?string $table = null)
{
$this->value = $value;

if ($column instanceof ExpressionInterface) {
$this->column = $column;
} elseif (is_string($column)) {
if ($table) {
$this->column = $table . '.' . $column;
} else {
$this->column = $column;
}
} else {
$type = \is_object($column) ? \get_class($column) : \gettype($column);
throw new InvalidArgumentException('Column must be string or instance of "' . ExpressionInterface::class . '". "' . $type . '" given.');
}
$this->setColumn($column, $table);
}

public function withIgnoreNull(bool $ignoreNull = false): self
public function withIgnoreNull(bool $ignoreNull = true): self
{
$new = clone $this;
$new->ignoreNull = $ignoreNull;

return $new;
}

public function getIgnoreNull(): bool
public function withDateTimeFormat(?string $format): self
{
return $this->ignoreNull;
$new = clone $this;
$new->dateTimeFormat = $format;

return $new;
}

/**
* @param mixed $value
*
* @return mixed
*/
protected function formatValue($value)
{
$format = $this->dateTimeFormat ?? self::$mainDateTimeFormat;

if ($format && $value instanceof DateTimeInterface) {
return $value->format($format);
}

return $value;
}

/**
* @psalm-param array<int, mixed> $values
*
* @return array
*/
protected function formatValues(array $values): array
{
return array_map([$this, 'formatValue'], $values);
}

public function toArray(): array
{
if ($this->value === null) {
if ($this->ignoreNull) {
return [];
}
return $this->ignoreNull ? [] : (new IsNull($this->column))->toArray();
}

return ['IS', $this->column, null];
if (is_array($this->value)) {
$value = $this->formatValues($this->value);
} else {
$value = $this->formatValue($this->value);
}

return [static::getOperator(), $this->column , $this->value];
return [static::getOperator(), $this->column , $value];
}
}
6 changes: 3 additions & 3 deletions src/Filter/Equals.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Yiisoft\Data\Db\Filter;

use Yiisoft\Db\Query\Query;
use Yiisoft\Db\Query\QueryInterface;
use Yiisoft\Data\Reader\Filter\Equals as FilterEquals;

final class Equals extends CompareFilter
Expand All @@ -16,8 +16,8 @@ public static function getOperator(): string

public function toArray(): array
{
if (is_array($this->value) || $this->value instanceof Query) {
return [In::getOperator(), $this->column, $this->value];
if (is_array($this->value) || $this->value instanceof QueryInterface) {
return (new In($this->column, $this->value))->toArray();
}

return parent::toArray();
Expand Down
5 changes: 3 additions & 2 deletions src/Filter/GroupFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Yiisoft\Data\Db\Filter;

use Yiisoft\Data\Reader\Filter\FilterInterface;
use function count;

abstract class GroupFilter implements FilterInterface
{
Expand All @@ -22,8 +23,8 @@ public function toArray(): array
foreach ($this->filters as $filter) {
$arr = $filter->toArray();

if (count($arr)) {
$array[] = $filter->toArray();
if ($arr !== []) {
$array[] = $arr;
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/Filter/In.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@

use InvalidArgumentException;
use Yiisoft\Data\Reader\Filter\In as FilterIn;
use Yiisoft\Db\Query\Query;
use Yiisoft\Db\Query\QueryInterface;

use function is_array;

final class In extends CompareFilter
{
/**
* @param mixed $column
* @param mixed $value
*/
public function __construct(string $column, $value, ?string $table = null)
public function __construct($column, $value, ?string $table = null)
{
if ($value !== null && !is_array($value) && $value instanceof Query === false) {
throw new InvalidArgumentException('value must be null, array or ' . Query::class . ' instance');
if ($value !== null && !is_array($value) && !is_a($value, QueryInterface::class)) {
throw new InvalidArgumentException('Value must be null, array or ' . QueryInterface::class . ' instance.');
}

parent::__construct($column, $value, $table);
Expand Down
32 changes: 32 additions & 0 deletions src/Filter/IsNull.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Filter;

use Yiisoft\Data\Db\ColumnFormatterTrait;
use Yiisoft\Data\Reader\Filter\FilterInterface;

final class IsNull implements FilterInterface
{
use ColumnFormatterTrait;

/**
* @param mixed $column
* @param string|null $table
*/
public function __construct($column, ?string $table = null)
{
$this->setColumn($column, $table);
}

public static function getOperator(): string
{
return 'is';
}

public function toArray(): array
{
return [self::getOperator(), $this->column, null];
}
}
27 changes: 8 additions & 19 deletions src/Filter/Like.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ class Like extends CompareFilter
private bool $start = true;
private bool $end = true;

public function __construct(string $column, ?string $value, ?string $table = null)
/**
* @param mixed $column
*/
public function __construct($column, ?string $value, ?string $table = null)
{
parent::__construct($column, $value, $table);
}
Expand All @@ -37,10 +40,6 @@ public function withoutBoth(): self

public function withStart(): self
{
if ($this->start === true) {
return $this;
}

$new = clone $this;
$new->start = true;

Expand All @@ -49,10 +48,6 @@ public function withStart(): self

public function withoutStart(): self
{
if ($this->start === false) {
return $this;
}

$new = clone $this;
$new->start = false;

Expand All @@ -61,10 +56,6 @@ public function withoutStart(): self

public function withEnd(): self
{
if ($this->end === true) {
return $this;
}

$new = clone $this;
$new->end = true;

Expand All @@ -73,10 +64,6 @@ public function withEnd(): self

public function withoutEnd(): self
{
if ($this->end === false) {
return $this;
}

$new = clone $this;
$new->end = false;

Expand All @@ -89,11 +76,13 @@ public function toArray(): array
return parent::toArray();
}

$value = $this->formatValue($this->value);

if (!$this->start && !$this->end) {
return [static::getOperator(), $this->column, $this->value, false];
return [static::getOperator(), $this->column, $value, false];
}

$value = $this->start ? '%' . $this->value : $this->value . '%';
$value = $this->start ? '%' . $value : $value . '%';

return [static::getOperator(), $this->column, $value, false];
}
Expand Down
6 changes: 4 additions & 2 deletions src/Filter/Not.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ public function toArray(): array
}

switch ($array[0]) {
case 'IS':
case IsNull::getOperator():
$array[0] .= ' ' . self::getOperator();
break;
case Exists::getOperator(): case In::getOperator(): case Between::getOperator():
case In::getOperator():
case Exists::getOperator():
case Between::getOperator():
$array[0] = self::getOperator() . ' ' . $array[0];
break;
default:
Expand Down

0 comments on commit 8f0ed75

Please sign in to comment.