From 51ea37d2ec2f33684c89a2ae41b36bdff2679f79 Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Tue, 10 Mar 2026 23:19:32 +0100 Subject: [PATCH] feat: Implement order submit token handling in ShopBasketController and update views --- .../Controllers/ShopBasketController.php | 71 ++++++++++++++++++- templates/shop-basket/address-form.php | 3 +- templates/shop-basket/summary-view.php | 33 +++++---- templates_user/shop-basket/summary-view.php | 32 +++++---- 4 files changed, 110 insertions(+), 29 deletions(-) diff --git a/autoload/front/Controllers/ShopBasketController.php b/autoload/front/Controllers/ShopBasketController.php index e166c7e..e267d48 100644 --- a/autoload/front/Controllers/ShopBasketController.php +++ b/autoload/front/Controllers/ShopBasketController.php @@ -3,6 +3,9 @@ namespace front\Controllers; class ShopBasketController { + private const ORDER_SUBMIT_TOKEN_SESSION_KEY = 'order-submit-token'; + private const ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY = 'order-submit-last-order-id'; + public static $title = [ 'mainView' => 'Koszyk' ]; @@ -274,6 +277,7 @@ class ShopBasketController } $client = \Shared\Helpers\Helpers::get_session( 'client' ); + $orderSubmitToken = $this->createOrderSubmitToken(); return \Shared\Tpl\Tpl::view( 'shop-basket/summary-view', [ 'lang_id' => $lang_id, @@ -284,12 +288,35 @@ class ShopBasketController 'addresses' => ( new \Domain\Client\ClientRepository( $GLOBALS['mdb'] ) )->clientAddresses( (int)$client['id'] ), 'settings' => $settings, 'coupon' => \Shared\Helpers\Helpers::get_session( 'coupon' ), - 'basket_message' => \Shared\Helpers\Helpers::get_session( 'basket_message' ) + 'basket_message' => \Shared\Helpers\Helpers::get_session( 'basket_message' ), + 'order_submit_token' => $orderSubmitToken ] ); } public function basketSave() { + $orderSubmitToken = (string)\Shared\Helpers\Helpers::get( 'order_submit_token', true ); + $existingOrderId = isset( $_SESSION[ self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY ] ) ? (int)$_SESSION[ self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY ] : 0; + + if ( !$this->isValidOrderSubmitToken( $orderSubmitToken ) ) + { + if ( $existingOrderId > 0 ) + { + $existingOrderHash = $this->orderRepository->findHashById( $existingOrderId ); + if ( $existingOrderHash ) + { + header( 'Location: /zamowienie/' . $existingOrderHash ); + exit; + } + } + + \Shared\Helpers\Helpers::error( \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-zlozone-komunikat-blad' ) ); + header( 'Location: /koszyk' ); + exit; + } + + $this->consumeOrderSubmitToken(); + $client = \Shared\Helpers\Helpers::get_session( 'client' ); if ( \Domain\Basket\BasketCalculator::checkProductQuantityInStock( \Shared\Helpers\Helpers::get_session( 'basket' ) ) ) @@ -322,6 +349,7 @@ class ShopBasketController \Shared\Helpers\Helpers::get_session( 'basket_message' ) ) ) { + \Shared\Helpers\Helpers::set_session( self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY, (int)$order_id ); \Shared\Helpers\Helpers::alert( \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-zlozone-komunikat' ) ); \Shared\Helpers\Helpers::delete_session( 'basket' ); \Shared\Helpers\Helpers::delete_session( 'basket-transport-method-id' ); @@ -414,4 +442,45 @@ class ShopBasketController ] ); exit; } + + private function createOrderSubmitToken() + { + $token = $this->generateOrderSubmitToken(); + \Shared\Helpers\Helpers::set_session( self::ORDER_SUBMIT_TOKEN_SESSION_KEY, $token ); + \Shared\Helpers\Helpers::delete_session( self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY ); + + return $token; + } + + private function generateOrderSubmitToken() + { + try + { + return bin2hex( random_bytes( 16 ) ); + } + catch ( \Exception $exception ) + { + return md5( uniqid( (string)mt_rand(), true ) ); + } + } + + private function isValidOrderSubmitToken( $token ) + { + if ( !$token ) + return false; + + $sessionToken = isset( $_SESSION[ self::ORDER_SUBMIT_TOKEN_SESSION_KEY ] ) ? (string)$_SESSION[ self::ORDER_SUBMIT_TOKEN_SESSION_KEY ] : ''; + if ( !$sessionToken ) + return false; + + if ( function_exists( 'hash_equals' ) ) + return hash_equals( $sessionToken, $token ); + + return $sessionToken === $token; + } + + private function consumeOrderSubmitToken() + { + \Shared\Helpers\Helpers::delete_session( self::ORDER_SUBMIT_TOKEN_SESSION_KEY ); + } } diff --git a/templates/shop-basket/address-form.php b/templates/shop-basket/address-form.php index 098efc1..1dac889 100644 --- a/templates/shop-basket/address-form.php +++ b/templates/shop-basket/address-form.php @@ -34,6 +34,7 @@ client ):?>
+ client ):?>
@@ -198,4 +199,4 @@ $( '#address-' + address_id ).addClass( 'active' ); }); }); - \ No newline at end of file + diff --git a/templates/shop-basket/summary-view.php b/templates/shop-basket/summary-view.php index 61305a8..1a88680 100644 --- a/templates/shop-basket/summary-view.php +++ b/templates/shop-basket/summary-view.php @@ -140,14 +140,16 @@
$this -> transport + 'transport_method' => $this -> transport, + 'order_submit_token' => $this -> order_submit_token ] );?>
$this -> client, 'addresses' => $this -> addresses, - 'transport_method' => $this -> transport + 'transport_method' => $this -> transport, + 'order_submit_token' => $this -> order_submit_token ] );?>
@@ -156,17 +158,20 @@
\ No newline at end of file + diff --git a/templates_user/shop-basket/summary-view.php b/templates_user/shop-basket/summary-view.php index 8ac63b3..8386881 100644 --- a/templates_user/shop-basket/summary-view.php +++ b/templates_user/shop-basket/summary-view.php @@ -134,14 +134,16 @@
$this -> transport + 'transport_method' => $this -> transport, + 'order_submit_token' => $this -> order_submit_token ] );?>
$this -> client, 'addresses' => $this -> addresses, - 'transport_method' => $this -> transport + 'transport_method' => $this -> transport, + 'order_submit_token' => $this -> order_submit_token ] );?> @@ -150,18 +152,22 @@