Add contact type to schema to allow GetFields filtering
[civicrm-core.git] / Civi / Api4 / Service / Spec / SpecGatherer.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
6 | |
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 +--------------------------------------------------------------------+
11 */
12
13 /**
14 *
15 * @package CRM
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 * $Id$
18 *
19 */
20
21
22 namespace Civi\Api4\Service\Spec;
23
24 use Civi\Api4\CustomField;
25 use Civi\Api4\Service\Spec\Provider\Generic\SpecProviderInterface;
26 use Civi\Api4\Utils\CoreUtil;
27
28 class SpecGatherer {
29
30 /**
31 * @var \Civi\Api4\Service\Spec\Provider\Generic\SpecProviderInterface[]
32 */
33 protected $specProviders = [];
34
35 /**
36 * A cache of DAOs based on entity
37 *
38 * @var \CRM_Core_DAO[]
39 */
40 protected $DAONames;
41
42 /**
43 * Returns a RequestSpec with all the fields available. Uses spec providers
44 * to add or modify field specifications.
45 * For an example @see CustomFieldSpecProvider.
46 *
47 * @param string $entity
48 * @param string $action
49 * @param bool $includeCustom
50 * @param array $values
51 *
52 * @return \Civi\Api4\Service\Spec\RequestSpec
53 */
54 public function getSpec($entity, $action, $includeCustom, $values = []) {
55 $specification = new RequestSpec($entity, $action);
56
57 // Real entities
58 if (strpos($entity, 'Custom_') !== 0) {
59 $this->addDAOFields($entity, $action, $specification, $values);
60 if ($includeCustom && array_key_exists($entity, \CRM_Core_SelectValues::customGroupExtends())) {
61 $this->addCustomFields($entity, $specification, $values);
62 }
63 }
64 // Custom pseudo-entities
65 else {
66 $this->getCustomGroupFields(substr($entity, 7), $specification);
67 }
68
69 // Default value only makes sense for create actions
70 if ($action != 'create') {
71 foreach ($specification->getFields() as $field) {
72 $field->setDefaultValue(NULL);
73 }
74 }
75
76 foreach ($this->specProviders as $provider) {
77 if ($provider->applies($entity, $action)) {
78 $provider->modifySpec($specification);
79 }
80 }
81
82 return $specification;
83 }
84
85 /**
86 * @param \Civi\Api4\Service\Spec\Provider\Generic\SpecProviderInterface $provider
87 */
88 public function addSpecProvider(SpecProviderInterface $provider) {
89 $this->specProviders[] = $provider;
90 }
91
92 /**
93 * @param string $entity
94 * @param string $action
95 * @param \Civi\Api4\Service\Spec\RequestSpec $specification
96 * @param array $values
97 */
98 private function addDAOFields($entity, $action, RequestSpec $specification, $values = []) {
99 $DAOFields = $this->getDAOFields($entity);
100
101 foreach ($DAOFields as $DAOField) {
102 if ($DAOField['name'] == 'id' && $action == 'create') {
103 continue;
104 }
105 if (array_key_exists('contactType', $DAOField) && !empty($values['contact_type']) && $DAOField['contactType'] != $values['contact_type']) {
106 continue;
107 }
108 if ($action !== 'create' || isset($DAOField['default'])) {
109 $DAOField['required'] = FALSE;
110 }
111 if ($DAOField['name'] == 'is_active' && empty($DAOField['default'])) {
112 $DAOField['default'] = '1';
113 }
114 $field = SpecFormatter::arrayToField($DAOField, $entity);
115 $specification->addFieldSpec($field);
116 }
117 }
118
119 /**
120 * @param string $entity
121 * @param \Civi\Api4\Service\Spec\RequestSpec $specification
122 * @param array $values
123 * @throws \API_Exception
124 */
125 private function addCustomFields($entity, RequestSpec $specification, $values = []) {
126 $extends = [$entity];
127 if ($entity === 'Contact') {
128 $extends = !empty($values['contact_type']) ? [$values['contact_type'], 'Contact'] : ['Contact', 'Individual', 'Organization', 'Household'];
129 }
130 $customFields = CustomField::get()
131 ->setCheckPermissions(FALSE)
132 ->addWhere('custom_group.extends', 'IN', $extends)
133 ->addWhere('custom_group.is_multiple', '=', '0')
134 ->setSelect(['custom_group.name', 'custom_group_id', 'name', 'label', 'data_type', 'html_type', 'is_searchable', 'is_search_range', 'weight', 'is_active', 'is_view', 'option_group_id', 'default_value', 'date_format', 'time_format', 'start_date_years', 'end_date_years', 'help_pre', 'help_post'])
135 ->execute();
136
137 foreach ($customFields as $fieldArray) {
138 $field = SpecFormatter::arrayToField($fieldArray, $entity);
139 $specification->addFieldSpec($field);
140 }
141 }
142
143 /**
144 * @param string $customGroup
145 * @param \Civi\Api4\Service\Spec\RequestSpec $specification
146 */
147 private function getCustomGroupFields($customGroup, RequestSpec $specification) {
148 $customFields = CustomField::get()
149 ->addWhere('custom_group.name', '=', $customGroup)
150 ->setSelect(['custom_group.name', 'custom_group_id', 'name', 'label', 'data_type', 'html_type', 'is_searchable', 'is_search_range', 'weight', 'is_active', 'is_view', 'option_group_id', 'default_value', 'custom_group.table_name', 'column_name', 'date_format', 'time_format', 'start_date_years', 'end_date_years', 'help_pre', 'help_post'])
151 ->execute();
152
153 foreach ($customFields as $fieldArray) {
154 $field = SpecFormatter::arrayToField($fieldArray, 'Custom_' . $customGroup);
155 $specification->addFieldSpec($field);
156 }
157 }
158
159 /**
160 * @param string $entityName
161 *
162 * @return array
163 */
164 private function getDAOFields($entityName) {
165 $bao = CoreUtil::getBAOFromApiName($entityName);
166
167 return $bao::fields();
168 }
169
170 }