Passed
Push — 1.0.0-dev ( ead601...e21083 )
by nguereza
04:39
created

Model::__construct()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 18
rs 9.9666
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
        protected $_temporary_return_type = NULL;
116
    	
117
    	
118
    	/**
119
    		The database cache time 
120
    	*/
121
    	protected $dbCacheTime = 0;
122
123
        /**
124
         * Instance of the Loader class
125
         * @var Loader
126
         */
127
        protected $loaderInstance = null;
128
129
        /**
130
         * Instance of the FormValidation library
131
         * @var FormValidation
132
         */
133
        protected $formValidationInstance = null;
134
		
135
        /* --------------------------------------------------------------
136
         * GENERIC METHODS
137
         * ------------------------------------------------------------ */
138
139
        /**
140
         * Initialise the model, tie into the CodeIgniter superobject and
141
         * try our best to guess the table name.
142
         */
143
        public function __construct(Database $db = null){
144
            if (is_object($db)){
145
                $this->setDatabaseInstance($db);
146
            }
147
            else{
148
                $obj = & get_instance();
149
        		if (isset($obj->database) && is_object($obj->database)){
150
                    /**
151
                    * NOTE: Need use "clone" because some Model need have the personal instance of the database library
152
                    * to prevent duplication
153
                    */
154
        			$this->setDatabaseInstance(clone $obj->database);
155
                }
156
            }
157
158
            array_unshift($this->before_create, 'protect_attributes');
159
            array_unshift($this->before_update, 'protect_attributes');
160
            $this->_temporary_return_type = $this->return_type;
161
        }
162
163
        /* --------------------------------------------------------------
164
         * CRUD INTERFACE
165
         * ------------------------------------------------------------ */
166
167
        /**
168
         * Fetch a single record based on the primary key. Returns an object.
169
         */
170
        public function get($primary_value)
171
        {
172
    		return $this->get_by($this->primary_key, $primary_value);
173
        }
174
175
        /**
176
         * Fetch a single record based on an arbitrary WHERE call. Can be
177
         * any valid value to DatabaseQueryBuilder->where().
178
         */
179
        public function get_by()
180
        {
181
            $where = func_get_args();
182
183
            if ($this->soft_delete && $this->_temporary_with_deleted !== TRUE)
184
            {
185
                $this->getQueryBuilder()->where($this->soft_delete_key, (bool)$this->_temporary_only_deleted);
186
            }
187
    		$this->_set_where($where);
188
189
            $this->trigger('before_get');
190
			$type = $this->_temporary_return_type == 'array' ? 'array' : false;
0 ignored issues
show
introduced by
The condition $this->_temporary_return_type == 'array' is always false.
Loading history...
191
            $this->getQueryBuilder()->from($this->_table);
192
			$row = $this->_database->get($type);
193
            $this->_temporary_return_type = $this->return_type;
194
            $row = $this->trigger('after_get', $row);
195
            $this->_with = array();
196
            return $row;
197
        }
198
199
        /**
200
         * Fetch an array of records based on an array of primary values.
201
         */
202
        public function get_many($values)
203
        {
204
            $this->getQueryBuilder()->in($this->primary_key, $values);
205
            return $this->get_all();
206
        }
207
208
        /**
209
         * Fetch an array of records based on an arbitrary WHERE call.
210
         */
211
        public function get_many_by()
212
        {
213
            $where = func_get_args();
214
            $this->_set_where($where);
215
            return $this->get_all();
216
        }
217
218
        /**
219
         * Fetch all the records in the table. Can be used as a generic call
220
         * to $this->_database->get() with scoped methods.
221
         */
222
        public function get_all()
