Skip to content

Commit 1fed886

Browse files
Merge branch '2.3-develop' into 2.3.6-develop
# Conflicts: # app/code/Magento/Theme/etc/di.xml
2 parents 6089855 + 0df6fcd commit 1fed886

File tree

812 files changed

+21010
-14473
lines changed

Some content is hidden

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

812 files changed

+21010
-14473
lines changed

app/code/Magento/Analytics/Model/ReportWriter.php

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

1111
/**
1212
* Writes reports in files in csv format
13-
* @inheritdoc
1413
*/
1514
class ReportWriter implements ReportWriterInterface
1615
{
@@ -54,7 +53,7 @@ public function __construct(
5453
}
5554

5655
/**
57-
* {@inheritdoc}
56+
* @inheritdoc
5857
*/
5958
public function write(WriteInterface $directory, $path)
6059
{
@@ -81,7 +80,7 @@ public function write(WriteInterface $directory, $path)
8180
$headers = array_keys($row);
8281
$stream->writeCsv($headers);
8382
}
84-
$stream->writeCsv($row);
83+
$stream->writeCsv($this->prepareRow($row));
8584
}
8685
$stream->unlock();
8786
$stream->close();
@@ -98,4 +97,18 @@ public function write(WriteInterface $directory, $path)
9897

9998
return true;
10099
}
100+
101+
/**
102+
* Replace wrong symbols in row
103+
*
104+
* @param array $row
105+
* @return array
106+
*/
107+
private function prepareRow(array $row): array
108+
{
109+
$row = preg_replace('/(?<!\\\\)"/', '\\"', $row);
110+
$row = preg_replace('/[\\\\]+/', '\\', $row);
111+
112+
return $row;
113+
}
101114
}

app/code/Magento/Analytics/Test/Unit/Model/ReportWriterTest.php

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,43 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Analytics\Test\Unit\Model;
79

810
use Magento\Analytics\Model\ConfigInterface;
911
use Magento\Analytics\Model\ProviderFactory;
1012
use Magento\Analytics\Model\ReportWriter;
1113
use Magento\Analytics\ReportXml\DB\ReportValidator;
1214
use Magento\Analytics\ReportXml\ReportProvider;
13-
use Magento\Framework\Filesystem\Directory\WriteInterface;
15+
use Magento\Framework\Filesystem\Directory\WriteInterface as DirectoryWriteInterface;
16+
use Magento\Framework\Filesystem\File\WriteInterface as FileWriteInterface;
1417
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
18+
use PHPUnit\Framework\MockObject\MockObject;
19+
use PHPUnit\Framework\TestCase;
1520

