Skip to content

Commit 94def29

Browse files
authored
Merge branch '2.4-develop' into fix-for-issue-38315
2 parents 2a31ebf + 84e4b7b commit 94def29

File tree

186 files changed

+4771
-11444
lines changed

Some content is hidden

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

186 files changed

+4771
-11444
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
// phpcs:disable PHPCompatibility.Miscellaneous.RemovedAlternativePHPTags.MaybeASPOpenTagFound
88
/** @var $block \Magento\Backend\Block\Media\Uploader */
9+
/** @var \Magento\Framework\Escaper $escaper */
910
?>
1011

1112
<div id="<?= $block->getHtmlId() ?>" class="uploader"
@@ -19,9 +20,8 @@
1920
}'
2021
>
2122
<div class="fileinput-button form-buttons button">
22-
<span><?= $block->escapeHtml(__('Browse Files...')) ?></span>
23-
<input id="fileupload" type="file" name="<?= $block->escapeHtmlAttr($block->getConfig()->getFileField()) ?>"
24-
data-url="<?= $block->escapeHtmlAttr($block->getConfig()->getUrl()) ?>" multiple="multiple" />
23+
<span><?= $escaper->escapeHtml(__('Browse Files...')) ?></span>
24+
<div id="fileUploader" data-url="<?= $escaper->escapeHtmlAttr($block->getConfig()->getUrl()) ?>"></div>
2525
</div>
2626
<div class="clear"></div>
2727
<script id="<?= $block->getHtmlId() ?>-template" type="text/x-magento-template" data-template="uploader">

app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js

Lines changed: 124 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* See COPYING.txt for license details.
55
*/
66

