prefix . 'addwwomu_customer_addresses'; // Use your actual table name $billing_addresses = $wpdb->get_results($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "SELECT * FROM $table_name WHERE user_id = %d", // phpcs:ignore $user_id )); if (!empty($billing_addresses)) { $options = [ '' => __('Select a billing address', 'addweb-woo-multi-address') ]; $default_selected = ''; // will hold the default ID foreach ($billing_addresses as $address) { $options[$address->id] = esc_html($address->address_label); if ($address->address_type === 'billing') { if ((int)$address->is_default === 1) { $default_selected = $address->id; } } } // Override WC value if none selected (i.e., during first load) $selected_value = WC()->checkout->get_value('contact-namespace-billing_address'); if (empty($selected_value) && $default_selected) { $selected_value = $default_selected; } // Render the select field with selected value woocommerce_form_field('contact-namespace-billing_address', array( 'type' => 'select', 'class' => array('form-row-wide', 'billing-select'), 'label' => __('Billing Address', 'addweb-woo-multi-address'), 'options' => $options, ), $selected_value); // Hidden field woocommerce_form_field('addwwomu_simple_billing_type', array( 'type' => 'hidden', 'default' => 'simple_billing', ), '1'); // Optional loader HTML echo '
'; } } public function addwwomu_normal_custom_checkout_shipping_field() { global $wpdb; $user_id = get_current_user_id(); $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; // change this to your actual table name $shipping_addresses = $wpdb->get_results($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "SELECT * FROM $table_name WHERE user_id = %d", // phpcs:ignore $user_id )); if (! empty($shipping_addresses)) { $options = [ '' => __('Select a shipping address', 'addweb-woo-multi-address') ]; foreach ($shipping_addresses as $address) { $options[$address->id] = esc_html($address->address_label); if ($address->address_type === 'shipping') { if ((int)$address->is_default === 1) { $default_selected = $address->id; } } } // Override WC value if none selected (i.e., during first load) $selected_value = WC()->checkout->get_value('contact-namespace-shipping_address'); if (empty($selected_value) && $default_selected) { $selected_value = $default_selected; } woocommerce_form_field('contact-namespace-shipping_address', array( 'type' => 'select', 'class' => array('form-row-wide', 'shipping-select'), 'label' => __('shipping Address', 'addweb-woo-multi-address'), 'options' => $options, ), $selected_value); } } // end for classic WordPress woocommerce public function addwwomu_custom_orders_table_supported() { return true; } public function addwwomu_should_display_features_settings() { return false; } public function addwwomu_address_update_notice() { ?>

