prefix . 'cfep_checkout_fields'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { return $fields; } $cache_key = 'cfep_custom_address_fields'; $custom_fields = wp_cache_get($cache_key, 'cfep'); if ($custom_fields === false) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $custom_fields = $wpdb->get_results( "SELECT field_key, field_type, field_label, position, required, placeholder FROM {$table_name} WHERE enabled = 1 AND section IN ('billing', 'shipping') ORDER BY position ASC" ); wp_cache_set($cache_key, $custom_fields, 'cfep', 300); } if (empty($custom_fields)) { return $fields; } foreach ($custom_fields as $field) { // Remove prefixes to get clean field key $clean_key = str_replace(array('billing_', 'shipping_', 'cfep_', 'cfep-'), '', $field->field_key); $clean_key = str_replace('-', '_', $clean_key); // Build field configuration EXACTLY like WooCommerce native fields $field_config = array( 'label' => $field->field_label, 'required' => (bool) $field->required, 'priority' => (int) $field->position, // THIS IS THE KEY! 'class' => array('form-row-wide'), 'autocomplete' => 'off', ); if (!empty($field->placeholder)) { $field_config['placeholder'] = $field->placeholder; } // Map field types switch ($field->field_type) { case 'select': $field_config['type'] = 'select'; // Get options from database $options = $this->get_field_options($field->field_key); if (!empty($options)) { $field_config['options'] = $options; } break; case 'textarea': $field_config['type'] = 'textarea'; break; default: $field_config['type'] = 'text'; break; } // Add to fields array - it will be sorted by priority later $fields[$clean_key] = $field_config; } return $fields; } /** * Add custom fields to locale array as well */ public function add_to_locale($locale) { global $wpdb; $table_name = $wpdb->prefix . 'cfep_checkout_fields'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) { return $locale; } $cache_key = 'cfep_locale_address_fields'; $custom_fields = wp_cache_get($cache_key, 'cfep'); if ($custom_fields === false) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $custom_fields = $wpdb->get_results( "SELECT field_key, field_label, position, required FROM {$table_name} WHERE enabled = 1 AND section IN ('billing', 'shipping')" ); wp_cache_set($cache_key, $custom_fields, 'cfep', 300); } foreach ($custom_fields as $field) { $clean_key = str_replace(array('billing_', 'shipping_', 'cfep_', 'cfep-'), '', $field->field_key); $clean_key = str_replace('-', '_', $clean_key); $locale[$clean_key] = array( 'label' => $field->field_label, 'required' => (bool) $field->required, 'priority' => (int) $field->position, ); } return $locale; } /** * Get field options for select fields */ private function get_field_options($field_key) { global $wpdb; $table_name = $wpdb->prefix . 'cfep_checkout_fields'; $cache_key = 'cfep_field_options_' . $field_key; $field_options = wp_cache_get($cache_key, 'cfep'); if ($field_options === false) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $field_options = $wpdb->get_var( $wpdb->prepare( "SELECT field_options FROM {$table_name} WHERE field_key = %s", $field_key ) ); wp_cache_set($cache_key, $field_options, 'cfep', 300); } if (empty($field_options)) { return array(); } $options = array(); $lines = explode("\n", $field_options); foreach ($lines as $line) { $line = trim($line); if (empty($line)) continue; $options[$line] = $line; } return $options; } }