<?php /** * ACFE Form Action Base Class. * * Holds methods common to ACFE Form Action classes. * * @package Conditional_Form_Actions_For_ACFE */ // Exit if accessed directly. defined( 'ABSPATH' ) || exit; /** * "Base" ACFE Form Action Class. * * A class that is extended by ACFE Form Action classes. * * @since 0.2.0 */ class CFAFA_ACFE_Form_Action_Base extends acfe_module_form_action { /** * Form Action Name. * * @since 0.2.0 * @access public * @var string */ public $action_name = ''; /** * Form Action Label. * * @since 0.2.0 * @access public * @var string */ public $action_label = ''; /** * Form Action Alias Placeholder. * * @since 0.2.0 * @access public * @var string */ public $alias_placeholder = ''; /** * Field Key Prefix. * * @since 0.2.0 * @access public * @var string */ public $field_key = ''; /** * Field Name Prefix. * * @since 0.2.0 * @access public * @var string */ public $field_name = ''; /** * Conditional Field "code". * * @since 0.2.0 * @access public * @var string */ public $conditional_code = ''; /** * Maybe skip the Action when the Form the Action is attached to is submitted. * * @since 0.2.0 * * @param array $form The array of Form data. * @param array $action The array of Action data. * @return bool $prepare The net result of the set of filters. */ public function make_skip( $form, $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.2.0 * * @param bool $prepare True by default so that the Form Action goes ahead. * @param array $form The array of Form data. * @param array $action The array of Action data. */ $filter = 'acfe/form/v3/skip/' . $this->action_name; $prepare = apply_filters( $filter, $prepare, $form, $action ); $prepare = apply_filters( $filter . '/form=' . $form_name, $prepare, $form, $action ); if ( ! empty( $action['name'] ) ) { $prepare = apply_filters( $filter . '/action=' . $action['name'], $prepare, $form, $action ); } // --< return $prepare; } /** * Saves the result of the Action for use by subsequent Actions. * * @since 0.2.0 * * @param array $action The array of Action data. * @param array $data The result of the Action. */ public function make_action_save( $action, $data ) { // Update array of Action results. $this->set_action_output( $data, $action ); } /** * Defines the action by adding a layout. * * @since 0.2.0 * * @param array $layout The existing layout. * @return array $layout The modified layout. */ public function register_layout( $layout ) { // Build Action Tab. $action_tab_fields = $this->tab_action_add(); // Build Mapping Tab. $mapping_tab_fields = $this->tab_mapping_add(); // Build Attachments Tab. $attachments_tab_fields = $this->tab_attachments_add(); // Combine Sub-Fields. $layout = array_merge( $action_tab_fields, $mapping_tab_fields, $attachments_tab_fields ); /** * Let the classes that extend this one modify the Sub-Fields. * * @since 0.2.0 * * @param array $sub_fields The array of Sub-Fields. */ $layout = apply_filters( 'cfafa/acfe/form/v3/actions/sub_fields', $layout ); return $layout; } /** * 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 "name" as its "name" and * "field_name" as its "key". Only its "placeholder" attribute needs to be * configured. * * @since 0.2.0 * * @return array $fields The array of Fields for this section. */ public function tab_action_add() { // Init Fields array. $fields = []; // "Action" Tab wrapper. $fields[] = [ 'key' => 'field_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' => 'field_name', 'label' => __( 'Action name', 'conditional-form-actions-for-acfe' ), 'name' => 'name', '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.2.0 * * @return array $fields The array of Fields for this section. */ public function tab_action_append() { $fields = []; return $fields; } /** * Defines the "Mapping" Tab. * * @since 0.2.0 * * @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.2.0 * * @param string $label The label for this section. * @return array $fields The array of Fields for this section. */ public function tab_mapping_header( $label = '' ) { // Set a default label. if ( empty( $label ) ) { $label = __( 'Mapping', 'conditional-form-actions-for-acfe' ); } // "Mapping" Tab wrapper. $mapping_tab = [ [ 'key' => $this->field_key . 'tab_load', 'label' => $label, '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; } /** * Defines the "Attachments" Tab. * * @since 0.2.0 * * @return array $fields The array of Fields for this section. */ public function tab_attachments_add() { $fields = []; return $fields; } /** * Defines the "Attachments" Tab Header. * * @since 0.2.0 * * @return array $fields The array of Fields for this section. */ public function tab_attachments_header() { // "Attachments" Tab wrapper. $attachments_tab = [ [ 'key' => $this->field_key . 'tab_attachments', 'label' => __( 'Attachments', '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( $attachments_tab ); // --< return $fields; } /** * Gets the array that defines a "Map Field" for the "Mapping" Tab. * * @since 0.2.0 * * @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' => '', ], 'choices' => [], 'default_value' => [], 'allow_null' => 1, 'multiple' => 0, 'ui' => 1, 'return_format' => 'value', 'placeholder' => __( 'Default', 'conditional-form-actions-for-acfe' ), 'ajax' => 1, 'search_placeholder' => __( 'Select a field or enter a custom value or template tag.', 'conditional-form-actions-for-acfe' ), 'allow_custom' => 1, 'conditional_logic' => 0, 'ajax_action' => 'acfe/form/map_field_ajax', ]; // Default conditional logic. $field['conditional_logic'] = []; // Maybe replace with custom conditional logic. if ( ! empty( $conditional_logic ) ) { $field['conditional_logic'] = $conditional_logic; } // --< return $field; } /** * Prepare the data from an ACFE Form. * * @since 0.2.0 * * @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 return array from the Form data. foreach ( $form_data as $param => $value ) { // Skip if empty but allow (string) "0" as valid data. if ( empty( $value ) && '0' !== $value ) { continue; } // Maybe decode entities. if ( is_string( $value ) && ! is_numeric( $value ) ) { $value = html_entity_decode( $value ); } // Maybe decode entities in arrays. if ( is_array( $value ) ) { array_walk_recursive( $value, function( &$item ) { if ( is_string( $item ) && ! is_numeric( $item ) ) { $item = html_entity_decode( $item ); } } ); } // Finally add value to return array. $filtered_data[ $param ] = $value; } // --< return $filtered_data; } /** * Adds the Conditional Field given data from mapped Fields. * * @since 0.2.0 * * @param array $action The array of Action data. * @return array $action The modified array of Action data. */ public function form_conditional_populate( $action ) { // Build the action key. $key = $this->field_name . 'map_' . $this->conditional_code; // Store Conditional Field reference. $action[ $this->conditional_code . '_ref' ] = $action[ $key ]; // Prepare to apply tags. $action[ $this->conditional_code ] = $action[ $key ]; // Set ACFE "context". We want unformatted data. $context = [ 'context' => 'save', 'format' => false, ]; // Apply tags to the Conditional Field value. acfe_apply_tags( $action[ $this->conditional_code ], $context ); // Save a generic conditional result. $action['conditional'] = $action[ $this->conditional_code ]; // --< return $action; } /** * Checks the Conditional Field given data from mapped Fields. * * @since 0.2.0 * * @param array $action The array of Action data. * @return bool $continue True if the Action should continue or false to skip. */ public function form_conditional_check( $action ) { // Approve by default. $continue = true; // Skip if the Redirect Conditional Reference Field has a value. if ( ! empty( $action[ $this->conditional_code . '_ref' ] ) ) { // And the Redirect Conditional Field has no value. if ( empty( $action[ $this->conditional_code ] ) ) { return false; } } // --< return $continue; } }