223
        {
224
            $this->trigger('before_get');
225
            if ($this->soft_delete && $this->_temporary_with_deleted !== TRUE)
226
            {
227
                $this->getQueryBuilder()->where($this->soft_delete_key, (bool)$this->_temporary_only_deleted);
228
            }
229
			$type = $this->_temporary_return_type == 'array' ? 'array':false;
0 ignored issues
show
introduced by
The condition $this->_temporary_return_type == 'array' is always false.
Loading history...
230
            $this->getQueryBuilder()->from($this->_table);
231
			$result = $this->_database->getAll($type);
232
            $this->_temporary_return_type = $this->return_type;
233
234
            foreach ($result as $key => &$row)
235
            {
236
                $row = $this->trigger('after_get', $row, ($key == count($result) - 1));
237
            }
238
            $this->_with = array();
239
            return $result;
240
        }
241
242
        /**
243
         * Insert a new row into the table. $data should be an associative array
244
         * of data to be inserted. Returns newly created ID.
245
		 * @see Database::insert
246
         */
247
        public function insert($data = array(), $skip_validation = FALSE, $escape = true)
248
        {
249
            if ($skip_validation === FALSE)
250
            {
251
                $data = $this->validate($data);
252
            }
253
254
            if ($data !== FALSE)
255
            {
256
                $data = $this->trigger('before_create', $data);
257
                $this->getQueryBuilder()->from($this->_table);
258
				$this->_database->insert($data, $escape);
259
                $insert_id = $this->_database->insertId();
260
                $this->trigger('after_create', $insert_id);
261
				//if the table doesn't have the auto increment field or sequence, the value of 0 will be returned 
262
				return ! $insert_id ? true : $insert_id;
263
            }
264
            else
265
            {
266
                return FALSE;
267
            }
268
        }
269
270
        /**
271
         * Insert multiple rows into the table. Returns an array of multiple IDs.
272
         */
273
        public function insert_many($data = array(), $skip_validation = FALSE, $escape = true)
274
        {
275
            $ids = array();
276
            foreach ($data as $key => $row)
277
            {
278
                $ids[] = $this->insert($row, $skip_validation, $escape);
279
            }
280
            return $ids;
281
        }
282
283
        /**
284
         * Updated a record based on the primary value.
285
         */
286
        public function update($primary_value, $data = array(), $skip_validation = FALSE, $escape = true)
287
        {
288
            $data = $this->trigger('before_update', $data);
289
            if ($skip_validation === FALSE)
290
            {
291
                $data = $this->validate($data);
292
            }
293
294
            if ($data !== FALSE)
295
            {
296
                $this->getQueryBuilder()->where($this->primary_key, $primary_value)
297
                                        ->from($this->_table);
298
                $result = $this->_database->update($data, $escape);
299
                $this->trigger('after_update', array($data, $result));
300
                return $result;
301
            }
302
            else
303
            {
304
                return FALSE;
305
            }
306
        }
307
308
        /**
309
         * Update many records, based on an array of primary values.
310
         */
311
        public function update_many($primary_values, $data = array(), $skip_validation = FALSE, $escape = true)
312
        {
313
            $data = $this->trigger('before_update', $data);
314
            if ($skip_validation === FALSE)
315
            {
316
                $data = $this->validate($data);
317
            }
318
            if ($data !== FALSE)
319
            {
320
                $this->getQueryBuilder()->in($this->primary_key, $primary_values)
321
                                        ->from($this->_table);
322
				$result = $this->_database->update($data, $escape);
323
                $this->trigger('after_update', array($data, $result));
324
                return $result;
325
            }
326
            else
327
            {
328
                return FALSE;
329
            }
330
        }
331
332
        /**
333
         * Updated a record based on an arbitrary WHERE clause.
334
         */
335
        public function update_by()
336
        {
337
            $args = func_get_args();
338
            $data = array();
339
            if (count($args) == 2){
340
                if (is_array($args[1])){
341
                    $data = array_pop($args);
342
                }
343
            }
344
            else if (count($args) == 3){
345
                if (is_array($args[2])){
346
                    $data = array_pop($args);
347
                }
348
            }
349
            $data = $this->trigger('before_update', $data);
350
            if ($this->validate($data) !== FALSE)
351
            {
352
                $this->_set_where($args);
353
                $this->getQueryBuilder()->from($this->_table);
354
				$result = $this->_database->update($data);
355
                $this->trigger('after_update', array($data, $result));
356
                return $result;
357
            }
358
            else
359
            {
360
                return FALSE;
361
            }
362
        }
