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 | ||
37836cb1 CW |
15 | use Civi\Api4\Utils\CoreUtil; |
16 | use Civi\Api4\Utils\FormattingUtil; | |
17 | ||
19b53e5b | 18 | /** |
e15f9453 | 19 | * @inheritDoc |
19b53e5b C |
20 | * @method bool getIncludeCustom() |
21 | */ | |
22 | class DAOGetFieldsAction extends BasicGetFieldsAction { | |
23 | ||
19b53e5b | 24 | /** |
e15f9453 | 25 | * Get fields for a DAO-based entity. |
19b53e5b C |
26 | * |
27 | * @return array | |
28 | */ | |
29 | protected function getRecords() { | |
37d2f985 | 30 | $fieldsToGet = $this->_itemsToGet('name'); |
a1415a02 | 31 | $typesToGet = $this->_itemsToGet('type'); |
19b53e5b C |
32 | /** @var \Civi\Api4\Service\Spec\SpecGatherer $gatherer */ |
33 | $gatherer = \Civi::container()->get('spec_gatherer'); | |
a1415a02 CW |
34 | $includeCustom = TRUE; |
35 | if ($typesToGet) { | |
36 | $includeCustom = in_array('Custom', $typesToGet, TRUE); | |
19b53e5b | 37 | } |
a1415a02 CW |
38 | elseif ($fieldsToGet) { |
39 | // Any fields name with a dot in it is either custom or an implicit join | |
40 | $includeCustom = strpos(implode('', $fieldsToGet), '.') !== FALSE; | |
41 | } | |
37836cb1 | 42 | $this->formatValues(); |
a1415a02 | 43 | $spec = $gatherer->getSpec($this->getEntityName(), $this->getAction(), $includeCustom, $this->values); |
2bf220fd | 44 | $fields = $this->specToArray($spec->getFields($fieldsToGet)); |
37d2f985 CW |
45 | foreach ($fieldsToGet ?? [] as $fieldName) { |
46 | if (empty($fields[$fieldName]) && strpos($fieldName, '.') !== FALSE) { | |
47 | $fkField = $this->getFkFieldSpec($fieldName, $fields); | |
48 | if ($fkField) { | |
49 | $fkField['name'] = $fieldName; | |
50 | $fields[] = $fkField; | |
51 | } | |
52 | } | |
53 | } | |
54 | return $fields; | |
55 | } | |
56 | ||
2bf220fd CW |
57 | /** |
58 | * @param \Civi\Api4\Service\Spec\FieldSpec[] $fields | |
59 | * | |
60 | * @return array | |
61 | */ | |
62 | protected function specToArray($fields) { | |
63 | $fieldArray = []; | |
64 | ||
65 | foreach ($fields as $field) { | |
66 | if ($this->loadOptions) { | |
67 | $field->getOptions($this->values, $this->loadOptions, $this->checkPermissions); | |
68 | } | |
69 | $fieldArray[$field->getName()] = $field->toArray(); | |
70 | } | |
71 | ||
72 | return $fieldArray; | |
73 | } | |
74 | ||
37d2f985 CW |
75 | /** |
76 | * @param string $fieldName | |
77 | * @param array $fields | |
78 | * @return array|null | |
79 | * @throws \API_Exception | |
80 | */ | |
81 | private function getFkFieldSpec($fieldName, $fields) { | |
82 | $fieldPath = explode('.', $fieldName); | |
83 | // Search for the first segment alone plus the first and second | |
84 | // No field in the schema contains more than one dot in its name. | |
85 | $searchPaths = [$fieldPath[0], $fieldPath[0] . '.' . $fieldPath[1]]; | |
86 | $fkFieldName = array_intersect($searchPaths, array_keys($fields))[0] ?? NULL; | |
87 | if ($fkFieldName && !empty($fields[$fkFieldName]['fk_entity'])) { | |
88 | $newFieldName = substr($fieldName, 1 + strlen($fkFieldName)); | |
89 | return civicrm_api4($fields[$fkFieldName]['fk_entity'], 'getFields', [ | |
90 | 'checkPermissions' => $this->checkPermissions, | |
91 | 'where' => [['name', '=', $newFieldName]], | |
92 | 'loadOptions' => $this->loadOptions, | |
93 | 'action' => $this->action, | |
94 | ])->first(); | |
95 | } | |
19b53e5b C |
96 | } |
97 | ||
37836cb1 CW |
98 | /** |
99 | * Special handling for pseudoconstant replacements. | |
100 | * | |
101 | * Normally this would involve calling getFields... but this IS getFields. | |
102 | * | |
103 | * @throws \API_Exception | |
104 | */ | |
105 | private function formatValues() { | |
106 | foreach (array_keys($this->values) as $key) { | |
107 | if (strpos($key, ':')) { | |
108 | [$fieldName, $suffix] = explode(':', $key); | |
109 | $context = FormattingUtil::$pseudoConstantContexts[$suffix] ?? NULL; | |
110 | if (!$context) { | |
111 | throw new \API_Exception('Illegal expression'); | |
112 | } | |
113 | $baoName = CoreUtil::getBAOFromApiName($this->getEntityName()); | |
114 | $options = $baoName::buildOptions($fieldName, $context); | |
115 | $this->values[$fieldName] = FormattingUtil::replacePseudoconstant($options, $this->values[$key], TRUE); | |
116 | unset($this->values[$key]); | |
117 | } | |
118 | } | |
119 | } | |
120 | ||
19b53e5b C |
121 | public function fields() { |
122 | $fields = parent::fields(); | |
f274627b CW |
123 | $fields[] = [ |
124 | 'name' => 'help_pre', | |
125 | 'data_type' => 'String', | |
126 | ]; | |
127 | $fields[] = [ | |
128 | 'name' => 'help_post', | |
129 | 'data_type' => 'String', | |
130 | ]; | |
f0acec37 CW |
131 | $fields[] = [ |
132 | 'name' => 'column_name', | |
133 | 'data_type' => 'String', | |
134 | ]; | |
19b53e5b C |
135 | $fields[] = [ |
136 | 'name' => 'custom_field_id', | |
137 | 'data_type' => 'Integer', | |
138 | ]; | |
139 | $fields[] = [ | |
140 | 'name' => 'custom_group_id', | |
141 | 'data_type' => 'Integer', | |
142 | ]; | |
a1415a02 CW |
143 | $fields[] = [ |
144 | 'name' => 'sql_filters', | |
145 | 'data_type' => 'Array', | |
146 | '@internal' => TRUE, | |
147 | ]; | |
9c961a3a CW |
148 | $fields[] = [ |
149 | 'name' => 'sql_renderer', | |
150 | 'data_type' => 'Array', | |
151 | '@internal' => TRUE, | |
152 | ]; | |
19b53e5b C |
153 | return $fields; |
154 | } | |
155 | ||
156 | } |