Skip to content

Commit 140b2ce

Browse files
committed
MAGE-1097: add a plugin to forward insights information
1 parent 77d540c commit 140b2ce

File tree

3 files changed

+200
-0
lines changed

3 files changed

+200
-0
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Plugin;
4+
5+
use Magento\Catalog\Api\ProductRepositoryInterface;
6+
use Magento\Catalog\Model\Product;
7+
use Magento\CatalogInventory\Api\StockRegistryInterface;
8+
use Magento\Checkout\Model\Cart;
9+
use Magento\Checkout\Model\Cart\RequestInfoFilterInterface;
10+
use Magento\Checkout\Model\Session;
11+
use Magento\Framework\DataObject;
12+
use Magento\Framework\Event\ManagerInterface;
13+
use Magento\Framework\Exception\LocalizedException;
14+
use Magento\Framework\Exception\NoSuchEntityException;
15+
use Magento\Store\Model\StoreManagerInterface;
16+
17+
class AddToCartRedirectForInsights
18+
{
19+
/**
20+
* @var RequestInfoFilterInterface
21+
*/
22+
private $requestInfoFilter;
23+
24+
public function __construct(
25+
protected StoreManagerInterface $storeManager,
26+
protected ProductRepositoryInterface $productRepository,
27+
protected Session $checkoutSession,
28+
protected StockRegistryInterface $stockRegistry,
29+
protected ManagerInterface $eventManager,
30+
) {}
31+
32+
/**
33+
* @param Cart $cartModel
34+
* @param int|Product $productInfo
35+
* @param array|int|DataObject|null $requestInfo
36+
*
37+
* @return void
38+
*
39+
* @throws LocalizedException
40+
* @throws NoSuchEntityException
41+
*/
42+
public function beforeAddProduct(Cart $cartModel, int|Product $productInfo, array|int|DataObject $requestInfo = null)
43+
{
44+
// If the request doesn't have any insights info, no need to handle it
45+
if (!isset($requestInfo['referer']) || !isset($requestInfo['queryID']) || !isset($requestInfo['indexName'])) {
46+
return;
47+
}
48+
49+
// Check if the request comes from the PLP handled by InstantSearch
50+
if ($requestInfo['referer'] != 'instantsearch') {
51+
return;
52+
}
53+
54+
$product = $this->getProduct($productInfo);
55+
$productId = $product->getId();
56+
57+
if ($productId) {
58+
$request = $this->getQtyRequest($product, $requestInfo);
59+
60+
try {
61+
$result = $product->getTypeInstance()->prepareForCartAdvanced($request, $product);
62+
} catch (LocalizedException $e) {
63+
$this->checkoutSession->setUseNotice(false);
64+
$result = $e->getMessage();
65+
}
66+
67+
// if the result is a string, this mean that the product can't be added to the cart
68+
// see Magento\Quote\Model\Quote::addProduct()
69+
// Here we need to add the insights information to the redirect
70+
if (is_string($result)) {
71+
$redirectUrl = $product->getUrlModel()->getUrl(
72+
$product,
73+
[
74+
'_query' => [
75+
'objectID' => $product->getId(),
76+
'queryID' => $requestInfo['queryID'],
77+
'indexName' => $requestInfo['indexName']
78+
]
79+
]
80+
);
81+
82+
$this->checkoutSession->setRedirectUrl($redirectUrl);
83+
if ($this->checkoutSession->getUseNotice() === null) {
84+
$this->checkoutSession->setUseNotice(true);
85+
}
86+
throw new LocalizedException(__($result));
87+
}
88+
}
89+
}
90+
91+
/**
92+
* @param $productInfo
93+
*
94+
* @return Product
95+
*
96+
* @throws NoSuchEntityException
97+
* @throws LocalizedException
98+
*/
99+
protected function getProduct($productInfo): Product
100+
{
101+
$product = null;
102+
if ($productInfo instanceof Product) {
103+
$product = $productInfo;
104+
if (!$product->getId()) {
105+
throw new LocalizedException(
106+
__("The product wasn't found. Verify the product and try again.")
107+
);
108+
}
109+
} elseif (is_int($productInfo) || is_string($productInfo)) {
110+
$storeId = $this->storeManager->getStore()->getId();
111+
try {
112+
$product = $this->productRepository->getById($productInfo, false, $storeId);
113+
} catch (NoSuchEntityException $e) {
114+
throw new LocalizedException(
115+
__("The product wasn't found. Verify the product and try again."),
116+
$e
117+
);
118+
}
119+
} else {
120+
throw new LocalizedException(
121+
__("The product wasn't found. Verify the product and try again.")
122+
);
123+
}
124+
$currentWebsiteId = $this->storeManager->getStore()->getWebsiteId();
125+
if (!is_array($product->getWebsiteIds()) || !in_array($currentWebsiteId, $product->getWebsiteIds())) {
126+
throw new LocalizedException(
127+
__("The product wasn't found. Verify the product and try again.")
128+
);
129+
}
130+
return $product;
131+
}
132+
133+
/**
134+
* Get request quantity
135+
*
136+
* @param Product $product
137+
* @param DataObject|int|array $request
138+
* @return int|DataObject
139+
*/
140+
protected function getQtyRequest($product, $request = 0)
141+
{
142+
$request = $this->getProductRequest($request);
143+
$stockItem = $this->stockRegistry->getStockItem($product->getId(), $product->getStore()->getWebsiteId());
144+
$minimumQty = $stockItem->getMinSaleQty();
145+
//If product quantity is not specified in request and there is set minimal qty for it
146+
if ($minimumQty
147+
&& $minimumQty > 0
148+
&& !$request->getQty()
149+
) {
150+
$request->setQty($minimumQty);
151+
}
152+
153+
return $request;
154+
}
155+
156+
/**
157+
* Get request for product add to cart procedure
158+
*
159+
* @param DataObject|int|array $requestInfo
160+
* @return DataObject
161+
* @throws LocalizedException
162+
*/
163+
protected function getProductRequest($requestInfo)
164+
{
165+
if ($requestInfo instanceof DataObject) {
166+
$request = $requestInfo;
167+
} elseif (is_numeric($requestInfo)) {
168+
$request = new DataObject(['qty' => $requestInfo]);
169+
} elseif (is_array($requestInfo)) {
170+
$request = new DataObject($requestInfo);
171+
} else {
172+
throw new LocalizedException(
173+
__('We found an invalid request for adding product to quote.')
174+
);
175+
}
176+
$this->getRequestInfoFilter()->filter($request);
177+
178+
return $request;
179+
}
180+
181+
/**
182+
* Getter for RequestInfoFilter
183+
*
184+
* @return RequestInfoFilterInterface
185+
*/
186+
protected function getRequestInfoFilter()
187+
{
188+
if ($this->requestInfoFilter === null) {
189+
$this->requestInfoFilter = \Magento\Framework\App\ObjectManager::getInstance()
190+
->get(RequestInfoFilterInterface::class);
191+
}
192+
return $this->requestInfoFilter;
193+
}
194+
}

