Completed
Push — master ( 09bb07...3577e6 )
by Gabriel
04:08 queued 10s
created

ActiveRecordsTrait::paginate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 2
dl 0
loc 15
ccs 0
cts 10
cp 0
crap 2
rs 9.9666
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A ActiveRecordsTrait::cleanData() 0 3 1
1
<?php
2
3
namespace Nip\Records\Traits\ActiveRecord;
4
5
use Nip\Database\Query\AbstractQuery as Query;
6
use Nip\Database\Query\Delete as DeleteQuery;
7
use Nip\Database\Query\Insert as InsertQuery;
8
use Nip\Database\Query\Select as SelectQuery;
9
use Nip\Database\Query\Update as UpdateQuery;
10
use Nip\Database\Result;
11
use Nip\Records\AbstractModels\Record;
12
use Nip\Records\Collections\Collection as RecordCollection;
13
use Nip\Records\Traits\HasDatabase\HasDatabaseRecordsTrait;
14
use Nip\Records\Traits\Searchable\SearchableRecordsTrait;
15
use Nip\Records\Traits\TableStructure\TableStructureRecordsTrait;
16
use Nip\Records\Traits\Unique\RecordsTrait as UniqueRecordsTrait;
17
use Nip\Records\Traits\HasForeignKey\RecordsTrait as HasForeignKeyTrait;
18
use Nip\Records\Traits\HasPrimaryKey\RecordsTrait as HasPrimaryKeyTrait;
19
20
/**
21
 * Class ActiveRecordsTrait
22
 * @package Nip\Records\Traits\ActiveRecord
23
 */
