Test Failed
Push — 1.0.0-dev ( 73dca1...204371 )
by nguereza
02:34
created

Model   F

Complexity

Total Complexity 121

Size/Duplication

Total Lines 893
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 344
c 0
b 0
f 0
dl 0
loc 893
rs 2
wmc 121

55 Methods

Rating   Name   Duplication   Size   Complexity  
B _set_where() 0 18 8
A setDatabaseInstance() 0 6 2
A updated_at() 0 7 2
A as_array() 0 3 1
A insert_many() 0 8 2
A getDatabaseInstance() 0 2 1
A insert() 0 21 4
A get_skip_validation() 0 2 1
A protect_attributes() 0 9 5
A getLoaderInstanceOrCreate() 0 5 2
A trigger() 0 12 5
A skip_validation() 0 3 1
A truncate() 0 4 1
A __construct() 0 18 3
A __get() 0 2 1
A checkForSoftDelete() 0 5 3
A count_by() 0 7 1
A only_deleted() 0 3 1
A order_by() 0 9 3
A with() 0 6 2
A _set_where_array() 0 9 4
A update() 0 15 3
A table() 0 2 1
A validate() 0 17 5
A get_by() 0 13 1
A get_many_by() 0 5 1
A delete_by() 0 14 2
A relateBelongsTo() 0 12 3
A getFormValidation() 0 2 1
A get_all() 0 13 2
A limit() 0 3 1
A as_object() 0 3 1
A delete_many() 0 12 2
A delete() 0 13 2
A get_many() 0 4 1
A get_next_id() 0 6 1
A relateHasMany() 0 12 3
A update_by() 0 21 6
A unserialize() 0 9 3
A relateBelongsToAndHasMany() 0 20 5
A setLoader() 0 3 1
A created_at() 0 7 2
A getLoader() 0 2 1
A getQueryBuilder() 0 2 1
A serialize() 0 5 2
A dropdown() 0 19 3
A relate() 0 7 2
A cached() 0 3 1
A getReturnType() 0 6 2
A update_many() 0 14 3
A setQueryBuilder() 0 3 1
A count_all() 0 6 1
A setFormValidation() 0 3 1
A update_all() 0 7 1
A with_deleted() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Model often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Model, and based on these observations, apply Extract Interface, too.

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 GNU GPL License (GPL)
9
     *
10
     * Copyright (C) 2017 Tony NGUEREZA
11
     *
12
     * This program is free software; you can redistribute it and/or
13
     * modify it under the terms of the GNU General Public License
14
     * as published by the Free Software Foundation; either version 3
15
     * of the License, or (at your option) any later version.
16
     *
17
     * This program is distributed in the hope that it will be useful,
18
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
     * GNU General Public License for more details.
21
     *
22
     * You should have received a copy of the GNU General Public License
23
     * along with this program; if not, write to the Free Software
24
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25
     */
26
27
28
    /**
29
     * A base model with a series of CRUD functions (powered by CI's query builder),
30
     * validation-in-model support, event callbacks and more.
31
     *
32
     * @link http://github.com/jamierumbelow/codeigniter-base-model
33
     * @copyright Copyright (c) 2012, Jamie Rumbelow <http://jamierumbelow.net>
34
     */