prefix . 'addwwomu_customer_addresses'; // Check if the table already exists $table_exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name)) === $table_name; // phpcs:ignore if (!$table_exists) { $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id BIGINT(20) NOT NULL AUTO_INCREMENT, user_id BIGINT(20) NOT NULL, address_type VARCHAR(20) NOT NULL, address_label VARCHAR(50), first_name VARCHAR(100), last_name VARCHAR(100), company VARCHAR(100), country VARCHAR(100), address_1 TEXT, address_2 TEXT, city VARCHAR(100), state VARCHAR(100), postcode VARCHAR(20), phone VARCHAR(30), email VARCHAR(100), is_default TINYINT(1) DEFAULT 0, PRIMARY KEY (id) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); $executed_queries = dbDelta($sql); if (!empty($executed_queries) || $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name)) === $table_name) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery // Enqueue AJAX script to trigger the function wp_schedule_single_event(time() + 5, 'addwwomu_delayed_import'); } } } public function addwwomu_enqueue_scripts_frontend() { wp_enqueue_style('dashicons'); wp_enqueue_script('multiple-addresses', ADDWWOMU_MULTIPLE_ADDRESSES_URL . 'assets/js/multiple-addresses.js', ['jquery'], '1.0.0', true); // wp_enqueue_script('custom-checkout', ADDWWOMU_MULTIPLE_ADDRESSES_URL . 'assets/js/custom-checkout.js', ['jquery'], '1.0.0', true); if (is_wc_endpoint_url('edit-address')) { wp_enqueue_style('addweb-custom', ADDWWOMU_MULTIPLE_ADDRESSES_URL . 'assets/css/addweb-custom.css', [], '1.0.0'); } // wp_localize_script('multiple-addresses', 'addwwomu_add_addresses', array( // 'ajax_url' => admin_url('admin-ajax.php'), // 'nonce' => wp_create_nonce('add_address_nonce') // Create nonce for security // )); wp_localize_script('multiple-addresses', 'addwwomu_multiple_addresses', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('addwwomu_multiple_addresses_nonce'), 'error_message' => __('Something went wrong, please try again.', 'addweb-woo-multi-address'), 'success_message' => __('Address added successfully!', 'addweb-woo-multi-address') )); wp_enqueue_style('multiple-addresses', ADDWWOMU_MULTIPLE_ADDRESSES_URL . 'assets/css/addweb-style.css', [], '1.0.0'); } public function addwwomu_enqueue_scripts_admin() { // if ($hook !== 'toplevel_page_address-import') { // return; // } wp_enqueue_script('datatables-js', ADDWWOMU_MULTIPLE_ADDRESSES_URL . 'assets/js/jquery.dataTables.min.js', array('jquery'), '2.3', true); wp_enqueue_style('datatables-css', ADDWWOMU_MULTIPLE_ADDRESSES_URL . 'assets/css/jquery.dataTables.min.css', array(), '2.3'); wp_localize_script('address-datatable', 'addwwomuAddressData', [ 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('address_table_nonce'), ]); wp_enqueue_script('address-import-script', ADDWWOMU_MULTIPLE_ADDRESSES_URL . 'assets/js/address-import.js', ['jquery'], '1.0.0', true); wp_localize_script('address-import-script', 'addwwomu_address_import', [ 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('address_import_nonce'), ]); } public function addwwomu_add_admin_menu() { // Add main menu page add_menu_page( 'Customer Addresses', // Page title 'Addresses', // Menu title 'manage_options', // Capability 'addweb-customer_address', // Menu slug [$this, 'addwwomu_render_customer_addresses_page'], // Callback function '', // Icon URL (optional, empty for default) 6 // Position in the menu ); } public function addwwomu_handle_address_data_by_pagination() { check_ajax_referer('address_table_nonce', 'nonce'); global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; // Read DataTables parameters $draw = isset($_POST['draw']) ? intval($_POST['draw']) : 0; $start = isset($_POST['start']) ? intval($_POST['start']) : 0; $length = isset($_POST['length']) ? intval($_POST['length']) : 10; $length = $length > 50 ? 50 : $length; // Enforce a maximum limit of 50 rows per request $search_value = ''; if (isset($_POST['search']['value'])) { $search_value = sanitize_text_field(wp_unslash($_POST['search']['value'])); } $order_column_index = isset($_POST['order'][0]['column']) ? intval($_POST['order'][0]['column']) : 0; $order_direction = isset($_POST['order'][0]['dir']) ? sanitize_text_field(wp_unslash($_POST['order'][0]['dir'])) : 'asc'; $columns = [ 'id', 'user_id', 'address_type', 'address_label', 'first_name', 'last_name', 'company', 'country', 'address_1', 'address_2', 'city', 'state', 'postcode', 'phone', 'email', 'is_default' ]; $order_column = isset($columns[$order_column_index]) ? $columns[$order_column_index] : 'id'; // Build the query $query = "SELECT * FROM $table_name"; $query_count = "SELECT COUNT(*) FROM $table_name"; // Add search functionality if (! empty($search_value)) { $like = '%' . $wpdb->esc_like($search_value) . '%'; $where_clause = $wpdb->prepare( " WHERE (first_name LIKE %s OR last_name LIKE %s OR email LIKE %s OR phone LIKE %s OR city LIKE %s OR postcode LIKE %s)", $like, $like, $like, $like, $like, $like ); $query .= $where_clause; $query_count .= $where_clause; } // Add ordering $query .= " ORDER BY $order_column $order_direction"; // Add pagination $query .= " LIMIT $start, $length"; // Execute queries // phpcs:ignore $data = $wpdb->get_results($query, ARRAY_A); // phpcs:ignore $total_records = $wpdb->get_var($query_count); // Prepare response wp_send_json([ 'draw' => $draw, 'recordsTotal' => $total_records, 'recordsFiltered' => $total_records, // Update if search filters change the count 'data' => $data, ]); } public function addwwomu_export_addresses_csv() { global $wpdb; // Sanitize table name manually — table names can't use prepare() placeholders $table_name = esc_sql($wpdb->prefix . 'addwwomu_customer_addresses'); $addresses = $wpdb->get_results("SELECT * FROM {$table_name}", ARRAY_A); // phpcs:ignore if (!$addresses) { wp_send_json_error(['message' => 'No addresses found to export.']); return; } // Prepare the CSV content $csv_data = []; $csv_data[] = array_keys($addresses[0]); // Header row foreach ($addresses as $row) { $csv_data[] = $row; } // Output CSV $csv_output = fopen('php://output', 'w'); foreach ($csv_data as $csv_row) { fputcsv($csv_output, $csv_row); } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Using fclose() for controlled CSV export fclose($csv_output); // Send response as a downloadable file header('Content-Type: text/csv'); header('Content-Disposition: attachment; filename="customer_addresses.csv"'); header('Pragma: no-cache'); header('Expires: 0'); exit; } public function addwwomu_import_first_shipping_billing_address() { // Verify nonce // if ( // ! isset($_POST['nonce']) || // ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'addwwomu_ajax_nonce') // ) { // wp_send_json_error(['message' => __('Security check failed', 'addweb-woo-multi-address')]); // return; // } global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; // Check if the table exists $table_exists = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare('SHOW TABLES LIKE %s', $table_name) ) === $table_name; if (! $table_exists) { wp_send_json_error(['message' => __('Table does not exist. Please activate the plugin again.', 'addweb-woo-multi-address')]); return; } // Get all users $users = get_users(); $total_users = count($users); // Validate offset from POST $offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0; // phpcs:ignore $batch_size = 10; $users_to_process = array_slice($users, $offset, $batch_size); foreach ($users_to_process as $user) { $user_id = $user->ID; // Billing address $billing_data = [ 'first_name' => get_user_meta($user_id, 'billing_first_name', true), 'last_name' => get_user_meta($user_id, 'billing_last_name', true), 'company' => get_user_meta($user_id, 'billing_company', true), 'country' => get_user_meta($user_id, 'billing_country', true), 'address_1' => get_user_meta($user_id, 'billing_address_1', true), 'address_2' => get_user_meta($user_id, 'billing_address_2', true), 'city' => get_user_meta($user_id, 'billing_city', true), 'state' => get_user_meta($user_id, 'billing_state', true), 'postcode' => get_user_meta($user_id, 'billing_postcode', true), 'phone' => get_user_meta($user_id, 'billing_phone', true), 'email' => get_user_meta($user_id, 'billing_email', true), ]; $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $table_name, array_merge($billing_data, [ 'user_id' => $user_id, 'address_type' => 'billing', 'address_label' => 'home', 'is_default' => 1, ]) ); // Shipping address $shipping_data = [ 'first_name' => get_user_meta($user_id, 'shipping_first_name', true), 'last_name' => get_user_meta($user_id, 'shipping_last_name', true), 'company' => get_user_meta($user_id, 'shipping_company', true), 'country' => get_user_meta($user_id, 'shipping_country', true), 'address_1' => get_user_meta($user_id, 'shipping_address_1', true), 'address_2' => get_user_meta($user_id, 'shipping_address_2', true), 'city' => get_user_meta($user_id, 'shipping_city', true), 'state' => get_user_meta($user_id, 'shipping_state', true), 'postcode' => get_user_meta($user_id, 'shipping_postcode', true), 'phone' => get_user_meta($user_id, 'shipping_phone', true), 'email' => get_user_meta($user_id, 'shipping_email', true), ]; $wpdb->insert( // phpcs:ignore $table_name, array_merge($shipping_data, [ 'user_id' => $user_id, 'address_type' => 'shipping', 'address_label' => 'office', 'is_default' => 1, ]) ); } // Send success and next offset for AJAX continuation $new_offset = $offset + $batch_size; $finished = $new_offset >= $total_users; wp_send_json_success([ 'message' => __('Batch processed successfully.', 'addweb-woo-multi-address'), 'new_offset' => $new_offset, 'completed' => $finished, ]); } public function addwwomu_on_deactivation() { global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; // Using a prepared statement for the 'WHERE' clause with data values $default_addresses = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare("SELECT * FROM {$table_name} WHERE is_default = %d", 1), // phpcs:ignore ARRAY_A ); // Update user meta with default addresses foreach ($default_addresses as $address) { $user_id = $address['user_id']; if ($address['address_type'] === 'billing') { update_user_meta($user_id, 'billing_first_name', $address['first_name']); update_user_meta($user_id, 'billing_last_name', $address['last_name']); update_user_meta($user_id, 'billing_company', $address['company']); update_user_meta($user_id, 'billing_country', $address['country']); update_user_meta($user_id, 'billing_address_1', $address['address_1']); update_user_meta($user_id, 'billing_address_2', $address['address_2']); update_user_meta($user_id, 'billing_city', $address['city']); update_user_meta($user_id, 'billing_state', $address['state']); update_user_meta($user_id, 'billing_postcode', $address['postcode']); update_user_meta($user_id, 'billing_phone', $address['phone']); update_user_meta($user_id, 'billing_email', $address['email']); } if ($address['address_type'] === 'shipping') { update_user_meta($user_id, 'shipping_first_name', $address['first_name']); update_user_meta($user_id, 'shipping_last_name', $address['last_name']); update_user_meta($user_id, 'shipping_company', $address['company']); update_user_meta($user_id, 'shipping_country', $address['country']); update_user_meta($user_id, 'shipping_address_1', $address['address_1']); update_user_meta($user_id, 'shipping_address_2', $address['address_2']); update_user_meta($user_id, 'shipping_city', $address['city']); update_user_meta($user_id, 'shipping_state', $address['state']); update_user_meta($user_id, 'shipping_postcode', $address['postcode']); update_user_meta($user_id, 'shipping_phone', $address['phone']); } } // Empty the table $wpdb->query("DROP TABLE IF EXISTS $table_name"); //phpcs:ignore } public function addwwomu_add_first_address_to_meta($user_id, $address_type, $first_name, $last_name, $company, $country, $address_1, $address_2, $city, $postcode, $phone, $email, $state) { update_user_meta($user_id, $address_type . '_first_name', $first_name); update_user_meta($user_id, $address_type . '_last_name', $last_name); update_user_meta($user_id, $address_type . '_company', $company); update_user_meta($user_id, $address_type . '_country', $country); update_user_meta($user_id, $address_type . '_address_1', $address_1); update_user_meta($user_id, $address_type . '_address_2', $address_2); update_user_meta($user_id, $address_type . '_city', $city); update_user_meta($user_id, $address_type . '_state', $state); update_user_meta($user_id, $address_type . '_postcode', $postcode); update_user_meta($user_id, $address_type . '_phone', $phone); update_user_meta($user_id, $address_type . '_email', $email); } public function addwwomu_show_adddress_type() { $user_id = get_current_user_id(); if (!$user_id) return; global $wpdb; $table_name = esc_sql($wpdb->prefix . 'addwwomu_customer_addresses'); // Sanitize table name // Use $wpdb->prepare() for the user input (user_id) and directly insert the sanitized table name $query = $wpdb->prepare("SELECT * FROM $table_name WHERE user_id = %d", $user_id); //phpcs:ignore $addresses = $wpdb->get_results($query); //phpcs:ignore echo ''; foreach ($addresses as $address) { //$checked = ($address->is_default == 1) ? 'checked' : ''; $starcolor = ($address->is_default == 1) ? 'starcolor' : ''; echo ''; } echo '
Label Address Type Actions
' . esc_html($address->address_label) . '
' . esc_html($address->first_name . ' ' . $address->last_name) . '
' . esc_html($address->address_1) . '
' . esc_html($address->address_2) . '
' . esc_html($address->city) . '
' . esc_html($address->postcode . ' ' . $address->country) . '
' . esc_html($address->address_type) . '    
'; } public function addwwomu_display_address_book() { echo 'Add New Address'; echo ''; //Edit address echo ''; echo '

