'Koszyk' ]; private $orderRepository; private $paymentMethodRepository; public function __construct( \Domain\Order\OrderRepository $orderRepository, \Domain\PaymentMethod\PaymentMethodRepository $paymentMethodRepository ) { $this->orderRepository = $orderRepository; $this->paymentMethodRepository = $paymentMethodRepository; } public function basketMessageSave() { \Shared\Helpers\Helpers::set_session( 'basket_message', \Shared\Helpers\Helpers::get( 'basket_message' ) ); echo json_encode( [ 'result' => 'ok' ] ); exit; } public function basketRemoveProduct() { global $lang_id; $basket = \Shared\Helpers\Helpers::get_session( 'basket' ); $coupon = \Shared\Helpers\Helpers::get_session( 'coupon' ); $product_hash = \Shared\Helpers\Helpers::get( 'product_hash' ); $basket_transport_method_id = \Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ); unset( $basket[ $product_hash ] ); $basket = (new \Domain\Promotion\PromotionRepository($GLOBALS['mdb']))->findPromotion( $basket ); \Shared\Helpers\Helpers::set_session( 'basket', $basket ); $this->jsonBasketResponse( $basket, $coupon, $lang_id, $basket_transport_method_id ); } public function basketIncreaseQuantityProduct() { global $lang_id; $basket = \Shared\Helpers\Helpers::get_session( 'basket' ); $coupon = \Shared\Helpers\Helpers::get_session( 'coupon' ); $product_hash = \Shared\Helpers\Helpers::get( 'product_hash' ); $basket_transport_method_id = \Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ); $basket[ $product_hash ][ 'quantity' ]++; \Domain\Basket\BasketCalculator::checkProductQuantityInStock( $basket, false ); $basket = \Shared\Helpers\Helpers::get_session( 'basket' ); $basket = (new \Domain\Promotion\PromotionRepository($GLOBALS['mdb']))->findPromotion( $basket ); \Shared\Helpers\Helpers::set_session( 'basket', $basket ); $this->jsonBasketResponse( $basket, $coupon, $lang_id, $basket_transport_method_id ); } public function basketDecreaseQuantityProduct() { global $lang_id; $basket = \Shared\Helpers\Helpers::get_session( 'basket' ); $coupon = \Shared\Helpers\Helpers::get_session( 'coupon' ); $product_hash = \Shared\Helpers\Helpers::get( 'product_hash' ); $basket_transport_method_id = \Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ); $basket[ $product_hash ][ 'quantity' ]--; if ( $basket[ $product_hash ][ 'quantity' ] < 1 ) unset( $basket[ $product_hash ] ); $basket = (new \Domain\Promotion\PromotionRepository($GLOBALS['mdb']))->findPromotion( $basket ); \Shared\Helpers\Helpers::set_session( 'basket', $basket ); $this->jsonBasketResponse( $basket, $coupon, $lang_id, $basket_transport_method_id ); } public function basketChangeQuantityProduct() { global $lang_id; $basket = \Shared\Helpers\Helpers::get_session( 'basket' ); $coupon = \Shared\Helpers\Helpers::get_session( 'coupon' ); $product_hash = \Shared\Helpers\Helpers::get( 'product_hash' ); $basket_transport_method_id = \Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ); $basket[ $product_hash ][ 'quantity' ] = (int)\Shared\Helpers\Helpers::get( 'quantity' ); if ( $basket[ $product_hash ][ 'quantity' ] < 1 ) unset( $basket[ $product_hash ] ); $basket = (new \Domain\Promotion\PromotionRepository($GLOBALS['mdb']))->findPromotion( $basket ); \Domain\Basket\BasketCalculator::checkProductQuantityInStock( $basket, false ); $basket = \Shared\Helpers\Helpers::get_session( 'basket' ); $this->jsonBasketResponse( $basket, $coupon, $lang_id, $basket_transport_method_id ); } public function productMessageChange() { $basket = \Shared\Helpers\Helpers::get_session( 'basket' ); $basket[ \Shared\Helpers\Helpers::get( 'position_code' ) ]['message'] = \Shared\Helpers\Helpers::get( 'product_message' ); \Shared\Helpers\Helpers::set_session( 'basket', $basket ); exit; } public function basketAddProduct() { global $lang_id; $basket = \Domain\Basket\BasketCalculator::validateBasket( \Shared\Helpers\Helpers::get_session( 'basket' ) ); $values_tmp = json_decode( \Shared\Helpers\Helpers::get( 'values' ), true ); $values = []; $attributes = []; $custom_fields = []; foreach( $values_tmp as $key => $val ) $values[ $val['name'] ] = $val['value']; foreach( $values as $key => $val ) { if ( $key != 'product-id' and $key != 'quantity' and $key != 'product-message' and strpos( $key, 'custom_field' ) === false ) $attributes[] = $val; } // Sort by attribute ID to match permutation_hash order (generated with ksort) usort( $attributes, function ( $a, $b ) { return (int) explode( '-', $a )[0] - (int) explode( '-', $b )[0]; } ); foreach( $values as $key => $val ) { if ( strpos( $key, 'custom_field' ) !== false ) { preg_match( '/\d+/', $key, $matches ); $custom_field_id = $matches[0]; $custom_fields[ $custom_field_id ] = $val; } } if ( \Shared\Helpers\Helpers::is_array_fix( $attributes ) ) { $values['parent_id'] = $values[ 'product-id' ]; $values['product-id'] = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->getProductIdByAttributes( $values[ 'product-id' ], $attributes ); $values['attributes'] = $attributes; } $values['wp'] = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->getWeightCached( (int)$values[ 'product-id' ] ); $attributes_implode = ''; if ( is_array( $attributes ) and count( $attributes ) > 0 ) $attributes_implode = implode( '|', $attributes ); $product_code = md5( $values['product-id'] . $attributes_implode . $values['product-message'] . json_encode( $custom_fields ) ); if ( isset( $basket[ $product_code ] ) ) $basket[ $product_code ][ 'quantity' ] += $values[ 'quantity' ]; else $basket[ $product_code ] = $values; $basket[ $product_code ]['message'] = $values['product-message']; $basket[ $product_code ]['custom_fields'] = $custom_fields; $basket = (new \Domain\Promotion\PromotionRepository($GLOBALS['mdb']))->findPromotion( $basket ); \Shared\Helpers\Helpers::set_session( 'basket', $basket ); $coupon = \Shared\Helpers\Helpers::get_session( 'coupon' ); echo json_encode( [ 'result' => 'ok', 'basket_mini_count' => \Domain\Basket\BasketCalculator::countProductsText( \Domain\Basket\BasketCalculator::countProducts( $basket ) ), 'basket_mini_value' => \Domain\Basket\BasketCalculator::summaryPrice( $basket, $coupon, $lang_id ), 'product_sets' => ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->productSetsWhenAddToBasket( (int)$values['product-id'] ) ] ); exit; } public function transportMethodInpostCheck() { $transport_id = \Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ); if ( $transport_id === '2' or $transport_id === '1' ) { if ( !\Shared\Helpers\Helpers::get_session( 'basket-inpost-info' ) ) { echo json_encode( [ 'result' => 'bad' ] ); exit; } } if ( $transport_id === '9' ) { if ( !\Shared\Helpers\Helpers::get_session( 'basket_orlen_point_id' ) ) { echo json_encode( [ 'result' => 'bad' ] ); exit; } } echo json_encode( [ 'result' => 'ok' ] ); exit; } public function inpostCheck() { if ( !\Shared\Helpers\Helpers::get_session( 'basket-inpost-info' ) ) echo json_encode( [ 'result' => 'bad' ] ); else echo json_encode( [ 'result' => 'ok' ] ); exit; } public function orlenSave() { \Shared\Helpers\Helpers::set_session( 'basket_orlen_point_id', \Shared\Helpers\Helpers::get( 'orlen_point_id' ) ); \Shared\Helpers\Helpers::set_session( 'basket_orlen_point_info', \Shared\Helpers\Helpers::get( 'orlen_point_name' ) ); echo json_encode( [ 'result' => 'ok' ] ); exit; } public function inpostSave() { \Shared\Helpers\Helpers::set_session( 'basket-inpost-info', \Shared\Helpers\Helpers::get( 'paczkomat' ) ); echo json_encode( [ 'result' => 'ok' ] ); exit; } public function basketPaymentMethodSet() { \Shared\Helpers\Helpers::set_session( 'basket-payment-method-id', \Shared\Helpers\Helpers::get( 'payment_method_id' ) ); echo json_encode( [ 'result' => 'ok' ] ); exit; } public function basketTransportMethodSet() { \Shared\Helpers\Helpers::set_session( 'basket-transport-method-id', \Shared\Helpers\Helpers::get( 'transport_method_id' ) ); echo json_encode( [ 'result' => 'ok' ] ); exit; } public function basketPaymentsMethods() { \Shared\Helpers\Helpers::set_session( 'basket-transport-method-id', \Shared\Helpers\Helpers::get( 'transport_method_id' ) ); echo json_encode( [ 'result' => 'ok', 'payment_methods' => \front\Views\ShopPaymentMethod::basketPaymentMethods( $this->paymentMethodRepository->paymentMethodsByTransport( (int)\Shared\Helpers\Helpers::get( 'transport_method_id' ) ), \Shared\Helpers\Helpers::get( 'payment_method_id' ) ) ] ); exit; } public function summaryView() { global $lang_id, $settings; if ( \Domain\Basket\BasketCalculator::checkProductQuantityInStock( \Shared\Helpers\Helpers::get_session( 'basket' ) ) ) { header( 'Location: /koszyk' ); exit; } $client = \Shared\Helpers\Helpers::get_session( 'client' ); $orderSubmitToken = $this->createOrderSubmitToken(); return \Shared\Tpl\Tpl::view( 'shop-basket/summary-view', [ 'lang_id' => $lang_id, 'client' => \Shared\Helpers\Helpers::get_session( 'client' ), 'basket' => \Shared\Helpers\Helpers::get_session( 'basket' ), 'transport' => ( new \Domain\Transport\TransportRepository( $GLOBALS['mdb'] ) )->findActiveByIdCached( \Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ) ), 'payment_method' => $this->paymentMethodRepository->paymentMethodCached( (int)\Shared\Helpers\Helpers::get_session( 'basket-payment-method-id' ) ), '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' ), 'order_submit_token' => $orderSubmitToken ] ); } public function basketSave() { $basket = \Shared\Helpers\Helpers::get_session( 'basket' ); $existingOrderId = isset( $_SESSION[ self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY ] ) ? (int)$_SESSION[ self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY ] : 0; if ( ( !is_array( $basket ) || empty( $basket ) ) && $existingOrderId > 0 ) { $existingOrderHash = $this->orderRepository->findHashById( $existingOrderId ); if ( $existingOrderHash ) { $this->logOrder( 'Double-submit detected, redirecting to existing order id=' . $existingOrderId ); header( 'Location: /zamowienie/' . $existingOrderHash ); exit; } } $orderSubmitToken = (string)\Shared\Helpers\Helpers::get( 'order_submit_token', true ); if ( !$this->isValidOrderSubmitToken( $orderSubmitToken ) ) { $this->logOrder( 'Token validation failed. formToken=' . ($orderSubmitToken ?: '(empty)') ); \Shared\Helpers\Helpers::error( \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-zlozone-komunikat-blad' ) ); header( 'Location: /koszyk-podsumowanie' ); exit; } $this->consumeOrderSubmitToken(); $client = \Shared\Helpers\Helpers::get_session( 'client' ); if ( \Domain\Basket\BasketCalculator::checkProductQuantityInStock( \Shared\Helpers\Helpers::get_session( 'basket' ) ) ) { header( 'Location: /koszyk' ); exit; } $order_id = null; try { $order_id = $this->orderRepository->createFromBasket( $client[ 'id' ], \Shared\Helpers\Helpers::get_session( 'basket' ), \Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ), \Shared\Helpers\Helpers::get_session( 'basket-payment-method-id' ), \Shared\Helpers\Helpers::get( 'email', true ), \Shared\Helpers\Helpers::get( 'phone', true ), \Shared\Helpers\Helpers::get( 'name', true ), \Shared\Helpers\Helpers::get( 'surname', true ), \Shared\Helpers\Helpers::get( 'street' ), \Shared\Helpers\Helpers::get( 'postal_code', true ), \Shared\Helpers\Helpers::get( 'city', true ), \Shared\Helpers\Helpers::get( 'firm_name', true ), \Shared\Helpers\Helpers::get( 'firm_street', true ), \Shared\Helpers\Helpers::get( 'firm_postal_code', true ), \Shared\Helpers\Helpers::get( 'firm_city', true ), \Shared\Helpers\Helpers::get( 'firm_nip', true ), \Shared\Helpers\Helpers::get_session( 'basket-inpost-info' ), \Shared\Helpers\Helpers::get_session( 'basket_orlen_point_id' ), \Shared\Helpers\Helpers::get_session( 'basket_orlen_point_info' ), \Shared\Helpers\Helpers::get_session( 'coupon' ), \Shared\Helpers\Helpers::get_session( 'basket_message' ) ); } catch ( \Exception $e ) { $this->logOrder( 'createFromBasket exception: ' . $e->getMessage() ); \Shared\Helpers\Helpers::error( \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-zlozone-komunikat-blad' ) ); header( 'Location: /koszyk' ); exit; } if ( $order_id ) { \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' ); \Shared\Helpers\Helpers::delete_session( 'basket-payment-method-id' ); \Shared\Helpers\Helpers::delete_session( 'basket-inpost-info' ); \Shared\Helpers\Helpers::delete_session( 'basket_orlen_point_id' ); \Shared\Helpers\Helpers::delete_session( 'basket_orlen_point_info' ); \Shared\Helpers\Helpers::delete_session( 'coupon' ); \Shared\Helpers\Helpers::delete_session( 'basket_message' ); \Shared\Helpers\Helpers::set_session( 'piksel_purchase', true ); \Shared\Helpers\Helpers::set_session( 'google-adwords-purchase', true ); \Shared\Helpers\Helpers::set_session( 'google-analytics-purchase', true ); \Shared\Helpers\Helpers::set_session( 'ekomi-purchase', true ); $redis = \Shared\Cache\RedisConnection::getInstance() -> getConnection(); if ( $redis ) $redis -> flushAll(); header( 'Location: /zamowienie/' . $this->orderRepository->findHashById( $order_id ) ); exit; } else { $this->logOrder( 'createFromBasket returned falsy order_id. client_id=' . ($client['id'] ?? 'guest') . ' email=' . \Shared\Helpers\Helpers::get( 'email', true ) ); \Shared\Helpers\Helpers::error( \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-zlozone-komunikat-blad' ) ); header( 'Location: /koszyk' ); exit; } } public function mainView() { global $lang_id, $page, $settings; $page[ 'language' ][ 'meta_title' ] = 'Koszyk'; $basket = \Shared\Helpers\Helpers::get_session( 'basket' ); $coupon = \Shared\Helpers\Helpers::get_session( 'coupon' ); $payment_method_id = \Shared\Helpers\Helpers::get_session( 'payment_method_id' ); $basket_transport_method_id = \Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ); if ( \Domain\Basket\BasketCalculator::checkProductQuantityInStock( $basket ) ) { header( 'Location: /koszyk' ); exit; } $basket = (new \Domain\Promotion\PromotionRepository($GLOBALS['mdb']))->findPromotion( $basket ); return \Shared\Tpl\Tpl::view( 'shop-basket/basket', [ 'basket' => $basket, 'coupon' => $coupon, 'transport_id' => \Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ), 'transport_methods' => \Shared\Tpl\Tpl::view( 'shop-basket/basket-transport-methods', [ 'transports_methods' => ( new \Domain\Transport\TransportRepository( $GLOBALS['mdb'] ) )->transportMethodsFront( $basket, $coupon ), 'transport_id' => $basket_transport_method_id, 'free_delivery' => (float)($settings['free_delivery'] ?? 0), 'basket_summary' => (float)\Domain\Basket\BasketCalculator::summaryPrice( $basket, $coupon ) ] ), 'payment_method_id' => $payment_method_id, 'basket_details' => \Shared\Tpl\Tpl::view( 'shop-basket/basket-details', [ 'basket' => $basket, 'lang_id' => $lang_id, 'coupon' => $coupon, 'basket_message' => \Shared\Helpers\Helpers::get_session( 'basket_message' ), 'settings' => $settings ] ) ] ); } private function jsonBasketResponse( $basket, $coupon, $lang_id, $basket_transport_method_id ) { global $settings; echo json_encode( [ 'basket' => \Shared\Tpl\Tpl::view( 'shop-basket/basket-details', [ 'basket' => $basket, 'lang_id' => $lang_id, 'coupon' => $coupon ] ), 'basket_mini_count' => \Domain\Basket\BasketCalculator::countProductsText( \Domain\Basket\BasketCalculator::countProducts( $basket ) ), 'basket_mini_value' => \Domain\Basket\BasketCalculator::summaryPrice( $basket, $coupon, $lang_id ), 'products_count' => count( $basket ), 'transport_methods' => \Shared\Tpl\Tpl::view( 'shop-basket/basket-transport-methods', [ 'transports_methods' => ( new \Domain\Transport\TransportRepository( $GLOBALS['mdb'] ) )->transportMethodsFront( $basket, $coupon ), 'transport_id' => $basket_transport_method_id, 'free_delivery' => (float)($settings['free_delivery'] ?? 0), 'basket_summary' => (float)\Domain\Basket\BasketCalculator::summaryPrice( $basket, $coupon ) ] ) ] ); exit; } private function createOrderSubmitToken() { $existingTokenData = isset( $_SESSION[ self::ORDER_SUBMIT_TOKEN_SESSION_KEY ] ) ? $_SESSION[ self::ORDER_SUBMIT_TOKEN_SESSION_KEY ] : null; if ( is_array( $existingTokenData ) && !empty( $existingTokenData['token'] ) && !empty( $existingTokenData['created_at'] ) ) { $age = time() - (int)$existingTokenData['created_at']; if ( $age < self::ORDER_SUBMIT_TOKEN_TTL ) { \Shared\Helpers\Helpers::delete_session( self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY ); return $existingTokenData['token']; } } $token = $this->generateOrderSubmitToken(); \Shared\Helpers\Helpers::set_session( self::ORDER_SUBMIT_TOKEN_SESSION_KEY, [ 'token' => $token, 'created_at' => time() ] ); \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; $tokenData = isset( $_SESSION[ self::ORDER_SUBMIT_TOKEN_SESSION_KEY ] ) ? $_SESSION[ self::ORDER_SUBMIT_TOKEN_SESSION_KEY ] : null; if ( is_string( $tokenData ) ) { $sessionToken = $tokenData; if ( !$sessionToken ) return false; return function_exists( 'hash_equals' ) ? hash_equals( $sessionToken, $token ) : $sessionToken === $token; } if ( !is_array( $tokenData ) || empty( $tokenData['token'] ) || empty( $tokenData['created_at'] ) ) return false; $age = time() - (int)$tokenData['created_at']; if ( $age > self::ORDER_SUBMIT_TOKEN_TTL ) return false; $sessionToken = (string)$tokenData['token']; 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 ); } private function logOrder( $message ) { $logDir = $_SERVER['DOCUMENT_ROOT'] . '/logs'; $logFile = $logDir . '/logs-order-' . date( 'Y-m-d' ) . '.log'; $line = '[' . date( 'Y-m-d H:i:s' ) . '] ' . $message . PHP_EOL; @file_put_contents( $logFile, $line, FILE_APPEND | LOCK_EX ); } }