is_block_checkout_active()) { return; } // Modify all checkout fields add_filter('woocommerce_checkout_fields', array($this, 'modify_all_fields'), 9999); // Specific field type filters add_filter('woocommerce_billing_fields', array($this, 'modify_billing_fields'), 9999); add_filter('woocommerce_shipping_fields', array($this, 'modify_shipping_fields'), 9999); // Add custom fields to checkout add_action('woocommerce_checkout_fields', array($this, 'add_custom_fields'), 9999); // Save custom fields add_action('woocommerce_checkout_create_order', array($this, 'save_fields_to_order'), 10, 2); add_action('woocommerce_store_api_checkout_update_order_from_request', array($this, 'save_block_fields'), 10, 2); // Display in admin add_action('woocommerce_admin_order_data_after_billing_address', array($this, 'display_in_admin'), 10, 1); } /** * Detect if Block Checkout is active on current page */ private function is_block_checkout_active() { // Method 1: Check Store API (Block Checkout ALWAYS uses Store API) if (did_action('woocommerce_store_api_checkout_update_order_from_request')) { return true; } // Method 2: Check if checkout page uses blocks $checkout_page_id = wc_get_page_id('checkout'); if ($checkout_page_id) { $post = get_post($checkout_page_id); // If has shortcode, it's DEFINITELY Classic if ($post && has_shortcode($post->post_content, 'woocommerce_checkout')) { return false; } // If has blocks, check for checkout block if ($post && has_blocks($post->post_content)) { if (has_block('woocommerce/checkout', $post)) { return true; } } } // Method 3: Check for Block Checkout specific classes in the DOM // (This won't work in PHP, but we default to Classic to be safe) return false; } /** * Modify all checkout fields - visibility, labels, order */ public function modify_all_fields($fields) { if (!class_exists('CFEP_Block_Field_Manager')) { return $fields; } $block_manager = CFEP_Block_Field_Manager::instance(); $all_block_fields = $block_manager->get_all_fields(null, false); foreach ($all_block_fields as $block_field) { $field_key = $block_field['field_key']; $enabled = (int) $block_field['enabled']; $is_default = (int) $block_field['is_default']; $position = (int) $block_field['position']; // Determine section $section = $this->get_field_section($field_key, $block_field['location']); // If disabled, remove it if ($enabled === 0) { if (isset($fields[$section][$field_key])) { unset($fields[$section][$field_key]); } continue; } // If it's a default field, modify it if ($is_default === 1 && isset($fields[$section][$field_key])) { $fields[$section][$field_key]['label'] = $block_field['label']; $fields[$section][$field_key]['required'] = (bool) $block_field['required']; $fields[$section][$field_key]['priority'] = $position; if (!empty($block_field['placeholder'])) { $fields[$section][$field_key]['placeholder'] = $block_field['placeholder']; } } // If it's custom, add it if ($is_default !== 1) { if (!isset($fields[$section])) { $fields[$section] = array(); } $fields[$section][$field_key] = array( 'type' => $block_field['field_type'], 'label' => $block_field['label'], 'required' => (bool) $block_field['required'], 'class' => array('form-row-wide'), 'priority' => $position, 'placeholder' => $block_field['placeholder'] ?? '' ); // Add options for select if ($block_field['field_type'] === 'select' && !empty($block_field['options'])) { $options = maybe_unserialize($block_field['options']); if (is_array($options)) { $fields[$section][$field_key]['options'] = $options; } } } } return $fields; } /** * Modify billing fields specifically */ public function modify_billing_fields($fields) { if (!class_exists('CFEP_Block_Field_Manager')) { return $fields; } $block_manager = CFEP_Block_Field_Manager::instance(); $all_block_fields = $block_manager->get_all_fields(null, false); foreach ($all_block_fields as $block_field) { if (strpos($block_field['field_key'], 'billing_') !== 0) { continue; } $field_key = $block_field['field_key']; $enabled = (int) $block_field['enabled']; $position = (int) $block_field['position']; // Remove if disabled if ($enabled === 0 && isset($fields[$field_key])) { unset($fields[$field_key]); continue; } // Update if exists if (isset($fields[$field_key])) { $fields[$field_key]['label'] = $block_field['label']; $fields[$field_key]['required'] = (bool) $block_field['required']; $fields[$field_key]['priority'] = $position; if (!empty($block_field['placeholder'])) { $fields[$field_key]['placeholder'] = $block_field['placeholder']; } } } return $fields; } /** * Modify shipping fields specifically */ public function modify_shipping_fields($fields) { if (!class_exists('CFEP_Block_Field_Manager')) { return $fields; } $block_manager = CFEP_Block_Field_Manager::instance(); $all_block_fields = $block_manager->get_all_fields(null, false); foreach ($all_block_fields as $block_field) { if (strpos($block_field['field_key'], 'shipping_') !== 0) { continue; } $field_key = $block_field['field_key']; $enabled = (int) $block_field['enabled']; $position = (int) $block_field['position']; // Remove if disabled if ($enabled === 0 && isset($fields[$field_key])) { unset($fields[$field_key]); continue; } // Update if exists if (isset($fields[$field_key])) { $fields[$field_key]['label'] = $block_field['label']; $fields[$field_key]['required'] = (bool) $block_field['required']; $fields[$field_key]['priority'] = $position; if (!empty($block_field['placeholder'])) { $fields[$field_key]['placeholder'] = $block_field['placeholder']; } } } return $fields; } /** * Add custom fields to checkout */ public function add_custom_fields($fields) { // Already handled in modify_all_fields return $fields; } /** * Get field section from key and location */ private function get_field_section($field_key, $location) { // Check key prefix first if (strpos($field_key, 'billing_') === 0) { return 'billing'; } if (strpos($field_key, 'shipping_') === 0) { return 'shipping'; } if ($field_key === 'order_comments') { return 'order'; } // Map location to section $mapping = array( 'contact' => 'billing', 'address' => 'shipping', 'billing' => 'billing', 'additional' => 'order' ); return $mapping[$location] ?? 'billing'; } /** * Save custom fields to order */ public function save_fields_to_order($order, $data) { if (!class_exists('CFEP_Block_Field_Manager')) { return; } $block_manager = CFEP_Block_Field_Manager::instance(); $custom_fields = $block_manager->get_all_fields(null, true); foreach ($custom_fields as $field) { if ((int) $field['is_default'] === 1) { continue; } $field_key = $field['field_key']; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash if (isset($_POST[$field_key])) { // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash $value = sanitize_text_field(wp_unslash($_POST[$field_key])); $order->update_meta_data('_' . $field_key, $value); } } } /** * Save Block Checkout fields */ public function save_block_fields($order, $request) { if (!class_exists('CFEP_Block_Field_Manager')) { return; } $block_manager = CFEP_Block_Field_Manager::instance(); $custom_fields = $block_manager->get_all_fields(null, true); $request_data = $request->get_params(); foreach ($custom_fields as $field) { if ((int) $field['is_default'] === 1) { continue; } $field_key = $field['field_key']; $value = null; if (isset($request_data[$field_key])) { $value = $request_data[$field_key]; } elseif (isset($request_data['extensions']['cfep-block-fields'][$field_key])) { $value = $request_data['extensions']['cfep-block-fields'][$field_key]; } if ($value !== null) { $order->update_meta_data('_' . $field_key, sanitize_text_field($value)); } } $order->save(); } /** * Display custom fields in admin */ public function display_in_admin($order) { if (!class_exists('CFEP_Block_Field_Manager')) { return; } $block_manager = CFEP_Block_Field_Manager::instance(); $custom_fields = $block_manager->get_all_fields(null, true); $has_data = false; $output = '

Custom Fields

'; foreach ($custom_fields as $field) { if ((int) $field['is_default'] === 1) { continue; } $value = $order->get_meta('_' . $field['field_key']); if (!empty($value)) { $has_data = true; $output .= '

' . esc_html($field['label']) . ': ' . esc_html($value) . '

'; } } $output .= '
'; if ($has_data) { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML built with escaped values echo $output; } } }