Skip to content
Snippets Groups Projects
class-cfafa-form-action-base.php 12.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Christian Wach's avatar
    Christian Wach committed
    <?php
    /**
    
     * ACFE Form Action Base Class.
    
    Christian Wach's avatar
    Christian Wach committed
     *
     * 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.
    
    Christian Wach's avatar
    Christian Wach committed
     *
    
     * A class that is extended by ACFE Form Action classes.
    
     * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
     */
    
    class CFAFA_ACFE_Form_Action_Base extends acfe_module_form_action {
    
    Christian Wach's avatar
    Christian Wach committed
    
    	/**
    	 * Form Action Name.
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 * @access public
    
    	 * @var string
    
    Christian Wach's avatar
    Christian Wach committed
    	 */
    	public $action_name = '';
    
    	/**
    	 * Form Action Label.
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 * @access public
    
    	 * @var string
    
    Christian Wach's avatar
    Christian Wach committed
    	 */
    	public $action_label = '';
    
    	/**
    	 * Form Action Alias Placeholder.
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 * @access public
    
    	 * @var string
    
    Christian Wach's avatar
    Christian Wach committed
    	 */
    	public $alias_placeholder = '';
    
    	/**
    	 * Field Key Prefix.
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 * @access public
    
    	 * @var string
    
    Christian Wach's avatar
    Christian Wach committed
    	 */
    	public $field_key = '';
    
    	/**
    	 * Field Name Prefix.
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 * @access public
    
    	 * @var string
    
    Christian Wach's avatar
    Christian Wach committed
    	 */
    	public $field_name = '';
    
    	/**
    
    	 * Conditional Field "code".
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    
    	 * @since 0.2.0
    	 * @access public
    	 * @var string
    
    Christian Wach's avatar
    Christian Wach committed
    	 */
    
    	public $conditional_code = '';
    
    Christian Wach's avatar
    Christian Wach committed
    
    	/**
    	 * Maybe skip the Action when the Form the Action is attached to is submitted.
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    
    	 * @param array $form The array of Form data.
    	 * @param array $action The array of Action data.
    
    Christian Wach's avatar
    Christian Wach committed
    	 * @return bool $prepare The net result of the set of filters.
    	 */
    
    	public function make_skip( $form, $action ) {
    
    Christian Wach's avatar
    Christian Wach committed
    
    		// Get some Form details.
    		$form_name = acf_maybe_get( $form, 'name' );
    
    		$form_id   = acf_maybe_get( $form, 'ID' );
    
    Christian Wach's avatar
    Christian Wach committed
    
    		// 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
    
    Christian Wach's avatar
    Christian Wach committed
    		 *
    
    		 * @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.
    
    Christian Wach's avatar
    Christian Wach committed
    		 */
    
    		$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 );
    
    Christian Wach's avatar
    Christian Wach committed
    		}
    
    		// --<
    		return $prepare;
    
    	}
    
    	/**
    	 * Saves the result of the Action for use by subsequent Actions.
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    
    	 * @param array $action The array of Action data.
    	 * @param array $data The result of the Action.
    
    Christian Wach's avatar
    Christian Wach committed
    	 */
    
    Christian Wach's avatar
    Christian Wach committed
    	public function make_action_save( $action, $data ) {
    
    Christian Wach's avatar
    Christian Wach committed
    
    		// Update array of Action results.
    
    		$this->set_action_output( $data, $action );
    
    Christian Wach's avatar
    Christian Wach committed
    
    	}
    
    	/**
    	 * Defines the action by adding a layout.
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    
    	 * @param array $layout The existing layout.
    	 * @return array $layout The modified layout.
    
    Christian Wach's avatar
    Christian Wach committed
    	 */
    
    	public function register_layout( $layout ) {
    
    Christian Wach's avatar
    Christian Wach committed
    
    		// 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();
    
    
    Christian Wach's avatar
    Christian Wach committed
    		// Combine Sub-Fields.
    
    		$layout = array_merge(
    
    Christian Wach's avatar
    Christian Wach committed
    			$action_tab_fields,
    
    			$mapping_tab_fields,
    			$attachments_tab_fields
    
    Christian Wach's avatar
    Christian Wach committed
    		);
    
    		/**
    		 * Let the classes that extend this one modify the Sub-Fields.
    		 *
    
    		 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    		 *
    		 * @param array $sub_fields The array of Sub-Fields.
    		 */
    
    		$layout = apply_filters( 'cfafa/acfe/form/v3/actions/sub_fields', $layout );
    
    Christian Wach's avatar
    Christian Wach committed
    
    
    		return $layout;
    
    Christian Wach's avatar
    Christian Wach committed
    
    	}
    
    	/**
    	 * 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.
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    	 * @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,
    
    Christian Wach's avatar
    Christian Wach committed
    			'conditional_logic' => 0,
    
    			'wrapper'           => [
    				'width'              => '',
    				'class'              => '',
    				'id'                 => '',
    
    Christian Wach's avatar
    Christian Wach committed
    				'data-no-preference' => true,
    			],
    
    			'acfe_permissions'  => '',
    			'placement'         => 'top',
    			'endpoint'          => 0,
    
    Christian Wach's avatar
    Christian Wach committed
    		];
    
    		// "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,
    
    Christian Wach's avatar
    Christian Wach committed
    			'conditional_logic' => 0,
    
    			'wrapper'           => [
    				'width'                      => '',
    				'class'                      => '',
    				'id'                         => '',
    
    Christian Wach's avatar
    Christian Wach committed
    				'data-instruction-placement' => 'field',
    			],
    
    			'acfe_permissions'  => '',
    			'default_value'     => '',
    			'placeholder'       => $this->alias_placeholder,
    			'prepend'           => '',
    			'append'            => '',
    			'maxlength'         => '',
    
    Christian Wach's avatar
    Christian Wach committed
    		];
    
    		// Add any further Fields.
    		$action_extras = $this->tab_action_append();
    		if ( ! empty( $action_extras ) ) {
    
    			$fields = array_merge( $fields, $action_extras );
    
    Christian Wach's avatar
    Christian Wach committed
    		}
    
    		// --<
    		return $fields;
    
    	}
    
    	/**
    	 * Defines additional Fields for the "Action" Tab.
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    	 * @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
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    	 * @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
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    
    	 * @param string $label The label for this section.
    
    Christian Wach's avatar
    Christian Wach committed
    	 * @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' );
    		}
    
    Christian Wach's avatar
    Christian Wach committed
    
    		// "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,
    
    Christian Wach's avatar
    Christian Wach committed
    			],
    
    Christian Wach's avatar
    Christian Wach committed
    
    		// 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;
    
    	}
    
    
    Christian Wach's avatar
    Christian Wach committed
    	/**
    	 * Gets the array that defines a "Map Field" for the "Mapping" Tab.
    	 *
    
    	 * @since 0.2.0
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    	 * @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.
    
    Christian Wach's avatar
    Christian Wach committed
    	 * @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'            => [
    
    Christian Wach's avatar
    Christian Wach committed
    				'width' => '',
    				'class' => '',
    
    				'id'    => '',
    
    Christian Wach's avatar
    Christian Wach committed
    			],
    
    			'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',
    
    			'nonce'              => wp_create_nonce( $this->field_key . 'map_' . $code ),
    
    Christian Wach's avatar
    Christian Wach committed
    		];
    
    		// Default conditional logic.
    
    		$field['conditional_logic'] = [];
    
    Christian Wach's avatar
    Christian Wach committed
    
    		// 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
    
    Christian Wach's avatar
    Christian Wach committed
    	 *
    	 * @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.
    
    Christian Wach's avatar
    Christian Wach committed
    		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 );
    
    Christian Wach's avatar
    Christian Wach committed
    			}
    
    
    			// 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;
    
    
    Christian Wach's avatar
    Christian Wach committed
    		}
    
    		// --<
    		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;
    
    	}
    
    
    Christian Wach's avatar
    Christian Wach committed
    }