Files
2026-04-28 15:13:50 +02:00

148 lines
5.0 KiB
PHP

<?php
namespace QuadLayers\WOOCCM\View\Frontend;
use QuadLayers\WOOCCM\Helpers;
/**
* Fields_Conditional Class
*/
class Fields_Conditional {
protected static $_instance;
public function __construct() {
// Add field attributes
add_filter( 'wooccm_checkout_field_filter', array( $this, 'add_field_attributes' ) );
add_action( 'wooccm_billing_fields', array( $this, 'remove_required' ) );
add_action( 'wooccm_shipping_fields', array( $this, 'remove_required' ) );
add_action( 'wooccm_additional_fields', array( $this, 'remove_required' ) );
}
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function remove_required( $fields ) {
foreach ( $fields as $field_id => $field ) {
/**
* Continue if it's not a conditional field
*/
if ( empty( $field['conditional'] ) ) {
continue;
}
/**
* Continue if it doesn't have the conditional parent key
*/
if ( empty( $field['conditional_parent_key'] ) ) {
continue;
}
/**
* Continue if it's parent of self
*/
if ( $field['conditional_parent_key'] == $field['key'] ) {
continue;
}
/**
* Continue if parent doesn't exists
*/
if ( empty( $fields[ $field['conditional_parent_key'] ] ) ) {
continue;
}
$form_action = Helpers::get_form_action();
switch ( $form_action ) {
case 'account':
case 'save':
$is_woocommerce_process_checkout_nonce = isset( $_POST['woocommerce-process-checkout-nonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_POST['woocommerce-process-checkout-nonce'] ) ), 'woocommerce-process_checkout' );
$is_woocommerce_edit_address_nonce = isset( $_POST['woocommerce-edit-address-nonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_POST['woocommerce-edit-address-nonce'] ) ), 'woocommerce-edit_address' );
// Check if is checkout or edit address page
if ( $is_woocommerce_process_checkout_nonce || $is_woocommerce_edit_address_nonce ) {
$is_valid_conditional_field = $this->is_valid_conditional_field( $_POST, $field, $fields );
if ( ! $is_valid_conditional_field ) {
$fields[ $field['key'] ]['required'] = false;
}
}
break;
case 'update':
if ( isset( $_REQUEST['post_data'] ) ) {
$post_data = array();
parse_str( wp_unslash( $_REQUEST['post_data'] ), $post_data ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$is_valid_conditional_field = $this->is_valid_conditional_field( $post_data, $field, $fields );
if ( ! $is_valid_conditional_field ) {
$fields[ $field['key'] ]['required'] = false;
}
break;
}
case 'paypal-payments':
if ( isset( $GLOBALS['_POST'] ) ) {
$post_data = wp_unslash( $GLOBALS['_POST'] );
$is_valid_conditional_field = $this->is_valid_conditional_field( $post_data, $field, $fields );
if ( ! $is_valid_conditional_field ) {
$fields[ $field['key'] ]['required'] = false;
}
break;
}
}
}
return $fields;
}
public function is_valid_conditional_field( $post_data, $field, $all_fields = array() ) {
/**
* Don't remove field if parent doesn't exists in the current form posts
*/
if ( ! isset( $post_data[ $field['conditional_parent_key'] ] ) ) {
return false;
}
/**
* Don't remove field if conditional parent value is undefined
*/
if ( ! isset( $field['conditional_parent_value'] ) ) {
return false;
}
$posted_conditional_parent_value = (array) $post_data[ $field['conditional_parent_key'] ];
$conditional_parent_value = (array) $field['conditional_parent_value'];
/**
* Check if current field's parent condition is met
*/
if ( ! array_intersect( $conditional_parent_value, $posted_conditional_parent_value ) ) {
return false;
}
/**
* Recursively check if all ancestor fields are visible
* This ensures that fields with multiple levels of conditional dependencies work correctly
*/
if ( ! empty( $all_fields ) && ! empty( $all_fields[ $field['conditional_parent_key'] ] ) ) {
$parent_field = $all_fields[ $field['conditional_parent_key'] ];
// If parent is also conditional, check its visibility recursively
if ( ! empty( $parent_field['conditional'] ) && ! empty( $parent_field['conditional_parent_key'] ) ) {
return $this->is_valid_conditional_field( $post_data, $parent_field, $all_fields );
}
}
return true;
}
public function add_field_attributes( $field ) {
if ( ! empty( $field['conditional'] ) && ! empty( $field['conditional_parent_key'] ) && isset( $field['conditional_parent_value'] ) && ( $field['conditional_parent_key'] != $field['name'] ) ) {
$field['class'][] = 'wooccm-conditional-child';
$field['custom_attributes']['data-conditional-parent'] = $field['conditional_parent_key'];
$field['custom_attributes']['data-conditional-parent-value'] = $field['conditional_parent_value'];
}
return $field;
}
}