4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
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 +--------------------------------------------------------------------+
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
20 namespace Civi\Api4\Service\Spec
;
22 use CRM_Core_DAO_AllCoreTables
as AllCoreTables
;
27 * @param FieldSpec[] $fields
28 * @param bool $includeFieldOptions
29 * @param array $values
33 public static function specToArray($fields, $includeFieldOptions = FALSE, $values = []) {
36 foreach ($fields as $field) {
37 if ($includeFieldOptions) {
38 $field->getOptions($values, $includeFieldOptions);
40 $fieldArray[$field->getName()] = $field->toArray();
48 * @param string $entity
52 public static function arrayToField(array $data, $entity) {
53 $dataTypeName = self
::getDataType($data);
55 if (!empty($data['custom_group_id'])) {
56 $field = new CustomFieldSpec($data['name'], $entity, $dataTypeName);
57 if (strpos($entity, 'Custom_') !== 0) {
58 $field->setName($data['custom_group.name'] . '.' . $data['name']);
61 $field->setCustomTableName($data['custom_group.table_name']);
63 $field->setColumnName($data['column_name']);
64 $field->setCustomFieldId($data['id'] ??
NULL);
65 $field->setCustomGroupName($data['custom_group.name']);
66 $field->setTitle($data['label'] ??
NULL);
67 $field->setHelpPre($data['help_pre'] ??
NULL);
68 $field->setHelpPost($data['help_post'] ??
NULL);
69 $field->setOptions(self
::customFieldHasOptions($data));
70 if (\CRM_Core_BAO_CustomField
::isSerialized($data)) {
71 $field->setSerialize(\CRM_Core_DAO
::SERIALIZE_SEPARATOR_BOOKEND
);
75 $name = $data['name'] ??
NULL;
76 $field = new FieldSpec($name, $entity, $dataTypeName);
77 $field->setRequired(!empty($data['required']));
78 $field->setTitle($data['title'] ??
NULL);
79 $field->setOptions(!empty($data['pseudoconstant']));
80 $field->setSerialize($data['serialize'] ??
NULL);
83 $field->setDefaultValue($data['default'] ??
NULL);
84 $field->setDescription($data['description'] ??
NULL);
85 self
::setInputTypeAndAttrs($field, $data, $dataTypeName);
87 $field->setPermission($data['permission'] ??
NULL);
88 $fkAPIName = $data['FKApiName'] ??
NULL;
89 $fkClassName = $data['FKClassName'] ??
NULL;
90 if ($fkAPIName ||
$fkClassName) {
91 $field->setFkEntity($fkAPIName ?
: AllCoreTables
::getBriefName($fkClassName));
98 * Does this custom field have options
100 * @param array $field
103 private static function customFieldHasOptions($field) {
104 // This will include boolean fields with Yes/No options.
105 if (in_array($field['html_type'], ['Radio', 'CheckBox'])) {
108 // Do this before the "Select" string search because date fields have a "Select Date" html_type
109 // and contactRef fields have an "Autocomplete-Select" html_type - contacts are an FK not an option list.
110 if (in_array($field['data_type'], ['ContactReference', 'Date'])) {
113 if (strpos($field['html_type'], 'Select') !== FALSE) {
116 return !empty($field['option_group_id']);
120 * Get the data type from an array. Defaults to 'data_type' with fallback to
121 * mapping for the integer value 'type'
127 private static function getDataType(array $data) {
128 if (isset($data['data_type'])) {
129 return !empty($data['time_format']) ?
'Timestamp' : $data['data_type'];
132 $dataTypeInt = $data['type'] ??
NULL;
133 $dataTypeName = \CRM_Utils_Type
::typeToString($dataTypeInt);
135 return $dataTypeName;
139 * @param \Civi\Api4\Service\Spec\FieldSpec $fieldSpec
141 * @param string $dataTypeName
143 public static function setInputTypeAndAttrs(FieldSpec
&$fieldSpec, $data, $dataTypeName) {
144 $inputType = $data['html']['type'] ??
$data['html_type'] ??
NULL;
145 $inputAttrs = $data['html'] ??
[];
146 unset($inputAttrs['type']);
148 if (strstr($inputType, 'Multi-Select') ||
($inputType == 'Select' && !empty($data['serialize']))) {
149 $inputAttrs['multiple'] = TRUE;
150 $inputType = 'Select';
153 'Select State/Province' => 'Select',
154 'Select Country' => 'Select',
155 'Select Date' => 'Date',
158 $inputType = $map[$inputType] ??
$inputType;
159 if ($inputType == 'Date' && !empty($inputAttrs['formatType'])) {
160 self
::setLegacyDateFormat($inputAttrs);
162 // Date/time settings from custom fields
163 if ($inputType == 'Date' && !empty($data['custom_group_id'])) {
164 $inputAttrs['time'] = empty($data['time_format']) ?
FALSE : ($data['time_format'] == 1 ?
12 : 24);
165 $inputAttrs['date'] = $data['date_format'];
166 $inputAttrs['start_date_years'] = (int) $data['start_date_years'];
167 $inputAttrs['end_date_years'] = (int) $data['end_date_years'];
169 if ($inputType == 'Text' && !empty($data['maxlength'])) {
170 $inputAttrs['maxlength'] = (int) $data['maxlength'];
172 if ($inputType == 'TextArea') {
173 foreach (['rows', 'cols', 'note_rows', 'note_cols'] as $prop) {
174 if (!empty($data[$prop])) {
175 $inputAttrs[str_replace('note_', '', $prop)] = (int) $data[$prop];
180 ->setInputType($inputType)
181 ->setInputAttrs($inputAttrs);
185 * @param array $inputAttrs
187 private static function setLegacyDateFormat(&$inputAttrs) {
188 if (empty(\Civi
::$statics['legacyDatePrefs'][$inputAttrs['formatType']])) {
189 \Civi
::$statics['legacyDatePrefs'][$inputAttrs['formatType']] = [];
190 $params = ['name' => $inputAttrs['formatType']];
191 \CRM_Core_DAO
::commonRetrieve('CRM_Core_DAO_PreferencesDate', $params, \Civi
::$statics['legacyDatePrefs'][$inputAttrs['formatType']]);
193 $dateFormat = \Civi
::$statics['legacyDatePrefs'][$inputAttrs['formatType']];
194 unset($inputAttrs['formatType']);
195 $inputAttrs['time'] = !empty($dateFormat['time_format']);
196 $inputAttrs['date'] = TRUE;
197 $inputAttrs['start_date_years'] = (int) $dateFormat['start'];
198 $inputAttrs['end_date_years'] = (int) $dateFormat['end'];