Skip to content

Commit 32353b8

Browse files
committed
Merge remote-tracking branch 'origin/MC-37922' into 2.4-develop-pr112
2 parents 74029c3 + 6300c09 commit 32353b8

File tree

3 files changed

+112
-5
lines changed

3 files changed

+112
-5
lines changed

app/code/Magento/ImportExport/Controller/Adminhtml/ImportResult.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use Magento\ImportExport\Model\Import\Entity\AbstractEntity;
1010
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;
1111
use Magento\ImportExport\Model\History as ModelHistory;
12+
use Magento\Framework\Escaper;
13+
use Magento\Framework\App\ObjectManager;
1214

1315
/**
1416
* Import controller
@@ -37,22 +39,31 @@ abstract class ImportResult extends Import
3739
*/
3840
protected $reportHelper;
3941

42+
/**
43+
* @var Escaper|null
44+
*/
45+
protected $escaper;
46+
4047
/**
4148
* @param \Magento\Backend\App\Action\Context $context
4249
* @param \Magento\ImportExport\Model\Report\ReportProcessorInterface $reportProcessor
4350
* @param \Magento\ImportExport\Model\History $historyModel
4451
* @param \Magento\ImportExport\Helper\Report $reportHelper
52+
* @param Escaper|null $escaper
4553
*/
4654
public function __construct(
4755
\Magento\Backend\App\Action\Context $context,
4856
\Magento\ImportExport\Model\Report\ReportProcessorInterface $reportProcessor,
4957
\Magento\ImportExport\Model\History $historyModel,
50-
\Magento\ImportExport\Helper\Report $reportHelper
58+
\Magento\ImportExport\Helper\Report $reportHelper,
59+
Escaper $escaper = null
5160
) {
5261
parent::__construct($context);
5362
$this->reportProcessor = $reportProcessor;
5463
$this->historyModel = $historyModel;
5564
$this->reportHelper = $reportHelper;
65+
$this->escaper = $escaper
66+
?? ObjectManager::getInstance()->get(Escaper::class);
5667
}
5768

