Compare commits

...

35 Commits

Author SHA1 Message Date
Remo Zaros
ef3abb9514 clean up prijs-per-postcode 2026-07-01 11:19:33 +02:00
Remo Zaros
03f7e9857d move register_modal_api to main file 2026-07-01 11:18:44 +02:00
Remo Zaros
bdeae51bdb rewrite pppr_is_local 2026-07-01 11:17:12 +02:00
Remo Zaros
2df645be97 remove trim()s. was used twice 2026-06-30 10:46:08 +02:00
Remo Zaros
4173e32489 Change instruction text 2026-06-30 10:43:40 +02:00
Remo Zaros
a43d6213b5 Remove the PHP class 2026-06-29 18:53:19 +02:00
Remo Zaros
76ca74e1a6 clear shopping card when modal is shown 2026-06-29 13:35:30 +02:00
Remo Zaros
4f8de2e1f4 Make chechout work in Safari 2026-06-29 11:39:43 +02:00
Remo Zaros
159f96c9c2 Trim values 2026-06-29 09:42:10 +02:00
Remo Zaros
72bfb88bfb Make address fields populate dynamic. 2026-06-27 13:43:48 +02:00
Remo Zaros
0b467752fb remove 'winkel' from code 2026-06-26 18:28:41 +02:00
Remo Zaros
ab97611783 change cookie to work with cache plugin 2026-06-26 18:27:21 +02:00
Remo Zaros
8d42eee2c1 Correct reset function 2026-06-25 11:02:11 +02:00
Remo Zaros
29109c47d1 change version nr 2026-06-25 11:01:42 +02:00
Remo Zaros
297ba93508 Change sercure when http or https is used 2026-06-25 11:01:11 +02:00
Remo Zaros
d805477f4e Make sure prices show 2026-06-22 12:24:03 +02:00
Remo Zaros
e5e17cbafc swap session with cookie with hash 2026-06-22 09:34:14 +02:00
Remo Zaros
ba63181e6a Tried to set cookie 2026-06-13 18:06:26 +02:00
Remo Zaros
e57a7aadb9 change <?php to <<<HTML 2026-06-10 13:30:03 +02:00
Remo Zaros
0ba7c07287 rewrite API call 2026-06-10 09:11:28 +02:00
Remo Zaros
558ea24cec style postcode form 2026-06-01 12:03:17 +02:00
Remo Zaros
f0b7c405fa add extra error messages 2026-06-01 12:02:59 +02:00
Remo Zaros
a9c7f7c70f increase version 2026-06-01 12:01:38 +02:00
Remo Zaros
5345b86a25 Increase version number 2026-05-28 09:46:24 +02:00
Remo Zaros
f458be3293 Change shipping fields to billing fields. Change error message to error code in switcht statement. 2026-05-28 09:44:33 +02:00
Remo Zaros
a08d0527b4 remove session_start() that magically reappeared 2026-05-20 09:14:48 +02:00
Remo Zaros
458c216fea Replace | with a - in postcode ranges 2026-05-20 09:06:39 +02:00
Remo Zaros
5828269a70 include admin page, bump version number 2026-05-19 16:57:24 +02:00
Remo Zaros
d4be70eb78 Change postcode_in_range() to work with admin page 2026-05-19 16:56:03 +02:00
Remo Zaros
f1d0414f58 Add page wp admin 2026-05-19 16:54:21 +02:00
Remo Zaros
41f44b1200 Add more postcode ranges 2026-05-18 18:42:26 +02:00
Remo Zaros
7f32a4bb1b Add new styles 2026-05-18 18:41:52 +02:00
Remo Zaros
492289deb1 session changed, css, postcode range 2026-05-18 10:17:45 +02:00
Remo Zaros
318eb8f0c5 Change postcode modal. 2026-05-17 16:44:57 +02:00
Remo Zaros
6fd3f4a13c Add dropdown filter. Add label rename variable products admin 2026-05-14 15:04:55 +02:00
6 changed files with 1059 additions and 368 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
wp-pppr-salt.php

167
admin.php Normal file
View File

