Skip to content

Commit c6326ec

Browse files
author
Volodymyr Kublytskyi
committed
Merge remote-tracking branch 'mainline/2.1-develop' into MAGETWO-83288-magento-magento2-12041
2 parents 90ea1c0 + bfd3bf6 commit c6326ec

File tree

93 files changed

+2879
-996
lines changed

Some content is hidden

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

93 files changed

+2879
-996
lines changed

app/code/Magento/Catalog/Block/Product/AbstractProduct.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public function __construct(\Magento\Catalog\Block\Product\Context $context, arr
124124
*/
125125
public function getAddToCartUrl($product, $additional = [])
126126
{
127-
if ($product->getTypeInstance()->hasRequiredOptions($product)) {
127+
if (!$product->getTypeInstance()->isPossibleBuyFromList($product)) {
128128
if (!isset($additional['_escape'])) {
129129
$additional['_escape'] = true;
130130
}

app/code/Magento/Catalog/Block/Product/View/Attributes.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,9 @@ public function getAdditionalData(array $excludeAttr = [])
8181
$attributes = $product->getAttributes();
8282
foreach ($attributes as $attribute) {
8383
if ($attribute->getIsVisibleOnFront() && !in_array($attribute->getAttributeCode(), $excludeAttr)) {
84-
$value = $attribute->getFrontend()->getValue($product);
85-
84+
if (is_array($value = $attribute->getFrontend()->getValue($product))) {
85+
continue;
86+
}
8687
if (!$product->hasData($attribute->getAttributeCode())) {
8788
$value = __('N/A');
8889
} elseif ((string)$value == '') {

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ public function getCalendarDateHtml()
8282
$yearStart = $this->_catalogProductOptionTypeDate->getYearStart();
8383
$yearEnd = $this->_catalogProductOptionTypeDate->getYearEnd();
8484

85+
$dateFormat = $this->_localeDate->getDateFormat(\IntlDateFormatter::SHORT);
86+
/** Escape invisible characters which are present in some locales and may corrupt formatting */
87+
$escapedDateFormat = preg_replace('/[^MmDdYy\/\.\-]/', '', $dateFormat);
8588
$calendar = $this->getLayout()->createBlock(
8689
'Magento\Framework\View\Element\Html\Date'
8790
)->setId(
@@ -93,7 +96,7 @@ public function getCalendarDateHtml()
9396
)->setImage(
9497
$this->getViewFileUrl('Magento_Theme::calendar.png')
9598
)->setDateFormat(
96-
$this->_localeDate->getDateFormat(\IntlDateFormatter::SHORT)
99+
$escapedDateFormat
97100
)->setValue(
98101
$value
99102
)->setYearsRange(

app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory as CustomOptionFactory;
99
use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory as ProductLinkFactory;
1010
use Magento\Catalog\Api\ProductRepositoryInterface\Proxy as ProductRepository;
11+
use Magento\Catalog\Model\Product;
1112
use Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks;
1213
use Magento\Catalog\Model\Product\Link\Resolver as LinkResolver;
1314
use Magento\Framework\App\ObjectManager;
@@ -112,14 +113,14 @@ public function __construct(
112113
/**
113114
* Initialize product from data
114115
*
115-
* @param \Magento\Catalog\Model\Product $product
116+
* @param Product $product
116117
* @param array $productData
117-
* @return \Magento\Catalog\Model\Product
118+
* @return Product
118119
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
119120
* @SuppressWarnings(PHPMD.NPathComplexity)
120121
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
121122
*/
122-
public function initializeFromData(\Magento\Catalog\Model\Product $product, array $productData)
123+
public function initializeFromData(Product $product, array $productData)
123124
{
124125
unset($productData['custom_attributes']);
125126
unset($productData['extension_attributes']);
@@ -195,36 +196,7 @@ public function initializeFromData(\Magento\Catalog\Model\Product $product, arra
195196
}
196197

197198
$product = $this->setProductLinks($product);
198-
199-
/**
200-
* Initialize product options
201-
*/
202-
if ($productOptions && !$product->getOptionsReadonly()) {
203-
// mark custom options that should to fall back to default value
204-
$options = $this->mergeProductOptions(
205-
$productOptions,
206-
$this->request->getPost('options_use_default')
207-
);
208-
$customOptions = [];
209-
foreach ($options as $customOptionData) {
210-
if (empty($customOptionData['is_delete'])) {
211-
if (empty($customOptionData['option_id'])) {
212-
$customOptionData['option_id'] = null;
213-
}
214-
215-
if (isset($customOptionData['values'])) {
216-
$customOptionData['values'] = array_filter($customOptionData['values'], function ($valueData) {
217-
return empty($valueData['is_delete']);
218-
});
219-
}
220-
221-
$customOption = $this->getCustomOptionFactory()->create(['data' => $customOptionData]);
222-
$customOption->setProductSku($product->getSku());
223-
$customOptions[] = $customOption;
224-
}
225-
}
226-
$product->setOptions($customOptions);
227-
}
199+
$product = $this->fillProductOptions($product, $productOptions);
228200

229201
$product->setCanSaveCustomOptions(
230202
!empty($productData['affect_product_custom_options']) && !$product->getOptionsReadonly()
@@ -236,10 +208,10 @@ public function initializeFromData(\Magento\Catalog\Model\Product $product, arra
236208
/**
237209
* Initialize product before saving
238210
*
239-
* @param \Magento\Catalog\Model\Product $product
240-
* @return \Magento\Catalog\Model\Product
211+
* @param Product $product
212+
* @return Product
241213
*/
242-
public function initialize(\Magento\Catalog\Model\Product $product)
214+
public function initialize(Product $product)
243215
{
244216
$productData = $this->request->getPost('product', []);
245217
return $this->initializeFromData($product, $productData);
@@ -248,11 +220,11 @@ public function initialize(\Magento\Catalog\Model\Product $product)
248220
/**
249221
* Setting product links
250222
*
251-
* @param \Magento\Catalog\Model\Product $product
252-
* @return \Magento\Catalog\Model\Product
223+
* @param Product $product
224+
* @return Product
253225
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
254226
*/
255-
protected function setProductLinks(\Magento\Catalog\Model\Product $product)
227+
protected function setProductLinks(Product $product)
256228
{
257229
$links = $this->getLinkResolver()->getLinks();
258230

@@ -454,4 +426,51 @@ private function getDateTimeFilter()
454426

455427
return $this->dateTimeFilter;
456428
}
429+
430+
/**
431+
* Fills $product with options from $productOptions array
432+
*
433+
* @param Product $product
434+
* @param array $productOptions
435+
* @return Product
436+
*/
437+
private function fillProductOptions(Product $product, array $productOptions)
438+
{
439+
if ($product->getOptionsReadonly()) {
440+
return $product;
441+
}
442+
if (empty($productOptions)) {
443+
return $product->setOptions([]);
444+
}
445+
// mark custom options that should to fall back to default value
446+
$options = $this->mergeProductOptions(
447+
$productOptions,
448+
$this->request->getPost('options_use_default')
449+
);
450+
$customOptions = [];
451+
foreach ($options as $customOptionData) {
452+
if (!empty($customOptionData['is_delete'])) {
453+
continue;
454+
}
455+
456+
if (empty($customOptionData['option_id'])) {
457+
$customOptionData['option_id'] = null;
458+
}
459+
if (isset($customOptionData['values'])) {
460+
$customOptionData['values'] = array_filter(
461+
$customOptionData['values'],
462+
function ($valueData) {
463+
return empty($valueData['is_delete']);
464+
}
465+
);
466+
}
467+
$customOption = $this->getCustomOptionFactory()->create(
468+
['data' => $customOptionData]
469+
);
470+
$customOption->setProductSku($product->getSku());
471+
$customOptions[] = $customOption;
472+
}
473+
474+
return $product->setOptions($customOptions);
475+
}
457476
}

app/code/Magento/Catalog/Model/Product/Option/Type/Date.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public function prepareForCart()
142142

143143
if ($this->_dateExists()) {
144144
if ($this->useCalendar()) {
145-
$timestamp += (new \DateTime($value['date']))->getTimestamp();
145+
$timestamp += $this->_localeDate->date($value['date'], null, true, false)->getTimestamp();
146146
} else {
147147
$timestamp += mktime(0, 0, 0, $value['month'], $value['day'], $value['year']);
148148
}

app/code/Magento/Catalog/Model/Product/Type/AbstractType.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,4 +1092,16 @@ public function getAssociatedProducts($product)
10921092
{
10931093
return [];
10941094
}
1095+
1096+
/**
1097+
* Check if product can be potentially buyed from the category page or some
1098+
* other list
1099+
*
1100+
* @param \Magento\Catalog\Model\Product $product
1101+
* @return bool
1102+
*/
1103+
public function isPossibleBuyFromList($product)
1104+
{
1105+
return !$this->hasRequiredOptions($product);
1106+
}
10951107
}

app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ public function testGetAddToCartPostParams()
195195
];
196196

197197
$this->typeInstanceMock->expects($this->once())
198-
->method('hasRequiredOptions')
198+
->method('isPossibleBuyFromList')
199199
->with($this->equalTo($this->productMock))
200-
->will($this->returnValue(false));
200+
->will($this->returnValue(true));
201201
$this->cartHelperMock->expects($this->any())
202202
->method('getAddUrl')
203203
->with($this->equalTo($this->productMock), $this->equalTo([]))

app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -719,9 +719,24 @@ private function assembleProductRepositoryMock($links)
719719
private function getOptionsData()
720720
{
721721
$optionsData = [
722-
'option1' => ['is_delete' => true, 'name' => 'name1', 'price' => 'price1', 'option_id' => ''],
723-
'option2' => ['is_delete' => false, 'name' => 'name1', 'price' => 'price1', 'option_id' => '13'],
724-
'option3' => ['is_delete' => false, 'name' => 'name1', 'price' => 'price1', 'option_id' => '14'],
722+
'option1' => [
723+
'is_delete' => true,
724+
'name' => 'name1',
725+
'price' => 'price1',
726+
'option_id' => '',
727+
],
728+
'option2' => [
729+
'is_delete' => false,
730+
'name' => 'name2',
731+
'price' => 'price1',
732+
'option_id' => '13',
733+
],
734+
'option3' => [
735+
'is_delete' => false,
736+
'name' => 'name1',
737+
'price' => 'price1',
738+
'option_id' => '14',
739+
],
725740
];
726741

727742
return $optionsData;

app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,6 @@ define([
1010
], function (DynamicRows, _, utils) {
1111
'use strict';
1212

13-
var maxId = 0,
14-
15-
/**
16-
* Stores max option_id value of the options from recordData once on initialization
17-
* @param {Array} data - array with records data
18-
*/
19-
initMaxId = function (data) {
20-
if (data && data.length) {
21-
maxId = _.max(data, function (record) {
22-
return parseInt(record['option_id'], 10) || 0;
23-
})['option_id'];
24-
maxId = parseInt(maxId, 10) || 0;
25-
}
26-
};
27-
2813
return DynamicRows.extend({
2914
defaults: {
3015
mappingSettings: {
@@ -39,18 +24,24 @@ define([
3924
identificationDRProperty: 'option_id'
4025
},
4126

42-
/** @inheritdoc */
43-
initialize: function () {
44-
this._super();
45-
initMaxId(this.recordData());
46-
47-
return this;
27+
/**
28+
* Cleans options' values from IDs because otherwise wrong IDs will be assigned.
29+
*
30+
* @param {Array} values
31+
* @private
32+
*/
33+
__cleanOptionValuesUp: function (values) {
34+
values.each(function (value) {
35+
delete value['option_id'];
36+
delete value['option_type_id'];
37+
});
4838
},
4939

5040
/** @inheritdoc */
5141
processingInsertData: function (data) {
5242
var options = [],
53-
currentOption;
43+
currentOption,
44+
self = this;
5445

5546
if (!data) {
5647
return;
@@ -65,7 +56,14 @@ define([
6556
if (currentOption.hasOwnProperty('sort_order')) {
6657
delete currentOption['sort_order'];
6758
}
68-
currentOption['option_id'] = ++maxId;
59+
60+
if (currentOption.hasOwnProperty('option_id')) {
61+
delete currentOption['option_id'];
62+
}
63+
64+
if (currentOption.values.length > 0) {
65+
self.__cleanOptionValuesUp(currentOption.values);
66+
}
6967
options.push(currentOption);
7068
});
7169
});
@@ -90,9 +88,7 @@ define([
9088

9189
/** @inheritdoc */
9290
processingAddChild: function (ctx, index, prop) {
93-
if (ctx && !_.isNumber(ctx['option_id'])) {
94-
ctx['option_id'] = ++maxId;
95-
} else if (!ctx) {
91+
if (!ctx) {
9692
this.showSpinner(true);
9793
this.addChild(ctx, index, prop);
9894

app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,17 @@ define([
8686
}
8787

8888
if (res.backUrl) {
89+
var eventData = {
90+
'form': form,
91+
'redirectParameters': []
92+
}
93+
// trigger global event, so other modules will be able add parameters to redirect url
94+
$('body').trigger('catalogCategoryAddToCartRedirect', eventData);
95+
if (eventData.redirectParameters.length > 0) {
96+
var parameters = res.backUrl.split('#');
97+
parameters.push(eventData.redirectParameters.join('&'));
98+
res.backUrl = parameters.join('#');
99+
}
89100
window.location = res.backUrl;
90101
return;
91102
}

0 commit comments

Comments
 (0)