Merge pull request #21228 from colemanw/afformFixTitle
[civicrm-core.git] / ext / afform / core / Civi / Api4 / Action / Afform / Get.php
CommitLineData
11e724f0
TO
1<?php
2
3namespace Civi\Api4\Action\Afform;
4
9c84a124
CW
5use Civi\Api4\CustomField;
6use Civi\Api4\CustomGroup;
67d666c6 7use CRM_Afform_ExtensionUtil as E;
9c84a124 8
11e724f0 9/**
28b4ace4 10 * @inheritDoc
11e724f0
TO
11 * @package Civi\Api4\Action\Afform
12 */
28b4ace4 13class Get extends \Civi\Api4\Generic\BasicGetAction {
11e724f0 14
28b4ace4 15 use \Civi\Api4\Utils\AfformFormatTrait;
11e724f0
TO
16
17 public function getRecords() {
18 /** @var \CRM_Afform_AfformScanner $scanner */
19 $scanner = \Civi::service('afform_scanner');
9c84a124
CW
20 $getComputed = $this->_isFieldSelected('has_local') || $this->_isFieldSelected('has_base');
21 $getLayout = $this->_isFieldSelected('layout');
22
edf837b4
CW
23 // This helps optimize lookups by file/module/directive name
24 $toGet = array_filter([
25 'name' => $this->_itemsToGet('name'),
26 'module_name' => $this->_itemsToGet('module_name'),
27 'directive_name' => $this->_itemsToGet('directive_name'),
28 ]);
11e724f0 29
edf837b4 30 $names = $toGet['name'] ?? array_keys($scanner->findFilePaths());
25f2b36b 31
9c84a124 32 $values = $this->getAutoGenerated($names, $toGet, $getLayout);
11e724f0 33
48be26b0
CW
34 if ($this->checkPermissions) {
35 $names = array_filter($names, [$this, 'checkPermission']);
36 }
37
11e724f0 38 foreach ($names as $name) {
25f2b36b 39 $info = [
edf837b4 40 'name' => $name,
25f2b36b
CW
41 'module_name' => _afform_angular_module_name($name, 'camel'),
42 'directive_name' => _afform_angular_module_name($name, 'dash'),
43 ];
edf837b4
CW
44 foreach ($toGet as $key => $get) {
45 if (!in_array($info[$key], $get)) {
fa8dc3f2 46 continue 2;
edf837b4 47 }
25f2b36b 48 }
11e724f0 49 $record = $scanner->getMeta($name);
9c84a124
CW
50 if (!$record && !isset($values[$name])) {
51 continue;
52 }
25f2b36b 53 $values[$name] = array_merge($values[$name] ?? [], $record ?? [], $info);
9c84a124
CW
54 if ($getComputed) {
55 $scanner->addComputedFields($values[$name]);
1aebf5b0 56 }
9c84a124 57 if ($getLayout) {
236719c6 58 // Autogenerated layouts will already be in values but can be overridden; scanner takes priority
9c84a124 59 $values[$name]['layout'] = $scanner->getLayout($name) ?? $values[$name]['layout'] ?? '';
11e724f0 60 }
11e724f0
TO
61 }
62
9c84a124
CW
63 if ($getLayout && $this->layoutFormat !== 'html') {
64 foreach ($values as $name => $record) {
65 $values[$name]['layout'] = $this->convertHtmlToOutput($record['layout']);
66 }
67 }
68
69 return $values;
70 }
71
48be26b0
CW
72 /**
73 * Assert that a form is authorized.
74 *
75 * @return bool
76 */
77 protected function checkPermission($name) {
78 return \CRM_Core_Permission::check("@afform:$name");
79 }
80
9c84a124
CW
81 /**
82 * Generates afform blocks from custom field sets.
83 *
84 * @param $names
85 * @param $toGet
86 * @param $getLayout
87 * @return array
88 * @throws \API_Exception
89 */
90 protected function getAutoGenerated(&$names, $toGet, $getLayout) {
91 $values = $groupNames = [];
edf837b4 92 foreach ($toGet['name'] ?? [] as $name) {
fa8dc3f2
CW
93 if (strpos($name, 'afblockCustom_') === 0 && strlen($name) > 13) {
94 $groupNames[] = substr($name, 14);
9c84a124
CW
95 }
96 }
c3273f01
CW
97 // Early return if this api call is fetching afforms by name and those names are not custom-related
98 if ((!empty($toGet['name']) && !$groupNames)
fa8dc3f2
CW
99 || (!empty($toGet['module_name']) && !strstr(implode(' ', $toGet['module_name']), 'afblockCustom'))
100 || (!empty($toGet['directive_name']) && !strstr(implode(' ', $toGet['directive_name']), 'afblock-custom'))
edf837b4 101 ) {
9c84a124
CW
102 return $values;
103 }
104 $customApi = CustomGroup::get()
105 ->setCheckPermissions(FALSE)
83412ba5 106 ->addSelect('name', 'title', 'help_pre', 'help_post', 'extends', 'max_multiple')
9c84a124
CW
107 ->addWhere('is_multiple', '=', 1)
108 ->addWhere('is_active', '=', 1);
109 if ($groupNames) {
110 $customApi->addWhere('name', 'IN', $groupNames);
111 }
112 if ($getLayout) {
83412ba5
CW
113 $customApi->addSelect('help_pre', 'help_post');
114 $customApi->addChain('fields', CustomField::get(FALSE)
9c84a124
CW
115 ->addSelect('name')
116 ->addWhere('custom_group_id', '=', '$id')
117 ->addWhere('is_active', '=', 1)
118 ->addOrderBy('weight', 'ASC')
119 );
120 }
121 foreach ($customApi->execute() as $custom) {
fa8dc3f2 122 $name = 'afblockCustom_' . $custom['name'];
9c84a124
CW
123 if (!in_array($name, $names)) {
124 $names[] = $name;
125 }
126 $item = [
127 'name' => $name,
b1335297 128 'type' => 'block',
9c84a124 129 'requires' => [],
fa8dc3f2 130 'title' => E::ts('%1 block', [1 => $custom['title']]),
9c84a124 131 'description' => '',
1887d8bd 132 'is_dashlet' => FALSE,
9c84a124 133 'is_public' => FALSE,
053ab2a5 134 'is_token' => FALSE,
9c84a124 135 'permission' => 'access CiviCRM',
fa8dc3f2
CW
136 'join_entity' => 'Custom_' . $custom['name'],
137 'entity_type' => $custom['extends'],
6c108cab 138 'repeat' => $custom['max_multiple'] ?: TRUE,
9c84a124
CW
139 'has_base' => TRUE,
140 ];
141 if ($getLayout) {
142 $item['layout'] = ($custom['help_pre'] ? '<div class="af-markup">' . $custom['help_pre'] . "</div>\n" : '');
143 foreach ($custom['fields'] as $field) {
144 $item['layout'] .= "<af-field name=\"{$field['name']}\" />\n";
145 }
146 $item['layout'] .= ($custom['help_post'] ? '<div class="af-markup">' . $custom['help_post'] . "</div>\n" : '');
147 }
148 $values[$name] = $item;
149 }
11e724f0
TO
150 return $values;
151 }
152
153}