Skip to content

Commit fdc06a4

Browse files
author
Korshenko, Oleksii(okorshenko)
committed
Merge pull request #367 from magento-tango/MAGETWO-48913
[Tango+Vanilla+Webdev] Product Page Update
2 parents 22cbf56 + 6907ef4 commit fdc06a4

File tree

532 files changed

+33752
-5292
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

532 files changed

+33752
-5292
lines changed

app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml

+3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ require([
3838

3939
$('#fileupload').fileupload({
4040
dataType: 'json',
41+
formData: {
42+
'form_key': window.FORM_KEY
43+
},
4144
dropZone: '[data-tab-panel=image-management]',
4245
sequentialUploads: true,
4346
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,

app/code/Magento/Bundle/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Bundle.php

+27-19
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function __construct(
7373
}
7474

7575
/**
76-
* Setting Bundle Items Data to product for father processing
76+
* Setting Bundle Items Data to product for further processing
7777
*
7878
* @param \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $subject
7979
* @param \Magento\Catalog\Model\Product $product
@@ -88,20 +88,27 @@ public function afterInitialize(
8888
\Magento\Catalog\Model\Product $product
8989
) {
9090
$compositeReadonly = $product->getCompositeReadonly();
91-
$selections = $this->request->getPost('bundle_selections');
92-
if ($selections && !$compositeReadonly) {
93-
$product->setBundleSelectionsData($selections);
94-
}
91+
$result['bundle_selections'] = $result['bundle_options'] = [];
92+
if (isset($this->request->getPost('bundle_options')['bundle_options'])) {
93+
foreach ($this->request->getPost('bundle_options')['bundle_options'] as $key => $option) {
94+
if (empty($option['bundle_selections'])) {
95+
continue;
96+
}
97+
$result['bundle_selections'][$key] = $option['bundle_selections'];
98+
unset($option['bundle_selections']);
99+
$result['bundle_options'][$key] = $option;
100+
}
101+
if ($result['bundle_selections'] && !$compositeReadonly) {
102+
$product->setBundleSelectionsData($result['bundle_selections']);
103+
}
95104

96-
$items = $this->request->getPost('bundle_options');
97-
if ($items && !$compositeReadonly) {
98-
$product->setBundleOptionsData($items);
105+
if ($result['bundle_options'] && !$compositeReadonly) {
106+
$product->setBundleOptionsData($result['bundle_options']);
107+
}
108+
$this->processBundleOptionsData($product);
109+
$this->processDynamicOptionsData($product);
99110
}
100111

101-
$this->processBundleOptionsData($product);
102-
103-
$this->processDynamicOptionsData($product);
104-
105112
$affectProductSelections = (bool)$this->request->getPost('affect_bundle_product_selections');
106113
$product->setCanSaveBundleSelections($affectProductSelections && !$compositeReadonly);
107114
return $product;
@@ -139,12 +146,13 @@ protected function processBundleOptionsData(\Magento\Catalog\Model\Product $prod
139146
}
140147
$link = $this->linkFactory->create(['data' => $linkData]);
141148

142-
if (array_key_exists('selection_price_value', $linkData)) {
143-
$link->setPrice($linkData['selection_price_value']);
144-
}
145-
146-
if (array_key_exists('selection_price_type', $linkData)) {
147-
$link->setPriceType($linkData['selection_price_type']);
149+
if ((int)$product->getPriceType() !== \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC) {
150+
if (array_key_exists('selection_price_value', $linkData)) {
151+
$link->setPrice($linkData['selection_price_value']);
152+
}
153+
if (array_key_exists('selection_price_type', $linkData)) {
154+
$link->setPriceType($linkData['selection_price_type']);
155+
}
148156
}
149157

150158
$linkProduct = $this->productRepository->getById($linkData['product_id']);
@@ -172,7 +180,7 @@ protected function processBundleOptionsData(\Magento\Catalog\Model\Product $prod
172180
*/
173181
protected function processDynamicOptionsData(\Magento\Catalog\Model\Product $product)
174182
{
175-
if ($product->getPriceType() !== \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC) {
183+
if ((int)$product->getPriceType() !== \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC) {
176184
return;
177185
}
178186

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Bundle\Model\Product\Attribute\Source\Price;
7+
8+
/**
9+
* Bundle Price Type Attribute Renderer
10+
*/
11+
class Type extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
12+
{
13+
/**
14+
* Get all options
15+
*
16+
* @return array
17+
*/
18+
public function getAllOptions()
19+
{
20+
if (null === $this->_options) {
21+
$this->_options = [
22+
['label' => __('Dynamic'), 'value' => 0],
23+
['label' => __('Fixed'), 'value' => 1],
24+
];
25+
}
26+
return $this->_options;
27+
}
28+
29+
/**
30+
* Get a text for option value
31+
*
32+
* @param string|integer $value
33+
* @return string|bool
34+
*/
35+
public function getOptionText($value)
36+
{
37+
foreach ($this->getAllOptions() as $option) {
38+
if ($option['value'] == $value) {
39+
return $option['label'];
40+
}
41+
}
42+
43+
return false;
44+
}
45+
}

app/code/Magento/Bundle/Model/Product/Attribute/Source/Price/View.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ public function getAllOptions()
3737
{
3838
if (null === $this->_options) {
3939
$this->_options = [
40-
['label' => __('As Low as'), 'value' => 1],
4140
['label' => __('Price Range'), 'value' => 0],
41+
['label' => __('As Low as'), 'value' => 1],
4242
];
4343
}
4444
return $this->_options;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Bundle\Model\Product\Attribute\Source\Shipment;
7+
8+
/**
9+
* Bundle Shipment Type Attribute Renderer
10+
*/
11+
class Type extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
12+
{
13+
/**
14+
* {@inheritdoc}
15+
*/
16+
public function getAllOptions()
17+
{
18+
if (null === $this->_options) {
19+
$this->_options = [
20+
['label' => __('Together'), 'value' => 0],
21+
['label' => __('Separately'), 'value' => 1],
22+
];
23+
}
24+
return $this->_options;
25+
}
26+
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
public function getOptionText($value)
31+
{
32+
foreach ($this->getAllOptions() as $option) {
33+
if ($option['value'] == $value) {
34+
return $option['label'];
35+
}
36+
}
37+
return false;
38+
}
39+
}

app/code/Magento/Bundle/Model/Product/SaveHandler.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function __construct(
5555
public function execute($entityType, $entity)
5656
{
5757
$bundleProductOptions = $entity->getExtensionAttributes()->getBundleProductOptions();
58-
if ($entity->getTypeId() !== 'bundle' || $bundleProductOptions === null) {
58+
if ($entity->getTypeId() !== 'bundle' || empty($bundleProductOptions)) {
5959
return $entity;
6060
}
6161
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Bundle\Setup;
7+
8+
use Magento\Catalog\Model\Product;
9+
use Magento\Framework\Setup\ModuleContextInterface;
10+
use Magento\Framework\Setup\ModuleDataSetupInterface;
11+
use Magento\Framework\Setup\UpgradeDataInterface;
12+
use Magento\Eav\Setup\EavSetupFactory;
13+
14+
class UpgradeData implements UpgradeDataInterface
15+
{
16+
/**
17+
* @var EavSetupFactory
18+
*/
19+
protected $eavSetupFactory;
20+
21+
/**
22+
* UpgradeData constructor
23+
*
24+
* @param EavSetupFactory $eavSetupFactory
25+
*/
26+
public function __construct(EavSetupFactory $eavSetupFactory)
27+
{
28+
$this->eavSetupFactory = $eavSetupFactory;
29+
}
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
35+
{
36+
$setup->startSetup();
37+
38+
if (version_compare($context->getVersion(), '2.0.2', '<')) {
39+
/** @var \Magento\Eav\Setup\EavSetup $eavSetup */
40+
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
41+
42+
$eavSetup->updateAttribute(Product::ENTITY, 'price_type', 'frontend_input', 'boolean');
43+
$eavSetup->updateAttribute(
44+
Product::ENTITY,
45+
'price_type',
46+
'source_model',
47+
'Magento\Bundle\Model\Product\Attribute\Source\Price\Type'
48+
);
49+
$eavSetup->updateAttribute(Product::ENTITY, 'sku_type', 'frontend_input', 'boolean');
50+
$eavSetup->updateAttribute(
51+
Product::ENTITY,
52+
'sku_type',
53+
'source_model',
54+
'Magento\Bundle\Model\Product\Attribute\Source\Price\Type'
55+
);
56+
$eavSetup->updateAttribute(Product::ENTITY, 'weight_type', 'frontend_input', 'boolean');
57+
$eavSetup->updateAttribute(
58+
Product::ENTITY,
59+
'weight_type',
60+
'source_model',
61+
'Magento\Bundle\Model\Product\Attribute\Source\Price\Type'
62+
);
63+
$eavSetup->updateAttribute(Product::ENTITY, 'shipment_type', 'frontend_input', 'select');
64+
$eavSetup->updateAttribute(Product::ENTITY, 'shipment_type', 'frontend_label', __('Ship Bundle Items'), 1);
65+
$eavSetup->updateAttribute(
66+
Product::ENTITY,
67+
'shipment_type',
68+
'source_model',
69+
'Magento\Bundle\Model\Product\Attribute\Source\Shipment\Type'
70+
);
71+
}
72+
73+
$setup->endSetup();
74+
}
75+
}

app/code/Magento/Bundle/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/BundleTest.php

+40-30
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ class BundleTest extends \PHPUnit_Framework_TestCase
2929
*/
3030
protected $subjectMock;
3131

32+
/**
33+
* @var array
34+
*/
35+
protected $bundleSelections;
36+
37+
/**
38+
* @var array
39+
*/
40+
protected $bundleOptionsRaw;
41+
42+
/**
43+
* @var array
44+
*/
45+
protected $bundleOptionsCleaned;
46+
3247
protected function setUp()
3348
{
3449
$this->requestMock = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false);
@@ -74,21 +89,35 @@ protected function setUp()
7489
$storeManager,
7590
$customOptionFactory
7691
);
92+
93+
$this->bundleSelections = [
94+
['postValue'],
95+
];
96+
$this->bundleOptionsRaw = [
97+
'bundle_options' => [
98+
[
99+
'title' => 'Test Option',
100+
'bundle_selections' => $this->bundleSelections,
101+
],
102+
],
103+
];
104+
$this->bundleOptionsCleaned = $this->bundleOptionsRaw['bundle_options'];
105+
unset($this->bundleOptionsCleaned[0]['bundle_selections']);
77106
}
78107

79108
public function testAfterInitializeIfBundleAnsCustomOptionsAndBundleSelectionsExist()
80109
{
81110
$productOptionsBefore = [0 => ['key' => 'value'], 1 => ['is_delete' => false]];
82-
$postValue = 'postValue';
83111
$valueMap = [
84-
['bundle_options', null, $postValue],
85-
['bundle_selections', null, $postValue],
112+
['bundle_options', null, $this->bundleOptionsRaw],
86113
['affect_bundle_product_selections', null, 1],
87114
];
88115
$this->requestMock->expects($this->any())->method('getPost')->will($this->returnValueMap($valueMap));
89116
$this->productMock->expects($this->any())->method('getCompositeReadonly')->will($this->returnValue(false));
90-
$this->productMock->expects($this->once())->method('setBundleOptionsData')->with($postValue);
91-
$this->productMock->expects($this->once())->method('setBundleSelectionsData')->with($postValue);
117+
$this->productMock->expects($this->once())
118+
->method('setBundleOptionsData')
119+
->with($this->bundleOptionsCleaned);
120+
$this->productMock->expects($this->once())->method('setBundleSelectionsData')->with([$this->bundleSelections]);
92121
$this->productMock->expects($this->once())->method('getPriceType')->will($this->returnValue(0));
93122
$this->productMock->expects($this->any())->method('getOptionsReadonly')->will($this->returnValue(false));
94123
$this->productMock->expects($this->once())->method('setCanSaveCustomOptions')->with(true);
@@ -106,40 +135,21 @@ public function testAfterInitializeIfBundleAnsCustomOptionsAndBundleSelectionsEx
106135

107136
public function testAfterInitializeIfBundleSelectionsAndCustomOptionsExist()
108137
{
109-
$postValue = 'postValue';
138+
$bundleOptionsRawWithoutSelections = $this->bundleOptionsRaw;
139+
$bundleOptionsRawWithoutSelections['bundle_options'][0]['bundle_selections'] = false;
110140
$valueMap = [
111-
['bundle_options', null, $postValue],
112-
['bundle_selections', null, false],
141+
['bundle_options', null, $bundleOptionsRawWithoutSelections],
113142
['affect_bundle_product_selections', null, false],
114143
];
115144
$this->requestMock->expects($this->any())->method('getPost')->will($this->returnValueMap($valueMap));
116145
$this->productMock->expects($this->any())->method('getCompositeReadonly')->will($this->returnValue(false));
117-
$this->productMock->expects($this->once())->method('setBundleOptionsData')->with($postValue);
146+
$this->productMock->expects($this->never())
147+
->method('setBundleOptionsData')
148+
->with($this->bundleOptionsCleaned);
118149
$this->productMock->expects($this->never())->method('setBundleSelectionsData');
119150
$this->productMock->expects($this->once())->method('getPriceType')->will($this->returnValue(2));
120151
$this->productMock->expects($this->any())->method('getOptionsReadonly')->will($this->returnValue(true));
121152
$this->productMock->expects($this->once())->method('setCanSaveBundleSelections')->with(false);
122153
$this->model->afterInitialize($this->subjectMock, $this->productMock);
123154
}
124-
125-
public function testAfterInitializeIfCustomAndBundleOptionNotExist()
126-
{
127-
$postValue = 'postValue';
128-
$valueMap = [
129-
['bundle_options', null, false],
130-
['bundle_selections', null, $postValue],
131-
['affect_bundle_product_selections', null, 1],
132-
];
133-
$this->requestMock->expects($this->any())->method('getPost')->will($this->returnValueMap($valueMap));
134-
$this->productMock->expects($this->any())->method('getCompositeReadonly')->will($this->returnValue(false));
135-
$this->productMock->expects($this->never())->method('setBundleOptionsData');
136-
$this->productMock->expects($this->once())->method('setBundleSelectionsData')->with($postValue);
137-
$this->productMock->expects($this->once())->method('getPriceType')->will($this->returnValue(0));
138-
$this->productMock->expects($this->any())->method('getOptionsReadonly')->will($this->returnValue(false));
139-
$this->productMock->expects($this->once())->method('setCanSaveCustomOptions')->with(true);
140-
$this->productMock->expects($this->once())->method('getProductOptions')->will($this->returnValue(false));
141-
$this->productMock->expects($this->never())->method('setProductOptions');
142-
$this->productMock->expects($this->once())->method('setCanSaveBundleSelections')->with(true);
143-
$this->model->afterInitialize($this->subjectMock, $this->productMock);
144-
}
145155
}

0 commit comments

Comments
 (0)