Merge pull request #17159 from eileenmcnaughton/ids
[civicrm-core.git] / Civi / Api4 / Generic / BasicGetFieldsAction.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
13/**
14 *
15 * @package CRM
ca5cec67 16 * @copyright CiviCRM LLC https://civicrm.org/licensing
380f3545
TO
17 * $Id$
18 *
19 */
20
21
19b53e5b
C
22namespace Civi\Api4\Generic;
23
24use Civi\API\Exception\NotImplementedException;
19b53e5b
C
25
26/**
fc95d9a5 27 * Lists information about fields for the $ENTITY entity.
e15f9453
CW
28 *
29 * This field information is also known as "metadata."
30 *
31 * Note that different actions may support different lists of fields.
fc95d9a5 32 * By default this will fetch the field list relevant to `get`,
e15f9453 33 * but a different list may be returned if you specify another action.
19b53e5b
C
34 *
35 * @method $this setLoadOptions(bool $value)
36 * @method bool getLoadOptions()
37 * @method $this setAction(string $value)
c752d94b
CW
38 * @method $this setValues(array $values)
39 * @method array getValues()
19b53e5b
C
40 */
41class BasicGetFieldsAction extends BasicGetAction {
42
43 /**
44 * Fetch option lists for fields?
45 *
46 * @var bool
47 */
48 protected $loadOptions = FALSE;
49
50 /**
c752d94b
CW
51 * Fields will be returned appropriate to the specified action (get, create, delete, etc.)
52 *
19b53e5b
C
53 * @var string
54 */
55 protected $action = 'get';
56
c752d94b
CW
57 /**
58 * Fields will be returned appropriate to the specified values (e.g. ['contact_type' => 'Individual'])
59 *
60 * @var array
61 */
62 protected $values = [];
63
19b53e5b
C
64 /**
65 * To implement getFields for your own entity:
66 *
67 * 1. From your entity class add a static getFields method.
68 * 2. That method should construct and return this class.
69 * 3. The 3rd argument passed to this constructor should be a function that returns an
70 * array of fields for your entity's CRUD actions.
71 * 4. For non-crud actions that need a different set of fields, you can override the
72 * list from step 3 on a per-action basis by defining a fields() method in that action.
73 * See for example BasicGetFieldsAction::fields() or GetActions::fields().
74 *
75 * @param Result $result
76 * @throws \Civi\API\Exception\NotImplementedException
77 */
78 public function _run(Result $result) {
79 try {
3a8dc228 80 $actionClass = \Civi\API\Request::create($this->getEntityName(), $this->getAction(), ['version' => 4]);
19b53e5b
C
81 }
82 catch (NotImplementedException $e) {
83 }
84 if (isset($actionClass) && method_exists($actionClass, 'fields')) {
85 $values = $actionClass->fields();
86 }
87 else {
88 $values = $this->getRecords();
89 }
90 $this->padResults($values);
91 $result->exchangeArray($this->queryArray($values));
92 }
93
94 /**
95 * Ensure every result contains, at minimum, the array keys as defined in $this->fields.
96 *
97 * Attempt to set some sensible defaults for some fields.
98 *
99 * In most cases it's not necessary to override this function, even if your entity is really weird.
100 * Instead just override $this->fields and thes function will respect that.
101 *
102 * @param array $values
103 */
104 protected function padResults(&$values) {
105 $fields = array_column($this->fields(), 'name');
106 foreach ($values as &$field) {
107 $defaults = array_intersect_key([
108 'title' => empty($field['name']) ? NULL : ucwords(str_replace('_', ' ', $field['name'])),
109 'entity' => $this->getEntityName(),
110 'required' => FALSE,
111 'options' => !empty($field['pseudoconstant']),
112 'data_type' => \CRM_Utils_Array::value('type', $field, 'String'),
113 ], array_flip($fields));
114 $field += $defaults;
115 if (!$this->loadOptions && isset($defaults['options'])) {
116 $field['options'] = (bool) $field['options'];
117 }
118 $field += array_fill_keys($fields, NULL);
119 }
120 }
121
122 /**
123 * @return string
124 */
125 public function getAction() {
126 // For actions that build on top of other actions, return fields for the simpler action
127 $sub = [
128 'save' => 'create',
129 'replace' => 'create',
130 ];
131 return $sub[$this->action] ?? $this->action;
132 }
133
121ec912
CW
134 /**
135 * Add an item to the values array
136 * @param string $fieldName
137 * @param mixed $value
138 * @return $this
139 */
140 public function addValue(string $fieldName, $value) {
141 $this->values[$fieldName] = $value;
142 return $this;
143 }
144
3a8dc228
CW
145 /**
146 * @param bool $includeCustom
147 * @return $this
148 */
149 public function setIncludeCustom(bool $includeCustom) {
150 // Be forgiving if the param doesn't exist and don't throw an exception
151 if (property_exists($this, 'includeCustom')) {
152 $this->includeCustom = $includeCustom;
153 }
154 return $this;
155 }
156
19b53e5b
C
157 public function fields() {
158 return [
159 [
160 'name' => 'name',
161 'data_type' => 'String',
162 ],
163 [
164 'name' => 'title',
165 'data_type' => 'String',
166 ],
167 [
168 'name' => 'description',
169 'data_type' => 'String',
170 ],
171 [
172 'name' => 'default_value',
173 'data_type' => 'String',
174 ],
175 [
176 'name' => 'required',
177 'data_type' => 'Boolean',
178 ],
179 [
180 'name' => 'required_if',
181 'data_type' => 'String',
182 ],
183 [
184 'name' => 'options',
185 'data_type' => 'Array',
186 ],
187 [
188 'name' => 'data_type',
189 'data_type' => 'String',
190 ],
191 [
192 'name' => 'input_type',
193 'data_type' => 'String',
194 ],
195 [
196 'name' => 'input_attrs',
197 'data_type' => 'Array',
198 ],
199 [
200 'name' => 'fk_entity',
201 'data_type' => 'String',
202 ],
203 [
204 'name' => 'serialize',
205 'data_type' => 'Integer',
206 ],
207 [
208 'name' => 'entity',
209 'data_type' => 'String',
210 ],
211 ];
212 }
213
214}