24
trait ActiveRecordsTrait
25
{
26
    use UniqueRecordsTrait;
27
    use HasForeignKeyTrait;
28
    use HasPrimaryKeyTrait;
29
    use SearchableRecordsTrait;
30
    use TableStructureRecordsTrait;
31
    use HasDatabaseRecordsTrait;
32
33
    /**
34
     * @var null|string
35
     */
36
    protected $table = null;
37
38
    /**
39
     * @return SelectQuery
40
     */
41
    public function newSelectQuery()
42
    {
43
        return $this->newQuery('select');
44
    }
45
46
    /**
47
     * Factory
48
     * @param string $type
49
     * @return Query|SelectQuery|InsertQuery|DeleteQuery|UpdateQuery
50
     */
51 5
    public function newQuery($type = 'select')
52
    {
53 5
        $query = $this->getDB()->newQuery($type);
54 5
        $query->cols("`" . $this->getTable() . "`.*");
0 ignored issues
show
Bug introduced by
'`' . $this->getTable() . '`.*' of type string is incompatible with the type array expected by parameter $| of Nip\Database\Query\AbstractQuery::cols(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

54
        $query->cols(/** @scrutinizer ignore-type */ "`" . $this->getTable() . "`.*");
Loading history...
55 5
        $query->from($this->getFullNameTable());
0 ignored issues
show
Bug introduced by
$this->getFullNameTable() of type string is incompatible with the type array expected by parameter $| of Nip\Database\Query\AbstractQuery::from(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

55
        $query->from(/** @scrutinizer ignore-type */ $this->getFullNameTable());
Loading history...
56 5
        $query->table($this->getTable());
0 ignored issues
show
Bug introduced by
$this->getTable() of type string is incompatible with the type array expected by parameter $| of Nip\Database\Query\AbstractQuery::table(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

56
        $query->table(/** @scrutinizer ignore-type */ $this->getTable());
Loading history...
57
58 5
        return $query;
59
    }
60
61
    /**
62
     * @return string
63
     */
64 10
    public function getTable()
65
    {
66 10
        if ($this->table === null) {
67 7
            $this->initTable();
68
        }
69
70 10
        return $this->table;
71
    }
72
73
    /**
74
     * @param string $table
75
     */
76 31
    public function setTable($table)
77
    {
78 31
        $this->table = $table;
79 31
    }
80
81 7
    protected function initTable()
82
    {
83 7
        $this->setTable($this->generateTable());
84 7
    }
85
86
    /**
87
     * @return string
88
     */
89 5
    protected function generateTable()
90
    {
91 5
        return str_replace('-', '_', $this->getController());
0 ignored issues
show
Bug introduced by
It seems like getController() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

91
        return str_replace('-', '_', $this->/** @scrutinizer ignore-call */ getController());
Loading history...
92
    }
93
94
    /**
95
     * @return string
96
     */
97 7
    public function getFullNameTable()
98
    {
99 7
        $database = $this->getDB()->getDatabase();
100
101 7
        return $database ? $database . '.' . $this->getTable() : $this->getTable();
102
    }
103
104
    /**
105
     * @return InsertQuery
106
     */
107
    public function newInsertQuery()
108
    {
109
        return $this->newQuery('insert');
110
    }
111
112
    /**
113
     * Updates a Record's database entry
114
     * @param Record $model
115
     * @return bool|Result
116
     */
117
    public function update(Record $model)
118
    {
119
        $query = $this->updateQuery($model);
120
121
        if ($query) {
122
            return $query->execute();
123
        }
124
125
        return false;
126
    }
127
128
    /**
129
     * @param Record $model
130
     * @return bool|UpdateQuery
131
     */
132
    public function updateQuery(Record $model)
133
    {
134
        $pk = $this->getPrimaryKey();
135
        if (!is_array($pk)) {
0 ignored issues
show
introduced by
The condition is_array($pk) is always false.
Loading history...
136
            $pk = [$pk];
137
        }
138
139
        $data = $this->getQueryModelData($model);
0 ignored issues
show
Bug introduced by
It seems like getQueryModelData() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

139
        /** @scrutinizer ignore-call */ 
140
        $data = $this->getQueryModelData($model);
Loading history...
140
141
        if ($data) {
142
            $query = $this->newUpdateQuery();
143
            $query->data($data);
144
145
            foreach ($pk as $key) {
146
                $query->where("$key = ?", $model->{$key});
147
            }
148
149
            return $query;
150
        }
151
152
        return false;
153
    }
154
155
156
157
    /**
158
     * @return UpdateQuery
159
     */
160
    public function newUpdateQuery()
161
    {
162
        return $this->newQuery('update');
163
    }
164
165
    /**
166
     * Saves a Record's database entry
167
     * @param Record $model
168
     * @return mixed
169
     */
170
    public function save(Record $model)
171
    {
172
        $pk = $this->getPrimaryKey();
173
174
        if (isset($model->{$pk})) {
175
            $model->update();
176
177
            return $model->{$pk};
178
        } else {
179
            /** @var Record $previous */
180
            $previous = $model->exists();
181
182
            if ($previous) {
0 ignored issues
show
introduced by
$previous is of type Nip\Records\AbstractModels\Record, thus it always evaluated to true.
Loading history...
183
                $data = $model->toArray();
184
185
                if ($data) {
186
                    $previous->writeData($model->toArray());
187
                }
188
                $previous->update();
189
190
                $model->writeData($previous->toArray());
191
192
                return $model->getPrimaryKey();
193
            }
194
        }
195
196
        $model->insert();
197
198
        return $model->getPrimaryKey();
199
    }
200
201
    /**
202
     * Delete a Record's database entry
203
     *
204
     * @param Record $input
205
     */
206
    public function delete($input)
207
    {
208
        $pk = $this->getPrimaryKey();
209
210
        if ($input instanceof $this->model) {
211
            $primary = $input->getPrimaryKey();
212
        } else {
213
            $primary = $input;
214
        }
215
216
        $query = $this->newDeleteQuery();
217
        $query->where("$pk = ?", $primary);
218
        $query->limit(1);
219
220
        $this->getDB()->execute($query);
221
    }
222
223
    /**
224
     * @return DeleteQuery
225
     */
226
    public function newDeleteQuery()
227
    {
228
        return $this->newQuery('delete');
229
    }
230
231
    /**
232
     * Delete a Record's database entry
233
     * @param array $params
234
     * @return $this
235
     */
236
    public function deleteByParams($params = [])
237
    {
238
        extract($params);
239
240
        $query = $this->newDeleteQuery();
241
242
        if (isset($where)) {
243
            if (is_array($where)) {
244
                foreach ($where as $condition) {
245
                    $condition = (array)$condition;
246
                    $query->where($condition[0], $condition[1]);
247
                }
248
            } else {
249
                call_user_func_array([$query, 'where'], $where);
250
            }
251
        }
252
253
        if (isset($order)) {
254
            call_user_func_array([$query, 'order'], $order);
255
        }
256
257
        if (isset($limit)) {
258
            call_user_func_array([$query, 'limit'], $limit);
259
        }
260
261
        $this->getDB()->execute($query);
262
263
        return $this;
264
    }
265
266
    /**
267
     * @param array $params
268
     * @return SelectQuery
269
     */
270 3
    public function paramsToQuery($params = [])
271
    {
272 3
        $this->injectParams($params);
273
274 3
        $query = $this->newQuery('select');
275 3
        $query->addParams($params);
276
277 3
        return $query;
278
    }
279
280
    /**
281
     * @param bool|array $where
282
     * @return int
283
     */
284
    public function count($where = false)
285
    {
286
        return $this->countByParams(["where" => $where]);
287
    }
288
289
    /**
290
     * Counts all the Record entries in the database
291
     * @param array $params
292
     * @return int
293
     */
294
    public function countByParams($params = [])
295
    {
296
        $this->injectParams($params);
297
        $query = $this->newQuery('select');
298
        $query->addParams($params);
299
300
        return $this->countByQuery($query);
301
    }
302
303
    /**
304
     * Counts all the Record entries in the database
305
     * @param Query $query
306
     * @return int
307
     */
308
    public function countByQuery($query)
309
    {
310
        $queryCount = clone $query;
311
        $queryCount->setCols('count(*) as count');
0 ignored issues
show
Bug introduced by
'count(*) as count' of type string is incompatible with the type array expected by parameter $| of Nip\Database\Query\AbstractQuery::setCols(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

311
        $queryCount->setCols(/** @scrutinizer ignore-type */ 'count(*) as count');
Loading history...
312
        $result = $this->getDB()->execute($queryCount);
313
314
        if ($result->numRows()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result->numRows() of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
315
            $row = $result->fetchResult();
316
317
            return (int)$row['count'];
318
        }
319
320
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type integer.
Loading history...
321
    }
322
323
    /**
324
     * @param $data
325
     * @return mixed
326
     */
327
    public function cleanData($data)
328
    {
329
        return $this->getDB()->getAdapter()->cleanData($data);
330
    }
331
332
    /**
333
     * @param string $name
334
     * @param $arguments
335
     * @return RecordCollection|false
336
     */
337 1
    protected function isCallDatabaseOperation($name, $arguments)
338
    {
339 1
        $operations = ["find", "delete", "count"];
340 1
        foreach ($operations as $operation) {
341 1
            if (strpos($name, $operation . "By") !== false || strpos($name, $operation . "OneBy") !== false) {
342
                $params = [];
343
                if (count($arguments) > 1) {
344
                    $params = end($arguments);
345
                }
346
347
                $match = str_replace([$operation . "By", $operation . "OneBy"], "", $name);
348
                $field = inflector()->underscore($match);
349
350
                if ($field == $this->getPrimaryKey()) {
351
                    return $this->findByPrimary($arguments[0]);
0 ignored issues
show
Bug introduced by
It seems like findByPrimary() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

351
                    return $this->/** @scrutinizer ignore-call */ findByPrimary($arguments[0]);
Loading history...
352
                }
353
354
                $params['where'][] = ["$field " . (is_array($arguments[0]) ? "IN" : "=") . " ?", $arguments[0]];
355
356
                $operation = str_replace($match, "", $name) . "Params";
357
358
                $results = $this->$operation($params);
359
                // RETURN NULL TO DISTINCT FROM FALSE THAT MEANS NOT A DATABASE OPERATION
360 1
                return ($results) ? $results : null;
361
            }
362
        }
363
364 1
        return false;
365
    }
366
}
367