' . esc_html__('My Addresses', 'addweb-woo-multi-address') . '

'; $this->addwwomu_show_adddress_type(); } public function addwwomu_show_forms($id) { // Start output buffering ob_start(); // Get WooCommerce countries & states $countries = new WC_Countries(); $country_list = $countries->get_countries(); $states = $countries->get_states(); // Include form layout include ADDWWOMU_MULTIPLE_ADDRESSES_PATH . 'pages/addweb-form-layout.php'; // Store buffered output in a variable $output = ob_get_clean(); // Return the stored output return $output; } public function addwwomu_save_selected_addresses($order_id) { if (isset($_POST['billing_address'])) { // phpcs:ignore update_post_meta($order_id, '_billing_address_id', sanitize_text_field($_POST['billing_address'])); // phpcs:ignore } if (isset($_POST['shipping_address'])) { // phpcs:ignore update_post_meta($order_id, '_shipping_address_id', sanitize_text_field($_POST['shipping_address'])); // phpcs:ignore } } public function addwwomu_display_order_addresses_in_admin($order) { $billing_address_id = get_post_meta($order->get_id(), '_billing_address_id', true); $shipping_address_id = get_post_meta($order->get_id(), '_shipping_address_id', true); if ($billing_address_id || $shipping_address_id) { global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; // Table name // If billing address is provided if ($billing_address_id) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery $billing_address = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $billing_address_id) // phpcs:ignore ); if ($billing_address) { echo '

