Skip to content

Commit 5874f9d

Browse files
Merge pull request #3625 from magento-qwerty/2.3-bugfixes-230119
Fixed issues: - MAGETWO-88663: Wrong custom option behavior - MAGETWO-70972: Servers Configurations Needs Update - MAGETWO-88607: Wrong behavior of static content deploy - MAGETWO-90467: Added posibility to use captcha on share wishlist page - MAGETWO-92167: Apply HTML5 Attributes to Newsletter Preview - MAGETWO-92726: Fixed wrong admin notifications behavior - MAGETWO-88649: Wrong swatches behavior - MAGETWO-95439: Fixed incorrect request flow for sitemaps - MAGETWO-85120: Wrong wysiwyg images request flow
2 parents b3ebb80 + 54de6b3 commit 5874f9d

File tree

36 files changed

+969
-691
lines changed

36 files changed

+969
-691
lines changed

.htaccess

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,15 @@
364364
Require all denied
365365
</IfVersion>
366366
</Files>
367+
<Files .user.ini>
368+
<IfVersion < 2.4>
369+
order allow,deny
370+
deny from all
371+
</IfVersion>
372+
<IfVersion >= 2.4>
373+
Require all denied
374+
</IfVersion>
375+
</Files>
367376

368377
# For 404s and 403s that aren't handled by the application, show plain 404 response
369378
ErrorDocument 404 /pub/errors/404.php

.htaccess.sample

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,15 @@
341341
Require all denied
342342
</IfVersion>
343343
</Files>
344+
<Files .user.ini>
345+
<IfVersion < 2.4>
346+
order allow,deny
347+
deny from all
348+
</IfVersion>
349+
<IfVersion >= 2.4>
350+
Require all denied
351+
</IfVersion>
352+
</Files>
344353

345354
# For 404s and 403s that aren't handled by the application, show plain 404 response
346355
ErrorDocument 404 /pub/errors/404.php

app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88

99
namespace Magento\AdminNotification\Block\Grid\Renderer;
1010

