APIv4 - Use non-deprecated join syntax internally
[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 namespace Civi\Api4\Service\Spec;
14
15 use Civi\Api4\CustomField;
16 use Civi\Api4\Service\Spec\Provider\Generic\SpecProviderInterface;
17 use Civi\Api4\Utils\CoreUtil;
18
19 class SpecGatherer {
20
21 /**
22 * @var \Civi\Api4\Service\Spec\Provider\Generic\SpecProviderInterface[]
23 */
24 protected $specProviders = [];
25
26 /**
27 * Returns a RequestSpec with all the fields available. Uses spec providers
28 * to add or modify field specifications.
29 * @see \Civi\Api4\Service\Spec\Provider\CustomFieldCreationSpecProvider
30 *
31 * @param string $entity
32 * @param string $action
33 * @param bool $includeCustom
34 * @param array $values
35 *
36 * @return \Civi\Api4\Service\Spec\RequestSpec
37 */
38 public function getSpec($entity, $action, $includeCustom, $values = []) {
39 $specification = new RequestSpec($entity, $action);
40
41 // Real entities
42 if (strpos($entity, 'Custom_') !== 0) {
43 $this->addDAOFields($entity, $action, $specification, $values);
44 if ($includeCustom) {
45 $this->addCustomFields($entity, $specification, $values);
46 }
47 }
48 // Custom pseudo-entities
49 else {
50 $this->getCustomGroupFields(substr($entity, 7), $specification);
51 }
52
53 // Default value only makes sense for create actions
54 if ($action != 'create') {
55 foreach ($specification->getFields() as $field) {
56 $field->setDefaultValue(NULL);
57 }
58 }
59
60 foreach ($this->specProviders as $provider) {
61 if ($provider->applies($entity, $action)) {
62 $provider->modifySpec($specification);
63 }
64 }
65
66 return $specification;
67 }
68
69 /**
70 * @param \Civi\Api4\Service\Spec\Provider\Generic\SpecProviderInterface $provider
71 */
72 public function addSpecProvider(SpecProviderInterface $provider) {
73 $this->specProviders[] = $provider;
74 }
75
76 /**
77 * @param string $entity
78 * @param string $action
79 * @param \Civi\Api4\Service\Spec\RequestSpec $specification
80 * @param array $values
81 */
82 private function addDAOFields($entity, $action, RequestSpec $specification, $values = []) {
83 $DAOFields = $this->getDAOFields($entity);
84
85 foreach ($DAOFields as $DAOField) {
86 if ($DAOField['name'] == 'id' && $action == 'create') {
87 continue;
88 }
89 if (array_key_exists('contactType', $DAOField) && !empty($values['contact_type']) && $DAOField['contactType'] != $values['contact_type']) {
90 continue;
91 }
92 if (!empty($DAOField['component']) &&
93 !in_array($DAOField['component'], \Civi::settings()->get('enable_components'), TRUE)
94 ) {
95 continue;
96 }
97 if ($action !== 'create' || isset($DAOField['default'])) {
98 $DAOField['required'] = FALSE;
99 }
100 if ($DAOField['name'] == 'is_active' && empty($DAOField['default'])) {
101 $DAOField['default'] = '1';
102 }
103 $field = SpecFormatter::arrayToField($DAOField, $entity);
104 $specification->addFieldSpec($field);
105 }
106 }
107
108 /**
109 * Get custom fields that extend this entity
110 *
111 * @see \CRM_Core_SelectValues::customGroupExtends
112 *
113 * @param string $entity
114 * @param \Civi\Api4\Service\Spec\RequestSpec $specification
115 * @param array $values
116 * @throws \API_Exception
117 */
118 private function addCustomFields($entity, RequestSpec $specification, $values = []) {
119 $customInfo = \Civi\Api4\Utils\CoreUtil::getCustomGroupExtends($entity);
120 if (!$customInfo) {
121 return;
122 }
123 // If a contact_type was passed in, exclude custom groups for other contact types
124 if ($entity === 'Contact' && !empty($values['contact_type'])) {
125 $extends = ['Contact', $values['contact_type']];
126 }
127 else {
128 $extends = $customInfo['extends'];
129 }
130 $customFields = CustomField::get(FALSE)
131 ->addWhere('custom_group_id.extends', 'IN', $extends)
132 ->addWhere('custom_group_id.is_multiple', '=', '0')
133 ->setSelect(['custom_group_id.name', 'custom_group_id.title', '*'])
134 ->execute();
135
136 foreach ($customFields as $fieldArray) {
137 $field = SpecFormatter::arrayToField($fieldArray, $entity);
138 $specification->addFieldSpec($field);
139 }
140 }
141
142 /**
143 * @param string $customGroup
144 * @param \Civi\Api4\Service\Spec\RequestSpec $specification
145 */
146 private function getCustomGroupFields($customGroup, RequestSpec $specification) {
147 $customFields = CustomField::get(FALSE)
148 ->addWhere('custom_group_id.name', '=', $customGroup)
149 ->setSelect(['custom_group_id.name', 'custom_group_id.table_name', 'custom_group_id.title', '*'])
150 ->execute();
151
152 foreach ($customFields as $fieldArray) {
153 $field = SpecFormatter::arrayToField($fieldArray, 'Custom_' . $customGroup);
154 $specification->addFieldSpec($field);
155 }
156 }
157
158 /**
159 * @param string $entityName
160 *
161 * @return array
162 */
163 private function getDAOFields($entityName) {
164 $bao = CoreUtil::getBAOFromApiName($entityName);
165
166 return $bao::getSupportedFields();
167 }
168
169 }