Update guzzle to 6.5.7
[civicrm-core.git] / ext / afform / core / afform.php
CommitLineData
66aa0f5e
TO
1<?php
2
3require_once 'afform.civix.php';
4use CRM_Afform_ExtensionUtil as E;
5
bc3b7c5b
TO
6/**
7 * Filter the content of $params to only have supported afform fields.
8 *
9 * @param array $params
10 * @return array
11 */
12function _afform_fields_filter($params) {
5591cfbf 13 $result = [];
67d666c6 14 $fields = \Civi\Api4\Afform::getfields(FALSE)->setAction('create')->execute()->indexBy('name');
50868e8d
CW
15 foreach ($fields as $fieldName => $field) {
16 if (isset($params[$fieldName])) {
17 $result[$fieldName] = $params[$fieldName];
d1ec770c 18
e38db494
CW
19 if ($field['data_type'] === 'Boolean' && !is_bool($params[$fieldName])) {
20 $result[$fieldName] = CRM_Utils_String::strtobool($params[$fieldName]);
d1ec770c
TO
21 }
22 }
bc3b7c5b
TO
23 }
24 return $result;
25}
26
8f4a0ee9 27/**
5591cfbf 28 * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
8f4a0ee9
TO
29 */
30function afform_civicrm_container($container) {
77dccccb 31 $container->addResource(new \Symfony\Component\Config\Resource\FileResource(__FILE__));
8f4a0ee9
TO
32 $container->setDefinition('afform_scanner', new \Symfony\Component\DependencyInjection\Definition(
33 'CRM_Afform_AfformScanner',
5591cfbf 34 []
b53fe171 35 ))->setPublic(TRUE);
8f4a0ee9
TO
36}
37
66aa0f5e
TO
38/**
39 * Implements hook_civicrm_config().
40 *
41 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_config
42 */
43function afform_civicrm_config(&$config) {
44 _afform_civix_civicrm_config($config);
77dccccb
TO
45
46 if (isset(Civi::$statics[__FUNCTION__])) {
47 return;
48 }
49 Civi::$statics[__FUNCTION__] = 1;
50
b7edd04e 51 $dispatcher = Civi::dispatcher();
07a1bc45
A
52 $dispatcher->addListener('civi.afform.submit', ['\Civi\Api4\Action\Afform\Submit', 'processGenericEntity'], 0);
53 $dispatcher->addListener('civi.afform.submit', ['\Civi\Api4\Action\Afform\Submit', 'preprocessContact'], 10);
e1f79950 54 $dispatcher->addListener('civi.afform.submit', ['\Civi\Api4\Action\Afform\Submit', 'processRelationships'], 1);
b7edd04e
TO
55 $dispatcher->addListener('hook_civicrm_angularModules', ['\Civi\Afform\AngularDependencyMapper', 'autoReq'], -1000);
56 $dispatcher->addListener('hook_civicrm_alterAngular', ['\Civi\Afform\AfformMetadataInjector', 'preprocess']);
bdceaf62 57 $dispatcher->addListener('hook_civicrm_check', ['\Civi\Afform\StatusChecks', 'hook_civicrm_check']);
92a43aef 58 $dispatcher->addListener('civi.afform.get', ['\Civi\Api4\Action\Afform\Get', 'getCustomGroupBlocks']);
b7edd04e
TO
59
60 // Register support for email tokens
bdceaf62
TO
61 if (CRM_Extension_System::singleton()->getMapper()->isActiveModule('authx')) {
62 $dispatcher->addListener('hook_civicrm_alterMailContent', ['\Civi\Afform\Tokens', 'applyCkeditorWorkaround']);
63 $dispatcher->addListener('hook_civicrm_tokens', ['\Civi\Afform\Tokens', 'hook_civicrm_tokens']);
64 $dispatcher->addListener('hook_civicrm_tokenValues', ['\Civi\Afform\Tokens', 'hook_civicrm_tokenValues']);
65 }
66aa0f5e
TO
66}
67
66aa0f5e
TO
68/**
69 * Implements hook_civicrm_install().
70 *
71 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_install
72 */
73function afform_civicrm_install() {
74 _afform_civix_civicrm_install();
75}
76
77/**
78 * Implements hook_civicrm_postInstall().
79 *
80 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_postInstall
81 */
82function afform_civicrm_postInstall() {
83 _afform_civix_civicrm_postInstall();
84}
85
86/**
87 * Implements hook_civicrm_uninstall().
88 *
89 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall
90 */
91function afform_civicrm_uninstall() {
92 _afform_civix_civicrm_uninstall();
93}
94
95/**
96 * Implements hook_civicrm_enable().
97 *
98 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_enable
99 */
100function afform_civicrm_enable() {
101 _afform_civix_civicrm_enable();
102}
103
104/**
105 * Implements hook_civicrm_disable().
106 *
107 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable
108 */
109function afform_civicrm_disable() {
110 _afform_civix_civicrm_disable();
111}
112
113/**
114 * Implements hook_civicrm_upgrade().
115 *
116 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_upgrade
117 */
118function afform_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
119 return _afform_civix_civicrm_upgrade($op, $queue);
120}
121
122/**
123 * Implements hook_civicrm_managed().
124 *
125 * Generate a list of entities to create/deactivate/delete when this module
126 * is installed, disabled, uninstalled.
127 *
128 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed
129 */
fdc67a75
TO
130function afform_civicrm_managed(&$entities, $modules) {
131 if ($modules && !in_array(E::LONG_NAME, $modules, TRUE)) {
132 return;
133 }
521b232a
TO
134 /** @var \CRM_Afform_AfformScanner $scanner */
135 if (\Civi::container()->has('afform_scanner')) {
136 $scanner = \Civi::service('afform_scanner');
137 }
138 else {
139 // This might happen at oddballs points - e.g. while you're in the middle of re-enabling the ext.
140 // This AfformScanner instance only lives during this method call, and it feeds off the regular cache.
141 $scanner = new CRM_Afform_AfformScanner();
142 }
143
144 foreach ($scanner->getMetas() as $afform) {
145 if (empty($afform['is_dashlet']) || empty($afform['name'])) {
146 continue;
147 }
148 $entities[] = [
149 'module' => E::LONG_NAME,
150 'name' => 'afform_dashlet_' . $afform['name'],
151 'entity' => 'Dashboard',
152 'update' => 'always',
153 // ideal cleanup policy might be to (a) deactivate if used and (b) remove if unused
154 'cleanup' => 'always',
155 'params' => [
9bed436a
CW
156 'version' => 4,
157 'values' => [
158 // Q: Should we loop through all domains?
159 'domain_id' => 'current_domain',
160 'is_active' => TRUE,
161 'name' => $afform['name'],
162 'label' => $afform['title'] ?? E::ts('(Untitled)'),
163 'directive' => _afform_angular_module_name($afform['name'], 'dash'),
164 'permission' => "@afform:" . $afform['name'],
165 'url' => NULL,
166 ],
521b232a
TO
167 ],
168 ];
169 }
66aa0f5e
TO
170}
171
172/**
c63f20d3 173 * Implements hook_civicrm_tabset().
66aa0f5e 174 *
c63f20d3
CW
175 * Adds afforms as contact summary tabs.
176 */
177function afform_civicrm_tabset($tabsetName, &$tabs, $context) {
178 if ($tabsetName !== 'civicrm/contact/view') {
179 return;
180 }
181 $scanner = \Civi::service('afform_scanner');
182 $weight = 111;
183 foreach ($scanner->getMetas() as $afform) {
184 if (!empty($afform['contact_summary']) && $afform['contact_summary'] === 'tab') {
185 $module = _afform_angular_module_name($afform['name']);
186 $tabs[] = [
187 'id' => $afform['name'],
188 'title' => $afform['title'],
189 'weight' => $weight++,
190 'icon' => 'crm-i fa-list-alt',
191 'is_active' => TRUE,
192 'template' => 'afform/contactSummary/AfformTab.tpl',
193 'module' => $module,
194 'directive' => _afform_angular_module_name($afform['name'], 'dash'),
195 ];
196 // If this is the real contact summary page (and not a callback from ContactLayoutEditor), load module.
197 if (empty($context['caller'])) {
198 Civi::service('angularjs.loader')->addModules($module);
199 }
200 }
201 }
202}
203
204/**
205 * Implements hook_civicrm_pageRun().
66aa0f5e 206 *
c63f20d3
CW
207 * Adds afforms as contact summary blocks.
208 */
209function afform_civicrm_pageRun(&$page) {
210 if (get_class($page) !== 'CRM_Contact_Page_View_Summary') {
211 return;
212 }
213 $scanner = \Civi::service('afform_scanner');
214 $cid = $page->get('cid');
215 $side = 'left';
216 foreach ($scanner->getMetas() as $afform) {
217 if (!empty($afform['contact_summary']) && $afform['contact_summary'] === 'block') {
218 $module = _afform_angular_module_name($afform['name']);
219 $block = [
220 'module' => $module,
221 'directive' => _afform_angular_module_name($afform['name'], 'dash'),
222 ];
223 $content = CRM_Core_Smarty::singleton()->fetchWith('afform/contactSummary/AfformBlock.tpl', ['contactId' => $cid, 'block' => $block]);
224 CRM_Core_Region::instance("contact-basic-info-$side")->add([
225 'markup' => '<div class="crm-summary-block">' . $content . '</div>',
226 'weight' => 1,
227 ]);
228 Civi::service('angularjs.loader')->addModules($module);
229 $side = $side === 'left' ? 'right' : 'left';
230 }
231 }
232}
233
234/**
235 * Implements hook_civicrm_contactSummaryBlocks().
66aa0f5e 236 *
c63f20d3 237 * @link https://github.com/civicrm/org.civicrm.contactlayout
66aa0f5e 238 */
c63f20d3 239function afform_civicrm_contactSummaryBlocks(&$blocks) {
4f664e9c
CW
240 $afforms = \Civi\Api4\Afform::get(FALSE)
241 ->setSelect(['name', 'title', 'directive_name', 'module_name', 'type', 'type:icon', 'type:label'])
242 ->addWhere('contact_summary', '=', 'block')
243 ->execute();
4096e4b0 244 foreach ($afforms as $index => $afform) {
4f664e9c
CW
245 // Create a group per afform type
246 $blocks += [
247 "afform_{$afform['type']}" => [
248 'title' => $afform['type:label'],
249 'icon' => $afform['type:icon'],
250 'blocks' => [],
251 ],
252 ];
253 $blocks["afform_{$afform['type']}"]['blocks'][$afform['name']] = [
254 'title' => $afform['title'],
255 'tpl_file' => 'afform/contactSummary/AfformBlock.tpl',
256 'module' => $afform['module_name'],
257 'directive' => $afform['directive_name'],
258 'sample' => [
259 $afform['type:label'],
260 ],
261 'edit' => 'civicrm/admin/afform#/edit/' . $afform['name'],
4096e4b0 262 'system_default' => [0, $index % 2],
4f664e9c 263 ];
c63f20d3 264 }
66aa0f5e
TO
265}
266
267/**
268 * Implements hook_civicrm_angularModules().
269 *
e1aca853 270 * Generate a list of Afform Angular modules.
66aa0f5e
TO
271 */
272function afform_civicrm_angularModules(&$angularModules) {
5e04a2d4 273 $afforms = \Civi\Api4\Afform::get(FALSE)
e38db494 274 ->setSelect(['name', 'requires', 'module_name', 'directive_name'])
2d4bfef1
CW
275 ->execute();
276
277 foreach ($afforms as $afform) {
e38db494 278 $angularModules[$afform['module_name']] = [
bb56ac78 279 'ext' => E::LONG_NAME,
2d4bfef1
CW
280 'js' => ['assetBuilder://afform.js?name=' . urlencode($afform['name'])],
281 'requires' => $afform['requires'],
bb56ac78 282 'basePages' => [],
aa6abb77 283 'partialsCallback' => '_afform_get_partials',
2d4bfef1 284 '_afform' => $afform['name'],
292054ac
CW
285 // TODO: Allow afforms to declare their own theming requirements
286 'bundles' => ['bootstrap3'],
77dccccb 287 'exports' => [
04417491 288 $afform['directive_name'] => 'E',
77dccccb 289 ],
bb56ac78 290 ];
bb56ac78 291 }
66aa0f5e
TO
292}
293
aa6abb77 294/**
2d4bfef1
CW
295 * Callback to retrieve partials for a given afform/angular module.
296 *
297 * @see afform_civicrm_angularModules
aa6abb77
TO
298 *
299 * @param string $moduleName
300 * The module name.
301 * @param array $module
302 * The module definition.
303 * @return array
304 * Array(string $filename => string $html).
2d4bfef1 305 * @throws API_Exception
aa6abb77
TO
306 */
307function _afform_get_partials($moduleName, $module) {
2d4bfef1
CW
308 $afform = civicrm_api4('Afform', 'get', [
309 'where' => [['name', '=', $module['_afform']]],
310 'select' => ['layout'],
311 'layoutFormat' => 'html',
312 'checkPermissions' => FALSE,
313 ], 0);
aa6abb77 314 return [
2d4bfef1 315 "~/$moduleName/$moduleName.aff.html" => $afform['layout'],
aa6abb77
TO
316 ];
317}
318
66aa0f5e
TO
319/**
320 * Implements hook_civicrm_entityTypes().
321 *
322 * Declare entity types provided by this module.
323 *
324 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_entityTypes
325 */
326function afform_civicrm_entityTypes(&$entityTypes) {
327 _afform_civix_civicrm_entityTypes($entityTypes);
328}
329
bb56ac78
TO
330/**
331 * Implements hook_civicrm_buildAsset().
332 */
333function afform_civicrm_buildAsset($asset, $params, &$mimeType, &$content) {
334 if ($asset !== 'afform.js') {
335 return;
336 }
337
338 if (empty($params['name'])) {
339 throw new RuntimeException("Missing required parameter: afform.js?name=NAME");
340 }
341
2d4bfef1 342 $moduleName = _afform_angular_module_name($params['name'], 'camel');
b6e13973
SL
343 $formMetaData = (array) civicrm_api4('Afform', 'get', [
344 'checkPermissions' => FALSE,
007167df 345 'select' => ['redirect', 'name', 'title'],
b6e13973
SL
346 'where' => [['name', '=', $params['name']]],
347 ], 0);
bb56ac78
TO
348 $smarty = CRM_Core_Smarty::singleton();
349 $smarty->assign('afform', [
aa6abb77 350 'camel' => $moduleName,
b6e13973 351 'meta' => $formMetaData,
aa6abb77 352 'templateUrl' => "~/$moduleName/$moduleName.aff.html",
bb56ac78
TO
353 ]);
354 $mimeType = 'text/javascript';
9ec944f2 355 $content = $smarty->fetch('afform/AfformAngularModule.tpl');
bb56ac78
TO
356}
357
8775c48a
TO
358/**
359 * Implements hook_civicrm_alterMenu().
360 */
361function afform_civicrm_alterMenu(&$items) {
92a43aef
CW
362 try {
363 $afforms = \Civi\Api4\Afform::get(FALSE)
364 ->addWhere('server_route', 'IS NOT EMPTY')
365 ->addSelect('name', 'server_route', 'is_public')
366 ->execute()->indexBy('name');
8f4a0ee9 367 }
92a43aef 368 catch (Exception $e) {
8f4a0ee9
TO
369 // During installation...
370 $scanner = new CRM_Afform_AfformScanner();
92a43aef 371 $afforms = $scanner->getMetas();
8f4a0ee9 372 }
92a43aef 373 foreach ($afforms as $name => $meta) {
8775c48a
TO
374 if (!empty($meta['server_route'])) {
375 $items[$meta['server_route']] = [
376 'page_callback' => 'CRM_Afform_Page_AfformBase',
377 'page_arguments' => 'afform=' . urlencode($name),
f16b2aee 378 'access_arguments' => [["@afform:$name"], 'and'],
254f01f0 379 'is_public' => $meta['is_public'],
8775c48a
TO
380 ];
381 }
382 }
f16b2aee
TO
383}
384
92d6b3d4
CW
385/**
386 * Implements hook_civicrm_permission().
387 *
388 * Define Afform permissions.
389 */
390function afform_civicrm_permission(&$permissions) {
391 $permissions['administer afform'] = [
392 E::ts('Form Builder: edit and delete forms'),
393 E::ts('Allows non-admin users to create, update and delete forms'),
394 ];
395}
396
f16b2aee
TO
397/**
398 * Implements hook_civicrm_permission_check().
399 *
586344a7
TO
400 * This extends the list of permissions available in `CRM_Core_Permission:check()`
401 * by introducing virtual-permissions named `@afform:myForm`. The evaluation
402 * of these virtual-permissions is dependent on the settings for `myForm`.
403 * `myForm` may be exposed/integrated through multiple subsystems (routing,
404 * nav-menu, API, etc), and the use of virtual-permissions makes easy to enforce
405 * consistent permissions across any relevant subsystems.
406 *
f16b2aee
TO
407 * @see CRM_Utils_Hook::permission_check()
408 */
409function afform_civicrm_permission_check($permission, &$granted, $contactId) {
14b26ac5 410 if ($permission[0] !== '@') {
f16b2aee
TO
411 // Micro-optimization - this function may get hit a lot.
412 return;
413 }
414
415 if (preg_match('/^@afform:(.*)/', $permission, $m)) {
416 $name = $m[1];
417
2d4bfef1
CW
418 $afform = \Civi\Api4\Afform::get()
419 ->setCheckPermissions(FALSE)
420 ->addWhere('name', '=', $name)
421 ->setSelect(['permission'])
422 ->execute()
423 ->first();
424 if ($afform) {
425 $granted = CRM_Core_Permission::check($afform['permission'], $contactId);
426 }
f16b2aee 427 }
8775c48a
TO
428}
429
c4e6b413
TO
430/**
431 * Implements hook_civicrm_permissionList().
432 *
433 * @see CRM_Utils_Hook::permissionList()
434 */
435function afform_civicrm_permissionList(&$permissions) {
436 $scanner = Civi::service('afform_scanner');
437 foreach ($scanner->getMetas() as $name => $meta) {
438 $permissions['@afform:' . $name] = [
439 'group' => 'afform',
67d666c6 440 'title' => E::ts('Afform: Inherit permission of %1', [
c4e6b413
TO
441 1 => $name,
442 ]),
443 ];
444 }
445}
446
74f862e4
TO
447/**
448 * Clear any local/in-memory caches based on afform data.
449 */
450function _afform_clear() {
451 $container = \Civi::container();
452 $container->get('afform_scanner')->clear();
76b9562a 453 $container->get('angular')->clear();
74f862e4
TO
454}
455
bb56ac78 456/**
87dde5eb
TO
457 * @param string $fileBaseName
458 * Ex: foo-bar
841850b1
TO
459 * @param string $format
460 * 'camel' or 'dash'.
bb56ac78 461 * @return string
841850b1 462 * Ex: 'FooBar' or 'foo-bar'.
3cd5c38b 463 * @throws \Exception
bb56ac78 464 */
87dde5eb 465function _afform_angular_module_name($fileBaseName, $format = 'camel') {
841850b1
TO
466 switch ($format) {
467 case 'camel':
87dde5eb 468 $camelCase = '';
9c84a124 469 foreach (preg_split('/[-_ ]/', $fileBaseName, NULL, PREG_SPLIT_NO_EMPTY) as $shortNamePart) {
87dde5eb
TO
470 $camelCase .= ucfirst($shortNamePart);
471 }
14b26ac5 472 return strtolower($camelCase[0]) . substr($camelCase, 1);
841850b1
TO
473
474 case 'dash':
9c84a124 475 return strtolower(implode('-', preg_split('/[-_ ]|(?=[A-Z])/', $fileBaseName, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE)));
841850b1
TO
476
477 default:
478 throw new \Exception("Unrecognized format");
479 }
bb56ac78 480}
355881ac
SL
481
482/**
483 * Implements hook_civicrm_alterApiRoutePermissions().
484 *
485 * @see CRM_Utils_Hook::alterApiRoutePermissions
486 */
487function afform_civicrm_alterApiRoutePermissions(&$permissions, $entity, $action) {
f362c531 488 if ($entity == 'Afform') {
db393580
CW
489 // These actions should be accessible to anonymous users; permissions are checked internally
490 $allowedActions = ['prefill', 'submit', 'submitFile', 'getOptions'];
491 if (in_array($action, $allowedActions, TRUE)) {
f362c531
TO
492 $permissions = CRM_Core_Permission::ALWAYS_ALLOW_PERMISSION;
493 }
355881ac
SL
494 }
495}
f228ad74
CW
496
497/**
498 * Implements hook_civicrm_preProcess().
499 *
500 * Wordpress only: Adds Afforms to the shortcode dialog (when editing pages/posts).
501 */
502function afform_civicrm_preProcess($formName, &$form) {
503 if ($formName === 'CRM_Core_Form_ShortCode') {
504 $form->components['afform'] = [
505 'label' => E::ts('Form Builder'),
506 'select' => [
507 'key' => 'name',
508 'entity' => 'Afform',
509 'select' => ['minimumInputLength' => 0],
510 'api' => [
511 'params' => ['type' => ['IN' => ['form', 'search']]],
512 ],
513 ],
514 ];
515 }
516}
517
1c3d1f8d
CW
518/**
519 * Implements hook_civicrm_pre().
520 */
521function afform_civicrm_pre($op, $entity, $id, &$params) {
522 // When deleting a searchDisplay, also delete any Afforms the display is embedded within
523 if ($entity === 'SearchDisplay' && $op === 'delete') {
524 $display = \Civi\Api4\SearchDisplay::get(FALSE)
525 ->addSelect('saved_search_id.name', 'name')
526 ->addWhere('id', '=', $id)
527 ->execute()->first();
528 \Civi\Api4\Afform::revert(FALSE)
529 ->addWhere('search_displays', 'CONTAINS', $display['saved_search_id.name'] . ".{$display['name']}")
530 ->execute();
531 }
04309075 532 // When deleting a savedSearch, delete any Afforms which use the default display
b6553656 533 elseif ($entity === 'SavedSearch' && $op === 'delete') {
04309075
CW
534 $search = \Civi\Api4\SavedSearch::get(FALSE)
535 ->addSelect('name')
536 ->addWhere('id', '=', $id)
537 ->execute()->first();
538 \Civi\Api4\Afform::revert(FALSE)
539 ->addWhere('search_displays', 'CONTAINS', $search['name'])
540 ->execute();
541 }
542}
543
544/**
545 * Implements hook_civicrm_referenceCounts().
546 */
547function afform_civicrm_referenceCounts($dao, &$counts) {
548 // Count afforms which contain a search display
549 if (is_a($dao, 'CRM_Search_DAO_SearchDisplay') && $dao->id) {
550 if (empty($dao->saved_search_id) || empty($dao->name)) {
551 $dao->find(TRUE);
552 }
553 $search = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $dao->saved_search_id);
554 $afforms = \Civi\Api4\Afform::get(FALSE)
555 ->selectRowCount()
556 ->addWhere('search_displays', 'CONTAINS', "$search.$dao->name")
557 ->execute();
558 if ($afforms->count()) {
559 $counts[] = [
560 'name' => 'Afform',
561 'type' => 'Afform',
562 'count' => $afforms->count(),
563 ];
564 }
565 }
566 // Count afforms which contain any displays from a SavedSearch (including the default display)
567 elseif (is_a($dao, 'CRM_Contact_DAO_SavedSearch') && $dao->id) {
568 if (empty($dao->name)) {
569 $dao->find(TRUE);
570 }
571 $clauses = [
572 ['search_displays', 'CONTAINS', $dao->name],
573 ];
574 try {
575 $displays = civicrm_api4('SearchDisplay', 'get', [
576 'where' => [['saved_search_id', '=', $dao->id]],
577 'select' => 'name',
578 ], ['name']);
579 foreach ($displays as $displayName) {
580 $clauses[] = ['search_displays', 'CONTAINS', $dao->name . '.' . $displayName];
581 }
582 }
583 catch (Exception $e) {
584 // In case SearchKit is not installed, the api call would fail
585 }
586 $afforms = \Civi\Api4\Afform::get(FALSE)
587 ->selectRowCount()
588 ->addClause('OR', $clauses)
589 ->execute();
590 if ($afforms->count()) {
591 $counts[] = [
592 'name' => 'Afform',
593 'type' => 'Afform',
594 'count' => $afforms->count(),
595 ];
596 }
597 }
1c3d1f8d
CW
598}
599
f228ad74
CW
600// Wordpress only: Register callback for rendering shortcodes
601if (function_exists('add_filter')) {
602 add_filter('civicrm_shortcode_get_markup', 'afform_shortcode_content', 10, 4);
603}
604
605/**
606 * Wordpress only: Render Afform content for shortcodes.
607 *
608 * @param string $content
609 * HTML Markup
610 * @param array $atts
611 * Shortcode attributes.
612 * @param array $args
613 * Existing shortcode arguments.
614 * @param string $context
615 * How many shortcodes are present on the page: 'single' or 'multiple'.
616 * @return string
617 * Modified markup.
618 */
619function afform_shortcode_content($content, $atts, $args, $context) {
620 if ($atts['component'] === 'afform') {
621 $afform = civicrm_api4('Afform', 'get', [
622 'select' => ['directive_name', 'module_name'],
623 'where' => [['name', '=', $atts['name']]],
624 ])->first();
625 if ($afform) {
626 Civi::service('angularjs.loader')->addModules($afform['module_name']);
627 $content = "
628 <div class='crm-container' id='bootstrap-theme'>
629 <crm-angular-js modules='{$afform['module_name']}'>
630 <{$afform['directive_name']}></{$afform['directive_name']}>
631 </crm-angular-js>
632 </div>";
633 }
634 }
635 return $content;
636}