Skip to content

Commit 6d55ca6

Browse files
Merge pull request #10 from Itonomy/develop
[M2M-12,M2M-15,M2M-16] New features
2 parents 5443d9e + 370923b commit 6d55ca6

File tree

18 files changed

+712
-248
lines changed

18 files changed

+712
-248
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "itonomy/module-flowbox",
33
"description": "Flowbox for Magento2",
44
"type": "magento2-module",
5-
"version": "1.4.2",
5+
"version": "1.4.3",
66
"license": [
77
"MIT"
88
],

src/Block/Base.php

Lines changed: 154 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,98 +7,220 @@
77

88
namespace Itonomy\Flowbox\Block;
99

10+
/**
11+
* Class Base
12+
* @package Itonomy\Flowbox\Block
13+
*/
1014
abstract class Base extends \Magento\Framework\View\Element\Template
1115
{
12-
const XML_PATH_FLOWBOX_ENABLE = 'itonomy_flowbox/general/enable';
16+
const XML_CONFIG_ENABLE = 'itonomy_flowbox/general/enable';
17+
18+
const XML_CONFIG_THIRD_PARTY_COOKIE_MGR = 'itonomy_flowbox/general/third_party_cookie_mgr';
19+
20+
const XML_CONFIG_DEBUG_JAVASCRIPT = 'itonomy_flowbox/general/debug_javascript';
21+
22+
const XML_CONFIG_API_KEY = 'itonomy_flowbox/general/api_key';
1323

14-
const XML_PATH_FLOWBOX_DEBUG_JS = 'itonomy_flowbox/general/debug_javascript';
24+
const XML_CONFIG_PRODUCT_ID_ATTR = 'itonomy_flowbox/general/product_id_attribute';
1525

16-
const XML_PATH_API_KEY = 'itonomy_flowbox/general/api_key';
26+
const XML_CONFIG_PRODUCT_ID_ATTR_CUSTOM = 'itonomy_flowbox/general/product_id_attribute_custom';
1727

18-
const FLOW_TYPE_DEFAULT = 'default';
28+
const XML_CONFIG_TAGBAR_INPUT_TYPE = 'itonomy_flowbox/general/tagbar_input_type';
1929

20-
const FLOW_TYPE_DYNAMIC_PRODUCT = 'dynamic-product';
30+
const XML_CONFIG_SHOW_HASHES = 'itonomy_flowbox/general/show_hashes';
2131

22-
const FLOW_TYPE_DYNAMIC_TAG = 'dynamic-tag';
2332

2433
/**
2534
* @var \Magento\Framework\Encryption\EncryptorInterface
2635
*/
2736
private $encryptor;
37+
/**
38+
* @var \Magento\Catalog\Api\ProductRepositoryInterface
39+
*/
40+
private $productRepository;
41+
/**
42+
* @var \Magento\Framework\Api\SearchCriteriaBuilder
43+
*/
44+
private $searchCriteriaBuilder;
45+
/**
46+
* @var array
47+
*/
48+
private $errors = [];
49+
/**
50+
* @var \Magento\Cookie\Helper\Cookie
51+
*/
52+
private $cookieHelper;
53+
/**
54+
* @var \Itonomy\Flowbox\Helper\Data
55+
*/
56+
protected $dataHelper;
2857

2958
/**
3059
* Base constructor.
3160
* @param \Magento\Framework\View\Element\Template\Context $context
3261
* @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
62+
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
63+
* @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
64+
* @param \Magento\Cookie\Helper\Cookie $cookieHelper
65+
* @param \Itonomy\Flowbox\Helper\Data $dataHelper
3366
* @param array $data
3467
*/
3568
public function __construct(
3669
\Magento\Framework\View\Element\Template\Context $context,
3770
\Magento\Framework\Encryption\EncryptorInterface $encryptor,
71+
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
72+
\Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
73+
\Magento\Cookie\Helper\Cookie $cookieHelper,
74+
\Itonomy\Flowbox\Helper\Data $dataHelper,
3875
array $data = []
3976
) {
40-
\Magento\Framework\View\Element\Template::__construct($context, $data);
77+
parent::__construct($context, $data);
78+
79+
$this->cookieHelper = $cookieHelper;
4180
$this->encryptor = $encryptor;
81+
$this->productRepository = $productRepository;
82+
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
83+
$this->dataHelper = $dataHelper;
4284
}
4385

4486
/**
4587
* @return bool
4688
*/
4789
public function isFlowboxEnabled(): bool
4890
{
49-
return $this->_scopeConfig->isSetFlag(static::XML_PATH_FLOWBOX_ENABLE);
91+
return $this->_scopeConfig->isSetFlag(self::XML_CONFIG_ENABLE);
5092
}
5193

5294
/**
95+
* @return string
96+
*/
97+
public function getJsConfig(): string
98+
{
99+
$errors = $this->getErrors();
100+
if (\count($errors)) {
101+
$this->setData('errors', $errors);
102+
}
103+
return $this->toJson(['flowbox', 'errors']);
104+
}
105+
106+
/**
107+
* Checks if user is allowed to save cookies
108+
*
109+
* True if any of the following conditions are met:
110+
* - A third party cookie manager is in use;
111+
* - Magento Cookie Restriction Mode is disabled or it allows the user to
112+
* save cookies.
113+
*
53114
* @return bool
54115
*/
55-
public function isDebugJavaScript(): bool
116+
protected function isUserAllowSaveCookie(): bool
56117
{
57-
return $this->_scopeConfig->isSetFlag(static::XML_PATH_FLOWBOX_DEBUG_JS);
118+
return ($this->_scopeConfig->isSetFlag(self::XML_CONFIG_THIRD_PARTY_COOKIE_MGR)
119+
|| false === $this->cookieHelper->isUserNotAllowSaveCookie());
58120
}
59121

60122
/**
123+
* Return product identifier
61124
* @return string
125+
* @throws \Magento\Framework\Exception\NoSuchEntityException
62126
*/
63-
public function getApiKey(): string
127+
protected function getProductIdentifier(): ?string
64128
{
65-
return $this->encryptor->decrypt(
66-
$this->_scopeConfig->getValue(static::XML_PATH_API_KEY)
129+
// Return product ID attribute value for currently viewed product
130+
return $this->getProductIdAttributeValue(
131+
$this->getProductIdAttribute(),
132+
$this->getRequest()->getParam('id')
67133
);
68134
}
69135

70136
/**
71-
* Return json configuration for javascript component
72-
* @return string
137+
* @return \Magento\Catalog\Api\Data\ProductInterface
138+
* @throws \Magento\Framework\Exception\NoSuchEntityException
73139
*/
74-
public function getJsConfig(): string
140+
protected function getProduct(): \Magento\Catalog\Api\Data\ProductInterface
75141
{
76-
if (!$this->hasData('flowbox')) {
77-
$this->unsetData('errors');
78-
$this->prepareConfig();
79-
}
80-
if ($this->hasData('errors')) {
81-
return $this->toJson(['errors']);
82-
}
83-
return $this->toJson(['flowbox']);
142+
return $this->productRepository->getById(
143+
$this->getRequest()->getParam('id')
144+
);
84145
}
85146

86147
/**
87-
* Prepare configuration for javascript component
88-
*
89-
* You should set an array 'flowbox' containing configuration, or an array
90-
* 'errors' containing error messages.
148+
* @return bool
149+
*/
150+
protected function isDebugJavaScript(): bool
151+
{
152+
return $this->_scopeConfig->isSetFlag(self::XML_CONFIG_DEBUG_JAVASCRIPT);
153+
}
154+
155+
/**
156+
* @return string|null
157+
*/
158+
protected function getApiKey(): ?string
159+
{
160+
return $this->encryptor->decrypt(
161+
$this->_scopeConfig->getValue(self::XML_CONFIG_API_KEY)
162+
);
163+
}
164+
165+
/**
166+
* @return string|null
91167
*/
92-
abstract protected function prepareConfig(): void;
168+
protected function getProductIdAttribute(): ?string
169+
{
170+
$value = $this->_scopeConfig->getValue(self::XML_CONFIG_PRODUCT_ID_ATTR);
171+
if ($value === \Itonomy\Flowbox\Model\Config\Source\ProductIdentifier::CUSTOM) {
172+
$value = $this->_scopeConfig->getValue(self::XML_CONFIG_PRODUCT_ID_ATTR_CUSTOM);
173+
}
174+
return $value;
175+
}
93176

94177
/**
95178
* @param string $message
96179
*/
97180
protected function addError(string $message): void
98181
{
99-
if (!$this->hasData('errors')) {
100-
$this->_data['errors'] = [];
182+
$this->errors[] = $message;
183+
}
184+
185+
/**
186+
* @return string[]
187+
*/
188+
protected function getErrors(): array
189+
{
190+
return $this->errors;
191+
}
192+
193+
/**
194+
* @param $attributeCode
195+
* @param $productId
196+
* @return string
197+
* @throws \Magento\Framework\Exception\NoSuchEntityException
198+
*/
199+
private function getProductIdAttributeValue($attributeCode, $productId): string
200+
{
201+
$searchCriteria = $this->searchCriteriaBuilder->addFilter('entity_id', $productId)->setPageSize(1);
202+
203+
$products = $this->productRepository->getList(
204+
$searchCriteria->create()
205+
)->getItems();
206+
207+
$product = \reset($products);
208+
if (!$product instanceof \Magento\Catalog\Api\Data\ProductInterface) {
209+
throw new \Magento\Framework\Exception\NoSuchEntityException(
210+
__('No product found with entity_id=%product_id', ['product_id' => $productId])
211+
);
212+
}
213+
214+
$value = (string) $product->getData($attributeCode);
215+
if (empty($value)) {
216+
throw new \Magento\Framework\Exception\NoSuchEntityException(
217+
__(
218+
'Attribute with attribute_code=%attribute_code not set on product with entity_id=%product_id',
219+
['attribute_code' => $attributeCode, 'product_id' => $productId]
220+
)
221+
);
101222
}
102-
$this->_data['errors'][] = $message;
223+
224+
return $value;
103225
}
104226
}

src/Block/Checkout/Onepage/Success.php

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,47 +14,55 @@ class Success extends \Itonomy\Flowbox\Block\Base
1414
*/
1515
private $checkoutSession;
1616

17-
/**
18-
* Success constructor.
19-
* @param \Magento\Framework\View\Element\Template\Context $context
20-
* @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
21-
* @param \Magento\Checkout\Model\Session $checkoutSession
22-
* @param array $data
23-
*/
2417
public function __construct(
2518
\Magento\Framework\View\Element\Template\Context $context,
2619
\Magento\Framework\Encryption\EncryptorInterface $encryptor,
20+
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
21+
\Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
22+
\Magento\Cookie\Helper\Cookie $cookieHelper,
23+
\Itonomy\Flowbox\Helper\Data $dataHelper,
2724
\Magento\Checkout\Model\Session $checkoutSession,
2825
array $data = []
2926
) {
30-
parent::__construct($context, $encryptor, $data);
27+
parent::__construct(
28+
$context,
29+
$encryptor,
30+
$productRepository,
31+
$searchCriteriaBuilder,
32+
$cookieHelper,
33+
$dataHelper,
34+
$data
35+
);
36+
3137
$this->checkoutSession = $checkoutSession;
3238
}
3339

34-
/**
35-
* @inheritDoc
36-
*/
37-
protected function prepareConfig(): void
40+
public function getJsConfig(): string
3841
{
3942
try {
4043
$order = $this->checkoutSession->getLastRealOrder();
44+
$productIdAttribute = $this->getProductIdAttribute();
4145

42-
$this->setData('flowbox', [
43-
'debug' => $this->isDebugJavaScript(),
44-
'apiKey' => (string) $this->getApiKey(),
45-
'orderId' => \ltrim($order->getIncrementId(), '#'),
46-
'products' => \array_map(
47-
function ($item) {
48-
return [
49-
'id' => (string) $item->getSku(),
50-
'quantity' => (int) $item->getQtyOrdered()
51-
];
52-
},
53-
$this->getAllVisibleItems($order)
54-
),
55-
]);
46+
$this->setData(
47+
'flowbox',
48+
[
49+
'alowCookies' => $this->isUserAllowSaveCookie(),
50+
'debug' => $this->isDebugJavaScript(),
51+
'apiKey' => (string) $this->getApiKey(),
52+
'orderId' => \ltrim($order->getIncrementId(), '#'),
53+
'products' => \array_map(
54+
function ($item) use ($productIdAttribute) {
55+
return [
56+
'id' => (string) $item->getData($productIdAttribute),
57+
'quantity' => (int) $item->getQtyOrdered()
58+
];
59+
},
60+
$this->getAllVisibleOrderItems($order)
61+
),
62+
]
63+
);
5664
} catch (\Exception $e) {
57-
$errorMessage = $this->escapeHtml(
65+
$errorMessage = $this->_escaper->escapeHtml(
5866
(string) __(
5967
'%flowbox: could not compile configuration: %error',
6068
['flowbox' => 'Flowbox', 'error' => $e->getMessage()]
@@ -63,21 +71,30 @@ function ($item) {
6371
$this->addError($errorMessage);
6472
$this->_logger->error($errorMessage, ['exception' => $e]);
6573
}
74+
return parent::getJsConfig();
6675
}
76+
6777
/**
6878
* Retrieves visible products of the order, omitting its children (yes, this is different than Magento's method)
69-
* @param Magento\Sales\Model\Order $order
7079
*
80+
* @param \Magento\Sales\Model\Order $order
7181
* @return array
7282
*/
73-
protected function getAllVisibleItems($order)
83+
protected function getAllVisibleOrderItems(\Magento\Sales\Model\Order $order): array
7484
{
85+
$productIdAttribute = $this->getProductIdAttribute();
86+
7587
$items = [];
7688
foreach ($order->getItems() as $item) {
89+
/** @var \Magento\Sales\Model\Order\Item $item */
7790
if (!$item->isDeleted() && !$item->getParentItem()) {
91+
$productIdAttributeValue = $item->getProduct()->getAttributeText($productIdAttribute);
92+
$item->setData($productIdAttribute, $productIdAttributeValue);
93+
7894
$items[] = $item;
7995
}
8096
}
97+
8198
return $items;
8299
}
83-
}
100+
}

0 commit comments

Comments
 (0)