7+
/* eslint-disable no-undef */
8+
79
/**
810
* @api
911
*/
@@ -15,11 +17,11 @@ define([
1517
'Magento_Ui/js/modal/alert',
1618
'Magento_Ui/js/form/element/file-uploader',
1719
'mage/translate',
18-
'jquery/file-uploader'
20+
'jquery/uppy-core'
1921
], function ($, mageTemplate, alert, FileUploader) {
2022
'use strict';
2123

22-
var fileUploader = new FileUploader({
24+
let fileUploader = new FileUploader({
2325
dataScope: '',
2426
isMultipleFiles: true
2527
});
@@ -33,113 +35,149 @@ define([
3335
* @private
3436
*/
3537
_create: function () {
36-
var self = this,
38+
let self = this,
39+
arrayFromObj = Array.from,
3740
progressTmpl = mageTemplate('[data-template="uploader"]'),
38-
isResizeEnabled = this.options.isResizeEnabled,
39-
resizeConfiguration = {
40-
action: 'resizeImage',
41-
maxWidth: this.options.maxWidth,
42-
maxHeight: this.options.maxHeight
41+
uploaderElement = '#fileUploader',
42+
targetElement = this.element.find('.fileinput-button.form-buttons')[0],
43+
uploadUrl = $(uploaderElement).attr('data-url'),
44+
fileId = null,
45+
allowedExt = ['jpeg', 'jpg', 'png', 'gif'],
46+
allowedResize = false,
47+
options = {
48+
proudlyDisplayPoweredByUppy: false,
49+
target: targetElement,
50+
hideUploadButton: true,
51+
hideRetryButton: true,
52+
hideCancelButton: true,
53+
inline: true,
54+
debug:true,
55+
showRemoveButtonAfterComplete: true,
56+
showProgressDetails: false,
57+
showSelectedFiles: false,
58+
hideProgressAfterFinish: true
4359
};
4460

45-
if (!isResizeEnabled) {
46-
resizeConfiguration = {
47-
action: 'resizeImage'
48-
};
49-
}
61+
$(document).on('click', uploaderElement ,function () {
62+
$(uploaderElement).closest('.fileinput-button.form-buttons')
63+
.find('.uppy-Dashboard-browse').trigger('click');
64+
});
5065

51-
this.element.find('input[type=file]').fileupload({
52-
dataType: 'json',
53-
formData: {
54-
'form_key': window.FORM_KEY
55-
},
56-
dropZone: this.element.find('input[type=file]').closest('[role="dialog"]'),
57-
sequentialUploads: true,
58-
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
59-
maxFileSize: this.options.maxFileSize,
60-
61-
/**
62-
* @param {Object} e
63-
* @param {Object} data
64-
*/
65-
add: function (e, data) {
66-
var fileSize,
66+
const uppy = new Uppy.Uppy({
67+
autoProceed: true,
68+
69+
onBeforeFileAdded: (currentFile) => {
70+
let fileSize,
6771
tmpl;
6872

69-
$.each(data.files, function (index, file) {
70-
fileSize = typeof file.size == 'undefined' ?
71-
$.mage.__('We could not detect a size.') :
72-
byteConvert(file.size);
73+
fileSize = typeof currentFile.size == 'undefined' ?
74+
$.mage.__('We could not detect a size.') :
75+
byteConvert(currentFile.size);
7376

74-
data.fileId = Math.random().toString(33).substr(2, 18);
77+
// check if file is allowed to upload and resize
78+
allowedResize = $.inArray(currentFile.extension, allowedExt) !== -1;
7579

76-
tmpl = progressTmpl({
77-
data: {
78-
name: file.name,
79-
size: fileSize,
80-
id: data.fileId
81-
}
82-
});
80+
if (!allowedResize) {
81+
fileUploader.aggregateError(currentFile.name,
82+
$.mage.__('Disallowed file type.'));
83+
fileUploader.onLoadingStop();
84+
return false;
85+
}
8386

84-
$(tmpl).appendTo(self.element);
85-
});
87+
fileId = Math.random().toString(33).substr(2, 18);
8688

87-
$(this).fileupload('process', data).done(function () {
88-
data.submit();
89+
tmpl = progressTmpl({
90+
data: {
91+
name: currentFile.name,
92+
size: fileSize,
93+
id: fileId
94+
}
8995
});
96+
97+
// code to allow duplicate files from same folder
98+
const modifiedFile = {
99+
...currentFile,
100+
id: currentFile.id + '-' + fileId,
101+
tempFileId: fileId
102+
};
103+
104+
$(tmpl).appendTo(self.element);
105+
return modifiedFile;
90106
},
91107

92-
/**
93-
* @param {Object} e
94-
* @param {Object} data
95-
*/
96-
done: function (e, data) {
97-
if (data.result && !data.result.error) {
98-
self.element.trigger('addItem', data.result);
99-
} else {
100-
fileUploader.aggregateError(data.files[0].name, data.result.error);
108+
meta: {
109+
'form_key': window.FORM_KEY,
110+
isAjax : true
111+
}
112+
});
113+
114+
// initialize Uppy upload
115+
uppy.use(Uppy.Dashboard, options);
116+
117+
// Resize Image as per configuration
118+
if (this.options.isResizeEnabled) {
119+
uppy.use(Uppy.Compressor, {
120+
maxWidth: this.options.maxWidth,
121+
maxHeight: this.options.maxHeight,
122+
quality: 0.92,
123+
beforeDraw() {
124+
if (!allowedResize) {
125+
this.abort();
126+
}
101127
}
128+
});
129+
}
102130

103-
self.element.find('#' + data.fileId).remove();
131+
// drop area for file upload
132+
uppy.use(Uppy.DropTarget, {
133+
target: targetElement,
134+
onDragOver: () => {
135+
// override Array.from method of legacy-build.min.js file
136+
Array.from = null;
104137
},
138+
onDragLeave: () => {
139+
Array.from = arrayFromObj;
140+
}
141+
});
105142

106-
/**
107-
* @param {Object} e
108-
* @param {Object} data
109-
*/
110-
progress: function (e, data) {
111-
var progress = parseInt(data.loaded / data.total * 100, 10),
112-
progressSelector = '#' + data.fileId + ' .progressbar-container .progressbar';
143+
// upload files on server
144+
uppy.use(Uppy.XHRUpload, {
145+
endpoint: uploadUrl,
146+
fieldName: 'image'
147+
});
113148

114-
self.element.find(progressSelector).css('width', progress + '%');
115-
},
149+
uppy.on('upload-success', (file, response) => {
150+
if (response.body && !response.body.error) {
151+
self.element.trigger('addItem', response.body);
152+
} else {
153+
fileUploader.aggregateError(file.name, response.body.error);
154+
}
116155

117-
/**
118-
* @param {Object} e
119-
* @param {Object} data
120-
*/
121-
fail: function (e, data) {
122-
var progressSelector = '#' + data.fileId;
123-
124-
self.element.find(progressSelector).removeClass('upload-progress').addClass('upload-failure')
125-
.delay(2000)
126-
.hide('highlight')
127-
.remove();
128-
},
156+
self.element.find('#' + file.tempFileId).remove();
157+
});
129158

130-
stop: fileUploader.uploaderConfig.stop
159+
uppy.on('upload-progress', (file, progress) => {
160+
let progressWidth = parseInt(progress.bytesUploaded / progress.bytesTotal * 100, 10),
161+
progressSelector = '#' + file.tempFileId + ' .progressbar-container .progressbar';
162+
163+
self.element.find(progressSelector).css('width', progressWidth + '%');
131164
});
132165

133-
this.element.find('input[type=file]').fileupload('option', {
134-
processQueue: [{
135-
action: 'loadImage',
136-
fileTypes: /^image\/(gif|jpeg|png)$/
137-
},
138-
resizeConfiguration,
139-
{
140-
action: 'saveImage'
141-
}]
166+
uppy.on('upload-error', (error, file) => {
167+
let progressSelector = '#' + file.tempFileId;
168+
169+
self.element.find(progressSelector).removeClass('upload-progress').addClass('upload-failure')
170+
.delay(2000)
171+
.hide('highlight')
172+
.remove();
142173
});
174+
175+
uppy.on('complete', () => {
176+
fileUploader.uploaderConfig.stop();
177+
$(window).trigger('reload.MediaGallery');
178+
Array.from = arrayFromObj;
179+
});
180+
143181
}
144182
});
145183

app/code/Magento/Catalog/Test/Fixture/Product.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class Product implements RevertibleDataFixtureInterface
5353
'media_gallery_entries' => [],
5454
'tier_prices' => [],
5555
'created_at' => null,
56-
'updated_at' => null,
56+
'updated_at' => null
5757
];
5858

5959
private const DEFAULT_PRODUCT_LINK_DATA = [

app/code/Magento/Catalog/Test/Fixture/ProductStock.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ class ProductStock implements DataFixtureInterface
2626
{
2727
private const DEFAULT_DATA = [
2828
'prod_id' => null,
29-
'prod_qty' => 1
29+
'prod_qty' => 1,
30+
'is_in_stock' => 1
3031
];
3132

3233
/**
@@ -67,8 +68,8 @@ public function apply(array $data = []): ?DataObject
6768
{
6869
$data = $this->dataMerger->merge(self::DEFAULT_DATA, $data);
6970
$stockItem = $this->stockRegistry->getStockItem($data['prod_id']);
70-
$stockItem->setData('is_in_stock', 1);
71-
$stockItem->setData('qty', 90);
71+
$stockItem->setData('is_in_stock', $data['is_in_stock']);
72+
$stockItem->setData('qty', $data['prod_qty']);
7273
$stockItem->setData('manage_stock', 1);
7374
$stockItem->save();
7475

app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminAddCustomAttributeToSelectedProductActionGroup.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<checkOption selector="{{AdminProductAttributeSetGridSection.selectFromAttributeResult(attributeCode)}}" stepKey="selectAttributeFromDisplayedResult"/>
2626
<click selector="{{AdminProductAttributeSetGridSection.addSelected}}" stepKey="clickAddSelectedButton" />
2727
<waitForPageLoad stepKey="waitForAttributesToBeAdded"/>
28-
<scrollTo selector="{{AdminProductFormSection.attributeTab}}" stepKey="scrollToAttributeTab" />
28+
<scrollTo selector="{{AdminProductFormSection.attributeTab}}" x="0" y="-100" stepKey="scrollToAttributeTab" />
2929
<click selector="{{AdminProductFormSection.attributeTab}}" stepKey="expandAttributeTab" />
3030
<selectOption selector="{{AdminProductFormSection.customSelectField(attributeCode)}}" userInput="{{adminOption1}}" stepKey="selectAvalueFromDropdown"/>
3131
<click selector="{{AdminProductFormSection.save}}" stepKey="saveTheProduct" />

app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<element name="sectionHeader" type="button" selector="div[data-index='content']" timeout="30"/>
1313
<element name="uploadButton" type="button" selector="//*[@class='file-uploader-area']/label[text()='Upload']"/>
1414
<element name="selectFromGalleryButton" type="button" selector="//*[@class='file-uploader-area']/label[text()='Select from Gallery']"/>
15-
<element name="uploadImageFile" type="input" selector=".file-uploader-area>input"/>
15+
<element name="uploadImageFile" type="input" selector=".file-uploader-area .uppy-Dashboard-input"/>
1616
<element name="imageFileName" type="text" selector=".file-uploader-filename"/>
1717
<element name="imageFileMeta" type="text" selector=".file-uploader-meta"/>
1818
<element name="removeImageButton" type="button" selector=".file-uploader-summary .action-remove"/>

app/code/Magento/Catalog/Test/Mftf/Section/AdminProductImagesSection.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
1111
<section name="AdminProductImagesSection">
1212
<element name="productImagesToggle" type="button" selector="div[data-index=gallery] .admin__collapsible-title"/>
13-
<element name="imageFileUpload" type="input" selector="#fileupload"/>
13+
<element name="imageFileUpload" type="input" selector="div.image div.fileinput-button .uppy-Dashboard-input"/>
1414
<element name="imageUploadButton" type="button" selector="div.image div.fileinput-button"/>
1515
<element name="imageFile" type="text" selector="//*[@id='media_gallery_content']//img[contains(@src, '{{url}}')]" parameterized="true"/>
1616
<element name="imageFileRoleByImage" type="text" selector="//*[@id='media_gallery_content']//img[contains(@src, '{{url}}')]/ancestor::div[@data-role='image']//*[@data-role-code='{{roleCode}}']" parameterized="true"/>

app/code/Magento/Catalog/Test/Mftf/Test/AddExistingProductAttributeFromProductPageTest.xml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,15 @@
4747
<actionGroup ref="NavigateToEditProductAttributeActionGroup" stepKey="goToAttributeEditPage">
4848
<argument name="ProductAttribute" value="Test Attribute"/>
4949
</actionGroup>
50-
<click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="clickDeleteAttribute" />
51-
<click selector="{{AttributeDeleteModalSection.confirm}}" stepKey="clickOkToConfirmDelete" />
52-
<waitForPageLoad stepKey="waitForDeletion"/>
50+
<actionGroup ref="DeleteProductAttributeByAttributeCodeActionGroup" stepKey="deleteProductAttribute"/>
51+
<comment userInput="BIC workaround" stepKey="clickDeleteAttribute"/>
52+
<comment userInput="BIC workaround" stepKey="clickOkToConfirmDelete"/>
53+
<comment userInput="BIC workaround" stepKey="waitForDeletion"/>
54+
55+
<!-- Reindex invalidated indices after product attribute has been created/deleted -->
56+
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexInvalidatedIndices">
57+
<argument name="indices" value=""/>
58+
</actionGroup>
5359

5460
<!-- Select the Default Category for Main Webstore -->
5561
<actionGroup ref="UpdateRootCategoryForStoresActionGroup" stepKey="UpdateRootCategoryForStores">

app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductAttributeTextSwatchFromProductPageTest.xml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,16 @@
2727
<actionGroup ref="NavigateToEditProductAttributeActionGroup" stepKey="goToEditPage">
2828
<argument name="ProductAttribute" value="{{textSwatchProductAttribute.attribute_code}}"/>
2929
</actionGroup>
30-
<click stepKey="clickDelete" selector="{{AttributePropertiesSection.DeleteAttribute}}"/>
31-
<click stepKey="clickOk" selector="{{AttributeDeleteModalSection.confirm}}"/>
32-
<waitForPageLoad stepKey="waitForDeletion"/>
30+
31+
<actionGroup ref="DeleteProductAttributeByAttributeCodeActionGroup" stepKey="deleteProductAttribute"/>
32+
<comment userInput="BIC workaround" stepKey="clickDelete"/>
33+
<comment userInput="BIC workaround" stepKey="clickOk"/>
34+
<comment userInput="BIC workaround" stepKey="waitForDeletion"/>
35+
<!-- Reindex invalidated indices after product attribute has been created/deleted -->
36+
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexInvalidatedIndices">
37+
<argument name="indices" value=""/>
38+
</actionGroup>
39+
3340
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
3441
</after>
3542

app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductAttributeVisualSwatchFromProductPageTest.xml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@
2727
<actionGroup ref="NavigateToEditProductAttributeActionGroup" stepKey="goToEditPage">
2828
<argument name="ProductAttribute" value="{{visualSwatchProductAttribute.attribute_code}}"/>
2929
</actionGroup>
30-
<click stepKey="clickDelete" selector="{{AttributePropertiesSection.DeleteAttribute}}"/>
31-
<click stepKey="clickOk" selector="{{AttributeDeleteModalSection.confirm}}"/>
32-
<waitForPageLoad stepKey="waitForDeletion"/>
30+
<actionGroup ref="DeleteProductAttributeByAttributeCodeActionGroup" stepKey="deleteProductAttribute"/>
31+
<comment userInput="BIC workaround" stepKey="clickDelete"/>
32+
<comment userInput="BIC workaround" stepKey="clickOk"/>
33+
<comment userInput="BIC workaround" stepKey="waitForDeletion"/>
34+
<!-- Reindex invalidated indices after product attribute has been created/deleted -->
35+
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexInvalidatedIndices">
36+
<argument name="indices" value=""/>
37+
</actionGroup>
3338
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
3439
</after>
3540

0 commit comments

Comments
 (0)