Take two:
[www-register-wizard.git] / database / DB_active_rec.php
1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
2 /**\r
3  * CodeIgniter\r
4  *\r
5  * An open source application development framework for PHP 4.3.2 or newer\r
6  *\r
7  * @package             CodeIgniter\r
8  * @author              ExpressionEngine Dev Team\r
9  * @copyright   Copyright (c) 2008, EllisLab, Inc.\r
10  * @license             http://codeigniter.com/user_guide/license.html\r
11  * @link                http://codeigniter.com\r
12  * @since               Version 1.0\r
13  * @filesource\r
14  */\r
15 \r
16 // ------------------------------------------------------------------------\r
17 \r
18 /**\r
19  * Active Record Class\r
20  *\r
21  * This is the platform-independent base Active Record implementation class.\r
22  *\r
23  * @package             CodeIgniter\r
24  * @subpackage  Drivers\r
25  * @category    Database\r
26  * @author              ExpressionEngine Dev Team\r
27  * @link                http://codeigniter.com/user_guide/database/\r
28  */\r
29 class CI_DB_active_record extends CI_DB_driver {\r
30 \r
31         var $ar_select                          = array();\r
32         var $ar_distinct                        = FALSE;\r
33         var $ar_from                            = array();\r
34         var $ar_join                            = array();\r
35         var $ar_where                           = array();\r
36         var $ar_like                            = array();\r
37         var $ar_groupby                         = array();\r
38         var $ar_having                          = array();\r
39         var $ar_limit                           = FALSE;\r
40         var $ar_offset                          = FALSE;\r
41         var $ar_order                           = FALSE;\r
42         var $ar_orderby                         = array();\r
43         var $ar_set                                     = array();      \r
44         var $ar_wherein                         = array();\r
45         var $ar_aliased_tables          = array();\r
46         var $ar_store_array                     = array();\r
47         \r
48         // Active Record Caching variables\r
49         var $ar_caching                         = FALSE;\r
50         var $ar_cache_exists            = array();\r
51         var $ar_cache_select            = array();\r
52         var $ar_cache_from                      = array();\r
53         var $ar_cache_join                      = array();\r
54         var $ar_cache_where                     = array();\r
55         var $ar_cache_like                      = array();\r
56         var $ar_cache_groupby           = array();\r
57         var $ar_cache_having            = array();\r
58         var $ar_cache_orderby           = array();\r
59         var $ar_cache_set                       = array();      \r
60 \r
61 \r
62         // --------------------------------------------------------------------\r
63 \r
64         /**\r
65          * Select\r
66          *\r
67          * Generates the SELECT portion of the query\r
68          *\r
69          * @access      public\r
70          * @param       string\r
71          * @return      object\r
72          */\r
73         function select($select = '*', $escape = NULL)\r
74         {\r
75                 // Set the global value if this was sepecified  \r
76                 if (is_bool($escape))\r
77                 {\r
78                         $this->_protect_identifiers = $escape;\r
79                 }\r
80                 \r
81                 if (is_string($select))\r
82                 {\r
83                         $select = explode(',', $select);\r
84                 }\r
85 \r
86                 foreach ($select as $val)\r
87                 {\r
88                         $val = trim($val);\r
89 \r
90                         if ($val != '')\r
91                         {\r
92                                 $this->ar_select[] = $val;\r
93 \r
94                                 if ($this->ar_caching === TRUE)\r
95                                 {\r
96                                         $this->ar_cache_select[] = $val;\r
97                                         $this->ar_cache_exists[] = 'select';\r
98                                 }\r
99                         }\r
100                 }\r
101                 return $this;\r
102         }\r
103 \r
104         // --------------------------------------------------------------------\r
105 \r
106         /**\r
107          * Select Max\r
108          *\r
109          * Generates a SELECT MAX(field) portion of a query\r
110          *\r
111          * @access      public\r
112          * @param       string  the field\r
113          * @param       string  an alias\r
114          * @return      object\r
115          */\r
116         function select_max($select = '', $alias = '')\r
117         {\r
118                 return $this->_max_min_avg_sum($select, $alias, 'MAX');\r
119         }\r
120                 \r
121         // --------------------------------------------------------------------\r
122 \r
123         /**\r
124          * Select Min\r
125          *\r
126          * Generates a SELECT MIN(field) portion of a query\r
127          *\r
128          * @access      public\r
129          * @param       string  the field\r
130          * @param       string  an alias\r
131          * @return      object\r
132          */\r
133         function select_min($select = '', $alias = '')\r
134         {\r
135                 return $this->_max_min_avg_sum($select, $alias, 'MIN');\r
136         }\r
137 \r
138         // --------------------------------------------------------------------\r
139 \r
140         /**\r
141          * Select Average\r
142          *\r
143          * Generates a SELECT AVG(field) portion of a query\r
144          *\r
145          * @access      public\r
146          * @param       string  the field\r
147          * @param       string  an alias\r
148          * @return      object\r
149          */\r
150         function select_avg($select = '', $alias = '')\r
151         {\r
152                 return $this->_max_min_avg_sum($select, $alias, 'AVG');\r
153         }\r
154 \r
155         // --------------------------------------------------------------------\r
156 \r
157         /**\r
158          * Select Sum\r
159          *\r
160          * Generates a SELECT SUM(field) portion of a query\r
161          *\r
162          * @access      public\r
163          * @param       string  the field\r
164          * @param       string  an alias\r
165          * @return      object\r
166          */\r
167         function select_sum($select = '', $alias = '')\r
168         {\r
169                 return $this->_max_min_avg_sum($select, $alias, 'SUM');\r
170         }\r
171 \r
172         // --------------------------------------------------------------------\r
173 \r
174         /**\r
175          * Processing Function for the four functions above:\r
176          *\r
177          *      select_max()\r
178          *      select_min()\r
179          *      select_avg()\r
180          *  select_sum()\r
181          *      \r
182          * @access      public\r
183          * @param       string  the field\r
184          * @param       string  an alias\r
185          * @return      object\r
186          */\r
187         function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX')\r
188         {\r
189                 if ( ! is_string($select) OR $select == '')\r
190                 {\r
191                         $this->display_error('db_invalid_query');\r
192                 }\r
193         \r
194                 $type = strtoupper($type);\r
195         \r
196                 if ( ! in_array($type, array('MAX', 'MIN', 'AVG', 'SUM')))\r
197                 {\r
198                         show_error('Invalid function type: '.$type);\r
199                 }\r
200         \r
201                 if ($alias == '')\r
202                 {\r
203                         $alias = $this->_create_alias_from_table(trim($select));\r
204                 }\r
205         \r
206                 $sql = $type.'('.$this->_protect_identifiers(trim($select)).') AS '.$alias;\r
207 \r
208                 $this->ar_select[] = $sql;\r
209                 \r
210                 if ($this->ar_caching === TRUE)\r
211                 {\r
212                         $this->ar_cache_select[] = $sql;\r
213                         $this->ar_cache_exists[] = 'select';\r
214                 }\r
215                 \r
216                 return $this;\r
217         }\r
218 \r
219         // --------------------------------------------------------------------\r
220 \r
221         /**\r
222          * Determines the alias name based on the table\r
223          *\r
224          * @access      private\r
225          * @param       string\r
226          * @return      string\r
227          */\r
228         function _create_alias_from_table($item)\r
229         {\r
230                 if (strpos($item, '.') !== FALSE)\r
231                 {\r
232                         return end(explode('.', $item));\r
233                 }\r
234                 \r
235                 return $item;\r
236         }\r
237 \r
238         // --------------------------------------------------------------------\r
239 \r
240         /**\r
241          * DISTINCT\r
242          *\r
243          * Sets a flag which tells the query string compiler to add DISTINCT\r
244          *\r
245          * @access      public\r
246          * @param       bool\r
247          * @return      object\r
248          */\r
249         function distinct($val = TRUE)\r
250         {\r
251                 $this->ar_distinct = (is_bool($val)) ? $val : TRUE;\r
252                 return $this;\r
253         }\r
254         \r
255         // --------------------------------------------------------------------\r
256 \r
257         /**\r
258          * From\r
259          *\r
260          * Generates the FROM portion of the query\r
261          *\r
262          * @access      public\r
263          * @param       mixed   can be a string or array\r
264          * @return      object\r
265          */\r
266         function from($from)\r
267         {\r
268                 foreach ((array)$from as $val)\r
269                 {\r
270                         // Extract any aliases that might exist.  We use this information\r
271                         // in the _protect_identifiers to know whether to add a table prefix \r
272                         $this->_track_aliases($val);\r
273 \r
274                         $this->ar_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);\r
275                         \r
276                         if ($this->ar_caching === TRUE)\r
277                         {\r
278                                 $this->ar_cache_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);\r
279                                 $this->ar_cache_exists[] = 'from';\r
280                         }\r
281                 }\r
282 \r
283                 return $this;\r
284         }\r
285 \r
286         // --------------------------------------------------------------------\r
287 \r
288         /**\r
289          * Join\r
290          *\r
291          * Generates the JOIN portion of the query\r
292          *\r
293          * @access      public\r
294          * @param       string\r
295          * @param       string  the join condition\r
296          * @param       string  the type of join\r
297          * @return      object\r
298          */\r
299         function join($table, $cond, $type = '')\r
300         {               \r
301                 if ($type != '')\r
302                 {\r
303                         $type = strtoupper(trim($type));\r
304 \r
305                         if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER')))\r
306                         {\r
307                                 $type = '';\r
308                         }\r
309                         else\r
310                         {\r
311                                 $type .= ' ';\r
312                         }\r
313                 }\r
314 \r
315                 // Extract any aliases that might exist.  We use this information\r
316                 // in the _protect_identifiers to know whether to add a table prefix \r
317                 $this->_track_aliases($table);\r
318 \r
319                 // Strip apart the condition and protect the identifiers\r
320                 if (preg_match('/([\w\.]+)([\W\s]+)(.+)/', $cond, $match))\r
321                 {\r
322                         $match[1] = $this->_protect_identifiers($match[1]);\r
323                         $match[3] = $this->_protect_identifiers($match[3]);\r
324                 \r
325                         $cond = $match[1].$match[2].$match[3];          \r
326                 }\r
327                 \r
328                 // Assemble the JOIN statement\r
329                 $join = $type.'JOIN '.$this->_protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;\r
330 \r
331                 $this->ar_join[] = $join;\r
332                 if ($this->ar_caching === TRUE)\r
333                 {\r
334                         $this->ar_cache_join[] = $join;\r
335                         $this->ar_cache_exists[] = 'join';\r
336                 }\r
337 \r
338                 return $this;\r
339         }\r
340 \r
341         // --------------------------------------------------------------------\r
342 \r
343         /**\r
344          * Where\r
345          *\r
346          * Generates the WHERE portion of the query. Separates\r
347          * multiple calls with AND\r
348          *\r
349          * @access      public\r
350          * @param       mixed\r
351          * @param       mixed\r
352          * @return      object\r
353          */\r
354         function where($key, $value = NULL, $escape = TRUE)\r
355         {\r
356                 return $this->_where($key, $value, 'AND ', $escape);\r
357         }\r
358         \r
359         // --------------------------------------------------------------------\r
360 \r
361         /**\r
362          * OR Where\r
363          *\r
364          * Generates the WHERE portion of the query. Separates\r
365          * multiple calls with OR\r
366          *\r
367          * @access      public\r
368          * @param       mixed\r
369          * @param       mixed\r
370          * @return      object\r
371          */\r
372         function or_where($key, $value = NULL, $escape = TRUE)\r
373         {\r
374                 return $this->_where($key, $value, 'OR ', $escape);\r
375         }\r
376 \r
377         // --------------------------------------------------------------------\r
378 \r
379         /**\r
380          * orwhere() is an alias of or_where()\r
381          * this function is here for backwards compatibility, as\r
382          * orwhere() has been deprecated\r
383          */\r
384         function orwhere($key, $value = NULL, $escape = TRUE)\r
385         {\r
386                 return $this->or_where($key, $value, $escape);\r
387         }\r
388 \r
389         // --------------------------------------------------------------------\r
390 \r
391         /**\r
392          * Where\r
393          *\r
394          * Called by where() or orwhere()\r
395          *\r
396          * @access      private\r
397          * @param       mixed\r
398          * @param       mixed\r
399          * @param       string\r
400          * @return      object\r
401          */\r
402         function _where($key, $value = NULL, $type = 'AND ', $escape = NULL)\r
403         {\r
404                 if ( ! is_array($key))\r
405                 {\r
406                         $key = array($key => $value);\r
407                 }\r
408                 \r
409                 // If the escape value was not set will will base it on the global setting\r
410                 if ( ! is_bool($escape))\r
411                 {\r
412                         $escape = $this->_protect_identifiers;\r
413                 }\r
414 \r
415                 foreach ($key as $k => $v)\r
416                 {\r
417                         $prefix = (count($this->ar_where) == 0 AND count($this->ar_cache_where) == 0) ? '' : $type;\r
418 \r
419                         if (is_null($v) && ! $this->_has_operator($k))\r
420                         {\r
421                                 // value appears not to have been set, assign the test to IS NULL\r
422                                 $k .= ' IS NULL';\r
423                         }\r
424                         \r
425                         if ( ! is_null($v))\r
426                         {\r
427                                 if ($escape === TRUE)\r
428                                 {\r
429                                         $k = $this->_protect_identifiers($k, FALSE, $escape);\r
430                                         \r
431                                         $v = ' '.$this->escape($v);\r
432                                 }\r
433 \r
434                                 if ( ! $this->_has_operator($k))\r
435                                 {\r
436                                         $k .= ' =';\r
437                                 }\r
438                         }\r
439                         else\r
440                         {\r
441                                 $k = $this->_protect_identifiers($k, FALSE, $escape);                   \r
442                         }\r
443 \r
444                         $this->ar_where[] = $prefix.$k.$v;\r
445                         \r
446                         if ($this->ar_caching === TRUE)\r
447                         {\r
448                                 $this->ar_cache_where[] = $prefix.$k.$v;\r
449                                 $this->ar_cache_exists[] = 'where';\r
450                         }\r
451                         \r
452                 }\r
453                 \r
454                 return $this;\r
455         }\r
456 \r
457         // --------------------------------------------------------------------\r
458 \r
459         /**\r
460          * Where_in\r
461          *\r
462          * Generates a WHERE field IN ('item', 'item') SQL query joined with\r
463          * AND if appropriate\r
464          *\r
465          * @access      public\r
466          * @param       string  The field to search\r
467          * @param       array   The values searched on\r
468          * @return      object\r
469          */\r
470         function where_in($key = NULL, $values = NULL)\r
471         {\r
472                 return $this->_where_in($key, $values);\r
473         }\r
474         \r
475         // --------------------------------------------------------------------\r
476 \r
477         /**\r
478          * Where_in_or\r
479          *\r
480          * Generates a WHERE field IN ('item', 'item') SQL query joined with\r
481          * OR if appropriate\r
482          *\r
483          * @access      public\r
484          * @param       string  The field to search\r
485          * @param       array   The values searched on\r
486          * @return      object\r
487          */\r
488         function or_where_in($key = NULL, $values = NULL)\r
489         {\r
490                 return $this->_where_in($key, $values, FALSE, 'OR ');\r
491         }\r
492 \r
493         // --------------------------------------------------------------------\r
494 \r
495         /**\r
496          * Where_not_in\r
497          *\r
498          * Generates a WHERE field NOT IN ('item', 'item') SQL query joined\r
499          * with AND if appropriate\r
500          *\r
501          * @access      public\r
502          * @param       string  The field to search\r
503          * @param       array   The values searched on\r
504          * @return      object\r
505          */\r
506         function where_not_in($key = NULL, $values = NULL)\r
507         {\r
508                 return $this->_where_in($key, $values, TRUE);\r
509         }\r
510         \r
511         // --------------------------------------------------------------------\r
512 \r
513         /**\r
514          * Where_not_in_or\r
515          *\r
516          * Generates a WHERE field NOT IN ('item', 'item') SQL query joined\r
517          * with OR if appropriate\r
518          *\r
519          * @access      public\r
520          * @param       string  The field to search\r
521          * @param       array   The values searched on\r
522          * @return      object\r
523          */\r
524         function or_where_not_in($key = NULL, $values = NULL)\r
525         {\r
526                 return $this->_where_in($key, $values, TRUE, 'OR ');\r
527         }\r
528 \r
529         // --------------------------------------------------------------------\r
530 \r
531         /**\r
532          * Where_in\r
533          *\r
534          * Called by where_in, where_in_or, where_not_in, where_not_in_or\r
535          *\r
536          * @access      public\r
537          * @param       string  The field to search\r
538          * @param       array   The values searched on\r
539          * @param       boolean If the statement would be IN or NOT IN\r
540          * @param       string  \r
541          * @return      object\r
542          */\r
543         function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ')\r
544         {\r
545                 if ($key === NULL OR $values === NULL)\r
546                 {\r
547                         return;\r
548                 }\r
549                 \r
550                 if ( ! is_array($values))\r
551                 {\r
552                         $values = array($values);\r
553                 }\r
554                 \r
555                 $not = ($not) ? ' NOT' : '';\r
556 \r
557                 foreach ($values as $value)\r
558                 {\r
559                         $this->ar_wherein[] = $this->escape($value);\r
560                 }\r
561 \r
562                 $prefix = (count($this->ar_where) == 0) ? '' : $type;\r
563  \r
564                 $where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") ";\r
565 \r
566                 $this->ar_where[] = $where_in;\r
567                 if ($this->ar_caching === TRUE)\r
568                 {\r
569                         $this->ar_cache_where[] = $where_in;\r
570                         $this->ar_cache_exists[] = 'where';\r
571                 }\r
572 \r
573                 // reset the array for multiple calls\r
574                 $this->ar_wherein = array();\r
575                 return $this;\r
576         }\r
577                 \r
578         // --------------------------------------------------------------------\r
579 \r
580         /**\r
581          * Like\r
582          *\r
583          * Generates a %LIKE% portion of the query. Separates\r
584          * multiple calls with AND\r
585          *\r
586          * @access      public\r
587          * @param       mixed\r
588          * @param       mixed\r
589          * @return      object\r
590          */\r
591         function like($field, $match = '', $side = 'both')\r
592         {\r
593                 return $this->_like($field, $match, 'AND ', $side);\r
594         }\r
595 \r
596         // --------------------------------------------------------------------\r
597 \r
598         /**\r
599          * Not Like\r
600          *\r
601          * Generates a NOT LIKE portion of the query. Separates\r
602          * multiple calls with AND\r
603          *\r
604          * @access      public\r
605          * @param       mixed\r
606          * @param       mixed\r
607          * @return      object\r
608          */\r
609         function not_like($field, $match = '', $side = 'both')\r
610         {\r
611                 return $this->_like($field, $match, 'AND ', $side, 'NOT');\r
612         }\r
613                 \r
614         // --------------------------------------------------------------------\r
615 \r
616         /**\r
617          * OR Like\r
618          *\r
619          * Generates a %LIKE% portion of the query. Separates\r
620          * multiple calls with OR\r
621          *\r
622          * @access      public\r
623          * @param       mixed\r
624          * @param       mixed\r
625          * @return      object\r
626          */\r
627         function or_like($field, $match = '', $side = 'both')\r
628         {\r
629                 return $this->_like($field, $match, 'OR ', $side);\r
630         }\r
631 \r
632         // --------------------------------------------------------------------\r
633 \r
634         /**\r
635          * OR Not Like\r
636          *\r
637          * Generates a NOT LIKE portion of the query. Separates\r
638          * multiple calls with OR\r
639          *\r
640          * @access      public\r
641          * @param       mixed\r
642          * @param       mixed\r
643          * @return      object\r
644          */\r
645         function or_not_like($field, $match = '', $side = 'both')\r
646         {\r
647                 return $this->_like($field, $match, 'OR ', $side, 'NOT');\r
648         }\r
649         \r
650         // --------------------------------------------------------------------\r
651 \r
652         /**\r
653          * orlike() is an alias of or_like()\r
654          * this function is here for backwards compatibility, as\r
655          * orlike() has been deprecated\r
656          */\r
657         function orlike($field, $match = '', $side = 'both')\r
658         {\r
659                 return $this->or_like($field, $match, $side);\r
660         }\r
661         \r
662         // --------------------------------------------------------------------\r
663 \r
664         /**\r
665          * Like\r
666          *\r
667          * Called by like() or orlike()\r
668          *\r
669          * @access      private\r
670          * @param       mixed\r
671          * @param       mixed\r
672          * @param       string\r
673          * @return      object\r
674          */\r
675         function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '')\r
676         {\r
677                 if ( ! is_array($field))\r
678                 {\r
679                         $field = array($field => $match);\r
680                 }\r
681         \r
682                 foreach ($field as $k => $v)\r
683                 {\r
684                         $k = $this->_protect_identifiers($k);\r
685 \r
686                         $prefix = (count($this->ar_like) == 0) ? '' : $type;\r
687 \r
688                         $v = $this->escape_str($v);\r
689 \r
690                         if ($side == 'before')\r
691                         {\r
692                                 $like_statement = $prefix." $k $not LIKE '%{$v}'";\r
693                         }\r
694                         elseif ($side == 'after')\r
695                         {\r
696                                 $like_statement = $prefix." $k $not LIKE '{$v}%'";\r
697                         }\r
698                         else\r
699                         {\r
700                                 $like_statement = $prefix." $k $not LIKE '%{$v}%'";\r
701                         }\r
702                         \r
703                         $this->ar_like[] = $like_statement;\r
704                         if ($this->ar_caching === TRUE)\r
705                         {\r
706                                 $this->ar_cache_like[] = $like_statement;\r
707                                 $this->ar_cache_exists[] = 'like';\r
708                         }\r
709                         \r
710                 }\r
711                 return $this;\r
712         }\r
713         \r
714         // --------------------------------------------------------------------\r
715 \r
716         /**\r
717          * GROUP BY\r
718          *\r
719          * @access      public\r
720          * @param       string\r
721          * @return      object\r
722          */\r
723         function group_by($by)\r
724         {\r
725                 if (is_string($by))\r
726                 {\r
727                         $by = explode(',', $by);\r
728                 }\r
729         \r
730                 foreach ($by as $val)\r
731                 {\r
732                         $val = trim($val);\r
733                 \r
734                         if ($val != '')\r
735                         {\r
736                                 $this->ar_groupby[] = $this->_protect_identifiers($val);\r
737                                 \r
738                                 if ($this->ar_caching === TRUE)\r
739                                 {\r
740                                         $this->ar_cache_groupby[] = $this->_protect_identifiers($val);\r
741                                         $this->ar_cache_exists[] = 'groupby';\r
742                                 }\r
743                         }\r
744                 }\r
745                 return $this;\r
746         }\r
747 \r
748         // --------------------------------------------------------------------\r
749 \r
750         /**\r
751          * groupby() is an alias of group_by()\r
752          * this function is here for backwards compatibility, as\r
753          * groupby() has been deprecated\r
754          */\r
755         function groupby($by)\r
756         {\r
757                 return $this->group_by($by);\r
758         }       \r
759 \r
760         // --------------------------------------------------------------------\r
761 \r
762         /**\r
763          * Sets the HAVING value\r
764          *\r
765          * Separates multiple calls with AND\r
766          *\r
767          * @access      public\r
768          * @param       string\r
769          * @param       string\r
770          * @return      object\r
771          */\r
772         function having($key, $value = '', $escape = TRUE)\r
773         {\r
774                 return $this->_having($key, $value, 'AND ', $escape);\r
775         }\r
776 \r
777         // --------------------------------------------------------------------\r
778 \r
779         /**\r
780          * orhaving() is an alias of or_having()\r
781          * this function is here for backwards compatibility, as\r
782          * orhaving() has been deprecated\r
783          */\r
784 \r
785         function orhaving($key, $value = '', $escape = TRUE)\r
786         {\r
787                 return $this->or_having($key, $value, $escape);\r
788         }       \r
789         // --------------------------------------------------------------------\r
790 \r
791         /**\r
792          * Sets the OR HAVING value\r
793          *\r
794          * Separates multiple calls with OR\r
795          *\r
796          * @access      public\r
797          * @param       string\r
798          * @param       string\r
799          * @return      object\r
800          */\r
801         function or_having($key, $value = '', $escape = TRUE)\r
802         {\r
803                 return $this->_having($key, $value, 'OR ', $escape);\r
804         }\r
805         \r
806         // --------------------------------------------------------------------\r
807 \r
808         /**\r
809          * Sets the HAVING values\r
810          *\r
811          * Called by having() or or_having()\r
812          *\r
813          * @access      private\r
814          * @param       string\r
815          * @param       string\r
816          * @return      object\r
817          */\r
818         function _having($key, $value = '', $type = 'AND ', $escape = TRUE)\r
819         {\r
820                 if ( ! is_array($key))\r
821                 {\r
822                         $key = array($key => $value);\r
823                 }\r
824         \r
825                 foreach ($key as $k => $v)\r
826                 {\r
827                         $prefix = (count($this->ar_having) == 0) ? '' : $type;\r
828 \r
829                         if ($escape === TRUE)\r
830                         {\r
831                                 $k = $this->_protect_identifiers($k);\r
832                         }\r
833 \r
834                         if ( ! $this->_has_operator($k))\r
835                         {\r
836                                 $k .= ' = ';\r
837                         }\r
838 \r
839                         if ($v != '')\r
840                         {\r
841                                 $v = ' '.$this->escape_str($v);\r
842                         }\r
843                         \r
844                         $this->ar_having[] = $prefix.$k.$v;\r
845                         if ($this->ar_caching === TRUE)\r
846                         {\r
847                                 $this->ar_cache_having[] = $prefix.$k.$v;\r
848                                 $this->ar_cache_exists[] = 'having';\r
849                         }\r
850                 }\r
851                 \r
852                 return $this;\r
853         }\r
854         \r
855         // --------------------------------------------------------------------\r
856 \r
857         /**\r
858          * Sets the ORDER BY value\r
859          *\r
860          * @access      public\r
861          * @param       string\r
862          * @param       string  direction: asc or desc\r
863          * @return      object\r
864          */\r
865         function order_by($orderby, $direction = '')\r
866         {\r
867                 if (strtolower($direction) == 'random')\r
868                 {\r
869                         $orderby = ''; // Random results want or don't need a field name\r
870                         $direction = $this->_random_keyword;\r
871                 }\r
872                 elseif (trim($direction) != '')\r
873                 {\r
874                         $direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';\r
875                 }\r
876                 \r
877                 $orderby_statement = $this->_protect_identifiers($orderby).$direction;\r
878                 \r
879                 $this->ar_orderby[] = $orderby_statement;\r
880                 if ($this->ar_caching === TRUE)\r
881                 {\r
882                         $this->ar_cache_orderby[] = $orderby_statement;\r
883                         $this->ar_cache_exists[] = 'orderby';\r
884                 }\r
885 \r
886                 return $this;\r
887         }\r
888         \r
889         // --------------------------------------------------------------------\r
890 \r
891         /**\r
892          * orderby() is an alias of order_by()\r
893          * this function is here for backwards compatibility, as\r
894          * orderby() has been deprecated\r
895          */\r
896         function orderby($orderby, $direction = '')\r
897         {\r
898                 return $this->order_by($orderby, $direction);\r
899         }\r
900         \r
901         // --------------------------------------------------------------------\r
902 \r
903         /**\r
904          * Sets the LIMIT value\r
905          *\r
906          * @access      public\r
907          * @param       integer the limit value\r
908          * @param       integer the offset value\r
909          * @return      object\r
910          */\r
911         function limit($value, $offset = '')\r
912         {\r
913                 $this->ar_limit = $value;\r
914 \r
915                 if ($offset != '')\r
916                 {\r
917                         $this->ar_offset = $offset;\r
918                 }\r
919                 \r
920                 return $this;\r
921         }\r
922         \r
923         // --------------------------------------------------------------------\r
924 \r
925         /**\r
926          * Sets the OFFSET value\r
927          *\r
928          * @access      public\r
929          * @param       integer the offset value\r
930          * @return      object\r
931          */\r
932         function offset($offset)\r
933         {\r
934                 $this->ar_offset = $offset;\r
935                 return $this;\r
936         }\r
937         \r
938         // --------------------------------------------------------------------\r
939 \r
940         /**\r
941          * The "set" function.  Allows key/value pairs to be set for inserting or updating\r
942          *\r
943          * @access      public\r
944          * @param       mixed\r
945          * @param       string\r
946          * @param       boolean\r
947          * @return      object\r
948          */\r
949         function set($key, $value = '', $escape = TRUE)\r
950         {\r
951                 $key = $this->_object_to_array($key);\r
952         \r
953                 if ( ! is_array($key))\r
954                 {\r
955                         $key = array($key => $value);\r
956                 }       \r
957 \r
958                 foreach ($key as $k => $v)\r
959                 {\r
960                         if ($escape === FALSE)\r
961                         {\r
962                                 $this->ar_set[$this->_protect_identifiers($k)] = $v;\r
963                         }\r
964                         else\r
965                         {\r
966                                 $this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v);\r
967                         }\r
968                 }\r
969                 \r
970                 return $this;\r
971         }\r
972         \r
973         // --------------------------------------------------------------------\r
974 \r
975         /**\r
976          * Get\r
977          *\r
978          * Compiles the select statement based on the other functions called\r
979          * and runs the query\r
980          *\r
981          * @access      public\r
982          * @param       string  the table\r
983          * @param       string  the limit clause\r
984          * @param       string  the offset clause\r
985          * @return      object\r
986          */\r
987         function get($table = '', $limit = null, $offset = null)\r
988         {\r
989                 if ($table != '')\r
990                 {\r
991                         $this->_track_aliases($table);\r
992                         $this->from($table);\r
993                 }\r
994                 \r
995                 if ( ! is_null($limit))\r
996                 {\r
997                         $this->limit($limit, $offset);\r
998                 }\r
999                         \r
1000                 $sql = $this->_compile_select();\r
1001 \r
1002                 $result = $this->query($sql);\r
1003                 $this->_reset_select();\r
1004                 return $result;\r
1005         }\r
1006 \r
1007         /**\r
1008          * "Count All Results" query\r
1009          *\r
1010          * Generates a platform-specific query string that counts all records \r
1011          * returned by an Active Record query.\r
1012          *\r
1013          * @access      public\r
1014          * @param       string\r
1015          * @return      string\r
1016          */\r
1017         function count_all_results($table = '')\r
1018         {\r
1019                 if ($table != '')\r
1020                 {\r
1021                         $this->_track_aliases($table);\r
1022                         $this->from($table);\r
1023                 }\r
1024                 \r
1025                 $sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows'));\r
1026 \r
1027                 $query = $this->query($sql);\r
1028                 $this->_reset_select();\r
1029         \r
1030                 if ($query->num_rows() == 0)\r
1031                 {\r
1032                         return '0';\r
1033                 }\r
1034 \r
1035                 $row = $query->row();\r
1036                 return $row->numrows;\r
1037         }\r
1038 \r
1039         // --------------------------------------------------------------------\r
1040 \r
1041         /**\r
1042          * Get_Where\r
1043          *\r
1044          * Allows the where clause, limit and offset to be added directly\r
1045          *\r
1046          * @access      public\r
1047          * @param       string  the where clause\r
1048          * @param       string  the limit clause\r
1049          * @param       string  the offset clause\r
1050          * @return      object\r
1051          */\r
1052         function get_where($table = '', $where = null, $limit = null, $offset = null)\r
1053         {\r
1054                 if ($table != '')\r
1055                 {\r
1056                         $this->from($table);\r
1057                 }\r
1058 \r
1059                 if ( ! is_null($where))\r
1060                 {\r
1061                         $this->where($where);\r
1062                 }\r
1063                 \r
1064                 if ( ! is_null($limit))\r
1065                 {\r
1066                         $this->limit($limit, $offset);\r
1067                 }\r
1068                         \r
1069                 $sql = $this->_compile_select();\r
1070 \r
1071                 $result = $this->query($sql);\r
1072                 $this->_reset_select();\r
1073                 return $result;\r
1074         }\r
1075 \r
1076         // --------------------------------------------------------------------\r
1077 \r
1078         /**\r
1079          * getwhere() is an alias of get_where()\r
1080          * this function is here for backwards compatibility, as\r
1081          * getwhere() has been deprecated\r
1082          */\r
1083         function getwhere($table = '', $where = null, $limit = null, $offset = null)\r
1084         {\r
1085                 return $this->get_where($table, $where, $limit, $offset);\r
1086         }\r
1087         \r
1088         // --------------------------------------------------------------------\r
1089 \r
1090         /**\r
1091          * Insert\r
1092          *\r
1093          * Compiles an insert string and runs the query\r
1094          *\r
1095          * @access      public\r
1096          * @param       string  the table to retrieve the results from\r
1097          * @param       array   an associative array of insert values\r
1098          * @return      object\r
1099          */\r
1100         function insert($table = '', $set = NULL)\r
1101         {       \r
1102                 if ( ! is_null($set))\r
1103                 {\r
1104                         $this->set($set);\r
1105                 }\r
1106         \r
1107                 if (count($this->ar_set) == 0)\r
1108                 {\r
1109                         if ($this->db_debug)\r
1110                         {\r
1111                                 return $this->display_error('db_must_use_set');\r
1112                         }\r
1113                         return FALSE;\r
1114                 }\r
1115 \r
1116                 if ($table == '')\r
1117                 {\r
1118                         if ( ! isset($this->ar_from[0]))\r
1119                         {\r
1120                                 if ($this->db_debug)\r
1121                                 {\r
1122                                         return $this->display_error('db_must_set_table');\r
1123                                 }\r
1124                                 return FALSE;\r
1125                         }\r
1126                         \r
1127                         $table = $this->ar_from[0];\r
1128                 }\r
1129 \r
1130                 $sql = $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));\r
1131                 \r
1132                 $this->_reset_write();\r
1133                 return $this->query($sql);              \r
1134         }\r
1135         \r
1136         // --------------------------------------------------------------------\r
1137 \r
1138         /**\r
1139          * Update\r
1140          *\r
1141          * Compiles an update string and runs the query\r
1142          *\r
1143          * @access      public\r
1144          * @param       string  the table to retrieve the results from\r
1145          * @param       array   an associative array of update values\r
1146          * @param       mixed   the where clause\r
1147          * @return      object\r
1148          */\r
1149         function update($table = '', $set = NULL, $where = NULL, $limit = NULL)\r
1150         {\r
1151                 // Combine any cached components with the current statements\r
1152                 $this->_merge_cache();\r
1153 \r
1154                 if ( ! is_null($set))\r
1155                 {\r
1156                         $this->set($set);\r
1157                 }\r
1158         \r
1159                 if (count($this->ar_set) == 0)\r
1160                 {\r
1161                         if ($this->db_debug)\r
1162                         {\r
1163                                 return $this->display_error('db_must_use_set');\r
1164                         }\r
1165                         return FALSE;\r
1166                 }\r
1167 \r
1168                 if ($table == '')\r
1169                 {\r
1170                         if ( ! isset($this->ar_from[0]))\r
1171                         {\r
1172                                 if ($this->db_debug)\r
1173                                 {\r
1174                                         return $this->display_error('db_must_set_table');\r
1175                                 }\r
1176                                 return FALSE;\r
1177                         }\r
1178                         \r
1179                         $table = $this->ar_from[0];\r
1180                 }\r
1181                 \r
1182                 if ($where != NULL)\r
1183                 {\r
1184                         $this->where($where);\r
1185                 }\r
1186 \r
1187                 if ($limit != NULL)\r
1188                 {\r
1189                         $this->limit($limit);\r
1190                 }\r
1191                 \r
1192                 $sql = $this->_update($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);\r
1193                 \r
1194                 $this->_reset_write();\r
1195                 return $this->query($sql);\r
1196         }\r
1197 \r
1198         // --------------------------------------------------------------------\r
1199 \r
1200         /**\r
1201          * Empty Table\r
1202          *\r
1203          * Compiles a delete string and runs "DELETE FROM table"\r
1204          *\r
1205          * @access      public\r
1206          * @param       string  the table to empty\r
1207          * @return      object\r
1208          */\r
1209         function empty_table($table = '')\r
1210         {\r
1211                 if ($table == '')\r
1212                 {\r
1213                         if ( ! isset($this->ar_from[0]))\r
1214                         {\r
1215                                 if ($this->db_debug)\r
1216                                 {\r
1217                                         return $this->display_error('db_must_set_table');\r
1218                                 }\r
1219                                 return FALSE;\r
1220                         }\r
1221 \r
1222                         $table = $this->ar_from[0];\r
1223                 }\r
1224                 else\r
1225                 {\r
1226                         $table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);\r
1227                 }\r
1228 \r
1229                 $sql = $this->_delete($table);\r
1230 \r
1231                 $this->_reset_write();\r
1232                 \r
1233                 return $this->query($sql);\r
1234         }\r
1235 \r
1236         // --------------------------------------------------------------------\r
1237 \r
1238         /**\r
1239          * Truncate\r
1240          *\r
1241          * Compiles a truncate string and runs the query\r
1242          * If the database does not support the truncate() command\r
1243          * This function maps to "DELETE FROM table"\r
1244          *\r
1245          * @access      public\r
1246          * @param       string  the table to truncate\r
1247          * @return      object\r
1248          */\r
1249         function truncate($table = '')\r
1250         {\r
1251                 if ($table == '')\r
1252                 {\r
1253                         if ( ! isset($this->ar_from[0]))\r
1254                         {\r
1255                                 if ($this->db_debug)\r
1256                                 {\r
1257                                         return $this->display_error('db_must_set_table');\r
1258                                 }\r
1259                                 return FALSE;\r
1260                         }\r
1261 \r
1262                         $table = $this->ar_from[0];\r
1263                 }\r
1264                 else\r
1265                 {\r
1266                         $table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);\r
1267                 }\r
1268 \r
1269                 $sql = $this->_truncate($table);\r
1270 \r
1271                 $this->_reset_write();\r
1272                 \r
1273                 return $this->query($sql);\r
1274         }\r
1275         \r
1276         // --------------------------------------------------------------------\r
1277 \r
1278         /**\r
1279          * Delete\r
1280          *\r
1281          * Compiles a delete string and runs the query\r
1282          *\r
1283          * @access      public\r
1284          * @param       mixed   the table(s) to delete from. String or array\r
1285          * @param       mixed   the where clause\r
1286          * @param       mixed   the limit clause\r
1287          * @param       boolean\r
1288          * @return      object\r
1289          */\r
1290         function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE)\r
1291         {\r
1292                 // Combine any cached components with the current statements\r
1293                 $this->_merge_cache();\r
1294 \r
1295                 if ($table == '')\r
1296                 {\r
1297                         if ( ! isset($this->ar_from[0]))\r
1298                         {\r
1299                                 if ($this->db_debug)\r
1300                                 {\r
1301                                         return $this->display_error('db_must_set_table');\r
1302                                 }\r
1303                                 return FALSE;\r
1304                         }\r
1305 \r
1306                         $table = $this->ar_from[0];\r
1307                 }\r
1308                 elseif (is_array($table))\r
1309                 {\r
1310                         foreach($table as $single_table)\r
1311                         {\r
1312                                 $this->delete($single_table, $where, $limit, FALSE);\r
1313                         }\r
1314 \r
1315                         $this->_reset_write();\r
1316                         return;\r
1317                 }\r
1318                 else\r
1319                 {\r
1320                         $table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);\r
1321                 }\r
1322 \r
1323                 if ($where != '')\r
1324                 {\r
1325                         $this->where($where);\r
1326                 }\r
1327 \r
1328                 if ($limit != NULL)\r
1329                 {\r
1330                         $this->limit($limit);\r
1331                 }\r
1332 \r
1333                 if (count($this->ar_where) == 0 && count($this->ar_like) == 0)\r
1334                 {\r
1335                         if ($this->db_debug)\r
1336                         {\r
1337                                 return $this->display_error('db_del_must_use_where');\r
1338                         }\r
1339 \r
1340                         return FALSE;\r
1341                 }               \r
1342 \r
1343                 $sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit);\r
1344 \r
1345                 if ($reset_data)\r
1346                 {\r
1347                         $this->_reset_write();\r
1348                 }\r
1349                 \r
1350                 return $this->query($sql);\r
1351         }\r
1352 \r
1353         // --------------------------------------------------------------------\r
1354 \r
1355         /**\r
1356          * DB Prefix\r
1357          *\r
1358          * Prepends a database prefix if one exists in configuration\r
1359          *\r
1360          * @access      public\r
1361          * @param       string  the table\r
1362          * @return      string\r
1363          */\r
1364         function dbprefix($table = '')\r
1365         {\r
1366                 if ($table == '')\r
1367                 {\r
1368                         $this->display_error('db_table_name_required');\r
1369                 }\r
1370 \r
1371                 return $this->dbprefix.$table;\r
1372         }\r
1373 \r
1374         // --------------------------------------------------------------------\r
1375 \r
1376         /**\r
1377          * Track Aliases\r
1378          *\r
1379          * Used to track SQL statements written with aliased tables.\r
1380          *\r
1381          * @access      private\r
1382          * @param       string  The table to inspect\r
1383          * @return      string\r
1384          */     \r
1385         function _track_aliases($table)\r
1386         {\r
1387                 if (is_array($table))\r
1388                 {\r
1389                         foreach ($table as $t)\r
1390                         {\r
1391                                 $this->_track_aliases($t);\r
1392                         }\r
1393                         return;\r
1394                 }\r
1395                 \r
1396                 // Does the string contain a comma?  If so, we need to separate\r
1397                 // the string into discreet statements\r
1398                 if (strpos($table, ',') !== FALSE)\r
1399                 {\r
1400                         return $this->_track_aliases(explode(',', $table));\r
1401                 }\r
1402         \r
1403                 // if a table alias is used we can recognize it by a space\r
1404                 if (strpos($table, " ") !== FALSE)\r
1405                 {\r
1406                         // if the alias is written with the AS keyword, remove it\r
1407                         $table = preg_replace('/ AS /i', ' ', $table);\r
1408                         \r
1409                         // Grab the alias\r
1410                         $table = trim(strrchr($table, " "));\r
1411                         \r
1412                         // Store the alias, if it doesn't already exist\r
1413                         if ( ! in_array($table, $this->ar_aliased_tables))\r
1414                         {\r
1415                                 $this->ar_aliased_tables[] = $table;\r
1416                         }\r
1417                 }\r
1418         }\r
1419 \r
1420         // --------------------------------------------------------------------\r
1421 \r
1422         /**\r
1423          * Compile the SELECT statement\r
1424          *\r
1425          * Generates a query string based on which functions were used.\r
1426          * Should not be called directly.  The get() function calls it.\r
1427          *\r
1428          * @access      private\r
1429          * @return      string\r
1430          */\r
1431         function _compile_select($select_override = FALSE)\r
1432         {\r
1433                 // Combine any cached components with the current statements\r
1434                 $this->_merge_cache();\r
1435 \r
1436                 // ----------------------------------------------------------------\r
1437                 \r
1438                 // Write the "select" portion of the query\r
1439 \r
1440                 if ($select_override !== FALSE)\r
1441                 {\r
1442                         $sql = $select_override;\r
1443                 }\r
1444                 else\r
1445                 {\r
1446                         $sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';\r
1447                 \r
1448                         if (count($this->ar_select) == 0)\r
1449                         {\r
1450                                 $sql .= '*';            \r
1451                         }\r
1452                         else\r
1453                         {                               \r
1454                                 // Cycle through the "select" portion of the query and prep each column name.\r
1455                                 // The reason we protect identifiers here rather then in the select() function\r
1456                                 // is because until the user calls the from() function we don't know if there are aliases\r
1457                                 foreach ($this->ar_select as $key => $val)\r
1458                                 {\r
1459                                         $this->ar_select[$key] = $this->_protect_identifiers($val);\r
1460                                 }\r
1461                                 \r
1462                                 $sql .= implode(', ', $this->ar_select);\r
1463                         }\r
1464                 }\r
1465 \r
1466                 // ----------------------------------------------------------------\r
1467                 \r
1468                 // Write the "FROM" portion of the query\r
1469 \r
1470                 if (count($this->ar_from) > 0)\r
1471                 {\r
1472                         $sql .= "\nFROM ";\r
1473 \r
1474                         $sql .= $this->_from_tables($this->ar_from);\r
1475                 }\r
1476 \r
1477                 // ----------------------------------------------------------------\r
1478                 \r
1479                 // Write the "JOIN" portion of the query\r
1480 \r
1481                 if (count($this->ar_join) > 0)\r
1482                 {\r
1483                         $sql .= "\n";\r
1484 \r
1485                         $sql .= implode("\n", $this->ar_join);\r
1486                 }\r
1487 \r
1488                 // ----------------------------------------------------------------\r
1489                 \r
1490                 // Write the "WHERE" portion of the query\r
1491 \r
1492                 if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)\r
1493                 {\r
1494                         $sql .= "\n";\r
1495 \r
1496                         $sql .= "WHERE ";\r
1497                 }\r
1498 \r
1499                 $sql .= implode("\n", $this->ar_where);\r
1500 \r
1501                 // ----------------------------------------------------------------\r
1502                 \r
1503                 // Write the "LIKE" portion of the query\r
1504         \r
1505                 if (count($this->ar_like) > 0)\r
1506                 {\r
1507                         if (count($this->ar_where) > 0)\r
1508                         {\r
1509                                 $sql .= "\nAND ";\r
1510                         }\r
1511 \r
1512                         $sql .= implode("\n", $this->ar_like);\r
1513                 }\r
1514 \r
1515                 // ----------------------------------------------------------------\r
1516                 \r
1517                 // Write the "GROUP BY" portion of the query\r
1518         \r
1519                 if (count($this->ar_groupby) > 0)\r
1520                 {\r
1521                         $sql .= "\nGROUP BY ";\r
1522                         \r
1523                         $sql .= implode(', ', $this->ar_groupby);\r
1524                 }\r
1525 \r
1526                 // ----------------------------------------------------------------\r
1527                 \r
1528                 // Write the "HAVING" portion of the query\r
1529                 \r
1530                 if (count($this->ar_having) > 0)\r
1531                 {\r
1532                         $sql .= "\nHAVING ";\r
1533                         $sql .= implode("\n", $this->ar_having);\r
1534                 }\r
1535 \r
1536                 // ----------------------------------------------------------------\r
1537                 \r
1538                 // Write the "ORDER BY" portion of the query\r
1539 \r
1540                 if (count($this->ar_orderby) > 0)\r
1541                 {\r
1542                         $sql .= "\nORDER BY ";\r
1543                         $sql .= implode(', ', $this->ar_orderby);\r
1544                         \r
1545                         if ($this->ar_order !== FALSE)\r
1546                         {\r
1547                                 $sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';\r
1548                         }               \r
1549                 }\r
1550 \r
1551                 // ----------------------------------------------------------------\r
1552                 \r
1553                 // Write the "LIMIT" portion of the query\r
1554                 \r
1555                 if (is_numeric($this->ar_limit))\r
1556                 {\r
1557                         $sql .= "\n";\r
1558                         $sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset);\r
1559                 }\r
1560 \r
1561                 return $sql;\r
1562         }\r
1563 \r
1564         // --------------------------------------------------------------------\r
1565 \r
1566         /**\r
1567          * Object to Array\r
1568          *\r
1569          * Takes an object as input and converts the class variables to array key/vals\r
1570          *\r
1571          * @access      public\r
1572          * @param       object\r
1573          * @return      array\r
1574          */\r
1575         function _object_to_array($object)\r
1576         {\r
1577                 if ( ! is_object($object))\r
1578                 {\r
1579                         return $object;\r
1580                 }\r
1581                 \r
1582                 $array = array();\r
1583                 foreach (get_object_vars($object) as $key => $val)\r
1584                 {\r
1585                         // There are some built in keys we need to ignore for this conversion\r
1586                         if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name' && $key != '_ci_scaffolding' && $key != '_ci_scaff_table')\r
1587                         {\r
1588                                 $array[$key] = $val;\r
1589                         }\r
1590                 }\r
1591         \r
1592                 return $array;\r
1593         }\r
1594         \r
1595         // --------------------------------------------------------------------\r
1596 \r
1597         /**\r
1598          * Start Cache\r
1599          *\r
1600          * Starts AR caching\r
1601          *\r
1602          * @access      public\r
1603          * @return      void\r
1604          */             \r
1605         function start_cache()\r
1606         {\r
1607                 $this->ar_caching = TRUE;\r
1608         }\r
1609 \r
1610         // --------------------------------------------------------------------\r
1611 \r
1612         /**\r
1613          * Stop Cache\r
1614          *\r
1615          * Stops AR caching\r
1616          *\r
1617          * @access      public\r
1618          * @return      void\r
1619          */             \r
1620         function stop_cache()\r
1621         {\r
1622                 $this->ar_caching = FALSE;\r
1623         }\r
1624 \r
1625         // --------------------------------------------------------------------\r
1626 \r
1627         /**\r
1628          * Flush Cache\r
1629          *\r
1630          * Empties the AR cache\r
1631          *\r
1632          * @access      public\r
1633          * @return      void\r
1634          */     \r
1635         function flush_cache()\r
1636         {       \r
1637                 $this->_reset_run(\r
1638                                                         array(\r
1639                                                                         'ar_cache_select'       => array(), \r
1640                                                                         'ar_cache_from'         => array(), \r
1641                                                                         'ar_cache_join'         => array(),\r
1642                                                                         'ar_cache_where'        => array(), \r
1643                                                                         'ar_cache_like'         => array(), \r
1644                                                                         'ar_cache_groupby'      => array(), \r
1645                                                                         'ar_cache_having'       => array(), \r
1646                                                                         'ar_cache_orderby'      => array(), \r
1647                                                                         'ar_cache_set'          => array(),\r
1648                                                                         'ar_cache_exists'       => array()\r
1649                                                                 )\r
1650                                                         );      \r
1651         }\r
1652 \r
1653         // --------------------------------------------------------------------\r
1654 \r
1655         /**\r
1656          * Merge Cache\r
1657          *\r
1658          * When called, this function merges any cached AR arrays with \r
1659          * locally called ones.\r
1660          *\r
1661          * @access      private\r
1662          * @return      void\r
1663          */\r
1664         function _merge_cache()\r
1665         {\r
1666                 if (count($this->ar_cache_exists) == 0)\r
1667                 {\r
1668                         return;\r
1669                 }\r
1670 \r
1671                 foreach ($this->ar_cache_exists as $val)\r
1672                 {\r
1673                         $ar_variable    = 'ar_'.$val;\r
1674                         $ar_cache_var   = 'ar_cache_'.$val;\r
1675 \r
1676                         if (count($this->$ar_cache_var) == 0)\r
1677                         {\r
1678                                 continue;\r
1679                         }\r
1680 \r
1681                         $this->$ar_variable = array_unique(array_merge($this->$ar_cache_var, $this->$ar_variable));\r
1682                 }\r
1683 \r
1684                 // If we are "protecting identifiers" we need to examine the "from"\r
1685                 // portion of the query to determine if there are any aliases\r
1686                 if ($this->_protect_identifiers === TRUE AND count($this->ar_cache_from) > 0)\r
1687                 {\r
1688                         $this->_track_aliases($this->ar_from);\r
1689                 }\r
1690         }\r
1691 \r
1692         // --------------------------------------------------------------------\r
1693 \r
1694         /**\r
1695          * Resets the active record values.  Called by the get() function\r
1696          *\r
1697          * @access      private\r
1698          * @param       array   An array of fields to reset\r
1699          * @return      void\r
1700          */\r
1701         function _reset_run($ar_reset_items)\r
1702         {\r
1703                 foreach ($ar_reset_items as $item => $default_value)\r
1704                 {\r
1705                         if ( ! in_array($item, $this->ar_store_array))\r
1706                         {\r
1707                                 $this->$item = $default_value;\r
1708                         }\r
1709                 }\r
1710         }\r
1711 \r
1712         // --------------------------------------------------------------------\r
1713 \r
1714         /**\r
1715          * Resets the active record values.  Called by the get() function\r
1716          *\r
1717          * @access      private\r
1718          * @return      void\r
1719          */\r
1720         function _reset_select()\r
1721         {\r
1722                 $ar_reset_items = array(\r
1723                                                                 'ar_select'                     => array(), \r
1724                                                                 'ar_from'                       => array(), \r
1725                                                                 'ar_join'                       => array(), \r
1726                                                                 'ar_where'                      => array(), \r
1727                                                                 'ar_like'                       => array(), \r
1728                                                                 'ar_groupby'            => array(), \r
1729                                                                 'ar_having'                     => array(), \r
1730                                                                 'ar_orderby'            => array(), \r
1731                                                                 'ar_wherein'            => array(), \r
1732                                                                 'ar_aliased_tables'     => array(),\r
1733                                                                 'ar_distinct'           => FALSE, \r
1734                                                                 'ar_limit'                      => FALSE, \r
1735                                                                 'ar_offset'                     => FALSE, \r
1736                                                                 'ar_order'                      => FALSE,\r
1737                                                         );\r
1738                 \r
1739                 $this->_reset_run($ar_reset_items);\r
1740         }\r
1741         \r
1742         // --------------------------------------------------------------------\r
1743 \r
1744         /**\r
1745          * Resets the active record "write" values.\r
1746          *\r
1747          * Called by the insert() update() and delete() functions\r
1748          *\r
1749          * @access      private\r
1750          * @return      void\r
1751          */\r
1752         function _reset_write()\r
1753         {       \r
1754                 $ar_reset_items = array(\r
1755                                                                 'ar_set'                => array(), \r
1756                                                                 'ar_from'               => array(), \r
1757                                                                 'ar_where'              => array(), \r
1758                                                                 'ar_like'               => array(),\r
1759                                                                 'ar_orderby'    => array(), \r
1760                                                                 'ar_limit'              => FALSE, \r
1761                                                                 'ar_order'              => FALSE\r
1762                                                                 );\r
1763 \r
1764                 $this->_reset_run($ar_reset_items);\r
1765         }\r
1766         \r
1767 }\r
1768 \r
1769 /* End of file DB_active_rec.php */\r
1770 /* Location: ./system/database/DB_active_rec.php */