get('afModule') == 'afGuiAdmin') { Civi::resources()->addScriptUrl(Civi::service('asset_builder')->getUrl('af-gui-vars.js')); } } /** * Implements hook_civicrm_buildAsset(). * * Loads metadata to send to the gui editor. * * FIXME: This is a prototype and should get broken out into separate callbacks with hooks, events, etc. */ function afform_gui_civicrm_buildAsset($asset, $params, &$mimeType, &$content) { if ($asset !== 'af-gui-vars.js') { return; } $entityWhitelist = $data = []; // First scan the entityDefaults directory for our list of supported entities // FIXME: Need a way to load this from other extensions too foreach (glob(__DIR__ . '/ang/afGuiEditor/entityDefaults/*.json') as $file) { $matches = []; preg_match('/([-a-z_A-Z0-9]*).json/', $file, $matches); $entityWhitelist[] = $entity = $matches[1]; // No json_decode, the files are not strict json and will go through angular.$parse clientside $data['defaults'][$entity] = trim(CRM_Utils_JS::stripComments(file_get_contents($file))); } // Load main entities $data['entities'] = (array) Civi\Api4\Entity::get() ->setCheckPermissions(FALSE) ->setSelect(['name', 'description']) ->addWhere('name', 'IN', $entityWhitelist) ->execute(); // Load blocks $data['blocks'] = []; $blockData = \Civi\Api4\Afform::get() ->setCheckPermissions(FALSE) ->addWhere('block', 'IS NOT NULL') ->setSelect(['name', 'title', 'block', 'join', 'layout', 'repeat']) ->setFormatWhitespace(TRUE) ->setLayoutFormat('shallow') ->execute(); foreach ($blockData as $block) { if (!empty($block['join']) && !in_array($block['join'], $entityWhitelist)) { $entityWhitelist[] = $block['join']; } $data['blocks'][_afform_angular_module_name($block['name'], 'dash')] = $block; } // Todo: scan for other elements $data['elements'] = [ 'container' => [ 'title' => ts('Container'), 'element' => [ '#tag' => 'div', 'class' => 'af-container', '#children' => [], ], ], 'text' => [ 'title' => ts('Text box'), 'element' => [ '#tag' => 'p', 'class' => 'af-text', '#children' => [ ['#text' => ts('Enter text')], ], ], ], 'markup' => [ 'title' => ts('Rich content'), 'element' => [ '#tag' => 'div', 'class' => 'af-markup', '#markup' => FALSE, ], ], 'button' => [ 'title' => ts('Button'), 'element' => [ '#tag' => 'button', 'class' => 'af-button btn-primary', 'crm-icon' => 'fa-check', 'ng-click' => 'afform.submit()', '#children' => [ ['#text' => ts('Enter text')], ], ], ], ]; $getFieldParams = [ 'checkPermissions' => FALSE, 'includeCustom' => TRUE, 'loadOptions' => TRUE, 'action' => 'create', 'select' => ['name', 'title', 'input_type', 'input_attrs', 'required', 'options', 'help_pre', 'help_post', 'serialize', 'data_type'], 'where' => [['input_type', 'IS NOT NULL']], ]; // Get fields for main entities + joined entities foreach (array_unique($entityWhitelist) as $entityName) { $data['fields'][$entityName] = (array) civicrm_api4($entityName, 'getFields', $getFieldParams, 'name'); // TODO: Teach the api to return options in this format foreach ($data['fields'][$entityName] as $name => $field) { if (!empty($field['options'])) { $data['fields'][$entityName][$name]['options'] = CRM_Utils_Array::makeNonAssociative($field['options'], 'key', 'label'); } else { unset($data['fields'][$entityName][$name]['options']); } } } // Now adjust the field metadata // FIXME: This should probably be a callback event or something to allow extensions to tweak the metadata for their entities $data['fields']['Contact']['contact_type']['required_data'] = TRUE; // Scan for input types // FIXME: Need a way to load this from other extensions too foreach (glob(__DIR__ . '/ang/afGuiEditor/inputType/*.html') as $file) { $matches = []; preg_match('/([-a-z_A-Z0-9]*).html/', $file, $matches); $data['inputType'][$matches[1]] = $matches[1]; } $data['styles'] = [ 'default' => ts('Default'), 'primary' => ts('Primary'), 'success' => ts('Success'), 'info' => ts('Info'), 'warning' => ts('Warning'), 'danger' => ts('Danger'), ]; $data['permissions'] = []; foreach (CRM_Core_Permission::basicPermissions(TRUE, TRUE) as $name => $perm) { $data['permissions'][] = [ 'id' => $name, 'text' => $perm[0], 'description' => $perm[1] ?? NULL, ]; } $mimeType = 'text/javascript'; $content = "CRM.afformAdminData=" . json_encode($data, JSON_UNESCAPED_SLASHES) . ';'; }