Skip to content

Commit 8b09e3a

Browse files
committed
Merge remote-tracking branch 'origin/2.2-develop' into MAGETWO-90727
2 parents 7f7783c + 899e950 commit 8b09e3a

File tree

17 files changed

+462
-63
lines changed

17 files changed

+462
-63
lines changed

app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
define([
88
'jquery',
99
'underscore',
10-
'mage/utils/wrapper',
1110
'Magento_Checkout/js/view/payment/default',
1211
'Magento_Braintree/js/view/payment/adapter',
1312
'Magento_Checkout/js/model/quote',
@@ -19,7 +18,6 @@ define([
1918
], function (
2019
$,
2120
_,
22-
wrapper,
2321
Component,
2422
Braintree,
2523
quote,
@@ -105,6 +103,12 @@ define([
105103
}
106104
});
107105

106+
quote.shippingAddress.subscribe(function () {
107+
if (self.isActive()) {
108+
self.reInitPayPal();
109+
}
110+
});
111+
108112
// for each component initialization need update property
109113
this.isReviewRequired(false);
110114
this.initClientConfig();
@@ -222,9 +226,8 @@ define([
222226

223227
/**
224228
* Re-init PayPal Auth Flow
225-
* @param {Function} callback - Optional callback
226229
*/
227-
reInitPayPal: function (callback) {
230+
reInitPayPal: function () {
228231
if (Braintree.checkout) {
229232
Braintree.checkout.teardown(function () {
230233
Braintree.checkout = null;
@@ -235,17 +238,6 @@ define([
235238
this.clientConfig.paypal.amount = this.grandTotalAmount;
236239
this.clientConfig.paypal.shippingAddressOverride = this.getShippingAddress();
237240

238-
if (callback) {
239-
this.clientConfig.onReady = wrapper.wrap(
240-
this.clientConfig.onReady,
241-
function (original, checkout) {
242-
this.clientConfig.onReady = original;
243-
original(checkout);
244-
callback();
245-
}.bind(this)
246-
);
247-
}
248-
249241
Braintree.setConfig(this.clientConfig);
250242
Braintree.setup();
251243
},
@@ -429,19 +421,17 @@ define([
429421
* Triggers when customer click "Continue to PayPal" button
430422
*/
431423
payWithPayPal: function () {
432-
this.reInitPayPal(function () {
433-
if (!additionalValidators.validate()) {
434-
return;
435-
}
424+
if (!additionalValidators.validate()) {
425+
return;
426+
}
436427

437-
try {
438-
Braintree.checkout.paypal.initAuthFlow();
439-
} catch (e) {
440-
this.messageContainer.addErrorMessage({
441-
message: $t('Payment ' + this.getTitle() + ' can\'t be initialized.')
442-
});
443-
}
444-
}.bind(this));
428+
try {
429+
Braintree.checkout.paypal.initAuthFlow();
430+
} catch (e) {
431+
this.messageContainer.addErrorMessage({
432+
message: $t('Payment ' + this.getTitle() + ' can\'t be initialized.')
433+
});
434+
}
445435
},
446436

447437
/**

app/code/Magento/Catalog/view/base/web/js/price-box.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@ define([
7878
pricesCode = [],
7979
priceValue, origin, finalPrice;
8080

81-
this.cache.additionalPriceObject = this.cache.additionalPriceObject || {};
81+
if (typeof newPrices !== 'undefined' && newPrices.hasOwnProperty('prices')) {
82+
this.cache.additionalPriceObject = {};
83+
} else {
84+
this.cache.additionalPriceObject = this.cache.additionalPriceObject || {};
85+
}
8286

8387
if (newPrices) {
8488
$.extend(this.cache.additionalPriceObject, newPrices);

app/code/Magento/CatalogImportExport/Model/Import/Product.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
129129
*/
130130
const COL_NAME = 'name';
131131

132+
/**
133+
* Column new_from_date.
134+
*/
135+
const COL_NEW_FROM_DATE = 'new_from_date';
136+
137+
/**
138+
* Column new_to_date.
139+
*/
140+
const COL_NEW_TO_DATE = 'new_to_date';
141+
132142
/**
133143
* Column product website.
134144
*/
@@ -292,7 +302,8 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
292302
ValidatorInterface::ERROR_MEDIA_PATH_NOT_ACCESSIBLE => 'Imported resource (image) does not exist in the local media storage',
293303
ValidatorInterface::ERROR_MEDIA_URL_NOT_ACCESSIBLE => 'Imported resource (image) could not be downloaded from external resource due to timeout or access permissions',
294304
ValidatorInterface::ERROR_INVALID_WEIGHT => 'Product weight is invalid',
295-
ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually'
305+
ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually',
306+
ValidatorInterface::ERROR_NEW_TO_DATE => 'Make sure new_to_date is later than or the same as new_from_date',
296307
];
297308

298309
/**
@@ -313,8 +324,8 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
313324
Product::COL_TYPE => 'product_type',
314325
Product::COL_PRODUCT_WEBSITES => 'product_websites',
315326
'status' => 'product_online',
316-
'news_from_date' => 'new_from_date',
317-
'news_to_date' => 'new_to_date',
327+
'news_from_date' => self::COL_NEW_FROM_DATE,
328+
'news_to_date' => self::COL_NEW_TO_DATE,
318329
'options_container' => 'display_product_options_in',
319330
'minimal_price' => 'map_price',
320331
'msrp' => 'msrp_price',
@@ -2477,6 +2488,20 @@ public function validateRow(array $rowData, $rowNum)
24772488
}
24782489
}
24792490
}
2491+
2492+
if (!empty($rowData[self::COL_NEW_FROM_DATE]) && !empty($rowData[self::COL_NEW_TO_DATE])
2493+
) {
2494+
$newFromTimestamp = strtotime($this->dateTime->formatDate($rowData[self::COL_NEW_FROM_DATE], false));
2495+
$newToTimestamp = strtotime($this->dateTime->formatDate($rowData[self::COL_NEW_TO_DATE], false));
2496+
if ($newFromTimestamp > $newToTimestamp) {
2497+
$this->addRowError(
2498+
ValidatorInterface::ERROR_NEW_TO_DATE,
2499+
$rowNum,
2500+
$rowData[self::COL_NEW_TO_DATE]
2501+
);
2502+
}
2503+
}
2504+
24802505
return !$this->getErrorAggregator()->isRowInvalid($rowNum);
24812506
}
24822507

app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ interface RowValidatorInterface extends \Magento\Framework\Validator\ValidatorIn
8585

8686
const ERROR_DUPLICATE_URL_KEY = 'duplicatedUrlKey';
8787

88+
const ERROR_NEW_TO_DATE = 'invalidNewToDateValue';
89+
8890
/**
8991
* Value that means all entities (e.g. websites, groups etc.)
9092
*/
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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\CatalogUrlRewrite\Plugin\Webapi\Controller\Rest;
10+
11+
use Magento\Catalog\Api\ProductRepositoryInterface;
12+
use Magento\Catalog\Model\Product;
13+
use Magento\Framework\Webapi\Rest\Request as RestRequest;
14+
use Magento\Webapi\Controller\Rest\InputParamsResolver as InputParamsResolverController;
15+
16+
/**
17+
* Plugin for InputParamsResolver
18+
*
19+
* Used to modify product data with save_rewrites_history flag
20+
*/
21+
class InputParamsResolver
22+
{
23+
/**
24+
* @var RestRequest
25+
*/
26+
private $request;
27+
28+
/**
29+
* @param RestRequest $request
30+
*/
31+
public function __construct(RestRequest $request)
32+
{
33+
$this->request = $request;
34+
}
35+
36+
/**
37+
* Add 'save_rewrites_history' param to the product data
38+
*
39+
* @see \Magento\CatalogUrlRewrite\Plugin\Catalog\Controller\Adminhtml\Product\Initialization\Helper
40+
* @param InputParamsResolverController $subject
41+
* @param array $result
42+
* @return array
43+
*/
44+
public function afterResolve(InputParamsResolverController $subject, array $result): array
45+
{
46+
$route = $subject->getRoute();
47+
$serviceMethodName = $route->getServiceMethod();
48+
$serviceClassName = $route->getServiceClass();
49+
$requestBodyParams = $this->request->getBodyParams();
50+
51+
if ($this->isProductSaveCalled($serviceClassName, $serviceMethodName)
52+
&& $this->isCustomAttributesExists($requestBodyParams)) {
53+
foreach ($requestBodyParams['product']['custom_attributes'] as $attribute) {
54+
if ($attribute['attribute_code'] === 'save_rewrites_history') {
55+
foreach ($result as $resultItem) {
56+
if ($resultItem instanceof Product) {
57+
$resultItem->setData('save_rewrites_history', (bool)$attribute['value']);
58+
break 2;
59+
}
60+
}
61+
break;
62+
}
63+
}
64+
}
65+
return $result;
66+
}
67+
68+
/**
69+
* Check that product save method called
70+
*
71+
* @param string $serviceClassName
72+
* @param string $serviceMethodName
73+
* @return bool
74+
*/
75+
private function isProductSaveCalled(string $serviceClassName, string $serviceMethodName): bool
76+
{
77+
return $serviceClassName === ProductRepositoryInterface::class && $serviceMethodName === 'save';
78+
}
79+
80+
/**
81+
* Check is any custom options exists in product data
82+
*
83+
* @param array $requestBodyParams
84+
* @return bool
85+
*/
86+
private function isCustomAttributesExists(array $requestBodyParams): bool
87+
{
88+
return !empty($requestBodyParams['product']['custom_attributes']);
89+
}
90+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
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\CatalogUrlRewrite\Test\Unit\Plugin\Webapi\Controller\Rest;
10+
11+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
12+
use Magento\Webapi\Controller\Rest\InputParamsResolver;
13+
use Magento\CatalogUrlRewrite\Plugin\Webapi\Controller\Rest\InputParamsResolver as InputParamsResolverPlugin;
14+
use Magento\Framework\Webapi\Rest\Request as RestRequest;
15+
use Magento\Catalog\Model\Product;
16+
use Magento\Webapi\Controller\Rest\Router\Route;
17+
use Magento\Catalog\Api\ProductRepositoryInterface;
18+
use PHPUnit_Framework_MockObject_MockObject as MockObject;
19+
20+
/**
21+
* Unit test for InputParamsResolver plugin
22+
*/
23+
class InputParamsResolverTest extends \PHPUnit\Framework\TestCase
24+
{
25+
/**
26+
* @var string
27+
*/
28+
private $saveRewritesHistory;
29+
30+
/**
31+
* @var array
32+
*/
33+
private $requestBodyParams;
34+
35+
/**
36+
* @var array
37+
*/
38+
private $result;
39+
40+
/**
41+
* @var ObjectManager
42+
*/
43+
private $objectManager;
44+
45+
/**
46+
* @var InputParamsResolver|MockObject
47+
*/
48+
private $subject;
49+
50+
/**
51+
* @var RestRequest|MockObject
52+
*/
53+
private $request;
54+
55+
/**
56+
* @var Product|MockObject
57+
*/
58+
private $product;
59+
60+
/**
61+
* @var Route|MockObject
62+
*/
63+
private $route;
64+
65+
/**
66+
* @var InputParamsResolverPlugin
67+
*/
68+
private $plugin;
69+
70+
/**
71+
* @inheritdoc
72+
*/
73+
protected function setUp()
74+
{
75+
$this->saveRewritesHistory = 'save_rewrites_history';
76+
$this->requestBodyParams = [
77+
'product' => [
78+
'sku' => 'test',
79+
'custom_attributes' => [
80+
[
81+
'attribute_code' => $this->saveRewritesHistory,
82+
'value' => 1
83+
]
84+
]
85+
]
86+
];
87+
88+
$this->route = $this->createPartialMock(Route::class, ['getServiceMethod', 'getServiceClass']);
89+
$this->request = $this->createPartialMock(RestRequest::class, ['getBodyParams']);
90+
$this->request->method('getBodyParams')
91+
->willReturn($this->requestBodyParams);
92+
$this->subject = $this->createPartialMock(InputParamsResolver::class, ['getRoute']);
93+
$this->subject->method('getRoute')
94+
->willReturn($this->route);
95+
$this->product = $this->createPartialMock(Product::class, ['setData']);
96+
97+
$this->result = [false, $this->product, 'test'];
98+
99+
$this->objectManager = new ObjectManager($this);
100+
$this->plugin = $this->objectManager->getObject(
101+
InputParamsResolverPlugin::class,
102+
[
103+
'request' => $this->request
104+
]
105+
);
106+
}
107+
108+
public function testAfterResolve()
109+
{
110+
$this->route->method('getServiceClass')
111+
->willReturn(ProductRepositoryInterface::class);
112+
$this->route->method('getServiceMethod')
113+
->willReturn('save');
114+
$this->product->expects($this->once())
115+
->method('setData')
116+
->with($this->saveRewritesHistory, true);
117+
118+
$this->plugin->afterResolve($this->subject, $this->result);
119+
}
120+
}

app/code/Magento/CatalogUrlRewrite/composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
"magento/framework": "101.0.*",
1414
"magento/module-ui": "101.0.*"
1515
},
16+
"suggest": {
17+
"magento/module-webapi": "*"
18+
},
1619
"type": "magento2-module",
1720
"version": "100.2.5",
1821
"license": [

app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
99
<preference for="Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator" type="Magento\CatalogUrlRewrite\Model\WebapiProductUrlPathGenerator"/>
10+
<type name="Magento\Webapi\Controller\Rest\InputParamsResolver">
11+
<plugin name="product_save_rewrites_history_rest_plugin" type="Magento\CatalogUrlRewrite\Plugin\Webapi\Controller\Rest\InputParamsResolver" sortOrder="1" disabled="false" />
12+
</type>
1013
</config>

0 commit comments

Comments
 (0)