Skip to content

Commit 3a40589

Browse files
authored
Merge pull request #15 from magefan/12599-add-custom-position
12599 added ability to create custom positions and use them in rules
2 parents aa4ae45 + 77dfb03 commit 3a40589

File tree

9 files changed

+168
-13
lines changed

9 files changed

+168
-13
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
/**
3+
* Copyright © Magefan ([email protected]). All rights reserved.
4+
* Please visit Magefan.com for license details (https://magefan.com/end-user-license-agreement).
5+
*
6+
* Glory to Ukraine! Glory to the heroes!
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace Magefan\ProductLabel\Block\Adminhtml\System\Config\Form;
12+
13+
use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
14+
15+
class DynamicRow extends AbstractFieldArray
16+
{
17+
/**
18+
* Prepare rendering the new field by adding all the needed columns
19+
*/
20+
protected function _prepareToRender()
21+
{
22+
$this->addColumn('position', ['label' => __('Position')]);
23+
$this->_addAfter = false;
24+
$this->_addButtonLabel = __('Add');
25+
}
26+
}

Model/Config.php

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use Magento\Framework\App\Config\ScopeConfigInterface;
1111
use Magento\Store\Model\ScopeInterface;
12+
use Magento\Framework\Serialize\SerializerInterface;
1213

1314
/**
1415
* Class Config
@@ -20,6 +21,16 @@ class Config
2021
*/
2122
protected $scopeConfig;
2223

24+
/**
25+
* @var SerializerInterface
26+
*/
27+
protected $serializer;
28+
29+
/**
30+
* @var null
31+
*/
32+
protected $customPositions = null;
33+
2334
/**
2435
* Extension enabled config path
2536
*/
@@ -35,14 +46,20 @@ class Config
3546

3647
const XML_PATH_EXCLUDE_PAGE_TYPES = 'mfproductlabel/general/exclude_page_types';
3748

49+
const XML_PATH_CUSTOM_POSITIONS = 'mfproductlabel/general/custom_positions';
50+
51+
const SPLITTERS_FOR_CUSTOM_POSITIONS = '<!--mfcp_splitter--!>';
52+
3853
/**
39-
* Config constructor.
4054
* @param ScopeConfigInterface $scopeConfig
55+
* @param SerializerInterface $serializer
4156
*/
4257
public function __construct(
43-
ScopeConfigInterface $scopeConfig
58+
ScopeConfigInterface $scopeConfig,
59+
SerializerInterface $serializer
4460
) {
4561
$this->scopeConfig = $scopeConfig;
62+
$this->serializer = $serializer;
4663
}
4764

4865
/**
@@ -100,4 +117,25 @@ public function getExcludePageTypes(): array
100117
return explode(',', $pageTypes);
101118
}
102119

120+
/**
121+
* @return array
122+
*/
123+
public function getCustomPositions(): array
124+
{
125+
if (null == $this->customPositions) {
126+
$this->customPositions = [];
127+
128+
try {
129+
$customPositions = $this->serializer->unserialize($this->getConfig(self::XML_PATH_CUSTOM_POSITIONS));
130+
} catch (\InvalidArgumentException $e) {
131+
return $this->customPositions;
132+
}
133+
134+
foreach ($customPositions as $positionData) {
135+
$this->customPositions[$positionData['position']] = $positionData['position'];
136+
}
137+
}
138+
139+
return $this->customPositions;
140+
}
103141
}

Model/GetLabels.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ public function execute(array $productIds, array $productIdsForProductPage = [])
9595

9696
$productLabels = $this->getAvailableProductLabels($rules, $productRuleIds, $forProductPage);
9797

98+
$productLabelsForCustomPosition = $productLabels['custom'] ?? [];
99+
unset($productLabels['custom']);
100+
98101
$htmlToReplace = $this->layout
99102
->createBlock(\Magefan\ProductLabel\Block\Label::class)
100103
->setProductLabels($productLabels)
@@ -104,6 +107,21 @@ public function execute(array $productIds, array $productIdsForProductPage = [])
104107
if ($htmlToReplace) {
105108
$replaceMap[$productId] = $htmlToReplace;
106109
}
110+
111+
if ($productLabelsForCustomPosition) {
112+
foreach ($productLabelsForCustomPosition as $customPositionName => $productLabelsForCustomPosition) {
113+
$htmlToReplace = $this->layout
114+
->createBlock(\Magefan\ProductLabel\Block\Label::class)
115+
->setProductLabels([$customPositionName => $productLabelsForCustomPosition])
116+
->setAdditionalCssClass($forProductPage ? 'mfpl-product-page' : '')
117+
->setIsCustomPosition(true)
118+
->toHtml();
119+
120+
if ($htmlToReplace) {
121+
$replaceMap[$productId] .= Config::SPLITTERS_FOR_CUSTOM_POSITIONS . $htmlToReplace;
122+
}
123+
}
124+
}
107125
}
108126

