PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 3.6.40
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v3.6.40
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Services / wpfluent / src / QueryBuilder / QueryBuilderHandler.php

QueryBuilderHandler.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 3.6.40, at app/Services/wpfluent/src/QueryBuilder/QueryBuilderHandler.php

1,155 lines 26.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php namespace WpFluent\QueryBuilder;
2
3 use WpFluent\Connection;
4 use WpFluent\Exception;
5
6 class QueryBuilderHandler
7 {
8
9 /**
10 * @var \Viocon\Container
11 */
12 protected $container;
13
14 /**
15 * @var Connection
16 */
17 protected $connection;
18
19 /**
20 * @var array
21 */
22 protected $statements = array();
23
24 /**
25 * @var \wpdb
26 */
27 protected $db;
28
29 /**
30 * @var null|string
31 */
32 protected $dbStatement = null;
33
34 /**
35 * @var null|string
36 */
37 protected $tablePrefix = null;
38
39 /**
40 * @var \WpFluent\QueryBuilder\Adapters\BaseAdapter
41 */
42 protected $adapterInstance;
43
44 /**
45 * The PDO fetch parameters to use
46 *
47 * @var array
48 */
49 protected $fetchParameters = array(\PDO::FETCH_OBJ);
50
51 /**
52 * @param null|\WpFluent\Connection $connection
53 *
54 * @throws \WpFluent\Exception
55 */
56 public function __construct(Connection $connection = null)
57 {
58 if (is_null($connection)) {
59 if (! $connection = Connection::getStoredConnection()) {
60 throw new Exception('No database connection found.', 1);
61 }
62 }
63
64 $this->connection = $connection;
65 $this->container = $this->connection->getContainer();
66 $this->db = $this->connection->getDbInstance();
67 $this->adapter = $this->connection->getAdapter();
68 $this->adapterConfig = $this->connection->getAdapterConfig();
69
70 if (isset($this->adapterConfig['prefix'])) {
71 $this->tablePrefix = $this->adapterConfig['prefix'];
72 }
73
74 // Query builder adapter instance
75 $this->adapterInstance = $this->container->build(
76 '\\WpFluent\\QueryBuilder\\Adapters\\' . ucfirst($this->adapter),
77 array($this->connection)
78 );
79 }
80
81 /**
82 * Set the fetch mode
83 *
84 * @param $mode
85 * @return $this
86 */
87 public function setFetchMode($mode)
88 {
89 $this->fetchParameters = func_get_args();
90
91 return $this;
92 }
93
94 /**
95 * Fetch query results as object of specified type
96 *
97 * @param $className
98 * @param array $constructorArgs
99 * @return QueryBuilderHandler
100 */
101 public function asObject($className, $constructorArgs = array())
102 {
103 var_dump('need to implement this'); die();
104
105 return $this->setFetchMode(\PDO::FETCH_CLASS, $className, $constructorArgs);
106 }
107
108 /**
109 * @param null|\WpFluent\Connection $connection
110 *
111 * @return static
112 */
113 public function newQuery(Connection $connection = null)
114 {
115 if (is_null($connection)) {
116 $connection = $this->connection;
117 }
118
119 return new static($connection);
120 }
121
122 /**
123 * @param $sql
124 * @param array $bindings
125 *
126 * @return $this
127 */
128 public function query($sql, $bindings = array())
129 {
130 $this->dbStatement = $this->container->build(
131 '\\WpFluent\\QueryBuilder\\QueryObject',
132 array($sql, $bindings)
133 )->getRawSql();
134
135 return $this;
136 }
137
138 /**
139 * @param $rawSql
140 *
141 * @return float execution time
142 */
143 public function statement($rawSql)
144 {
145 $start = microtime(true);
146
147 $this->db->query($rawSql);
148
149 return microtime(true) - $start;
150 }
151
152 /**
153 * Get all rows
154 *
155 * @return array|object|null
156 * @throws \WpFluent\Exception
157 */
158 public function get()
159 {
160 $eventResult = $this->fireEvents('before-select');
161
162 if (! is_null($eventResult)) {
163 return $eventResult;
164 };
165
166 if (is_null($this->dbStatement)) {
167 $queryObject = $this->getQuery('select');
168
169 $this->dbStatement = $queryObject->getRawSql();
170 }
171
172 $start = microtime(true);
173 $result = $this->db->get_results($this->dbStatement);
174 $executionTime = microtime(true) - $start;
175 $this->dbStatement = null;
176 $this->fireEvents('after-select', $result, $executionTime);
177
178 return $result;
179 }
180
181 /**
182 * Get first row
183 *
184 * @return \stdClass|null
185 */
186 public function first()
187 {
188 $this->limit(1);
189 $result = $this->get();
190
191 return empty($result) ? null : $result[0];
192 }
193
194 /**
195 * @param $value
196 * @param string $fieldName
197 *
198 * @return null|\stdClass
199 */
200 public function findAll($fieldName, $value)
201 {
202 $this->where($fieldName, '=', $value);
203
204 return $this->get();
205 }
206
207 /**
208 * @param $value
209 * @param string $fieldName
210 *
211 * @return null|\stdClass
212 */
213 public function find($value, $fieldName = 'id')
214 {
215 $this->where($fieldName, '=', $value);
216
217 return $this->first();
218 }
219
220 /**
221 * Get count of rows
222 *
223 * @return int
224 */
225 public function count()
226 {
227 // Get the current statements
228 $originalStatements = $this->statements;
229
230 unset($this->statements['orderBys']);
231 unset($this->statements['limit']);
232 unset($this->statements['offset']);
233
234 $count = $this->aggregate('count');
235 $this->statements = $originalStatements;
236
237 return $count;
238 }
239
240 /**
241 * @param $type
242 *
243 * @return int
244 */
245 protected function aggregate($type)
246 {
247 // Get the current selects
248 $mainSelects = isset($this->statements['selects']) ? $this->statements['selects'] : null;
249 // Replace select with a scalar value like `count`
250 $this->statements['selects'] = array($this->raw($type . '(*) as field'));
251 $row = $this->get();
252
253 // Set the select as it was
254 if ($mainSelects) {
255 $this->statements['selects'] = $mainSelects;
256 } else {
257 unset($this->statements['selects']);
258 }
259
260 if (($count = count($row)) > 1) {
261 return $count;
262 } else {
263 $item = (array) $row[0];
264
265 return (int) $item['field'];
266 }
267 }
268
269 /**
270 * @param string $type
271 * @param array $dataToBePassed
272 *
273 * @return mixed
274 * @throws Exception
275 */
276 public function getQuery($type = 'select', $dataToBePassed = array())
277 {
278 $allowedTypes = array('select', 'insert', 'insertignore', 'replace', 'delete', 'update', 'criteriaonly');
279
280 if (! in_array(strtolower($type), $allowedTypes)) {
281 throw new Exception($type . ' is not a known type.', 2);
282 }
283
284 $queryArr = $this->adapterInstance->$type($this->statements, $dataToBePassed);
285
286 return $this->container->build(
287 '\\WpFluent\\QueryBuilder\\QueryObject',
288 array($queryArr['sql'], $queryArr['bindings'])
289 );
290 }
291
292 /**
293 * @param QueryBuilderHandler $queryBuilder
294 * @param null $alias
295 *
296 * @return Raw
297 */
298 public function subQuery(QueryBuilderHandler $queryBuilder, $alias = null)
299 {
300 $sql = '(' . $queryBuilder->getQuery()->getRawSql() . ')';
301
302 if ($alias) {
303 $sql = $sql . ' as ' . $alias;
304 }
305
306 return $queryBuilder->raw($sql);
307 }
308
309 /**
310 * @param $data
311 *
312 * @return array|string
313 * @throws \WpFluent\Exception
314 */
315 private function doInsert($data, $type)
316 {
317 $eventResult = $this->fireEvents('before-insert');
318
319 if (! is_null($eventResult)) {
320 return $eventResult;
321 }
322
323 // If first value is not an array
324 // Its not a batch insert
325 if (! is_array(current($data))) {
326 $start = microtime(true);
327
328 $queryObject = $this->getQuery($type, $data);
329
330 $executionTime = $this->statement($queryObject->getRawSql());
331
332 $return = $this->db->insert_id;
333 } else {
334 // Its a batch insert
335 $executionTime = 0;
336 $return = array();
337 foreach ($data as $subData) {
338 $start = microtime(true);
339
340 $queryObject = $this->getQuery($type, $subData);
341
342 $executionTime = $this->statement($queryObject->getRawSql());
343
344 $return[] = $this->db->insert_id;
345 }
346 }
347
348 $this->fireEvents('after-insert', $return, $executionTime);
349
350 return $return;
351 }
352
353 /**
354 * @param $data
355 *
356 * @return array|string
357 */
358 public function insert($data)
359 {
360 return $this->doInsert($data, 'insert');
361 }
362
363 /**
364 * @param $data
365 *
366 * @return array|string
367 */
368 public function insertIgnore($data)
369 {
370 return $this->doInsert($data, 'insertignore');
371 }
372
373 /**
374 * @param $data
375 *
376 * @return array|string
377 */
378 public function replace($data)
379 {
380 return $this->doInsert($data, 'replace');
381 }
382
383 /**
384 * @param $data
385 *
386 * @throws \WpFluent\Exception
387 */
388 public function update($data)
389 {
390 $eventResult = $this->fireEvents('before-update');
391
392 if (! is_null($eventResult)) {
393 return $eventResult;
394 }
395
396 $queryObject = $this->getQuery('update', $data);
397
398 $executionTime = $this->statement($queryObject->getRawSql());
399
400 $this->fireEvents('after-update', $queryObject, $executionTime);
401 }
402
403 /**
404 * @param $data
405 *
406 * @return array|string
407 */
408 public function updateOrInsert($data)
409 {
410 if ($this->first()) {
411 return $this->update($data);
412 } else {
413 return $this->insert($data);
414 }
415 }
416
417 /**
418 * @param $data
419 *
420 * @return $this
421 */
422 public function onDuplicateKeyUpdate($data)
423 {
424 $this->addStatement('onduplicate', $data);
425
426 return $this;
427 }
428
429 /**
430 * @return mixed
431 * @throws \WpFluent\Exception
432 */
433 public function delete()
434 {
435 $eventResult = $this->fireEvents('before-delete');
436
437 if (! is_null($eventResult)) {
438 return $eventResult;
439 }
440
441 $queryObject = $this->getQuery('delete');
442
443 $executionTime = $this->statement($queryObject->getRawSql());
444
445 $this->fireEvents('after-delete', $queryObject, $executionTime);
446 }
447
448 /**
449 * @param string|array $tables Single table or multiple tables
450 * as an array or as multiple parameters
451 *
452 * @return static
453 */
454 public function table($tables)
455 {
456 if (! is_array($tables)) {
457 // because a single table is converted to an array anyways,
458 // this makes sense.
459 $tables = func_get_args();
460 }
461
462 $instance = new static($this->connection);
463 $tables = $this->addTablePrefix($tables, false);
464 $instance->addStatement('tables', $tables);
465
466 return $instance;
467 }
468
469 /**
470 * @param $tables
471 *
472 * @return $this
473 */
474 public function from($tables)
475 {
476 if (! is_array($tables)) {
477 $tables = func_get_args();
478 }
479
480 $tables = $this->addTablePrefix($tables, false);
481 $this->addStatement('tables', $tables);
482
483 return $this;
484 }
485
486 /**
487 * @param $fields
488 *
489 * @return $this
490 */
491 public function select($fields)
492 {
493 if (! is_array($fields)) {
494 $fields = func_get_args();
495 }
496
497 $fields = $this->addTablePrefix($fields);
498 $this->addStatement('selects', $fields);
499
500 return $this;
501 }
502
503 /**
504 * @param $fields
505 *
506 * @return $this
507 */
508 public function selectDistinct($fields)
509 {
510 $this->select($fields);
511 $this->addStatement('distinct', true);
512
513 return $this;
514 }
515
516 /**
517 * @param $field
518 *
519 * @return $this
520 */
521 public function groupBy($field)
522 {
523 $field = $this->addTablePrefix($field);
524 $this->addStatement('groupBys', $field);
525
526 return $this;
527 }
528
529 /**
530 * @param $fields
531 * @param string $defaultDirection
532 *
533 * @return $this
534 */
535 public function orderBy($fields, $defaultDirection = 'ASC')
536 {
537 if (! is_array($fields)) {
538 $fields = array($fields);
539 }
540
541 foreach ($fields as $key => $value) {
542 $field = $key;
543 $type = $value;
544
545 if (is_int($key)) {
546 $field = $value;
547 $type = $defaultDirection;
548 }
549
550 if (!$field instanceof Raw) {
551 $field = $this->addTablePrefix($field);
552 }
553
554 $this->statements['orderBys'][] = compact('field', 'type');
555 }
556
557 return $this;
558 }
559
560 /**
561 * @param $limit
562 *
563 * @return $this
564 */
565 public function limit($limit)
566 {
567 $this->statements['limit'] = $limit;
568
569 return $this;
570 }
571
572 /**
573 * @param $offset
574 *
575 * @return $this
576 */
577 public function offset($offset)
578 {
579 $this->statements['offset'] = $offset;
580
581 return $this;
582 }
583
584 /**
585 * @param $key
586 * @param $operator
587 * @param $value
588 * @param string $joiner
589 *
590 * @return $this
591 */
592 public function having($key, $operator = null, $value = null, $joiner = 'AND')
593 {
594 $key = $this->addTablePrefix($key);
595 $this->statements['havings'][] = compact('key', 'operator', 'value', 'joiner');
596
597 return $this;
598 }
599
600 /**
601 * @param $key
602 * @param $operator
603 * @param $value
604 *
605 * @return $this
606 */
607 public function orHaving($key, $operator, $value)
608 {
609 return $this->having($key, $operator, $value, 'OR');
610 }
611
612 /**
613 * @param $key
614 * @param $operator
615 * @param $value
616 *
617 * @return $this
618 */
619 public function where($key, $operator = null, $value = null)
620 {
621 // If two params are given then assume operator is =
622 if (func_num_args() == 2) {
623 $value = $operator;
624 $operator = '=';
625 }
626
627 return $this->whereHandler($key, $operator, $value);
628 }
629
630 /**
631 * @param $key
632 * @param $operator
633 * @param $value
634 *
635 * @return $this
636 */
637 public function orWhere($key, $operator = null, $value = null)
638 {
639 // If two params are given then assume operator is =
640 if (func_num_args() == 2) {
641 $value = $operator;
642 $operator = '=';
643 }
644
645 return $this->whereHandler($key, $operator, $value, 'OR');
646 }
647
648 /**
649 * @param $key
650 * @param $operator
651 * @param $value
652 *
653 * @return $this
654 */
655 public function whereNot($key, $operator = null, $value = null)
656 {
657 // If two params are given then assume operator is =
658 if (func_num_args() == 2) {
659 $value = $operator;
660 $operator = '=';
661 }
662
663 return $this->whereHandler($key, $operator, $value, 'AND NOT');
664 }
665
666 /**
667 * @param $key
668 * @param $operator
669 * @param $value
670 *
671 * @return $this
672 */
673 public function orWhereNot($key, $operator = null, $value = null)
674 {
675 // If two params are given then assume operator is =
676 if (func_num_args() == 2) {
677 $value = $operator;
678 $operator = '=';
679 }
680
681 return $this->whereHandler($key, $operator, $value, 'OR NOT');
682 }
683
684 /**
685 * @param $key
686 * @param array $values
687 *
688 * @return $this
689 */
690 public function whereIn($key, $values)
691 {
692 return $this->whereHandler($key, 'IN', $values, 'AND');
693 }
694
695 /**
696 * @param $key
697 * @param array $values
698 *
699 * @return $this
700 */
701 public function whereNotIn($key, $values)
702 {
703 return $this->whereHandler($key, 'NOT IN', $values, 'AND');
704 }
705
706 /**
707 * @param $key
708 * @param array $values
709 *
710 * @return $this
711 */
712 public function orWhereIn($key, $values)
713 {
714 return $this->whereHandler($key, 'IN', $values, 'OR');
715 }
716
717 /**
718 * @param $key
719 * @param array $values
720 *
721 * @return $this
722 */
723 public function orWhereNotIn($key, $values)
724 {
725 return $this->whereHandler($key, 'NOT IN', $values, 'OR');
726 }
727
728 /**
729 * @param $key
730 * @param $valueFrom
731 * @param $valueTo
732 *
733 * @return $this
734 */
735 public function whereBetween($key, $valueFrom, $valueTo)
736 {
737 return $this->whereHandler($key, 'BETWEEN', array($valueFrom, $valueTo), 'AND');
738 }
739
740 /**
741 * @param $key
742 * @param $valueFrom
743 * @param $valueTo
744 *
745 * @return $this
746 */
747 public function orWhereBetween($key, $valueFrom, $valueTo)
748 {
749 return $this->whereHandler($key, 'BETWEEN', array($valueFrom, $valueTo), 'OR');
750 }
751
752 /**
753 * @param $key
754 * @return QueryBuilderHandler
755 */
756 public function whereNull($key)
757 {
758 return $this->whereNullHandler($key);
759 }
760
761 /**
762 * @param $key
763 * @return QueryBuilderHandler
764 */
765 public function whereNotNull($key)
766 {
767 return $this->whereNullHandler($key, 'NOT');
768 }
769
770 /**
771 * @param $key
772 * @return QueryBuilderHandler
773 */
774 public function orWhereNull($key)
775 {
776 return $this->whereNullHandler($key, '', 'or');
777 }
778
779 /**
780 * @param $key
781 * @return QueryBuilderHandler
782 */
783 public function orWhereNotNull($key)
784 {
785 return $this->whereNullHandler($key, 'NOT', 'or');
786 }
787
788 protected function whereNullHandler($key, $prefix = '', $operator = '')
789 {
790 $key = $this->adapterInstance->wrapSanitizer($this->addTablePrefix($key));
791
792 return $this->{$operator . 'Where'}($this->raw("{$key} IS {$prefix} NULL"));
793 }
794
795 /**
796 * @param $table
797 * @param $key
798 * @param $operator
799 * @param $value
800 * @param string $type
801 *
802 * @return $this
803 */
804 public function join($table, $key, $operator = null, $value = null, $type = 'inner')
805 {
806 if (! $key instanceof \Closure) {
807 $key = function ($joinBuilder) use ($key, $operator, $value) {
808 $joinBuilder->on($key, $operator, $value);
809 };
810 }
811
812 // Build a new JoinBuilder class, keep it by reference so any changes made
813 // in the closure should reflect here
814 $joinBuilder = $this->container->build('\\WpFluent\\QueryBuilder\\JoinBuilder', array($this->connection));
815 $joinBuilder = & $joinBuilder;
816 // Call the closure with our new joinBuilder object
817 $key($joinBuilder);
818 $table = $this->addTablePrefix($table, false);
819 // Get the criteria only query from the joinBuilder object
820 $this->statements['joins'][] = compact('type', 'table', 'joinBuilder');
821
822 return $this;
823 }
824
825 /**
826 * Runs a transaction
827 *
828 * @param $callback
829 *
830 * @return $this
831 */
832 public function transaction(\Closure $callback)
833 {
834 try {
835 // Begin the PDO transaction
836 $this->db->query('START TRANSACTION');
837
838 // Get the Transaction class
839 $transaction = $this->container->build(
840 '\\WpFluent\\QueryBuilder\\Transaction',
841 array($this->connection)
842 );
843
844 // Call closure
845 $callback($transaction);
846
847 // If no errors have been thrown or the transaction wasn't completed within
848 // the closure, commit the changes
849 $this->db->query('COMMIT');
850
851 return $this;
852 } catch (TransactionHaltException $e) {
853 // Commit or rollback behavior has been handled in the closure, so exit
854 return $this;
855 } catch (\Exception $e) {
856 // something happened, rollback changes
857 $this->db->query('ROLLBACK');
858
859 return $this;
860 }
861 }
862
863 /**
864 * @param $table
865 * @param $key
866 * @param null $operator
867 * @param null $value
868 *
869 * @return $this
870 */
871 public function leftJoin($table, $key, $operator = null, $value = null)
872 {
873 return $this->join($table, $key, $operator, $value, 'left');
874 }
875
876 /**
877 * @param $table
878 * @param $key
879 * @param null $operator
880 * @param null $value
881 *
882 * @return $this
883 */
884 public function rightJoin($table, $key, $operator = null, $value = null)
885 {
886 return $this->join($table, $key, $operator, $value, 'right');
887 }
888
889 /**
890 * @param $table
891 * @param $key
892 * @param null $operator
893 * @param null $value
894 *
895 * @return $this
896 */
897 public function innerJoin($table, $key, $operator = null, $value = null)
898 {
899 return $this->join($table, $key, $operator, $value, 'inner');
900 }
901
902 /**
903 * Add a raw query
904 *
905 * @param $value
906 * @param $bindings
907 *
908 * @return mixed
909 */
910 public function raw($value, $bindings = array())
911 {
912 return $this->container->build('\\WpFluent\\QueryBuilder\\Raw', array($value, $bindings));
913 }
914
915 /**
916 * Return db instance
917 *
918 * @return \wpdb
919 */
920 public function db()
921 {
922 return $this->db;
923 }
924
925 /**
926 * @param Connection $connection
927 *
928 * @return $this
929 */
930 public function setConnection(Connection $connection)
931 {
932 $this->connection = $connection;
933
934 return $this;
935 }
936
937 /**
938 * @return Connection
939 */
940 public function getConnection()
941 {
942 return $this->connection;
943 }
944
945 /**
946 * @param $key
947 * @param $operator
948 * @param $value
949 * @param string $joiner
950 *
951 * @return $this
952 */
953 protected function whereHandler($key, $operator = null, $value = null, $joiner = 'AND')
954 {
955 $key = $this->addTablePrefix($key);
956 $this->statements['wheres'][] = compact('key', 'operator', 'value', 'joiner');
957
958 return $this;
959 }
960
961 /**
962 * Add table prefix (if given) on given string.
963 *
964 * @param $values
965 * @param bool $tableFieldMix If we have mixes of field and table names with a "."
966 *
967 * @return array|mixed
968 */
969 public function addTablePrefix($values, $tableFieldMix = true)
970 {
971 if (is_null($this->tablePrefix)) {
972 return $values;
973 }
974
975 // $value will be an array and we will add prefix to all table names
976
977 // If supplied value is not an array then make it one
978 $single = false;
979
980 if (! is_array($values)) {
981 $values = array($values);
982 // We had single value, so should return a single value
983 $single = true;
984 }
985
986 $return = array();
987
988 foreach ($values as $key => $value) {
989 // It's a raw query, just add it to our return array and continue next
990 if ($value instanceof Raw || $value instanceof \Closure) {
991 $return[$key] = $value;
992 continue;
993 }
994
995 // If key is not integer, it is likely a alias mapping,
996 // so we need to change prefix target
997 $target = &$value;
998 if (! is_int($key)) {
999 $target = &$key;
1000 }
1001
1002 if (! $tableFieldMix || ($tableFieldMix && strpos($target, '.') !== false)) {
1003 $target = $this->tablePrefix . $target;
1004 }
1005
1006 $return[$key] = $value;
1007 }
1008
1009 // If we had single value then we should return a single value (end value of the array)
1010 return $single ? end($return) : $return;
1011 }
1012
1013 /**
1014 * @param $key
1015 * @param $value
1016 */
1017 protected function addStatement($key, $value)
1018 {
1019 if (! is_array($value)) {
1020 $value = array($value);
1021 }
1022
1023 if (! array_key_exists($key, $this->statements)) {
1024 $this->statements[$key] = $value;
1025 } else {
1026 $this->statements[$key] = array_merge($this->statements[$key], $value);
1027 }
1028 }
1029
1030 /**
1031 * @param $event
1032 * @param $table
1033 *
1034 * @return callable|null
1035 */
1036 public function getEvent($event, $table = ':any')
1037 {
1038 return $this->connection->getEventHandler()->getEvent($event, $table);
1039 }
1040
1041 /**
1042 * @param $event
1043 * @param string $table
1044 * @param callable $action
1045 *
1046 * @return void
1047 */
1048 public function registerEvent($event, $table, \Closure $action)
1049 {
1050 $table = $table ?: ':any';
1051
1052 if ($table != ':any') {
1053 $table = $this->addTablePrefix($table, false);
1054 }
1055
1056 $this->connection->getEventHandler()->registerEvent($event, $table, $action);
1057 }
1058
1059 /**
1060 * @param $event
1061 * @param string $table
1062 *
1063 * @return void
1064 */
1065 public function removeEvent($event, $table = ':any')
1066 {
1067 if ($table != ':any') {
1068 $table = $this->addTablePrefix($table, false);
1069 }
1070
1071 $this->connection->getEventHandler()->removeEvent($event, $table);
1072 }
1073
1074 /**
1075 * @param $event
1076 * @return mixed
1077 */
1078 public function fireEvents($event)
1079 {
1080 $params = func_get_args();
1081 array_unshift($params, $this);
1082
1083 return call_user_func_array(
1084 array($this->connection->getEventHandler(), 'fireEvents'),
1085 $params
1086 );
1087 }
1088
1089 /**
1090 * @return array
1091 */
1092 public function getStatements()
1093 {
1094 return $this->statements;
1095 }
1096
1097 /**
1098 * Get the paginated rows.
1099 *
1100 * @param null $perPage
1101 * @param array $columns
1102 *
1103 * @return array
1104 */
1105 public function paginate($perPage = null, $columns = array('*'))
1106 {
1107 $currentPage = intval($_GET['page']) ?: 1;
1108
1109 $perPage = $perPage ?: intval($_REQUEST['per_page']) ?: 15;
1110
1111 $skip = $perPage * ($currentPage - 1);
1112
1113 $data = (array) $this->select($columns)->limit($perPage)->offset($skip)->get();
1114
1115 $dataCount = count($data);
1116
1117 $from = $dataCount > 0 ? ($currentPage - 1) * $perPage + 1 : null;
1118
1119 $to = $dataCount > 0 ? $from + $dataCount - 1 : null;
1120
1121 $total = $this->count();
1122
1123 $lastPage = (int) ceil($total / $perPage);
1124
1125 return array(
1126 'current_page' => $currentPage,
1127 'per_page' => $perPage,
1128 'from' => $from,
1129 'to' => $to,
1130 'last_page' => $lastPage,
1131 'total' => $total,
1132 'data' => $data,
1133 );
1134 }
1135
1136 /**
1137 * Apply the callback's query changes if the given "value" is true.
1138 *
1139 * @param mixed $value
1140 * @param callable $callback
1141 * @param callable $default
1142 * @return mixed
1143 */
1144 public function when($value, $callback, $default = null)
1145 {
1146 if ($value) {
1147 return $callback($this, $value) ?: $this;
1148 } elseif ($default) {
1149 return $default($this, $value) ?: $this;
1150 }
1151
1152 return $this;
1153 }
1154 }
1155