35
36
    class Model {
37
38
        /* --------------------------------------------------------------
39
         * VARIABLES
40
         * ------------------------------------------------------------ */
41
42
        /**
43
         * This model's default database table. Automatically
44
         * guessed by pluralising the model name.
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 $_database;
54
55
        /**
56
         * This model's default primary key or unique identifier.
57
         * Used by the get(), update() and delete() functions.
58
         */
59
        protected $primary_key = 'id';
60
61
        /**
62
         * Support for soft deletes and this model's 'deleted' key
63
         */
64
        protected $soft_delete = false;
65
        protected $soft_delete_key = 'is_deleted';
66
        protected $_temporary_with_deleted = FALSE;
67
        protected $_temporary_only_deleted = FALSE;
68
69
        /**
70
         * The various callbacks available to the model. Each are
71
         * simple lists of method names (methods will be run on $this).
72
         */
73
        protected $before_create = array();
74
        protected $after_create = array();
75
        protected $before_update = array();
76
        protected $after_update = array();
77
        protected $before_get = array();
78
        protected $after_get = array();
79
        protected $before_delete = array();
80
        protected $after_delete = array();
81
82
        protected $callback_parameters = array();
83
84
        /**
85
         * Protected, non-modifiable attributes
86
         */
87
        protected $protected_attributes = array();
88
89
        /**
90
         * Relationship arrays. Use flat strings for defaults or string
91
         * => array to customise the class name and primary key
92
         */
93
        protected $belongs_to = array();
94
        protected $has_many = array();
95
96
        protected $_with = array();
97
98
        /**
99
         * An array of validation rules. This needs to be the same format
100
         * as validation rules passed to the FormValidation library.
101
         */
102
        protected $validate = array();
103
104
        /**
105
         * Optionally skip the validation. Used in conjunction with
106
         * skip_validation() to skip data validation for any future calls.
107
         */
108
        protected $skip_validation = FALSE;
109
110
        /**
111
         * By default we return our results as objects. If we need to override
112
         * this, we can, or, we could use the `as_array()` and `as_object()` scopes.
113
         */
114
        protected $return_type = 'object';
115
116
        /**
117
         * Set return type array or object
118
         * @var string
119
         */
120
        protected $_temporary_return_type = NULL;
121
    	
122
    	
123
        /**
124
    		The database cache time 
125
         */
126
        protected $dbCacheTime = 0;
127
128
        /**
129
         * Instance of the Loader class
130
         * @var Loader
131
         */
132
        protected $loaderInstance = null;
133
134
        /**
135
         * Instance of the FormValidation library
136
         * @var FormValidation
137
         */
138
        protected $formValidationInstance = null;
139
		
140
        /* --------------------------------------------------------------
141
         * GENERIC METHODS
142
         * ------------------------------------------------------------ */
143
144
        /**
145
         * Initialise the model, tie into the CodeIgniter superobject and
146
         * try our best to guess the table name.
147
         */
148
        public function __construct(Database $db = null) {
149
            $instance = null;
150
            if (is_object($db)) {
151
                $instance = $db;
152
            } else if (isset(get_instance()->database)){
153
                /**
154
                 * NOTE: Need use "clone" because some Model need have the personal instance of the database library
155
                 * to prevent duplication
156
                 */
157
                $instance = clone get_instance()->database;
158
            }
159
            //Note: don't use the property direct access here as some update is done in the method
160
            //$this->setDatabaseInstance
161
            $this->setDatabaseInstance($instance);
162
163
            array_unshift($this->before_create, 'protect_attributes');
164
            array_unshift($this->before_update, 'protect_attributes');
165
            $this->_temporary_return_type = $this->return_type;
166
        }
167
168
        /* --------------------------------------------------------------
169
         * CRUD INTERFACE
170
         * ------------------------------------------------------------ */
171
172
        /**
173
         * Fetch a single record based on the primary key. Returns an object.
174
         */
175
        public function get($primary_value)
176
        {
177
            return $this->get_by($this->primary_key, $primary_value);
178
        }
179
180
181
        /**
182
         * Fetch a single record based on an arbitrary WHERE call. Can be
183
         * any valid value to DatabaseQueryBuilder->where().
184
         */
185
        public function get_by()
186
        {
187
            $where = func_get_args();
188
            $this->checkForSoftDelete();
189
            $this->_set_where($where);
190
            $this->trigger('before_get');
191
            $type = $this->getReturnType();
192
            $this->getQueryBuilder()->from($this->_table);
193
            $row = $this->_database->get($type);
194
            $this->_temporary_return_type = $this->return_type;
195
            $row = $this->trigger('after_get', $row);
196
            $this->_with = array();
197
            return $row;
198
        }
199
200
        /**
201
         * Fetch an array of records based on an array of primary values.
202
         */
203
        public function get_many($values)
204
        {
205
            $this->getQueryBuilder()->in($this->primary_key, $values);
206
            return $this->get_all();
207
        }
208
209
        /**
210
         * Fetch an array of records based on an arbitrary WHERE call.
211
         */
212
        public function get_many_by()
213
        {
214
            $where = func_get_args();
215
            $this->_set_where($where);
216
            return $this->get_all();
217
        }
218
219
        /**
220
         * Fetch all the records in the table. Can be used as a generic call
221
         * to $this->_database->get() with scoped methods.
222
         */
223
        public function get_all()
224
        {
225
            $this->trigger('before_get');
226
            $this->checkForSoftDelete();
227
            $type = $this->getReturnType();
228
            $this->getQueryBuilder()->from($this->_table);
229
            $result = $this->_database->getAll($type);
230
            $this->_temporary_return_type = $this->return_type;
231
            foreach ($result as $key => &$row) {
232
                $row = $this->trigger('after_get', $row, ($key == count($result) - 1));
233
            }
234
            $this->_with = array();
235
            return $result;
236
        }
237
238
        /**
239
         * Insert a new row into the table. $data should be an associative array
240
         * of data to be inserted. Returns newly created ID.
241
         * @see Database::insert
242
         */
243
        public function insert($data = array(), $skip_validation = FALSE, $escape = true)
244
        {
245
            if ($skip_validation === FALSE)
246
            {
247
                $data = $this->validate($data);
248
            }
249
250
            if ($data !== FALSE) {
251
                $data = $this->trigger('before_create', $data);
252
                $this->getQueryBuilder()->from($this->_table);
253
                $this->_database->insert($data, $escape);
254
                $insert_id = $this->_database->insertId();
255
                $this->trigger('after_create', $insert_id);
256
                //if the table doesn't have the auto increment field or sequence, the value of 0 will be returned 
257
                $id = $insert_id;
258
                if (!$id) {
259
                    $id = true;
260
                }
261
                return $id;
262
            } 
263
            return FALSE;
264
            
265
        }
266
267
        /**
268
         * Insert multiple rows into the table. Returns an array of multiple IDs.
269
         */
270
        public function insert_many($data = array(), $skip_validation = FALSE, $escape = true)
271
        {
272
            $ids = array();
273
            foreach ($data as $key => $row)
274
            {
275
                $ids[] = $this->insert($row, $skip_validation, $escape);
276
            }
277
            return $ids;
278
        }
279
280
        /**
281
         * Updated a record based on the primary value.
282
         */
283
        public function update($primary_value, $data = array(), $skip_validation = FALSE, $escape = true)
284
        {
285
            $data = $this->trigger('before_update', $data);
286
            if ($skip_validation === FALSE) {
287
                $data = $this->validate($data);
288
            }
289
290
            if ($data !== FALSE) {
291
                $this->getQueryBuilder()->where($this->primary_key, $primary_value)
292
                                        ->from($this->_table);
293
                $result = $this->_database->update($data, $escape);
294
                $this->trigger('after_update', array($data, $result));
295
                return $result;
296
            } 
297
            return FALSE;
298
        }
299
300
        /**
301
         * Update many records, based on an array of primary values.
302
         */
303
        public function update_many($primary_values, $data = array(), $skip_validation = FALSE, $escape = true)
304
        {
305
            $data = $this->trigger('before_update', $data);
306
            if ($skip_validation === FALSE) {
307
                $data = $this->validate($data);
308
            }
309
            if ($data !== FALSE) {
310
                $this->getQueryBuilder()->in($this->primary_key, $primary_values)
311
                                        ->from($this->_table);
312
                $result = $this->_database->update($data, $escape);
313
                $this->trigger('after_update', array($data, $result));
314
                return $result;
315
            }
316
            return FALSE;
317
        }
318
319
        /**
320
         * Updated a record based on an arbitrary WHERE clause.
321
         */
322
        public function update_by() {
323
            $args = func_get_args();
324
            $data = array();
325
            if (count($args) == 2) {
326
                if (is_array($args[1])) {
327
                    $data = array_pop($args);
328
                }
329
            } else if (count($args) == 3) {
330
                if (is_array($args[2])) {
331
                    $data = array_pop($args);
332
                }
333
            }
334
            $data = $this->trigger('before_update', $data);
335
            if ($this->validate($data) !== FALSE) {
336
                $this->_set_where($args);
337
                $this->getQueryBuilder()->from($this->_table);
338
                $result = $this->_database->update($data);
339
                $this->trigger('after_update', array($data, $result));
340
                return $result;
341
            }
342
            return FALSE;
343
        }
344
345
        /**
346
         * Update all records
347
         */
348
        public function update_all($data = array(), $escape = true)
349
        {
350
            $data = $this->trigger('before_update', $data);
351
            $this->getQueryBuilder()->from($this->_table);
352
            $result = $this->_database->update($data, $escape);
353
            $this->trigger('after_update', array($data, $result));
354
            return $result;
355
        }
356
357
        /**
358
         * Delete a row from the table by the primary value
359
         */
360
        public function delete($id)
361
        {
362
            $this->trigger('before_delete', $id);
363
            $this->getQueryBuilder()->where($this->primary_key, $id);
364
            $result = false;
365
            $this->getQueryBuilder()->from($this->_table);  
366
            if ($this->soft_delete) {
367
                $result = $this->_database->update(array($this->soft_delete_key => TRUE));
368
            } else {
369
                $result = $this->_database->delete();
370
            }
371
            $this->trigger('after_delete', $result);
372
            return $result;
373
        }
374
375
        /**
376
         * Delete a row from the database table by an arbitrary WHERE clause
377
         */
378
        public function delete_by()
379
        {
380
            $where = func_get_args();
381
            $where = $this->trigger('before_delete', $where);
382
            $this->_set_where($where);
383
            $result = false;
384
            $this->getQueryBuilder()->from($this->_table);  
385
            if ($this->soft_delete) {
386
                $result = $this->_database->update(array($this->soft_delete_key => TRUE));
387
            } else {
388
                $result = $this->_database->delete();
389
            }
390
            $this->trigger('after_delete', $result);
391
            return $result;
392
        }
393
394
        /**
395
         * Delete many rows from the database table by multiple primary values
396
         */
397
        public function delete_many($primary_values) {
398
            $primary_values = $this->trigger('before_delete', $primary_values);
399
            $this->getQueryBuilder()->in($this->primary_key, $primary_values);
400
            $result = false;
401
            $this->getQueryBuilder()->from($this->_table);  
402
            if ($this->soft_delete) {
403
                $result = $this->_database->update(array($this->soft_delete_key => TRUE));
404
            } else {
405
                $result = $this->_database->delete();
406
            }
407
            $this->trigger('after_delete', $result);
408
            return $result;
409
        }
410
411
412
        /**
413
         * Truncates the table
414
         */
415
        public function truncate() {
416
            $this->getQueryBuilder()->from($this->_table); 
417
            $result = $this->_database->delete();
418
            return $result;
419
        }
420
421
        /* --------------------------------------------------------------
422
         * RELATIONSHIPS
423
         * ------------------------------------------------------------ */
424
425
        public function with($relationship) {
426
            $this->_with[] = $relationship;
427
            if (!in_array('relate', $this->after_get)) {
428
                $this->after_get[] = 'relate';
429
            }
430
            return $this;
431
        }
432
		
433
        /**
434
         * Relationship
435
         */
436
        public function relate($row) {
437
            if (empty($row)) {
438
                return $row;
439
            }
440
            $row = $this->relateBelongsTo($row);
441
            $row = $this->relateHasMany($row);
442
            return $row;
443
        }
444
445
        /* --------------------------------------------------------------
446
         * UTILITY METHODS
447
         * ------------------------------------------------------------ */
448
449
        /**
450
         * Retrieve and generate a form_dropdown friendly array
451
         */
452
        public function dropdown() {
453
            $args = func_get_args();
454
            if (count($args) == 2) {
455
                list($key, $value) = $args;
456
            } else {
457
                $key = $this->primary_key;
458
                $value = $args[0];
459
            }
460
            $this->trigger('before_dropdown', array($key, $value));
461
            $this->checkForSoftDelete();
462
            $this->getQueryBuilder()->select(array($key, $value))
463
                                    ->from($this->_table);
464
            $result = $this->_database->getAll();
465
            $options = array();
466
            foreach ($result as $row) {
467
                $options[$row->{$key}] = $row->{$value};
468
            }
469
            $options = $this->trigger('after_dropdown', $options);
470
            return $options;
471
        }
472
473
        /**
474
         * Fetch a count of rows based on an arbitrary WHERE call.
475
         */
476
        public function count_by() {
477
            $this->checkForSoftDelete();
478
            $where = func_get_args();
479
            $this->_set_where($where);
480
            $this->getQueryBuilder()->from($this->_table);
481
            $this->_database->getAll();
482
            return $this->_database->numRows();
483
        }
484
485
        /**
486
         * Fetch a total count of rows, disregarding any previous conditions
487
         */
488
        public function count_all()
489
        {
490
            $this->checkForSoftDelete();
491
            $this->getQueryBuilder()->from($this->_table);
492
            $this->_database->getAll();
493
            return $this->_database->numRows();
494
        }
495
		
496
        /**
497
         * Enabled cache temporary
498
         */
499
        public function cached($ttl = 0) {
500
            $this->_database = $this->_database->cached($ttl);
501
            return $this;
502
        }
503
504
        /**
505
         * Tell the class to skip the insert validation
506
         */
507
        public function skip_validation() {
508
            $this->skip_validation = TRUE;
509
            return $this;
510
        }
511
512
        /**
513
         * Get the skip validation status
514
         */
515
        public function get_skip_validation() {
516
            return $this->skip_validation;
517
        }
518
519
        /**
520
         * Return the next auto increment of the table. Only tested on MySQL.
521
         */
522
        public function get_next_id() {
523
            $this->getQueryBuilder()->select('AUTO_INCREMENT')
524
                                    ->from('information_schema.TABLES')
525
                                    ->where('TABLE_NAME', $this->_table)
526
                                    ->where('TABLE_SCHEMA', $this->_database->getDatabaseName());
527
            return (int) $this->_database->get()->AUTO_INCREMENT;
528
        }
529
530
        /**
531
         * Getter for the table name
532
         */
533
        public function table() {
534
            return $this->_table;
535
        }
536
537
        /* --------------------------------------------------------------
538
         * GLOBAL SCOPES
539
         * ------------------------------------------------------------ */
540
541
        /**
542
         * Return the next call as an array rather than an object
543
         */
544
        public function as_array() {
545
            $this->_temporary_return_type = 'array';
546
            return $this;
547
        }
548
549
        /**
550
         * Return the next call as an object rather than an array
551
         */
552
        public function as_object() {
553
            $this->_temporary_return_type = 'object';
554
            return $this;
555
        }
556
557
        /**
558
         * Don't care about soft deleted rows on the next call
559
         */
560
        public function with_deleted() {
561
            $this->_temporary_with_deleted = TRUE;
562
            return $this;
563
        }
564
565
        /**
566
         * Only get deleted rows on the next call
567
         */
568
        public function only_deleted() {
569
            $this->_temporary_only_deleted = TRUE;
570
            return $this;
571
        }
572
573
        /* --------------------------------------------------------------
574
         * OBSERVERS
575
         * ------------------------------------------------------------ */
576
577
        /**
578
         * MySQL DATETIME created_at and updated_at
579
         */
580
        public function created_at($row) {
581
            if (is_object($row)) {
582
                $row->created_at = date('Y-m-d H:i:s');
583
            } else {
584
                $row['created_at'] = date('Y-m-d H:i:s');
585
            }
586
            return $row;
587
        }
588
589
        public function updated_at($row) {
590
            if (is_object($row)) {
591
                $row->updated_at = date('Y-m-d H:i:s');
592
            } else {
593
                $row['updated_at'] = date('Y-m-d H:i:s');
594
            }
595
            return $row;
596
        }
597
598
        /**
599
         * Serialises data for you automatically, allowing you to pass
600
         * through objects and let it handle the serialisation in the background
601
         */
602
        public function serialize($row) {
603
            foreach ($this->callback_parameters as $column) {
604
                $row[$column] = serialize($row[$column]);
605
            }
606
            return $row;
607
        }
608
609
        public function unserialize($row) {
610
            foreach ($this->callback_parameters as $column) {
611
                if (is_array($row)) {
612
                    $row[$column] = unserialize($row[$column]);
613
                } else {
614
                    $row->$column = unserialize($row->$column);
615
                }
616
            }
617
            return $row;
618
        }
619
620
        /**
621
         * Protect attributes by removing them from $row array
622
         */
623
        public function protect_attributes($row) {
624
            foreach ($this->protected_attributes as $attr) {
625
                if (is_object($row) && isset($row->$attr)) {
626
                    unset($row->$attr);
627
                } else if (isset($row[$attr])) {
628
                    unset($row[$attr]);
629
                }
630
            }
631
            return $row;
632
        }
633
		
634
            /**
635
             * Return the database instance
636
             * @return Database the database instance
637
             */
638
        public function getDatabaseInstance() {
639
            return $this->_database;
640
        }
641
642
        /**
643
         * set the Database instance for future use
644
         * @param Database $db the database object
645
         */
646
        public function setDatabaseInstance($db) {
647
            $this->_database = $db;
648
            if ($this->dbCacheTime > 0) {
649
                $this->_database->setCache($this->dbCacheTime);
650
            }
651
            return $this;
652
        }
653
654
        /**
655
         * Return the loader instance
656
         * @return Loader the loader instance
657
         */
658
        public function getLoader() {
659
            return $this->loaderInstance;
660
        }
661
662
        /**
663
         * Set the loader instance for future use
664
         * @param Loader $loader the loader object
665
         * @return object
666
         */
667
        public function setLoader($loader) {
668
            $this->loaderInstance = $loader;
669
            return $this;
670
        }
671
672
        /**
673
         * Return the queryBuilder instance this is the shortcut to database queryBuilder
674
         * @return object the DatabaseQueryBuilder instance
675
         */
676
        public function getQueryBuilder() {
677
            return $this->_database->getQueryBuilder();
678
        }
679
680
        /**
681
         * Set the DatabaseQueryBuilder instance for future use
682
         * @param object $queryBuilder the DatabaseQueryBuilder object
683
         * @return object
684
         */
685
        public function setQueryBuilder($queryBuilder) {
686
            $this->_database->setQueryBuilder($queryBuilder);
687
            return $this;
688
        }
689
690
        /**
691
         * Return the FormValidation instance
692
         * @return FormValidation the form validation instance
693
         */
694
        public function getFormValidation() {
695
            return $this->formValidationInstance;
696
        }
697
698
        /**
699
         * Set the form validation instance for future use
700
         * @param FormValidation $fv the form validation object
701
         * @return object
702
         */
703
        public function setFormValidation($fv) {
704
            $this->formValidationInstance = $fv;
705
            return $this;
706
        }
707
708
        /* --------------------------------------------------------------
709
         * QUERY BUILDER DIRECT ACCESS METHODS
710
         * ------------------------------------------------------------ */
711
712
        /**
713
         * A wrapper to $this->getQueryBuilder()->orderBy()
714
         */
715
        public function order_by($criteria, $order = 'ASC') {
716
            if (is_array($criteria)) {
717
                foreach ($criteria as $key => $value) {
718
                    $this->getQueryBuilder()->orderBy($key, $value);
719
                }
720
            } else {
721
                $this->getQueryBuilder()->orderBy($criteria, $order);
722
            }
723
            return $this;
724
        }
725
726
        /**
727
         * A wrapper to $this->getQueryBuilder()->limit()
728
         */
729
        public function limit($offset = 0, $limit = 10) {
730
            $this->getQueryBuilder()->limit($offset, $limit);
731
            return $this;
732
        }
733
734
        /* --------------------------------------------------------------
735
         * INTERNAL METHODS
736
         * ------------------------------------------------------------ */
737
        
738
        /**
739
         * Return the loader instance or create
740
         * @return object
741
         */
742
        protected function getLoaderInstanceOrCreate() {
743
            if (! is_object($this->loaderInstance)) {
744
                $this->loaderInstance = & get_instance()->loader;
745
            } 
746
            return $this->loaderInstance;
747
        }
748
749
         /**
750
         * Get the return type array or object
751
         * @return string|boolean
752
         */
753
        protected function getReturnType(){
754
            $type = false;
755
            if ($this->_temporary_return_type == 'array') {
756
               $type = 'array';
757
            }
758
            return $type;
759
        }
760
761
         /**
762
         * Check if soft delete is enable setting the condition
763
         * @return object the current instance 
764
         */
765
        protected function checkForSoftDelete(){
766
            if ($this->soft_delete && $this->_temporary_with_deleted !== true) {
767
                $this->getQueryBuilder()->where($this->soft_delete_key, (bool) $this->_temporary_only_deleted);
768
            }
769
            return $this;
770
        }
771
772
         /**
773
         * Relate for "belongs_to" and "has_many"
774
         * @param  string $relationship the name of relation
775
         * @param  string|array $options      the model and primary key values
776
         * @param  object|array $row          the row to update
777
         * @param  string $type         the type can be "belongs_to", "has_many"
778
         * @return mixed               the final row values
779
         */
780
        protected function relateBelongsToAndHasMany($relationship, $options, $row, $type){
781
            if (in_array($relationship, $this->_with)) {
782
                $loaderInstance = $this->getLoaderInstanceOrCreate();
783
                $loaderInstance->model($options['model'], $relationship . '_model');
784
785
                if($type = 'belongs_to'){
0 ignored issues
show
Unused Code introduced by
The assignment to $type is dead and can be removed.
Loading history...
786
                    if (is_object($row)) {
787
                        $row->{$relationship} = $this->{$relationship . '_model'}->get($row->{$options['primary_key']});
788
                    } else {
789
                        $row[$relationship] = $this->{$relationship . '_model'}->get($row[$options['primary_key']]);
790
                    }
791
                } else {
792
                    if (is_object($row)) {
793
                        $row->{$relationship} = $this->{$relationship . '_model'}->get_many_by($options['primary_key'], $row->{$this->primary_key});
794
                    } else {
795
                        $row[$relationship] = $this->{$relationship . '_model'}->get_many_by($options['primary_key'], $row[$this->primary_key]);
796
                    }
797
                }
798
            }
799
            return $row;
800
        }
801
802
        /**
803
         * relate for the relation "belongs_to"
804
         * @return mixed
805
         */
806
        protected function relateBelongsTo($row) {
807
            foreach ($this->belongs_to as $key => $value) {
808
                if (is_string($value)) {
809
                    $relationship = $value;
810
                    $options = array('primary_key' => $value . '_id', 'model' => $value . '_model');
811
                } else {
812
                    $relationship = $key;
813
                    $options = $value;
814
                }
815
                $row = $this->relateBelongsToAndHasMany($relationship, $options, $row, 'belongs_to');
816
            }
817
            return $row;
818
        }
819
820
        /**
821
         * relate for the relation "has_many"
822
         * @return mixed
823
         */
824
        protected function relateHasMany($row) {
825
            foreach ($this->has_many as $key => $value) {
826
                if (is_string($value)) {
827
                    $relationship = $value;
828
                    $options = array('primary_key' => $this->_table . '_id', 'model' => $value . '_model');
829
                } else {
830
                    $relationship = $key;
831
                    $options = $value;
832
                }
833
                $row = $this->relateBelongsToAndHasMany($relationship, $options, $row, 'belongs_to');
834
            }
835
            return $row;
836
        }
837
		
838
        /**
839
         * Trigger an event and call its observers. Pass through the event name
840
         * (which looks for an instance variable $this->event_name), an array of
841
         * parameters to pass through and an optional 'last in interation' boolean
842
         */
843
        protected function trigger($event, $data = FALSE, $last = TRUE) {
844
            if (isset($this->$event) && is_array($this->$event)) {
845
                foreach ($this->$event as $method) {
846
                    if (strpos($method, '(')) {
847
                        preg_match('/([a-zA-Z0-9\_\-]+)(\(([a-zA-Z0-9\_\-\., ]+)\))?/', $method, $matches);
848
                        $method = $matches[1];
849
                        $this->callback_parameters = explode(',', $matches[3]);
850
                    }
851
                    $data = call_user_func_array(array($this, $method), array($data, $last));
852
                }
853
            }
854
            return $data;
855
        }
856
857
        /**
858
         * Run validation on the passed data
859
         */
860
        protected function validate(array $data) {
861
            if ($this->skip_validation || empty($this->validate)) {
862
                return $data;
863
            }
864
            $fv = $this->formValidationInstance;
865
            if (!is_object($fv)) {
866
                Loader::library('FormValidation');
867
                $fv = $this->formvalidation;
0 ignored issues
show
Bug Best Practice introduced by
The property formvalidation does not exist on Model. Since you implemented __get, consider adding a @property annotation.
Loading history...
868
                $this->setFormValidation($fv);  
869
            }
870
            $fv->setData($data);
871
            $fv->setRules($this->validate);
872
873
            if ($fv->run()) {
874
                return $data;
875
            }
876
            return FALSE;
877
        }
878
		
879
		
880
        /**
881
         * Set WHERE parameters, when is array
882
         * @param array $params
883
         */
884
        protected function _set_where_array(array $params) {
885
            foreach ($params as $field => $filter) {
886
                if (is_array($filter)) {
887
                    $this->getQueryBuilder()->in($field, $filter);
888
                } else {
889
                    if (is_int($field)) {
890
                        $this->getQueryBuilder()->where($filter);
891
                    } else {
892
                        $this->getQueryBuilder()->where($field, $filter);
893
                    }
894
                }
895
            }
896
        }
897
898
899
        /**
900
         * Set WHERE parameters, cleverly
901
         */
902
        protected function _set_where($params) {
903
            if (count($params) == 1 && is_array($params[0])) {
904
                $this->_set_where_array($params[0]);
905
            } else if (count($params) == 1) {
906
                $this->getQueryBuilder()->where($params[0]);
907
            } else if (count($params) == 2) {
908
                if (is_array($params[1])) {
909
                    $this->getQueryBuilder()->in($params[0], $params[1]);
910
                } else {
911
                    $this->getQueryBuilder()->where($params[0], $params[1]);
912
                }
913
            } else if (count($params) == 3) {
914
                $this->getQueryBuilder()->where($params[0], $params[1], $params[2]);
915
            } else {
916
                if (is_array($params[1])) {
917
                    $this->getQueryBuilder()->in($params[0], $params[1]);
918
                } else {
919
                    $this->getQueryBuilder()->where($params[0], $params[1]);
920
                }
921
            }
922
        }
923
924
        /**
925
            Shortcut to controller
926
         */
927
        public function __get($key) {
928
            return get_instance()->{$key};
929
        }
930
931
    }
932