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 | ||
13 | /** | |
14 | * | |
15 | * @package CRM | |
ca5cec67 | 16 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
380f3545 TO |
17 | */ |
18 | ||
19 | ||
19b53e5b C |
20 | namespace Civi\Api4\Generic; |
21 | ||
3c7c8fa6 CW |
22 | use Civi\Api4\Query\Api4SelectQuery; |
23 | ||
19b53e5b | 24 | /** |
e3c6d5ff | 25 | * Retrieve $ENTITIES based on criteria specified in the `where` parameter. |
19b53e5b | 26 | * |
fc95d9a5 | 27 | * Use the `select` param to determine which fields are returned, defaults to `[*]`. |
19b53e5b C |
28 | * |
29 | * Perform joins on other related entities using a dot notation. | |
c9e3ae2e CW |
30 | * |
31 | * @method $this setHaving(array $clauses) | |
32 | * @method array getHaving() | |
19b53e5b C |
33 | */ |
34 | class DAOGetAction extends AbstractGetAction { | |
35 | use Traits\DAOActionTrait; | |
36 | ||
39e0f675 | 37 | /** |
2f69b203 CW |
38 | * Fields to return. Defaults to all non-custom fields `['*']`. |
39 | * | |
40 | * The keyword `"custom.*"` selects all custom fields. So to select all core + custom fields, select `['*', 'custom.*']`. | |
39e0f675 | 41 | * |
fc95d9a5 | 42 | * Use the dot notation to perform joins in the select clause, e.g. selecting `['*', 'contact.*']` from `Email::get()` |
39e0f675 CW |
43 | * will select all fields for the email + all fields for the related contact. |
44 | * | |
45 | * @var array | |
46 | * @inheritDoc | |
47 | */ | |
48 | protected $select = []; | |
49 | ||
16f5a13d CW |
50 | /** |
51 | * Joins to other entities. | |
52 | * | |
90908aac CW |
53 | * Each join is an array of properties: |
54 | * | |
55 | * ``` | |
56 | * [Entity, Required, Bridge, [field, op, value]...] | |
57 | * ``` | |
58 | * | |
59 | * - `Entity`: the name of the api entity to join onto. | |
60 | * - `Required`: `TRUE` for an `INNER JOIN`, `FALSE` for a `LEFT JOIN`. | |
61 | * - `Bridge` (optional): Name of a BridgeEntity to incorporate into the join. | |
62 | * - `[field, op, value]...`: zero or more conditions for the ON clause, using the same nested format as WHERE and HAVING | |
63 | * but with the difference that "value" is interpreted as an expression (e.g. can be the name of a field). | |
64 | * Enclose literal values with quotes. | |
65 | * | |
16f5a13d | 66 | * @var array |
90908aac | 67 | * @see \Civi\Api4\Generic\BridgeEntity |
16f5a13d CW |
68 | */ |
69 | protected $join = []; | |
70 | ||
f0acec37 CW |
71 | /** |
72 | * Field(s) by which to group the results. | |
73 | * | |
74 | * @var array | |
75 | */ | |
76 | protected $groupBy = []; | |
77 | ||
78 | /** | |
79 | * Clause for filtering results after grouping and filters are applied. | |
80 | * | |
81 | * Each expression should correspond to an item from the SELECT array. | |
82 | * | |
83 | * @var array | |
84 | */ | |
85 | protected $having = []; | |
86 | ||
19b53e5b | 87 | public function _run(Result $result) { |
06f83d5c CW |
88 | // Early return if table doesn't exist yet due to pending upgrade |
89 | $baoName = $this->getBaoName(); | |
90 | if (!$baoName::tableHasBeenAdded()) { | |
91 | return; | |
92 | } | |
93 | ||
19b53e5b | 94 | $this->setDefaultWhereClause(); |
39e0f675 | 95 | $this->expandSelectClauseWildcards(); |
651c4c95 | 96 | $this->getObjects($result); |
19b53e5b C |
97 | } |
98 | ||
3c7c8fa6 | 99 | /** |
651c4c95 | 100 | * @param \Civi\Api4\Generic\Result $result |
3c7c8fa6 | 101 | */ |
651c4c95 CW |
102 | protected function getObjects(Result $result) { |
103 | $getCount = in_array('row_count', $this->getSelect()); | |
104 | $onlyCount = $this->getSelect() === ['row_count']; | |
105 | ||
106 | if (!$onlyCount) { | |
107 | $query = new Api4SelectQuery($this); | |
108 | $rows = $query->run(); | |
109 | \CRM_Utils_API_HTMLInputCoder::singleton()->decodeRows($rows); | |
110 | $result->exchangeArray($rows); | |
111 | // No need to fetch count if we got a result set below the limit | |
112 | if (!$this->getLimit() || count($rows) < $this->getLimit()) { | |
113 | $result->rowCount = count($rows) + $this->getOffset(); | |
114 | $getCount = FALSE; | |
115 | } | |
116 | } | |
117 | if ($getCount) { | |
118 | $query = new Api4SelectQuery($this); | |
119 | $result->rowCount = $query->getCount(); | |
3c7c8fa6 | 120 | } |
3c7c8fa6 CW |
121 | } |
122 | ||
f0acec37 CW |
123 | /** |
124 | * @return array | |
125 | */ | |
126 | public function getGroupBy(): array { | |
127 | return $this->groupBy; | |
128 | } | |
129 | ||
130 | /** | |
131 | * @param array $groupBy | |
132 | * @return $this | |
133 | */ | |
134 | public function setGroupBy(array $groupBy) { | |
135 | $this->groupBy = $groupBy; | |
136 | return $this; | |
137 | } | |
138 | ||
139 | /** | |
140 | * @param string $field | |
141 | * @return $this | |
142 | */ | |
143 | public function addGroupBy(string $field) { | |
144 | $this->groupBy[] = $field; | |
145 | return $this; | |
146 | } | |
147 | ||
148 | /** | |
149 | * @param string $expr | |
150 | * @param string $op | |
151 | * @param mixed $value | |
152 | * @return $this | |
153 | * @throws \API_Exception | |
154 | */ | |
155 | public function addHaving(string $expr, string $op, $value = NULL) { | |
156 | if (!in_array($op, \CRM_Core_DAO::acceptedSQLOperators())) { | |
157 | throw new \API_Exception('Unsupported operator'); | |
158 | } | |
159 | $this->having[] = [$expr, $op, $value]; | |
160 | return $this; | |
161 | } | |
162 | ||
16f5a13d CW |
163 | /** |
164 | * @param string $entity | |
165 | * @param bool $required | |
90908aac | 166 | * @param string $bridge |
16f5a13d CW |
167 | * @param array ...$conditions |
168 | * @return DAOGetAction | |
169 | */ | |
90908aac CW |
170 | public function addJoin(string $entity, bool $required = FALSE, $bridge = NULL, ...$conditions): DAOGetAction { |
171 | if ($bridge) { | |
172 | array_unshift($conditions, $bridge); | |
173 | } | |
16f5a13d CW |
174 | array_unshift($conditions, $entity, $required); |
175 | $this->join[] = $conditions; | |
176 | return $this; | |
177 | } | |
178 | ||
179 | /** | |
180 | * @param array $join | |
181 | * @return DAOGetAction | |
182 | */ | |
183 | public function setJoin(array $join): DAOGetAction { | |
184 | $this->join = $join; | |
185 | return $this; | |
186 | } | |
187 | ||
188 | /** | |
189 | * @return array | |
190 | */ | |
191 | public function getJoin(): array { | |
192 | return $this->join; | |
193 | } | |
194 | ||
19b53e5b | 195 | } |