etc/frontend/di.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@
2020
<type name="Magento\Framework\View\Element\AbstractBlock">
2121
<plugin name="remove_related_upsell_block" type="Algolia\AlgoliaSearch\Plugin\RemovePdpProductsBlock" />
2222
</type>
23+
24+
<type name="Magento\Checkout\Model\Cart">
25+
<plugin name="handle_redirect_for_insights" type="Algolia\AlgoliaSearch\Plugin\AddToCartRedirectForInsights" />
26+
</type>
2327
</config>

view/frontend/templates/instant/hit.phtml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ $origFormatedVar = $block->escapeHtml('price' . $priceKey . '_original_formated'
8585
<form data-role="tocart-form" action="{{ addToCart.action }}" method="post">
8686
<input type="hidden" name="queryID" value="{{__queryID}}">
8787
<input type="hidden" name="product" value="{{objectID}}">
88+
<input type="hidden" name="indexName" value="{{__indexName}}">
89+
<input type="hidden" name="referer" value="instantsearch">
8890
{{#_highlightResult.default_bundle_options}}<input type="hidden" name="bundle_option[{{ optionId }}]" value="{{selectionId}}">{{/_highlightResult.default_bundle_options}}
8991
<input type="hidden" name="{{ addToCart.redirectUrlParam }}" value="{{ addToCart.uenc }}">
9092
<input name="form_key" type="hidden" value="{{ addToCart.formKey }}">

0 commit comments

Comments
 (0)