Passed
Push — 1.0.0-dev ( d740ad...cd373d )
by nguereza
02:54
created

Model::deleteCond()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 0
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
    defined('ROOT_PATH') || exit('Access denied');
3
    /**
4
     * TNH Framework
5
     *
6
     * A simple PHP framework using HMVC architecture
7
     *
8
     * This content is released under the MIT License (MIT)
9
     *
10
     * Copyright (c) 2017 TNH Framework
11
     *
12
     * Permission is hereby granted, free of charge, to any person obtaining a copy
13
     * of this software and associated documentation files (the "Software"), to deal
14
     * in the Software without restriction, including without limitation the rights
15
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
     * copies of the Software, and to permit persons to whom the Software is
17
     * furnished to do so, subject to the following conditions:
18
     *
19
     * The above copyright notice and this permission notice shall be included in all
20
     * copies or substantial portions of the Software.
21
     *
22
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
     * SOFTWARE.
29
     */
30
31
32
    /**
33
     * A base model with a series of CRUD functions (powered by CI's query builder),
34
     * validation-in-model support, event callbacks and more.
35
     *
36
     * @link http://github.com/jamierumbelow/codeigniter-base-model
37
     * @copyright Copyright (c) 2012, Jamie Rumbelow <http://jamierumbelow.net>
38
     */
