Completed
Pull Request — master (#3870)
by Benjamin
119:20 queued 54:17
created

CompositeExpression::createPredicate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
ccs 1
cts 1
cp 1
cc 2
nc 2
nop 2
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Query\Expression;
6
7
use Countable;
8
use function array_merge;
9
use function array_unshift;
10
use function count;
11
use function implode;
12
13
/**
14
 * Composite expression is responsible to build a group of similar expression.
15
 *
16
 * This class is immutable.
17
 */
18
class CompositeExpression implements Countable
19
{
20
    /**
21
     * Constant that represents an AND composite expression.
22
     */
23
    public const TYPE_AND = 'AND';
24
25
    /**
26
     * Constant that represents an OR composite expression.
27
     */
28
    public const TYPE_OR = 'OR';
29
30
    /**
31
     * The instance type of composite expression.
32
     *
33
     * @var string
34
     */
35
    private $type;
36
37
    /**
38
     * Each expression part of the composite expression.
39
     *
40
     * @var array<int, self|string>
41
     */
42
    private $parts = [];
43
44 891
    /**
45
     * @internal Use the and() / or() factory methods.
46 891
     *
47
     * @param self|string $part
48 891
     * @param self|string ...$parts
49 891
     */
50
    private function __construct(string $type, $part, ...$parts)
51
    {
52
        $this->type  = $type;
53
        $this->parts = array_merge([$part], $parts);
54
    }
55
56
    /**
57
     * Creates a predicate from one or more predicates combined by the AND logic.
58 891
     *
59
     * @param self|string $predicate
60 891
     * @param self|string ...$predicates
61 567
     *
62
     * @return self|string
63
     */
64 891
    public static function createPredicate($predicate, ...$predicates)
65
    {
66
        if (count($predicates) === 0) {
67
            return $predicate;
68
        }
69
70
        return new self(self::TYPE_AND, $predicate, ...$predicates);
71
    }
72
73
    /**
74 891
     * Appends the given predicates combined by the given type of logic to the current predicate.
75
     *
76 891
     * @param self|string|null $currentPredicate
77
     * @param self|string      ...$predicates
78
     *
79
     * @return self|string
80 891
     */
81 27
    public static function appendToPredicate($currentPredicate, string $type, ...$predicates)
82
    {
83
        if ($currentPredicate instanceof self && $currentPredicate->type === $type) {
84 891
            return $currentPredicate->with(...$predicates);
85
        }
86 891
87
        if ($currentPredicate !== null) {
88
            array_unshift($predicates, $currentPredicate);
89
        } elseif (count($predicates) === 1) {
90
            return $predicates[0];
91
        }
92 864
93
        return new self($type, ...$predicates);
94 864
    }
95
96
    /**
97
     * @param self|string $part
98
     * @param self|string ...$parts
99
     */
100 810
    public static function and($part, ...$parts) : self
101
    {
102 810
        return new self(self::TYPE_AND, $part, ...$parts);
103 189
    }
104
105
    /**
106 621
     * @param self|string $part
107
     * @param self|string ...$parts
108
     */
109
    public static function or($part, ...$parts) : self
110
    {
111
        return new self(self::TYPE_OR, $part, ...$parts);
112 54
    }
113
114 54
    /**
115
     * Returns a new CompositeExpression with the given parts added.
116
     *
117
     * @param self|string $part
118
     * @param self|string ...$parts
119
     */
120
    public function with($part, ...$parts) : self
121
    {
122
        $that = clone $this;
123
124
        $that->parts[] = $part;
125
126
        foreach ($parts as $part) {
0 ignored issues
show
introduced by
$part is overwriting one of the parameters of this function.
Loading history...
127
            $that->parts[] = $part;
128
        }
129
130
        return $that;
131
    }
132
133
    /**
134
     * Retrieves the amount of expressions on composite expression.
135
     */
136
    public function count() : int
137
    {
138
        return count($this->parts);
139
    }
140
141
    /**
142
     * Retrieves the string representation of this composite expression.
143
     */
144
    public function __toString() : string
145
    {
146
        if ($this->count() === 1) {
147
            return (string) $this->parts[0];
148
        }
149
150
        return '(' . implode(') ' . $this->type . ' (', $this->parts) . ')';
151
    }
152
}
153