Passed
Push — master ( c65027...a39d50 )
by Wilmer
18:53 queued 16:02
created

BetweenColumnsCondition::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\QueryBuilder\Condition;
6
7
use Iterator;
8
use Yiisoft\Db\Exception\InvalidArgumentException;
9
use Yiisoft\Db\Expression\ExpressionInterface;
10
use Yiisoft\Db\QueryBuilder\Condition\Interface\BetweenColumnsConditionInterface;
11
12
/**
13
 * Class BetweenColumnCondition represents a `BETWEEN` condition where values are between two columns.
14
 *
15
 * For example:.
16
 *
17
 * ```php
18
 * new BetweenColumnsCondition(42, 'BETWEEN', 'min_value', 'max_value')
19
 * // Will be build to:
20
 * // 42 BETWEEN min_value AND max_value
21
 * ```
22
 *
23
 * And a more complex example:
24
 *
25
 * ```php
26
 * new BetweenColumnsCondition(
27
 *    new Expression('NOW()'),
28
 *    'NOT BETWEEN',
29
 *    (new Query)->select('time')->from('log')->orderBy('id ASC')->limit(1),
30
 *    'update_time'
31
 * );
32
 *
33
 * // Will be built to:
34
 * // NOW() NOT BETWEEN (SELECT time FROM log ORDER BY id ASC LIMIT 1) AND update_time
35
 * ```
36
 */
37
final class BetweenColumnsCondition implements BetweenColumnsConditionInterface
38
{
39
    public function __construct(
40
        private array|int|string|Iterator|ExpressionInterface $value,
41
        private string $operator,
42
        private string|ExpressionInterface $intervalStartColumn,
43
        private string|ExpressionInterface $intervalEndColumn
44
    ) {
45
    }
46
47
    public function getIntervalEndColumn(): string|ExpressionInterface
48
    {
49
        return $this->intervalEndColumn;
50
    }
51
52
    public function getIntervalStartColumn(): string|ExpressionInterface
53
    {
54
        return $this->intervalStartColumn;
55
    }
56
57
    public function getOperator(): string
58
    {
59
        return $this->operator;
60
    }
61
62
    public function getValue(): array|int|string|Iterator|ExpressionInterface
63
    {
64
        return $this->value;
65
    }
66
67
    /**
68
     * @throws InvalidArgumentException
69
     */
70
    public static function fromArrayDefinition(string $operator, array $operands): self
71
    {
72
        if (!isset($operands[0], $operands[1], $operands[2])) {
73
            throw new InvalidArgumentException("Operator '$operator' requires three operands.");
74
        }
75
76
        return new self(
77
            self::validateValue($operator, $operands[0]),
78
            $operator,
79
            self::validateIntervalStartColumn($operator, $operands[1]),
80
            self::validateIntervalEndColumn($operator, $operands[2]),
81
        );
82
    }
83
84
    private static function validateValue(
85
        string $operator,
86
        mixed $value
87
    ): array|int|string|Iterator|ExpressionInterface {
88
        if (
89
            !is_array($value) &&
90
            !is_int($value) &&
91
            !is_string($value) &&
92
            !($value instanceof Iterator) &&
93
            !($value instanceof ExpressionInterface)
94
        ) {
95
            throw new InvalidArgumentException(
96
                "Operator '$operator' requires value to be array, int, string, Iterator or ExpressionInterface."
97
            );
98
        }
99
100
        return $value;
101
    }
102
103
    private static function validateIntervalStartColumn(
104
        string $operator,
105
        mixed $intervalStartColumn
106
    ): string|ExpressionInterface {
107
        if (
108
            !is_string($intervalStartColumn) &&
109
            !($intervalStartColumn instanceof ExpressionInterface)
110
        ) {
111
            throw new InvalidArgumentException(
112
                "Operator '$operator' requires interval start column to be string or ExpressionInterface."
113
            );
114
        }
115
116
        return $intervalStartColumn;
117
    }
118
119
    private static function validateIntervalEndColumn(
120
        string $operator,
121
        mixed $intervalEndColumn
122
    ): string|ExpressionInterface {
123
        if (
124
            !is_string($intervalEndColumn) &&
125
            !($intervalEndColumn instanceof ExpressionInterface)
126
        ) {
127
            throw new InvalidArgumentException(
128
                "Operator '$operator' requires interval end column to be string or ExpressionInterface."
129
            );
130
        }
131
132
        return $intervalEndColumn;
133
    }
134
}
135