4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
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 |
10 +--------------------------------------------------------------------+
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
22 namespace Civi\Api4\Generic
;
24 use Civi\API\Exception\NotImplementedException
;
25 use Civi\Api4\Utils\ActionUtil
;
28 * Get fields for an entity.
30 * @method $this setLoadOptions(bool $value)
31 * @method bool getLoadOptions()
32 * @method $this setAction(string $value)
34 class BasicGetFieldsAction
extends BasicGetAction
{
37 * Fetch option lists for fields?
41 protected $loadOptions = FALSE;
46 protected $action = 'get';
49 * To implement getFields for your own entity:
51 * 1. From your entity class add a static getFields method.
52 * 2. That method should construct and return this class.
53 * 3. The 3rd argument passed to this constructor should be a function that returns an
54 * array of fields for your entity's CRUD actions.
55 * 4. For non-crud actions that need a different set of fields, you can override the
56 * list from step 3 on a per-action basis by defining a fields() method in that action.
57 * See for example BasicGetFieldsAction::fields() or GetActions::fields().
59 * @param Result $result
60 * @throws \Civi\API\Exception\NotImplementedException
62 public function _run(Result
$result) {
64 $actionClass = ActionUtil
::getAction($this->getEntityName(), $this->getAction());
66 catch (NotImplementedException
$e) {
68 if (isset($actionClass) && method_exists($actionClass, 'fields')) {
69 $values = $actionClass->fields();
72 $values = $this->getRecords();
74 $this->padResults($values);
75 $result->exchangeArray($this->queryArray($values));
79 * Ensure every result contains, at minimum, the array keys as defined in $this->fields.
81 * Attempt to set some sensible defaults for some fields.
83 * In most cases it's not necessary to override this function, even if your entity is really weird.
84 * Instead just override $this->fields and thes function will respect that.
86 * @param array $values
88 protected function padResults(&$values) {
89 $fields = array_column($this->fields(), 'name');
90 foreach ($values as &$field) {
91 $defaults = array_intersect_key([
92 'title' => empty($field['name']) ?
NULL : ucwords(str_replace('_', ' ', $field['name'])),
93 'entity' => $this->getEntityName(),
95 'options' => !empty($field['pseudoconstant']),
96 'data_type' => \CRM_Utils_Array
::value('type', $field, 'String'),
97 ], array_flip($fields));
99 if (!$this->loadOptions
&& isset($defaults['options'])) {
100 $field['options'] = (bool) $field['options'];
102 $field +
= array_fill_keys($fields, NULL);
109 public function getAction() {
110 // For actions that build on top of other actions, return fields for the simpler action
113 'replace' => 'create',
115 return $sub[$this->action
] ??
$this->action
;
118 public function fields() {
122 'data_type' => 'String',
126 'data_type' => 'String',
129 'name' => 'description',
130 'data_type' => 'String',
133 'name' => 'default_value',
134 'data_type' => 'String',
137 'name' => 'required',
138 'data_type' => 'Boolean',
141 'name' => 'required_if',
142 'data_type' => 'String',
146 'data_type' => 'Array',
149 'name' => 'data_type',
150 'data_type' => 'String',
153 'name' => 'input_type',
154 'data_type' => 'String',
157 'name' => 'input_attrs',
158 'data_type' => 'Array',
161 'name' => 'fk_entity',
162 'data_type' => 'String',
165 'name' => 'serialize',
166 'data_type' => 'Integer',
170 'data_type' => 'String',