Commit | Line | Data |
---|---|---|
19b53e5b C |
1 | <?php |
2 | ||
380f3545 TO |
3 | /* |
4 | +--------------------------------------------------------------------+ | |
41498ac5 | 5 | | Copyright CiviCRM LLC. All rights reserved. | |
380f3545 | 6 | | | |
41498ac5 TO |
7 | | This work is published under the GNU AGPLv3 license with some | |
8 | | permitted exceptions and without any warranty. For full license | | |
9 | | and copyright information, see https://civicrm.org/licensing | | |
380f3545 TO |
10 | +--------------------------------------------------------------------+ |
11 | */ | |
12 | ||
19b53e5b C |
13 | namespace Civi\Api4\Generic; |
14 | ||
9d2afe25 CW |
15 | use Civi\Api4\Utils\CoreUtil; |
16 | ||
19b53e5b | 17 | /** |
fc95d9a5 | 18 | * Base class for all actions that need to fetch records (`Get`, `Update`, `Delete`, etc.). |
19b53e5b C |
19 | * |
20 | * @package Civi\Api4\Generic | |
21 | * | |
22 | * @method $this setWhere(array $wheres) | |
23 | * @method array getWhere() | |
24 | * @method $this setOrderBy(array $order) | |
25 | * @method array getOrderBy() | |
26 | * @method $this setLimit(int $limit) | |
27 | * @method int getLimit() | |
28 | * @method $this setOffset(int $offset) | |
29 | * @method int getOffset() | |
30 | */ | |
31 | abstract class AbstractQueryAction extends AbstractAction { | |
32 | ||
33 | /** | |
e3c6d5ff | 34 | * Criteria for selecting $ENTITIES. |
19b53e5b | 35 | * |
fc95d9a5 CW |
36 | * ```php |
37 | * $example->addWhere('contact_type', 'IN', ['Individual', 'Household']) | |
38 | * ``` | |
19b53e5b C |
39 | * @var array |
40 | */ | |
41 | protected $where = []; | |
42 | ||
43 | /** | |
fc95d9a5 | 44 | * Array of field(s) to use in ordering the results. |
19b53e5b C |
45 | * |
46 | * Defaults to id ASC | |
47 | * | |
fc95d9a5 | 48 | * ```php |
19b53e5b | 49 | * $example->addOrderBy('sort_name', 'ASC') |
fc95d9a5 | 50 | * ``` |
19b53e5b C |
51 | * @var array |
52 | */ | |
53 | protected $orderBy = []; | |
54 | ||
55 | /** | |
e3c6d5ff | 56 | * Maximum number of $ENTITIES to return. |
19b53e5b | 57 | * |
d71cde6c | 58 | * Defaults to `0` - unlimited. |
19b53e5b | 59 | * |
d71cde6c | 60 | * Note: the Api Explorer sets this to `25` by default to avoid timeouts. |
19b53e5b C |
61 | * Change or remove this default for your application code. |
62 | * | |
63 | * @var int | |
64 | */ | |
65 | protected $limit = 0; | |
66 | ||
67 | /** | |
fc95d9a5 | 68 | * Zero-based index of first $ENTITY to return. |
19b53e5b | 69 | * |
d71cde6c | 70 | * Defaults to `0` - first $ENTITY found. |
19b53e5b C |
71 | * |
72 | * @var int | |
73 | */ | |
74 | protected $offset = 0; | |
75 | ||
76 | /** | |
121ec912 | 77 | * @param string $fieldName |
19b53e5b C |
78 | * @param string $op |
79 | * @param mixed $value | |
80 | * @return $this | |
81 | * @throws \API_Exception | |
82 | */ | |
121ec912 | 83 | public function addWhere(string $fieldName, string $op, $value = NULL) { |
9d2afe25 | 84 | if (!in_array($op, CoreUtil::getOperators())) { |
19b53e5b C |
85 | throw new \API_Exception('Unsupported operator'); |
86 | } | |
121ec912 | 87 | $this->where[] = [$fieldName, $op, $value]; |
19b53e5b C |
88 | return $this; |
89 | } | |
90 | ||
91 | /** | |
92 | * Adds one or more AND/OR/NOT clause groups | |
93 | * | |
94 | * @param string $operator | |
95 | * @param mixed $condition1 ... $conditionN | |
96 | * Either a nested array of arguments, or a variable number of arguments passed to this function. | |
97 | * | |
98 | * @return $this | |
99 | * @throws \API_Exception | |
100 | */ | |
121ec912 | 101 | public function addClause(string $operator, $condition1) { |
19b53e5b C |
102 | if (!is_array($condition1[0])) { |
103 | $condition1 = array_slice(func_get_args(), 1); | |
104 | } | |
105 | $this->where[] = [$operator, $condition1]; | |
106 | return $this; | |
107 | } | |
108 | ||
109 | /** | |
121ec912 CW |
110 | * Adds to the orderBy clause |
111 | * @param string $fieldName | |
19b53e5b C |
112 | * @param string $direction |
113 | * @return $this | |
114 | */ | |
121ec912 CW |
115 | public function addOrderBy(string $fieldName, $direction = 'ASC') { |
116 | $this->orderBy[$fieldName] = $direction; | |
19b53e5b C |
117 | return $this; |
118 | } | |
119 | ||
120 | /** | |
121ec912 | 121 | * Produces a human-readable where clause, for the reading enjoyment of you humans. |
19b53e5b C |
122 | * |
123 | * @param array $whereClause | |
124 | * @param string $op | |
125 | * @return string | |
126 | */ | |
127 | protected function whereClauseToString($whereClause = NULL, $op = 'AND') { | |
128 | if ($whereClause === NULL) { | |
129 | $whereClause = $this->where; | |
130 | } | |
131 | $output = ''; | |
132 | if (!is_array($whereClause) || !$whereClause) { | |
133 | return $output; | |
134 | } | |
135 | if (in_array($whereClause[0], ['AND', 'OR', 'NOT'])) { | |
136 | $op = array_shift($whereClause); | |
137 | if ($op == 'NOT') { | |
138 | $output = 'NOT '; | |
139 | $op = 'AND'; | |
140 | } | |
141 | return $output . '(' . $this->whereClauseToString($whereClause, $op) . ')'; | |
142 | } | |
9d2afe25 | 143 | elseif (isset($whereClause[1]) && in_array($whereClause[1], CoreUtil::getOperators())) { |
19b53e5b C |
144 | $output = $whereClause[0] . ' ' . $whereClause[1] . ' '; |
145 | if (isset($whereClause[2])) { | |
146 | $output .= is_array($whereClause[2]) ? '[' . implode(', ', $whereClause[2]) . ']' : $whereClause[2]; | |
147 | } | |
148 | } | |
149 | else { | |
150 | $clauses = []; | |
151 | foreach (array_filter($whereClause) as $clause) { | |
152 | $clauses[] = $this->whereClauseToString($clause, $op); | |
153 | } | |
154 | $output = implode(" $op ", $clauses); | |
155 | } | |
156 | return $output; | |
157 | } | |
158 | ||
159 | } |