Skip to content

Commit e7cb393

Browse files
author
Oleksii Korshenko
authored
Merge pull request #413 from magento-dragons/092016-pr-2.1
Fixed issues: - MAGETWO-56944: Image does not save when edited via right-click and "Insert/Edit Image" - MAGETWO-56018: [GitHub] Fail to import custom options #5573 - MAGETWO-57035: [Backport] - Unable to upload change robots.txt file via admin panel - for 2.1 - MAGETWO-56922: [Backport] - [GitHub] When tier price qty above 1000 adds a thousand separator in the Admin Panel #5745
2 parents d7e0eb4 + ba4be84 commit e7cb393

File tree

8 files changed

+141
-84
lines changed

8 files changed

+141
-84
lines changed

app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ protected function getOptionsGridConfig($sortOrder)
362362
'collapsibleHeader' => true,
363363
'sortOrder' => $sortOrder,
364364
'dataProvider' => static::CUSTOM_OPTIONS_LISTING,
365-
'links' => ['insertData' => '${ $.provider }:${ $.dataProvider }'],
365+
'imports' => ['insertData' => '${ $.provider }:${ $.dataProvider }'],
366366
],
367367
],
368368
],
@@ -478,7 +478,7 @@ protected function getImportOptionsModalConfig()
478478
'render_url' => $this->urlBuilder->getUrl('mui/index/render'),
479479
'realTimeLink' => true,
480480
'behaviourType' => 'edit',
481-
'externalFilterMode' => true,
481+
'externalFilterMode' => false,
482482
'currentProductId' => $this->locator->getProduct()->getId(),
483483
'dataLinks' => [
484484
'imports' => false,

app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
use Magento\Catalog\Model\Locator\LocatorInterface;
1010
use Magento\Ui\Component\Form;
1111
use Magento\Framework\Stdlib\ArrayManager;
12-
use Magento\Store\Model\StoreManagerInterface;
1312
use Magento\Framework\Locale\CurrencyInterface;
1413

1514
/**
1615
* Data provider for main panel of product page
16+
*
17+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1718
*/
1819
class General extends AbstractModifier
1920
{
@@ -26,11 +27,6 @@ class General extends AbstractModifier
2627
* @var ArrayManager
2728
*/
2829
protected $arrayManager;
29-
30-
/**
31-
* @var StoreManagerInterface
32-
*/
33-
private $storeManager;
3430

3531
/**
3632
* @var CurrencyInterface
@@ -82,7 +78,7 @@ protected function customizeWeightFormat(array $data)
8278
$data = $this->arrayManager->replace(
8379
$path,
8480
$data,
85-
$this->formatNumber($this->arrayManager->get($path, $data))
81+
$this->formatWeight($this->arrayManager->get($path, $data))
8682
);
8783
}
8884

@@ -105,7 +101,7 @@ protected function customizeAdvancedPriceFormat(array $data)
105101
$value[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE] =
106102
$this->formatPrice($value[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE]);
107103
$value[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE_QTY] =
108-
$this->formatNumber((int)$value[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE_QTY]);
104+
(int)$value[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE_QTY];
109105
}
110106
}
111107

@@ -378,23 +374,6 @@ private function getLocaleCurrency()
378374
return $this->localeCurrency;
379375
}
380376

381-
/**
382-
* The getter function to get the store manager for real application code
383-
*
384-
* @return \Magento\Store\Model\StoreManagerInterface
385-
*
386-
* @deprecated
387-
*/
388-
private function getStoreManager()
389-
{
390-
if ($this->storeManager === null) {
391-
$this->storeManager =
392-
\Magento\Framework\App\ObjectManager::getInstance()->get(StoreManagerInterface::class);
393-
}
394-
return $this->storeManager;
395-
}
396-
397-
398377
/**
399378
* Format price according to the locale of the currency
400379
*
@@ -407,7 +386,7 @@ protected function formatPrice($value)
407386
return null;
408387
}
409388

410-
$store = $this->getStoreManager()->getStore();
389+
$store = $this->locator->getStore();
411390
$currency = $this->getLocaleCurrency()->getCurrency($store->getBaseCurrencyCode());
412391
$value = $currency->toCurrency($value, ['display' => \Magento\Framework\Currency::NO_SYMBOL]);
413392

@@ -428,7 +407,7 @@ protected function formatNumber($value)
428407

429408
$value = (float)$value;
430409
$precision = strlen(substr(strrchr($value, "."), 1));
431-
$store = $this->getStoreManager()->getStore();
410+
$store = $this->locator->getStore();
432411
$currency = $this->getLocaleCurrency()->getCurrency($store->getBaseCurrencyCode());
433412
$value = $currency->toCurrency($value, ['display' => \Magento\Framework\Currency::NO_SYMBOL,
434413
'precision' => $precision]);

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

Lines changed: 79 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,65 +4,109 @@
44
*/
55

66
define([
7-
'Magento_Ui/js/dynamic-rows/dynamic-rows',
7+
'Magento_Ui/js/dynamic-rows/dynamic-rows-grid',
8+
'underscore',
89
'mageUtils'
9-
], function (DynamicRows, utils) {
10+
], function (DynamicRows, _, utils) {
1011
'use strict';
1112

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+
1228
return DynamicRows.extend({
1329
defaults: {
14-
dataProvider: '',
15-
insertData: [],
16-
listens: {
17-
'insertData': 'processingInsertData'
18-
}
30+
mappingSettings: {
31+
enabled: false,
32+
distinct: false
33+
},
34+
update: true,
35+
map: {
36+
'option_id': 'option_id'
37+
},
38+
identificationProperty: 'option_id',
39+
identificationDRProperty: 'option_id'
1940
},
2041

21-
/**
22-
* Calls 'initObservable' of parent
23-
*
24-
* @returns {Object} Chainable.
25-
*/
26-
initObservable: function () {
27-
this._super()
28-
.observe([
29-
'insertData'
30-
]);
42+
/** @inheritdoc */
43+
initialize: function () {
44+
this._super();
45+
initMaxId(this.recordData());
3146

3247
return this;
3348
},
3449

35-
/**
36-
* Parsed data
37-
*
38-
* @param {Array} data - array with data
39-
* about selected records
40-
*/
50+
/** @inheritdoc */
4151
processingInsertData: function (data) {
42-
if (!data.length) {
43-
return false;
44-
}
52+
var options = [],
53+
currentOption;
4554

46-
data.each(function (options) {
47-
options.options.each(function (option) {
48-
var path = this.dataScope + '.' + this.index + '.' + this.recordIterator,
49-
curOption = utils.copy(option);
55+
if (!data) {
56+
return;
57+
}
58+
data.each(function (item) {
59+
if (!item.options) {
60+
return;
61+
}
62+
item.options.each(function (option) {
63+
currentOption = utils.copy(option);
5064

51-
if (curOption.hasOwnProperty('sort_order')) {
52-
delete curOption['sort_order'];
65+
if (currentOption.hasOwnProperty('sort_order')) {
66+
delete currentOption['sort_order'];
5367
}
68+
currentOption['option_id'] = ++maxId;
69+
options.push(currentOption);
70+
});
71+
});
5472

55-
this.source.set(path, curOption);
56-
this.addChild(curOption, false);
57-
}, this);
73+
if (!options.length) {
74+
return;
75+
}
76+
this.cacheGridData = options;
77+
options.each(function (opt) {
78+
this.mappingValue(opt);
5879
}, this);
80+
81+
this.insertData([]);
5982
},
6083

6184
/**
6285
* Set empty array to dataProvider
6386
*/
6487
clearDataProvider: function () {
6588
this.source.set(this.dataProvider, []);
89+
},
90+
91+
/** @inheritdoc */
92+
processingAddChild: function (ctx, index, prop) {
93+
if (ctx && !_.isNumber(ctx['option_id'])) {
94+
ctx['option_id'] = ++maxId;
95+
} else if (!ctx) {
96+
this.showSpinner(true);
97+
this.addChild(ctx, index, prop);
98+
99+
return;
100+
}
101+
102+
this._super(ctx, index, prop);
103+
},
104+
105+
/**
106+
* Mutes parent method
107+
*/
108+
updateInsertData: function () {
109+
return false;
66110
}
67111
});
68112
});

app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ define([
2323
listens: {
2424
'insertData': 'processingInsertData',
2525
'recordData': 'initElements setToInsertData'
26+
},
27+
mappingSettings: {
28+
enabled: true,
29+
distinct: true
2630
}
2731
},
2832

@@ -100,10 +104,20 @@ define([
100104
* @param {String|Number} recordId
101105
*/
102106
deleteRecord: function (index, recordId) {
107+
this._super();
108+
109+
this.updateInsertData(recordId);
110+
},
111+
112+
/**
113+
* Updates insertData when record is deleted
114+
*
115+
* @param {String|Number} recordId
116+
*/
117+
updateInsertData: function (recordId) {
103118
var data = this.getElementData(this.insertData(), recordId),
104119
prop = this.map[this.identificationDRProperty];
105120

106-
this._super();
107121
this.insertData(_.reject(this.source.get(this.dataProvider), function (recordData) {
108122
return ~~recordData[prop] === ~~data[prop];
109123
}, this));
@@ -163,7 +177,7 @@ define([
163177
var changes = [],
164178
tmpObj = {};
165179

166-
if (data.length !== this.relatedData) {
180+
if (data.length !== this.relatedData.length) {
167181
data.forEach(function (obj) {
168182
tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty];
169183

@@ -210,21 +224,27 @@ define([
210224
var obj = {},
211225
tmpObj = {};
212226

213-
_.each(this.map, function (prop, index) {
214-
obj[index] = !_.isUndefined(data[prop]) ? data[prop] : '';
215-
}, this);
227+
if (this.mappingSettings.enabled) {
228+
_.each(this.map, function (prop, index) {
229+
obj[index] = !_.isUndefined(data[prop]) ? data[prop] : '';
230+
}, this);
231+
} else {
232+
obj = data;
233+
}
216234

217-
tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty];
235+
if (this.mappingSettings.distinct) {
236+
tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty];
237+
238+
if (_.findWhere(this.recordData(), tmpObj)) {
239+
return false;
240+
}
241+
}
218242

219243
if (!obj.hasOwnProperty(this.positionProvider)) {
220244
this.setMaxPosition();
221245
obj[this.positionProvider] = this.maxPosition;
222246
}
223247

224-
if (_.findWhere(this.recordData(), tmpObj)) {
225-
return false;
226-
}
227-
228248
this.source.set(this.dataScope + '.' + this.index + '.' + this.recordData().length, obj);
229249
},
230250

lib/internal/Magento/Framework/Filesystem/Directory/Write.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
namespace Magento\Framework\Filesystem\Directory;
77

88
use Magento\Framework\Exception\FileSystemException;
9-
use Magento\Framework\Filesystem\DriverInterface;
109

1110
class Write extends Read implements WriteInterface
1211
{
@@ -40,7 +39,7 @@ public function __construct(
4039
}
4140

4241
/**
43-
* Check if directory is writable
42+
* Check if directory or file is writable
4443
*
4544
* @param string $path
4645
* @return void
@@ -49,7 +48,9 @@ public function __construct(
4948
protected function assertWritable($path)
5049
{
5150
if ($this->isWritable($path) === false) {
52-
$path = $this->getAbsolutePath($this->path, $path);
51+
$path = (!$this->driver->isFile($path))
52+
? $this->getAbsolutePath($this->path, $path)
53+
: $this->getAbsolutePath($path);
5354
throw new FileSystemException(new \Magento\Framework\Phrase('The path "%1" is not writable', [$path]));
5455
}
5556
}
@@ -238,12 +239,13 @@ public function isWritable($path = null)
238239
* @param string $path
239240
* @param string $mode
240241
* @return \Magento\Framework\Filesystem\File\WriteInterface
242+
* @throws \Magento\Framework\Exception\FileSystemException
241243
*/
242244
public function openFile($path, $mode = 'w')
243245
{
244246
$folder = dirname($path);
245247
$this->create($folder);
246-
$this->assertWritable($folder);
248+
$this->assertWritable($this->isExist($path) ? $path : $folder);
247249
$absolutePath = $this->driver->getAbsolutePath($this->path, $path);
248250
return $this->fileFactory->create($absolutePath, $this->driver, $mode);
249251
}

0 commit comments

Comments
 (0)