-
Christian Wach authoredChristian Wach authored
cfafa-form-action-product.php 8.88 KiB
<?php
/**
* "WooCommerce Product" ACFE Form Action Class.
*
* Handles the "WooCommerce Product" ACFE Form Action.
*
* @package Conditional_Form_Actions_For_ACFE
*/
// 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 Conditional_Form_Actions_For_ACFE
*/
public $plugin;
/**
* ACF Extended object.
*
* @since 0.1
* @access public
* @var CFAFA_ACFE
*/
public $acfe;
/**
* Form Action Name.
*
* @since 0.1
* @access public
* @var string
*/
public $action_name = 'woo_cfafa_product';
/**
* Field Key Prefix.
*
* @since 0.1
* @access public
* @var string
*/
public $field_key = 'field_cfafa_woo_product_';
/**
* Field Name Prefix.
*
* @since 0.1
* @access public
* @var string
*/
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_product_data( $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_product_data( $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 ( false === $result ) {
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;
}
}