-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Meta Checkout URL Implementation #39667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 2.4-develop
Are you sure you want to change the base?
Changes from 3 commits
a04c158
c345b33
87aa6ac
f26b9c4
4402ca3
f372039
10e504e
178fa97
580b049
63484c2
292df77
6b93084
e9e5641
f60700d
a3eec99
b793d68
704908d
cbe8c02
38c6902
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
namespace Magento\Checkout\Controller\Cart; | ||
|
||
use Magento\Framework\App\Action\HttpGetActionInterface; | ||
use Magento\Framework\App\RequestInterface; | ||
use Magento\Checkout\Model\Session as CheckoutSession; | ||
use Magento\Catalog\Api\ProductRepositoryInterface; | ||
use Magento\Framework\Exception\NoSuchEntityException; | ||
use Magento\Framework\Controller\Result\RedirectFactory; | ||
use Magento\Framework\View\Result\PageFactory; | ||
use Magento\Checkout\Model\Cart; | ||
use Magento\SalesRule\Model\CouponFactory; | ||
use Magento\SalesRule\Model\ResourceModel\Coupon\Usage; | ||
use Magento\Framework\Message\ManagerInterface; | ||
use Magento\Framework\App\ActionInterface; | ||
use Magento\Framework\App\Action\Context; | ||
|
||
/** | ||
* Controller for Meta Checkout URL implementation | ||
*/ | ||
class AddToCartLinkV1 implements HttpGetActionInterface, ActionInterface | ||
{ | ||
/** | ||
* @var RequestInterface | ||
*/ | ||
private $request; | ||
|
||
/** | ||
* @var CheckoutSession | ||
*/ | ||
private $checkoutSession; | ||
|
||
/** | ||
* @var ProductRepositoryInterface | ||
*/ | ||
private $productRepository; | ||
|
||
/** | ||
* @var Cart | ||
*/ | ||
private $cart; | ||
|
||
/** | ||
* @var PageFactory | ||
*/ | ||
private $resultPageFactory; | ||
|
||
/** | ||
* @var RedirectFactory | ||
*/ | ||
private $resultRedirectFactory; | ||
|
||
/** | ||
* @var CouponFactory | ||
*/ | ||
private $couponFactory; | ||
|
||
/** | ||
* @var Usage | ||
*/ | ||
private $couponUsage; | ||
|
||
/** | ||
* @var ManagerInterface | ||
*/ | ||
private $messageManager; | ||
|
||
/** | ||
* @param Context $context | ||
* @param CheckoutSession $checkoutSession | ||
* @param ProductRepositoryInterface $productRepository | ||
* @param Cart $cart | ||
* @param PageFactory $resultPageFactory | ||
* @param RedirectFactory $resultRedirectFactory | ||
* @param CouponFactory $couponFactory | ||
* @param Usage $couponUsage | ||
* @param ManagerInterface $messageManager | ||
*/ | ||
public function __construct( | ||
Context $context, | ||
CheckoutSession $checkoutSession, | ||
ProductRepositoryInterface $productRepository, | ||
Cart $cart, | ||
PageFactory $resultPageFactory, | ||
RedirectFactory $resultRedirectFactory, | ||
CouponFactory $couponFactory, | ||
Usage $couponUsage, | ||
ManagerInterface $messageManager | ||
) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
$this->request = $context->getRequest(); | ||
$this->checkoutSession = $checkoutSession; | ||
$this->productRepository = $productRepository; | ||
$this->cart = $cart; | ||
$this->resultPageFactory = $resultPageFactory; | ||
$this->resultRedirectFactory = $resultRedirectFactory; | ||
$this->couponFactory = $couponFactory; | ||
$this->couponUsage = $couponUsage; | ||
$this->messageManager = $messageManager; | ||
} | ||
|
||
/** | ||
* Execute action based on request and return result | ||
* | ||
* @return \Magento\Framework\Controller\ResultInterface | ||
*/ | ||
public function execute() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a return type declaration. |
||
{ | ||
// Get products parameter | ||
$productsParam = $this->request->getParam('products', ''); | ||
$couponCode = $this->request->getParam('coupon', ''); | ||
|
||
// Clear the cart first (required by Meta spec) | ||
$this->cart->truncate(); | ||
|
||
// Parse products parameter | ||
if (!empty($productsParam)) { | ||
$productItems = $this->parseProductsParam($productsParam); | ||
|
||
// Add products to cart | ||
foreach ($productItems as $item) { | ||
try { | ||
$productId = $item['product_id']; | ||
$qty = $item['qty']; | ||
|
||
$product = $this->productRepository->getById($productId); | ||
$this->cart->addProduct($product, ['qty' => $qty]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess we can pass |
||
} catch (NoSuchEntityException $e) { | ||
// Product not found, continue with next item | ||
$this->messageManager->addErrorMessage( | ||
__('Product with ID "%1" was not found.', $productId) | ||
); | ||
continue; | ||
} catch (\Exception $e) { | ||
// Other exceptions, continue with next item | ||
$this->messageManager->addErrorMessage($e->getMessage()); | ||
continue; | ||
} | ||
} | ||
|
||
// Save cart | ||
$this->cart->save(); | ||
} | ||
|
||
// Apply coupon code if provided | ||
if (!empty($couponCode)) { | ||
try { | ||
$this->cart->getQuote()->setCouponCode($couponCode); | ||
$this->cart->save(); | ||
|
||
// Check if coupon was actually applied | ||
if ($this->cart->getQuote()->getCouponCode() !== $couponCode) { | ||
$this->messageManager->addErrorMessage( | ||
__('The coupon code "%1" is not valid.', $couponCode) | ||
); | ||
} | ||
} catch (\Exception $e) { | ||
$this->messageManager->addErrorMessage( | ||
__('The coupon code "%1" is not valid: %2', $couponCode, $e->getMessage()) | ||
); | ||
} | ||
} | ||
|
||
// Render the checkout page directly (not a redirect) | ||
// This ensures the URL parameters remain in the browser address bar | ||
return $this->resultPageFactory->create(); | ||
} | ||
|
||
/** | ||
* Parse the products parameter from the URL | ||
* Format: product_id:qty,product_id:qty | ||
* | ||
* @param string $productsParam | ||
* @return array | ||
*/ | ||
private function parseProductsParam($productsParam) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a return type declaration and also add a parameter type declaration. |
||
{ | ||
$result = []; | ||
$productPairs = explode(',', $productsParam); | ||
|
||
foreach ($productPairs as $pair) { | ||
$parts = explode(':', $pair); | ||
if (count($parts) === 2) { | ||
$result[] = [ | ||
'product_id' => $parts[0], | ||
'qty' => (int)$parts[1] | ||
]; | ||
} | ||
} | ||
|
||
return $result; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?xml version="1.0"?> | ||
<!-- | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
--> | ||
<?xml version="1.0"?> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can remove this redundant statement |
||
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> | ||
<update handle="checkout_cart_index"/> | ||
</page> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the redundant implementation of
ActionInterface
. It is already implemented by HttpGetActionInterface.