Skip to content

Commit a6332d6

Browse files
🔃 [Magento Community Engineering] Community Contributions - 2.4-develop
Accepted Community Pull Requests: - #26075: Fix #6310 - Changing products 'this item has weight' using 'Update Attributes' is not possible (by @Bartlomiejsz) Fixed GitHub Issues: - #6310: Changing products 'this item has weight' using 'Update Attributes' is not possible (reported by @hostep) has been fixed in #26075 by @Bartlomiejsz in 2.4-develop branch Related commits: 1. 2506c08 2. f6f414b 3. 36738ec
2 parents 45a3970 + b2a2476 commit a6332d6

File tree

10 files changed

+755
-128
lines changed

10 files changed

+755
-128
lines changed

app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Attributes.php

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,18 @@
1313

1414
namespace Magento\Catalog\Block\Adminhtml\Product\Edit\Action\Attribute\Tab;
1515

16+
use Magento\Backend\Block\Template\Context;
17+
use Magento\Backend\Block\Widget\Tab\TabInterface;
18+
use Magento\Catalog\Block\Adminhtml\Form;
19+
use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Boolean;
20+
use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Image;
21+
use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Price;
22+
use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Weight;
23+
use Magento\Catalog\Helper\Product\Edit\Action\Attribute;
24+
use Magento\Catalog\Model\ProductFactory;
1625
use Magento\Framework\Data\Form\Element\AbstractElement;
26+
use Magento\Framework\Data\FormFactory;
27+
use Magento\Framework\Registry;
1728