363
364
        /**
365
         * Update all records
366
         */
367
        public function update_all($data = array(), $escape = true)
368
        {
369
            $data = $this->trigger('before_update', $data);
370
            $this->getQueryBuilder()->from($this->_table);
371
			$result = $this->_database->update($data, $escape);
372
            $this->trigger('after_update', array($data, $result));
373
            return $result;
374
        }
375
376
        /**
377
         * Delete a row from the table by the primary value
378
         */
379
        public function delete($id)
380
        {
381
            $this->trigger('before_delete', $id);
382
            $this->getQueryBuilder()->where($this->primary_key, $id);
383
			$result = false;
384
            if ($this->soft_delete)
385
            {
386
                $this->getQueryBuilder()->from($this->_table);	
387
				$result = $this->_database->update(array( $this->soft_delete_key => TRUE ));
388
            }
389
            else
390
            {
391
                $this->getQueryBuilder()->from($this->_table); 
392
				$result = $this->_database->delete();
393
            }
394
395
            $this->trigger('after_delete', $result);
396
            return $result;
397
        }
398
399
        /**
400
         * Delete a row from the database table by an arbitrary WHERE clause
401
         */
402
        public function delete_by()
403
        {
404
            $where = func_get_args();
405
    	    $where = $this->trigger('before_delete', $where);
406
            $this->_set_where($where);
407
			$result = false;
408
            if ($this->soft_delete)
409
            {
410
                $this->getQueryBuilder()->from($this->_table);	
411
				$result = $this->_database->update(array( $this->soft_delete_key => TRUE ));
412
            }
413
            else
414
            {
415
                $this->getQueryBuilder()->from($this->_table); 
416
				$result = $this->_database->delete();
417
            }
418
            $this->trigger('after_delete', $result);
419
            return $result;
420
        }
421
422
        /**
423
         * Delete many rows from the database table by multiple primary values
424
         */
425
        public function delete_many($primary_values)
426
        {
427
            $primary_values = $this->trigger('before_delete', $primary_values);
428
            $this->getQueryBuilder()->in($this->primary_key, $primary_values);
429
			$result = false;
430
            if ($this->soft_delete)
431
            {
432
                $this->getQueryBuilder()->from($this->_table);	
433
				$result = $this->_database->update(array( $this->soft_delete_key => TRUE ));
434
            }
435
            else
436
            {
437
                $this->getQueryBuilder()->from($this->_table); 
438
				$result = $this->_database->delete();
439
            }
440
            $this->trigger('after_delete', $result);
441
            return $result;
442
        }
443
444
445
        /**
446
         * Truncates the table
447
         */
448
        public function truncate()
449
        {
450
			$this->getQueryBuilder()->from($this->_table); 
451
			$result = $this->_database->delete();
452
            return $result;
453
        }
454
455
        /* --------------------------------------------------------------
456
         * RELATIONSHIPS
457
         * ------------------------------------------------------------ */
458
459
        public function with($relationship)
460
        {
461
            $this->_with[] = $relationship;
462
            if (!in_array('relate', $this->after_get))
463
            {
464
                $this->after_get[] = 'relate';
465
            }
466
            return $this;
467
        }
468
		
469
		/**
470
		* Relationship
471
		*/
472
        public function relate($row)
473
        {
474
    		if (empty($row))
475
            {
476
    		    return $row;
477
            }
478
479
            $row = $this->relateBelongsTo($row);
480
            $row = $this->relateHasMany($row);
481
            return $row;
482
        }
483
484
        /* --------------------------------------------------------------
485
         * UTILITY METHODS
486
         * ------------------------------------------------------------ */