1621
/**
1722
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1823
*/
19-
class ReportWriterTest extends \PHPUnit\Framework\TestCase
24+
class ReportWriterTest extends TestCase
2025
{
2126
/**
22-
* @var ConfigInterface|\PHPUnit_Framework_MockObject_MockObject
27+
* @var ConfigInterface|MockObject
2328
*/
2429
private $configInterfaceMock;
2530

2631
/**
27-
* @var ReportValidator|\PHPUnit_Framework_MockObject_MockObject
32+
* @var ReportValidator|MockObject
2833
*/
2934
private $reportValidatorMock;
3035

3136
/**
32-
* @var ProviderFactory|\PHPUnit_Framework_MockObject_MockObject
37+
* @var ProviderFactory|MockObject
3338
*/
3439
private $providerFactoryMock;
3540

3641
/**
37-
* @var ReportProvider|\PHPUnit_Framework_MockObject_MockObject
42+
* @var ReportProvider|MockObject
3843
*/
3944
private $reportProviderMock;
4045

@@ -44,7 +49,7 @@ class ReportWriterTest extends \PHPUnit\Framework\TestCase
4449
private $objectManagerHelper;
4550

4651
/**
47-
* @var WriteInterface|\PHPUnit_Framework_MockObject_MockObject
52+
* @var DirectoryWriteInterface|MockObject
4853
*/
4954
private $directoryMock;
5055

@@ -80,7 +85,7 @@ protected function setUp()
8085
->disableOriginalConstructor()->getMock();
8186
$this->reportProviderMock = $this->getMockBuilder(ReportProvider::class)
8287
->disableOriginalConstructor()->getMock();
83-
$this->directoryMock = $this->getMockBuilder(WriteInterface::class)->getMockForAbstractClass();
88+
$this->directoryMock = $this->getMockBuilder(DirectoryWriteInterface::class)->getMockForAbstractClass();
8489
$this->objectManagerHelper = new ObjectManagerHelper($this);
8590

8691
$this->reportWriter = $this->objectManagerHelper->getObject(
@@ -95,16 +100,15 @@ protected function setUp()
95100

96101
/**
97102
* @param array $configData
103+
* @param array $fileData
104+
* @param array $expectedFileData
98105
* @return void
99106
*
100107
* @dataProvider configDataProvider
101108
*/
102-
public function testWrite(array $configData)
109+
public function testWrite(array $configData, array $fileData, array $expectedFileData)
103110
{
104111
$errors = [];
105-
$fileData = [
106-
['number' => 1, 'type' => 'Shoes Usual']
107-
];
108112
$this->configInterfaceMock
109113
->expects($this->once())
110114
->method('get')
@@ -123,7 +127,7 @@ public function testWrite(array $configData)
123127
->with($parameterName ?: null)
124128
->willReturn($fileData);
125129
$errorStreamMock = $this->getMockBuilder(
126-
\Magento\Framework\Filesystem\File\WriteInterface::class
130+
FileWriteInterface::class
127131
)->getMockForAbstractClass();
128132
$errorStreamMock
129133
->expects($this->once())
@@ -133,8 +137,8 @@ public function testWrite(array $configData)
133137
->expects($this->exactly(2))
134138
->method('writeCsv')
135139
->withConsecutive(
136-
[array_keys($fileData[0])],
137-
[$fileData[0]]
140+
[array_keys($expectedFileData[0])],
141+
[$expectedFileData[0]]
138142
);
139143
$errorStreamMock->expects($this->once())->method('unlock');
140144
$errorStreamMock->expects($this->once())->method('close');
@@ -166,7 +170,7 @@ public function testWriteErrorFile($configData)
166170
$errors = ['orders', 'SQL Error: test'];
167171
$this->configInterfaceMock->expects($this->once())->method('get')->willReturn([$configData]);
168172
$errorStreamMock = $this->getMockBuilder(
169-
\Magento\Framework\Filesystem\File\WriteInterface::class
173+
FileWriteInterface::class
170174
)->getMockForAbstractClass();
171175
$errorStreamMock->expects($this->once())->method('lock');
172176
$errorStreamMock->expects($this->once())->method('writeCsv')->with($errors);
@@ -196,7 +200,7 @@ public function configDataProvider()
196200
{
197201
return [
198202
'reportProvider' => [
199-
[
203+
'configData' => [
200204
'providers' => [
201205
[
202206
'name' => $this->providerName,
@@ -206,6 +210,12 @@ public function configDataProvider()
206210
],
207211
]
208212
]
213+
],
214+
'fileData' => [
215+
['number' => 1, 'type' => 'Shoes\"" Usual\\\\"']
216+
],
217+
'expectedFileData' => [
218+
['number' => 1, 'type' => 'Shoes\"\" Usual\\"']
209219
]
210220
],
211221
];

app/code/Magento/Backend/Block/Widget/Grid/Export.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use Magento\Framework\App\Filesystem\DirectoryList;
1010

1111
/**
12+
* Class Export for exporting grid data as CSV file or MS Excel 2003 XML Document file
13+
*
1214
* @api
1315
* @deprecated 100.2.0 in favour of UI component implementation
1416
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -69,6 +71,8 @@ public function __construct(
6971
}
7072

7173
/**
74+
* Internal constructor, that is called from real constructor
75+
*
7276
* @return void
7377
* @throws \Magento\Framework\Exception\LocalizedException
7478
*/
@@ -242,6 +246,7 @@ protected function _getExportTotals()
242246

243247
/**
244248
* Iterate collection and call callback method per item
249+
*
245250
* For callback method first argument always is item object
246251
*
247252
* @param string $callback
@@ -273,7 +278,12 @@ public function _exportIterateCollection($callback, array $args)
273278

274279
$collection = $this->_getRowCollection($originalCollection);
275280
foreach ($collection as $item) {
276-
call_user_func_array([$this, $callback], array_merge([$item], $args));
281+
//phpcs:ignore Magento2.Functions.DiscouragedFunction
282+
call_user_func_array(
283+
[$this, $callback],
284+
// phpcs:ignore Magento2.Performance.ForeachArrayMerge
285+
array_merge([$item], $args)
286+
);
277287
}
278288
}
279289
}
@@ -307,7 +317,7 @@ protected function _exportCsvItem(
307317
*/
308318
public function getCsvFile()
309319
{
310-
$name = md5(microtime());
320+
$name = hash('sha256', microtime());
311321
$file = $this->_path . '/' . $name . '.csv';
312322

313323
$this->_directory->create($this->_path);
@@ -432,11 +442,11 @@ public function getRowRecord(\Magento\Framework\DataObject $data)
432442
*/
433443
public function getExcelFile($sheetName = '')
434444
{
435-
$collection = $this->_getRowCollection();
445+
$collection = $this->_getPreparedCollection();
436446

437447
$convert = new \Magento\Framework\Convert\Excel($collection->getIterator(), [$this, 'getRowRecord']);
438448

439-
$name = md5(microtime());
449+
$name = hash('sha256', microtime());
440450
$file = $this->_path . '/' . $name . '.xml';
441451

442452
$this->_directory->create($this->_path);
@@ -551,6 +561,8 @@ public function _getPreparedCollection()
551561
}
552562

553563
/**
564+
* Get export page size
565+
*
554566
* @return int
555567
*/
556568
public function getExportPageSize()

app/code/Magento/Backend/Block/Widget/Grid/Extended.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
use Magento\Framework\App\Filesystem\DirectoryList;
99

1010
/**
11+
* Extended Grid Widget
12+
*
1113
* @api
1214
* @deprecated 100.2.0 in favour of UI component implementation
1315
* @SuppressWarnings(PHPMD.ExcessivePublicCount)
@@ -177,7 +179,10 @@ class Extended extends \Magento\Backend\Block\Widget\Grid implements \Magento\Ba
177179
protected $_path = 'export';
178180

179181
/**
182+
* Initialization
183+
*
180184
* @return void
185+
* @throws \Magento\Framework\Exception\FileSystemException
181186
*/
182187
protected function _construct()
183188
{
@@ -297,6 +302,7 @@ public function addColumn($columnId, $column)
297302
);
298303
$this->getColumnSet()->getChildBlock($columnId)->setGrid($this);
299304
} else {
305+
// phpcs:ignore Magento2.Exceptions.DirectThrow
300306
throw new \Exception(__('Please correct the column format and try again.'));
301307
}
302308

@@ -471,10 +477,6 @@ protected function _prepareMassactionColumn()
471477
protected function _prepareCollection()
472478
{
473479
if ($this->getCollection()) {
474-
if ($this->getCollection()->isLoaded()) {
475-
$this->getCollection()->clear();
476-
}
477-
478480
parent::_prepareCollection();
479481

480482
if (!$this->_isExport) {
@@ -663,6 +665,7 @@ public function setEmptyCellLabel($label)
663665
*/
664666
public function getRowUrl($item)
665667
{
668+
// phpstan:ignore "Call to an undefined static method"
666669
$res = parent::getRowUrl($item);
667670
return $res ? $res : '#';
668671
}
@@ -680,6 +683,7 @@ public function getMultipleRows($item)
680683

681684
/**
682685
* Retrieve columns for multiple rows
686+
*
683687
* @return array
684688
*/
685689
public function getMultipleRowColumns()
@@ -943,6 +947,7 @@ protected function _getExportTotals()
943947

944948
/**
945949
* Iterate collection and call callback method per item
950+
*
946951
* For callback method first argument always is item object
947952
*
948953
* @param string $callback
@@ -972,7 +977,12 @@ public function _exportIterateCollection($callback, array $args)
972977
$page++;
973978

974979
foreach ($collection as $item) {
975-
call_user_func_array([$this, $callback], array_merge([$item], $args));
980+
//phpcs:ignore Magento2.Functions.DiscouragedFunction
981+
call_user_func_array(
982+
[$this, $callback],
983+
// phpcs:ignore Magento2.Performance.ForeachArrayMerge
984+
array_merge([$item], $args)
985+
);
976986
}
977987
}
978988
}
@@ -1009,6 +1019,7 @@ public function getCsvFile()
10091019
$this->_isExport = true;
10101020
$this->_prepareGrid();
10111021

1022+
// phpcs:ignore Magento2.Security.InsecureFunction
10121023
$name = md5(microtime());
10131024
$file = $this->_path . '/' . $name . '.csv';
10141025

@@ -1153,6 +1164,7 @@ public function getExcelFile($sheetName = '')
11531164
[$this, 'getRowRecord']
11541165
);
11551166

1167+
// phpcs:ignore Magento2.Security.InsecureFunction
11561168
$name = md5(microtime());
11571169
$file = $this->_path . '/' . $name . '.xml';
11581170

@@ -1244,7 +1256,7 @@ public function setCollection($collection)
12441256
}
12451257

12461258
/**
1247-
* get collection object
1259+
* Get collection object
12481260
*
12491261
* @return \Magento\Framework\Data\Collection
12501262
*/

app/code/Magento/Backend/Model/Setup/MenuBuilder.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* Plugin class to remove web setup wizard from menu if application root is pub/ and no setup url variable is specified.
1414
* @api
1515
* @since 100.1.0
16+
* @deprecated Starting from Magento 2.3.6 Web Setup Wizard is deprecated
1617
*/
1718
class MenuBuilder
1819
{

app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/ExtendedTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ public function testPrepareLoadedCollection()
3232
$layout->expects($this->any())->method('getBlock')->will($this->returnValue($columnSet));
3333

3434
$collection = $this->createMock(\Magento\Framework\Data\Collection::class);
35-
$collection->expects($this->atLeastOnce())->method('isLoaded')->will($this->returnValue(true));
36-
$collection->expects($this->atLeastOnce())->method('clear');
35+
$collection->expects($this->never())->method('isLoaded');
36+
$collection->expects($this->never())->method('clear');
3737
$collection->expects($this->atLeastOnce())->method('load');
3838

3939
/** @var \Magento\Backend\Block\Widget\Grid\Extended $block */

0 commit comments

Comments
 (0)