39
40
    class Model {
41
42
       /**
43
         * This model's default database table. 
44
         * @var string the name of table
45
         */
46
        protected $table = '';
47
48
        /**
49
         * The database connection object. Will be set to the default
50
         * connection. This allows individual models to use different DBs
51
         * without overwriting the global database connection.
52
         */
53
        protected $db = null;
54
55
        /**
56
         * This model's default primary key or unique identifier.
57
         * Used by the getSingleRecord(), update() and delete() functions.
58
         */
59
        protected $primaryKey = 'id';
60
61
        /**
62
         * Support for soft deletes and this model's 'deleted' key
63
         */
64
        /**
65
         * Whether soft delete is enabled or not
66
         * @var boolean
67
         */
68
        protected $softDeleteStatus = false;
69
70
        /**
71
         * Soft delete table column name to use
72
         * @var string
73
         */
74
        protected $softDeleteTableColumn = 'is_deleted';
75
76
        /**
77
         * Whether to return the records with the deleted
78
         * @var boolean
79
         */
80
        protected $returnRecordWithDeleted = false;
81
82
        /**
83
         * Whether to return only the deleted records
84
         * @var boolean
85
         */
86
        protected $returnOnlyRecordDeleted = false;
87
88
        /**
89
         * The various callbacks available to the model. Each are
90
         * simple lists of method names (methods will be call on $this->xxx).
91
         */
92
        protected $beforeCreateCallbacks = array();
93
        protected $afterCreateCallbacks = array();
94
        protected $beforeUpdateCallbacks = array();
95
        protected $afterUpdateCallbacks = array();
96
        protected $beforeGetCallbacks = array();
97
        protected $afterGetCallbacks = array();
98
        protected $beforeDeleteCallbacks = array();
99
        protected $afterDeleteCallbacks = array();
100
101
        /**
102
         * List of methods parameters to use in model callbacks
103
         * @var array
104
         */
105
        protected $callbackParameters = array();
106
107
        /**
108
         * Protected, non-modifiable tables columns
109
         * @var array the list of table attributes that can not be inserted 
110
         * or updated
111
         */
112
        protected $protectedTableColumns = array();
113
114
        /**
115
         * Relationship arrays. Use flat strings for defaults or 
116
         * string => array to customise the class name and primary key
117
         *
118
         * @example 
119
         *  For flat string:
120
         *  $manyToOne = array('relation_name')
121
         *
122
         *  For array:
123
         * $manyToOne = array('relation_name' => array(
124
         *  'primary_key' => 'pk_value',
125
         *  'modek' => 'model_name'
126
         * ))
127
         */
128
        protected $manyToOne = array();
129
        protected $oneToMany = array();
130
131
        /**
132
         * List of relation to return with the fetched record
133
         * @var array
134
         */
135
        protected $withs = array();
136
137
        /**
138
         * An array of validation rules. This needs to be the same format
139
         * as validation rules passed to the FormValidation::setRules library.
140
         */
141
        protected $validationRules = array();
142
143
        /**
144
         * Optionally skip the rules validation. Used in conjunction with
145
         * setSkipRulesValidation() to skip data validation for any future calls.
146
         */
147
        protected $skipRulesValidation = false;
148
149
        /**
150
         * By default we return our results as objects. If we need to override
151
         * this, we can, or, we could use the `asArray()` and `asObject()` scopes.
152
         */
153
        protected $returnRecordType = 'object';
154
155
        /**
156
         * Set return type array or object
157
         * @var string
158
         */
159
        protected $temporaryReturnRecordType = null;
160
    	
161
    	
162
        /**
163
         * The database cache time to live
164
         * The value is in second 
165
         * @example $dbCacheTimeToLive = 300; //so means 5 minutes
166
         *  for the cache to live
167
         *
168
         * @var integer 
169
         */
170
        protected $dbCacheTimeToLive = 0;
171
172
        /**
173
         * Initialise the model, tie into the CodeIgniter superobject and
174
         * try our best to guess the table name.
175
         *
176
         * @param object $db the Database instance to use
177
         * NOTE: each model need use different database instance 
178
         * for cache feature to work, so need use "clone" instead of use the global database 
179
         * instance directly.
180
         */
181
        public function __construct(Database $db = null) {
182
            $instance = null;
183
            if (is_object($db)) {
184
                $instance = $db;
185
            } else {
186
                $obj = & get_instance();
187
                if (isset($obj->database)){
188
                    /**
189
                     * NOTE: Need use "clone" because some Model need have the personal instance of the database library
190
                     * to prevent duplication
191
                     */
192
                    $instance = clone $obj->database;
193
                }
194
            }
195
            //Note: don't use the property direct access here as 
196
            //some update is done in the method
197
            //$this->setDb()
198
            $this->setDb($instance);
199
200
            array_unshift($this->beforeCreateCallbacks, 'removeProtectedTableColumns');
201
            array_unshift($this->beforeUpdateCallbacks, 'removeProtectedTableColumns');
202
            $this->temporaryReturnRecordType = $this->returnRecordType;
203
        }
204
205
        /**
206
         * Fetch a single record based on the primary key. Returns an object.
207
         *
208
         * @param mixed $pk the primary keys to get record for
209
         *
210
         * @return array|object
211
         */
212
        public function getSingleRecord($pk) {
213
            return $this->getSingleRecordCond($this->primaryKey, $pk);
214
        }
215
216
217
        /**
218
         * Fetch a single record based on an arbitrary WHERE call. Can be
219
         * any valid value to DatabaseQueryBuilder->where().
220
         *
221
         * @return array|object
222
         */
223
        public function getSingleRecordCond() {
224
            $where = func_get_args();
225
            $this->checkForSoftDelete();
226
            $this->setWhereValues($where);
227
            $this->trigger('beforeGetCallbacks');
228
            $type = $this->getReturnType();
229
            $this->getQueryBuilder()->from($this->table);
230
            $row = $this->db->get($type);
231
            $row = $this->trigger('afterGetCallbacks', $row);
232
            $this->temporaryReturnRecordType = $this->returnRecordType;
233
            $this->withs = array();
234
            return $row;
235
        }
236
237
        /**
238
         * Fetch all the records in the table. Can be used as a generic call
239
         * to $this->db->get() with scoped methods.
240
         *
241
         * @param array $pks the list of primary keys if not empty to get record
242
         *
243
         * @return array|object
244
         */
245
        public function getListRecord(array $pks = array()) {
246
            $this->trigger('beforeGetCallbacks');
247
            $this->checkForSoftDelete();
248
            if (!empty($pks)) {
249
                $this->getQueryBuilder()->in($this->primaryKey, $pks);
250
            }
251
            $type = $this->getReturnType();
252
            $this->getQueryBuilder()->from($this->table);
253
            $result = $this->db->getAll($type);
254
            foreach ($result as $key => &$row) {
255
                $row = $this->trigger('afterGetCallbacks', $row, ($key == count($result) - 1));
256
            }
257
            $this->temporaryReturnRecordType = $this->returnRecordType;
258
            $this->withs = array();
259
            return $result;
260
        }
261
262
        /**
263
         * Fetch an array of records based on an arbitrary WHERE call.
264
         *
265
         * @return array|object
266
         */
267
        public function getListRecordCond() {
268
            $where = func_get_args();
269
            $this->setWhereValues($where);
270
            return $this->getListRecord();
271
        }
272
273
        /**
274
         * Insert a new row into the table. $data should be an associative array
275
         * of data to be inserted. Returns newly created ID.
276
         *
277
         * @param array $data the data to be inserted
278
         * @param boolean $skipRulesValidation whether to skip rules validation or not
279
         * @param boolean $escape whether to escape all data values
280
         *
281
         * @return mixed the insert id if the table have auto increment or sequence id field
282
         */
283
        public function insert(array $data = array(), $skipRulesValidation = false, $escape = true) {
284
            if ($this->validateData($data, $skipRulesValidation) !== false) {
285
                $data = $this->trigger('beforeCreateCallbacks', $data);
286
                $this->getQueryBuilder()->from($this->table);
287
                $this->db->insert($data, $escape);
288
                $insertId = $this->db->insertId();
289
                $this->trigger('afterCreateCallbacks', $insertId);
290
                //if the table doesn't have the auto increment field 
291
                //or sequence, the value of 0 will be returned 
292
                if (!$insertId) {
293
                    $insertId = true;
294
                }
295
                return $insertId;
296
            } 
297
            return false;
298
        }
299
300
        /**
301
         * Insert multiple rows into the table.
302
         *
303
         * @param array $data the data to be inserted
304
         * @param boolean $skipRulesValidation whether to skip rules validation or not
305
         * @param boolean $escape whether to escape all data values
306
         *
307
         * @return mixed the array of insert id if the table have auto increment or sequence id field
308
         */
309
        public function insertMultiple(array $data = array(), $skipRulesValidation = false, $escape = true) {
310
            $ids = array();
311
            foreach ($data as $key => $row) {
312
                $ids[] = $this->insert($row, $skipRulesValidation, $escape);
313
            }
314
            return $ids;
315
        }
316
317
        /**
318
         * Updated a record based on the primary key value.
319
         *
320
         * @param mixed $pk the value of primary key to use to do update
321
         * @param array $data the data to be inserted
322
         * @param boolean $skipRulesValidation whether to skip rules validation or not
323
         * @param boolean $escape whether to escape all data values
324
         *
325
         * @return boolean the status of the operation
326
         */
327
        public function update($pk, array $data = array(), $skipRulesValidation = false, $escape = true) {
328
            $data = $this->trigger('beforeUpdateCallbacks', $data);
329
            if ($this->validateData($data, $skipRulesValidation) !== false) {
330
                $this->getQueryBuilder()->where($this->primaryKey, $pk)
331
                                        ->from($this->table);
332
                $result = $this->db->update($data, $escape);
333
                $this->trigger('afterUpdateCallbacks', array($data, $result));
334
                return $result;
335
            } 
336
            return false;
337
        }
338
339
        /**
340
         * Update many records, based on an array of primary keys values.
341
         * 
342
         * @param array $pks the array value of primary keys to do update
343
         * @param array $data the data to be inserted
344
         * @param boolean $skipRulesValidation whether to skip rules validation or not
345
         * @param boolean $escape whether to escape all data values
346
         *
347
         * @return boolean the status of the operation
348
         */
349
        public function updateMultiple($pks, array $data = array(), $skipRulesValidation = false, $escape = true) {
350
            $data = $this->trigger('beforeUpdateCallbacks', $data);
351
            if ($this->validateData($data, $skipRulesValidation) !== false) {
352
                $this->getQueryBuilder()->in($this->primaryKey, $pks)
353
                                        ->from($this->table);
354
                $result = $this->db->update($data, $escape);
355
                $this->trigger('afterUpdateCallbacks', array($data, $result));
356
                return $result;
357
            }
358
            return false;
359
        }
360
361
        /**
362
         * Updated a record based on an arbitrary WHERE clause.
363
         *
364
         * @return boolean the status of the operation
365
         */
366
        public function updateCond() {
367
            $args = func_get_args();
368
            $data = array();
369
            if (count($args) == 2 && is_array($args[1])) {
370
                $data = array_pop($args);
371
            } else if (count($args) == 3 && is_array($args[2])) {
372
                $data = array_pop($args);
373
            }
374
            $data = $this->trigger('beforeUpdateCallbacks', $data);
375
            if ($this->validateRules($data) !== false) {
0 ignored issues
show
introduced by
The condition $this->validateRules($data) !== false is always true.
Loading history...
376
                $this->setWhereValues($args);
377
                $this->getQueryBuilder()->from($this->table);
378
                $result = $this->db->update($data);
379
                $this->trigger('afterUpdateCallbacks', array($data, $result));
380
                return $result;
381
            }
382
            return false;
383
        }
384
385
        /**
386
         * Update all records in the database without conditions
387
         * 
388
         * @param array $data the data to be inserted
389
         * @param boolean $escape whether to escape all data values
390
         *
391
         * @return boolean the status of the operation
392
         */
393
        public function updateAllRecord(array $data = array(), $escape = true) {
394
            $data = $this->trigger('beforeUpdateCallbacks', $data);
395
            $this->getQueryBuilder()->from($this->table);
396
            $result = $this->db->update($data, $escape);
397
            $this->trigger('afterUpdateCallbacks', array($data, $result));
398
            return $result;
399
        }
400
401
        /**
402
         * Delete a row from the table by the primary value
403
         * @param array $id the value of primary key to do delete
404
         * 
405
         * @return boolean the status of the operation
406
         */
407
        public function delete($id) {
408
            $this->trigger('beforeDeleteCallbacks', $id);
409
            $this->getQueryBuilder()->where($this->primaryKey, $id);
410
            $this->getQueryBuilder()->from($this->table);  
411
            $result = $this->deleteRecords();
412
            $this->trigger('afterDeleteCallbacks', $result);
413
            return $result;
414
        }
415
416
        /**
417
         * Delete a row from the database table by an arbitrary WHERE clause
418
         * 
419
         * @return boolean the status of the operation
420
         */
421
        public function deleteCond() {
422
            $where = func_get_args();
423
            $where = $this->trigger('beforeDeleteCallbacks', $where);
424
            $this->setWhereValues($where);
425
            $this->getQueryBuilder()->from($this->table);  
426
            $result = $this->deleteRecords();
427
            $this->trigger('afterDeleteCallbacks', $result);
428
            return $result;
429
        }
430
431
        /**
432
         * Delete many rows from the database table by multiple primary values
433
         * 
434
         * @param array $pks the array value of primary keys to do delete
435
         *
436
         * @return boolean the status of the operation
437
         */
438
        public function deleteListRecord(array $pks) {
439
            $pks = $this->trigger('beforeDeleteCallbacks', $pks);
440
            $this->getQueryBuilder()->in($this->primaryKey, $pks);
441
            $this->getQueryBuilder()->from($this->table);  
442
            $result = $this->deleteRecords();
443
            $this->trigger('afterDeleteCallbacks', $result);
444
            return $result;
445
        }
446
447
        /**
448
         * Truncates the table
449
         *
450
         * @return boolean the truncate status
451
         */
452
        public function truncate() {
453
            $this->getQueryBuilder()->from($this->table); 
454
            $result = $this->db->delete();
455
            return $result;
456
        }
457
458
        /**
459
         * Return the record with the relation
460
         * @param  string $relationship the name of relation to fetch record
461
         * @return object               the current instance
462
         */
463
        public function with($relationship) {
464
            $this->withs[] = $relationship;
465
            if (!in_array('relate', $this->afterGetCallbacks)) {
466
                $this->afterGetCallbacks[] = 'relate';
467
            }
468
            return $this;
469
        }
470
		
471
        /**
472
         * Relationship
473
         * @param array|object $row the row to add relation data into
474
         *
475
         * @return array|object the final row after add relation data
476
         */
477
        protected function relate($row) {
478
            if (empty($row)) {
479
                return $row;
480
            }
481
            $row = $this->relateManyToOne($row);
482
            $row = $this->relateOneToMany($row);
483
            return $row;
484
        }
485
486
        /**
487
         * Retrieve and generate a data to use directly in Form::select()
488
         *
489
         * @return array
490
         */
491
        public function dropdown() {
492
            $args = func_get_args();
493
            if (count($args) == 2) {
494
                list($key, $value) = $args;
495
            } else {
496
                $key = $this->primaryKey;
497
                $value = $args[0];
498
            }
499
            $this->trigger('before_dropdown', array($key, $value));
500
            $this->checkForSoftDelete();
501
            $this->getQueryBuilder()->select(array($key, $value))
502
                                    ->from($this->table);
503
            $result = $this->db->getAll();
504
            $options = array();
505
            foreach ($result as $row) {
506
                $options[$row->{$key}] = $row->{$value};
507
            }
508
            $options = $this->trigger('after_dropdown', $options);
509
            return $options;
510
        }
511
512
        /**
513
         * Fetch a count of rows based on an arbitrary WHERE call.
514
         *
515
         * @return integer the number of rows
516
         */
517
        public function countCond() {
518
            $where = func_get_args();
519
            $this->checkForSoftDelete();
520
            $this->setWhereValues($where);
521
            $this->getQueryBuilder()->from($this->table);
522
            $this->db->getAll();
523
            return $this->db->numRows();
524
        }
525
526
        /**
527
         * Fetch a total count of rows, disregarding any previous conditions
528
         * 
529
         * @return integer the number of rows
530
         */
531
        public function countAllRecord() {
532
            $this->checkForSoftDelete();
533
            $this->getQueryBuilder()->from($this->table);
534
            $this->db->getAll();
535
            return $this->db->numRows();
536
        }
537
		
538
        /**
539
         * Enabled cache temporary. This method is the shortcut to Database::cached
540
         *
541
         * @param integer $ttl the cache default time to live
542
         *
543
         * @return object the current instance
544
         */
545
        public function cached($ttl = 0) {
546
            $this->db = $this->db->cached($ttl);
547
            return $this;
548
        }
549
550
        /**
551
         * Tell the class to skip the data validation
552
         * @param boolean $status the status of rules validation
553
         *
554
         * @return object the current instance
555
         */
556
        public function setSkipRulesValidation($status = true) {
557
            $this->skipRulesValidation = $status;
558
            return $this;
559
        }
560
561
        /**
562
         * Get the skip validation status
563
         *
564
         * @return boolean
565
         */
566
        public function isSkipRulesValidation() {
567
            return $this->skipRulesValidation;
568
        }
569
570
        /**
571
         * Return the next auto increment of the table. Only tested on MySQL.
572
         *
573
         * @return mixed
574
         */
575
        public function getNextAutoIncrementId() {
576
            $this->getQueryBuilder()->select('AUTO_INCREMENT')
577
                                    ->from('information_schema.TABLES')
578
                                    ->where('TABLE_NAME', $this->table)
579
                                    ->where('TABLE_SCHEMA', $this->db->getConnection()->getDatabase());
580
            return (int) $this->db->get()->AUTO_INCREMENT;
581
        }
582
583
        /**
584
         * Getter for the table name
585
         *
586
         * @return string the name of table
587
         */
588
        public function getTable() {
589
            return $this->table;
590
        }
591
592
        /**
593
         * Getter for the primary key name
594
         *
595
         * @return string the name of primary key
596
         */
597
        public function getPrimaryKey() {
598
            return $this->primaryKey;
599
        }
600
601
        /**
602
         * Return the next call as an array rather than an object
603
         */
604
        public function asArray() {
605
            $this->temporaryReturnRecordType = 'array';
606
            return $this;
607
        }
608
609
        /**
610
         * Return the next call as an object rather than an array
611
         */
612
        public function asObject() {
613
            $this->temporaryReturnRecordType = 'object';
614
            return $this;
615
        }
616
617
        /**
618
         * Don't care about soft deleted rows on the next call
619
         *
620
         * @return object the current instance
621
         */
622
        public function recordWithDeleted() {
623
            $this->returnRecordWithDeleted = true;
624
            return $this;
625
        }
626
627
        /**
628
         * Only get deleted rows on the next call
629
         * 
630
         * @return object the current instance
631
        */
632
        public function onlyRecordDeleted() {
633
            $this->returnOnlyRecordDeleted = true;
634
            return $this;
635
        }
636
637
        /**
638
         * Table DATETIME field created_at
639
         *
640
         * @param array|object $row the data to be inserted
641
         *
642
         * @return array|object the data after add field for created time
643
         */
644
        public function createdAt($row) {
645
            if (is_object($row)) {
646
                $row->created_at = date('Y-m-d H:i:s');
647
            } else {
648
                $row['created_at'] = date('Y-m-d H:i:s');
649
            }
650
            return $row;
651
        }
652
653
        /**
654
         * Table DATETIME field  updated_at
655
         *
656
         * @param array|object $row the data to be updated
657
         *
658
         * @return array|object the data after add field for updated time
659
         */
660
        public function updatedAt($row) {
661
            if (is_object($row)) {
662
                $row->updated_at = date('Y-m-d H:i:s');
663
            } else {
664
                $row['updated_at'] = date('Y-m-d H:i:s');
665
            }
666
            return $row;
667
        }
668
669
        /**
670
         * Serialises data for you automatically, allowing you to pass
671
         * through objects and let it handle the serialisation in the background
672
         *
673
         * @param array|object $row the data to be serialized
674
         * 
675
         * @return array|object the data after processing
676
         */
677
        public function serialize($row) {
678
            foreach ($this->callbackParameters as $column) {
679
                $row[$column] = serialize($row[$column]);
680
            }
681
            return $row;
682
        }
683
684
        /**
685
         * Unserialises data for you automatically, allowing you to pass
686
         * through objects and let it handle the serialisation in the background
687
         *
688
         * @param array|object $row the data to be unserialized
689
         * 
690
         * @return array|object the data after processing
691
         */
692
        public function unserialize($row) {
693
            foreach ($this->callbackParameters as $column) {
694
                if (is_array($row)) {
695
                    $row[$column] = unserialize($row[$column]);
696
                } else {
697
                    $row->$column = unserialize($row->$column);
698
                }
699
            }
700
            return $row;
701
        }
702
703
        /**
704
         * Protect attributes by removing them from data to insert or update
705
         *
706
         * @return mixed the final row after remove the protected
707
         * table columns if they exist
708
         */
709
        public function removeProtectedTableColumns($row) {
710
            foreach ($this->protectedTableColumns as $attr) {
711
                if (is_object($row) && isset($row->$attr)) {
712
                    unset($row->$attr);
713
                } else if (isset($row[$attr])) {
714
                    unset($row[$attr]);
715
                }
716
            }
717
            return $row;
718
        }
719
		
720
        /**
721
         * Return the database instance
722
         * @return Database the database instance
723
         */
724
        public function getDb() {
725
            return $this->db;
726
        }
727
728
        /**
729
         * Set the Database instance for future use
730
         * @param Database $db the database object
731
         */
732
        public function setDb(Database $db = null) {
733
            $this->db = $db;
734
            if ($this->dbCacheTimeToLive > 0) {
735
                $this->db->setCacheTimeToLive($this->dbCacheTimeToLive);
0 ignored issues
show
Bug introduced by
The method setCacheTimeToLive() does not exist on null. ( Ignorable by Annotation )

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

735
                $this->db->/** @scrutinizer ignore-call */ 
736
                           setCacheTimeToLive($this->dbCacheTimeToLive);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
736
            }
737
            return $this;
738
        }
739
740
        /**
741
         * Return the queryBuilder instance this is the shortcut to database queryBuilder
742
         * @return object the DatabaseQueryBuilder instance
743
         */
744
        public function getQueryBuilder() {
745
            return $this->db->getQueryBuilder();
746
        }
747
748
        /**
749
         * Set the DatabaseQueryBuilder instance for future use
750
         * @param object $queryBuilder the DatabaseQueryBuilder object
751
         * @return object
752
         */
753
        public function setQueryBuilder($queryBuilder) {
754
            $this->db->setQueryBuilder($queryBuilder);
755
            return $this;
756
        }
757
758
        /* --------------------------------------------------------------
759
         * QUERY BUILDER DIRECT ACCESS METHODS
760
         * ------------------------------------------------------------ */
761
762
        /**
763
         * A wrapper to $this->getQueryBuilder()->orderBy()
764
         *
765
         * @see  DatabaseQueryBuilder::orderBy
766
         */
767
        public function orderBy($criteria, $order = 'ASC') {
768
            if (is_array($criteria)) {
769
                foreach ($criteria as $key => $value) {
770
                    $this->getQueryBuilder()->orderBy($key, $value);
771
                }
772
            } else {
773
                $this->getQueryBuilder()->orderBy($criteria, $order);
774
            }
775
            return $this;
776
        }
777
778
        /**
779
         * A wrapper to $this->getQueryBuilder()->limit()
780
         * 
781
         * @see  DatabaseQueryBuilder::limit
782
         */
783
        public function limit($offset = 0, $limit = 10) {
784
            $this->getQueryBuilder()->limit($offset, $limit);
785
            return $this;
786
        }
787
788
        /**
789
         * Delete record in tha database
790
         * 
791
         * @return boolean the delete status
792
         */
793
        protected function deleteRecords() {
794
            $result = false;
795
            if ($this->softDeleteStatus) {
796
                $result = $this->db->update(array($this->softDeleteTableColumn => true));
797
            } else {
798
                $result = $this->db->delete();
799
            }
800
            return $result;
801
        }
802
803
        /**
804
         * Validate the data using the validation rules
805
         * 
806
         * @param  array $data the data to validate before insert, update, etc.
807
         * @param boolean $skipValidation whether to skip validation or not
808
         * 
809
         * @return array|boolean
810
         */
811
        protected function validateData($data, $skipValidation) {
812
            if ($skipValidation === false) {
813
                $data = $this->validateRules($data);
814
            }
815
            return $data;
816
        }
817
818
        /**
819
         * Run validation on the passed data
820
         * @param  array $data the data to validate before insert, update, etc.
821
         * 
822
         * @return array|boolean 
823
         */
824
        protected function validateRules(array $data) {
825
            if ($this->skipRulesValidation || empty($this->validationRules)) {
826
                return $data;
827
            }
828
            get_instance()->formvalidation->setData($data);
829
            get_instance()->formvalidation->setRules($this->validationRules);
830
            if (get_instance()->formvalidation->validate() === true) {
831
                return $data;
832
            }
833
            return false;
834
        }
835
836
         /**
837
         * Get the record return type array or object
838
         * 
839
         * @return string|boolean
840
         */
841
        protected function getReturnType(){
842
            $type = false;
843
            if ($this->temporaryReturnRecordType == 'array') {
844
               $type = 'array';
845
            }
846
            return $type;
847
        }
848
849
         /**
850
         * Check if soft delete is enable setting the condition
851
         * @return object the current instance 
852
         */
853
        protected function checkForSoftDelete(){
854
            if ($this->softDeleteStatus && $this->returnRecordWithDeleted !== true) {
855
                $this->getQueryBuilder()->where(
856
                                                $this->softDeleteTableColumn, 
857
                                                (bool) $this->returnOnlyRecordDeleted
858
                                            );
859
            }
860
            return $this;
861
        }
862
863
         /**
864
         * Relate for "manyToOne" and "oneToMany"
865
         * 
866
         * @param  string $relationship the name of relation
867
         * @param  string|array $options      the model and primary key values
868
         * @param  object|array $row          the row to update
869
         * @param  string $type the type can be "manyToOne", "oneToMany"
870
         * 
871
         * @return array|object the final row values
872
         */
873
        protected function relateOneToManyAndManyToOne($relationship, $options, $row, $type){
874
            if (in_array($relationship, $this->withs)) {
875
                get_instance()->loader->model($options['model'], $relationship . '_model');
876
                $model = get_instance()->{$relationship . '_model'};
877
                if($type == 'manyToOne'){
878
                    if (is_object($row)) {
879
                        $row->{$relationship} = $model->getSingleRecord($row->{$options['primary_key']});
880
                    } else {
881
                        $row[$relationship] = $model->getSingleRecord($row[$options['primary_key']]);
882
                    }
883
                } else {
884
                    if (is_object($row)) {
885
                        $row->{$relationship} = $model->getListRecordCond($options['primary_key'], $row->{$this->primaryKey});
886
                    } else {
887
                        $row[$relationship] = $model->getListRecordCond($options['primary_key'], $row[$this->primaryKey]);
888
                    }
889
                }
890
            }
891
            return $row;
892
        }
893
894
        /**
895
         * Relate for the relation "manyToOne"
896
         * @see Model::relateOneToManyAndManyToOne
897
         */
898
        protected function relateManyToOne($row) {
899
            foreach ($this->manyToOne as $key => $value) {
900
                $options = $this->getRelationshipOptions($key, $value);
901
                $row = $this->relateOneToManyAndManyToOne(
902
                                                            $options['relationship'], 
903
                                                            $options, 
904
                                                            $row, 
905
                                                            'manyToOne'
906
                                                        );
907
            }
908
            return $row;
909
        }
910
911
        /**
912
         * Relate for the relation "oneToMany"
913
         * @see Model::relateOneToManyAndManyToOne
914
         */
915
        protected function relateOneToMany($row) {
916
            foreach ($this->oneToMany as $key => $value) {
917
                $options = $this->getRelationshipOptions($key, $value);
918
                $row = $this->relateOneToManyAndManyToOne(
919
                                                            $options['relationship'], 
920
                                                            $options, 
921
                                                            $row, 
922
                                                            'oneToMany'
923
                                                        );
924
            }
925
            return $row;
926
        }
927
928
        /**
929
         * Get the relationship options to use 
930
         * @param  mixed $key   the relationship key
931
         * @param  mixed $value the raltionship value for custom option
932
         * @return array the options
933
         */
934
        protected function getRelationshipOptions($key, $value) {
935
            $relationship = null;
936
            $options = null;
937
            if (is_string($value)) {
938
                $relationship = $value;
939
                $options = array('primary_key' => $this->table . '_id', 'model' => $value . '_model');
940
            } else {
941
                $relationship = $key;
942
                $options = $value;
943
            }
944
            $options['relationship'] = $relationship;
945
            return $options;
946
        }
947
		
948
        /**
949
         * Trigger an event and call its observers. Pass through the event name
950
         * (which looks for an instance variable $this->event_name), an array of
951
         * parameters to pass through and an optional 'last in interation' boolean
952
         *
953
         * @param string $event the name of event like afterGetCallbacks
954
         * @param mixed $data the data to pass to the callback
955
         * @param boolean $last if is the last row of data to process
956
         *
957
         * @return mixed the data after each callbacks processed
958
         */
959
        protected function trigger($event, $data = false, $last = true) {
960
            if (isset($this->$event) && is_array($this->$event)) {
961
                foreach ($this->$event as $method) {
962
                    if (strpos($method, '(')) {
963
                        preg_match('/([a-zA-Z0-9\_\-]+)(\(([a-zA-Z0-9\_\-\., ]+)\))?/', $method, $matches);
964
                        $method = $matches[1];
965
                        $this->callbackParameters = explode(',', $matches[3]);
966
                    }
967
                    $data = call_user_func_array(array($this, $method), array($data, $last));
968
                }
969
            }
970
            return $data;
971
        }
972
		
973
        /**
974
         * Set WHERE parameters, when is array
975
         * @param array $params
976
         *
977
         * @return object the current instance
978
         */
979
        protected function setWhereValuesArray(array $params) {
980
            foreach ($params as $field => $filter) {
981
                if (is_array($filter)) {
982
                    $this->getQueryBuilder()->in($field, $filter);
983
                } else {
984
                    if (is_int($field)) {
985
                        $this->getQueryBuilder()->where($filter);
986
                    } else {
987
                        $this->getQueryBuilder()->where($field, $filter);
988
                    }
989
                }
990
            }
991
            return $this;
992
        }
993
994
        /**
995
         * Set WHERE parameters, cleverly
996
         * @param mixed $params the parameters of where
997
         * 
998
         * @return object the current instance
999
         */
1000
        protected function setWhereValues($params) {
1001
            if (count($params) == 1 && is_array($params[0])) {
1002
                $this->setWhereValuesArray($params[0]);
1003
            } else if (count($params) == 1) {
1004
                $this->getQueryBuilder()->where($params[0]);
1005
            } else if (count($params) == 2) {
1006
                if (is_array($params[1])) {
1007
                    $this->getQueryBuilder()->in($params[0], $params[1]);
1008
                } else {
1009
                    $this->getQueryBuilder()->where($params[0], $params[1]);
1010
                }
1011
            } else if (count($params) == 3) {
1012
                $this->getQueryBuilder()->where($params[0], $params[1], $params[2]);
1013
            } else {
1014
                if (is_array($params[1])) {
1015
                    $this->getQueryBuilder()->in($params[0], $params[1]);
1016
                } else {
1017
                    $this->getQueryBuilder()->where($params[0], $params[1]);
1018
                }
1019
            }
1020
        }
1021
    }
1022