Billing Address:
' . esc_html($billing_address->address_1) . ' ' . esc_html($billing_address->address_2) . ', ' . esc_html($billing_address->city) . ', ' . esc_html($billing_address->postcode) . '

'; } } // If shipping address is provided if ($shipping_address_id) { $shipping_address = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $shipping_address_id) // phpcs:ignore ); if ($shipping_address) { echo '

Shipping Address:
' . esc_html($shipping_address->address_1) . ' ' . esc_html($shipping_address->address_2) . ', ' . esc_html($shipping_address->city) . ', ' . esc_html($shipping_address->postcode) . '

'; } } } } // AJAX functions public function addwwomu_add_address() { if ( !isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'addwwomu_multiple_addresses_nonce') ) { wp_send_json_error(array('message' => 'Nonce verification failed.')); return; } $user_id = get_current_user_id(); if (!$user_id) { wp_send_json_error(['message' => 'User not logged in.']); } // Get the form data $address_label = isset($_POST['address_label']) ? sanitize_text_field(wp_unslash($_POST['address_label'])) : ''; $address_type = isset($_POST['address_type']) ? sanitize_text_field(wp_unslash($_POST['address_type'])) : ''; $first_name = isset($_POST['first_name']) ? sanitize_text_field(wp_unslash($_POST['first_name'])) : ''; $last_name = isset($_POST['last_name']) ? sanitize_text_field(wp_unslash($_POST['last_name'])) : ''; $company = isset($_POST['company']) ? sanitize_text_field(wp_unslash($_POST['company'])) : ''; $country = isset($_POST['country']) ? sanitize_text_field(wp_unslash($_POST['country'])) : ''; $address_1 = isset($_POST['address_1']) ? sanitize_text_field(wp_unslash($_POST['address_1'])) : ''; $address_2 = isset($_POST['address_2']) ? sanitize_text_field(wp_unslash($_POST['address_2'])) : ''; $city = isset($_POST['city']) ? sanitize_text_field(wp_unslash($_POST['city'])) : ''; $postcode = isset($_POST['postcode']) ? sanitize_text_field(wp_unslash($_POST['postcode'])) : ''; $phone = isset($_POST['phone']) ? sanitize_text_field(wp_unslash($_POST['phone'])) : ''; $email = isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : ''; $state = isset($_POST['state']) ? sanitize_text_field(wp_unslash($_POST['state'])) : ''; global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; //check if the user add first address then add to defult and to metadata of user for billing and shipping $check_for_first_address = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE user_id = %d AND address_type = %s", $user_id, $address_type)); // phpcs:ignore if (empty($check_for_first_address)) { $is_default = 1; $this->addwwomu_add_first_address_to_meta($user_id, $address_type, $first_name, $last_name, $company, $country, $address_1, $address_2, $city, $postcode, $phone, $email, $state); } else { $is_default = 0; } $status = $wpdb->insert( // phpcs:ignore $table_name, [ 'user_id' => $user_id, 'address_label' => $address_label, 'first_name' => $first_name, 'last_name' => $last_name, 'company' => $company, 'state' => $state, 'country' => $country, 'address_1' => $address_1, 'address_2' => $address_2, 'city' => $city, 'postcode' => $postcode, 'phone' => $phone, 'email' => $email, 'address_type' => $address_type, // Default address type 'is_default' => $is_default ] ); if ($status === false) { wp_send_json_error(['message' => 'Failed to add address.']); return; } wp_send_json_success(['message' => 'Address added successfully.']); } public function addwwomu_set_default_address() { // Verify the nonce for security if ( !isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'addwwomu_multiple_addresses_nonce') ) { wp_send_json_error(array('message' => 'Invalid request.')); return; } // Get the address ID and type (billing or shipping) from the request $address_id = isset($_POST['address_id']) ? absint($_POST['address_id']) : 0; $address_type = isset($_POST['address_type']) ? sanitize_text_field(wp_unslash($_POST['address_type'])) : ''; // Validate input if (!$address_id || !in_array($address_type, ['billing', 'shipping'])) { wp_send_json_error(array('message' => 'Invalid address ID or type.')); return; } // Get the current user ID $user_id = get_current_user_id(); if (!$user_id) { wp_send_json_error(array('message' => 'User not logged in.')); return; } // Update the database to set this address as default and unset others global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; // Unset previous default addresses $wpdb->update( //// phpcs:ignore WordPress.DB.DirectDatabaseQuery $table_name, ['is_default' => 0], ['user_id' => $user_id, 'address_type' => $address_type], ['%d'], ['%d', '%s'] ); // Set the selected address as default $updated = $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $table_name, ['is_default' => 1], ['id' => $address_id, 'user_id' => $user_id], ['%d'], ['%d', '%d'] ); if ($updated) { wp_send_json_success(array('message' => 'Default address updated successfully.')); } else { wp_send_json_error(array('message' => 'Failed to update default address.')); } } public function address_above_billing_form() { // Get saved addresses $user_id = get_current_user_id(); $addresses = $this->get_saved_addresses($user_id, 'billing'); // Fetch billing addresses if ($addresses) { echo '
'; echo '

