Skip to content
Snippets Groups Projects
Commit 9f3da56a authored by Christian Wach's avatar Christian Wach :soccer:
Browse files

Initial commit

parent 9db58788
No related branches found
No related tags found
No related merge requests found
# Conditional Form Actions for ACFE # Conditional Form Actions for ACFE
Adds some Form Actions to ACFE that have a Conditional Field through which the Action can be bypassed. Adds some Form Actions to *ACF Extended* that have a Conditional Field through which the Action can be bypassed.
\ No newline at end of file
## Basic Usage
When creating an *ACF Extended* Form, you will see some new Form Actions:
* _Conditional Redirect action_
* _Conditional Email action_
* _WooCommerce Product action_
Add them to your *ACF Extended* Form to make use of the functionality that they offer.
## Installation
There are two ways to install from GitLab:
### ZIP Download
If you have downloaded *Conditional Form Actions for ACFE* as a ZIP file from the GitLab repository, do the following to install the plugin:
1. Unzip the .zip file and, if needed, rename the enclosing folder so that the plugin's files are located directly inside `/wp-content/plugins/conditional-form-actions-for-acfe`
2. *Conditional Form Actions for ACFE* is installed.
### git clone
If you have cloned the code from GitLab, it is assumed that you know what you're doing.
<?php /*
--------------------------------------------------------------------------------
Plugin Name: Conditional Form Actions for ACFE
Plugin URI: https://develop.tadpole.cc/plugins/conditional-form-actions-for-acfe
Description: Provides some ACF Extended Form Actions that have a Conditional Field.
Author: Christian Wach
Version: 0.1
Author URI: https://haystack.co.uk
Text Domain: conditional-form-actions-for-acfe
Domain Path: /languages
--------------------------------------------------------------------------------
*/
// Set plugin version here.
define( 'CFAFA_VERSION', '0.1' );
// Store reference to this file.
if ( ! defined( 'CFAFA_FILE' ) ) {
define( 'CFAFA_FILE', __FILE__ );
}
// Store URL to this plugin's directory.
if ( ! defined( 'CFAFA_URL' ) ) {
define( 'CFAFA_URL', plugin_dir_url( CFAFA_FILE ) );
}
// Store PATH to this plugin's directory.
if ( ! defined( 'CFAFA_PATH' ) ) {
define( 'CFAFA_PATH', plugin_dir_path( CFAFA_FILE ) );
}
/**
* Conditional Form Actions for ACFE Class.
*
* A class that encapsulates this plugin's functionality.
*
* @since 0.1
*/
class Conditional_Form_Actions_For_ACFE {
/**
* ACF Extended object.
*
* @since 0.1
* @access public
* @var object $acfe The ACF Extended object.
*/
public $acfe;
/**
* Initialises this object.
*
* @since 0.1
*/
public function __construct() {
// Always load translations.
add_action( 'plugins_loaded', [ $this, 'translation' ] );
// Initialise when ACF Extended is initialised.
add_action( 'acfe/init', [ $this, 'initialise' ] );
}
/**
* Initialise this plugin.
*
* @since 0.1
*/
public function initialise() {
// Only do this once.
static $done;
if ( isset( $done ) && $done === true ) {
return;
}
// Include files.
$this->include_files();
// Set up objects and references.
$this->setup_objects();
/**
* Broadcast that this plugin is loaded.
*
* @since 0.1
*/
do_action( 'cfafa/loaded' );
// We're done.
$done = true;
}
/**
* Enable translation.
*
* @since 0.1
*/
public function translation() {
// Load translations.
load_plugin_textdomain(
'conditional-form-actions-for-acfe', // Unique name.
false, // Deprecated argument.
dirname( plugin_basename( CFAFA_FILE ) ) . '/languages/' // Relative path to files.
);
}
/**
* Include files.
*
* @since 0.1
*/
public function include_files() {
// Load our class files.
require CFAFA_PATH . 'includes/cfafa-acfe.php';
}
/**
* Set up this plugin's objects.
*
* @since 0.1
*/
public function setup_objects() {
// Initialise objects.
$this->acfe = new CFAFA_ACFE( $this );
}
/**
* Check if this plugin is network activated.
*
* @since 0.1
*
* @return bool $is_network_active True if network activated, false otherwise.
*/
public function is_network_activated() {
// Only need to test once.
static $is_network_active;
// Have we done this already?
if ( isset( $is_network_active ) ) {
return $is_network_active;
}
// If not multisite, it cannot be.
if ( ! is_multisite() ) {
$is_network_active = false;
return $is_network_active;
}
// Make sure plugin file is included when outside admin.
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
require_once ABSPATH . '/wp-admin/includes/plugin.php';
}
// Get path from 'plugins' directory to this plugin.
$this_plugin = plugin_basename( CFAFA_FILE );
// Test if network active.
$is_network_active = is_plugin_active_for_network( $this_plugin );
// --<
return $is_network_active;
}
} // Class ends.
/**
* Load plugin if not yet loaded and return reference.
*
* @since 0.1
*
* @return Conditional_Form_Actions_For_ACFE $plugin The plugin reference.
*/
function cfafa() {
// Declare as global.
static $plugin;
// Instantiate plugin if not yet instantiated.
if ( ! isset( $plugin ) ) {
$plugin = new Conditional_Form_Actions_For_ACFE();
}
// --<
return $plugin;
}
// Load immediately.
cfafa();
/**
* Performs plugin activation tasks.
*
* @since 0.1
*/
function cfafa_activate() {
/**
* Broadcast that this plugin has been activated.
*
* @since 0.1
*/
do_action( 'cfafa/activated' );
}
// Activation.
register_activation_hook( __FILE__, 'cfafa_activate' );
/**
* Performs plugin deactivation tasks.
*
* @since 0.1
*/
function cfafa_deactivated() {
/**
* Broadcast that this plugin has been deactivated.
*
* @since 0.1
*/
do_action( 'cfafa/deactivated' );
}
// Deactivation.
register_deactivation_hook( __FILE__, 'cfafa_deactivated' );
// Uninstall uses the 'uninstall.php' method.
// See: http://codex.wordpress.org/Function_Reference/register_uninstall_hook
<?php
/**
* ACFE Form Class.
*
* Handles compatibility with ACFE Forms.
*
* @package Conditional_Form_Actions_For_ACFE
* @since 0.1
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* CiviCRM Profile Sync ACFE Form Class.
*
* A class that handles compatibility with ACFE Forms.
*
* @since 0.1
*/
class CFAFA_Form {
/**
* Plugin object.
*
* @since 0.1
* @access public
* @var object $plugin The plugin object.
*/
public $plugin;
/**
* ACF Loader object.
*
* @since 0.1
* @access public
* @var object $acf_loader The ACF Loader object.
*/
public $acf_loader;
/**
* CiviCRM object.
*
* @since 0.1
* @access public
* @var object $civicrm The CiviCRM object.
*/
public $civicrm;
/**
* ACF object.
*
* @since 0.1
* @access public
* @var object $acf The ACF object.
*/
public $acf;
/**
* Parent (calling) object.
*
* @since 0.1
* @access public
* @var object $acfe The parent object.
*/
public $acfe;
/**
* Supported Location Rule name.
*
* @since 0.1
* @access public
* @var string $rule_name The supported Location Rule name.
*/
public $rule_name = 'form_civicrm';
/**
* Constructor.
*
* @since 0.1
*
* @param object $parent The parent object reference.
*/
public function __construct( $parent ) {
// Store references to objects.
$this->plugin = $parent->acf_loader->plugin;
$this->acf_loader = $parent->acf_loader;
$this->civicrm = $this->acf_loader->civicrm;
$this->acf = $this->acf_loader->acf;
$this->acfe = $parent;
// Init when this plugin is loaded.
add_action( 'cfafa/acf/acfe/loaded', [ $this, 'initialise' ] );
}
/**
* Initialise this object.
*
* @since 0.1
*/
public function initialise() {
// Include files.
$this->include_files();
// Register Location Types.
$this->register_location_types();
// Register hooks.
$this->register_hooks();
}
/**
* Include files.
*
* @since 0.1
*/
public function include_files() {
}
/**
* Register WordPress hooks.
*
* @since 0.1
*/
public function register_hooks() {
// Listen for queries from the ACF Field Group class.
add_filter( 'cfafa/acf/query_field_group_mapped', [ $this, 'query_field_group_mapped' ], 10, 2 );
add_filter( 'cfafa/acf/field_group/query_supported_rules', [ $this, 'query_supported_rules' ], 10, 4 );
// Listen for queries from the ACF Field class.
add_filter( 'cfafa/acf/query_settings_field', [ $this, 'query_settings_field' ], 200, 3 );
// Register ACFE Form Actions.
add_filter( 'acfe/include_form_actions', [ $this, 'register_form_actions' ] );
// Add Form Actions Javascript.
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_form_action_scripts' ] );
// Add Form Actions Javascript.
add_action( 'acfe/form/submit', [ $this, 'form_action_query_vars_clear' ] );
// Set a better Form Wrapper class.
add_filter( 'acfe/form/load', [ $this, 'form_wrapper' ], 10, 2 );
}
/**
* Clear the Form Action Query Vars.
*
* This means we get a fresh set of Query Vars during the load process after
* a Form has been submitted.
*
* @since 0.1
*/
public function form_action_query_vars_clear() {
// Clear the array of Action results.
set_query_var( 'acfe_form_actions', [] );
}
/**
* Alters the default "Success Wrapper" class.
*
* @since 0.1
*
* @param array $form The ACF Form data array.
* @param integer $post_id The numeric ID of the WordPress Post.
* @return array $form The modified ACF Form data array.
*/
public function form_wrapper( $form, $post_id ) {
// Alter the default "Success Wrapper".
if ( $form['html_updated_message'] === '<div id="message" class="updated">%s</div>' ) {
$form['html_updated_message'] = '<div id="message" class="acfe-success">%s</div>';
}
// --<
return $form;
}
/**
* Register Location Types.
*
* @since 0.1
*/
public function register_location_types() {
// Bail if less than ACF 5.9.0.
if ( ! function_exists( 'acf_register_location_type' ) ) {
return;
}
// Include Location Rule class files.
include CIVICRM_WP_PROFILE_SYNC_PATH . 'includes/acf/acfe/locations/cfafa-acf-acfe-location-bypass.php';
// Register Location Types with ACF.
acf_register_location_type( 'CiviCRM_Profile_Sync_ACF_Location_Type_Bypass' );
}
/**
* Register Form Actions.
*
* @since 0.1
*/
public function register_form_actions() {
// Include Form Action base class.
include CIVICRM_WP_PROFILE_SYNC_PATH . 'includes/acf/acfe/form-actions/cfafa-acf-acfe-form-action-base.php';
// Include Form Action classes.
include CIVICRM_WP_PROFILE_SYNC_PATH . 'includes/acf/acfe/form-actions/cfafa-acf-acfe-form-action-contact.php';
include CIVICRM_WP_PROFILE_SYNC_PATH . 'includes/acf/acfe/form-actions/cfafa-acf-acfe-form-action-activity.php';
include CIVICRM_WP_PROFILE_SYNC_PATH . 'includes/acf/acfe/form-actions/cfafa-acf-acfe-form-action-participant.php';
include CIVICRM_WP_PROFILE_SYNC_PATH . 'includes/acf/acfe/form-actions/cfafa-acf-acfe-form-action-redirect.php';
// Init Form Actions.
new CFAFA_Form_Action_Contact( $this );
new CFAFA_Form_Action_Activity( $this );
new CFAFA_Form_Action_Participant( $this );
new CFAFA_Form_Action_Redirect( $this );
// Init Case Action if the CiviCase component is active.
$case_active = $this->plugin->civicrm->is_component_enabled( 'CiviCase' );
if ( $case_active ) {
include CIVICRM_WP_PROFILE_SYNC_PATH . 'includes/acf/acfe/form-actions/cfafa-acf-acfe-form-action-case.php';
new CFAFA_Form_Action_Case( $this );
}
// Init Email Action if the "Email API" Extension is active.
$email_active = $this->plugin->civicrm->is_extension_enabled( 'org.civicoop.emailapi' );
if ( $email_active ) {
include CIVICRM_WP_PROFILE_SYNC_PATH . 'includes/acf/acfe/form-actions/cfafa-acf-acfe-form-action-email.php';
new CFAFA_Form_Action_Email( $this );
}
if ( function_exists( 'WC' ) ) {
include CIVICRM_WP_PROFILE_SYNC_PATH . 'includes/acf/acfe/form-actions/cfafa-acf-acfe-form-action-product.php';
new CFAFA_Form_Action_Product( $this );
}
}
/**
* Enqueue Form Action Javascript.
*
* @since 0.1
*/
public function enqueue_form_action_scripts() {
// Bail if the current screen is not an Edit ACFE Form screen.
$screen = get_current_screen();
if ( ! ( $screen instanceof WP_Screen ) ) {
return;
}
if ( $screen->base != 'post' || $screen->id != 'acfe-form' ) {
return;
}
// Add JavaScript plus dependencies.
wp_enqueue_script(
'cfafa-acfe-form-actions',
plugins_url( 'assets/js/acf/acfe/form-actions/cfafa-form-action-model.js', CIVICRM_WP_PROFILE_SYNC_FILE ),
[ 'acf-extended' ],
CIVICRM_WP_PROFILE_SYNC_VERSION // Version.
);
// Init the Contact Reference Field actions array.
$contact_action_refs = [
// Contact Actions must always be present.
'new_field/key=field_cfafa_contact_action_custom_alias' => 'newContactActionAlias',
'remove_field/key=field_cfafa_contact_action_custom_alias' => 'removeContactActionAlias',
];
/**
* Query Form Action classes to build the Contact Reference Fields ACF Model actions array.
*
* @since 0.1
*
* @param array $contact_action_refs The ACF Model actions array to be populated.
*/
$contact_actions = apply_filters( 'cfafa/acf/acfe/form_actions/reference_fields/contact', $contact_action_refs );
// Init the Case Reference Field actions array.
$case_action_refs = [
// Case Actions must always be present.
'new_field/key=field_cfafa_case_action_custom_alias' => 'newCaseActionAlias',
'remove_field/key=field_cfafa_case_action_custom_alias' => 'removeCaseActionAlias',
];
/**
* Query Form Action classes to build the Case Reference Fields ACF Model actions array.
*
* @since 0.1
*
* @param array $case_action_refs The ACF Model actions array to be populated.
*/
$case_actions = apply_filters( 'cfafa/acf/acfe/form_actions/reference_fields/case', $case_action_refs );
// Init the Participant Reference Field actions array.
$participant_action_refs = [
// Participant Actions must always be present.
'new_field/key=field_cfafa_participant_action_custom_alias' => 'newParticipantActionAlias',
'remove_field/key=field_cfafa_participant_action_custom_alias' => 'removeParticipantActionAlias',
];
/**
* Query Form Action classes to build the Participant Reference Fields ACF Model actions array.
*
* @since 0.1
*
* @param array $participant_action_refs The ACF Model actions array to be populated.
*/
$participant_actions = apply_filters( 'cfafa/acf/acfe/form_actions/reference_fields/participant', $participant_action_refs );
// Build data array.
$vars = [
'localisation' => [],
'settings' => [
'contact_actions_reference' => $contact_actions,
'case_actions_reference' => $case_actions,
'participant_actions_reference' => $participant_actions,
],
];
// Localize our script.
wp_localize_script(
'cfafa-acfe-form-actions',
'CWPS_ACFE_Form_Action_Vars',
$vars
);
}
// -------------------------------------------------------------------------
/**
* Listen for queries from the Field Group class.
*
* This method responds with a Boolean if it detects that this Field Group
* should bypass ACF.
*
* @since 0.1
*
* @param bool $mapped The existing mapping flag.
* @param array $field_group The array of ACF Field Group data.
* @param bool $mapped True if the Field Group should bypass ACF, or pass through if not.
*/
public function query_field_group_mapped( $mapped, $field_group ) {
// Bail if a Mapping has already been found.
if ( $mapped !== false ) {
return $mapped;
}
// Bail if this is not a Bypass Field Group.
$is_bypass_field_group = $this->is_bypass_field_group( $field_group );
if ( $is_bypass_field_group === false ) {
return $mapped;
}
// --<
return true;
}
/**
* Check if this Field Group should bypass ACF.
*
* @since 0.1
*
* @param array $field_group The Field Group to check.
* @return array|bool The array of Entities if the Field Group should bypass ACF, or false otherwise.
*/
public function is_bypass_field_group( $field_group ) {
// Bail if there's no Field Group ID.
if ( empty( $field_group['ID'] ) ) {
return false;
}
// Only do this once per Field Group.
static $pseudocache;
if ( isset( $pseudocache[ $field_group['ID'] ] ) ) {
return $pseudocache[ $field_group['ID'] ];
}
// Assume not visible.
$is_visible = false;
// Bail if no Location Rules exist.
if ( ! empty( $field_group['location'] ) ) {
// We only need the key to test for an ACF Bypass location.
$params = [
$this->rule_name => 'foo',
];
// Do the check.
$is_visible = $this->acf_loader->acf->field_group->is_visible( $field_group, $params );
}
// Maybe add to pseudo-cache.
if ( ! isset( $pseudocache[ $field_group['ID'] ] ) ) {
$pseudocache[ $field_group['ID'] ] = $is_visible;
}
// --<
return $is_visible;
}
/**
* Listen for queries for supported Location Rules.
*
* @since 0.1
*
* @param bool $supported The existing supported Location Rules status.
* @param array $rule The Location Rule.
* @param array $params The query params array.
* @param array $field_group The ACF Field Group data array.
* @return bool $supported The modified supported Location Rules status.
*/
public function query_supported_rules( $supported, $rule, $params, $field_group ) {
// Bail if already supported.
if ( $supported === true ) {
return $supported;
}
// Test for this Location Rule.
if ( $rule['param'] == $this->rule_name && ! empty( $params[$this->rule_name] ) ) {
$supported = true;
}
// --<
return $supported;
}
// -------------------------------------------------------------------------
/**
* Returns a Setting Field from this Entity when found.
*
* @since 0.1
*
* @param array $setting_field The existing Setting Field array.
* @param array $field The ACF Field data array.
* @param array $field_group The ACF Field Group data array.
* @return array|bool $setting_field The Setting Field array if populated, false if conflicting.
*/
public function query_settings_field( $setting_field, $field, $field_group ) {
// Pass if conflicting Fields have been found.
if ( $setting_field === false ) {
return false;
}
// Pass if this is not a Bypass Field Group.
$is_visible = $this->is_bypass_field_group( $field_group );
if ( $is_visible === false ) {
return $setting_field;
}
// If already populated, then this is a conflicting Field.
if ( ! empty( $setting_field ) ) {
return false;
}
// Get the array of Entities and IDs.
$entity_array = $this->entity_mapping_extract( $field_group['location'] );
/**
* Request an array of Setting Field choices from Entity classes.
*
* @since 0.1
*
* @param array The empty default Setting Field choices array.
* @param array $field The ACF Field data array.
* @param array $field_group The ACF Field Group data array.
* @param array $entity_array The array of Entities and IDs.
*/
$choices = apply_filters( 'cfafa/acf/bypass/query_settings_choices', [], $field, $field_group, $entity_array );
// Bail if there aren't any.
if ( empty( $choices ) ) {
return false;
}
// Define Setting Field.
$setting_field = [
'key' => $this->civicrm->acf_field_key_get(),
'label' => __( 'CiviCRM Field', 'conditional-form-actions-for-acfe' ),
'name' => $this->civicrm->acf_field_key_get(),
'type' => 'select',
'instructions' => __( 'Choose the CiviCRM Field that this ACF Field should sync with. (Optional)', 'conditional-form-actions-for-acfe' ),
'default_value' => '',
'placeholder' => '',
'allow_null' => 1,
'multiple' => 0,
'ui' => 0,
'required' => 0,
'return_format' => 'value',
'parent' => $this->acf->field_group->placeholder_group_get(),
'choices' => $choices,
];
// Return populated array.
return $setting_field;
}
/**
* Returns an array containing the Entities and their IDs.
*
* @since 0.1
*
* @param array $location_rules The Location Rules for the Field.
* @return array $entity_mapping The array containing the Entities and IDs.
*/
public function entity_mapping_extract( $location_rules ) {
// Init an empty Entity mapping array.
$entity_mapping = [];
// The Location Rules outer array is made of "grouos".
foreach ( $location_rules as $group ) {
// Skip group if it has no rules.
if ( empty( $group ) ) {
continue;
}
// The Location Rules inner array is made of "rules".
foreach ( $group as $rule ) {
// Is this a Bypass rule?
if ( $rule['param'] === $this->rule_name ) {
// Extract the Entity and ID.
//$entity_map = [];
$tmp = explode( '-', $rule['value'] );
//$entity_map[] = [ 'entity' => $tmp[0], 'entity_id' => (int) $tmp[1] ];
// Add to return.
$entity_mapping[ $tmp[0] ][] = (int) $tmp[1];
}
}
}
// --<
return $entity_mapping;
}
} // Class ends.
<?php
/**
* ACF Extended Class.
*
* Handles general "ACF Extended" functionality.
*
* @package Conditional_Form_Actions_For_ACFE
* @since 0.1
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* "ACF Extended" Class.
*
* A class that encapsulates ACF Extended functionality.
*
* @since 0.1
*/
class CFAFA_ACFE {
/**
* Plugin object.
*
* @since 0.1
* @access public
* @var object $plugin The plugin object.
*/
public $plugin;
/**
* Constructor.
*
* @since 0.1
*
* @param object $plugin The plugin object.
*/
public function __construct( $plugin ) {
// Store references to objects.
$this->plugin = $plugin;
// Init when ACF class is loaded.
add_action( 'cfafa/loaded', [ $this, 'initialise' ] );
}
/**
* Initialise this object.
*
* @since 0.1
*/
public function initialise() {
// Only do this once.
static $done;
if ( isset( $done ) && $done === true ) {
return;
}
// Register hooks.
$this->register_hooks();
/**
* Broadcast that this class is now loaded.
*
* @since 0.1
*/
do_action( 'cfafa/acfe/loaded' );
// We're done and loaded.
$done = true;
}
/**
* Register hooks.
*
* @since 0.1
*/
public function register_hooks() {
// Register ACFE Form Actions.
add_filter( 'acfe/include_form_actions', [ $this, 'register_form_actions' ], 50 );
// Add Form Actions Javascript.
add_action( 'acfe/form/submit', [ $this, 'form_action_query_vars_clear' ] );
}
/**
* Clear the Form Action Query Vars.
*
* This means we get a fresh set of Query Vars during the load process after
* a Form has been submitted.
*
* @since 0.1
*/
public function form_action_query_vars_clear() {
// Clear the array of Action results.
set_query_var( 'acfe_form_actions', [] );
}
/**
* Register Form Actions.
*
* @since 0.1
*/
public function register_form_actions() {
// Include class files.
include CFAFA_PATH . 'includes/form-actions/cfafa-form-action-base.php';
include CFAFA_PATH . 'includes/form-actions/cfafa-form-action-redirect.php';
//include CFAFA_PATH . 'includes/form-actions/cfafa-form-action-email.php';
// Instantiate the Form Actions.
new CFAFA_Form_Action_Redirect( $this );
//new CFAFA_Form_Action_Email( $this );
// Maybe add WooCommerce Product Action.
if ( function_exists( 'WC' ) ) {
include CFAFA_PATH . 'includes/form-actions/cfafa-form-action-product.php';
new CFAFA_Form_Action_Product( $this );
}
}
} // Class ends.
<?php
/**
* ACFE Base Form Action Class.
*
* Holds methods common to ACFE Form Action classes.
*
* @package Conditional_Form_Actions_For_ACFE
* @since 0.1
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* CiviCRM Profile Sync "Base" ACFE Form Action Class.
*
* A class that is extended by CiviCRM Profile Sync ACFE Form Action classes.
* *
* @since 0.1
*/
class CFAFA_Form_Action_Base {
/**
* Form Action Name.
*
* @since 0.1
* @access public
* @var string $action_name The unique name of the Form Action.
*/
public $action_name = '';
/**
* Form Action Label.
*
* @since 0.1
* @access public
* @var string $action_label The label of the Form Action.
*/
public $action_label = '';
/**
* Form Action Alias Placeholder.
*
* @since 0.1
* @access public
* @var string $alias_placeholder The alias placeholder for the Form Action.
*/
public $alias_placeholder = '';
/**
* Field Key Prefix.
*
* @since 0.1
* @access public
* @var string $field_key The prefix for the Field Key.
*/
public $field_key = '';
/**
* Field Name Prefix.
*
* @since 0.1
* @access public
* @var string $field_name The prefix for the Field Name.
*/
public $field_name = '';
/**
* Constructor.
*
* @since 0.1
*/
public function __construct() {
// Callback for the "acfe/form/load/..." hook.
add_filter( 'acfe/form/load/' . $this->action_name, [ $this, 'load' ], 10, 3 );
// Callback for the "acfe/form/make/..." hook.
add_action( 'acfe/form/make/' . $this->action_name, [ $this, 'make' ], 10, 3 );
// Generic callback for ACFE Form Actions hook.
add_filter( 'acfe/form/actions', [ $this, 'action_add' ] );
}
/**
* Allow classes to configure themselves prior to the Layout being returned.
*
* @since 0.1
*/
public function configure() {}
/**
* Performs tasks when the Form that the Action is attached to is loaded.
*
* @since 0.1
*
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post in which the Form has been embedded.
* @param string $action The customised name of the action.
*/
public function load( $form, $current_post_id, $action ) {
return $form;
}
/**
* Saves the result of the Action for use by subsequent Actions.
*
* @since 0.1
*
* @param string $action The name of the Action.
* @param array $data The result of the Action.
*/
public function load_action_save( $action = '', $data ) {
// Get the existing array of Action results.
$actions = get_query_var( 'acfe_form_actions', [] );
$actions[$this->action_name] = $data;
if ( ! empty( $action ) ) {
$actions[$action] = $data;
}
// Update array of Action results.
set_query_var( 'acfe_form_actions', $actions );
}
/**
* Performs the Action when the Form the Action is attached to is submitted.
*
* @since 0.1
*
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the action.
*/
public function make( $form, $current_post_id, $action ) {}
/**
* Maybe skip the Action when the Form the Action is attached to is submitted.
*
* @since 0.1
*
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the Form Action.
* @return bool $prepare The net result of the set of filters.
*/
public function make_skip( $form, $current_post_id, $action ) {
// Get some Form details.
$form_name = acf_maybe_get( $form, 'name' );
$form_id = acf_maybe_get( $form, 'ID' );
// Assume we're good to go.
$prepare = true;
/**
* Allow others to prevent Form Action.
*
* Returning false for any of these filters will skip the Action.
*
* @since 0.1
*
* @param bool $prepare True by default so that the Form Action goes ahead.
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the Form Action.
*/
$filter = 'acfe/form/prepare/' . $this->action_name;
$prepare = apply_filters( $filter, $prepare, $form, $current_post_id, $action );
$prepare = apply_filters( $filter . '/form=' . $form_name, $prepare, $form, $current_post_id, $action );
if ( ! empty( $action ) ) {
$prepare = apply_filters( $filter . '/action=' . $action, $prepare, $form, $current_post_id, $action );
}
// --<
return $prepare;
}
/**
* Saves the result of the Action for use by subsequent Actions.
*
* @since 0.1
*
* @param string $action The name of the Action.
* @param array $data The result of the Action.
*/
public function make_action_save( $action = '', $data ) {
// Get the existing array of Action results.
$actions = get_query_var( 'acfe_form_actions', [] );
$actions[$this->action_name] = $data;
if ( ! empty( $action ) ) {
$actions[$action] = $data;
}
// Update array of Action results.
set_query_var( 'acfe_form_actions', $actions );
}
/**
* Defines the action by adding a layout.
*
* The "name" value of the layout determines the construction of the
* "acfe/form/load/..." and "acfe/form/make/..." actions.
*
* @since 0.1
*
* @param array $layouts The existing layouts.
* @return array $layouts The modified layouts.
*/
public function action_add( $layouts ) {
// Let the classes that extend this one configure themselves.
$this->configure();
// Init our layout.
$layout = [
'key' => 'layout_' . $this->action_name,
'name' => $this->action_name,
'label' => $this->action_label,
'display' => 'row',
'min' => '',
'max' => '',
];
// Build Action Tab.
$action_tab_fields = $this->tab_action_add();
// Build Mapping Tab.
$mapping_tab_fields = $this->tab_mapping_add();
// Combine Sub-Fields.
$sub_fields = array_merge(
$action_tab_fields,
$mapping_tab_fields
);
/**
* Let the classes that extend this one modify the Sub-Fields.
*
* @since 0.1
*
* @param array $sub_fields The array of Sub-Fields.
*/
$layout['sub_fields'] = apply_filters( 'cfafa/acfe/form/actions/sub_fields', $sub_fields );
// Add our completed layout to the layouts array.
$layouts['layout_' . $this->action_name] = $layout;
// --<
return $layouts;
}
/**
* Defines the "Action" Tab.
*
* These Fields are required to configure the Form Action.
*
* The ACFE "Action name" Field has a pre-defined format, e.g. it must be
* assigned the "acfe_slug" Field Type and have "acfe_form_custom_alias" as
* its "name". Only its "placeholder" attribute needs to be configured.
*
* @since 0.1
*
* @return array $fields The array of Fields for this section.
*/
public function tab_action_add() {
// Init Fields array.
$fields = [];
// "Action" Tab wrapper.
$fields[] = [
'key' => $this->field_key . 'tab_action',
'label' => __( 'Action', 'conditional-form-actions-for-acfe' ),
'name' => '',
'type' => 'tab',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
'data-no-preference' => true,
],
'acfe_permissions' => '',
'placement' => 'top',
'endpoint' => 0,
];
// "Action name" Field.
$fields[] = [
'key' => $this->field_key . 'custom_alias',
'label' => __( 'Action name', 'conditional-form-actions-for-acfe' ),
'name' => 'acfe_form_custom_alias',
'type' => 'acfe_slug',
'instructions' => __( '(Required) Name this action so it can be referenced.', 'conditional-form-actions-for-acfe' ),
'required' => 1,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
'data-instruction-placement' => 'field',
],
'acfe_permissions' => '',
'default_value' => '',
'placeholder' => $this->alias_placeholder,
'prepend' => '',
'append' => '',
'maxlength' => '',
];
// Add any further Fields.
$action_extras = $this->tab_action_append();
if ( ! empty( $action_extras ) ) {
$fields = array_merge(
$fields,
$action_extras
);
}
// --<
return $fields;
}
/**
* Defines additional Fields for the "Action" Tab.
*
* @since 0.1
*
* @return array $fields The array of Fields for this section.
*/
public function tab_action_append() {
$fields = [];
return $fields;
}
/**
* Defines the "Mapping" Tab.
*
* @since 0.1
*
* @return array $fields The array of Fields for this section.
*/
public function tab_mapping_add() {
$fields = [];
return $fields;
}
/**
* Defines the "Mapping" Tab Header.
*
* @since 0.1
*
* @return array $fields The array of Fields for this section.
*/
public function tab_mapping_header() {
// "Mapping" Tab wrapper.
$mapping_tab = [ [
'key' => $this->field_key . 'tab_load',
'label' => __( 'Mapping', 'conditional-form-actions-for-acfe' ),
'name' => '',
'type' => 'tab',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
'data-no-preference' => true,
],
'acfe_permissions' => '',
'placement' => 'top',
'endpoint' => 0,
] ];
// Combine Fields.
$fields = array_merge(
$mapping_tab
);
// --<
return $fields;
}
/**
* Gets the array that defines a "Map Field" for the "Mapping" Tab.
*
* @since 0.1
*
* @param string $code The unique code for the Field.
* @param string $label The label for the Field.
* @param array $conditional_logic The conditional logic for the Field.
* @return array $field The array of Field data.
*/
public function mapping_field_get( $code, $label, $conditional_logic = [] ) {
// Build the Field array.
$field = [
'key' => $this->field_key . 'map_' . $code,
'label' => $label,
'name' => $this->field_name . 'map_' . $code,
'type' => 'select',
'instructions' => '',
'required' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
],
'acfe_permissions' => '',
'choices' => [],
'default_value' => [],
'allow_null' => 1,
'multiple' => 0,
'ui' => 1,
'return_format' => 'value',
'placeholder' => __( 'Default', 'conditional-form-actions-for-acfe' ),
'ajax' => 0,
'search_placeholder' => __( 'Enter a custom value or template tag. (See "Cheatsheet" tab)', 'conditional-form-actions-for-acfe' ),
'allow_custom' => 1,
];
// Default conditional logic.
$field['conditional_logic'] = 0;
// Maybe replace with custom conditional logic.
if ( ! empty( $conditional_logic ) ) {
$field['conditional_logic'] = $conditional_logic;
}
// --<
return $field;
}
/**
* Adds filters that configure "Mapping Fields" when loaded.
*
* @since 0.1
*
* @param string $code The unique code for the Field.
*/
public function mapping_field_filters_add( $code ) {
// Grab reference to ACFE Helper object.
$helpers = acf_get_instance( 'acfe_dynamic_forms_helpers' );
// Populate mapping Fields.
add_filter( 'acf/prepare_field/name=' . $this->field_name . 'map_' . $code, [ $helpers, 'map_fields_deep_no_custom' ] );
}
/**
* Prepare the data from an ACFE Form.
*
* @since 0.1
*
* @param array $form_data The array of data from the ACFE Form.
* @return array $filtered_data The filtered data.
*/
public function form_data_prepare( $form_data ) {
// Init filtered data.
$filtered_data = [];
// Bail if we have no Form data to save.
if ( empty( $form_data ) ) {
return $filtered_data;
}
// Populate Activity data from the Form data.
foreach ( $form_data as $param => $value ) {
// Allow (string) "0" as valid data.
if ( ! empty( $value ) || $value === '0' ) {
$filtered_data[$param] = $value;
}
}
// --<
return $filtered_data;
}
} // Class ends.
<?php
/**
* "Conditional Email" ACFE Form Action Class.
*
* Handles the "Conditional Email" ACFE Form Action.
*
* @package Conditional_Form_Actions_For_ACFE
* @since 0.1
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* CiviCRM Profile Sync "Conditional Email" ACFE Form Action Class.
*
* A class that handles the "Conditional Email" ACFE Form Action.
*
* @since 0.1
*/
class CFAFA_Form_Action_Email extends CFAFA_Form_Action_Base {
/**
* Plugin object.
*
* @since 0.1
* @access public
* @var object $plugin The plugin object.
*/
public $plugin;
/**
* Parent (calling) object.
*
* @since 0.1
* @access public
* @var object $acf The parent object.
*/
public $acfe;
/**
* Form Action Name.
*
* @since 0.1
* @access public
* @var string $action_name The unique name of the Form Action.
*/
public $action_name = 'email_cfafa';
/**
* Field Key Prefix.
*
* @since 0.1
* @access public
* @var string $field_key The prefix for the Field Key.
*/
public $field_key = 'field_cfafa_email_';
/**
* Field Name Prefix.
*
* @since 0.1
* @access public
* @var string $field_name The prefix for the Field Name.
*/
public $field_name = 'cfafa_email_';
/**
* Constructor.
*
* @since 0.1
*
* @param object $parent The parent object reference.
*/
public function __construct( $parent ) {
// Store references to objects.
$this->plugin = $parent->plugin;
$this->acfe = $parent;
// Label this Form Action.
$this->action_label = __( 'Conditional Email action', 'conditional-form-actions-for-acfe' );
// Alias Placeholder for this Form Action.
$this->alias_placeholder = __( 'Conditional Email', 'conditional-form-actions-for-acfe' );
// Init parent.
parent::__construct();
}
/**
* Configure this object.
*
* @since 0.1
*/
public function configure() {
// Declare the mapped Email Fields with translatable titles.
$this->mapped_email_fields = [
'subject' => __( 'Subject', 'conditional-form-actions-for-acfe' ),
'from_name' => __( 'From Name', 'conditional-form-actions-for-acfe' ),
'from_email' => __( 'From Email', 'conditional-form-actions-for-acfe' ),
'alternative_receiver_address' => __( 'Alternative Receiver Address', 'conditional-form-actions-for-acfe' ),
'cc' => __( 'Carbon Copy', 'conditional-form-actions-for-acfe' ),
'bcc' => __( 'Blind Carbon Copy', 'conditional-form-actions-for-acfe' ),
//'extra_data' => __( 'Extra Data', 'conditional-form-actions-for-acfe' ),
//'from_email_option' => __( 'From Email Option', 'conditional-form-actions-for-acfe' ),
];
// Populate mapping Fields.
foreach ( $this->mapped_email_fields as $name => $title ) {
$this->mapping_field_filters_add( $name );
}
// Declare the Email Contact Fields with translatable titles.
$this->contact_fields = [
'contact_id' => __( 'Recipient CiviCRM Contact', 'conditional-form-actions-for-acfe' ),
];
// Handle Contact Fields.
foreach ( $this->contact_fields as $name => $title ) {
// Populate mapping Fields.
$this->mapping_field_filters_add( $name );
// Add Contact Action Reference Field to ACF Model.
$this->js_model_contact_reference_field_add( $this->field_name . 'ref_' . $name );
// Pre-load with "Generic" values.
//$filter = 'acf/prepare_field/name=' . $this->field_name . 'map_' . $name;
//add_filter( $filter, [ $this, 'prepare_choices' ], 5 );
}
// Email Conditional Field.
$this->mapping_field_filters_add( 'email_conditional' );
}
/**
* Pre-load mapping Fields with "Generic" choices.
*
* Not used but leaving this here for future use.
*
* @since 0.1
*
* @param array $field The existing array of Field data.
* @param array $field The modified array of Field data.
*/
public function prepare_choices( $field ) {
// --<
return $field;
}
/**
* Performs validation when the Form the Action is attached to is submitted.
*
* @since 0.1
*
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the action.
*/
public function validation( $form, $current_post_id, $action ) {
/*
// Get some Form details.
$form_name = acf_maybe_get( $form, 'name' );
$form_id = acf_maybe_get( $form, 'ID' );
//acfe_add_validation_error( $selector, $message );
*/
}
/**
* Performs the action when the Form the Action is attached to is submitted.
*
* @since 0.1
*
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the action.
*/
public function make( $form, $current_post_id, $action ) {
// Bail if a filter has overridden the action.
if ( false === $this->make_skip( $form, $current_post_id, $action ) ) {
return;
}
// Get some Form details.
$form_name = acf_maybe_get( $form, 'name' );
$form_id = acf_maybe_get( $form, 'ID' );
// Populate Email data array.
$email = $this->form_email_data( $form, $current_post_id, $action );
// Send the Email with the data from the Form.
$email = $this->form_email_save( $email );
// Save the results of this Action for later use.
$this->make_action_save( $action, $email );
}
/**
* Defines additional Fields for the "Action" Tab.
*
* @since 0.1
*
* @return array $fields The array of Fields for this section.
*/
public function tab_action_append() {
// Define Template Field.
$template_field = [
'key' => $this->field_key . 'template',
'label' => __( 'Message Template', 'conditional-form-actions-for-acfe' ),
'name' => $this->field_name . 'template',
'type' => 'select',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
'data-instruction-placement' => 'field',
],
'acfe_permissions' => '',
'default_value' => '',
'placeholder' => '',
'allow_null' => 0,
'multiple' => 0,
'ui' => 0,
'return_format' => 'value',
'choices' => $this->civicrm->email->template_options_get(),
];
// Define "Disable Smarty" Field.
$smarty_field = [
'key' => $this->field_key . 'disable_smarty',
'label' => __( 'Disable Smarty', 'conditional-form-actions-for-acfe' ),
'name' => $this->field_name . 'disable_smarty',
'type' => 'true_false',
'instructions' => __( 'Disable Smarty. Normal CiviMail tokens are still supported. By default Smarty is enabled if configured by CIVICRM_MAIL_SMARTY.', 'conditional-form-actions-for-acfe' ),
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
'data-instruction-placement' => 'field',
],
'acfe_permissions' => '',
'message' => '',
'default_value' => 0,
'ui' => 1,
'ui_on_text' => '',
'ui_off_text' => '',
];
// Define "Create Activity" Field.
$create_activity_field = [
'key' => $this->field_key . 'create_activity',
'label' => __( 'Create Activity', 'conditional-form-actions-for-acfe' ),
'name' => $this->field_name . 'create_activity',
'type' => 'true_false',
'instructions' => __( 'Usually an Email Activity is created when an Email is sent.', 'conditional-form-actions-for-acfe' ),
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
'data-instruction-placement' => 'field',
],
'acfe_permissions' => '',
'message' => '',
'default_value' => 1,
'ui' => 1,
'ui_on_text' => '',
'ui_off_text' => '',
];
// Define "Activity Details" Field.
$activity_details_field = [
'key' => $this->field_key . 'activity_details',
'label' => __( 'Activity Details', 'conditional-form-actions-for-acfe' ),
'name' => $this->field_name . 'activity_details',
'type' => 'select',
'instructions' => '',
'required' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
'data-instruction-placement' => 'field',
],
'acfe_permissions' => '',
'default_value' => 'html,text',
'placeholder' => '',
'allow_null' => 0,
'multiple' => 0,
'ui' => 0,
'return_format' => 'value',
'choices' => [
'html,text' => __( 'HTML and Text versions of the body', 'conditional-form-actions-for-acfe' ),
'tplName' => __( 'Just the name of the message template', 'conditional-form-actions-for-acfe' ),
'html' => __( 'Just the HTML version of the body', 'conditional-form-actions-for-acfe' ),
'text' => __( 'Just the text version of the body', 'conditional-form-actions-for-acfe' ),
],
'conditional_logic' => [
[
[
'field' => $this->field_key . 'create_activity',
'operator' => '==',
'value' => 1,
],
],
],
];
// Init Fields.
$fields = [
$template_field,
$smarty_field,
$create_activity_field,
$activity_details_field,
];
// Add Case Field if the CiviCase component is active.
$case_active = $this->civicrm->is_component_enabled( 'CiviCase' );
if ( $case_active ) {
$fields[] = [
'key' => $this->field_key . 'email_case_id',
'label' => __( 'Case', 'conditional-form-actions-for-acfe' ),
'name' => $this->field_name . 'email_case_id',
'type' => 'cfafa_acfe_case_action_ref',
'instructions' => __( 'Select a Case Action in this Form.', 'conditional-form-actions-for-acfe' ),
'required' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
'data-instruction-placement' => 'field',
],
'acfe_permissions' => '',
'default_value' => '',
'placeholder' => __( 'None', 'conditional-form-actions-for-acfe' ),
'allow_null' => 1,
'multiple' => 0,
'ui' => 0,
'return_format' => 'value',
'choices' => [],
];
}
// Add Conditional Field.
$code = 'email_conditional';
$label = __( 'Conditional On', 'conditional-form-actions-for-acfe' );
$conditional = $this->mapping_field_get( $code, $label );
$conditional['placeholder'] = __( 'Always send', 'conditional-form-actions-for-acfe' );
$conditional['wrapper']['data-instruction-placement'] = 'field';
$conditional['instructions'] = __( 'To send the Email only when a Form Field is populated (e.g. "First Name") link this to the Form Field. To send the Email only when more complex conditions are met, link this to a Hidden Field with value "1" where the conditional logic of that Field shows it when the conditions are met.', 'conditional-form-actions-for-acfe' );
$fields[] = $conditional;
// --<
return $fields;
}
/**
* Defines the "Mapping" Tab.
*
* @since 0.1
*
* @return array $fields The array of Fields for this section.
*/
public function tab_mapping_add() {
// Get Tab Header.
$mapping_tab_header = $this->tab_mapping_header();
// Build Contacts Accordion.
$mapping_contacts_accordion = $this->tab_mapping_accordion_contacts_add();
// Build Email Details Accordion.
$mapping_email_accordion = $this->tab_mapping_accordion_email_add();
// Combine Sub-Fields.
$fields = array_merge(
$mapping_tab_header,
$mapping_contacts_accordion,
$mapping_email_accordion
);
// --<
return $fields;
}
/**
* Defines the Fields in the "Contacts" Accordion.
*
* @since 0.1
*
* @return array $fields The array of Fields for this section.
*/
public function tab_mapping_accordion_contacts_add() {
// Init return.
$fields = [];
// "Recipient Contact Reference" Accordion wrapper open.
$fields[] = [
'key' => $this->field_key . 'mapping_accordion_contacts_open',
'label' => __( 'Recipient Contact Reference', 'conditional-form-actions-for-acfe' ),
'name' => '',
'type' => 'accordion',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
],
'acfe_permissions' => '',
'open' => 0,
'multi_expand' => 1,
'endpoint' => 0,
];
// Add Contact Reference Fields.
foreach ( $this->contact_fields as $name => $title ) {
// Bundle them into a container group.
$contact_group_field = [
'key' => $this->field_key . 'contact_group_' . $name,
'label' => $title,
'name' => $this->field_name . 'contact_group_' . $name,
'type' => 'group',
'instructions' => sprintf( __( 'Use one Field to identify the %s.', 'conditional-form-actions-for-acfe' ), $title ),
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
],
'required' => 0,
'layout' => 'block',
];
// Define Contact Action Reference Field.
$contact_group_field['sub_fields'][] = [
'key' => $this->field_key . 'ref_' . $name,
'label' => __( 'CiviCRM Contact Action', 'conditional-form-actions-for-acfe' ),
'name' => $this->field_name . 'ref_' . $name,
'type' => 'cfafa_acfe_contact_action_ref',
'instructions' => __( 'Select a Contact Action in this Form.', 'conditional-form-actions-for-acfe' ),
'required' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
],
'acfe_permissions' => '',
'default_value' => '',
'placeholder' => __( 'None', 'conditional-form-actions-for-acfe' ),
'allow_null' => 0,
'multiple' => 0,
'ui' => 0,
'return_format' => 'value',
'choices' => [],
'conditional_logic' => [
[
[
'field' => $this->field_key . 'map_' . $name,
'operator' => '==empty',
],
[
'field' => $this->field_key . 'cid_' . $name,
'operator' => '==empty',
],
],
],
];
// Define Contact ID Field.
$cid_field = [
'key' => $this->field_key . 'cid_' . $name,
'label' => __( 'CiviCRM Contact ID', 'conditional-form-actions-for-acfe' ),
'name' => $this->field_name . 'cid_' . $name,
'type' => 'civicrm_contact',
'instructions' => __( 'Select a CiviCRM Contact ID from the database.', 'conditional-form-actions-for-acfe' ),
'required' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
],
'acfe_permissions' => '',
'default_value' => '',
'placeholder' => __( 'None', 'conditional-form-actions-for-acfe' ),
'allow_null' => 0,
'multiple' => 0,
'ui' => 0,
'return_format' => 'value',
'choices' => [],
'conditional_logic' => [
[
[
'field' => $this->field_key . 'ref_' . $name,
'operator' => '==empty',
],
[
'field' => $this->field_key . 'map_' . $name,
'operator' => '==empty',
],
],
],
];
// Add Contact ID Field.
$contact_group_field['sub_fields'][] = $cid_field;
// Define Custom Contact Reference Field.
$title = sprintf( __( 'Custom Contact Reference', 'conditional-form-actions-for-acfe' ), $title );
$mapping_field = $this->mapping_field_get( $name, $title );
$mapping_field['instructions'] = __( 'Define a custom Contact Reference.', 'conditional-form-actions-for-acfe' );
$mapping_field['conditional_logic'] = [
[
[
'field' => $this->field_key . 'ref_' . $name,
'operator' => '==empty',
],
[
'field' => $this->field_key . 'cid_' . $name,
'operator' => '==empty',
],
],
];
// Add Custom Contact Reference Field.
$contact_group_field['sub_fields'][] = $mapping_field;
// Add Contact Reference Group.
$fields[] = $contact_group_field;
}
// "Recipient Contact Reference" Accordion wrapper close.
$fields[] = [
'key' => $this->field_key . 'mapping_accordion_contacts_close',
'label' => __( 'Recipient Contact Reference', 'conditional-form-actions-for-acfe' ),
'name' => '',
'type' => 'accordion',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
],
'acfe_permissions' => '',
'open' => 0,
'multi_expand' => 1,
'endpoint' => 1,
];
// --<
return $fields;
}
/**
* Defines the Fields in the "Email Fields" Accordion.
*
* @since 0.1
*
* @return array $fields The array of Fields for this section.
*/
public function tab_mapping_accordion_email_add() {
// Init return.
$fields = [];
// "Email Fields" Accordion wrapper open.
$fields[] = [
'key' => $this->field_key . 'mapping_accordion_email_open',
'label' => __( 'Email Fields', 'conditional-form-actions-for-acfe' ),
'name' => '',
'type' => 'accordion',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
],
'acfe_permissions' => '',
'open' => 0,
'multi_expand' => 1,
'endpoint' => 0,
];
// Add "Mapping" Fields.
foreach ( $this->mapped_email_fields as $name => $title ) {
$fields[] = $this->mapping_field_get( $name, $title );
}
// "Email Fields" Accordion wrapper close.
$fields[] = [
'key' => $this->field_key . 'mapping_accordion_email_close',
'label' => __( 'Email Fields', 'conditional-form-actions-for-acfe' ),
'name' => '',
'type' => 'accordion',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
],
'acfe_permissions' => '',
'open' => 0,
'multi_expand' => 1,
'endpoint' => 1,
];
// --<
return $fields;
}
/**
* Builds Email data array from mapped Fields.
*
* @since 0.1
*
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the action.
* @return array $data The array of Email data.
*/
public function form_email_data( $form, $current_post_id, $action ) {
// Init data array.
$data = [];
// Get Field data.
$data['from'] = get_sub_field( $this->field_key . 'from' );
$data['from'] = acfe_form_map_field_value( $from, $current_post_id, $form );
$data['reply_to'] = get_sub_field( $this->field_key . 'reply_to' );
$data['reply_to'] = acfe_form_map_field_value( $reply_to, $current_post_id, $form );
$data['to'] = get_sub_field($this->field_key . 'to' );
$data['to'] = acfe_form_map_field_value( $to, $current_post_id, $form );
$data['cc'] = get_sub_field( $this->field_key . 'cc' );
$data['cc'] = acfe_form_map_field_value( $cc, $current_post_id, $form );
$data['bcc'] = get_sub_field( $this->field_key . 'bcc' );
$data['bcc'] = acfe_form_map_field_value( $bcc, $current_post_id, $form );
$data['subject'] = get_sub_field( $this->field_key . 'subject' );
$data['subject'] = acfe_form_map_field_value( $subject, $current_post_id, $form );
$data['content'] = get_sub_field( $this->field_key . 'content' );
$data['content'] = acfe_form_map_field_value( $content, $current_post_id, $form );
// Get Email Conditional Reference.
$data['email_conditional_ref'] = get_sub_field( $this->field_key . 'map_email_conditional' );
$conditionals = [ $data['email_conditional_ref'] ];
// Populate array with mapped Conditional Field values.
$conditionals = acfe_form_map_vs_fields( $conditionals, $conditionals, $current_post_id, $form );
// Save Email Conditional.
$data['email_conditional'] = array_pop( $conditionals );
// --<
return $data;
}
/**
* Sends the Conditional Email given data from mapped Fields.
*
* @since 0.1
*
* @param array $email_data The array of Email data.
* @return array|bool $email The Email data array, or false on failure.
*/
public function form_email_save( $email_data ) {
// Init return.
$email = false;
// Skip if the Email Conditional Reference Field has a value.
if ( ! empty( $email_data['email_conditional_ref'] ) ) {
// And the Email Conditional Field has no value.
if ( empty( $email_data['email_conditional'] ) ) {
return $email;
}
}
// Add Custom Field data if present.
if ( ! empty ( $custom_data ) ) {
$email_data += $custom_data;
}
// Unset Email Conditionals.
if ( isset( $email_data['email_conditional'] ) ) {
unset( $email_data['email_conditional'] );
}
if ( isset( $email_data['email_conditional_ref'] ) ) {
unset( $email_data['email_conditional_ref'] );
}
// Strip out empty Fields.
$email_data = $this->form_data_prepare( $email_data );
// Sanity checks.
if ( empty( $email_data['contact_id'] ) || empty( $email_data['template_id'] ) ) {
return $email;
}
// Send the Email.
$result = $this->civicrm->email->email_send( $email_data );
// Bail on failure.
if ( $result === false ) {
return $email;
}
// --<
return $result;
}
/**
* Finds the linked Contact ID when it has been mapped.
*
* @since 0.1
*
* @param string $action_name The name of the referenced Form Action.
* @return integer|bool $contact_id The numeric ID of the Contact, or false if not found.
*/
public function form_contact_id_get_mapped( $action_name ) {
// Init return.
$contact_id = false;
// We need an Action Name.
if ( empty( $action_name ) ) {
return $contact_id;
}
// Get the Contact data for that Action.
$related_contact = acfe_form_get_action( $action_name, 'contact' );
if ( empty( $related_contact['id'] ) ) {
return $contact_id;
}
// Assign return.
$contact_id = (int) $related_contact['id'];
// --<
return $contact_id;
}
/**
* Finds the linked Case ID when it has been mapped.
*
* @since 0.1
*
* @param string $action_name The name of the referenced Form Action.
* @return integer|bool $case_id The numeric ID of the Case, or false if not found.
*/
public function form_case_id_get_mapped( $action_name ) {
// Init return.
$case_id = false;
// We need an Action Name.
if ( empty( $action_name ) ) {
return $case_id;
}
// Get the Case ID for that Action.
$related_case_id = acfe_form_get_action( $action_name, 'id' );
if ( empty( $related_case_id ) ) {
return $case_id;
}
// Assign return.
$case_id = (int) $related_case_id;
// --<
return $case_id;
}
} // Class ends.
<?php
/**
* "WooCommerce Product" ACFE Form Action Class.
*
* Handles the "WooCommerce Product" ACFE Form Action.
*
* @package Conditional_Form_Actions_For_ACFE
* @since 0.1
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* CiviCRM Profile Sync "WooCommerce Product" ACFE Form Action Class.
*
* A class that handles the "WooCommerce Product" ACFE Form Action.
*
* @since 0.1
*/
class CFAFA_Form_Action_Product extends CFAFA_Form_Action_Base {
/**
* Plugin object.
*
* @since 0.1
* @access public
* @var object $plugin The plugin object.
*/
public $plugin;
/**
* Parent (calling) object.
*
* @since 0.1
* @access public
* @var object $acf The parent object.
*/
public $acfe;
/**
* Form Action Name.
*
* @since 0.1
* @access public
* @var string $action_name The unique name of the Form Action.
*/
public $action_name = 'woo_cfafa_product';
/**
* Field Key Prefix.
*
* @since 0.1
* @access public
* @var string $field_key The prefix for the Field Key.
*/
public $field_key = 'field_cfafa_woo_product_';
/**
* Field Name Prefix.
*
* @since 0.1
* @access public
* @var string $field_name The prefix for the Field Name.
*/
public $field_name = 'cfafa_woo_product_';
/**
* Constructor.
*
* @since 0.1
*
* @param object $parent The parent object reference.
*/
public function __construct( $parent ) {
// Store references to objects.
$this->plugin = $parent->plugin;
$this->acfe = $parent;
// Label this Form Action.
$this->action_label = __( 'WooCommerce Product action', 'conditional-form-actions-for-acfe' );
// Alias Placeholder for this Form Action.
$this->alias_placeholder = __( 'WooCommerce Product', 'conditional-form-actions-for-acfe' );
// Init parent.
parent::__construct();
}
/**
* Configure this object.
*
* @since 0.1
*/
public function configure() {
// WooCommerce Product Conditional Field.
$this->mapping_field_filters_add( 'product_conditional' );
}
/**
* Performs the action when the Form the Action is attached to is submitted.
*
* @since 0.1
*
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the action.
*/
public function make( $form, $current_post_id, $action ) {
// Bail if a filter has overridden the action.
if ( false === $this->make_skip( $form, $current_post_id, $action ) ) {
return;
}
// Get some Form details.
$form_name = acf_maybe_get( $form, 'name' );
$form_id = acf_maybe_get( $form, 'ID' );
// Populate Product data array.
$product_data = $this->form_data_get( $form, $current_post_id, $action );
// Act with the data from the Form.
$product_data = $this->form_product_save( $product_data );
// Save the results of this Action for later use.
$this->make_action_save( $action, $product_data );
}
/**
* Defines additional Fields for the "Action" Tab.
*
* @since 0.1
*
* @return array $fields The array of Fields for this section.
*/
public function tab_action_append() {
// Init Fields.
$fields = [];
$fields[] = [
'key' => $this->field_key . 'product_id',
'label' => __( 'WooCommerce Product', 'conditional-form-actions-for-acfe' ),
'name' => $this->field_name . 'product_id',
'type' => 'select',
'instructions' => __( 'Use this to add a WooCommerce Product to the Cart.', 'conditional-form-actions-for-acfe' ),
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
'data-instruction-placement' => 'field',
],
'acfe_permissions' => '',
'default_value' => '',
'placeholder' => '',
'allow_null' => 1,
'multiple' => 0,
'ui' => 0,
//'ajax' => 1,
//'ajax_action' => 'cfafa_get_products',
'return_format' => 'value',
'choices' => $this->product_choices_get(),
];
// Add Conditional Field.
$code = 'product_conditional';
$label = __( 'Conditional On', 'conditional-form-actions-for-acfe' );
$conditional = $this->mapping_field_get( $code, $label );
$conditional['placeholder'] = __( 'Always add', 'conditional-form-actions-for-acfe' );
$conditional['wrapper']['data-instruction-placement'] = 'field';
$conditional['instructions'] = __( 'To add the Product to the Cart only when a Form Field is populated (e.g. "First Name") link this to the Form Field. To add the Product to the Cart only when more complex conditions are met, link this to a Hidden Field with value "1" where the conditional logic of that Field shows it when the conditions are met.', 'conditional-form-actions-for-acfe' );
$fields[] = $conditional;
// --<
return $fields;
}
/**
* Builds Product data array from mapped Fields.
*
* @since 0.1
*
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the action.
* @return array $data The array of Product data.
*/
public function form_data_get( $form, $current_post_id, $action ) {
// Add Product ID.
$data['product_id'] = get_sub_field( $this->field_key . 'product_id' );
// Get Product Conditional Reference.
$data['product_conditional_ref'] = get_sub_field( $this->field_key . 'map_product_conditional' );
$conditionals = [ $data['product_conditional_ref'] ];
// Populate array with mapped Conditional Field values.
$conditionals = acfe_form_map_vs_fields( $conditionals, $conditionals, $current_post_id, $form );
// Save Product Conditional.
$data['product_conditional'] = array_pop( $conditionals );
// --<
return $data;
}
/**
* Sends the WooCommerce Product given data from mapped Fields.
*
* @since 0.1
*
* @param array $product_data The array of Product data.
* @return array|bool $product_data The Product data array, or false on failure.
*/
public function form_product_save( $product_data ) {
// Skip if the Product Conditional Reference Field has a value.
if ( ! empty( $product_data['product_conditional_ref'] ) ) {
// And the Product Conditional Field has no value.
if ( empty( $product_data['product_conditional'] ) ) {
return $product_data;
}
}
// Unset Product Conditionals.
if ( isset( $product_data['product_conditional'] ) ) {
unset( $product_data['product_conditional'] );
}
if ( isset( $product_data['product_conditional_ref'] ) ) {
unset( $product_data['product_conditional_ref'] );
}
// Strip out empty Fields.
$product_data = $this->form_data_prepare( $product_data );
// Sanity check.
if ( empty( $product_data['product_id'] ) ) {
return false;
}
// Add the Product to the WooCommerce Cart.
$result = $this->product_add_to_cart( $product_data );
// Bail on failure.
if ( $result === false ) {
return false;
}
// Add Cart Item key to Product data.
$product_data['cart_item_key'] = $result;
// --<
return $product_data;
}
/**
* Gets the WooCommerce Products as an array of options for ACF.
*
* @since 0.1
*
* @return array $options The array of Products formatted for ACF.
*/
public function product_choices_get() {
// Init return.
$options = [];
/*
* Build params to get all published Products.
*
* We have to query directly because WooCommerce has not been initialised
* at this point and wc_get_products() does not return any results. This
* is because ACF hooks into `init` with priority 5 *before* WooCommerce
* initialises.
*
* This may need to be looked at again in future.
*/
$args = [
'post_type' => 'product',
'post_status' => [ 'publish' ],
'no_found_rows' => true,
'posts_per_page' => -1,
];
// Do query.
$query = new WP_Query( $args );
// Do the loop.
if ( $query->have_posts() ) {
foreach ( $query->get_posts() as $found ) {
$options[ $found->ID ] = $found->post_title;
}
}
// Reset Post data just in case.
wp_reset_postdata();
// --<
return $options;
}
/**
* Adds the Product to the Cart.
*
* @since 0.1
*
* @param array $product_data The array of Product data.
* @return integer|bool $cart_item_key The key of the Cart Item, or false otherwise.
*/
public function product_add_to_cart( $product_data ) {
// Get the Product.
$product = wc_get_product( $product_data['product_id'] );
// Sanity check.
if ( empty( $product ) ) {
return false;
}
// Some defaults.
$product_id = $product->get_id();
$quantity = 1;
$variation_id = 0;
$variation = [];
$cart_item_data = [];
// Build Cart Item data?
// Add the configured Product to the Cart.
$cart_item_key = WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation, $cart_item_data );
// --<
return $cart_item_key;
}
} // Class ends.
<?php
/**
* "CiviCRM Redirect" ACFE Form Action Class.
*
* Handles the "CiviCRM Redirect" ACFE Form Action.
*
* @package Conditional_Form_Actions_For_ACFE
* @since 0.1
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* CiviCRM Profile Sync "CiviCRM Redirect" ACFE Form Action Class.
*
* A class that handles the "CiviCRM Redirect" ACFE Form Action.
*
* @since 0.1
*/
class CFAFA_Form_Action_Redirect extends CFAFA_Form_Action_Base {
/**
* Plugin object.
*
* @since 0.1
* @access public
* @var object $plugin The plugin object.
*/
public $plugin;
/**
* Parent (calling) object.
*
* @since 0.1
* @access public
* @var object $acf The parent object.
*/
public $acfe;
/**
* Form Action Name.
*
* @since 0.1
* @access public
* @var string $action_name The unique name of the Form Action.
*/
public $action_name = 'redirect_cfafa';
/**
* Field Key Prefix.
*
* @since 0.1
* @access public
* @var string $field_key The prefix for the Field Key.
*/
public $field_key = 'field_cfafa_redirect_';
/**
* Field Name Prefix.
*
* @since 0.1
* @access public
* @var string $field_name The prefix for the Field Name.
*/
public $field_name = 'cfafa_redirect_';
/**
* Constructor.
*
* @since 0.1
*
* @param object $parent The parent object reference.
*/
public function __construct( $parent ) {
// Store references to objects.
$this->plugin = $parent->plugin;
$this->acfe = $parent;
// Label this Form Action.
$this->action_label = __( 'Conditional Redirect action', 'conditional-form-actions-for-acfe' );
// Alias Placeholder for this Form Action.
$this->alias_placeholder = __( 'Conditional Redirect', 'conditional-form-actions-for-acfe' );
// Init parent.
parent::__construct();
}
/**
* Configure this object.
*
* @since 0.1
*/
public function configure() {
// Conditional Field.
$this->mapping_field_filters_add( 'redirect_conditional' );
}
/**
* Performs the action when the Form the Action is attached to is submitted.
*
* @since 0.1
*
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the action.
*/
public function make( $form, $current_post_id, $action ) {
// Bail if a filter has overridden the action.
if ( false === $this->make_skip( $form, $current_post_id, $action ) ) {
return;
}
// Populate Redirect data array.
$conditional_redirect = $this->form_redirect_data( $form, $current_post_id, $action );
// Do the Redirect with the data from the Form.
$conditional_redirect = $this->form_redirect_perform( $conditional_redirect );
// Save the results of this Action for later use.
$this->make_action_save( $action, $conditional_redirect );
}
/**
* Defines additional Fields for the "Action" Tab.
*
* @since 0.1
*
* @return array $fields The array of Fields for this section.
*/
public function tab_action_append() {
// Init Fields.
$fields = [];
// Add URL Field.
$fields[] = [
'key' => $this->field_key . 'redirect_url',
'label' => __( 'Redirect URL', 'conditional-form-actions-for-acfe' ),
'name' => $this->field_name . 'redirect_url',
'type' => 'text',
'instructions' => __( 'The URL to redirect to. See "Cheatsheet" tab for all available template tags.', 'conditional-form-actions-for-acfe' ),
'required' => 0,
'conditional_logic' => 0,
'wrapper' => [
'width' => '',
'class' => '',
'id' => '',
'data-instruction-placement' => 'field'
],
'acfe_permissions' => '',
'default_value' => '',
'placeholder' => '',
'prepend' => '',
'append' => '',
'maxlength' => '',
];
// Add Conditional Field.
$code = 'redirect_conditional';
$label = __( 'Conditional On', 'conditional-form-actions-for-acfe' );
$conditional = $this->mapping_field_get( $code, $label );
$conditional['placeholder'] = __( 'Always redirect', 'conditional-form-actions-for-acfe' );
$conditional['wrapper']['data-instruction-placement'] = 'field';
$conditional['instructions'] = __( 'To redirect only when a Form Field is populated, link this to the Form Field. To redirect only when more complex conditions are met, link this to a Hidden Field with value "1" where the conditional logic of that Field shows it when the conditions are met.', 'conditional-form-actions-for-acfe' );
$fields[] = $conditional;
// --<
return $fields;
}
/**
* Builds Redirect data array from mapped Fields.
*
* @since 0.1
*
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the action.
* @return array $data The array of Redirect data.
*/
public function form_redirect_data( $form, $current_post_id, $action ) {
// Get some Form details.
$form_name = acf_maybe_get( $form, 'name' );
$form_id = acf_maybe_get( $form, 'ID' );
// Init data array.
$data = [];
// Get the Action variables.
$url = get_sub_field( $this->field_key . 'redirect_url' );
$url = acfe_form_map_field_value( $url, $current_post_id, $form );
/**
* Filter the Redirect URL.
*
* @since 0.1
*
* @param string $url The Redirect URL.
* @param array $form The array of Form data.
* @param integer $current_post_id The ID of the Post from which the Form has been submitted.
* @param string $action The customised name of the Form Action.
*/
$filter = 'acfe/form/submit/' . $this->action_name . '/url';
$url = apply_filters( $filter, $url, $form, $current_post_id, $action );
$url = apply_filters( $filter . '/form=' . $form_name, $url, $form, $current_post_id, $action );
if ( ! empty( $action ) ) {
$url = apply_filters( $filter . '/action=' . $action, $url, $form, $current_post_id, $action );
}
// Add trimmed URL to the data array.
$data['redirect_url'] = trim( $url );
// Get Redirect Conditional Reference.
$data['redirect_conditional_ref'] = get_sub_field( $this->field_key . 'map_redirect_conditional' );
$conditionals = [ $data['redirect_conditional_ref'] ];
// Populate array with mapped Conditional Field values.
$conditionals = acfe_form_map_vs_fields( $conditionals, $conditionals, $current_post_id, $form );
// Save Redirect Conditional.
$data['redirect_conditional'] = array_pop( $conditionals );
// --<
return $data;
}
/**
* Conditionally performs the redirect given data from mapped Fields.
*
* @since 0.1
*
* @param array $redirect_data The array of Redirect data.
* @return array|bool $redirect The Redirect data array, or false on failure.
*/
public function form_redirect_perform( $redirect_data ) {
// Skip if the Redirect Conditional Reference Field has a value.
if ( ! empty( $redirect_data['redirect_conditional_ref'] ) ) {
// And the Redirect Conditional Field has no value.
if ( empty( $redirect_data['redirect_conditional'] ) ) {
return $redirect_data;
}
}
// Unset Redirect Conditionals.
if ( isset( $redirect_data['redirect_conditional'] ) ) {
unset( $redirect_data['redirect_conditional'] );
}
if ( isset( $redirect_data['redirect_conditional_ref'] ) ) {
unset( $redirect_data['redirect_conditional_ref'] );
}
// Strip out empty Fields.
$redirect_data = $this->form_data_prepare( $redirect_data );
// Sanity check.
if ( empty( $redirect_data['redirect_url'] ) ) {
return false;
}
// Do the redirect.
wp_redirect( $redirect_data['redirect_url'] );
exit;
}
} // Class ends.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment