Skip to content

Commit 8df880c

Browse files
sol-loupjczhuoMeta
andauthored
Checkout URLs are now persistent between page refresh (#837)
* Checkout URLs are now persistent between page refresh * Adding fallback logic for SKU => NUMID * Fixing lint issues * Final lint fixes --------- Co-authored-by: jczhuoMeta <[email protected]>
1 parent 9aa1655 commit 8df880c

File tree

1 file changed

+106
-93
lines changed
  • app/code/Meta/Sales/Controller/Checkout

1 file changed

+106
-93
lines changed

app/code/Meta/Sales/Controller/Checkout/Index.php

Lines changed: 106 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@
2323
use Magento\Checkout\Model\Session as CheckoutSession;
2424
use Magento\Framework\App\Action\HttpGetActionInterface;
2525
use Magento\Framework\App\Request\Http;
26-
use Magento\Framework\Controller\Result\Redirect;
27-
use Magento\Framework\Controller\Result\RedirectFactory;
26+
use Magento\Framework\View\Result\PageFactory;
2827
use Magento\Framework\Exception\CouldNotSaveException;
29-
use Magento\Framework\Exception\LocalizedException;
3028
use Magento\Quote\Api\CartRepositoryInterface;
3129
use Magento\Quote\Api\Data\CartItemInterfaceFactory;
3230
use Magento\Quote\Model\GuestCart\GuestCartItemRepository;
@@ -40,15 +38,18 @@
4038
use Magento\ConfigurableProduct\Model\Product\Type\Configurable as ConfigurableType;
4139
use Magento\Quote\Api\Data\ProductOptionInterfaceFactory;
4240
use Magento\ConfigurableProduct\Api\Data\ConfigurableItemOptionValueInterfaceFactory;
43-
use Meta\BusinessExtension\Model\Api\CustomApiKey\Authenticator;
4441
use Meta\BusinessExtension\Helper\FBEHelper;
4542
use Meta\Sales\Helper\OrderHelper;
4643
use Exception;
4744

4845
/**
46+
* Handles the Meta Checkout URL endpoint.
47+
* Creates a quote, adds products, applies coupons, and redirects to checkout.
48+
*
4949
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
5050
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
5151
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
52+
* @SuppressWarnings(PHPMD.TooManyFields)
5253
*/
5354
class Index implements HttpGetActionInterface
5455
{
@@ -71,7 +72,6 @@ class Index implements HttpGetActionInterface
7172
* @var CartRepositoryInterface
7273
*/
7374
private CartRepositoryInterface $quoteRepository;
74-
7575
/**
7676
* @var GuestCartItemRepository
7777
*/
@@ -98,9 +98,9 @@ class Index implements HttpGetActionInterface
9898
private Http $httpRequest;
9999

100100
/**
101-
* @var RedirectFactory
101+
* @var PageFactory
102102
*/
103-
private RedirectFactory $resultRedirectFactory;
103+
private PageFactory $resultPageFactory;
104104

105105
/**
106106
* @var FBEHelper
@@ -133,40 +133,40 @@ class Index implements HttpGetActionInterface
133133
private ConfigurableItemOptionValueInterfaceFactory $configurableItemOptionValueFactory;
134134

135135
/**
136-
* @param QuoteFactory $quoteFactory
137-
* @param QuoteIdMaskFactory $quoteIdMaskFactory
138-
* @param AddressFactory $quoteAddressFactory
139-
* @param CartRepositoryInterface $quoteRepository
140-
* @param GuestCartItemRepository $guestCartItemRepository
141-
* @param CartItemInterfaceFactory $cartItemInterfaceFactory
142-
* @param GuestCouponManagement $guestCouponManagement
143-
* @param CheckoutSession $checkoutSession
144-
* @param Http $httpRequest
145-
* @param RedirectFactory $resultRedirectFactory
146-
* @param Authenticator $authenticator
147-
* @param FBEHelper $fbeHelper
148-
* @param OrderHelper $orderHelper
149-
* @param ProductRepositoryInterface $productRepository
150-
* @param ConfigurableType $configurableType
151-
* @param ProductOptionInterfaceFactory $productOptionInterfaceFactory
136+
* Constructor
137+
*
138+
* @param QuoteFactory $quoteFactory
139+
* @param QuoteIdMaskFactory $quoteIdMaskFactory
140+
* @param AddressFactory $quoteAddressFactory
141+
* @param CartRepositoryInterface $quoteRepository
142+
* @param GuestCartItemRepository $guestCartItemRepository
143+
* @param CartItemInterfaceFactory $cartItemInterfaceFactory
144+
* @param GuestCouponManagement $guestCouponManagement
145+
* @param CheckoutSession $checkoutSession
146+
* @param Http $httpRequest
147+
* @param PageFactory $resultPageFactory
148+
* @param FBEHelper $fbeHelper
149+
* @param OrderHelper $orderHelper
150+
* @param ProductRepositoryInterface $productRepository
151+
* @param ConfigurableType $configurableType
152+
* @param ProductOptionInterfaceFactory $productOptionInterfaceFactory
152153
* @param ConfigurableItemOptionValueInterfaceFactory $configurableItemOptionValueFactory
153154
*/
154155
public function __construct(
155-
QuoteFactory $quoteFactory,
156-
QuoteIdMaskFactory $quoteIdMaskFactory,
157-
AddressFactory $quoteAddressFactory,
158-
CartRepositoryInterface $quoteRepository,
159-
GuestCartItemRepository $guestCartItemRepository,
156+
QuoteFactory $quoteFactory,
157+
QuoteIdMaskFactory $quoteIdMaskFactory,
158+
AddressFactory $quoteAddressFactory,
159+
CartRepositoryInterface $quoteRepository,
160+
GuestCartItemRepository $guestCartItemRepository,
160161
CartItemInterfaceFactory $cartItemInterfaceFactory,
161-
GuestCouponManagement $guestCouponManagement,
162-
CheckoutSession $checkoutSession,
163-
Http $httpRequest,
164-
RedirectFactory $resultRedirectFactory,
165-
Authenticator $authenticator,
166-
FBEHelper $fbeHelper,
167-
OrderHelper $orderHelper,
162+
GuestCouponManagement $guestCouponManagement,
163+
CheckoutSession $checkoutSession,
164+
Http $httpRequest,
165+
PageFactory $resultPageFactory,
166+
FBEHelper $fbeHelper,
167+
OrderHelper $orderHelper,
168168
ProductRepositoryInterface $productRepository,
169-
ConfigurableType $configurableType,
169+
ConfigurableType $configurableType,
170170
ProductOptionInterfaceFactory $productOptionInterfaceFactory,
171171
ConfigurableItemOptionValueInterfaceFactory $configurableItemOptionValueFactory
172172
) {
@@ -179,7 +179,7 @@ public function __construct(
179179
$this->guestCouponManagement = $guestCouponManagement;
180180
$this->checkoutSession = $checkoutSession;
181181
$this->httpRequest = $httpRequest;
182-
$this->resultRedirectFactory = $resultRedirectFactory;
182+
$this->resultPageFactory = $resultPageFactory;
183183
$this->fbeHelper = $fbeHelper;
184184
$this->orderHelper = $orderHelper;
185185
$this->productRepository = $productRepository;
@@ -189,18 +189,18 @@ public function __construct(
189189
}
190190

191191
/**
192-
* Execute action based on request.
192+
* Execute action based on request and return result
193193
*
194-
* @return Redirect
195-
* @throws LocalizedException
194+
* Processes incoming request to create cart with specified products and coupon.
195+
*
196+
* @return \Magento\Framework\Controller\ResultInterface|\Magento\Framework\View\Result\Page
197+
* @throws CouldNotSaveException If quote cannot be created.
196198
*/
197199
public function execute()
198200
{
199201
$ebid = $this->httpRequest->getParam('ebid');
200202
$productsParam = $this->httpRequest->getParam('products');
201203
$coupon = $this->httpRequest->getParam('coupon');
202-
$redirectPath = $this->httpRequest->getParam('redirect');
203-
204204
$storeId = (int)$this->orderHelper->getStoreIdByExternalBusinessId($ebid);
205205
$products = explode(',', $productsParam);
206206

@@ -216,15 +216,19 @@ public function execute()
216216
}
217217

218218
$this->checkoutSession->replaceQuote($quote);
219-
return $this->redirectToPath($redirectPath);
219+
220+
$resultPage = $this->resultPageFactory->create();
221+
$resultPage->addHandle('checkout_index_index');
222+
return $resultPage;
220223
}
221224

222225
/**
223-
* Create a new quote.
226+
* Create a new guest quote for the specified store.
227+
*
228+
* @param int $storeId The store ID for the quote.
224229
*
225-
* @param int $storeId
226-
* @return Quote
227-
* @throws CouldNotSaveException
230+
* @return Quote The created quote object.
231+
* @throws CouldNotSaveException If the quote cannot be saved.
228232
*/
229233
private function createQuote(int $storeId): Quote
230234
{
@@ -244,10 +248,11 @@ private function createQuote(int $storeId): Quote
244248
}
245249

246250
/**
247-
* Get masked cart ID.
251+
* Get the masked (hashed) ID for a given quote.
252+
*
253+
* @param Quote $quote The quote object.
248254
*
249-
* @param Quote $quote
250-
* @return string
255+
* @return string The masked quote ID.
251256
*/
252257
private function getMaskedCartId(Quote $quote): string
253258
{
@@ -257,25 +262,32 @@ private function getMaskedCartId(Quote $quote): string
257262
}
258263

259264
/**
260-
* Add product to cart.
265+
* Add a product item to the guest cart.
266+
*
267+
* Handles simple and configurable products.
268+
*
269+
* @param string $productItem The product string in "sku:qty" format.
270+
* @param string $cartId The masked cart ID.
271+
* @param int $storeId The store ID.
261272
*
262-
* @param string $productItem
263-
* @param string $cartId
264-
* @param int $storeId
265273
* @return void
266274
*/
267275
private function addProductToCart(string $productItem, string $cartId, int $storeId): void
268276
{
269277
try {
270-
[$sku, $quantity] = explode(':', $productItem);
278+
[$sku_or_id, $quantity] = explode(':', $productItem);
271279
$quantity = (int)$quantity;
280+
try {
281+
$product = $this->productRepository->get($sku_or_id, false, $storeId, true);
282+
} catch (Exception $e) {
283+
$product = $this->productRepository->getById($sku_or_id);
284+
}
272285

273-
$product = $this->productRepository->get($sku, false, $storeId, true);
274-
275-
[$parentSku, $configurableOptions] = $this->getConfigurableOptions($product, $storeId);
286+
[$parentSku, $configurableOptions]
287+
= $this->getConfigurableOptions($product, $storeId);
276288

277289
$cartItem = $this->cartItemInterfaceFactory->create();
278-
$cartItem->setSku($sku);
290+
$cartItem->setSku($product->getSku());
279291
$cartItem->setQty($quantity);
280292
$cartItem->setQuoteId($cartId);
281293

@@ -290,53 +302,53 @@ private function addProductToCart(string $productItem, string $cartId, int $stor
290302

291303
$this->guestCartItemRepository->save($cartItem);
292304
} catch (Exception $e) {
293-
$this->logExceptionToMeta($e, $storeId, 'error_adding_item', [
294-
'cart_id' => $cartId,
295-
'sku' => $sku,
296-
'quantity' => $quantity,
297-
]);
305+
$this->logExceptionToMeta(
306+
$e,
307+
$storeId,
308+
'error_adding_item',
309+
[
310+
'cart_id' => $cartId,
311+
// can't always rely on sku_or_id being present, as it resides in the catch block
312+
'sku' => $productItem,
313+
'quantity' => $quantity,
314+
]
315+
);
298316
}
299317
}
300318

301319
/**
302-
* Apply coupon to cart.
320+
* Apply a coupon code to the guest cart.
321+
*
322+
* @param string $coupon The coupon code.
323+
* @param string $cartId The masked cart ID.
324+
* @param int $storeId The store ID.
303325
*
304-
* @param string $coupon
305-
* @param string $cartId
306-
* @param int $storeId
307326
* @return void
308327
*/
309328
private function applyCouponToCart(string $coupon, string $cartId, int $storeId): void
310329
{
311330
try {
312331
$this->guestCouponManagement->set($cartId, $coupon);
313332
} catch (Exception $e) {
314-
$this->logExceptionToMeta($e, $storeId, 'error_adding_coupon', [
315-
'cart_id' => $cartId,
316-
'coupon' => $coupon,
317-
]);
333+
$this->logExceptionToMeta(
334+
$e,
335+
$storeId,
336+
'error_adding_coupon',
337+
[
338+
'cart_id' => $cartId,
339+
'coupon' => $coupon,
340+
]
341+
);
318342
}
319343
}
320344

321345
/**
322-
* Redirect to path.
346+
* Get configurable product options if the product is a child of a configurable product.
323347
*
324-
* @param string|null $redirectPath
325-
* @return Redirect
326-
*/
327-
private function redirectToPath(?string $redirectPath): Redirect
328-
{
329-
$resultRedirect = $this->resultRedirectFactory->create();
330-
$resultRedirect->setPath($redirectPath ?: 'checkout');
331-
return $resultRedirect;
332-
}
333-
334-
/**
335-
* Get configurable options for a product.
348+
* @param ProductInterface $product The product object.
349+
* @param int $storeId The store ID.
336350
*
337-
* @param ProductInterface $product
338-
* @param int $storeId
339-
* @return array
351+
* @return array The parent SKU (if applicable) and configurable options.
340352
*/
341353
private function getConfigurableOptions(ProductInterface $product, int $storeId): array
342354
{
@@ -369,12 +381,13 @@ private function getConfigurableOptions(ProductInterface $product, int $storeId)
369381
}
370382

371383
/**
372-
* Log exception to Meta.
384+
* Log an exception to Meta using the FBEHelper.
385+
*
386+
* @param Exception $e The exception to log.
387+
* @param int $storeId The store ID associated with the exception.
388+
* @param string $eventType Where the exception occurred.
389+
* @param array $extraData Additional data to include in the log entry.
373390
*
374-
* @param Exception $e
375-
* @param int $storeId
376-
* @param string $eventType
377-
* @param array $extraData
378391
* @return void
379392
*/
380393
private function logExceptionToMeta(Exception $e, int $storeId, string $eventType, array $extraData = []): void

0 commit comments

Comments
 (0)