487
488
        /**
489
         * Retrieve and generate a form_dropdown friendly array
490
         */
491
        public function dropdown()
492
        {
493
            $args = func_get_args();
494
            if (count($args) == 2)
495
            {
496
                list($key, $value) = $args;
497
            }
498
            else
499
            {
500
                $key = $this->primary_key;
501
                $value = $args[0];
502
            }
503
            $this->trigger('before_dropdown', array( $key, $value ));
504
            if ($this->soft_delete && $this->_temporary_with_deleted !== TRUE)
505
            {
506
                $this->getQueryBuilder()->where($this->soft_delete_key, FALSE);
507
            }
508
            $this->getQueryBuilder()
509
									 ->select(array($key, $value))
510
									 ->from($this->_table);
511
			$result = $this->_database->getAll();
512
            $options = array();
513
            foreach ($result as $row)
514
            {
515
                $options[$row->{$key}] = $row->{$value};
516
            }
517
            $options = $this->trigger('after_dropdown', $options);
518
            return $options;
519
        }
520
521
        /**
522
         * Fetch a count of rows based on an arbitrary WHERE call.
523
         */
524
        public function count_by()
525
        {
526
            if ($this->soft_delete && $this->_temporary_with_deleted !== TRUE)
527
            {
528
                $this->getQueryBuilder()->where($this->soft_delete_key, (bool)$this->_temporary_only_deleted);
529
            }
530
            $where = func_get_args();
531
            $this->_set_where($where);
532
            $this->getQueryBuilder()->from($this->_table);
533
			$this->_database->getAll();
534
            return $this->_database->numRows();
535
        }
536
537
        /**
538
         * Fetch a total count of rows, disregarding any previous conditions
539
         */
540
        public function count_all()
541
        {
542
            if ($this->soft_delete && $this->_temporary_with_deleted !== TRUE)
543
            {
544
                $this->getQueryBuilder()->where($this->soft_delete_key, (bool)$this->_temporary_only_deleted);
545
            }
546
			$this->getQueryBuilder()->from($this->_table);
547
			$this->_database->getAll();
548
            return $this->_database->numRows();
549
        }
550
		
551
		/**
552
		* Enabled cache temporary
553
		*/
554
		public function cached($ttl = 0){
555
		  if ($ttl > 0){
556
			$this->_database = $this->_database->cached($ttl);
557
		  }
558
		  return $this;
559
		}
560
561
        /**
562
         * Tell the class to skip the insert validation
563
         */
564
        public function skip_validation()
565
        {
566
            $this->skip_validation = TRUE;
567
            return $this;
568
        }
569
570
        /**
571
         * Get the skip validation status
572
         */
573
        public function get_skip_validation()
574
        {
575
            return $this->skip_validation;
576
        }
577
578
        /**
579
         * Return the next auto increment of the table. Only tested on MySQL.
580
         */
581
        public function get_next_id()
582
        {
583
			$this->getQueryBuilder()->select('AUTO_INCREMENT')
584
									->from('information_schema.TABLES')
585
									->where('TABLE_NAME', $this->_table)
586
									->where('TABLE_SCHEMA', $this->_database->getDatabaseName());
587
            return (int) $this->_database->get()->AUTO_INCREMENT;
588
        }
589
590
        /**
591
         * Getter for the table name
592
         */
593
        public function table()
594
        {
595
            return $this->_table;
596
        }
597
598
        /* --------------------------------------------------------------
599
         * GLOBAL SCOPES
600
         * ------------------------------------------------------------ */
601
602
        /**
603
         * Return the next call as an array rather than an object
604
         */
605
        public function as_array()
606
        {
607
            $this->_temporary_return_type = 'array';
608
            return $this;
609
        }
610
611
        /**
612
         * Return the next call as an object rather than an array
613
         */
614
        public function as_object()
615
        {
616
            $this->_temporary_return_type = 'object';
617
            return $this;
618
        }
619
620
        /**
621
         * Don't care about soft deleted rows on the next call
622
         */
