load_settings(); add_action('woocommerce_admin_order_data_after_shipping_address', array($this, 'display_custom_fields_in_order'), 10, 1); add_action('woocommerce_process_shop_order_meta', array($this, 'save_custom_fields_admin'), 10, 2); } private function load_settings() { $this->settings = get_option('enspireplugins_acfw_settings', array( 'custom_fields' => array() )); $this->custom_fields = isset($this->settings['custom_fields']) ? $this->settings['custom_fields'] : array(); } public function display_custom_fields_in_order($order) { $order_id = $order->get_id(); 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; } $has_data = false; foreach ($active_fields as $field) { $field_id = 'enspireplugins_acfw_' . $field['id']; $field_value = $order->get_meta($field_id, true); if (!empty($field_value)) { $has_data = true; break; } } if (!empty($active_fields)) { $nonce_field = wp_nonce_field('enspireplugins_acfw_save_order_fields', 'enspireplugins_acfw_nonce', true, false); $output = '
' . esc_html($field['label']) . ': ' . $display_value . '
'; } else { if ($field['type'] === 'checkbox') { $display_value = $this->format_field_value('no', $field); $output .= '' . esc_html($field['label']) . ': ' . $display_value . '
'; } else { $output .= '' . esc_html($field['label']) . ': ' . esc_html__('-', 'additional-checkout-fields-for-woo') . '
'; } } } $output .= ''; $output .= ''; switch ($field['type']) { case 'number': $output .= ''; break; case 'email': $output .= ''; break; case 'url': $output .= ''; break; case 'textarea': $output .= ''; break; case 'select': $output .= ''; break; case 'radio': if (isset($field['options']) && is_array($field['options'])) { foreach ($field['options'] as $option) { if (isset($option['value']) && isset($option['label'])) { $checked = checked($field_value, $option['value'], false); $output .= ''; } } } break; case 'checkbox': $field_value = !empty($field_value) ? $field_value : 'no'; $checked = ($field_value === 'yes' || $field_value === '1') ? 'checked="checked"' : ''; $checkbox_label = isset($field['placeholder']) && !empty($field['placeholder']) ? $field['placeholder'] : esc_html__('Check this box', 'additional-checkout-fields-for-woo'); $output .= ''; break; default: // text $output .= ''; break; } $output .= '
'; return $output; } public function save_custom_fields_admin($order_id, $post) { if (!current_user_can('edit_shop_orders')) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification handled below if (!isset($_POST['enspireplugins_acfw_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['enspireplugins_acfw_nonce'])), 'enspireplugins_acfw_save_order_fields')) { return; } if (empty($this->custom_fields)) { return; } $order = wc_get_order($order_id); if (!$order) { return; } try { $fields_updated = false; foreach ($this->custom_fields as $field) { if (isset($field['active']) && $field['active'] === 'yes') { $field_id = 'enspireplugins_acfw_' . $field['id']; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is already done above if (isset($_POST[$field_id])) { $field_value = $this->get_posted_field_value($field_id, $field['type']); $sanitized_value = $this->sanitize_field_value($field_value, $field['type']); if ($this->validate_field_value($sanitized_value, $field['type'])) { if (!empty($sanitized_value) || $sanitized_value === '0' || $sanitized_value === 0) { $order->update_meta_data($field_id, $sanitized_value); $fields_updated = true; } else { $order->delete_meta_data($field_id); $fields_updated = true; } } } else { if ($field['type'] === 'checkbox') { $order->delete_meta_data($field_id); $fields_updated = true; } } } } if ($fields_updated) { $order->save(); } } catch (Exception $e) { // error_log('ENS ACFW Admin Save Error: ' . $e->getMessage()); } } private function get_posted_field_value($field_id, $field_type) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is handled in parent function if (!isset($_POST[$field_id])) { return ''; } switch ($field_type) { case 'textarea': // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce verification is handled in parent function, input is sanitized below return sanitize_textarea_field(wp_unslash($_POST[$field_id])); case 'checkbox': // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce verification is handled in parent function, input is sanitized below return sanitize_text_field(wp_unslash($_POST[$field_id])); default: // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce verification is handled in parent function, input is sanitized below return sanitize_text_field(wp_unslash($_POST[$field_id])); } } 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' || $value === '1') ? 'yes' : 'no'; 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', '')); default: return true; } } }