From 4f8de2e1f44b6e9a1be5c143c404a5eafbc86282 Mon Sep 17 00:00:00 2001 From: Remo Zaros Date: Mon, 29 Jun 2026 11:39:43 +0200 Subject: [PATCH] Make chechout work in Safari --- prijs-per-postcode.php | 2 +- session_dialog.php | 250 +++++++++++++++++++++++------------------ 2 files changed, 140 insertions(+), 112 deletions(-) diff --git a/prijs-per-postcode.php b/prijs-per-postcode.php index 3e125db..af9d358 100644 --- a/prijs-per-postcode.php +++ b/prijs-per-postcode.php @@ -4,7 +4,7 @@ * Plugin Name: Prijzen per poscodeereeks. * Description: Producten worden gefiltered aan de hand van opgegegeven postcodereeksen.Gebruikers met een postcode die in een opgegegeven postcodereeks valt zal een lokale prijs zien. Waar elke gebruiker met een postcode die buiten eem opgegeven reeks valt zal de reguliere prijs te zien krijgen. * Author: Remo Zaros - * Version: 0.9.8 + * Version: 0.9.81 * Text Domeain: prijs-per-postcode */ diff --git a/session_dialog.php b/session_dialog.php index a045cb0..d989a74 100644 --- a/session_dialog.php +++ b/session_dialog.php @@ -343,7 +343,7 @@ function getStraatnaam($postcode, $huisnummer) ]; } - // Geef de RUWE response terug (inclusief meta, error, results, etc.) + // Give me back RUWE data (inclusive meta, error, results, etc.) return $data; } @@ -374,129 +374,157 @@ function postcode_in_range($postcode) return false; } -function modify_checkout_with_js() -{ - if ( - !is_checkout() || - (is_wc_endpoint_url() && !is_wc_endpoint_url("order-received")) - ) { +function modify_checkout_with_js() { + if ( ! is_checkout() || ( is_wc_endpoint_url() && ! is_wc_endpoint_url( 'order-received' ) ) ) { return; } - $data = get_PPPR_data(); - $city = esc_js($data["city"]); - $postcode = esc_js( preg_replace( - "/(\d+)([A-Z]+)/", - '$1 $2', - strtoupper($data["postcode"]) - )); - $address = - esc_js($data["street"] . " " . strtoupper($data["house_number"])); + $data = get_PPPR_data(); + if ( empty( $data ) ) { + return; + } + + $city = trim(esc_js( $data['city'] )); + $postcode = trim(esc_js( preg_replace( '/(\d+)([A-Z]+)/', '$1 $2', strtoupper( $data['postcode'])))); + $address = trim(esc_js( $data['street'] . ' ' . strtoupper( $data['house_number']))); + + // Enqueue script properly to handle dependencies and nonces + wp_enqueue_script( 'jquery' ); + wp_localize_script( 'jquery', 'ajax_object', array( + 'ajax_url' => admin_url( 'admin-ajax.php' ), + 'nonce' => wp_create_nonce( 'unset_my_session_nonce' ) + ) ); echo << - jQuery(document).ready(function($) { - - function lockCheckoutFields() { - if (typeof wp !== 'undefined' && wp.data && wp.data.dispatch) { - const store = 'wc/store/cart'; - - wp.data.dispatch(store).setShippingAddress({ - first_name: '', - last_name: '', - address_1: '{$address}', - address_2: '', - city: '{$city}', - state: '', - postcode: '{$postcode}', - country: 'NL', - phone: '', - email: '' - }); - - setTimeout(() => { - const targets = '#shipping-postcode, #shipping-city, #shipping-address_1'; - - $(targets).each(function() { - // Voeg readonly attribuut toe (voor toegankelijkheid) - $(this).prop('readonly', true); - - $(this).css({ - 'background-color': '#f9f9f9', - 'cursor': 'not-allowed', - 'pointer-events': 'none' // Blokkeert alle muisklikken in het veld - }); - }); - - if ($('.postcode-reset').length === 0) { - const div = document.createElement("div"); - div.setAttribute("class", "postcode-reset"); - div.innerHTML = ` - Reset postcode. - `; - - div.style.width = "100%"; - document.querySelector(".wc-block-components-address-form__city")?.after(div); - - $('.reset-postcode-show-comfirm').on('click', function(e) { - e.preventDefault(); - $(this).hide(); - $(this).next('.bevestiging').show(); - }); - $('.decline').on('click', function(e) { - e.preventDefault(); - $(this).closest('.bevestiging').hide(); - $('.reset-postcode-show-comfirm').show(); - }); - - - $('.accept').on('click', function(e) { - e.preventDefault(); - - $.ajax({ - url: ajax_object.ajax_url, - type: 'POST', - data: { - action: 'unset_my_session', // Matches wp_ajax_ hook - nonce: ajax_object.nonce // Matches wp_create_nonce action - }, - success: function(response) { - if (response.success) { - location.reload(); - } else { - console.error('Server returned error:', response.data); - alert('Failed to reset session: ' + (response.data || 'Unknown error')); - } - }, - error: function(xhr, status, error) { - console.error('AJAX request failed:', status, error); - console.log('Response Text:', xhr.responseText); // Check for PHP fatal errors - } - }); - }); + document.addEventListener('DOMContentLoaded', function() { + + // Safari Fix: Handle back/forward cache (bfcache) + window.addEventListener('pageshow', function(event) { + if (event.persisted || (typeof wp !== 'undefined' && wp.data)) { + initPPPRFields(); } + }); - jQuery(document.body).trigger('update_checkout'); + function initPPPRFields() { + // Wait for React/WC Blocks to mount + setTimeout(() => { + const addressVal = '{$address}'; + const cityVal = '{$city}'; + const postcodeVal = '{$postcode}'; - }, 800); // Iets langere delay voor React rendering - } else { - console.error('WooCommerce Blocks API is niet beschikbaar'); - } + // Map WC Blocks field selectors + const fields = [ + { id: 'shipping-address_1', val: addressVal }, + { id: 'shipping-city', val: cityVal }, + { id: 'shipping-postcode', val: postcodeVal } + ]; + + fields.forEach(field => { + // 1. Try Redux Dispatch (Standard) + if (typeof wp !== 'undefined' && wp.data && wp.data.dispatch) { + try { + wp.data.dispatch('wc/store/cart').setShippingAddress({ [field.id.replace('shipping-', '')]: field.val }); + } catch(e) { console.warn('Redux update skipped', e); } + } + + // 2. Force DOM Update (Safari Fallback) + // Select both legacy and Blocks inputs + const inputs = document.querySelectorAll('#' + field.id + ', input[name="' + field.id.replace('shipping-', '') + '"]'); + + inputs.forEach(input => { + if (input.value !== field.val) { + input.value = field.val; + + // CRITICAL FOR SAFARI: Manually trigger events so React notices + ['input', 'change'].forEach(evtType => { + input.dispatchEvent(new Event(evtType, { bubbles: true, cancelable: true })); + }); + } + + // 3. Apply Visual Lock + input.setAttribute('data-pppr-locked', 'true'); + input.readOnly = true; + }); + }); + + // Inject Reset Button once + if (!document.querySelector('.postcode-reset')) { + const cityContainer = document.querySelector('.wc-block-components-address-form__city'); + if (cityContainer) { + const div = document.createElement('div'); + div.className = 'postcode-reset'; + div.style.display = 'block'; + div.style.width = '100%'; + div.style.marginTop = '10px'; + + div.innerHTML = ` + Reset postcode. + `; + cityContainer.parentNode.insertBefore(div, cityContainer.nextSibling); + + // Event Listeners (using delegation for safety) + div.addEventListener('click', function(e) { + e.preventDefault(); + if (e.target.classList.contains('reset-postcode-show-comfirm')) { + e.target.style.display = 'none'; + div.querySelector('.bevestiging').style.display = 'block'; + } else if (e.target.classList.contains('decline')) { + div.querySelector('.bevestiging').style.display = 'none'; + div.querySelector('.reset-postcode-show-comfirm').style.display = 'block'; + } else if (e.target.classList.contains('accept')) { + fetch(ajax_object.ajax_url, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: new URLSearchParams({ + action: 'unset_my_session', + nonce: ajax_object.nonce + }) + }) + .then(res => res.json()) + .then(res => { + if (res.success) location.reload(); + else alert('Failed to reset: ' + (res.data || 'Unknown error')); + }) + .catch(err => console.error('AJAX error:', err)); + } + }); + } + } + + // Add CSS for locked state dynamically + if (!document.getElementById('pppr-styles')) { + const style = document.createElement('style'); + style.id = 'pppr-styles'; + style.textContent = ` + input[data-pppr-locked="true"] { + background-color: #f9f9f9 !important; + cursor: not-allowed !important; + pointer-events: none !important; + opacity: 0.7; + } + `; + document.head.appendChild(style); + } + + }, 600); // Delay for WC Blocks hydration } - lockCheckoutFields(); + // Initialize on load + initPPPRFields(); - let updateTimeout; - $(document.body).on('updated_checkout', function() { - clearTimeout(updateTimeout); - updateTimeout = setTimeout(lockCheckoutFields, 500); + // Re-apply if checkout updates (e.g. shipping method change) + document.body.addEventListener('updated_checkout', function() { + setTimeout(initPPPRFields, 400); }); - }); - + }); + HTML; }