PhpToolCase
Api Documentation Version 0.9.2
PtcQueryBuilder.php
Go to the documentation of this file.
1 <?php
2 
3  /**
4  * PHP TOOLCASE QUERY BUILDER CLASS
5  * PHP version 5.3
6  * @category Library
7  * @version 0.9.2
8  * @author Irony <carlo@salapc.com>
9  * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
10  * @link http://phptoolcase.com
11  */
12 
14  {
15  /**
16  * Adds the pdo instance to the query builder object. See @ref qb_getting_started
17  * @param object $pdo the pdo object
18  */
19  public function __construct( PDO $pdo = null )
20  {
21  $this->_randomId = $this->_generateRandomId( );
22  if ( $pdo ){ $this->_pdo = $pdo; }
23  return $this;
24  }
25  /**
26  * Adds tables to the query. See @ref qb_multiple_tables
27  * @param array|string $table the name of the table
28  */
29  public function table( $table )
30  {
31  $this->reset( );
32  $table = ( is_array( $table ) ) ? $table : array( $table );
33  foreach ( $table as $v )
34  {
35  if ( $val = $this->_checkRawValue( $v ) )
36  {
37  $this->_table .= ' ' . $val. ',';
38  continue;
39  }
40  $divider = ( strpos( $v , ' as ' ) ) ? ' as ' : ' AS ';
41  $table = explode( $divider , $v );
42  $t = $this->addBackTicks( $table[ 0 ] );
43  if ( array_key_exists( 1 , $table ) )
44  {
45  $t .= ' as ' . $this->addBackTicks( $table[ 1 ] );
46  }
47  $this->_table .= $this->sanitize( $t ) . ',';
48  //$this->_table .= $this->addBackTicks( $this->sanitize( $v ) ) . ',';
49  }
50  $this->_table = substr( $this->_table , 0 , strlen( $this->_table ) - 1 );
51  $this->_currentQueryType = 'select'; // set query type as select by default
52  return $this;
53  }
54  /**
55  * Sets the columns to be selected. See @ref qb_specify_column
56  * @param array|string $columns the columns to be selected
57  */
58  public function select( $columns )
59  {
60  $this->_columns = '';
61  $columns = is_array( $columns ) ? $columns : array( $columns );
62  foreach ( $columns as $v )
63  {
64  if ( $val = $this->_checkRawValue( $v ) )
65  {
66  $this->_columns .= ' ' . $val. ',';
67  continue;
68  }
69  $divider = ( strpos( $v , ' as ' ) ) ? ' as ' : ' AS ';
70  $column = explode( $divider , $v );
71  if ( preg_match( '/\(([^\)]*)\)/' , $column[ 0 ] , $matches ) )
72  {
73  $col = str_replace( $matches[ 0 ] , '(' .
74  $this->addBackTicks( $matches[ 1 ] ) . ')' , $column[ 0 ] );
75  }
76  else{ $col = $this->addBackTicks( $column[ 0 ] ); }
77  $col .= ( array_key_exists( 1, $column ) ) ? ' as ' .
78  $this->addBackTicks( $column[ 1 ] ) : ' ';
79  $this->_columns .= $this->sanitize( $col ) . ',';
80  }
81  $this->_columns = substr( $this->_columns , 0 , strlen( $this->_columns ) - 1 ). ' ';
82  return $this;
83  }
84  /**
85  * Adds A raw where clause to the query. See @ref qb_rawStatemet
86  * @param string $rawClause the where clause
87  */
88  public function rawSelect( $rawClause )
89  {
90  $this->_where = $this->_where . ' ' . $rawClause;
91  return $this;
92  }
93  /**
94  * Sanitize unsafe data
95  * @param string $value the value to sanitize
96  * @return the value with back slashes added
97  */
98  public function sanitize( $value )
99  {
100  if ( $val = $this->_checkRawValue( $value ) ){ return $value; }
101  /*if( $this->_pdo ){ return $this->_pdo->quote( $string ); }*/
102  return addslashes( $value ); // should be done better
103  }
104  /**
105  * Adds a raw value to a where clause in the query. See @ref qb_rawValues
106  * @param string $value a raw value for the sql query
107  * @return the raw value to be added with a unique identifier string
108  */
109  public function raw( $value ){ return $this->_randomId . 'RAW{' .$value . '}'; }
110  /**
111  * Adds backticks to the passed string
112  * @param string $string the column or table name
113  * @return the string with backticks added,
114  */
115  public function addBackTicks( $string )
116  {
117  if ( $val = $this->_checkRawValue( $string ) ){ return $val; }
118  $raw = explode( '.' , $string );
119  $string = ( $raw[ 0 ] === '*' ) ? $raw[ 0 ] : '`' . $raw[ 0 ] . '`';
120  return $string .= ( @$raw[ 1 ] ) ? '.`' . $raw[ 1 ] . '`': '';
121  }
122  /**
123  * Creates a join based on the parameters. See @ref qb_joins
124  * @param string $table the name of the table to join
125  * @param string $first the first column
126  * @param string $operator the operator to use for the join
127  * @param string $second the second column
128  * @param string $type the type of join
129  */
130  public function join( $table , $first , $operator = null , $second = null , $type = 'inner' )
131  {
132  if ( !$this->_isTableSet( ) ) { return false; }
133  $this->_join .= ' ' . strtoupper( $type ) . ' JOIN ' . $this->addBackTicks( $table );
134  $this->_isClosure = true;
135  if ( $first instanceof Closure ){ $this->_runClosure( $first , 'join' ); }
136  else{ $this->on( $first, $operator, $second ); }
137  return $this;
138  }
139  /**
140  * Joins columns based on values. See @ref qb_joins
141  * @param string $column the first column for the join
142  * @param string $operator the operator to use
143  * @param string $value the second column for the join
144  * @param string $type adds "and" , "or" to multiple joins statements
145  */
146  public function on( $column, $operator, $value , $type = 'and' )
147  {
148  if ( !$this->_checkOperator( $operator ) ) { return; }
149  $this->_join .= ( $this->_isClosure ) ? ' ON ' : ' ' . strtoupper( $type ) . ' ';
150  $this->_isClosure = false;
151  $this->_join .= $this->addBackTicks( $column ) . ' ' . $operator . ' ' .
152  $this->addBackTicks( $value ) . ' ';
153  return $this;
154  }
155  /**
156  * Adds where clouses to the query. See @ref qb_where_operators
157  * @param mixed $column the column name or a closure function
158  * @param string $operator the operator to use for the where clause
159  * @param string $value the value to look for in the column
160  * @param string $type the type of where clasuse
161  */
162  public function where( $column , $operator = null , $value = null , $type = 'and' )
163  {
164  if ( !$this->_isTableSet( ) ) { return false; }
165  if ( $column instanceof Closure )
166  {
167  $this->_runClosure( $column , $type );
168  return $this;
169  }
170  if ( $this->_isClosure )
171  {
172  $this->_isClosure = false;
173  $type = '';
174  }
175  $this->_buildWhereClause( $type , $column , $operator , $value );
176  return $this;
177  }
178  /**
179  * returns 1 record from a given table based on the id. See @ref qb_selecting_one_row
180  * @param numeric $id the record id
181  */
182  public function find( $id )
183  {
184  if ( !$this->_isTableSet( ) ) { return; } // check if table property is set
185  $this->_where = null;
186  $this->_buildWhereClause( 'and', 'id' , '=' , $id );
187  $query = 'SELECT ' . $this->_columns . ' FROM ' . $this->_table . $this->_where;
188  $this->_currentQuery = $query;
189  $result = $this->_executeSql( 2 );
190  return ( !empty( $result ) ) ? $result : null;
191  }
192  /**
193  * Runs queries if pdo object is present. See @ref qb_getting_started
194  * @param string $query the query to run
195  * @param array $bind the values to bind to the query
196  * @param numeric $type the query type ( 1,2,3)
197  * @return the query result if select, otherwise the number of affected rows
198  */
199  public function run( $query = null , $bind = null , $type = null )
200  {
201  if ( $this->_currentQueryType == 'select' ) // run select query stored in memory
202  {
203  if ( !$this->_isTableSet( ) ){ return false; }
204  $this->_currentQuery = $this->_buildQuery( );
205  }
206  $this->_bindings = ( $bind ) ? $bind : $this->_bindings;
207  $this->_currentQuery = ( $query ) ? $query : $this->_currentQuery;
208  if ( !$type )
209  {
210  $type = 3;
211  // check prepared statement that needs a return result
212  foreach ( $this->_returnStatements as $statement )
213  {
214  if ( strpos( trim( strtoupper( $this->_currentQuery ) ) , $statement ) === 0 )
215  {
216  $type = 1; // set type to 1 to return the result of the query
217  break;
218  }
219  }
220  }
221  return $this->_executeSql( $type ); // execute the query
222  }
223  /**
224  * Retrieves 1 row from a given table. See @ref qb_selecting_one_row
225  * @param string $column column name to return only 1 value as string
226  * @return single column value if "$column" argument is set, the full row otherwise
227  */
228  public function row( $column = null )
229  {
230  if ( !$this->_isTableSet( ) ) { return false; }
231  if ( $column )
232  {
233  $this->_columns = $this->addBackTicks( $column );
234  $this->setFetchMode( PDO::FETCH_ASSOC );
235  }
236  //$this->_columns = ( $column ) ? $this->addBackTicks( $column ) : $this->_columns;
237  $this->_currentQueryType = 'select';
238  $this->_currentQuery = $this->_buildQuery( );
239  $result = $this->_executeSql( 2 );
240  if ( empty( $result ) ){ return null; }
241  if ( $column )
242  {
243  if ( array_key_exists( $column , $result ) ){ return $result[ $column ]; }
244  trigger_error( 'Could not find column "' . $column . '"!' , E_USER_WARNING );
245  return null;
246  }
247  else{ return $result; }
248  }
249  /**
250  * Builds the query and returns it as string with place holders. See @ref qb_preparing_queries
251  */
252  public function prepare( )
253  {
254  if ( !$this->_isTableSet( ) ) { return false; }
255  $query = ( $this->_currentQuery ) ? $this->_currentQuery : $this->_buildQuery( );
256  foreach ( $this->_bindings as $k => $v )
257  {
258  if ( is_string( $v ) )
259  {
260  if ( false === strpos( $v, ':' ) ) { continue; }
261  $query = preg_replace( '/\?/' , $v , $query , 1 );
262  }
263  }
264  $this->reset( ); // reset properties
265  return $query;
266  }
267  /**
268  * Adds order to the query. See @ref qb_order_group_limit
269  * @param string $column the column names
270  * @param string $direction asc or desc
271  */
272  public function order( $column , $direction = 'asc' )
273  {
274  $direction = strtoupper( $direction );
275  $this->_orderBy = ( $this->_orderBy ) ? $this->_orderBy . ', ' : ' ORDER BY ';
276  $this->_orderBy .= $this->addBackTicks( $this->sanitize( $column ) ) . ' ' . $direction;
277  return $this;
278  }
279  /**
280  * Adds group by to the query. See @ref qb_order_group_limit
281  * @param string $column the column names
282  */
283  public function group( $column )
284  {
285  $this->_groupBy = ( $this->_groupBy ) ? $this->_groupBy . ', ' : ' GROUP BY ';
286  $this->_groupBy .= $this->addBackTicks( $this->sanitize( $column ) );
287  return $this;
288  }
289  /**
290  * Adds limit to the query. See @ref qb_order_group_limit
291  * @param string|int $start an integer value or a place holder
292  * @param string|int $results an integer value or a place holder
293  */
294  public function limit( $start , $results = null )
295  {
296  $start = is_numeric( $start ) ? ( int ) $start : $start;
297  $results = is_numeric( $results ) ? ( int ) $results : $results;
298  $this->_bindings[ ] = $start;
299  $this->_limit = ' LIMIT ?';
300  if ( $results )
301  {
302  $this->_bindings[ ] = $results;
303  $this->_limit .= ',?';
304  }
305  return $this;
306  }
307  /**
308  * Returns number of affected rows from last query. See @ref qb_count_rows
309  * @return the affected rows by the last query
310  */
311  public function countRows( )
312  {
313  if ( !$this->_lastQuery )
314  {
315  trigger_error( 'No queries Found to countRows!' , E_USER_NOTICE );
316  return false;
317  }
318  return $this->_lastQuery->rowCount( );
319  }
320  /**
321  * Retrieves last inserted id. See @ref qb_last_insert_id
322  * @return the last inserted id
323  */
324  public function lastId( ) { return $this->_pdo->lastInsertId( ); }
325  /**
326  * Inserts a record in a given table. See @ref qb_insert_data
327  * @param array $array an associative array , Ex.: array( column => value )
328  */
329  public function insert( $array )
330  {
331  if ( !$this->_isTableSet( ) ) { return false; }
332  $this->_currentQueryType = 'insert';
333  $this->_values = $array;
334  $this->_currentQuery = $this->_buildQuery( );
335  return $this;
336  }
337  /**
338  * Updates records in a given table based on a where clause. See @ref qb_update_data
339  * @param array $array associative array of values, Ex.: array( column => value )
340  * @param numeric $id a row id
341  */
342  public function update( $array , $id = null )
343  {
344  if ( !$this->_isTableSet( ) ){ return false; }
345  if ( !$this->_where && !$id )
346  {
347  trigger_error( 'No id or where clause was specified for the update!' ,
348  E_USER_ERROR );
349  return false;
350  }
351  $this->_currentQueryType = 'update';
352  $this->_values = $array;
353  if ( $id )
354  {
355  $this->_where = null;
356  $this->_buildWhereClause( 'and' , 'id' , '=' , $id );
357  }
358  $this->_currentQuery = $this->_buildQuery( );
359  return $this;
360  }
361  /**
362  * Deletes rows from a given table based on a where clause. See @ref qb_delete_data
363  * @param numeric $id a row id
364  */
365  public function delete( $id = null )
366  {
367  if ( !$this->_isTableSet( ) ) { return false; }
368  if ( !$this->_where && !$id )
369  {
370  trigger_error( 'No id or where clause was specified for the delete!' ,
371  E_USER_ERROR );
372  return false;
373  }
374  $this->_currentQueryType = 'delete';
375  if ( $id )
376  {
377  $this->_where = null;
378  $this->_bindings = null;
379  $this->_buildWhereClause( 'and' , 'id' , '=' , $id );
380  }
381  $this->_currentQuery = $this->_buildQuery( );
382  return $this;
383  }
384  /**
385  * Resets the query parameters
386  */
387  public function reset( )
388  {
389  $this->_table = null;
390  $this->_where = null;
391  $this->_columns = '*';
392  $this->_orderBy = null;
393  $this->_groupBy = null;
394  $this->_limit = null;
395  $this->_query = null;
396  $this->_currentQueryType = null;
397  $this->_currentQuery = null;
398  $this->_bindings = array( );
399  $this->_join = null;
400  }
401  /**
402  * Sets fetch mode for the next query. See @ref set_fetch_mode
403  * @param constant $mode a pdo constant
404  * @param mixed $class a class name if needed
405  */
406  public function setFetchMode( $mode , $class = null )
407  {
408  if ( $class && !class_exists( $class ) )
409  {
410  trigger_error( 'Class ' . $class . ' does not exists!' , E_USER_ERROR );
411  return false;
412  }
413  $this->_fetchMode = ( $class ) ? array( $mode , $class ) : array( $mode );
414 
415  }
416  /**
417  * Adds where operators and joins to the query
418  * @param string $method the method to call
419  * @param array $args arguments used by the called methods
420  */
421  public function __call( $method , $args )
422  {
423  if ( false !== strpos( $method , 'where' ) ) // work with where clause
424  {
425  $type = str_replace( 'where' , '' , $method );
426  if ( false !== strpos( $type , '_between' ) )
427  {
428  // build between clause
429  $type = $this->_addAndOR( $type );
430  $this->_buildBetweenClause( $args[ 0 ] , @$args[ 1 ] , @$args[ 2 ] , $type );
431  }
432  else if ( false !== strpos( $type , '_in' ) )
433  {
434  // build in clause
435  $type = $this->_addAndOR( $type );
436  $this->_buildInClause( $args[ 0 ] , $args[ 1 ] , $type );
437  }
438  else // process or_where( )
439  {
440  $type = str_replace( '_' , ' ' , $type );
441  $this->where( $args[ 0 ] , @$args[ 1 ] , @$args[ 2 ] , $type );
442  }
443  return $this;
444  }
445  else if ( false !== strpos( $method , '_join' ) ) // work with joins
446  {
447  $type = str_replace( '_join' , '' , $method );
448  $this->join( $args[ 0 ] , @$args[ 1 ] , @$args[ 2 ] , @$args[ 3 ] , $type );
449  return $this;
450  }
451  else if ( false !== strpos( $method , '_on' ) )
452  {
453  $type = str_replace( '_on' , '' , $method );
454  $this->on( $args[ 0 ] , @$args[ 1 ] , @$args[ 2 ] , $type );
455  return $this;
456  }
457  trigger_error( 'Called to undefined method "' . get_called_class( ) . '::' .
458  $method . '( )"!' , E_USER_ERROR );
459  }
460  /**
461  * Limit property for the query
462  */
463  protected $_bindLimit = array( );
464  /**
465  * Columns property for the query
466  */
467  protected $_columns = '*';
468  /**
469  * Table property for the query
470  */
471  protected $_table = null;
472  /**
473  * Where property for the query
474  */
475  protected $_where = null;
476  /**
477  * Order by property for the query
478  */
479  protected $_orderBy = null;
480  /**
481  * Group by property for the query
482  */
483  protected $_groupBy = null;
484  /**
485  * Limit property for the query
486  */
487  protected $_limit = null;
488  /**
489  * Pdo object prperty to run queries
490  */
491  protected $_pdo = null;
492  /**
493  * Prepared query property
494  */
495  protected $_query = null;
496  /**
497  * Last query property
498  */
499  protected $_lastQuery = null;
500  /**
501  * Current query property
502  */
503  protected $_currentQuery = null;
504  /**
505  * Current query type property
506  */
507  protected $_currentQueryType = null;
508  /**
509  * Bind values property
510  */
511  protected $_values = null;
512  /**
513  * Place holders property
514  */
515  protected $_bindings = array( );
516  /**
517  * Operator for where and join clauses property
518  */
519  protected $_operators = array( '=' , '<' , '>' , '<=' , '>=' , '<>' , '!=' ,
520  'like' , 'not like' , 'between' , 'ilike' );
521  /**
522  * Queries that need a return result propeerty
523  */
524  protected $_returnStatements = array( 'SHOW' , 'SELECT' );
525  /**
526  * Join Property
527  */
528  protected $_join = null;
529  /**
530  * Random Id property for raw values
531  */
532  protected $_randomId = null;
533  /**
534  * Property that checks if class is running a closure
535  */
536  protected $_isClosure = false;
537  /**
538  * Fecth mode pdo property for current query
539  */
540  protected $_fetchMode = array( );
541  /**
542  * Event class name property
543  */
544  protected $_eventClass = '\PtcEvent';
545  /**
546  * Builds the query based on the type
547  */
548  protected function _buildQuery( )
549  {
550  switch( $this->_currentQueryType )
551  {
552  case 'insert' :
553  $this->_bindings = array_values( $this->_values );
554  foreach ( $this->_values as $k => $v )
555  {
556  @$fields .= $this->addBackTicks( $k ) . ',';
557  @$values .= '?,';
558  }
559  $fields = substr( $fields , 0 , strlen( $fields ) - 1 );
560  $values = substr( $values , 0 , strlen( $values ) - 1 );
561  $query = 'INSERT INTO ' . $this->_table . ' (' . $fields . ') VALUES (' . $values . ')';
562  break;
563  case 'update' :
564  $bind = array_values( $this->_values );
565  $this->_bindings = array_merge( $bind , $this->_bindings );
566  foreach ( $this->_values as $k => $v )
567  {
568  @$values .= $this->addBackTicks( $k ) . ' = ?,';
569  }
570  $values = substr( $values , 0 , strlen( $values ) - 1 );
571  $query = "UPDATE " . $this->_table . " SET " . $values . $this->_where;
572  break;
573  case 'delete' : $query = 'DELETE FROM ' . $this->_table . $this->_where;
574  break;
575  case 'select' :
576  default :
577  $query = 'SELECT ' . $this->_columns . ' FROM ' . $this->_table . $this->_join .
578  $this->_where . $this->_groupBy . $this->_orderBy . $this->_limit;
579  }
580  return $query;
581  }
582  /**
583  * Executes sql queries. See @ref specifying_return
584  * @param numeric $mode the type of query (1,2,3)
585  * @return the result if query was select, the affected rows otherwise
586  */
587  protected function _executeSql( $mode = 1 )
588  {
589  if ( !$this->_checkPdo( ) ) { return false; }
590  $query = $this->_currentQuery;
591  self::_debug( '' , ' - ' . $query . ' - ' ); // debug
592  $this->_query = $this->_pdo->prepare( $query );
593  $this->_lastQuery = $this->_query;
594  if ( !empty( $this->_bindings ) )
595  {
596  foreach ( $this->_bindings as $k => $v ) { $this->_bind( $k , $v ); }
597  }
598  $this->_query->execute( );
599  if ( !empty( $this->_fetchMode ) )
600  {
601  if ( array_key_exists( 1 , $this->_fetchMode ) )
602  {
603  $this->_query->setFetchMode( $this->_fetchMode[ 0 ] , $this->_fetchMode[ 1 ] );
604  }
605  else{ $this->_query->setFetchMode( $this->_fetchMode[ 0 ] ); }
606  $this->_fetchMode = array( );
607  }
608  switch ( $mode )
609  {
610  case 3 : $result = $this->countRows( );
611  break;
612  case 2 : $result = $this->_query->fetch( );
613  break;
614  case 1 :
615  default : $result = $this->_query->fetchAll( );
616  }
617  self::_debugBuffer( ' - ' . $query . ' - ' ); // debug stop timer
618  $final_query = $this->_debugQuery( $this->_lastQuery->queryString , $this->_bindings );
619  $this->_fireEvent( array( $final_query , $this->_currentQuery , $this->_bindings ) ); // ptc.query event
620  $this->reset( ); // reset properties
621  // debug attach result
622  self::_debugBuffer( ' - ' . $query . ' - ' , 'attach' , $result , ' - ' . $final_query . ' - ' );
623  return $result;
624  }
625  /**
626  * Binds values to the query
627  * @param mixed $pos the param position if numeric
628  * @param mixed $value the value to bind the place holder to
629  * @param contants $type a pdo constant to bind values
630  */
631  protected function _bind( $pos , $value , $type = null )
632  {
633  if ( is_numeric( $pos ) ) { $pos = ( $pos + 1 ); }
634  if ( is_null( $type ) )
635  {
636  switch ( $value )
637  {
638  case is_int( $value ): $type = PDO::PARAM_INT;
639  break;
640  case is_bool( $value ): $type = PDO::PARAM_BOOL;
641  break;
642  case is_null( $value ): $type = PDO::PARAM_NULL;
643  break;
644  default: $type = PDO::PARAM_STR;
645  }
646  }
647  $this->_query->bindValue( $pos , $value , $type );
648  }
649  /**
650  * adds "and" or "or" to the query
651  * @param string $value the value to check
652  */
653  protected function _addAndOR( $value )
654  {
655  if ( false !== strpos( $value , 'or_' ) )
656  {
657  $value = str_replace( 'or_' , '' , $value );
658  $this->_where .= ( !$this->_where ) ? ' WHERE ' : ' OR ';
659  }
660  else
661  {
662  $value = str_replace( 'and_' , '' , $value );
663  $this->_where .= ( !$this->_where ) ? ' WHERE ' : ' AND ';
664  }
665  return $value;
666  }
667  /**
668  * Builds the where clause
669  * @param string $type specifies "and"/"or"
670  * @param string $column the table column
671  * @param string $operator the operator to use
672  * @param mixed $value the value to check
673  */
674  protected function _buildWhereClause( $type , $column , $operator = null , $value = null )
675  {
676  if ( !$this->_checkOperator( $operator ) ) { return; }
677  $this->_where .= ( $this->_where ) ? ' ' . strtoupper( $type ) . ' ' : ' WHERE ';
678  $this->_where .= $this->addBackTicks( $column ) . ' ' . $operator;
679  if ( preg_match( '|' . $this->_randomId . 'RAW{(.*?)}|', $value , $matches ) )
680  {
681  $this->_where .= ' ' . $matches[ 1 ];
682  return $this;
683  }
684  if ( $val = $this->_checkRawValue( $value ) )
685  {
686  $this->_where .= ' ' . $val;
687  return $this;
688  }
689  $this->_where .= ' ?';
690  $this->_bindings[ ] = ( @get_magic_quotes_gpc( ) ) ? @stripslashes( $value ) : $value;
691  return $this;
692  }
693  /**
694  * Creates a "where in" statement
695  */
696  protected function _buildInClause( $column , $array , $type = 'in' )
697  {
698  $this->_where .= $this->addBackTicks( $column ) . ' ';
699  $this->_where .= strtoupper( str_replace( '_' , ' ' , $type ) ) . ' ';
700  $this->_where .= ' (';
701  foreach ( $array as $v )
702  {
703  if ( $val = $this->_checkRawValue( $v ) )
704  {
705  $this->_where .= ' ' . $val;
706  continue;
707  }
708  $this->_where .= '?,';
709  $this->_bindings[ ] = ( @get_magic_quotes_gpc( ) ) ? @stripslashes( $v ) : $v;
710  //$this->_where .= is_numeric( $v ) ? ( int ) $v . ',': $this->sanitize( $v ). ',';
711  }
712  $this->_where = substr( $this->_where , 0 , strlen( $this->_where ) - 1 );
713  $this->_where .= ') ';
714  return $this;
715  }
716  /**
717  * Creates a "where between" statement
718  */
719  protected function _buildBetweenClause( $column , $start , $end , $type = 'between' )
720  {
721  $needle = ( false !== strpos( $type , '_not' ) ) ? ' NOT BETWEEN ' : ' BETWEEN ';
722  $type = str_replace( '_not' , ' ' , $type );
723  $type = strtoupper( $type );
724  $type = str_replace( '_BETWEEN' , $this->addBackTicks( $column ) . $needle , $type );
725  $this->_where .= $type . ' ';
726  if ( $val = $this->_checkRawValue( $start ) ){ $this->_where .= ' ' . $val; }
727  else
728  {
729  $this->_where .= ' ? ';
730  $this->_bindings[ ] = ( get_magic_quotes_gpc( ) ) ? stripslashes( $start ) : $start;
731  }
732  $this->_where .= ' AND ';
733  if ( $val = $this->_checkRawValue( $end ) ){ $this->_where .= ' ' . $val; }
734  else
735  {
736  $this->_where .= ' ? ';
737  $this->_bindings[ ] = ( get_magic_quotes_gpc( ) ) ? stripslashes( $end ) : $end;
738  }
739  return $this;
740  }
741  /**
742  * Checks if a rwa value was added
743  */
744  protected function _checkRawValue( $value )
745  {
746  if ( preg_match( '|' . $this->_randomId . 'RAW{(.*?)}|', $value , $matches ) )
747  {
748  return $matches[ 1 ];
749  }
750  return false;
751  }
752  /**
753  *
754  */
755  protected function _checkOperator( $operator )
756  {
757  if ( !in_array( strtolower( $operator ) , $this->_operators ) )
758  {
759  trigger_error( 'Invalid query operator "' . $operator . '"!' , E_USER_ERROR );
760  return false;
761  }
762  return true;
763  }
764  /**
765  * Runs closures for "where" and "joins"
766  */
767  protected function _runClosure( Closure $function , $type )
768  {
769  $this->_isClosure = true;
770  if ( 'join' === $type ){ return call_user_func_array( $function , array( $this ) ); }
771  $this->_where .= ' ' . strtoupper( str_replace( '_' , ' ' , strtolower( $type ) ) );
772  $this->_where .= ' ( ';
773  call_user_func_array( $function , array( $this ) );
774  $this->_where .= ' ) ';
775  $this->_isClosure = false;
776  }
777  /**
778  * Checks if Pdo object was passed to the constructor to run queries
779  */
780  protected function _checkPdo( )
781  {
782  if( !$this->_pdo )
783  {
784  trigger_error( 'Pdo was not set to execute queries with query builder!' ,
785  E_USER_ERROR );
786  return false;
787  }
788  return true;
789  }
790  /**
791  * Checks if a table was set
792  */
793  protected function _isTableSet( )
794  {
795  if ( !$this->_table )
796  {
797  trigger_error( 'No table set for query, use table( )!' , E_USER_ERROR );
798  return false;
799  }
800  return true;
801  }
802  /**
803  * Generates a random numeric string to secure the raw function
804  */
805  protected function _generateRandomId( )
806  {
807  return mt_rand( 1000000 , 9999999 ) . '_';
808  }
809  /**
810  * Fires "ptc.query" event if PtcEvent class is present. See @ref query_event
811  */
812  protected function _fireEvent( $data )
813  {
814  if ( !class_exists( $event_class = $this->_getEventClass( ) ) ){ return; }
815  $listeners = $event_class::getEvents( 'ptc' );
816  if ( @$listeners[ 'query' ] ){ $event_class::fire( 'ptc.query' , $data ); }
817  }
818  /**
819  * Retrieves the event class names and it's namespace
820  * @return the event class name defined in the "$_eventclass" property and the namespace
821  */
822  protected function _getEventClass( )
823  {
824  return __NAMESPACE__ . $this->_eventClass;
825  }
826  /**
827  * Send messsages to the PtcDebug class if present
828  * @param mixed $string the string to pass
829  * @param mixed $statement some statement if required
830  * @param string $category a category for the messages panel
831  */
832  protected static function _debug( $string , $statement = null , $category = 'QueryBuilder' )
833  {
834  if ( !defined( '_PTCDEBUG_NAMESPACE_' ) ){ return false; }
835  return @call_user_func_array( array( _PTCDEBUG_NAMESPACE_ , 'bufferSql' ) ,
836  array( $string , $statement , $category ) );
837  }
838  /**
839  * Sends queries to the Debugger & Logger if present
840  */
841  protected function _debugQuery( $string , $data )
842  {
843  $indexed=$data==array_values( $data );
844  foreach ( $data as $k => $v )
845  {
846  $v = ( is_string( $v ) ) ? "'$v'" : $v;
847  if ( $indexed ){ $string = preg_replace( '/\?/' , $v , $string , 1 ); }
848  else{ $string = preg_replace( '/' . $k . '/' , $v , $string , 1 ); }
849  }
850  return $string;
851  }
852  /**
853  * Adds execution time and query results to the PtcDebug class
854  * @param string $reference a reference to look for ("$statement")
855  * @param string $type the type of debug (timer, attach)
856  * @param mixed $string the string to pass
857  * @param mixed $statement some new statement if required
858  */
859  protected static function _debugBuffer( $reference , $type = null , $string = null , $statement = null )
860  {
861  if ( !defined( '_PTCDEBUG_NAMESPACE_' ) ){ return false; }
862  if ( $type == 'attach' )
863  {
864  return @call_user_func_array( array( '\\' . _PTCDEBUG_NAMESPACE_ ,
865  'addToBuffer' ) , array( $reference , $string , $statement ) );
866  }
867  else
868  {
869  return @call_user_func_array( array( '\\' .
870  _PTCDEBUG_NAMESPACE_ , 'stopTimer' ) , array( $reference ) );
871  }
872  }
873  }
sanitize($value)
Sanitize unsafe data.
setFetchMode($mode, $class=null)
Sets fetch mode for the next query.
on($column, $operator, $value, $type= 'and')
Joins columns based on values.
$_where
Where property for the query.
_checkPdo()
Checks if Pdo object was passed to the constructor to run queries.
$_join
Join Property.
$_isClosure
Property that checks if class is running a closure.
__call($method, $args)
Adds where operators and joins to the query.
$_limit
Limit property for the query.
$_returnStatements
Queries that need a return result propeerty.
_runClosure(Closure $function, $type)
Runs closures for &quot;where&quot; and &quot;joins&quot;.
_generateRandomId()
Generates a random numeric string to secure the raw function.
lastId()
Retrieves last inserted id.
_debugQuery($string, $data)
Sends queries to the Debugger &amp; Logger if present.
$_columns
Columns property for the query.
$_lastQuery
Last query property.
prepare()
Builds the query and returns it as string with place holders.
addBackTicks($string)
Adds backticks to the passed string.
_checkOperator($operator)
$_bindLimit
Limit property for the query.
$_eventClass
Event class name property.
_executeSql($mode=1)
Executes sql queries.
_addAndOR($value)
adds &quot;and&quot; or &quot;or&quot; to the query
_buildBetweenClause($column, $start, $end, $type= 'between')
Creates a &quot;where between&quot; statement.
_isTableSet()
Checks if a table was set.
$_orderBy
Order by property for the query.
$_currentQuery
Current query property.
_fireEvent($data)
Fires &quot;ptc.query&quot; event if PtcEvent class is present.
order($column, $direction= 'asc')
Adds order to the query.
find($id)
returns 1 record from a given table based on the id.
select($columns)
Sets the columns to be selected.
run($query=null, $bind=null, $type=null)
Runs queries if pdo object is present.
_buildQuery()
Builds the query based on the type.
__construct(PDO $pdo=null)
Adds the pdo instance to the query builder object.
_getEventClass()
Retrieves the event class names and it&#39;s namespace.
rawSelect($rawClause)
Adds A raw where clause to the query.
$_fetchMode
Fecth mode pdo property for current query.
limit($start, $results=null)
Adds limit to the query.
$_bindings
Place holders property.
group($column)
Adds group by to the query.
_buildWhereClause($type, $column, $operator=null, $value=null)
Builds the where clause.
$_operators
Operator for where and join clauses property.
$_table
Table property for the query.
update($array, $id=null)
Updates records in a given table based on a where clause.
_buildInClause($column, $array, $type= 'in')
Creates a &quot;where in&quot; statement.
$_randomId
Random Id property for raw values.
row($column=null)
Retrieves 1 row from a given table.
static _debugBuffer($reference, $type=null, $string=null, $statement=null)
Adds execution time and query results to the PtcDebug class.
countRows()
Returns number of affected rows from last query.
_bind($pos, $value, $type=null)
Binds values to the query.
$_currentQueryType
Current query type property.
insert($array)
Inserts a record in a given table.
$_query
Prepared query property.
$_values
Bind values property.
table($table)
Adds tables to the query.
$_pdo
Pdo object prperty to run queries.
raw($value)
Adds a raw value to a where clause in the query.
reset()
Resets the query parameters.
static _debug($string, $statement=null, $category= 'QueryBuilder')
Send messsages to the PtcDebug class if present.
join($table, $first, $operator=null, $second=null, $type= 'inner')
Creates a join based on the parameters.
where($column, $operator=null, $value=null, $type= 'and')
Adds where clouses to the query.
_checkRawValue($value)
Checks if a rwa value was added.
$_groupBy
Group by property for the query.