Completed
Push — master ( 9060a9...8d9a79 )
by Gabriel
02:31 queued 11s
created

ActiveRecordsTrait::insert()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 6
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
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
     * Inserts a Record into the database
106
     * @param Record $model
107
     * @param array|bool $onDuplicate
108
     * @return integer
109
     */
110
    public function insert($model, $onDuplicate = false)
111
    {
112
        $query = $this->insertQuery($model, $onDuplicate);
113
        $query->execute();
114
115
        return $this->getDB()->lastInsertID();
116
    }
117
118
    /**
119
     * @param Record $model
120
     * @param $onDuplicate
121
     * @return InsertQuery
122
     */
123
    public function insertQuery($model, $onDuplicate)
124
    {
125
        $inserts = $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

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

344
        $queryCount->setCols(/** @scrutinizer ignore-type */ 'count(*) as count');
Loading history...
345
        $result = $this->getDB()->execute($queryCount);
346
347
        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...
348
            $row = $result->fetchResult();
349
350
            return (int)$row['count'];
351
        }
352
353
        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...
354
    }
355
356
    /**
357
     * @param $data
358
     * @return mixed
359
     */
360
    public function cleanData($data)
361
    {
362
        return $this->getDB()->getAdapter()->cleanData($data);
363
    }
364
365
    /**
366
     * @param string $name
367
     * @param $arguments
368
     * @return RecordCollection|false
369
     */
370 1
    protected function isCallDatabaseOperation($name, $arguments)
371
    {
372 1
        $operations = ["find", "delete", "count"];
373 1
        foreach ($operations as $operation) {
374 1
            if (strpos($name, $operation . "By") !== false || strpos($name, $operation . "OneBy") !== false) {
375
                $params = [];
376
                if (count($arguments) > 1) {
377
                    $params = end($arguments);
378
                }
379
380
                $match = str_replace([$operation . "By", $operation . "OneBy"], "", $name);
381
                $field = inflector()->underscore($match);
382
383
                if ($field == $this->getPrimaryKey()) {
384
                    return $this->findByPrimary($arguments[0]);
385
                }
386
387
                $params['where'][] = ["$field " . (is_array($arguments[0]) ? "IN" : "=") . " ?", $arguments[0]];
388
389
                $operation = str_replace($match, "", $name) . "Params";
390
391
                $results = $this->$operation($params);
392
                // RETURN NULL TO DISTINCT FROM FALSE THAT MEANS NOT A DATABASE OPERATION
393 1
                return ($results) ? $results : null;
394
            }
395
        }
396
397 1
        return false;
398
    }
399
}
400