109127
if (null !== $this->labelProcessor) {
@@ -137,7 +155,12 @@ public function getAvailableProductLabels($rules, $productRuleIds, $forProductPa
137155
}
138156

139157
if (!isset($discardRulePerPosition[$position])) {
140-
$productLabels[$position][] = $rule->getLabelData($forProductPage);
158+
if ($position == 'custom') {
159+
$customPosition = $forProductPage ? $rule->getData('pp_custom_position') : $rule->getData('custom_position');
160+
$productLabels[$position][$customPosition][] = $rule->getLabelData($forProductPage);
161+
} else {
162+
$productLabels[$position][] = $rule->getLabelData($forProductPage);
163+
}
141164
}
142165

143166
if ($rule->getDiscardSubsequentRules()) {

Model/Parser/Html.php

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@
99
namespace Magefan\ProductLabel\Model\Parser;
1010

1111
use Magefan\ProductLabel\Model\GetLabels;
12+
use Magefan\ProductLabel\Model\Config;
1213

1314
class Html
1415
{
1516
const COMMENT_PREFIX = '<!--mf_product_label_comment_';
1617
const COMMENT_PREFIX_GALLERY = '<!--mf_product_label_gallery_comment_';
1718
const COMMENT_SUFFIX = '-->';
1819

20+
1921
/**
2022
* @var GetLabels
2123
*/
2224
protected $getLabels;
25+
protected $mapProductToCustomPosition = [];
2326

2427
public function __construct(
2528
GetLabels $getLabels
@@ -35,8 +38,8 @@ public function __construct(
3538
public function execute(string $output): string
3639
{
3740
$isOutputIsJson = $this->json_validate($output);
38-
3941
$productIds = $this->getProductIds($output);
42+
4043
$currentPageProductId = $this->getCurrentPageProductId($output);
4144
$productIdsForProductPage = [];
4245

@@ -50,6 +53,9 @@ public function execute(string $output): string
5053
foreach ($replaceMap as $productId => $replace) {
5154
$replace = $isOutputIsJson ? trim(json_encode($replace),'"') : $replace;
5255

56+
// should be above regular replace
57+
$this->replaceForCustomPosition($output, $replace, $productId);
58+
5359
$output = ($currentPageProductId && $currentPageProductId == $productId)
5460
? str_replace(self::COMMENT_PREFIX_GALLERY . $productId . self::COMMENT_SUFFIX, $replace, $output)
5561
: str_replace(self::COMMENT_PREFIX . $productId . self::COMMENT_SUFFIX, $replace, $output);
@@ -58,6 +64,36 @@ public function execute(string $output): string
5864
return $output;
5965
}
6066

67+
/**
68+
* @param string $output
69+
* @param string $replace
70+
* @param $productId
71+
* @return void
72+
*/
73+
private function replaceForCustomPosition(string &$output, string &$replace, $productId)
74+
{
75+
$customPositions = $this->mapProductToCustomPosition[$productId] ?? [];
76+
77+
if (strpos($replace, Config::SPLITTERS_FOR_CUSTOM_POSITIONS) !== false) {
78+
if ($customPositions) {
79+
$customPositionsLabels = explode(Config::SPLITTERS_FOR_CUSTOM_POSITIONS, $replace);
80+
$replace = $customPositionsLabels[0];
81+
unset($customPositionsLabels[0]);
82+
83+
foreach ($customPositionsLabels as $label) {
84+
foreach ($customPositions as $customPosition) {
85+
if (strpos($label, $customPosition) !== false) {
86+
$output = str_replace(self::COMMENT_PREFIX . $productId . '____' . $customPosition . self::COMMENT_SUFFIX, $label, $output);
87+
}
88+
}
89+
}
90+
} else {
91+
// leave only labels with regular positions
92+
$replace = explode(Config::SPLITTERS_FOR_CUSTOM_POSITIONS, $replace);
93+
$replace = $replace[0];
94+
}
95+
}
96+
}
6197

6298
/**
6399
* @param string $html
@@ -68,7 +104,6 @@ private function getCurrentPageProductId(string $html): int
68104
$pattern = '/' . self::COMMENT_PREFIX_GALLERY . '(.*?)' . self::COMMENT_SUFFIX . '/';
69105
preg_match_all($pattern, $html, $matches);
70106

71-
72107
foreach ($matches[1] as $commentData) {
73108
$productId = (int)$commentData;
74109

@@ -91,9 +126,18 @@ private function getProductIds(string $html): array
91126
$productIds = [];
92127

93128
foreach ($matches[1] as $commentData) {
94-
$productId = (int)$commentData; //for now commentData=productId
129+
/* $commentData = '3____product_list' | '3'*/
130+
131+
if (is_numeric($commentData)) {
132+
$productId = (int)$commentData;
133+
} else {
134+
[$productId, $customPositionName] = explode('____', $commentData);
135+
$productId = (int)$productId;
136+
$this->mapProductToCustomPosition[$productId][$customPositionName] = $customPositionName;
137+
}
138+
95139
if ($productId) {
96-
$productIds[] = $productId;
140+
$productIds[$productId] = $productId;
97141
}
98142
}
99143

Model/ProductLabelAction.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use Magefan\ProductLabel\Model\ResourceModel\Rule\CollectionFactory as RuleCollectionFactory;
1212
use Magefan\ProductLabel\Model\CacheManager;
13-
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
13+
use Magefan\Community\Model\Magento\Product\CollectionOptimizedForSqlValidatorFactory as ProductCollectionFactory;
1414
use Magento\CatalogRule\Model\RuleFactory as CatalogRuleFactory;
1515
use Magento\Framework\App\ResourceConnection;
1616
use Magefan\Community\Model\Magento\Rule\Model\Condition\Sql\Builder as SqlBuilder;

etc/adminhtml/system.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@
4646
<source_model>Magefan\ProductLabel\Model\Config\Source\PageType</source_model>
4747
<can_be_empty>1</can_be_empty>
4848
</field>
49+
50+
<field id="custom_positions" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="70" translate="label" type="textarea" canRestore="1">
51+
<label>Custom Positions (Plus)</label>
52+
<frontend_model>Magefan\ProductLabel\Block\Adminhtml\System\Config\Form\DynamicRow</frontend_model>
53+
<backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model>
54+
<comment><![CDATA[
55+
These positions will be available in the rule, when you choose position "Custom". There you can select the position from this list.
56+
]]></comment>
57+
</field>
4958
</group>
5059
</section>
5160
</system>

etc/config.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@
1717
<pp_selector>.fotorama__stage__shaft</pp_selector>
1818
<pl_selector>.product-image-wrapper</pl_selector>
1919
<exclude_page_types></exclude_page_types>
20+
<custom_positions>
21+
{
22+
"_1736868521129_129":{"position":"product_list_before_name"},
23+
"_1736868522601_601":{"position":"product_list_after_price"},
24+
"_1736868553357_357":{"position":"product_page_before_price"},
25+
"_1736868660176_176":{"position":"product_page_after_reviews"}
26+
}
27+
</custom_positions>
28+
2029
</general>
2130
</mfproductlabel>
2231

view/adminhtml/templates/form/css.phtml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,19 @@
2323
body.use_the_same_label_for_product_page [data-index="product_page"] [data-index="container_image"],
2424
body.use_the_same_label_for_product_page [data-index="product_page"] [data-index="pp_label_type"],
2525
body.use_the_same_label_for_product_page [data-index="product_page"] [data-index="container_shape"],
26-
body.use_the_same_label_for_product_page [data-index="product_page"] .html-preview
26+
body.use_the_same_label_for_product_page [data-index="product_page"] .html-preview,
27+
body.use_the_same_label_for_product_page [data-index="product_page"] [data-index="pp_custom_position"]
2728
{display: none !important;}
2829
</style>
2930

3031
<style>
32+
[data-index="custom_position"],
33+
[data-index="pp_custom_position"],
3134
.custom_position_description {display: none;}
3235

36+
body[position="custom"] [data-index="custom_position"],
37+
body[pp_position="custom"] [data-index="pp_custom_position"] {display: block;}
38+
3339
body[position="custom"] [data-index="position"] .custom_position_description,
3440
body[pp_position="custom"] [data-index="pp_position"] .custom_position_description {
3541
display: block;

view/adminhtml/ui_component/mfproductlabel_rule_form.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,11 @@
287287
<![CDATA[
288288
<div class="custom_position_description">
289289
<p>To insert label in custom position need to add next string in your template:<br><br>
290-
<code style="font-size: 12px"> &lt;?= '&lt;!--mf_product_label_comment_' . $product-&gt;getId() . '--&gt;' ?&gt;</code>
290+
<code style="font-size: 12px"> &lt;?= '&lt;!--mf_product_label_comment_' . $product-&gt;getId() . '____your_position--&gt;' ?&gt;</code>
291291
<br>
292292
<br>
293293
<hr>
294-
&lt;!--mf_product_label_comment_7--&gt; &nbsp; (7 - product id)
294+
&lt;!--mf_product_label_comment_7____product_list_after_price--&gt; &nbsp; (7 - product id, product_list_after_price - selected position)
295295
</p>
296296
</div>
297297
]]>
@@ -460,11 +460,11 @@
460460
<![CDATA[
461461
<div class="custom_position_description">
462462
<p>To insert label in custom position need to add next string in your template:<br><br>
463-
<code style="font-size: 12px"> &lt;?= '&lt;!--mf_product_label_comment_' . $product-&gt;getId() . '--&gt;' ?&gt;</code>
463+
<code style="font-size: 12px"> &lt;?= '&lt;!--mf_product_label_comment_' . $product-&gt;getId() . '____your_position--&gt;' ?&gt;</code>
464464
<br>
465465
<br>
466466
<hr>
467-
&lt;!--mf_product_label_comment_7--&gt; &nbsp; (7 - product id)
467+
&lt;!--mf_product_label_comment_7____product_list_after_price--&gt; &nbsp; (7 - product id, product_list_after_price - selected position)
468468
</p>
469469
</div>
470470
]]>

0 commit comments

Comments
 (0)