623
        public function with_deleted()
624
        {
625
            $this->_temporary_with_deleted = TRUE;
626
            return $this;
627
        }
628
629
        /**
630
         * Only get deleted rows on the next call
631
         */
632
        public function only_deleted()
633
        {
634
            $this->_temporary_only_deleted = TRUE;
635
            return $this;
636
        }
637
638
        /* --------------------------------------------------------------
639
         * OBSERVERS
640
         * ------------------------------------------------------------ */
641
642
        /**
643
         * MySQL DATETIME created_at and updated_at
644
         */
645
        public function created_at($row)
646
        {
647
            if (is_object($row))
648
            {
649
                $row->created_at = date('Y-m-d H:i:s');
650
            }
651
            else
652
            {
653
                $row['created_at'] = date('Y-m-d H:i:s');
654
            }
655
            return $row;
656
        }
657
658
        public function updated_at($row)
659
        {
660
            if (is_object($row))
661
            {
662
                $row->updated_at = date('Y-m-d H:i:s');
663
            }
664
            else
665
            {
666
                $row['updated_at'] = date('Y-m-d H:i:s');
667
            }
668
            return $row;
669
        }
670
671
        /**
672
         * Serialises data for you automatically, allowing you to pass
673
         * through objects and let it handle the serialisation in the background
674
         */
675
        public function serialize($row)
676
        {
677
            foreach ($this->callback_parameters as $column)
678
            {
679
                $row[$column] = serialize($row[$column]);
680
            }
681
            return $row;
682
        }
683
684
        public function unserialize($row)
685
        {
686
            foreach ($this->callback_parameters as $column)
687
            {
688
                if (is_array($row))
689
                {
690
                    $row[$column] = unserialize($row[$column]);
691
                }
692
                else
693
                {
694
                    $row->$column = unserialize($row->$column);
695
                }
696
            }
697
            return $row;
698
        }
699
700
        /**
701
         * Protect attributes by removing them from $row array
702
         */
703
        public function protect_attributes($row)
704
        {
705
            foreach ($this->protected_attributes as $attr)
706
            {
707
                if (is_object($row))
708
                {
709
					if (isset($row->$attr)){
710
						unset($row->$attr);
711
					}
712
                }
713
                else
714
                {
715
					if (isset($row[$attr])){
716
						unset($row[$attr]);
717
					}
718
                }
719
            }
720
            return $row;
721
        }
722
		
723
		 /**
724
         * Return the database instance
725
         * @return Database the database instance
726
         */
727
        public function getDatabaseInstance(){
728
            return $this->_database;
729
        }
730
731
        /**
732
         * set the Database instance for future use
733
         * @param Database $db the database object
734
         */
735
         public function setDatabaseInstance($db){
736
            $this->_database = $db;
737
            if ($this->dbCacheTime > 0){
738
                $this->_database->setCache($this->dbCacheTime);
739
            }
740
            return $this;
741
        }
742
743
        /**
744
         * Return the loader instance
745
         * @return Loader the loader instance
746
         */
747
        public function getLoader(){
748
            return $this->loaderInstance;
749
        }
750
751
        /**
752
         * Set the loader instance for future use
753
         * @param Loader $loader the loader object
754
		 * @return object
755
         */
756
         public function setLoader($loader){
757
            $this->loaderInstance = $loader;
758
            return $this;
759
        }
760
761
		/**
762
         * Return the queryBuilder instance this is the shortcut to database queryBuilder
763
         * @return object the DatabaseQueryBuilder instance
764
         */
765
        public function getQueryBuilder(){
766
            return $this->_database->getQueryBuilder();
767
        }
768
769
        /**
770
         * Set the DatabaseQueryBuilder instance for future use
771
         * @param object $queryBuilder the DatabaseQueryBuilder object
772
		 * @return object
773
         */
774
         public function setQueryBuilder($queryBuilder){
775
            $this->_database->setQueryBuilder($queryBuilder);
776
            return $this;
777
        }