@@ -0,0 +1,167 @@
<?php
function init_postode_admin()
{
add_action("admin_menu", "local_postcodes_admin_menu", 99);
add_action("admin_head", "local_postcodes_admin_css");
add_action("admin_init", "local_postcodes_register_settings"); // Correct
}
function local_postcodes_admin_menu()
{
add_submenu_page(
"woocommerce", // Parent menu slug
"Lokale Postcodes", // Page title
"Lokale Postcodes", // Menu title
"manage_options", // Capability
"local-postcodes", // Menu slug
"generate_admin_page", // Callback function
"dashicons-buddicons-pm", // Optional icon URL or dashicon
);
}
function local_postcodes_register_settings()
{
register_setting(
"my_plugin_options",
"local_postcodes_values",
"local_postcodes_input_validate",
);
}
function generate_admin_page()
{
?>
<div class="wrap">
<h1><span class="dashicons dashicons-admin-home"></span> Lokale Postcodereeksen</h1>
<?php settings_errors("local_postcodes_error_messages"); ?>
<div class="info">
<p class="info">Vul hier de lokale postcodereeksen in.</p>
<ul>
<li>Het formaat voor een reeks is #### - #### (voorbeeld: 5000 - 5199).</li>
<li>Plaats één reeks op één regel.</li>
<li>Een reeks van 1 is geldig. (voorbeeld: 5000 - 5000).</li>
<li>Om een reeks te verwijderen. Wis de reeks en sla vervolgens de wijzigen op.</li>
</ul>
</div>
<form id="postcodes_form" method="post" action="options.php">
<?php
settings_fields("my_plugin_options");
do_settings_sections("my_plugin_options");
?>
<textarea id="local_postcodes_values" name="local_postcodes_values"><?php echo esc_textarea(
get_option("local_postcodes_values"),
); ?></textarea>
<?php submit_button(); ?>
</form>
</div>
<?php
}
function local_postcodes_admin_css()
{
?>
<style>
h1 .dashicons{
font-size: 25px;
}
.info {
font-size: 1.1rem;
max-width: 60ch;
ul {
list-style: square inside;
}
}
#postcodes_form {
display: flex;
flex-direction: column;
max-width: 60ch;
align-items: flex-end;
font-size: 1.1rem;
#local_postcodes_values{
width: 100% !important;
height: 50vh !important;
font-size: 1.1rem;
font-family: "Consolas", "Monaco", "Courier New", monospace;
}
.submit{
margin-top: .2rem;
}
}
</style>';
<?php
}
function local_postcodes_input_validate($input)
{
$valid_input = "";
$lines = preg_split("/\R/", $input, -1, PREG_SPLIT_NO_EMPTY);
$pattern = '/^\d{4}\s*\-\s*\d{4}$/';
$pc_arr = [];
foreach ($lines as $line) {
$line = trim($line);
if (preg_match($pattern, $line)) {
$parts = explode("-", $line);
$first = (int) $parts[0];
$second = (int) $parts[1];
if ($first <= $second) {
$pc_arr[] = [$first, $second];
} else {
$pc_arr[] = [$second, $first];
}
} else {
add_settings_error(
"local_postcodes_error_messages",
"invalid_postcode_" . md5($line),
'❌️ Ongeldige regel: "' .
esc_html($line) .
'". Gebruik het formaat #### - ####.(bijvoorbeeld: 5000 - 5199)',
"error",
);
}
}
usort($pc_arr, function ($a, $b) {
return $a[0] <=> $b[0];
});
$old_pc_arr_len = count($pc_arr);
$pc_arr = array_map(
"unserialize",
array_unique(array_map("serialize", $pc_arr)),
);
$new_pc_arr_len = count($pc_arr);
if ($new_pc_arr_len < $old_pc_arr_len) {
add_settings_error(
"local_postcodes_error_messages",
"Duplicaten",
// @formatter:off
"⚠️ " .
$old_pc_arr_len -
$new_pc_arr_len .
" " .
($old_pc_arr_len - $new_pc_arr_len > 1
? "duplicaten"
: "duplicaat") .
" verwijderd.",
// @formatter:on
"warning",
);
}
foreach ($pc_arr as $range) {
$valid_input .= $range[0] . " - " . $range[1] . "\n";
}
return $valid_input;
}

View File

@@ -1,70 +1,127 @@
.postcode_modal { .postcode_modal {
border-radius: 20px; border-radius: 3px;
box-shadow(10px);
border: none; border: none;
max-width: 80ch; max-width: 65ch;
box-shadow: 0 0 20pc black;
padding: 2rem; padding: 2rem;
padding-bottom: 1rem;
opacity: 0; opacity: 0;
transition: opacity 0.3s ease, display 0.3s allow-discrete; transition:
opacity 0.3s ease,
display 0.3s allow-discrete;
&[open] { &[open] {
opacity: 1; opacity: 1;
transition-behavior: allow-discrete; transition-behavior: allow-discrete;
transition: opacity 0.3s ease, display 0.3s allow-discrete; transition:
opacity 0.3s ease,
display 0.3s allow-discrete;
@starting-style {
opacity: 0;
}
}
h2 {
font-size: 1.1rem;
font-weight: 700;
}
p {
font-size: 1rem;
} }
&:not([open]) { &:not([open]) {
display: none; display: none;
} }
h2 { form {
font-size: 1.5rem; margin-top: 1rem;
margin: .6rem;
} }
input[type="text"] { input[type="text"] {
padding: .3rem; padding: 0.3rem;
font-size: 1.4rem; font-size: 1.2rem;
caret-color: hsl(344 98 40); caret-color: var(--wp--preset--color--vivid-red);
background: hsl(0 1 80);
border: none;
text-transform: uppercase;
&:focus,
&:valid,
&:invalid,
&:autofill,
&:autofill:focus {
background: hsl(0 1 80) !important;
}
} }
button { #postcode_modal_submit {
border: none; display: grid;
font-size: 1.4rem; grid-template-columns: 1fr;
grid-template-rows: 1fr;
place-items: center;
font-size: 1.2rem;
font-weight: 700;
color: hsl(233 100 100); color: hsl(233 100 100);
padding: .4rem 1rem; padding: 0.4rem 1rem;
border-radius: 5px; background: var(--wp--preset--color--vivid-red);
background: hsl(344 98 40); border: 1px var(--wp--preset--color--vivid-red) solid;
border: 1px hsl(344 98 40) solid; transition: 0.2s all linear;
margin: 0 0 0 .3rem; padding: 0.2em 2.5em;
transition: .2s all linear;
&:hover { &:hover {
color: hsl(344 98 40 ); color: var(--wp--preset--color--vivid-red);
background: hsl(344 98 100); background: hsl(344 98 100);
cursor: pointer; cursor: pointer;
} }
&:hover > .btn_loader > svg > circle {
fill: var(--wp--preset--color--vivid-red);
} }
.btn_loader,
.btn_text {
transition: 0.2s opacity linear;
grid-row: 1 / -1;
grid-column: 1 / -1;
}
}
.form_fields { .form_fields {
display: flex; display: flex;
justify-content: space-between; justify-content: center;
align-items: center; align-items: center;
gap: 0.5rem;
&>{
display: flex;
}
} }
&::backdrop { &::backdrop {
backdrop-filter: blur(1px); backdrop-filter: blur(2px);
background-color: hsl(40deg 100 0 /0.4); background: hsl(0 1 65 / 0.6);
background: radial-gradient(circle,rgba(33, 33, 33, 0.68) 0%, rgba(15, 15, 15, 0.8) 23%, rgba(0, 0, 0, 0.87) 100%);
} }
.error_message_modal_postcode { .error_message_modal_postcode {
min-height: 1lh; min-height: 1lh;
color: hsl(344 98 40 ); color: var(--wp--preset--color--vivid-red);
} /* HTML: <div class="loader"></div> */ } /* HTML: <div class="loader"></div> */
} }
/* HTML: <div class="loader"></div> */
.btn_loader {
opacity: 0;
svg {
height: 0.4rem;
}
circle {
fill: white;
transition: 0.2s fill linear;
animation: loader-pulse 1.5s ease-in-out infinite;
animation-delay: calc((var(--i, 0)) * 0.2s);
}
}
@keyframes loader-pulse {
0%,
100% {
opacity: 0.3; /* Dim state */
}
50% {
opacity: 1; /* Bright state */
}
}

175
pppr_cookie.php Normal file
View File

@@ -0,0 +1,175 @@
<?php
function create_pppr_salt() {
// 1. Check permissions first (Optional but recommended)
if ( ! wp_is_writable( plugin_dir_path( __FILE__ ) ) ) {
// Log error or handle failure
return false;
}
// 2. Define path INSIDE the plugin folder
$file_path = plugin_dir_path( __FILE__ ) . 'wp-pppr-salt.php';
// 3. Get the salt
$current_salt = wp_salt( 'auth' );
if ( empty( $current_salt ) ) {
return false;
}
// 4. Prepare content
$file_content = "<?php\n";
$file_content .= "// Auto-generated salt constant\n";
$file_content .= "// Exported salt from " . date( 'Y-m-d H:i:s' ) . "\n";
$file_content .= "define( 'WP_PPPR_SALT', '{$current_salt}' );\n";
// 5. Write the file
$bytes_written = file_put_contents( $file_path, $file_content, LOCK_EX );
// 6. Verify success
if ( $bytes_written === false ) {
// Handle error (e.g., log it)
return false;
}
return true;
}
function set_pppr_cookie($is_local, $street_name, $house_number, $postcode, $city) {
$data_string = (int)$is_local . "|" . $street_name . "|" . $house_number . "|" . $postcode . "|" . $city;
$signature = hash_hmac('sha256', $data_string, WP_PPPR_SALT);
$cookie_value = $data_string . "|" . $signature;
$cookie_domain = $_SERVER['SERVER_NAME'];
$is_secure = is_ssl();
setcookie("PPPR", $cookie_value, [
'expires' => time() + 7200,
'path' => '/',
'domain' => $cookie_domain,
'secure' => $is_secure,
'httponly' => true, // Prevent JavaScript access
'samesite' => 'Lax' // Protect against CSRF
]);
}
function unset_pppr_cookie( $path = '/') {
unset($_COOKIE["PPPR"]);
$domain = $_SERVER['SERVER_NAME'];
$is_secure = is_ssl();
// 3. Send the delete command with ALL matching parameters
setcookie(
"PPPR",
'',
time() - 3600,
'/',
$domain,
$is_secure, // Critical: Must match the 'secure' flag used when setting
true
);
}
function update_expire_pppr_cookie() {
if (!isset($_COOKIE['PPPR'])) {
return false;
}
$cookie_value = $_COOKIE['PPPR'];
$cookie_domain = $_SERVER['SERVER_NAME'];
$is_secure = is_ssl();
setcookie("PPPR", $cookie_value, [
'expires' => time() + 7200,
'path' => '/',
'domain' => $cookie_domain,
'secure' => $is_secure,
'httponly' => true, // Prevent JavaScript access
'samesite' => 'Lax' // Protect against CSRF
]);
}
function verify_pppr_cookie_string() {
if (!isset($_COOKIE['PPPR'])) {
return false;
}
$cookie_value = $_COOKIE['PPPR'];
$last_delimiter = strrpos($cookie_value, '|');
if ($last_delimiter === false) {
return false;
}
$data_part = substr($cookie_value, 0, $last_delimiter);
$hash_part = substr($cookie_value, $last_delimiter + 1);
// Check if salt is defined
if (!defined('WP_PPPR_SALT')) {
return false;
}
$expected_hash = hash_hmac('sha256', $data_part, WP_PPPR_SALT);
return hash_equals($expected_hash, $hash_part);
}
function get_PPPR_data() {
// 1. Check if cookie exists
if (!isset($_COOKIE['PPPR'])) {
return false;
}
$cookie_value = $_COOKIE['PPPR'];
// 2. Split safely using the LAST delimiter (handles pipes in street names)
$last_delimiter = strrpos($cookie_value, '|');
if ($last_delimiter === false) {
return false; // Malformed cookie
}
$data_part = substr($cookie_value, 0, $last_delimiter);
$provided_hash = substr($cookie_value, $last_delimiter + 1);
// 3. CRITICAL: Verify the signature before trusting ANY data
// Ensure WP_PPPR_SALT is defined and matches the setter exactly
if (!defined('WP_PPPR_SALT')) {
return false;
}
$expected_hash = hash_hmac('sha256', $data_part, WP_PPPR_SALT);
if (!hash_equals($expected_hash, $provided_hash)) {
return false; // Tampered or invalid cookie
}
// 4. Only now is it safe to explode the verified data
$fields = explode('|', $data_part);
// Ensure we have enough fields
if (count($fields) < 5) {
return false;
}
return [
'is_local' => (bool)$fields[0],
'street' => $fields[1],
'house_number' => $fields[2],
'postcode' => $fields[3],
'city' => $fields[4],
];
}
function pppr_is_local() {
// Check if the cookie exists and is not empty
if (isset($_COOKIE['PPPR']) && !empty($_COOKIE['PPPR'])) {
// Ensure it's treated as a string before accessing the first character
$cookie_value = (string) $_COOKIE['PPPR'];
$first_char = $cookie_value[0] ?? '';
return $first_char === '1';
}
// Return false if cookie is missing or empty
return false;
}

View File

@@ -1,65 +1,70 @@
<?php <?php
session_start();
require_once "session_dialog.php";
/* /*
* Plugin Name: prijzen per poscode range * Plugin Name: Prijs per poscodeereeks.
* Description: posctcodes in de 5000-5800 range krijgen een lokaal tarief aangeboden. * 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 * Author: Remo Zaros
* Version: 0.9.1 * Version: 0.9.090
* Text Domeain: prijs-per-postcode * Text Domeain: prijs-per-postcode
*/ */
require_once plugin_dir_path(__FILE__) . "session_dialog.php";
require_once plugin_dir_path(__FILE__) . "admin.php";
require_once plugin_dir_path(__FILE__) . "pppr_cookie.php";
if (!defined("ABSPATH")) { if (!defined("ABSPATH")) {
echo "big bag of potatoes"; echo "big bag of potatoes";
exit(); exit();
} }
class PrijsPerPostcode /*
{ * Create salt
public function __construct() */
{ register_activation_hook( __FILE__, 'create_pppr_salt' );
add_action("init", [$this, "init"]); if ( ! defined( 'WP_PPPR_SALT' ) ) {
add_action("rest_api_init", "register_modal_api"); $salt_file = __DIR__ . '/wp-pppr-salt.php';
if ( file_exists( $salt_file ) ) {
require_once $salt_file;
}else {
define("WP_PPPR_SALT", wp_salt( 'auth' ));
}
} }
public function init()
{
$uri = $_SERVER["REQUEST_URI"];
add_filter("woocommerce_sale_flash", "__return_null"); add_filter("woocommerce_sale_flash", "__return_null");
add_filter('woocommerce_show_variation_price', '__return_true');
/*
* Init the plugin
*/
add_action("init", function() {
$uri = $_SERVER["REQUEST_URI"];
init_postcode_handlers($uri); init_postcode_handlers($uri);
// set the admin page
//add_action("template_redirect", [$this, "redirect_if_missing_tag"]); init_postode_admin();
add_action( }, 1
"woocommerce_variation_options_pricing",
[$this, "add_local_price_field"],
10,
3,
); );
add_action(
"woocommerce_save_product_variation",
[$this, "save_local_price_field"],
10,
2,
);
add_action("woocommerce_before_calculate_totals", [
$this,
"use_local_price_if_local_postcode",
]);
add_filter(
"woocommerce_get_price_html",
[$this, "display_local_price_on_product"],
10,
2,
);
add_action("template_redirect", [
$this,
"controleer_postcode_op_woocommerce_paginas",
]);
}
public function add_local_price_field($loop, $variation_data, $variation) /*
* Set endpoint (postcode-modal/v1/submit) for the modal form.
*/
add_action("rest_api_init", function () {
register_rest_route( 'postcode-modal/v1', '/submit', array(
'methods' => 'POST',
'callback' => 'handle_postcode_modal',
'permission_callback' => '__return_true',
) );
});
/*
* Add local orice field to variation product.
*/
add_action("woocommerce_variation_options_pricing",
function($loop, $variation_data, $variation)
{ {
woocommerce_wp_text_input([ woocommerce_wp_text_input([
"id" => "_local_price[" . $loop . "]", "id" => "_local_price[" . $loop . "]",
@@ -72,9 +77,15 @@ class PrijsPerPostcode
"data_type" => "price", "data_type" => "price",
"wrapper_class" => "form-row form-row-first", // Left half "wrapper_class" => "form-row form-row-first", // Left half
]); ]);
} }, 10, 3,
);
public function save_local_price_field($variation_id, $i)
/*
* Save the local price on product save in the admin
*/
add_action("woocommerce_save_product_variation",
function ($variation_id, $i)
{ {
$local_price = $_POST["_local_price"][$i]; $local_price = $_POST["_local_price"][$i];
if (isset($local_price)) { if (isset($local_price)) {
@@ -84,38 +95,131 @@ class PrijsPerPostcode
wc_clean($local_price), wc_clean($local_price),
); );
} }
}, 10, 2,
);
/*
* Replace "Reguliere prijs" with "Prijs overige regios"
* in variation prodict admin
*/
add_filter( "gettext", function( $translated_text, $text, $domain,) {
if (
"woocommerce" === $domain &&
is_admin() &&
isset($_REQUEST["action"]) &&
"woocommerce_load_variations" === $_REQUEST["action"]
) {
if ($translated_text === "Reguliere prijs (%s)") {
$translated_text = "Prijs overige regios (%s)";
}
}
return $translated_text;
}, 99, 3,
);
/*
* Filter out variations whwre the price is
* either 0 or '' in the dropdown menu product page
*/
add_filter("woocommerce_variation_is_visible",
function (
$visible,
$variation_id,
$parent_id,
$variation,
) {
// Ensure $variation is a valid object
if (!$variation instanceof WC_Product_Variation) {
$variation = wc_get_product($variation_id);
} }
public function use_local_price_if_local_postcode($cart) if (!$variation) {
return false;
}
$price = pppr_is_local()
? $variation->get_meta("_local_price", true)
: $variation->get_regular_price();
if (empty($price) || floatval($price) == 0) {
return false;
}
return $visible;
}, 10, 4,
);
/*
* Dynamically recalculates the cart total by overriding the standard price
* with a region-specific _local_price for variations when
* the user's location matches the PPPR cookie criteria
*/
add_action("woocommerce_before_calculate_totals", function($cart)
{ {
if (is_admin() && !defined("DOING_AJAX")) { if (is_admin() && !defined("DOING_AJAX")) {
return; return;
} }
foreach ($cart->get_cart() as $cart_item) { foreach ($cart->get_cart() as $cart_item)
{
$product = $cart_item["data"]; $product = $cart_item["data"];
$variation_id = $product->is_type("variation") $variation_id = $product->is_type("variation")
? $product->get_id() ? $product->get_id()
: 0; : 0;
if ( if ( $variation_id && isset($_COOKIE["PPPR"]) && pppr_is_local() )
$variation_id && {
isset($_SESSION["postcode_is_local"]) &&
$_SESSION["postcode_is_local"]
) {
$local_price = get_post_meta( $local_price = get_post_meta(
$variation_id, $variation_id,
"_local_price", "_local_price",
true, true,
); );
if ($local_price) {
if ($local_price)
{
$product->set_price($local_price); $product->set_price($local_price);
} }
} }
} }
} }
);
public function controleer_postcode_op_woocommerce_paginas()
/*
* Filter to display the regular or local price on teh product page.
*/
add_filter( "woocommerce_get_price_html",
function($price_html, $product)
{
if (
$product->is_type("variation") &&
isset($_COOKIE["PPPR"]) &&
pppr_is_local()
) {
$local_price = get_post_meta(
$product->get_id(),
"_local_price",
true,
);
if ($local_price !== "") {
return wc_price($local_price);
}
}
return $price_html;
}, 10, 2,
);
/*
* Enforces region-locking by clearing the cart and redirecting users to
* the shop page if their location cookie is invalid or expired when
* accessing key WooCommerce pages.
*/
add_action("template_redirect",
function ()
{ {
if (is_admin() || defined("DOING_AJAX")) { if (is_admin() || defined("DOING_AJAX")) {
return; return;
@@ -130,31 +234,59 @@ class PrijsPerPostcode
is_account_page()) && is_account_page()) &&
!is_shop() !is_shop()
) { ) {
if (!isset($_SESSION["postcode_is_local"])) { if (!verify_pppr_cookie_string()) {
wp_redirect(home_url("/winkel/")); if (!WC()->cart->is_empty()) {
WC()->cart->empty_cart();
}
wp_safe_redirect(get_shop_url());
exit(); exit();
}else{
update_expire_pppr_cookie();
} }
} }
} }
public function display_local_price_on_product($price_html, $product)
{
if (
$product->is_type("variation") &&
isset($_SESSION["postcode_is_local"]) &&
$_SESSION["postcode_is_local"] === true
) {
$local_price = get_post_meta(
$product->get_id(),
"_local_price",
true,
); );
if ($local_price !== "") {
return wc_price($local_price);
} /*
} * Chack or postcode is still valid when pressing the buy button
return $price_html; */
} add_action( 'woocommerce_after_checkout_validation', function( $data, $errors ) {
// 1. Controleer of de cookie bestaat en geldig is
if ( ! isset( $_COOKIE['PPPR'] ) || ! verify_pppr_cookie_string() ) {
$errors->add(
'pppr_cookie_invalid',
__( '<strong>Fout:</strong> Sessie verlopen. Vernieuw de pagina en vul je postcode opnieuw in.', 'woocommerce' )
);
return; // Stop hier, geen zin om verder te checken
} }
new PrijsPerPostcode(); $pppr_data = get_PPPR_data();
if ( ! $pppr_data || empty( $pppr_data['postcode'] ) ) {
$errors->add(
'pppr_data_missing',
__( '<strong>Fout:</strong> Kon postcode niet laden.', 'woocommerce' )
);
return;
}
// 3. Normalizeer postcodes (gebruik de juiste variabelen!)
$cookie_pc = strtoupper( str_replace( ' ', '', $pppr_data['postcode'] ) );
$shipping_pc = strtoupper( str_replace( ' ', '', $data['shipping_postcode'] ) );
// 4. Vergelijk
if ( $cookie_pc !== $shipping_pc ) {
wc_add_notice(
__( '<strong>Fout:</strong> Afleverpostcode komt niet overeen met de eerder ingevulde postcode.', 'woocommerce' ),
'error'
);
}
}, 10, 2 );
function get_shop_url () {
return (function_exists('wcml_get_store_url'))
? wcml_get_store_url() // WPML WooCommerce Multilingual
: get_permalink(wc_get_page_id('shop')); // Fallback
}

View File

@@ -1,12 +1,11 @@
<?php <?php
session_start();
function init_postcode_handlers($uri) function init_postcode_handlers($uri)
{ {
if (strpos($uri, "/winkel/") !== false) { if (strpos($uri, "/winkel/") !== false) {
add_action("wp_enqueue_scripts", "modal_styles"); add_action("wp_enqueue_scripts", "modal_styles");
add_action("wp_footer", "send_postcode_data"); add_action("wp_footer", "send_postcode_data");
if (!has_postcode()) { if (!verify_pppr_cookie_string()) {
if (!is_admin()) { if (!is_admin()) {
WC()->cart->empty_cart(); WC()->cart->empty_cart();
} }
@@ -25,121 +24,163 @@ function modal_styles()
wp_enqueue_style( wp_enqueue_style(
"prijs-per-postcode", "prijs-per-postcode",
plugins_url("/assets/postcode_modal.css", __FILE__), plugins_url("/assets/postcode_modal.css", __FILE__),
[], // Voeg een lege dependencies array toe (verplicht)
filemtime(plugin_dir_path(__FILE__) . "assets/postcode_modal.css"), // Voeg versie toe
); );
} }
function show_modal() function show_modal()
{ {
?> echo <<<'HTML'
<script id="postcode_modal"> <script id="postcode_modal_open">
const postcodeModal = document.querySelector("#postcode_modal"); const postcodeModal = document.querySelector("#postcode_modal");
postcodeModal.showModal(); postcodeModal.showModal();
</script> </script>
<?php HTML;
} }
function send_postcode_data() function send_postcode_data()
{ {
?> $URL = get_rest_url(null, "postcode-modal/v1/submit");
$nonce = wp_create_nonce("wp_rest");
echo <<<HTML
<script type="module"> <script type="module">
const postcodeModal = document.querySelector("#postcode_modal"); const postcodeModal = document.querySelector("#postcode_modal");
const modalForm = document.querySelector("#postcode_modal_form"); const modalForm = document.querySelector("#postcode_modal_form");
const sndBtn = document.querySelector("#postcode_modal_submit");
const sndBtnLdr = sndBtn.querySelector(".btn_loader");
const sndBtnTxt = sndBtn.querySelector(".btn_text");
const errorMsg = document.querySelector("#error_message_modal_postcode");
modalForm.addEventListener('submit', async (e) => { // 1. Validatie bij blur (client-side checks)
e.preventDefault(); modalForm.querySelectorAll("input").forEach(input => {
const formData = new FormData(e.target); input.addEventListener("blur", ev => {
const data = Object.fromEntries(formData.entries()); errorMsg.innerHTML = "";
const json = JSON.stringify(data); if (!ev.target.validity.valid && ev.target.value !== "") {
errorMsg.innerHTML = ev.target.title;
try { }
const resp = await fetch('<?php echo get_rest_url( });
null, });
"postcode-modal/v1/submit",
); ?>', { // 2. Submit Handler
method: 'POST', modalForm.addEventListener('submit', async (e) => {
credentials: 'same-origin', e.preventDefault();
headers: { errorMsg.innerHTML = "";
'Content-Type': 'application/json',
'X-WP-Nonce': '<?php echo wp_create_nonce("wp_rest"); ?>' // UI: Laadstatus
}, sndBtn.disabled = true;
body: json sndBtnLdr.style.opacity = "1";
sndBtnTxt.style.opacity = "0";
const formData = new FormData(e.target);
const payload = Object.fromEntries(formData.entries());
try {
const resp = await fetch('{$URL}', {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': '{$nonce}'
},
body: JSON.stringify(payload)
}); });
if(!resp.ok){
throw new Error(`HTTP Error! status: ${resp.status}` );
}
const data = await resp.json(); const data = await resp.json();
console.log("Data returnd", data);
sndBtn.disabled = false;
sndBtnLdr.style.opacity = "0";
sndBtnTxt.style.opacity = "1";
if (data.status === "error") { if (data.status === "error") {
const err = data.message; const errorCode = data.code; // Komt nu correct door vanuit PHP
let errmsg const apiMessage = data.message;
switch (err) { let userErrorMessage = "Gegevens zijn niet correct.";
case "Huisnummer not found":
errmsg = "Adres niet gevonden."; // Specifieke foutafhandeling
break; if (errorCode === "HUISNUMMER_NOT_FOUND" || apiMessage.includes("not found")) {
case "Multiple addresses match this huisnummer; add huisletter and/or huisnummertoevoeging": userErrorMessage = "Adres is niet gevonden.";
errmsg = "Huisnummertovoeging mist.";
break;
default:
errmsg = "Gegevens niet correct.";
} }
document.querySelector("#error_message_modal_postcode").innerHTML = errmsg; else if (errorCode === "HUISNUMMER_AMBIGUOUS") {
const suggestions = data.suggestions || [];
if (suggestions.length > 0) {
userErrorMessage = `Meerdere opties: \${suggestions.join(", ")}. Voeg een toevoeging toe.`;
} else {
userErrorMessage = "Huisnummertoevoeging is verplicht.";
}
}
else if (errorCode === "CURL_ERROR" || errorCode === "JSON_ERROR") {
userErrorMessage = "Serverfout. Probeer het later opnieuw.";
}
errorMsg.innerHTML = userErrorMessage;
} }
if (data.status === "success") { if (data.status === "success") {
// Succes: Modal sluiten en eventueel reload of update
postcodeModal.close(); postcodeModal.close();
//location.reload(); // Optioneel: location.reload(); of update de pagina content
} }
} catch (err) { } catch (err) {
console.error("Fetch Failed:", err); sndBtn.disabled = false;
throw err; sndBtnLdr.style.opacity = "0";
sndBtnTxt.style.opacity = "1";
errorMsg.innerHTML = "Er ging iets mis bij het verbinden.";
} }
}); });
</script> </script>
<?php HTML;
} }
function render_dialog_html() function render_dialog_html()
{ {
?> echo <<<'HTML'
<dialog id="postcode_modal" class="postcode_modal" closedby="none"> <dialog id="postcode_modal" class="postcode_modal" closedby="none">
<h2>Vul je postcode en huisnummer in.</h2> <h2>Vul je postcode en huisnummer in.</h2>
<form id="postcode_modal_form" method="post" action="" novalidation> <p>Onze prijzen zijn afhankelijk van de regio. Vul daarom de postcode en het huisnummer in om de exacte prijzen te bekijken.</p>
<form id="postcode_modal_form" method="post" action="" novalidate>
<div class="form_fields"> <div class="form_fields">
<div> <!-- Dutch Postcode Field -->
<input type="text" name="postcode" <input
title="Voer een geldige Nederlandse postcode in (bijv. 1234AB of 1234 AB)." type="text"
name="postcode"
title="Voer een geldige postcode in (bijv. 1234AB of 1234 AB)."
pattern="[1-9][0-9]{3} ?(?!sa|sd|ss)[a-zA-Z]{2}" pattern="[1-9][0-9]{3} ?(?!sa|sd|ss)[a-zA-Z]{2}"
placeholder= "1010 AA" placeholder="5010 AA"
size="10" size="8"
required required
autocomplete="off"
/> />
<input type="text" name="huisnummer" <!-- House Number Field -->
pattern="/\d+([-\\s]?[a-zA-Z]+)?/" <input
title="Voer een geldig huisnummer in (bijv. 1, 1A, 1-A, 1a)." type="text"
placeholder= "12A" name="huisnummer"
size="5" title="Voer een geldig huisnummer in (bijv. 1, 1A, 1-A)."
pattern="\d+([\- ]?[a-zA-Z]+)?"
placeholder="10"
size="3"
required required
autocomplete="off"
/> />
<button id="postcode_modal_submit" type="submit"><span class="btn_text">OK</span>
<div class="btn_loader">
<svg viewBox="0 0 128 30" xmlns="http://www.w3.org/2000/svg">
<circle style="--i:0" cx="14" cy="15" r="14" />
<circle style="--i:1" cx="64" cy="15" r="14" />
<circle style="--i:2" cx="114" cy="15" r="14" />
</svg>
</div> </div>
<button id="postcode_modal_submit" type="submit">verzend</button> </button>
</div> </div>
</form> </form>
<div class="error_message_modal_postcode" id="error_message_modal_postcode" aria-live="polite"></div> <div class="error_message_modal_postcode" id="error_message_modal_postcode" aria-live="polite"></div>
<div class="loader_modal"></div>
</dialog> </dialog>
<?php HTML;
}
function has_postcode()
{
if (isset($_SESSION["postcode"])) {
return true;
}
return false;
} }
function handle_postcode_modal($data) function handle_postcode_modal($data)
@@ -147,73 +188,95 @@ function handle_postcode_modal($data)
$params = $data->get_params(); $params = $data->get_params();
$nonce = $data->get_header("X-WP-Nonce"); $nonce = $data->get_header("X-WP-Nonce");
if (wp_verify_nonce($nonce, "wp_rest")) { // 1. Security
if (!wp_verify_nonce($nonce, "wp_rest")) {
echo json_encode(["status" => "error", "message" => "nononce"]);
exit();
}
// 2. Basis Validatie
if (!verify_postcode($params["postcode"])) { if (!verify_postcode($params["postcode"])) {
$resp = [ echo json_encode(["status" => "error", "message" => "postcode"]);
"status" => "error",
"message" => "postcode",
];
echo json_encode($resp);
exit(); exit();
} }
if (!verify_huisnummer($params["huisnummer"])) { if (!verify_huisnummer($params["huisnummer"])) {
$resp = [ echo json_encode(["status" => "error", "message" => "huisnummer"]);
"status" => "error",
"message" => "huisnummer",
];
echo json_encode($resp);
exit(); exit();
} }
// 3. API Call (Ruwe data)
$result = getStraatnaam($params["postcode"], $params["huisnummer"]); $result = getStraatnaam($params["postcode"], $params["huisnummer"]);
if (isset($result["error"])) {
$resp = [ // 4. Validatie & Logic
"status" => "error", $hasError = isset($result["error"]);
"message" => $result["error"], $errorCode = null;
"apirequest" => "openpostcode.nl", $errorMessage = null;
]; $candidates = [];
echo json_encode($resp); $straatnaam = null;
exit(); $woonplaats = null;
if ($hasError) {
$errorCode = $result["error"]["code"] ?? "UNKNOWN_ERROR";
$errorMessage = $result["error"]["message"] ?? "Onbekende fout";
$candidates = $result["error"]["details"]["candidates"] ?? [];
// SPECIAL CASE: HUISNUMMER_AMBIGUOUS
if ($errorCode === "HUISNUMMER_AMBIGUOUS" && !empty($candidates)) {
$plainMatch = null;
// Zoek naar candidate ZONDER toevoeging
foreach ($candidates as $candidate) {
if (
empty($candidate["huisletter"]) &&
empty($candidate["huisnummertoevoeging"])
) {
$plainMatch = $candidate;
break;
}
} }
$_SESSION["postcode"] = $params["postcode"]; // Als we een 'platte' match hebben (bijv. 15), dan is het SUCCES
$_SESSION["huisnummer"] = $params["huisnummer"]; if ($plainMatch) {
$_SESSION["straatnaam"] = $result["straatnaam"]; $hasError = false; // Negeer de error
$_SESSION["woonplaats"] = $result["woonplaats"]; $straatnaam = $plainMatch["straat"];
$woonplaats = $plainMatch["woonplaats"];
}
}
} else {
// Normaal succes (geen error in response)
if (!empty($result["results"])) {
$straatnaam = $result["results"][0]["straat"];
$woonplaats = $result["results"][0]["woonplaats"];
} else {
// Edge case: geen error veld, maar ook geen results
$hasError = true;
$errorCode = "NO_RESULTS";
$errorMessage = "Adres niet gevonden";
}
}
$_SESSION["postcode_is_local"] = postcode_in_range( // 5. Response sturen
$params["postcode"], if ($hasError) {
5000, return new WP_REST_Response([
5800, "status" => "error",
"code" => $errorCode,
"message" => $errorMessage,
"suggestions" => $result["error"]["details"]["suggestions"] ?? [],
"apirequest" => "openpostcode.nl",
], 400);
}
set_pppr_cookie(
postcode_in_range($params["postcode"]),
trim($straatnaam),
trim($params["huisnummer"]),
trim($params["postcode"]),
trim($woonplaats)
); );
$resp = [ return new WP_REST_Response([
"status" => "success", "status" => "success",
"message" => "all good", "message" => "all good",
"straatnaam" => $result["straatnaam"], ], 200);
"lokaal_trarief" => postcode_in_range(
$params["postcode"],
5000,
5800,
),
];
} else {
$resp = [
"status" => "error",
"message" => "nononce",
];
}
echo json_encode($resp);
exit();
}
function register_modal_api()
{
register_rest_route("postcode-modal/v1", "submit", [
"methods" => "POST",
"callback" => "handle_postcode_modal",
]);
} }
function verify_postcode($postcode) function verify_postcode($postcode)
@@ -247,31 +310,45 @@ function getStraatnaam($postcode, $huisnummer)
curl_setopt($ch, CURLOPT_USERAGENT, "PHP/OpenPostcodeClient"); curl_setopt($ch, CURLOPT_USERAGENT, "PHP/OpenPostcodeClient");
$response = curl_exec($ch); $response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_error($ch)) { if (curl_error($ch)) {
curl_close($ch); curl_close($ch);
return ["error" => "cURL error: " . curl_error($ch)]; return [
"error" => ["code" => "CURL_ERROR", "message" => curl_error($ch)],
];
} }
curl_close($ch); curl_close($ch);
// Decodeer als associatieve array (true)
$data = json_decode($response, true); $data = json_decode($response, true);
if (isset($data["error"])) { // Als JSON decode faalt
if (json_last_error() !== JSON_ERROR_NONE) {
return [ return [
"error" => $data["error"]["message"], "error" => [
"code" => $data["error"]["code"], "code" => "JSON_ERROR",
"message" => "Invalid JSON response",
],
]; ];
} }
return [ // Give me back RUWE data (inclusive meta, error, results, etc.)
"straatnaam" => $data["results"][0]["straat"], return $data;
"woonplaats" => $data["results"][0]["woonplaats"],
];
} }
function postcode_in_range($postcode, $start, $end) function postcode_in_range($postcode)
{ {
$vals = get_option("local_postcodes_values", "");
$rows = preg_split("/\R/", $vals, -1, PREG_SPLIT_NO_EMPTY);
$pc_arr = [];
foreach ($rows as $row) {
$row = trim($row);
$postcode_range = explode("-", $row);
$pc_arr[] = [(int) $postcode_range[0], (int) $postcode_range[1]];
}
$cleanPostcode = strtoupper(preg_replace("/\s+/", "", $postcode)); $cleanPostcode = strtoupper(preg_replace("/\s+/", "", $postcode));
if (!preg_match('/^\d{4}[A-Z]{2}$/', $cleanPostcode)) { if (!preg_match('/^\d{4}[A-Z]{2}$/', $cleanPostcode)) {
@@ -280,81 +357,166 @@ function postcode_in_range($postcode, $start, $end)
$numberPart = (int) substr($cleanPostcode, 0, 4); $numberPart = (int) substr($cleanPostcode, 0, 4);
return $numberPart >= $start && $numberPart <= $end; foreach ($pc_arr as $pc_to_check) {
if ($numberPart >= $pc_to_check[0] && $numberPart <= $pc_to_check[1]) {
return true;
}
}
return false;
} }
function modify_checkout_with_js() function modify_checkout_with_js() {
{ if ( ! is_checkout() || ( is_wc_endpoint_url() && ! is_wc_endpoint_url( 'order-received' ) ) ) {
if (
!is_checkout() ||
(is_wc_endpoint_url() && !is_wc_endpoint_url("order-received"))
) {
return; return;
} }
$woonplaats = $_SESSION["woonplaats"]; $data = get_PPPR_data();
$postcode = $formatted_postcode = preg_replace( if ( empty( $data ) ) {
"/(\d+)([A-Z]+)/", return;
'$1 $2', }
strtoupper($_SESSION["postcode"]),
); $city = esc_js( $data['city'] );
$address = $postcode = esc_js( preg_replace( '/(\d+)([A-Z]+)/', '$1 $2', strtoupper( $data['postcode'])));
$_SESSION["straatnaam"] . " " . strtoupper($_SESSION["huisnummer"]); $address = esc_js( $data['street'] . ' ' . strtoupper( $data['house_number']));
// Output the JavaScript
?> // Enqueue script properly to handle dependencies and nonces
<script type="text/javascript" id="fill_address_fields"> wp_enqueue_script( 'jquery' );
jQuery(document).ready(function($) { wp_localize_script( 'jquery', 'ajax_object', array(
fillCheckoutFields(); 'ajax_url' => admin_url( 'admin-ajax.php' ),
$(document.body).on('updated_checkout', fillCheckoutFields); 'nonce' => wp_create_nonce( 'unset_my_session_nonce' )
) );
echo <<<HTML
<script type="text/javascript" id="set_pppr_fields">
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();
}
}); });
function fillCheckoutFields() { function initPPPRFields() {
if (typeof wp !== 'undefined' && wp.data && wp.data.dispatch) { // Wait for React/WC Blocks to mount
const store = 'wc/store/cart';
wp.data.dispatch(store).setShippingAddress({
first_name: '',
last_name: '',
address_1: '<?php echo esc_js($address); ?>',
address_2: '',
city: '<?php echo esc_js($woonplaats); ?>',
state: '',
postcode: '<?php echo esc_js($postcode); ?>',
country: 'NL',
phone: '',
email: ''
});
//make fields READONLY and ppstcode reset.
setTimeout(() => { setTimeout(() => {
// make prefilled fiields readonly. const addressVal = '{$address}';
$('#shipping-postcode, #shipping-city, #shipping-address_1') const cityVal = '{$city}';
.prop('readonly', true) const postcodeVal = '{$postcode}';
.css('background', '#f9f9f9');
// 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';
// create postcode reset button
const div = document.createElement("div");
const script = document.createElement('script');
div.setAttribute("class", "postcode-reset")
div.innerHTML = ` div.innerHTML = `
<a href="#" class="reset-postcode-show-comfirm" >Reset postcode.</a> <a href="#" class="reset-postcode-show-comfirm" style="font-size:12px; text-decoration:underline; display:block; margin-top:5px;">Reset postcode.</a>
<span class="bevestiging"> Weet je het zeker? <span class="bevestiging" style="display:none; font-size:12px; margin-top:5px;">
<a href="#" class="accept">ja</a>/<a href="#" class="decline">nee</a> Deze handeling leegt ook de winkelwagen. Weet je het zeker?
(Deze handeling leegt de winkelwagen.) <a href="#" class="accept" style="color:red; font-weight:bold;">&nbsp;&nbsp;JA&nbsp;</a>/
<a href="#" class="decline">&nbsp;nee&nbsp;&nbsp;</a>
</span>`; </span>`;
div.style.width = "100%"; cityContainer.parentNode.insertBefore(div, cityContainer.nextSibling);
document.querySelector(".wc-block-components-address-form__city").after(div);
}, 500);
// Event Listeners (using delegation for safety)
div.addEventListener('click', function(e) {
jQuery(document.body).trigger('update_checkout'); e.preventDefault();
} else { if (e.target.classList.contains('reset-postcode-show-comfirm')) {
console.error('WooCommerce Blocks API is niet beschikbaar'); 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
}
// Initialize on load
initPPPRFields();
// Re-apply if checkout updates (e.g. shipping method change)
document.body.addEventListener('updated_checkout', function() {
setTimeout(initPPPRFields, 400);
});
});
</script> </script>
<?php HTML;
} }
function load_assets_reset_postcode_on_checkout() function load_assets_reset_postcode_on_checkout()
@@ -383,17 +545,14 @@ function load_assets_reset_postcode_on_checkout()
} }
} }
function handle_unset_session_fetch() function handle_unset_session_fetch()
{ {
// Verify the nonce for security // Verify the nonce for security
if (!wp_verify_nonce($_POST["nonce"], "reset_postcode_nonce")) { if (!wp_verify_nonce($_POST["nonce"], "reset_postcode_nonce")) {
wp_die("Security check failed."); wp_die("Security check failed.");
} }
unset_pppr_cookie();
// Unset the specific session variable
if (isset($_SESSION["postcode"])) {
$_SESSION = [];
}
// Send a JSON response // Send a JSON response
wp_send_json_success(); wp_send_json_success();