1829
/**
1930
* Attributes tab block
@@ -23,37 +34,38 @@
2334
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2435
* @since 100.0.2
2536
*/
26-
class Attributes extends \Magento\Catalog\Block\Adminhtml\Form implements
27-
\Magento\Backend\Block\Widget\Tab\TabInterface
37+
class Attributes extends Form implements TabInterface
2838
{
2939
/**
30-
* @var \Magento\Catalog\Model\ProductFactory
40+
* @var ProductFactory
3141
*/
3242
protected $_productFactory;
3343

3444
/**
35-
* @var \Magento\Catalog\Helper\Product\Edit\Action\Attribute
45+
* @var Attribute
3646
*/
3747
protected $_attributeAction;
3848

39-
/** @var array */
49+
/**
50+
* @var array
51+
*/
4052
private $excludeFields;
4153

4254
/**
43-
* @param \Magento\Backend\Block\Template\Context $context
44-
* @param \Magento\Framework\Registry $registry
45-
* @param \Magento\Framework\Data\FormFactory $formFactory
46-
* @param \Magento\Catalog\Model\ProductFactory $productFactory
47-
* @param \Magento\Catalog\Helper\Product\Edit\Action\Attribute $attributeAction
55+
* @param Context $context
56+
* @param Registry $registry
57+
* @param FormFactory $formFactory
58+
* @param ProductFactory $productFactory
59+
* @param Attribute $attributeAction
4860
* @param array $data
4961
* @param array|null $excludeFields
5062
*/
5163
public function __construct(
52-
\Magento\Backend\Block\Template\Context $context,
53-
\Magento\Framework\Registry $registry,
54-
\Magento\Framework\Data\FormFactory $formFactory,
55-
\Magento\Catalog\Model\ProductFactory $productFactory,
56-
\Magento\Catalog\Helper\Product\Edit\Action\Attribute $attributeAction,
64+
Context $context,
65+
Registry $registry,
66+
FormFactory $formFactory,
67+
ProductFactory $productFactory,
68+
Attribute $attributeAction,
5769
array $data = [],
5870
array $excludeFields = null
5971
) {
@@ -72,7 +84,7 @@ public function __construct(
7284
*/
7385
protected function _prepareForm(): void
7486
{
75-
$this->setFormExcludedFieldList($this->getExcludedFields());
87+
$this->setFormExcludedFieldList($this->excludeFields);
7688
$this->_eventManager->dispatch(
7789
'adminhtml_catalog_product_form_prepare_excluded_field_list',
7890
['object' => $this]
@@ -110,10 +122,10 @@ public function getAttributes()
110122
protected function _getAdditionalElementTypes()
111123
{
112124
return [
113-
'price' => \Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Price::class,
114-
'weight' => \Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Weight::class,
115-
'image' => \Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Image::class,
116-
'boolean' => \Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Boolean::class
125+
'price' => Price::class,
126+
'weight' => Weight::class,
127+
'image' => Image::class,
128+
'boolean' => Boolean::class
117129
];
118130
}
119131

@@ -129,7 +141,7 @@ protected function _getAdditionalElementHtml($element)
129141
$nameAttributeHtml = $element->getExtType() === 'multiple' ? 'name="' . $element->getId() . '_checkbox"' : '';
130142
$elementId = $element->getId();
131143
$dataAttribute = "data-disable='{$elementId}'";
132-
$dataCheckboxName = "toggle_" . "{$elementId}";
144+
$dataCheckboxName = "toggle_{$elementId}";
133145
$checkboxLabel = __('Change');
134146
// @codingStandardsIgnoreStart
135147
$html = <<<HTML
@@ -140,14 +152,8 @@ protected function _getAdditionalElementHtml($element)
140152
</label>
141153
</span>
142154
HTML;
143-
if ($elementId === 'weight') {
144-
$html .= <<<HTML
145-
<script>require(['Magento_Catalog/js/product/weight-handler'], function (weightHandle) {
146-
weightHandle.hideWeightSwitcher();
147-
});</script>
148-
HTML;
149-
// @codingStandardsIgnoreEnd
150-
}
155+
156+
// @codingStandardsIgnoreEnd
151157
return $html;
152158
}
153159

@@ -190,14 +196,4 @@ public function isHidden()
190196
{
191197
return false;
192198
}
193-
194-
/**
195-
* Returns excluded fields
196-
*
197-
* @return array
198-
*/
199-
private function getExcludedFields(): array
200-
{
201-
return $this->excludeFields;
202-
}
203199
}

app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Weight.php

Lines changed: 115 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,55 +3,64 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

7-
/**
8-
* Product form weight field helper
9-
*/
108
namespace Magento\Catalog\Block\Adminhtml\Product\Helper\Form;
119

10+
use Magento\Catalog\Api\Data\ProductAttributeInterface;
11+
use Magento\Directory\Helper\Data;
1212
use Magento\Framework\Data\Form;
1313
use Magento\Catalog\Model\Product\Edit\WeightResolver;
14+
use Magento\Framework\Data\Form\Element\CollectionFactory;
15+
use Magento\Framework\Data\Form\Element\Factory;
16+
use Magento\Framework\Data\Form\Element\Radios;
17+
use Magento\Framework\Data\Form\Element\Text;
18+
use Magento\Framework\Escaper;
19+
use Magento\Framework\Locale\Format;
1420

15-
class Weight extends \Magento\Framework\Data\Form\Element\Text
21+
/**
22+
* Product form weight field helper
23+
*/
24+
class Weight extends Text
1625
{
1726
/**
1827
* Weight switcher radio-button element
1928
*
20-
* @var \Magento\Framework\Data\Form\Element\Checkbox
29+
* @var Radios
2130
*/
2231
protected $weightSwitcher;
2332

2433
/**
25-
* @var \Magento\Framework\Locale\Format
34+
* @var Format
2635
*/
2736
protected $localeFormat;
2837

2938
/**
30-
* @var \Magento\Directory\Helper\Data
39+
* @var Data
3140
*/
3241
protected $directoryHelper;
3342

3443
/**
35-
* @param \Magento\Framework\Data\Form\Element\Factory $factoryElement
36-
* @param \Magento\Framework\Data\Form\Element\CollectionFactory $factoryCollection
37-
* @param \Magento\Framework\Escaper $escaper
38-
* @param \Magento\Framework\Locale\Format $localeFormat
39-
* @param \Magento\Directory\Helper\Data $directoryHelper
44+
* @param Factory $factoryElement
45+
* @param CollectionFactory $factoryCollection
46+
* @param Escaper $escaper
47+
* @param Format $localeFormat
48+
* @param Data $directoryHelper
4049
* @param array $data
4150
*/
4251
public function __construct(
43-
\Magento\Framework\Data\Form\Element\Factory $factoryElement,
44-
\Magento\Framework\Data\Form\Element\CollectionFactory $factoryCollection,
45-
\Magento\Framework\Escaper $escaper,
46-
\Magento\Framework\Locale\Format $localeFormat,
47-
\Magento\Directory\Helper\Data $directoryHelper,
52+
Factory $factoryElement,
53+
CollectionFactory $factoryCollection,
54+
Escaper $escaper,
55+
Format $localeFormat,
56+
Data $directoryHelper,
4857
array $data = []
4958
) {
5059
$this->directoryHelper = $directoryHelper;
5160
$this->localeFormat = $localeFormat;
5261
$this->weightSwitcher = $factoryElement->create('radios');
5362
$this->weightSwitcher->setValue(
54-
WeightResolver::HAS_WEIGHT
63+
WeightResolver::HAS_NO_WEIGHT
5564
)->setValues(
5665
[
5766
['value' => WeightResolver::HAS_WEIGHT, 'label' => __('Yes')],
@@ -75,28 +84,48 @@ public function __construct(
7584
*/
7685
public function getElementHtml()
7786
{
78-
if (!$this->getForm()->getDataObject()->getTypeInstance()->hasWeight()) {
79-
$this->weightSwitcher->setValue(WeightResolver::HAS_NO_WEIGHT);
87+
if ($this->getForm()->getDataObject()->getTypeInstance()->hasWeight()) {
88+
$this->weightSwitcher->setValue(WeightResolver::HAS_WEIGHT);
8089
}
90+
8191
if ($this->getDisabled()) {
8292
$this->weightSwitcher->setDisabled($this->getDisabled());
8393
}
84-
return '<div class="admin__field-control weight-switcher">' .
85-
'<div class="admin__control-switcher" data-role="weight-switcher">' .
86-
$this->weightSwitcher->getLabelHtml() .
87-
'<div class="admin__field-control-group">' .
88-
$this->weightSwitcher->getElementHtml() .
89-
'</div>' .
90-
'</div>' .
91-
'<div class="admin__control-addon">' .
92-
parent::getElementHtml() .
93-
'<label class="admin__addon-suffix" for="' .
94-
$this->getHtmlId() .
95-
'"><span>' .
96-
$this->directoryHelper->getWeightUnit() .
97-
'</span></label>' .
98-
'</div>' .
99-
'</div>';
94+
95+
$htmlId = $this->getHtmlId();
96+
$html = '';
97+
98+
if ($beforeElementHtml = $this->getBeforeElementHtml()) {
99+
$html .= '<label class="addbefore" for="' . $htmlId . '">' . $beforeElementHtml . '</label>';
100+
}
101+
102+
$html .= '<div class="admin__control-addon">';
103+
104+
if (is_array($this->getValue())) {
105+
foreach ($this->getValue() as $value) {
106+
$html .= $this->getHtmlForInputByValue($this->_escape($value));
107+
}
108+
} else {
109+
$html .= $this->getHtmlForInputByValue($this->getEscapedValue());
110+
}
111+
112+
$html .= '<label class="admin__addon-suffix" for="' .
113+
$this->getHtmlId() .
114+
'"><span>' .
115+
$this->directoryHelper->getWeightUnit() .
116+
'</span></label></div>';
117+
118+
if ($afterElementJs = $this->getAfterElementJs()) {
119+
$html .= $afterElementJs;
120+
}
121+
122+
if ($afterElementHtml = $this->getAfterElementHtml()) {
123+
$html .= '<label class="addafter" for="' . $htmlId . '">' . $afterElementHtml . '</label>';
124+
}
125+
126+
$html .= $this->getHtmlForWeightSwitcher();
127+
128+
return $html;
100129
}
101130

102131
/**
@@ -112,8 +141,7 @@ public function setForm($form)
112141
}
113142

114143
/**
115-
* @param null|int|string $index
116-
* @return null|string
144+
* @inheritDoc
117145
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
118146
*/
119147
public function getEscapedValue($index = null)
@@ -134,4 +162,53 @@ public function getEscapedValue($index = null)
134162

135163
return $value;
136164
}
165+
166+
/**
167+
* Get input html by sting value.
168+
*
169+
* @param string|null $value
170+
*
171+
* @return string
172+
*/
173+
private function getHtmlForInputByValue($value)
174+
{
175+
return '<input id="' . $this->getHtmlId() . '" name="' . $this->getName() . '" ' . $this->_getUiId()
176+
. ' value="' . $value . '" ' . $this->serialize($this->getHtmlAttributes()) . '/>';
177+
}
178+
179+
/**
180+
* Get weight switcher html.
181+
*
182+
* @return string
183+
*/
184+
private function getHtmlForWeightSwitcher()
185+
{
186+
$html = '<div class="admin__control-addon">';
187+
$html .= '<div class="admin__field-control weight-switcher">' .
188+
'<div class="admin__control-switcher" data-role="weight-switcher">' .
189+
$this->weightSwitcher->getLabelHtml() .
190+
'<div class="admin__field-control-group">' .
191+
$this->weightSwitcher->getElementHtml() .
192+
'</div>' .
193+
'</div>';
194+
195+
$html .= '<label class="addafter">';
196+
$elementId = ProductAttributeInterface::CODE_HAS_WEIGHT;
197+
$nameAttributeHtml = 'name="' . $elementId . '_checkbox"';
198+
$dataCheckboxName = "toggle_{$elementId}";
199+
$checkboxLabel = __('Change');
200+
$html .= <<<HTML
201+
<span class="attribute-change-checkbox">
202+
<input type="checkbox" id="$dataCheckboxName" name="$dataCheckboxName" class="checkbox" $nameAttributeHtml
203+
onclick="toogleFieldEditMode(this, 'weight-switcher1'); toogleFieldEditMode(this, 'weight-switcher0');" />
204+
<label class="label" for="$dataCheckboxName">
205+
{$checkboxLabel}
206+
</label>
207+
</span>
208+
HTML;
209+
210+
$html .= '</label></div></div>';
211+
212+
return $html;
213+
}
137214
}

app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
namespace Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute;
88

99
use Magento\AsynchronousOperations\Api\Data\OperationInterface;
10+
use Magento\Catalog\Api\Data\ProductAttributeInterface;
1011
use Magento\Eav\Model\Config;
1112
use Magento\Framework\App\Action\HttpPostActionInterface;
1213
use Magento\Backend\App\Action;
1314
use Magento\Framework\App\ObjectManager;
1415
use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
1516

1617
/**
17-
* Class Save
18+
* Class used for saving mass updated products attributes.
1819
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1920
*/
2021
class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute implements HttpPostActionInterface
@@ -146,6 +147,10 @@ private function sanitizeProductAttributes($attributesData)
146147
$dateFormat = $this->timezone->getDateFormat(\IntlDateFormatter::SHORT);
147148

148149
foreach ($attributesData as $attributeCode => $value) {
150+
if ($attributeCode === ProductAttributeInterface::CODE_HAS_WEIGHT) {
151+
continue;
152+
}
153+
149154
$attribute = $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode);
150155
if (!$attribute->getAttributeId()) {
151156
unset($attributesData[$attributeCode]);

0 commit comments

Comments
 (0)