custom_fields = isset($settings['custom_fields']) ? $settings['custom_fields'] : array(); } /** * Get active fields */ protected function get_active_fields() { return array_filter($this->custom_fields, function($field) { return isset($field['active']) && $field['active'] === 'yes'; }); } /** * Process options for select/radio fields (common logic) */ protected function process_field_options($field) { $options = array(); if (isset($field['options']) && !empty($field['options'])) { if (is_array($field['options'])) { foreach ($field['options'] as $option) { if (is_array($option)) { $value = isset($option['value']) ? $option['value'] : (isset($option['label']) ? $option['label'] : ''); $label = isset($option['label']) ? $option['label'] : (isset($option['value']) ? $option['value'] : ''); } else { $value = $label = $option; } if (!empty($value)) { $options[$value] = $label; } } } elseif (is_string($field['options'])) { $decoded_options = json_decode($field['options'], true); if (json_last_error() === JSON_ERROR_NONE && is_array($decoded_options)) { foreach ($decoded_options as $option) { if (is_array($option)) { $value = isset($option['value']) ? $option['value'] : (isset($option['label']) ? $option['label'] : ''); $label = isset($option['label']) ? $option['label'] : (isset($option['value']) ? $option['value'] : ''); } else { $value = $label = $option; } if (!empty($value)) { $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; } } } } } return $options; } /** * Sanitize POST value for a field */ protected 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)); } } /** * Sanitize field value based on its type */ protected 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); } } /** * Validate field value based on its type */ protected 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; } } /** * Format value for display */ protected 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 '' . esc_html($value) . ''; default: return esc_html($value); } } /** * Save custom fields to order meta */ protected function save_fields_to_order($order, $data_source = 'POST') { if (empty($this->custom_fields)) { return; } if (!$order) { return; } try { $saved_count = 0; foreach ($this->custom_fields as $field) { if (isset($field['active']) && $field['active'] === 'yes' && $field['type'] !== 'heading') { $field_id = 'enspireplugins_acfw_' . $field['id']; $raw_value = null; // Get value based on data source if ($data_source === 'POST' && isset($_POST[$field_id])) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is handled by WooCommerce checkout process $raw_value = $this->get_sanitized_post_value( sanitize_text_field(wp_unslash($_POST[$field_id])), // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is handled by WooCommerce checkout process $field['type'] ); } elseif (is_array($data_source) && isset($data_source[$field_id])) { $raw_value = $data_source[$field_id]; } if ($raw_value !== null && (!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'])) { // Save ONLY with field_id as in the classic version $order->update_meta_data($field_id, $field_value); $saved_count++; } } } } if ($saved_count > 0) { $order->save(); } } catch (Exception $e) { // Silent error handling } } /** * Get active fields for editor/frontend */ protected function get_active_fields_for_editor() { $active_fields = $this->get_active_fields(); $editor_fields = array(); foreach ($active_fields as $field) { $editor_fields[] = array( 'id' => isset($field['id']) ? $field['id'] : '', 'label' => isset($field['label']) ? $field['label'] : '', 'type' => isset($field['type']) ? $field['type'] : 'text', 'required' => isset($field['required']) && $field['required'] === 'yes', 'placeholder' => isset($field['placeholder']) ? $field['placeholder'] : '', 'options' => isset($field['options']) ? $field['options'] : array(), ); } return $editor_fields; } /** * Render a heading field (common logic) */ protected function render_heading_field($field) { echo '
'; echo '

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

'; echo '
'; } }