778
779
		
780
        /**
781
         * Return the FormValidation instance
782
         * @return FormValidation the form validation instance
783
         */
784
        public function getFormValidation(){
785
            return $this->formValidationInstance;
786
        }
787
788
        /**
789
         * Set the form validation instance for future use
790
         * @param FormValidation $fv the form validation object
791
		 * @return object
792
         */
793
         public function setFormValidation($fv){
794
            $this->formValidationInstance = $fv;
795
            return $this;
796
        }
797
798
        /* --------------------------------------------------------------
799
         * QUERY BUILDER DIRECT ACCESS METHODS
800
         * ------------------------------------------------------------ */
801
802
        /**
803
         * A wrapper to $this->getQueryBuilder()->orderBy()
804
         */
805
        public function order_by($criteria, $order = 'ASC')
806
        {
807
            if ( is_array($criteria) )
808
            {
809
                foreach ($criteria as $key => $value)
810
                {
811
                    $this->getQueryBuilder()->orderBy($key, $value);
812
                }
813
            }
814
            else
815
            {
816
                $this->getQueryBuilder()->orderBy($criteria, $order);
817
            }
818
            return $this;
819
        }
820
821
        /**
822
         * A wrapper to $this->getQueryBuilder()->limit()
823
         */
824
        public function limit($offset = 0, $limit = 10)
825
        {
826
            $this->getQueryBuilder()->limit($offset, $limit);
827
            return $this;
828
        }
829
830
        /* --------------------------------------------------------------
831
         * INTERNAL METHODS
832
         * ------------------------------------------------------------ */
833
834
		/**
835
		* relate for the relation "belongs_to"
836
		* @return mixed
837
		*/
838
		protected function relateBelongsTo($row){
839
			foreach ($this->belongs_to as $key => $value)
840
            {
841
                if (is_string($value))
842
                {
843
                    $relationship = $value;
844
                    $options = array( 'primary_key' => $value . '_id', 'model' => $value . '_model' );
845
                }
846
                else
847
                {
848
                    $relationship = $key;
849
                    $options = $value;
850
                }
851
852
                if (in_array($relationship, $this->_with))
853
                {
854
                    if (is_object($this->loaderInstance)){
855
                        $this->loaderInstance->model($options['model'], $relationship . '_model');
856
                    }
857
                    else{
858
                        Loader::model($options['model'], $relationship . '_model');    
859
                    }
860
                    if (is_object($row))
861
                    {
862
                        $row->{$relationship} = $this->{$relationship . '_model'}->get($row->{$options['primary_key']});
863
                    }
864
                    else
865
                    {
866
                        $row[$relationship] = $this->{$relationship . '_model'}->get($row[$options['primary_key']]);
867
                    }
868
                }
869
            }
870
			return $row;
871
		}
872
873
		/**
874
		* relate for the relation "has_many"
875
		* @return mixed
876
		*/
877
		protected function relateHasMany($row){
878
			foreach ($this->has_many as $key => $value)
879
            {
880
                if (is_string($value))
881
                {
882
                    $relationship = $value;
883
                    $options = array( 'primary_key' => $this->_table . '_id', 'model' => $value . '_model' );
884
                }
885
                else
886
                {
887
                    $relationship = $key;
888
                    $options = $value;
889
                }
890
891
                if (in_array($relationship, $this->_with))
892
                {
893
                    if (is_object($this->loaderInstance)){
894
                        $this->loaderInstance->model($options['model'], $relationship . '_model');
895
                    }
896
                    else{
897
                        Loader::model($options['model'], $relationship . '_model');    
898
                    }
899
                    if (is_object($row))
900
                    {
901
                        $row->{$relationship} = $this->{$relationship . '_model'}->get_many_by($options['primary_key'], $row->{$this->primary_key});
902
                    }
903
                    else
904
                    {
905
                        $row[$relationship] = $this->{$relationship . '_model'}->get_many_by($options['primary_key'], $row[$this->primary_key]);
906
                    }
907
                }
908
            }
909
			return $row;
910
		}
