Completed
Push — master ( d58317...6c60b4 )
by BENOIT
05:45
created

Expression::plus()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace BenTools\Where\Expression;
5
6
abstract class Expression
7
{
8
9
    /**
10
     * @param       $expression
11
     * @param array ...$values
12
     * @return CompositeExpression
13
     * @throws \InvalidArgumentException
14
     */
15
    final public function and($expression, ...$values): CompositeExpression
16
    {
17
        $expression = $this->where($expression, ...$values);
18
        return new CompositeExpression(' AND ', $this, $expression);
19
    }
20
21
    /**
22
     * @param       $expression
23
     * @param array ...$values
24
     * @return CompositeExpression
25
     * @throws \InvalidArgumentException
26
     */
27
    final public function or($expression, ...$values): CompositeExpression
28
    {
29
        $expression = $this->where($expression, ...$values);
30
        return new CompositeExpression(' OR ', $this, $expression);
31
    }
32
33
    /**
34
     * @param       $expression
35
     * @param array ...$values
36
     * @return CompositeExpression
37
     * @throws \InvalidArgumentException
38
     */
39
    final public function plus($expression, ...$values): CompositeExpression
40
    {
41
        $expression = $this->where($expression, ...$values);
42
        return new CompositeExpression(', ', $this, $expression);
43
    }
44
45
    /**
46
     * @return GroupExpression
47
     */
48
    final public function asGroup(): GroupExpression
49
    {
50
        return $this instanceof GroupExpression ? $this : new GroupExpression($this);
51
    }
52
53
    /**
54
     * @return Expression|NegatedExpression
55
     */
56
    final public function negate(): Expression
57
    {
58
        return $this instanceof NegatedExpression ? clone $this->expression : new NegatedExpression($this);
0 ignored issues
show
Bug introduced by
The property expression does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
59
    }
60
61
    /**
62
     * @param       $expression
63
     * @param array ...$values
64
     * @return Expression
65
     * @throws \InvalidArgumentException
66
     */
67
    final public static function where($expression, ...$values): self
68
    {
69
        if (is_string($expression)) {
70
            return new Condition($expression, self::valuesFactory($values));
71
        }
72
        if ($expression instanceof self) {
73
            if (1 !== func_num_args()) {
74
                throw new \InvalidArgumentException("Cannot pass values to an existing Expression object.");
75
            }
76
            return $expression;
77
        }
78
        throw new \InvalidArgumentException(sprintf('Expected string or Expression object, %s given', is_object($expression) ? get_class($expression) : gettype($expression)));
79
    }
80
81
    /**
82
     * @param       $expression
83
     * @param array ...$values
84
     * @return GroupExpression
85
     * @throws \InvalidArgumentException
86
     */
87
    final public static function group($expression, ...$values): GroupExpression
88
    {
89
        return new GroupExpression(self::where($expression, ...$values));
90
    }
91
92
    /**
93
     * @param       $expression
94
     * @param array ...$values
95
     * @return NegatedExpression
96
     * @throws \InvalidArgumentException
97
     */
98
    final public static function not($expression, ...$values): NegatedExpression
99
    {
100
        return new NegatedExpression(self::where($expression, ...$values));
101
    }
102
103
    /**
104
     * @param array $values
105
     * @return array
106
     * @throws \InvalidArgumentException
107
     */
108
    final private static function valuesFactory(array $values): array
109
    {
110
        if (0 === count($values)) {
111
            return [];
112
        }
113
        if (1 === count($values) && is_array($values[0])) {
114
            return $values[0];
115
        }
116
        foreach ($values as $value) {
117
            if (is_array($value)) {
118
                throw new \InvalidArgumentException("Cannot construct expression with multiple array values.");
119
            }
120
        }
121
        return $values;
122
    }
123
124
    /**
125
     * @return string
126
     */
127
    abstract public function __toString(): string;
128
129
    /**
130
     * @return array
131
     */
132
    abstract public function getValues(): array;
133
134
    /**
135
     * @param Expression[] ...$expressions
136
     * @return array
137
     */
138
    final public static function valuesOf(self ...$expressions): array
139
    {
140
        $generator = function (Expression ...$expressions) {
141
            foreach ($expressions as $expression) {
142
                foreach ($expression->getValues() as $key => $value) {
143
                    if (is_numeric($key)) {
144
                        yield $value;
145
                    } else {
146
                        yield $key => $value;
147
                    }
148
                }
149
            }
150
        };
151
        return iterator_to_array($generator(...$expressions));
152
    }
153
}
154