5869
/**
@@ -69,28 +80,30 @@ protected function addErrorMessages(
6980
if ($errorAggregator->getErrorsCount()) {
7081
$message = '';
7182
$counter = 0;
83+
$escapedMessages = [];
7284
foreach ($this->getErrorMessages($errorAggregator) as $error) {
73-
$message .= (++$counter) . '. ' . $error . '<br>';
85+
$escapedMessages[] = (++$counter) . '. ' . $this->escaper->escapeHtml($error);
7486
if ($counter >= self::LIMIT_ERRORS_MESSAGE) {
7587
break;
7688
}
7789
}
7890
if ($errorAggregator->hasFatalExceptions()) {
7991
foreach ($this->getSystemExceptions($errorAggregator) as $error) {
80-
$message .= $error->getErrorMessage()
92+
$escapedMessages[] = $this->escaper->escapeHtml($error->getErrorMessage())
8193
. ' <a href="#" onclick="$(this).next().show();$(this).hide();return false;">'
8294
. __('Show more') . '</a><div style="display:none;">' . __('Additional data') . ': '
83-
. $error->getErrorDescription() . '</div>';
95+
. $this->escaper->escapeHtml($error->getErrorDescription()) . '</div>';
8496
}
8597
}
8698
try {
99+
$message .= implode('<br>', $escapedMessages);
87100
$resultBlock->addNotice(
88101
'<strong>' . __('Following Error(s) has been occurred during importing process:') . '</strong><br>'
89102
. '<div class="import-error-wrapper">' . __('Only the first 100 errors are shown. ')
90103
. '<a href="'
91104
. $this->createDownloadUrlImportHistoryFile($this->createErrorReport($errorAggregator))
92105
. '">' . __('Download full report') . '</a><br>'
93-
. '<div class="import-error-list">' . $resultBlock->escapeHtml($message) . '</div></div>'
106+
. '<div class="import-error-list">' . $message . '</div></div>'
94107
);
95108
} catch (\Exception $e) {
96109
foreach ($this->getErrorMessages($errorAggregator) as $errorMessage) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
sku,_store,_attribute_set,product_type,categories,_product_websites,color,cost,country_of_manufacture,created_at,custom_design,custom_design_from,custom_design_to,custom_layout_update,description,gallery,gift_message_available,gift_wrapping_available,gift_wrapping_price,has_options,image,image_label,is_returnable,manufacturer,meta_description,meta_keyword,meta_title,minimal_price,msrp,msrp_display_actual_price_type,name,news_from_date,news_to_date,options_container,page_layout,price,quantity_and_stock_status,related_tgtr_position_behavior,related_tgtr_position_limit,required_options,short_description,small_image,small_image_label,special_from_date,special_price,special_to_date,status,tax_class_id,thumbnail,thumbnail_label,updated_at,upsell_tgtr_position_behavior,upsell_tgtr_position_limit,url_key,url_path,visibility,weight,qty,min_qty,use_config_min_qty,is_qty_decimal,backorders,use_config_backorders,min_sale_qty,use_config_min_sale_qty,max_sale_qty,use_config_max_sale_qty,is_in_stock,notify_stock_qty,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,_related_sku,_related_position,_crosssell_sku,_crosssell_position,_upsell_sku,_upsell_position,_tier_price_website,_tier_price_customer_group,_tier_price_qty,_tier_price_price,_media_attribute_id,_media_image,_media_label,_media_position,_media_is_disabled,_associated_sku,_associated_default_qty,_associated_position
2+
"",,Default,simple,,base,,,,"2014-12-25 19:52:47",,,,,,,,,,0,,,"No",,"simple product 1 ","simple product 1","simple product 1",,,,"simple product 1",,,"Block after Info Column",,100.0000,"In Stock",,,0,,,,,,,1,2,,,"2014-12-25 19:52:47",,,simple-product-1,,"catalog, search",,123.0000,0.0000,1,0,0,1,1.0000,1,0.0000,1,1,,1,1,0,1,0.0000,1,0,0,1,,,,,,,,,,,,,,,,,,
3+
"",,Default,simple,,base,,,,"2014-12-25 19:53:14",,,,,,,,,,0,,,"No",,"simple product 2 ","simple product 2","simple product 2",,,,"simple product 2",,,"Block after Info Column",,200.0000,"In Stock",,,0,,,,,,,1,2,,,"2014-12-25 19:53:14",,,simple-product-2,,"catalog, search",,234.0000,0.0000,1,0,0,1,1.0000,1,0.0000,1,1,,1,1,0,1,0.0000,1,0,0,1,,,,,,,,,,,,,,,,,,
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ImportExport\Controller\Adminhtml;
9+
10+
use Magento\Framework\Filesystem\DirectoryList;
11+
use Magento\Framework\HTTP\Adapter\FileTransferFactory;
12+
use Magento\ImportExport\Model\Import;
13+
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;
14+
use Magento\ImportExport\Controller\Adminhtml\Import\HttpFactoryMock;
15+
16+
/**
17+
* Test for \Magento\ImportExport\Controller\Adminhtml\ImportResult class.
18+
*
19+
* @magentoAppArea adminhtml
20+
*/
21+
class ImportResultTest extends \Magento\TestFramework\TestCase\AbstractBackendController
22+
{
23+
/**
24+
* @param string $fileName
25+
* @param string $mimeType
26+
* @param string $delimiter
27+
* @backupGlobals enabled
28+
* @magentoDbIsolation enabled
29+
* @dataProvider validationDataProvider
30+
* @SuppressWarnings(PHPMD.Superglobals)
31+
*/
32+
public function testAddErrorMessages(string $fileName, string $mimeType, string $delimiter): void
33+
{
34+
$validationStrategy = ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_STOP_ON_ERROR;
35+
36+
$this->getRequest()->setParam('isAjax', true);
37+
$this->getRequest()->setMethod('POST');
38+
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
39+
40+
/** @var $formKey \Magento\Framework\Data\Form\FormKey */
41+
$formKey = $this->_objectManager->get(\Magento\Framework\Data\Form\FormKey::class);
42+
$this->getRequest()->setPostValue('form_key', $formKey->getFormKey());
43+
$this->getRequest()->setPostValue('entity', 'catalog_product');
44+
$this->getRequest()->setPostValue('behavior', 'append');
45+
$this->getRequest()->setPostValue(Import::FIELD_NAME_VALIDATION_STRATEGY, $validationStrategy);
46+
$this->getRequest()->setPostValue(Import::FIELD_NAME_ALLOWED_ERROR_COUNT, 0);
47+
$this->getRequest()->setPostValue('_import_field_separator', $delimiter);
48+
49+
/** @var \Magento\TestFramework\App\Filesystem $filesystem */
50+
$filesystem = $this->_objectManager->get(\Magento\Framework\Filesystem::class);
51+
$tmpDir = $filesystem->getDirectoryWrite(DirectoryList::SYS_TMP);
52+
$subDir = str_replace('\\', '_', __CLASS__);
53+
$tmpDir->create($subDir);
54+
$target = $tmpDir->getAbsolutePath("{$subDir}" . DIRECTORY_SEPARATOR . "{$fileName}");
55+
copy(__DIR__ . DIRECTORY_SEPARATOR . 'Import' . DIRECTORY_SEPARATOR . '_files'
56+
. DIRECTORY_SEPARATOR . "{$fileName}", $target);
57+
58+
$_FILES = [
59+
'import_file' => [
60+
'name' => $fileName,
61+
'type' => $mimeType,
62+
'tmp_name' => $target,
63+
'error' => 0,
64+
'size' => filesize($target)
65+
]
66+
];
67+
68+
$this->_objectManager->configure(
69+
[
70+
'preferences' => [FileTransferFactory::class => HttpFactoryMock::class]
71+
]
72+
);
73+
74+
$this->dispatch('backend/admin/import/validate');
75+
$this->assertStringNotContainsString('&lt;br&gt;', $this->getResponse()->getBody());
76+
}
77+
78+
/**
79+
* @return array
80+
*/
81+
public function validationDataProvider(): array
82+
{
83+
return [
84+
[
85+
'file_name' => 'invalid_catalog_products.csv',
86+
'mime-type' => 'text/csv',
87+
'delimiter' => ',',
88+
],
89+
];
90+
}
91+
}

0 commit comments

Comments
 (0)