Expression::valuesFactory()   A
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 5
nop 1
dl 0
loc 15
rs 9.2222
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace BenTools\Where\Expression;
5
6
use BenTools\Where\Helper\Previewer;
7
8
abstract class Expression
9
{
10
    /**
11
     * @var Expression
12
     */
13
    protected $expression;
14
15
    /**
16
     * @param       $expression
17
     * @param array ...$values
18
     * @return CompositeExpression
19
     * @throws \InvalidArgumentException
20
     */
21
    final public function and($expression, ...$values): CompositeExpression
22
    {
23
        $expression = self::where($expression, ...$values);
24
        return new CompositeExpression(' AND ', $this, $expression);
25
    }
26
27
    /**
28
     * @param       $expression
29
     * @param array ...$values
30
     * @return CompositeExpression
31
     * @throws \InvalidArgumentException
32
     */
33
    final public function or($expression, ...$values): CompositeExpression
34
    {
35
        $expression = self::where($expression, ...$values);
36
        return new CompositeExpression(' OR ', $this, $expression);
37
    }
38
39
    /**
40
     * @param       $expression
41
     * @param array ...$values
42
     * @return CompositeExpression
43
     * @throws \InvalidArgumentException
44
     */
45
    final public function plus($expression, ...$values): CompositeExpression
46
    {
47
        $expression = self::where($expression, ...$values);
48
        return new CompositeExpression(', ', $this, $expression);
49
    }
50
51
    /**
52
     * @param       $expression
53
     * @param array ...$values
54
     * @return CompositeExpression
55
     * @throws \InvalidArgumentException
56
     */
57
    final public function as($expression, ...$values): CompositeExpression
58
    {
59
        $expression = self::where($expression, ...$values);
60
        return new CompositeExpression(' AS ', $this, $expression);
61
    }
62
63
    /**
64
     * @return GroupExpression
65
     */
66
    final public function asGroup(): GroupExpression
67
    {
68
        return $this instanceof GroupExpression ? $this : new GroupExpression($this);
69
    }
70
71
    /**
72
     * @return Expression|NegatedExpression
73
     */
74
    final public function negate(): Expression
75
    {
76
        return $this instanceof NegatedExpression ? clone $this->expression : new NegatedExpression($this);
77
    }
78
79
    /**
80
     * @param       $expression
81
     * @param array ...$values
82
     * @return Expression
83
     * @throws \InvalidArgumentException
84
     */
85
    final public static function where($expression, ...$values): self
86
    {
87
        if (\is_scalar($expression)) {
88
            return new Condition($expression, self::valuesFactory($values));
89
        }
90
        if ($expression instanceof self) {
91
            if (1 !== \func_num_args()) {
92
                throw new \InvalidArgumentException("Cannot pass values to an existing Expression object.");
93
            }
94
            return $expression;
95
        }
96
        throw new \InvalidArgumentException(\sprintf('Expected string or Expression object, %s given', \is_object($expression) ? \get_class($expression) : \gettype($expression)));
97
    }
98
99
    /**
100
     * @param       $expression
101
     * @param array ...$values
102
     * @return GroupExpression
103
     * @throws \InvalidArgumentException
104
     */
105
    final public static function group($expression, ...$values): GroupExpression
106
    {
107
        return new GroupExpression(self::where($expression, ...$values));
108
    }
109
110
    /**
111
     * @param       $expression
112
     * @param array ...$values
113
     * @return NegatedExpression
114
     * @throws \InvalidArgumentException
115
     */
116
    final public static function not($expression, ...$values): NegatedExpression
117
    {
118
        return new NegatedExpression(self::where($expression, ...$values));
119
    }
120
121
    /**
122
     * @param array $values
123
     * @return array
124
     * @throws \InvalidArgumentException
125
     */
126
    final private static function valuesFactory(array $values): array
127
    {
128
        if (0 === \count($values)) {
129
            return [];
130
        }
131
        if (1 === \count($values) && \is_array($values[0])) {
132
            return $values[0];
133
        }
134
        foreach ($values as $value) {
135
            if (\is_array($value)) {
136
                throw new \InvalidArgumentException("Cannot construct expression with multiple array values.");
137
            }
138
        }
139
        return $values;
140
    }
141
142
    /**
143
     * @return string
144
     */
145
    abstract public function __toString(): string;
146
147
    /**
148
     * @return array
149
     */
150
    abstract public function getValues(): array;
151
152
    /**
153
     * @return string
154
     */
155
    public function preview(): string
156
    {
157
        return Previewer::preview((string) $this, $this->getValues());
158
    }
159
160
    /**
161
     * @param Expression[] ...$expressions
162
     * @return array
163
     */
164
    final public static function valuesOf(self ...$expressions): array
165
    {
166
        $generator = function (Expression ...$expressions) {
167
            foreach ($expressions as $expression) {
168
                foreach ($expression->getValues() as $key => $value) {
169
                    if (\is_numeric($key)) {
170
                        yield $value;
171
                    } else {
172
                        yield $key => $value;
173
                    }
174
                }
175
            }
176
        };
177
        return \iterator_to_array($generator(...$expressions));
178
    }
179
}
180