911
		
912
        /**
913
         * Trigger an event and call its observers. Pass through the event name
914
         * (which looks for an instance variable $this->event_name), an array of
915
         * parameters to pass through and an optional 'last in interation' boolean
916
         */
917
        protected function trigger($event, $data = FALSE, $last = TRUE)
918
        {
919
            if (isset($this->$event) && is_array($this->$event))
920
            {
921
                foreach ($this->$event as $method)
922
                {
923
                    if (strpos($method, '('))
924
                    {
925
                        preg_match('/([a-zA-Z0-9\_\-]+)(\(([a-zA-Z0-9\_\-\., ]+)\))?/', $method, $matches);
926
                        $method = $matches[1];
927
                        $this->callback_parameters = explode(',', $matches[3]);
928
                    }
929
                    $data = call_user_func_array(array($this, $method), array($data, $last));
930
                }
931
            }
932
            return $data;
933
        }
934
935
        /**
936
         * Run validation on the passed data
937
         */
938
        protected function validate(array $data)
939
        {
940
            if ($this->skip_validation)
941
            {
942
                return $data;
943
            }
944
            if (!empty($this->validate))
945
            {
946
                $fv = null;
947
                if (is_object($this->formValidationInstance)){
948
                    $fv = $this->formValidationInstance;
949
                }
950
                else{
951
                    Loader::library('FormValidation');
952
                    $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...
953
                    $this->setFormValidation($fv);
954
                }
955
               
956
                $fv->setData($data);
957
                $fv->setRules($this->validate);
958
959
                if ($fv->run())
960
                {
961
                    return $data;
962
                }
963
                else
964
                {
965
                    return FALSE;
966
                }
967
            }
968
            else
969
            {
970
                return $data;
971
            }
972
        }
973
		
974
		
975
		/**
976
		* Set WHERE parameters, when is array
977
		* @param array $params
978
		*/
979
		protected function _set_where_array(array $params){
980
			foreach ($params as $field => $filter)
981
			{
982
				if (is_array($filter))
983
				{
984
					$this->getQueryBuilder()->in($field, $filter);
985
				}
986
				else
987
				{
988
					if (is_int($field))
989
					{
990
						$this->getQueryBuilder()->where($filter);
991
					}
992
					else
993
					{
994
						$this->getQueryBuilder()->where($field, $filter);
995
					}
996
				}
997
			}
998
		}
999
1000
1001
        /**
1002
         * Set WHERE parameters, cleverly
1003
         */
1004
        protected function _set_where($params)
1005
        {
1006
            if (count($params) == 1 && is_array($params[0]))
1007
            {
1008
                $this->_set_where_array($params[0]);
1009
            }
1010
            else if (count($params) == 1)
1011
            {
1012
                $this->getQueryBuilder()->where($params[0]);
1013
            }
1014
        	else if (count($params) == 2)
1015
    		{
1016
                if (is_array($params[1]))
1017
                {
1018
                    $this->getQueryBuilder()->in($params[0], $params[1]);
1019
                }
1020
                else
1021
                {
1022
                    $this->getQueryBuilder()->where($params[0], $params[1]);
1023
                }
1024
    		}
1025
    		else if (count($params) == 3)
1026
    		{
1027
    			$this->getQueryBuilder()->where($params[0], $params[1], $params[2]);
1028
    		}
1029
            else
1030
            {
1031
                if (is_array($params[1]))
1032
                {
1033
                    $this->getQueryBuilder()->in($params[0], $params[1]);
1034
                }
1035
                else
1036
                {
1037
                    $this->getQueryBuilder()->where($params[0], $params[1]);
1038
                }
1039
            }
1040
        }
1041
1042
        /**
1043
            Shortcut to controller
1044
        */
1045
        public function __get($key){
1046
            return get_instance()->{$key};
1047
        }
1048
1049
    }
1050