use CRM_Afform_ExtensionUtil as E;
use Civi\Api4\Action\Afform\Submit;
-function _afform_fields() {
- return ['name', 'title', 'description', 'requires', 'layout', 'server_route', 'client_route', 'is_public'];
-}
-
/**
* Filter the content of $params to only have supported afform fields.
*
*/
function _afform_fields_filter($params) {
$result = [];
- foreach (_afform_fields() as $field) {
- if (isset($params[$field])) {
- $result[$field] = $params[$field];
+ $fields = \Civi\Api4\Afform::getfields()->setCheckPermissions(FALSE)->execute()->indexBy('name');
+ foreach ($fields as $fieldName => $field) {
+ if (isset($params[$fieldName])) {
+ $result[$fieldName] = $params[$fieldName];
}
- if (isset($result[$field])) {
- switch ($field) {
+ if (isset($result[$fieldName])) {
+ switch ($fieldName) {
case 'is_public':
- $result[$field] = CRM_Utils_String::strtobool($result[$field]);
+ $result[$fieldName] = CRM_Utils_String::strtobool($result[$fieldName]);
break;
}
foreach (pq('af-field', $doc) as $afField) {
/** @var DOMElement $afField */
$fieldName = $afField->getAttribute('name');
- $entityName = pq($afField)->parent('[af-fieldset]')->attr('af-fieldset');
+ $entityName = pq($afField)->parents('[af-fieldset]')->attr('af-fieldset');
if (!preg_match(';^[a-zA-Z0-9\_\-\. ]+$;', $entityName)) {
throw new \CRM_Core_Exception("Cannot process $path: malformed entity name ($entityName)");
}
$entityType = $entities[$entityName]['type'];
$getFields = civicrm_api4($entityType, 'getFields', [
+ 'action' => 'create',
'where' => [['name', '=', $fieldName]],
'select' => ['title', 'input_type', 'input_attrs', 'options'],
'loadOptions' => TRUE,
]);
// Merge field definition data with whatever's already in the markup
- foreach ($getFields as $field) {
+ $deep = ['input_attrs'];
+ foreach ($getFields as $fieldInfo) {
$existingFieldDefn = trim(pq($afField)->attr('defn') ?: '');
if ($existingFieldDefn && $existingFieldDefn[0] != '{') {
// If it's not an object, don't mess with it.
continue;
}
- foreach ($field as &$prop) {
- $prop = json_encode($prop, JSON_UNESCAPED_SLASHES);
+ // TODO: Teach the api to return options in this format
+ if (!empty($fieldInfo['options'])) {
+ $fieldInfo['options'] = CRM_Utils_Array::makeNonAssociative($fieldInfo['options'], 'key', 'label');
}
- if ($existingFieldDefn) {
- $field = array_merge($field, CRM_Utils_JS::getRawProps($existingFieldDefn));
+ // Default placeholder for select inputs
+ if ($fieldInfo['input_type'] === 'Select') {
+ $fieldInfo['input_attrs'] = ($fieldInfo['input_attrs'] ?? []) + ['placeholder' => ts('Select')];
+ }
+
+ $fieldDefn = $existingFieldDefn ? CRM_Utils_JS::getRawProps($existingFieldDefn) : [];
+ foreach ($fieldInfo as $name => $prop) {
+ // Merge array props 1 level deep
+ if (in_array($name, $deep) && !empty($fieldDefn[$name])) {
+ $fieldDefn[$name] = CRM_Utils_JS::writeObject(CRM_Utils_JS::getRawProps($fieldDefn[$name]) + array_map(['CRM_Utils_JS', 'encode'], $prop));
+ }
+ elseif (!isset($fieldDefn[$name])) {
+ $fieldDefn[$name] = CRM_Utils_JS::encode($prop);
+ }
}
- pq($afField)->attr('defn', CRM_Utils_JS::writeObject($field));
+ pq($afField)->attr('defn', htmlspecialchars(CRM_Utils_JS::writeObject($fieldDefn)));
}
}
});
}
$name = $params['name'];
- // Hmm?? $scanner = new CRM_Afform_AfformScanner();
- // Hmm?? afform_scanner
+ /** @var \CRM_Afform_AfformScanner $scanner */
$scanner = Civi::service('afform_scanner');
$meta = $scanner->getMeta($name);
- // Hmm?? $scanner = new CRM_Afform_AfformScanner();
-
- $fileName = '~afform/' . _afform_angular_module_name($name, 'camel');
- $htmls = [
- $fileName => file_get_contents($scanner->findFilePath($name, 'aff.html')),
- ];
- $htmls = \Civi\Angular\ChangeSet::applyResourceFilters(Civi::service('angular')->getChangeSets(), 'partials', $htmls);
$smarty = CRM_Core_Smarty::singleton();
$smarty->assign('afform', [
'camel' => _afform_angular_module_name($name, 'camel'),
'meta' => $meta,
'metaJson' => json_encode($meta),
- 'layout' => $htmls[$fileName],
+ 'layout' => _afform_html_filter($name, $scanner->getLayout($name)),
]);
$mimeType = 'text/javascript';
$content = $smarty->fetch('afform/AfformAngularModule.tpl');
}
+/**
+ * Apply any filters to an HTML partial.
+ *
+ * @param string $formName
+ * @param string $html
+ * Original HTML.
+ * @return string
+ * Modified HTML.
+ */
+function _afform_html_filter($formName, $html) {
+ $fileName = '~afform/' . _afform_angular_module_name($formName, 'camel');
+ $htmls = [$fileName => $html];
+ $htmls = \Civi\Angular\ChangeSet::applyResourceFilters(Civi::service('angular')->getChangeSets(), 'partials', $htmls);
+ return $htmls[$fileName];
+}
+
/**
* Implements hook_civicrm_alterMenu().
*/