Issues (590)

src/Query/Clause.php (1 issue)

1
<?php
2
3
namespace Bdf\Prime\Query;
4
5
use Doctrine\DBAL\Query\Expression\CompositeExpression;
6
7
/**
8
 * Clause
9
 *
10
 * @author seb
11
 */
12
class Clause implements ClauseInterface
13
{
14
    /**
15
     * The collection of custom filter.
16
     *
17
     * @var array<string,callable(static,mixed):void>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string,callable(static,mixed):void> at position 4 could not be parsed: Expected '>' at position 4, but found 'callable'.
Loading history...
18
     */
19
    protected $customFilters = [];
20
21
    /**
22
     * The clause statements
23
     *
24
     * @var array<string,mixed>
25
     */
26
    public $statements = [];
27
28
    /**
29
     * Available operators
30
     *
31
     * @var array<string, true>
32
     */
33
    protected $operators = [
34
        '<'             => true,
35
        ':lt'           => true,
36
        '<='            => true,
37
        ':lte'          => true,
38
        '>'             => true,
39
        ':gt'           => true,
40
        '>='            => true,
41
        ':gte'          => true,
42
        '~='            => true,
43
        '=~'            => true,
44
        ':regex'        => true,
45
        ':like'         => true,
46
        'in'            => true,
47
        ':in'           => true,
48
        'notin'         => true,
49
        '!in'           => true,
50
        ':notin'        => true,
51
        'between'       => true,
52
        ':between'      => true,
53
        '!between'      => true,
54
        ':notbetween'   => true,
55
        '<>'            => true,
56
        '!='            => true,
57
        ':ne'           => true,
58
        ':not'          => true,
59
        '='             => true,
60
        ':eq'           => true,
61
    ];
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 709
    public function setCustomFilters(array $filters)
67
    {
68 709
        $this->customFilters = $filters;
69
70 709
        return $this;
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76 2
    public function addCustomFilter(string $name, callable $callback)
77
    {
78 2
        $this->customFilters[$name] = $callback;
79
80 2
        return $this;
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function getCustomFilters(): array
87
    {
88
        return $this->customFilters;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94 122
    public function statement(string $statement): array
95
    {
96 122
        return $this->statements[$statement] ?? [];
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102 112
    public function addStatement(string $name, $values): void
103
    {
104 112
        $this->statements[$name][] = $values;
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110 676
    public function buildClause(string $statement, $expression, $operator = null, $value = null, string $type = CompositeExpression::TYPE_AND)
111
    {
112 676
        if (is_array($expression)) {
113
            //nested expression
114 618
            $glue = ($operator ?: CompositeExpression::TYPE_AND);
115 618
            $parts = [];
116
117 618
            foreach ($expression as $key => $value) {
118 295
                if (isset($this->customFilters[$key])) {
119
                    // Custom filter
120 2
                    $this->customFilters[$key]($this, $value);
121 294
                } elseif (is_int($key)) {
122
                    // Raw value
123 3
                    $this->buildRaw($statement, $value, $glue);
124 291
                } elseif ($key[0] === ':') {
125
                    // Special command
126 6
                    $this->addCommand($key, $value);
127
                } else {
128
                    // Column with operator
129 288
                    $key  = explode(' ', trim($key), 2);
130 288
                    $parts[] = [
131 288
                        'column'    => $key[0],
132 288
                        'operator'  => isset($key[1]) ? $key[1] : '=',
133 288
                        'value'     => $value,
134 288
                        'glue'      => $glue,
135 288
                    ];
136
                }
137
            }
138
139 618
            if ($parts) {
140 618
                $this->statements[$statement][] = [
141 618
                    'nested'  => $parts,
142 618
                    'glue'    => $type,
143 618
                ];
144
            }
145
        } else {
146
            //if no value. Check if operator is a value. Otherwise we assume it is a 'is null' request
147 414
            if ($value === null && (!is_string($operator) || !isset($this->operators[$operator]))) {
148 330
                $value = $operator;
149 330
                $operator = '=';
150
            }
151
152 414
            if (isset($this->customFilters[$expression])) {
153
                // Custom filter
154 3
                $this->customFilters[$expression]($this, $value);
155
            } else {
156
                // Column with operator
157 412
                $this->statements[$statement][] = [
158 412
                    'column'    => $expression,
159 412
                    'operator'  => $operator,
160 412
                    'value'     => $value,
161 412
                    'glue'      => $type,
162 412
                ];
163
            }
164
        }
165
166 676
        return $this;
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172 13
    public function buildRaw(string $statement, $expression, string $type = CompositeExpression::TYPE_AND)
173
    {
174 13
        $this->statements[$statement][] = [
175 13
            'raw'  => $expression,
176 13
            'glue' => $type,
177 13
        ];
178
179 13
        return $this;
180
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185 4
    public function buildNested(string $statement, callable $callback, string $type = CompositeExpression::TYPE_AND)
186
    {
187 4
        $statements = $this->statements;
188 4
        $this->statements = [];
189
190 4
        $callback($this);
191
192 4
        if (!empty($this->statements[$statement])) {
193 4
            $statements[$statement][] = [
194 4
                'nested' => $this->statements[$statement],
195 4
                'glue'   => $type,
196 4
            ];
197
        }
198
199 4
        $this->statements = $statements;
200
201 4
        return $this;
202
    }
203
204
    /**
205
     * @todo Revoir cette gestion des commandes
206
     * {@inheritdoc}
207
     */
208
    public function addCommand(string $command, $value)
209
    {
210
        // TO overload
211
212
        return $this;
213
    }
214
}
215