11+
/**
12+
* Renderer class for action in the admin notifications grid
13+
*
14+
* @package Magento\AdminNotification\Block\Grid\Renderer
15+
*/
1116
class Actions extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
1217
{
1318
/**
@@ -37,7 +42,9 @@ public function __construct(
3742
*/
3843
public function render(\Magento\Framework\DataObject $row)
3944
{
40-
$readDetailsHtml = $row->getUrl() ? '<a class="action-details" target="_blank" href="' . $row->getUrl() . '">' .
45+
$readDetailsHtml = $row->getUrl() ? '<a class="action-details" target="_blank" href="' .
46+
$this->escapeUrl($row->getUrl())
47+
. '">' .
4148
__('Read Details') . '</a>' : '';
4249

4350
$markAsReadHtml = !$row->getIsRead() ? '<a class="action-mark" href="' . $this->getUrl(

app/code/Magento/Catalog/Block/Product/View/Options/Type/Select.php

Lines changed: 53 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,17 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Catalog\Block\Product\View\Options\Type;
78

9+
use Magento\Catalog\Model\Product\Option;
10+
use Magento\Catalog\Block\Product\View\Options\Type\Select\CheckableFactory;
11+
use Magento\Catalog\Block\Product\View\Options\Type\Select\MultipleFactory;
12+
use Magento\Framework\App\ObjectManager;
13+
use Magento\Framework\View\Element\Template\Context;
14+
use Magento\Framework\Pricing\Helper\Data;
15+
use Magento\Catalog\Helper\Data as CatalogHelper;
16+
817
/**
918
* Product options text type block
1019
*
@@ -13,169 +22,60 @@
1322
*/
1423
class Select extends \Magento\Catalog\Block\Product\View\Options\AbstractOptions
1524
{
25+
/**
26+
* @var CheckableFactory
27+
*/
28+
private $checkableFactory;
29+
/**
30+
* @var MultipleFactory
31+
*/
32+
private $multipleFactory;
33+
34+
/**
35+
* Select constructor.
36+
* @param Context $context
37+
* @param Data $pricingHelper
38+
* @param CatalogHelper $catalogData
39+
* @param array $data
40+
* @param CheckableFactory|null $checkableFactory
41+
* @param MultipleFactory|null $multipleFactory
42+
*/
43+
public function __construct(
44+
Context $context,
45+
Data $pricingHelper,
46+
CatalogHelper $catalogData,
47+
array $data = [],
48+
CheckableFactory $checkableFactory = null,
49+
MultipleFactory $multipleFactory = null
50+
) {
51+
parent::__construct($context, $pricingHelper, $catalogData, $data);
52+
$this->checkableFactory = $checkableFactory ?: ObjectManager::getInstance()->get(CheckableFactory::class);
53+
$this->multipleFactory = $multipleFactory ?: ObjectManager::getInstance()->get(MultipleFactory::class);
54+
}
55+
1656
/**
1757
* Return html for control element
1858
*
1959
* @return string
20-
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
21-
* @SuppressWarnings(PHPMD.NPathComplexity)
22-
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
2360
*/
2461
public function getValuesHtml()
2562
{
26-
$_option = $this->getOption();
27-
$configValue = $this->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId());
28-
$store = $this->getProduct()->getStore();
29-
30-
$this->setSkipJsReloadPrice(1);
31-
// Remove inline prototype onclick and onchange events
32-
33-
if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_DROP_DOWN ||
34-
$_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_MULTIPLE
63+
$option = $this->getOption();
64+
$optionType = $option->getType();
65+
if ($optionType === Option::OPTION_TYPE_DROP_DOWN ||
66+
$optionType === Option::OPTION_TYPE_MULTIPLE
3567
) {
36-
$require = $_option->getIsRequire() ? ' required' : '';
37-
$extraParams = '';
38-
$select = $this->getLayout()->createBlock(
39-
\Magento\Framework\View\Element\Html\Select::class
40-
)->setData(
41-
[
42-
'id' => 'select_' . $_option->getId(),
43-
'class' => $require . ' product-custom-option admin__control-select'
44-
]
45-
);
46-
if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_DROP_DOWN) {
47-
$select->setName('options[' . $_option->getId() . ']')->addOption('', __('-- Please Select --'));
48-
} else {
49-
$select->setName('options[' . $_option->getId() . '][]');
50-
$select->setClass('multiselect admin__control-multiselect' . $require . ' product-custom-option');
51-
}
52-
foreach ($_option->getValues() as $_value) {
53-
$priceStr = $this->_formatPrice(
54-
[
55-
'is_percent' => $_value->getPriceType() == 'percent',
56-
'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'),
57-
],
58-
false
59-
);
60-
$select->addOption(
61-
$_value->getOptionTypeId(),
62-
$_value->getTitle() . ' ' . strip_tags($priceStr) . '',
63-
['price' => $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false)]
64-
);
65-
}
66-
if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_MULTIPLE) {
67-
$extraParams = ' multiple="multiple"';
68-
}
69-
if (!$this->getSkipJsReloadPrice()) {
70-
$extraParams .= ' onchange="opConfig.reloadPrice()"';
71-
}
72-
$extraParams .= ' data-selector="' . $select->getName() . '"';
73-
$select->setExtraParams($extraParams);
74-
75-
if ($configValue) {
76-
$select->setValue($configValue);
77-
}
78-
79-
return $select->getHtml();
68+
$optionBlock = $this->multipleFactory->create();
8069
}
81-
82-
if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_RADIO ||
83-
$_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_CHECKBOX
70+
if ($optionType === Option::OPTION_TYPE_RADIO ||
71+
$optionType === Option::OPTION_TYPE_CHECKBOX
8472
) {
85-
$selectHtml = '<div class="options-list nested" id="options-' . $_option->getId() . '-list">';
86-
$require = $_option->getIsRequire() ? ' required' : '';
87-
$arraySign = '';
88-
switch ($_option->getType()) {
89-
case \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_RADIO:
90-
$type = 'radio';
91-
$class = 'radio admin__control-radio';
92-
if (!$_option->getIsRequire()) {
93-
$selectHtml .= '<div class="field choice admin__field admin__field-option">' .
94-
'<input type="radio" id="options_' .
95-
$_option->getId() .
96-
'" class="' .
97-
$class .
98-
' product-custom-option" name="options[' .
99-
$_option->getId() .
100-
']"' .
101-
' data-selector="options[' . $_option->getId() . ']"' .
102-
($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') .
103-
' value="" checked="checked" /><label class="label admin__field-label" for="options_' .
104-
$_option->getId() .
105-
'"><span>' .
106-
__('None') . '</span></label></div>';
107-
}
108-
break;
109-
case \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_CHECKBOX:
110-
$type = 'checkbox';
111-
$class = 'checkbox admin__control-checkbox';
112-
$arraySign = '[]';
113-
break;
114-
}
115-
$count = 1;
116-
foreach ($_option->getValues() as $_value) {
117-
$count++;
118-
119-
$priceStr = $this->_formatPrice(
120-
[
121-
'is_percent' => $_value->getPriceType() == 'percent',
122-
'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'),
123-
]
124-
);
125-
126-
$htmlValue = $_value->getOptionTypeId();
127-
if ($arraySign) {
128-
$checked = is_array($configValue) && in_array($htmlValue, $configValue) ? 'checked' : '';
129-
} else {
130-
$checked = $configValue == $htmlValue ? 'checked' : '';
131-
}
132-
133-
$dataSelector = 'options[' . $_option->getId() . ']';
134-
if ($arraySign) {
135-
$dataSelector .= '[' . $htmlValue . ']';
136-
}
137-
138-
$selectHtml .= '<div class="field choice admin__field admin__field-option' .
139-
$require .
140-
'">' .
141-
'<input type="' .
142-
$type .
143-
'" class="' .
144-
$class .
145-
' ' .
146-
$require .
147-
' product-custom-option"' .
148-
($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') .
149-
' name="options[' .
150-
$_option->getId() .
151-
']' .
152-
$arraySign .
153-
'" id="options_' .
154-
$_option->getId() .
155-
'_' .
156-
$count .
157-
'" value="' .
158-
$htmlValue .
159-
'" ' .
160-
$checked .
161-
' data-selector="' . $dataSelector . '"' .
162-
' price="' .
163-
$this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false) .
164-
'" />' .
165-
'<label class="label admin__field-label" for="options_' .
166-
$_option->getId() .
167-
'_' .
168-
$count .
169-
'"><span>' .
170-
$_value->getTitle() .
171-
'</span> ' .
172-
$priceStr .
173-
'</label>';
174-
$selectHtml .= '</div>';
175-
}
176-
$selectHtml .= '</div>';
177-
178-
return $selectHtml;
73+
$optionBlock = $this->checkableFactory->create();
17974
}
75+
return $optionBlock
76+
->setOption($option)
77+
->setProduct($this->getProduct())
78+
->setSkipJsReloadPrice(1)
79+
->_toHtml();
18080
}
18181
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Catalog\Block\Product\View\Options\Type\Select;
10+
11+
use Magento\Catalog\Api\Data\ProductCustomOptionValuesInterface;
12+
use Magento\Catalog\Block\Product\View\Options\AbstractOptions;
13+
use Magento\Catalog\Model\Product\Option;
14+
15+
/**
16+
* Represent needed logic for checkbox and radio button option types
17+
*/
18+
class Checkable extends AbstractOptions
19+
{
20+
/**
21+
* @var string
22+
*/
23+
protected $_template = 'Magento_Catalog::product/composite/fieldset/options/view/checkable.phtml';
24+
25+
/**
26+
* Returns formated price
27+
*
28+
* @param ProductCustomOptionValuesInterface $value
29+
* @return string
30+
*/
31+
public function formatPrice(ProductCustomOptionValuesInterface $value): string
32+
{
33+
/** @noinspection PhpMethodParametersCountMismatchInspection */
34+
return parent::_formatPrice(
35+
[
36+
'is_percent' => $value->getPriceType() === 'percent',
37+
'pricing_value' => $value->getPrice($value->getPriceType() === 'percent')
38+
]
39+
);
40+
}
41+
42+
/**
43+
* Returns current currency for store
44+
*
45+
* @param ProductCustomOptionValuesInterface $value
46+
* @return float|string
47+
*/
48+
public function getCurrencyByStore(ProductCustomOptionValuesInterface $value)
49+
{
50+
/** @noinspection PhpMethodParametersCountMismatchInspection */
51+
return $this->pricingHelper->currencyByStore(
52+
$value->getPrice(true),
53+
$this->getProduct()->getStore(),
54+
false
55+
);
56+
}
57+
58+
/**
59+
* Returns preconfigured value for given option
60+
*
61+
* @param Option $option
62+
* @return string|array|null
63+
*/
64+
public function getPreconfiguredValue(Option $option)
65+
{
66+
return $this->getProduct()->getPreconfiguredValues()->getData('options/' . $option->getId());
67+
}
68+
}

0 commit comments

Comments
 (0)