Completed
Push — master ( b43053...9b95b7 )
by Jared
03:16
created

Query   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 306
Duplicated Lines 0 %

Coupling/Cohesion

Components 5
Dependencies 3

Importance

Changes 6
Bugs 0 Features 1
Metric Value
wmc 28
c 6
b 0
f 1
lcom 5
cbo 3
dl 0
loc 306
rs 10

17 Methods

Rating   Name   Duplication   Size   Complexity  
A getModel() 0 4 1
A getLimit() 0 4 1
A getStart() 0 4 1
A getSort() 0 4 1
A getWhere() 0 4 1
A getJoins() 0 4 1
A all() 0 4 1
A __construct() 0 9 1
A limit() 0 6 1
A start() 0 6 1
B sort() 0 25 4
A where() 0 21 4
A first() 0 10 3
A execute() 0 16 2
A join() 0 6 1
A set() 0 10 2
A delete() 0 10 2
1
<?php
2
3
/**
4
 * @author Jared King <[email protected]>
5
 *
6
 * @link http://jaredtking.com
7
 *
8
 * @copyright 2015 Jared King
9
 * @license MIT
10
 */
11
namespace Pulsar;
12
13
class Query
14
{
15
    const DEFAULT_LIMIT = 100;
16
    const MAX_LIMIT = 1000;
17
18
    /**
19
     * @var Model
20
     */
21
    private $model;
22
23
    /**
24
     * @var array
25
     */
26
    private $joins;
27
28
    /**
29
     * @var array
30
     */
31
    private $where;
32
33
    /**
34
     * @var int
35
     */
36
    private $limit;
37
38
    /**
39
     * @var int
40
     */
41
    private $start;
42
43
    /**
44
     * @var array
45
     */
46
    private $sort;
47
48
    /**
49
     * @param Model $model model class
50
     */
51
    public function __construct(Model $model = null)
52
    {
53
        $this->model = $model;
54
        $this->joins = [];
55
        $this->where = [];
56
        $this->start = 0;
57
        $this->limit = self::DEFAULT_LIMIT;
58
        $this->sort = [];
59
    }
60
61
    /**
62
     * Gets the model class associated with this query.
63
     *
64
     * @return Model
65
     */
66
    public function getModel()
67
    {
68
        return $this->model;
69
    }
70
71
    /**
72
     * Sets the limit for this query.
73
     *
74
     * @param int $limit
75
     *
76
     * @return self
77
     */
78
    public function limit($limit)
79
    {
80
        $this->limit = min($limit, self::MAX_LIMIT);
81
82
        return $this;
83
    }
84
85
    /**
86
     * Gets the limit for this query.
87
     *
88
     * @return int
89
     */
90
    public function getLimit()
91
    {
92
        return $this->limit;
93
    }
94
95
    /**
96
     * Sets the start offset.
97
     *
98
     * @param int $start
99
     *
100
     * @return self
101
     */
102
    public function start($start)
103
    {
104
        $this->start = max($start, 0);
105
106
        return $this;
107
    }
108
109
    /**
110
     * Gets the start offset.
111
     *
112
     * @return int
113
     */
114
    public function getStart()
115
    {
116
        return $this->start;
117
    }
118
119
    /**
120
     * Sets the sort pattern for the query.
121
     *
122
     * @param array|string $sort
123
     *
124
     * @return self
125
     */
126
    public function sort($sort)
127
    {
128
        $columns = explode(',', $sort);
129
130
        $sortParams = [];
131
        foreach ($columns as $column) {
132
            $c = explode(' ', trim($column));
133
134
            if (count($c) != 2) {
135
                continue;
136
            }
137
138
            // validate direction
139
            $direction = strtolower($c[1]);
140
            if (!in_array($direction, ['asc', 'desc'])) {
141
                continue;
142
            }
143
144
            $sortParams[] = [$c[0], $direction];
145
        }
146
147
        $this->sort = $sortParams;
148
149
        return $this;
150
    }
151
152
    /**
153
     * Gets the sort parameters.
154
     *
155
     * @return array
156
     */
157
    public function getSort()
158
    {
159
        return $this->sort;
160
    }
161
162
    /**
163
     * Sets the where parameters.
164
     * Accepts the following forms:
165
     *   i)   where(['name' => 'Bob'])
166
     *   ii)  where('name', 'Bob')
167
     *   iii) where('balance', 100, >)
168
     *   iv)  where('balance > 100').
169
     *
170
     * @param array|string $where
171
     * @param mixed        $value optional value
172
     * @param 
173
     *
174
     * @return self
175
     */
176
    public function where($where, $value = null, $condition = null)
177
    {
178
        // handles i.
179
        if (is_array($where)) {
180
            $this->where = array_merge($this->where, $where);
181
        } else {
182
            // handles iii.
183
            $args = func_num_args();
184
            if ($args > 2) {
185
                $this->where[] = [$where, $value, $condition];
186
            // handles ii.
187
            } elseif ($args == 2) {
188
                $this->where[$where] = $value;
189
            // handles iv.
190
            } else {
191
                $this->where[] = $where;
192
            }
193
        }
194
195
        return $this;
196
    }
197
198
    /**
199
     * Gets the where parameters.
200
     *
201
     * @return array
202
     */
203
    public function getWhere()
204
    {
205
        return $this->where;
206
    }
207
208
    /**
209
     * Adds a join to the query. Matches a property on this model
210
     * to the ID of the model we are joining.
211
     *
212
     * @param string $model      model being joined
213
     * @param string $localKey   name of local property
214
     * @param string $foreignKey name of foreign property
215
     *
216
     * @return self
217
     */
218
    public function join($model, $localKey, $foreignKey)
219
    {
220
        $this->joins[] = [$model, $localKey, $foreignKey];
221
222
        return $this;
223
    }
224
225
    /**
226
     * Gets the joins.
227
     *
228
     * @return array
229
     */
230
    public function getJoins()
231
    {
232
        return $this->joins;
233
    }
234
235
    /**
236
     * Executes the query against the model's adapter.
237
     *
238
     * @return array results
239
     */
240
    public function execute()
241
    {
242
        $model = $this->model;
243
244
        $adapter = $model::getAdapter();
245
246
        $models = [];
247
        foreach ($adapter->queryModels($this) as $row) {
248
            // create a model with the retrieved values
249
            $obj = new $model();
250
            $obj->refreshWith($row);
251
            $models[] = $obj;
252
        }
253
254
        return $models;
255
    }
256
257
    /**
258
     * Creates an iterator for a search.
259
     *
260
     * @return Model\Iterator
261
     */
262
    public function all()
263
    {
264
        return new Iterator($this);
265
    }
266
267
    /**
268
     * Executes the query against the model's adapter and returns the first result.
269
     *
270
     * @param int $limit
271
     * 
272
     * @return array|\Pulsar\Model|null when $limit = 1, returns a single model or null, otherwise returns an array
273
     */
274
    public function first($limit = 1)
275
    {
276
        $models = $this->limit($limit)->execute();
277
278
        if ($limit == 1) {
279
            return (count($models) == 1) ? $models[0] : null;
280
        }
281
282
        return $models;
283
    }
284
285
    /**
286
     * Updates all of the matched models.
287
     *
288
     * @param array $params key-value update parameters
289
     *
290
     * @return int # of models updated
291
     */
292
    public function set(array $params)
293
    {
294
        $n = 0;
295
        foreach ($this->all() as $model) {
296
            $model->set($params);
297
            ++$n;
298
        }
299
300
        return $n;
301
    }
302
303
    /**
304
     * Deletes all of the matched models.
305
     *
306
     * @return int # of models deleted
307
     */
308
    public function delete()
309
    {
310
        $n = 0;
311
        foreach ($this->all() as $model) {
312
            $model->delete();
313
            ++$n;
314
        }
315
316
        return $n;
317
    }
318
}
319