[REF][PHP8.1] Add in type hints to fix deprecations and add in #[\ReturnTypeWillChang...
[civicrm-core.git] / Civi / Api4 / Service / Spec / RequestSpec.php
CommitLineData
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
13namespace Civi\Api4\Service\Spec;
14
e60149f3
CW
15use Civi\Api4\Utils\CoreUtil;
16
9c961a3a 17class RequestSpec implements \Iterator {
19b53e5b
C
18
19 /**
20 * @var string
21 */
22 protected $entity;
23
24 /**
25 * @var string
26 */
27 protected $action;
28
e60149f3
CW
29 /**
30 * @var string
31 */
32 protected $entityTableName;
33
19b53e5b
C
34 /**
35 * @var FieldSpec[]
36 */
37 protected $fields = [];
38
04ef69d3
CW
39 /**
40 * @var array
41 */
42 protected $values = [];
43
19b53e5b
C
44 /**
45 * @param string $entity
46 * @param string $action
04ef69d3 47 * @param array $values
19b53e5b 48 */
04ef69d3 49 public function __construct($entity, $action, $values = []) {
19b53e5b
C
50 $this->entity = $entity;
51 $this->action = $action;
e60149f3 52 $this->entityTableName = CoreUtil::getTableName($entity);
38016453
CW
53
54 // If `id` given, lookup other values needed to filter custom fields
55 $customInfo = \Civi\Api4\Utils\CoreUtil::getCustomGroupExtends($entity);
56 $idCol = $customInfo['column'] ?? NULL;
57 if ($idCol && !empty($values[$idCol])) {
58 $grouping = (array) $customInfo['grouping'];
59 $lookupNeeded = array_diff($grouping, array_keys($values));
60 if ($lookupNeeded) {
61 $record = \civicrm_api4($entity, 'get', [
62 'checkPermissions' => FALSE,
63 'where' => [[$idCol, '=', $values[$idCol]]],
64 'select' => $lookupNeeded,
65 ])->first();
66 if ($record) {
67 $values += $record;
68 }
69 }
04ef69d3
CW
70 }
71 $this->values = $values;
19b53e5b
C
72 }
73
04ef69d3
CW
74 /**
75 * @param FieldSpec $field
76 */
19b53e5b 77 public function addFieldSpec(FieldSpec $field) {
e60149f3
CW
78 if (!$field->getEntity()) {
79 $field->setEntity($this->entity);
80 }
81 if (!$field->getTableName()) {
82 $field->setTableName($this->entityTableName);
83 }
19b53e5b
C
84 $this->fields[] = $field;
85 }
86
87 /**
88 * @param $name
89 *
90 * @return FieldSpec|null
91 */
92 public function getFieldByName($name) {
93 foreach ($this->fields as $field) {
94 if ($field->getName() === $name) {
95 return $field;
96 }
97 }
98
99 return NULL;
100 }
101
102 /**
103 * @return array
104 * Gets all the field names currently part of the specification
105 */
106 public function getFieldNames() {
107 return array_map(function(FieldSpec $field) {
108 return $field->getName();
109 }, $this->fields);
110 }
111
112 /**
113 * @return array|FieldSpec[]
114 */
115 public function getRequiredFields() {
116 return array_filter($this->fields, function (FieldSpec $field) {
117 return $field->isRequired();
118 });
119 }
120
121 /**
122 * @return array|FieldSpec[]
123 */
124 public function getConditionalRequiredFields() {
125 return array_filter($this->fields, function (FieldSpec $field) {
126 return $field->getRequiredIf();
127 });
128 }
129
130 /**
131 * @param array $fieldNames
132 * Optional array of fields to return
133 * @return FieldSpec[]
134 */
135 public function getFields($fieldNames = NULL) {
136 if (!$fieldNames) {
137 return $this->fields;
138 }
37d2f985
CW
139 // Return all exact matches plus partial matches (to support retrieving fk fields)
140 return array_filter($this->fields, function($field) use($fieldNames) {
141 foreach ($fieldNames as $fieldName) {
142 if (strpos($fieldName, $field->getName()) === 0) {
143 return TRUE;
144 }
19b53e5b 145 }
37d2f985
CW
146 return FALSE;
147 });
19b53e5b
C
148 }
149
150 /**
151 * @return string
152 */
153 public function getEntity() {
154 return $this->entity;
155 }
156
04ef69d3
CW
157 /**
158 * @return array
159 */
160 public function getValues() {
161 return $this->values;
162 }
163
164 /**
165 * @param string $key
166 * @return mixed
167 */
168 public function getValue(string $key) {
169 return $this->values[$key] ?? NULL;
170 }
171
19b53e5b
C
172 /**
173 * @return string
174 */
175 public function getAction() {
176 return $this->action;
177 }
178
d77b3d91 179 #[\ReturnTypeWillChange]
9c961a3a
CW
180 public function rewind() {
181 return reset($this->fields);
182 }
183
d77b3d91 184 #[\ReturnTypeWillChange]
9c961a3a
CW
185 public function current() {
186 return current($this->fields);
187 }
188
d77b3d91 189 #[\ReturnTypeWillChange]
9c961a3a
CW
190 public function key() {
191 return key($this->fields);
192 }
193
d77b3d91
SL
194 public function next(): void {
195 next($this->fields);
9c961a3a
CW
196 }
197
d77b3d91 198 public function valid(): bool {
9c961a3a
CW
199 return key($this->fields) !== NULL;
200 }
201
19b53e5b 202}