82fd42fe28d04096ad4707d34d22ac7302c10aec
[civicrm-core.git] / Civi / Api4 / Generic / AbstractQueryAction.php
1 <?php
2
3 namespace Civi\Api4\Generic;
4
5 /**
6 * Base class for all actions that need to fetch records (Get, Update, Delete, etc)
7 *
8 * @package Civi\Api4\Generic
9 *
10 * @method $this setWhere(array $wheres)
11 * @method array getWhere()
12 * @method $this setOrderBy(array $order)
13 * @method array getOrderBy()
14 * @method $this setLimit(int $limit)
15 * @method int getLimit()
16 * @method $this setOffset(int $offset)
17 * @method int getOffset()
18 */
19 abstract class AbstractQueryAction extends AbstractAction {
20
21 /**
22 * Criteria for selecting items.
23 *
24 * $example->addWhere('contact_type', 'IN', array('Individual', 'Household'))
25 *
26 * @var array
27 */
28 protected $where = [];
29
30 /**
31 * Array of field(s) to use in ordering the results
32 *
33 * Defaults to id ASC
34 *
35 * $example->addOrderBy('sort_name', 'ASC')
36 *
37 * @var array
38 */
39 protected $orderBy = [];
40
41 /**
42 * Maximum number of results to return.
43 *
44 * Defaults to unlimited.
45 *
46 * Note: the Api Explorer sets this to 25 by default to avoid timeouts.
47 * Change or remove this default for your application code.
48 *
49 * @var int
50 */
51 protected $limit = 0;
52
53 /**
54 * Zero-based index of first result to return.
55 *
56 * Defaults to "0" - first record.
57 *
58 * @var int
59 */
60 protected $offset = 0;
61
62 /**
63 * @param string $field
64 * @param string $op
65 * @param mixed $value
66 * @return $this
67 * @throws \API_Exception
68 */
69 public function addWhere($field, $op, $value = NULL) {
70 if (!in_array($op, \CRM_Core_DAO::acceptedSQLOperators())) {
71 throw new \API_Exception('Unsupported operator');
72 }
73 $this->where[] = [$field, $op, $value];
74 return $this;
75 }
76
77 /**
78 * Adds one or more AND/OR/NOT clause groups
79 *
80 * @param string $operator
81 * @param mixed $condition1 ... $conditionN
82 * Either a nested array of arguments, or a variable number of arguments passed to this function.
83 *
84 * @return $this
85 * @throws \API_Exception
86 */
87 public function addClause($operator, $condition1) {
88 if (!is_array($condition1[0])) {
89 $condition1 = array_slice(func_get_args(), 1);
90 }
91 $this->where[] = [$operator, $condition1];
92 return $this;
93 }
94
95 /**
96 * @param string $field
97 * @param string $direction
98 * @return $this
99 */
100 public function addOrderBy($field, $direction = 'ASC') {
101 $this->orderBy[$field] = $direction;
102 return $this;
103 }
104
105 /**
106 * A human-readable where clause, for the reading enjoyment of you humans.
107 *
108 * @param array $whereClause
109 * @param string $op
110 * @return string
111 */
112 protected function whereClauseToString($whereClause = NULL, $op = 'AND') {
113 if ($whereClause === NULL) {
114 $whereClause = $this->where;
115 }
116 $output = '';
117 if (!is_array($whereClause) || !$whereClause) {
118 return $output;
119 }
120 if (in_array($whereClause[0], ['AND', 'OR', 'NOT'])) {
121 $op = array_shift($whereClause);
122 if ($op == 'NOT') {
123 $output = 'NOT ';
124 $op = 'AND';
125 }
126 return $output . '(' . $this->whereClauseToString($whereClause, $op) . ')';
127 }
128 elseif (isset($whereClause[1]) && in_array($whereClause[1], \CRM_Core_DAO::acceptedSQLOperators())) {
129 $output = $whereClause[0] . ' ' . $whereClause[1] . ' ';
130 if (isset($whereClause[2])) {
131 $output .= is_array($whereClause[2]) ? '[' . implode(', ', $whereClause[2]) . ']' : $whereClause[2];
132 }
133 }
134 else {
135 $clauses = [];
136 foreach (array_filter($whereClause) as $clause) {
137 $clauses[] = $this->whereClauseToString($clause, $op);
138 }
139 $output = implode(" $op ", $clauses);
140 }
141 return $output;
142 }
143
144 }