Merge pull request #15916 from civicrm/5.20
[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 $includeCustom
50 *
51 * @return \Civi\Api4\Service\Spec\RequestSpec
52 */
53 public function getSpec($entity, $action, $includeCustom) {
54 $specification = new RequestSpec($entity, $action);
55
56 // Real entities
57 if (strpos($entity, 'Custom_') !== 0) {
58 $this->addDAOFields($entity, $action, $specification);
59 if ($includeCustom && array_key_exists($entity, \CRM_Core_SelectValues::customGroupExtends())) {
60 $this->addCustomFields($entity, $specification);
61 }
62 }
63 // Custom pseudo-entities
64 else {
65 $this->getCustomGroupFields(substr($entity, 7), $specification);
66 }
67
68 // Default value only makes sense for create actions
69 if ($action != 'create') {
70 foreach ($specification->getFields() as $field) {
71 $field->setDefaultValue(NULL);
72 }
73 }
74
75 foreach ($this->specProviders as $provider) {
76 if ($provider->applies($entity, $action)) {
77 $provider->modifySpec($specification);
78 }
79 }
80
81 return $specification;
82 }
83
84 /**
85 * @param \Civi\Api4\Service\Spec\Provider\Generic\SpecProviderInterface $provider
86 */
87 public function addSpecProvider(SpecProviderInterface $provider) {
88 $this->specProviders[] = $provider;
89 }
90
91 /**
92 * @param string $entity
93 * @param string $action
94 * @param \Civi\Api4\Service\Spec\RequestSpec $specification
95 */
96 private function addDAOFields($entity, $action, RequestSpec $specification) {
97 $DAOFields = $this->getDAOFields($entity);
98
99 foreach ($DAOFields as $DAOField) {
100 if ($DAOField['name'] == 'id' && $action == 'create') {
101 continue;
102 }
103 if ($action !== 'create' || isset($DAOField['default'])) {
104 $DAOField['required'] = FALSE;
105 }
106 if ($DAOField['name'] == 'is_active' && empty($DAOField['default'])) {
107 $DAOField['default'] = '1';
108 }
109 $field = SpecFormatter::arrayToField($DAOField, $entity);
110 $specification->addFieldSpec($field);
111 }
112 }
113
114 /**
115 * @param string $entity
116 * @param \Civi\Api4\Service\Spec\RequestSpec $specification
117 */
118 private function addCustomFields($entity, RequestSpec $specification) {
119 $extends = ($entity == 'Contact') ? ['Contact', 'Individual', 'Organization', 'Household'] : [$entity];
120 $customFields = CustomField::get()
121 ->setCheckPermissions(FALSE)
122 ->addWhere('custom_group.extends', 'IN', $extends)
123 ->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'])
124 ->execute();
125
126 foreach ($customFields as $fieldArray) {
127 $field = SpecFormatter::arrayToField($fieldArray, $entity);
128 $specification->addFieldSpec($field);
129 }
130 }
131
132 /**
133 * @param string $customGroup
134 * @param \Civi\Api4\Service\Spec\RequestSpec $specification
135 */
136 private function getCustomGroupFields($customGroup, RequestSpec $specification) {
137 $customFields = CustomField::get()
138 ->addWhere('custom_group.name', '=', $customGroup)
139 ->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'])
140 ->execute();
141
142 foreach ($customFields as $fieldArray) {
143 $field = SpecFormatter::arrayToField($fieldArray, 'Custom_' . $customGroup);
144 $specification->addFieldSpec($field);
145 }
146 }
147
148 /**
149 * @param string $entityName
150 *
151 * @return array
152 */
153 private function getDAOFields($entityName) {
154 $bao = CoreUtil::getBAOFromApiName($entityName);
155
156 return $bao::fields();
157 }
158
159 }