Completed
Push — master ( 6762cf...75869c )
by James Ekow Abaka
01:37
created

QueryParameters::getEagerLoad()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
namespace ntentan\nibii;
4
5
use ntentan\nibii\exceptions\FieldNotFoundException;
6
use ntentan\nibii\exceptions\NibiiException;
7
8
/**
9
 * Holds parameters used for the fields, where clauses, limits and offsets in queries
10
 *
11
 * @author ekow
12
 */
13
class QueryParameters
14
{
15
    /**
16
     * The where clause string of the query parameters.
17
     *
18
     * @var string
19
     */
20
    private $whereClause;
21
22
    /**
23
     * The string used for conjuctions.
24
     * This could either be 'AND' and or an 'OR' operator.
25
     *
26
     * @var string
27
     */
28
    private $conjunction = '';
29
30
    /**
31
     * Data that will be bound when a query is executed with this object.
32
     *
33
     * @var array
34
     */
35
    private $boundData = [];
36
37
    /**
38
     * This flag is set to true whenever there is bound data prepared.
39
     *
40
     * @var bool
41
     */
42
    private $preparedBoundData = false;
43
44
    /**
45
     * A list of fields that have arrays bound to them.
46
     *
47
     * @var array
48
     */
49
    private $boundArrays = [];
50
51
    /**
52
     * A list of fields that should be returned for the query.
53
     *
54
     * @var array
55
     */
56
    private $fields = [];
57
58
    /**
59
     * The database table to be queried.
60
     *
61
     * @var null|string
62
     */
63
    private $table;
64
65
    /**
66
     * When this flag is set, only the first item in the query is returned.
67
     * It essentially forces a limit of 1.
68
     *
69
     * @var bool
70
     */
71
    private $firstOnly = false;
72
73
    /**
74
     * The number of records to return after the query.
75
     *
76
     * @var int
77
     */
78
    private $limit;
79
80
    /**
81
     * The number of items to skip in the query.
82
     *
83
     * @var int
84
     */
85
    private $offset;
86
87
    /**
88
     * Holds a list of sorted fields, sort order and the order by which they should all be sorted.
89
     *
90
     * @var array
91
     */
92
    private $sorts = [];
93
94
    /**
95
     * QueryParameters constructor
96
     *
97
     * @param string $table The name of the table
98
     */
99 32
    public function __construct($table = null)
100
    {
101 32
        $this->table = $table;
102 32
    }
103
104
    /**
105
     * Get the comma seperated list of fields for the query.
106
     * In cases where no fields have been specifid, the wildcard * is returned.
107
     *
108
     * @return string
109
     */
110 24
    public function getFields()
111
    {
112 24
        $fields = '*';
113
114 24
        if (count($this->fields) > 0) {
115 12
            $fields = implode(', ', $this->fields);
116
        }
117
118 24
        return $fields;
119
    }
120
121
    /**
122
     * Set an array of fields that this query should return.
123
     *
124
     * @param array $fields
125
     * @return $this
126
     */
127 12
    public function setFields(array $fields)
128
    {
129 12
        $this->fields = $fields;
130 12
        return $this;
131
    }
132
133
    /**
134
     * Get the table for this query.
135
     *
136
     * @return null|string
137
     */
138 32
    public function getTable()
139
    {
140 32
        return $this->table;
141
    }
142
143
    /**
144
     * Set the table for this query.
145
     *
146
     * @param $table
147
     * @return $this For chaining
148
     */
149 12
    public function setTable($table)
150
    {
151 12
        $this->table = $table;
152 12
        return $this;
153
    }
154
155
    /**
156
     * Gets the limit clause of the query.
157
     *
158
     * @return null|string
159
     */
160 24
    public function getLimit()
161
    {
162 24
        return $this->limit > 0 ? " LIMIT {$this->limit}" : null;
163
    }
164
165 24
    public function getOffset()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
166
    {
167 24
        return $this->offset > 0 ? " OFFSET {$this->offset}" : null;
168
    }
169
170 32
    public function getWhereClause()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
171
    {
172 32
        if ($this->whereClause) {
173 30
            foreach ($this->boundArrays as $boundArray) {
174 8
                $where = "";
175 8
                $comma = "";
176 8
                for ($i = 0; $i < count($this->boundData[$boundArray]); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
177 8
                    $where .= "{$comma}:{$boundArray}_{$i}";
178 8
                    $comma = ', ';
179
                }
180 8
                $this->whereClause = str_replace("%{$boundArray}%", $where, $this->whereClause);
181
            }
182
        }
183 32
        return $this->whereClause ? " WHERE {$this->whereClause}" : '';
184
    }
185
186 32
    public function getBoundData()
187
    {
188 32
        if ($this->preparedBoundData === false) {
189 32
            $this->preparedBoundData = [];
0 ignored issues
show
Documentation Bug introduced by
It seems like array() of type array is incompatible with the declared type boolean of property $preparedBoundData.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
190 32
            foreach ($this->boundData as $key => $value) {
191 30
                if (in_array($key, $this->boundArrays)) {
192 8
                    foreach ($value as $i => $v) {
193 8
                        $this->preparedBoundData["{$key}_{$i}"] = $v;
194
                    }
195
                } else {
196 30
                    $this->preparedBoundData[$key] = $value;
197
                }
198
            }
199
        }
200 32
        return $this->preparedBoundData;
201
    }
202
203 4
    public function setBoundData($field, $value)
204
    {
205 4
        if (array_key_exists($field, $this->boundData)) {
206 4
            $isArray = is_array($value);
207 4
            $boundArray = in_array($field, $this->boundArrays);
208 4
            if ($isArray && !$boundArray) {
209
                throw new NibiiException("The field '{$field}' cannot be bound to an array");
210 4
            } else if (!$isArray && $boundArray) {
211
                throw new NibiiException("The field '{$field}' must be bound to an array");
212
            }
213 4
            $this->boundData[$field] = $value;
214 4
            $this->preparedBoundData = false;
215 4
            return $this;
216
        }
217
        throw new FieldNotFoundException("The field '{$field}' has not been bound to the current query");
218
    }
219
220 24
    public function getSorts()
221
    {
222 24
        return count($this->sorts) ? " ORDER BY " . implode(", ", $this->sorts) : null;
223
    }
224
225 24
    public function addFilter($field, $values = null)
226
    {
227 24
        $this->whereClause .= $this->conjunction;
228
229 24
        if (is_array($values)) {
230 8
            $this->whereClause .= "{$field} IN (%{$field}%)";
231 8
            $this->boundArrays[] = $field;
232 8
            $this->boundData[$field] = $values;
233
        } else {
234 22
            if ($values === null) {
235
                $this->whereClause .= "{$field} is NULL";
236
            } else {
237 22
                $this->whereClause .= "{$field} = :$field";
238 22
                $this->boundData[$field] = $values;
239
            }
240
        }
241 24
        $this->conjunction = ' AND ';
242 24
        return $this;
243
    }
244
245 6
    public function setFilter($filter, $values)
246
    {
247 6
        $filterCompiler = new FilterCompiler();
248 6
        $compiledFilter = $filterCompiler->compile($filter);
249 6
        $compiledValues = $filterCompiler->rewriteBoundData($values);
250 6
        $this->whereClause .= "{$this->conjunction}$compiledFilter";
251 6
        $this->boundData += $compiledValues;
252 6
    }
253
254
    /**
255
     * @param boolean $firstOnly
256
     * @return $this
257
     */
258 24
    public function setFirstOnly($firstOnly)
259
    {
260 24
        $this->firstOnly = $firstOnly;
261 24
        return $this;
262
    }
263
264 24
    public function getFirstOnly()
265
    {
266 24
        return $this->firstOnly;
267
    }
268
269
    public function setLimit($numItems)
270
    {
271
        $this->limit = $numItems;
272
    }
273
274
    public function setOffset($offset)
275
    {
276
        $this->offset = $offset;
277
    }
278
279
    /**
280
     * @param string $field
281
     * @param string $direction
282
     */
283
    public function addSort($field, $direction = 'ASC')
284
    {
285
        $this->sorts[] = "$field $direction";
286
    }
287
288
}
289