Merge pull request #21513 from JKingsnorth/core-2846-1-improve-start-end-date-validation
[civicrm-core.git] / Civi / Api4 / Generic / DAOGetFieldsAction.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\Generic;
14
19b53e5b 15/**
e15f9453 16 * @inheritDoc
19b53e5b
C
17 * @method bool getIncludeCustom()
18 */
19class DAOGetFieldsAction extends BasicGetFieldsAction {
20
19b53e5b 21 /**
e15f9453 22 * Get fields for a DAO-based entity.
19b53e5b
C
23 *
24 * @return array
25 */
26 protected function getRecords() {
37d2f985 27 $fieldsToGet = $this->_itemsToGet('name');
a1415a02 28 $typesToGet = $this->_itemsToGet('type');
19b53e5b
C
29 /** @var \Civi\Api4\Service\Spec\SpecGatherer $gatherer */
30 $gatherer = \Civi::container()->get('spec_gatherer');
a1415a02
CW
31 $includeCustom = TRUE;
32 if ($typesToGet) {
33 $includeCustom = in_array('Custom', $typesToGet, TRUE);
19b53e5b 34 }
a1415a02
CW
35 elseif ($fieldsToGet) {
36 // Any fields name with a dot in it is either custom or an implicit join
37 $includeCustom = strpos(implode('', $fieldsToGet), '.') !== FALSE;
38 }
39 $spec = $gatherer->getSpec($this->getEntityName(), $this->getAction(), $includeCustom, $this->values);
2bf220fd 40 $fields = $this->specToArray($spec->getFields($fieldsToGet));
37d2f985
CW
41 foreach ($fieldsToGet ?? [] as $fieldName) {
42 if (empty($fields[$fieldName]) && strpos($fieldName, '.') !== FALSE) {
43 $fkField = $this->getFkFieldSpec($fieldName, $fields);
44 if ($fkField) {
45 $fkField['name'] = $fieldName;
46 $fields[] = $fkField;
47 }
48 }
49 }
50 return $fields;
51 }
52
2bf220fd
CW
53 /**
54 * @param \Civi\Api4\Service\Spec\FieldSpec[] $fields
55 *
56 * @return array
57 */
58 protected function specToArray($fields) {
59 $fieldArray = [];
60
61 foreach ($fields as $field) {
62 if ($this->loadOptions) {
63 $field->getOptions($this->values, $this->loadOptions, $this->checkPermissions);
64 }
65 $fieldArray[$field->getName()] = $field->toArray();
66 }
67
68 return $fieldArray;
69 }
70
37d2f985
CW
71 /**
72 * @param string $fieldName
73 * @param array $fields
74 * @return array|null
75 * @throws \API_Exception
76 */
77 private function getFkFieldSpec($fieldName, $fields) {
78 $fieldPath = explode('.', $fieldName);
79 // Search for the first segment alone plus the first and second
80 // No field in the schema contains more than one dot in its name.
81 $searchPaths = [$fieldPath[0], $fieldPath[0] . '.' . $fieldPath[1]];
82 $fkFieldName = array_intersect($searchPaths, array_keys($fields))[0] ?? NULL;
83 if ($fkFieldName && !empty($fields[$fkFieldName]['fk_entity'])) {
84 $newFieldName = substr($fieldName, 1 + strlen($fkFieldName));
85 return civicrm_api4($fields[$fkFieldName]['fk_entity'], 'getFields', [
86 'checkPermissions' => $this->checkPermissions,
87 'where' => [['name', '=', $newFieldName]],
88 'loadOptions' => $this->loadOptions,
89 'action' => $this->action,
90 ])->first();
91 }
19b53e5b
C
92 }
93
94 public function fields() {
95 $fields = parent::fields();
f274627b
CW
96 $fields[] = [
97 'name' => 'help_pre',
98 'data_type' => 'String',
99 ];
100 $fields[] = [
101 'name' => 'help_post',
102 'data_type' => 'String',
103 ];
f0acec37
CW
104 $fields[] = [
105 'name' => 'column_name',
106 'data_type' => 'String',
107 ];
19b53e5b
C
108 $fields[] = [
109 'name' => 'custom_field_id',
110 'data_type' => 'Integer',
111 ];
112 $fields[] = [
113 'name' => 'custom_group_id',
114 'data_type' => 'Integer',
115 ];
a1415a02
CW
116 $fields[] = [
117 'name' => 'sql_filters',
118 'data_type' => 'Array',
119 '@internal' => TRUE,
120 ];
9c961a3a
CW
121 $fields[] = [
122 'name' => 'sql_renderer',
123 'data_type' => 'Array',
124 '@internal' => TRUE,
125 ];
19b53e5b
C
126 return $fields;
127 }
128
129}