load_settings(); add_action('woocommerce_checkout_billing', array($this, 'display_custom_fields'), 20); add_action('woocommerce_after_checkout_billing_form', array($this, 'display_custom_fields')); add_action('woocommerce_before_order_notes', array($this, 'display_custom_fields')); add_action('woocommerce_checkout_update_order_meta', array($this, 'save_custom_fields')); } private function load_settings() { $settings = get_option('enspireplugins_acfw_settings', array()); $this->custom_fields = isset($settings['custom_fields']) ? $settings['custom_fields'] : array(); } public function display_custom_fields($checkout) { if (empty($this->custom_fields)) { return; } $active_fields = array_filter($this->custom_fields, function($field) { return isset($field['active']) && $field['active'] === 'yes'; }); if (empty($active_fields)) { return; } static $displayed = false; if ($displayed) { return; } $displayed = true; echo '
'; echo ''; echo '
'; } private function render_radio_field($field, $checkout) { $field_id = 'enspireplugins_acfw_' . $field['id']; $current_value = $checkout->get_value($field_id); $is_required = ($field['required'] === 'yes'); $options = array(); if (isset($field['options']) && is_array($field['options'])) { foreach ($field['options'] as $option) { if (is_array($option)) { $value = isset($option['value']) ? $option['value'] : $option['label']; $label = isset($option['label']) ? $option['label'] : $option['value']; } else { $value = $label = $option; } $options[$value] = $label; } } elseif (isset($field['options']) && is_string($field['options'])) { $decoded_options = json_decode($field['options'], true); if (is_array($decoded_options)) { foreach ($decoded_options as $option) { if (is_array($option)) { $value = isset($option['value']) ? $option['value'] : $option['label']; $label = isset($option['label']) ? $option['label'] : $option['value']; } else { $value = $label = $option; } $options[$value] = $label; } } else { $string_options = preg_split('/[\r\n,]+/', $field['options']); foreach ($string_options as $option) { $option = trim($option); if (!empty($option)) { $options[$option] = $option; } } } } if (empty($options)) { return; } $css_classes = array('form-row', 'form-row-wide', 'enspireplugins_acfw-field-class'); if ($is_required) { $css_classes[] = 'validate-required'; } echo ''; echo ''; echo ''; $counter = 0; foreach ($options as $option_value => $option_label) { $radio_id = $field_id . '_' . $counter; echo ''; $counter++; } echo ''; echo '
'; } public function save_custom_fields($order_id) { if (!isset($_POST['woocommerce-process-checkout-nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['woocommerce-process-checkout-nonce'])), 'woocommerce-process_checkout')) { return; } if (empty($this->custom_fields)) { return; } $order = wc_get_order($order_id); if (!$order) { return; } try { foreach ($this->custom_fields as $field) { if (isset($field['active']) && $field['active'] === 'yes' && $field['type'] !== 'heading') { $field_id = 'enspireplugins_acfw_' . $field['id']; if (isset($_POST[$field_id])) { $sanitized_post_value = sanitize_text_field(wp_unslash($_POST[$field_id])); $raw_value = $this->get_sanitized_post_value($sanitized_post_value, $field['type']); if (!empty($raw_value) || $field['type'] === 'checkbox') { $field_value = $this->sanitize_field_value($raw_value, $field['type']); if ($this->validate_field_value($field_value, $field['type'])) { $order->update_meta_data($field_id, $field_value); } } } } } $order->save(); } catch (Exception $e) { // error_log('ENS ACFW Display Error: ' . $e->getMessage()); } } private function get_sanitized_post_value($value, $type) { if (is_array($value)) { return array_map('sanitize_text_field', array_map('wp_unslash', $value)); } else { return sanitize_text_field(wp_unslash($value)); } } private function sanitize_field_value($value, $type) { switch ($type) { case 'email': return sanitize_email($value); case 'url': return esc_url_raw($value); case 'number': return is_numeric($value) ? floatval($value) : ''; case 'textarea': return sanitize_textarea_field($value); case 'checkbox': return $value ? 'yes' : 'no'; case 'select': case 'radio': return sanitize_text_field($value); default: return sanitize_text_field($value); } } private function validate_field_value($value, $type) { switch ($type) { case 'email': return empty($value) || is_email($value); case 'url': return empty($value) || filter_var($value, FILTER_VALIDATE_URL); case 'number': return empty($value) || is_numeric($value); case 'checkbox': return in_array($value, array('yes', 'no', '1', '0', 1, 0, true, false), true); default: return true; } } private function get_field_label($field_id) { $clean_id = str_replace('enspireplugins_acfw_', '', $field_id); foreach ($this->custom_fields as $field) { if ($field['id'] === $clean_id) { return $field['label']; } } return ''; } public function display_order_meta_fields($order) { if (empty($this->custom_fields)) { return; } foreach ($this->custom_fields as $field) { if (isset($field['active']) && $field['active'] === 'yes' && $field['type'] !== 'heading') { $field_id = 'enspireplugins_acfw_' . $field['id']; $field_value = $order->get_meta($field_id); if (!empty($field_value)) { $display_label = $field['label']; $display_value = $this->format_field_value_for_display($field_value, $field['type']); echo '' . esc_html($display_label) . ': ' . esc_html($display_value) . '
'; } } } } private function format_field_value_for_display($value, $type) { switch ($type) { case 'checkbox': return ($value === 'yes' || $value === '1') ? esc_html__('Yes', 'additional-checkout-fields-for-woo') : esc_html__('No', 'additional-checkout-fields-for-woo'); case 'url': return wp_kses('' . esc_html($value) . '', array( 'a' => array( 'href' => array(), 'target' => array() ) )); default: return esc_html($value); } } private function get_select_options($field) { $options = array('' => esc_html__('Select an option…', 'additional-checkout-fields-for-woo')); if (isset($field['options']) && is_array($field['options'])) { foreach ($field['options'] as $option) { if (isset($option['value']) && isset($option['label'])) { $options[$option['value']] = esc_html($option['label']); } } } return $options; } private function get_select_field_args($field, $field_id) { return array( 'type' => 'select', 'class' => array('form-row-wide', 'enspireplugins_acfw-field'), 'input_class' => array('wc-enhanced-select'), 'label' => esc_html($field['label']), 'placeholder' => esc_attr(isset($field['placeholder']) ? $field['placeholder'] : ''), 'options' => $this->get_select_options($field), 'required' => isset($field['required']) && $field['required'] === 'yes', 'custom_attributes' => array( 'data-placeholder' => esc_html__('Select an option…', 'additional-checkout-fields-for-woo'), ), ); } private function format_checkbox_value($value) { return ($value === 'yes' || $value === '1') ? esc_html__('Yes', 'additional-checkout-fields-for-woo') : esc_html__('No', 'additional-checkout-fields-for-woo'); } }