Select Billing Address

'; echo ''; echo '
'; } } public function address_above_shipping_form() { // Get saved addresses $user_id = get_current_user_id(); $addresses = $this->get_saved_addresses($user_id, 'shipping'); // Fetch shipping addresses if ($addresses) { echo '
'; echo '

Select Shipping Address

'; echo ''; echo '
'; } } public function get_saved_addresses($user_id, $type = 'billing') { global $wpdb; $table_name = esc_sql($wpdb->prefix . 'addwwomu_customer_addresses'); // Build the query string separately to avoid interpolation inside prepare() $sql = "SELECT * FROM {$table_name} WHERE user_id = %d AND address_type = %s"; // Now prepare the query safely $query = $wpdb->prepare($sql, $user_id, $type); // phpcs:ignore return $wpdb->get_results($query); // phpcs:ignore } public function get_address_by_id($address_id) { global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; // Get the address based on the address ID $address = $wpdb->get_row($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "SELECT * FROM $table_name WHERE id = %d", // phpcs:ignore $address_id )); return $address; } public function addwwomu_delete_address() { // Verify the nonce for security if ( !isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'addwwomu_multiple_addresses_nonce') ) { wp_send_json_error(array('message' => 'Invalid nonce.')); return; } // Get the address ID from the request $address_id = isset($_POST['address_id']) ? absint($_POST['address_id']) : 0; // Validate the address ID if (!$address_id) { wp_send_json_error(array('message' => 'Invalid address ID.')); return; } // Get the current user ID $user_id = get_current_user_id(); if (!$user_id) { wp_send_json_error(array('message' => 'User not logged in.')); return; } // Delete the address from the database global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; $deleted = $wpdb->delete($table_name, array('id' => $address_id, 'user_id' => $user_id), array('%d', '%d')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery // Check if the deletion was successful if ($deleted) { wp_send_json_success(array('message' => 'Address deleted successfully.')); } else { wp_send_json_error(array('message' => 'Failed to delete the address.')); } } public function addwwomu_edit_address() { // Verify the nonce for security if ( !isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'addwwomu_multiple_addresses_nonce') ) { wp_send_json_error(array('message' => 'Invalid nonce.')); return; } // Check request method if (!isset($_SERVER['REQUEST_METHOD']) || $_SERVER['REQUEST_METHOD'] !== 'POST') { wp_send_json_error(array('message' => 'Invalid request method.')); return; } // Get the address ID from the request $address_id = isset($_POST['address_id']) ? absint($_POST['address_id']) : 0; // Get the current user ID $user_id = get_current_user_id(); if (!$user_id) { wp_send_json_error(array('message' => 'User not logged in.')); return; } // Get data from the request $address_data = array( 'address_label' => isset($_POST['address_label']) ? sanitize_text_field(wp_unslash($_POST['address_label'])) : '', 'address_type' => isset($_POST['address_type']) ? sanitize_text_field(wp_unslash($_POST['address_type'])) : '', 'first_name' => isset($_POST['first_name']) ? sanitize_text_field(wp_unslash($_POST['first_name'])) : '', 'last_name' => isset($_POST['last_name']) ? sanitize_text_field(wp_unslash($_POST['last_name'])) : '', 'company' => isset($_POST['company']) ? sanitize_text_field(wp_unslash($_POST['company'])) : '', 'address_1' => isset($_POST['address_1']) ? sanitize_text_field(wp_unslash($_POST['address_1'])) : '', 'address_2' => isset($_POST['address_2']) ? sanitize_text_field(wp_unslash($_POST['address_2'])) : '', 'city' => isset($_POST['city']) ? sanitize_text_field(wp_unslash($_POST['city'])) : '', 'state' => isset($_POST['billing_state']) ? sanitize_text_field(wp_unslash($_POST['billing_state'])) : '', 'postcode' => isset($_POST['postcode']) ? sanitize_text_field(wp_unslash($_POST['postcode'])) : '', 'country' => isset($_POST['billing_country']) ? sanitize_text_field(wp_unslash($_POST['billing_country'])) : '', 'phone' => isset($_POST['phone']) ? sanitize_text_field(wp_unslash($_POST['phone'])) : '', 'email' => isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : '' ); // Validate email if (!is_email($address_data['email'])) { wp_send_json_error(array('message' => 'Invalid email address.')); return; } global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; if ($address_id > 0) { // Update existing address $updated = $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $table_name, $address_data, array('id' => $address_id, 'user_id' => $user_id), array('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'), array('%d', '%d') ); if ($updated !== false) { wp_send_json_success(array('message' => 'Address updated successfully.')); } else { wp_send_json_error(array('message' => 'Failed to update address.', 'error' => $wpdb->last_error)); } } else { // Insert new address $address_data['user_id'] = $user_id; $inserted = $wpdb->insert($table_name, $address_data, array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery if ($inserted) { wp_send_json_success(array('message' => 'Address added successfully.')); } else { wp_send_json_error(array('message' => 'Failed to add address.', 'error' => $wpdb->last_error)); } } } public function addwwomu_get_address_with_id() { // Verify nonce for security if ( !isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'addwwomu_multiple_addresses_nonce') ) { wp_send_json_error(array('message' => 'Invalid nonce.')); return; } // Check if the user is logged in $user_id = get_current_user_id(); if (!$user_id) { wp_send_json_error(array('message' => 'User not logged in.')); return; } // Get the address ID from the request $address_id = isset($_POST['address_id']) ? absint($_POST['address_id']) : 0; if (!$address_id) { wp_send_json_error(array('message' => 'Invalid address ID.')); return; } // Query the address from the database global $wpdb; $table_name = esc_sql($wpdb->prefix . 'addwwomu_customer_addresses'); // Sanitize table name $address = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare( "SELECT * FROM {$table_name} WHERE id = %d AND user_id = %d", // phpcs:ignore $address_id, $user_id ), ARRAY_A ); if ($address) { wp_send_json_success($address); } else { wp_send_json_error(array('message' => 'Address not found.')); } } //------------------------WP_LIST_TABLES STARTS HERE--------------------------- public function addwwomu_render_customer_addresses_page() { if (! class_exists('ADDWWOMU_Addresses_Table')) { require_once ADDWWOMU_MULTIPLE_ADDRESSES_PATH . 'class/class-customer-addresses-table.php'; } $table = new ADDWWOMU_Addresses_Table(); $table->prepare_items(); ?>

