Afform - Support embedding afforms in WP shortcodes
authorColeman Watts <coleman@civicrm.org>
Sun, 28 Feb 2021 04:35:42 +0000 (23:35 -0500)
committerColeman Watts <coleman@civicrm.org>
Wed, 7 Apr 2021 03:06:35 +0000 (23:06 -0400)
This implements the necessary hooks & callbacks for picking an afform from the Civi shortcode popup,
and displaying the afform when viewing a single WP post/page or list of posts.

Note that unlike traditional Civi shortcodes, afform does not rely on invoking a civi page request,
but simply outputs the AngularJS directive.

ext/afform/core/afform.php

index 8fd080ea99eafcad4114bad8a2b8b63479bd72fb..08844f65b7f448396012a061077cadbe9656474a 100644 (file)
@@ -489,3 +489,62 @@ function afform_civicrm_alterApiRoutePermissions(&$permissions, $entity, $action
     }
   }
 }
+
+/**
+ * Implements hook_civicrm_preProcess().
+ *
+ * Wordpress only: Adds Afforms to the shortcode dialog (when editing pages/posts).
+ */
+function afform_civicrm_preProcess($formName, &$form) {
+  if ($formName === 'CRM_Core_Form_ShortCode') {
+    $form->components['afform'] = [
+      'label' => E::ts('Form Builder'),
+      'select' => [
+        'key' => 'name',
+        'entity' => 'Afform',
+        'select' => ['minimumInputLength' => 0],
+        'api' => [
+          'params' => ['type' => ['IN' => ['form', 'search']]],
+        ],
+      ],
+    ];
+  }
+}
+
+// Wordpress only: Register callback for rendering shortcodes
+if (function_exists('add_filter')) {
+  add_filter('civicrm_shortcode_get_markup', 'afform_shortcode_content', 10, 4);
+}
+
+/**
+ * Wordpress only: Render Afform content for shortcodes.
+ *
+ * @param string $content
+ *   HTML Markup
+ * @param array $atts
+ *   Shortcode attributes.
+ * @param array $args
+ *   Existing shortcode arguments.
+ * @param string $context
+ *   How many shortcodes are present on the page: 'single' or 'multiple'.
+ * @return string
+ *   Modified markup.
+ */
+function afform_shortcode_content($content, $atts, $args, $context) {
+  if ($atts['component'] === 'afform') {
+    $afform = civicrm_api4('Afform', 'get', [
+      'select' => ['directive_name', 'module_name'],
+      'where' => [['name', '=', $atts['name']]],
+    ])->first();
+    if ($afform) {
+      Civi::service('angularjs.loader')->addModules($afform['module_name']);
+      $content = "
+        <div class='crm-container' id='bootstrap-theme'>
+          <crm-angular-js modules='{$afform['module_name']}'>
+            <{$afform['directive_name']}></{$afform['directive_name']}>
+          </crm-angular-js>
+        </div>";
+    }
+  }
+  return $content;
+}