search_box(__('Search Addresses', 'addweb-woo-multi-address'), 'customer-addresses-search'); ?>
display(); ?>
'addweb-address-block', 'render_callback' => array($this, 'addwwomu_render_address_selection') )); } // PHP function to fetch addresses function addwwomu_render_address_selection() { ob_start(); $user_id = get_current_user_id(); if (!$user_id) return ''; global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; $addresses = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE user_id = %d", $user_id)); // phpcs:ignore if (empty($addresses)) return ''; echo '
'; echo '

Select Billing Address

'; echo ''; echo '

Select Shipping Address

'; echo ''; echo '
'; return ob_get_clean(); } public function addwwomu_modify_block_checkout_order($order, $request = null) { global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; //user required fields safely using absint sanitize $data = $request ? $request->get_params() : $_POST; // phpcs:ignore $user_id = get_current_user_id(); // Get billing & shipping IDs from request $billing_id = isset($data['additional_fields']['namespace/billing_address']) ? absint($data['additional_fields']['namespace/billing_address']) : null; $shipping_id = isset($data['additional_fields']['namespace/shipping_address']) ? absint($data['additional_fields']['namespace/shipping_address']) : null; $is_same = isset($data['additional_fields']['namespace/use-same']) ? absint($data['additional_fields']['namespace/use-same']) : null; function address_exists($wpdb, $table_name, $user_id, $address) { // Escape the table name to prevent SQL injection $escaped_table = esc_sql($table_name); // Build the SQL with concatenation (not interpolation) $sql = " SELECT * FROM {$escaped_table} WHERE user_id = %d AND first_name = %s AND last_name = %s AND company = %s AND state = %s AND country = %s AND address_1 = %s AND address_2 = %s AND city = %s AND postcode = %s AND phone = %s AND email = %s "; // Prepare and execute the query securely return $wpdb->get_row($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $sql, // phpcs:ignore $user_id, trim($address['first_name'] ?? ''), trim($address['last_name'] ?? ''), trim($address['company'] ?? ''), trim($address['state'] ?? ''), trim($address['country'] ?? ''), trim($address['address_1'] ?? ''), trim($address['address_2'] ?? ''), trim($address['city'] ?? ''), trim($address['postcode'] ?? ''), trim($address['phone'] ?? ''), trim($address['email'] ?? '') )); } function addwwomu_handle_address($wpdb, $table_name, $user_id, $order, $prefix, $address_data, $address_id, $data) { $stored_address = null; if ($address_id) { $escaped_table = esc_sql($table_name); $sql = "SELECT * FROM {$escaped_table} WHERE id = %d"; $stored_address = $wpdb->get_row($wpdb->prepare($sql, $address_id)); // phpcs:ignore } $existing_address = address_exists($wpdb, $table_name, $user_id, $address_data); if ($existing_address) { $address_id = $existing_address->id; // Reuse existing address } elseif (!$stored_address) { $is_first_address = !$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $table_name WHERE user_id = %d AND address_type = %s", $user_id, $prefix)); // phpcs:ignore $address_label = !empty($address_data['address_1']) ? $address_data['address_1'] : ($address_data['address_2'] ?? 'Address'); $shipping_email = $data['billing_address']['email'] ?? ''; $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $table_name, [ 'user_id' => $user_id, 'address_label' => $address_label, 'first_name' => trim($address_data['first_name'] ?? ''), 'last_name' => trim($address_data['last_name'] ?? ''), 'company' => trim($address_data['company'] ?? ''), 'state' => trim($address_data['state'] ?? ''), 'country' => trim($address_data['country'] ?? ''), 'address_1' => trim($address_data['address_1'] ?? ''), 'address_2' => trim($address_data['address_2'] ?? ''), 'city' => trim($address_data['city'] ?? ''), 'postcode' => trim($address_data['postcode'] ?? ''), 'phone' => trim($address_data['phone'] ?? ''), 'email' => trim($address_data['email'] ?? $shipping_email ?? ''), 'address_type' => $prefix, 'is_default' => $is_first_address ? 1 : 0 ] ); $address_id = $wpdb->insert_id; } $final_address = $stored_address ?? $existing_address; if ($final_address) { $order->{"set_{$prefix}_first_name"}($final_address->first_name ?? ''); $order->{"set_{$prefix}_last_name"}($final_address->last_name ?? ''); $order->{"set_{$prefix}_address_1"}($final_address->address_1 ?? ''); $order->{"set_{$prefix}_address_2"}($final_address->address_2 ?? ''); $order->{"set_{$prefix}_city"}($final_address->city ?? ''); $order->{"set_{$prefix}_state"}($final_address->state ?? ''); $order->{"set_{$prefix}_postcode"}($final_address->postcode ?? ''); $order->{"set_{$prefix}_country"}($final_address->country ?? ''); $order->{"set_{$prefix}_phone"}($final_address->phone ?? ''); // If shipping email is missing, copy it from billing if ($prefix === 'shipping' && empty($final_address->email)) { $billing_email = get_user_meta($user_id, 'billing_email', true); $order->set_billing_email($billing_email); } } return $address_id; } // Handle Billing Address if (!empty($data['billing_address'])) { $billing_id = addwwomu_handle_address($wpdb, $table_name, $user_id, $order, 'billing', $data['billing_address'], $billing_id, $data); } // Handle Shipping Address if ($is_same === 1) { $order->set_shipping_first_name($order->get_billing_first_name()); $order->set_shipping_last_name($order->get_billing_last_name()); $order->set_shipping_company($order->get_billing_company()); $order->set_shipping_address_1($order->get_billing_address_1()); $order->set_shipping_address_2($order->get_billing_address_2()); $order->set_shipping_city($order->get_billing_city()); $order->set_shipping_state($order->get_billing_state()); $order->set_shipping_postcode($order->get_billing_postcode()); $order->set_shipping_country($order->get_billing_country()); $order->set_shipping_phone($order->get_billing_phone() ? $order->get_billing_phone() : ''); $shipping_id = $billing_id; // Same as billing } else { if (!empty($data['shipping_address'])) { $shipping_id = addwwomu_handle_address($wpdb, $table_name, $user_id, $order, 'shipping', $data['shipping_address'], $shipping_id, $data); } } // Update user meta with the latest address IDs update_user_meta($user_id, 'billing_address_id', $billing_id); update_user_meta($user_id, 'shipping_address_id', $shipping_id); return $order; } public function addwwomu_register_select_field() { $user_id = get_current_user_id(); if (!$user_id) return; global $wpdb; $table_name = $wpdb->prefix . 'addwwomu_customer_addresses'; //Fetch billing addresses $billing_addresses = $wpdb->get_results($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "SELECT * FROM $table_name WHERE user_id = %d", // phpcs:ignore $user_id, )); // Fetch shipping addresses $shipping_addresses = $wpdb->get_results($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "SELECT * FROM $table_name WHERE user_id = %d", // phpcs:ignore $user_id )); $default_billing_id = ''; $default_shipping_id = ''; // Prepare billing address options if (!empty($billing_addresses)) { foreach ($billing_addresses as $address) { $billing_options[] = [ 'value' => $address->id, 'label' => esc_html($address->address_label), //'selected' => $address->is_default == 1 ? true : false ]; } // Register Billing Address Select Field (Above Billing Form) woocommerce_register_additional_checkout_field([ 'id' => 'namespace/billing_address', 'label' => __('Billing Address', 'addweb-woo-multi-address'), 'placeholder' => __('Select a billing address', 'addweb-woo-multi-address'), 'location' => 'contact', // Contact section appears above billing form 'type' => 'select', 'class' => ['billing-select'], // Add custom class 'options' => $billing_options, //'value' => $default_billing_id ]); } // Prepare shipping address options if (!empty($shipping_addresses)) { foreach ($shipping_addresses as $address) { $shipping_options[] = [ 'value' => $address->id, 'label' => esc_html($address->address_label) ]; } // Register Shipping Address Select Field (Above Shipping Form) woocommerce_register_additional_checkout_field([ 'id' => 'namespace/shipping_address', 'label' => __('Shipping Address', 'addweb-woo-multi-address'), 'placeholder' => __('Select a shipping address', 'addweb-woo-multi-address'), 'location' => 'contact', // Shipping section 'type' => 'select', 'class' => ['shipping-select', 'loader'], // Add custom class 'options' => $shipping_options, 'required' => 'true' ]); // ✅ Register Hidden "use-same" Field woocommerce_register_additional_checkout_field([ 'id' => 'namespace/use-same', 'label' => __('Use same address', 'addweb-woo-multi-address'), 'type' => 'text', 'location' => 'contact', // Same section 'value' => '1', // Default value, you can dynamically change via JS 'class' => ['use-same-hidden-field'], // Optional class ],); } } public function addwwomu_update_guest_to_registered_customer($customer_id, $new_customer_data) { global $wpdb; if (!$customer_id) { return; // Exit if no customer ID } $customer_email = sanitize_email($new_customer_data['user_email']); // Step 1: Check if this email exists in WooCommerce order tables as a guest (customer_id = 0) $order_ids = $wpdb->get_col($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "SELECT ID FROM {$wpdb->prefix}wc_orders WHERE customer_id = 0 AND billing_email = %s", $customer_email )); if (!empty($order_ids)) { foreach ($order_ids as $order_id) { // Update the WooCommerce order's customer_id $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "{$wpdb->prefix}wc_orders", ['customer_id' => $customer_id], ['ID' => $order_id] ); // Update order metadata `_customer_user` update_post_meta($order_id, '_customer_user', $customer_id); // Using WordPress function for meta update // Fetch order metadata for address update $order_meta = $wpdb->get_results($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "SELECT meta_key, meta_value FROM {$wpdb->prefix}wc_orders_meta WHERE order_id = %d", $order_id )); $address_data = []; foreach ($order_meta as $meta) { $address_data[$meta->meta_key] = $meta->meta_value; } // Step 2: Check if email exists in `customer_addresses` with `user_id = 0` $existing_guest_addresses = $wpdb->get_results($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "SELECT * FROM {$wpdb->prefix}customer_addresses WHERE email = %s AND user_id = 0", $customer_email )); if (!empty($existing_guest_addresses)) { foreach ($existing_guest_addresses as $guest_address) { // Update the guest address with the new `user_id` $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "{$wpdb->prefix}customer_addresses", [ 'user_id' => $customer_id, 'is_default' => 1 ], ['id' => $guest_address->id] ); } // Step 3: Update billing & shipping addresses in `customer_addresses` // foreach (['billing', 'shipping'] as $type) { // $meta_key_prefix = "{$type}_"; // $address_data_for_type = [ // 'first_name' => $address_data["{$meta_key_prefix}first_name"] ?? '', // 'last_name' => $address_data["{$meta_key_prefix}last_name"] ?? '', // 'address_1' => $address_data["{$meta_key_prefix}address_1"] ?? '', // 'address_2' => $address_data["{$meta_key_prefix}address_2"] ?? '', // 'city' => $address_data["{$meta_key_prefix}city"] ?? '', // 'state' => $address_data["{$meta_key_prefix}state"] ?? '', // 'postcode' => $address_data["{$meta_key_prefix}postcode"] ?? '', // 'country' => $address_data["{$meta_key_prefix}country"] ?? '', // 'phone' => $address_data["{$meta_key_prefix}phone"] ?? '', // 'email' => $customer_email, // 'is_default' => 1 // ]; // // Update or insert address data for billing and shipping types // $wpdb->update( // "{$wpdb->prefix}customer_addresses", // $address_data_for_type, // [ // 'email' => $customer_email, // 'address_type' => $type // ] // ); // } } } } } } new ADDWWOMU_Multiple_Addresses();