Skip to content

Commit 12bfb59

Browse files
Merge MC-37623 into 2.3-bugfixes-101620
2 parents def5066 + b4031ab commit 12bfb59

File tree

4 files changed

+273
-0
lines changed

4 files changed

+273
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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\Csp\Model\Collector\CspWhitelistXml;
10+
11+
use Magento\Framework\Config\FileResolverInterface;
12+
use Magento\Framework\Filesystem;
13+
use Magento\Framework\View\Design\ThemeInterface;
14+
use Magento\Framework\View\DesignInterface;
15+
use Magento\Framework\View\Design\Theme\CustomizationInterface;
16+
use Magento\Framework\View\Design\Theme\CustomizationInterfaceFactory;
17+
use Magento\Framework\App\Filesystem\DirectoryList;
18+
use Magento\Framework\Filesystem\Directory\ReadInterface as DirectoryRead;
19+
use Magento\Framework\Config\CompositeFileIteratorFactory;
20+
21+
/**
22+
* Combines configuration files from both modules and current theme.
23+
*/
24+
class FileResolver implements FileResolverInterface
25+
{
26+
/**
27+
* @var FileResolverInterface
28+
*/
29+
private $moduleFileResolver;
30+
31+
/**
32+
* @var ThemeInterface
33+
*/
34+
private $theme;
35+
36+
/**
37+
* @var CustomizationInterfaceFactory
38+
*/
39+
private $themeInfoFactory;
40+
41+
/**
42+
* @var DirectoryRead
43+
*/
44+
private $rootDir;
45+
46+
/**
47+
* @var CompositeFileIteratorFactory
48+
*/
49+
private $iteratorFactory;
50+
51+
/**
52+
* @param FileResolverInterface $moduleFileResolver
53+
* @param DesignInterface $design
54+
* @param CustomizationInterfaceFactory $customizationFactory
55+
* @param Filesystem $filesystem
56+
* @param CompositeFileIteratorFactory $iteratorFactory
57+
*/
58+
public function __construct(
59+
FileResolverInterface $moduleFileResolver,
60+
DesignInterface $design,
61+
CustomizationInterfaceFactory $customizationFactory,
62+
Filesystem $filesystem,
63+
CompositeFileIteratorFactory $iteratorFactory
64+
) {
65+
$this->moduleFileResolver = $moduleFileResolver;
66+
$this->theme = $design->getDesignTheme();
67+
$this->themeInfoFactory = $customizationFactory;
68+
$this->rootDir = $filesystem->getDirectoryRead(DirectoryList::ROOT);
69+
$this->iteratorFactory = $iteratorFactory;
70+
}
71+
72+
/**
73+
* @inheritDoc
74+
*/
75+
public function get($filename, $scope)
76+
{
77+
$configs = $this->moduleFileResolver->get($filename, $scope);
78+
if ($scope === 'global') {
79+
$files = [];
80+
$theme = $this->theme;
81+
while ($theme) {
82+
/** @var CustomizationInterface $info */
83+
$info = $this->themeInfoFactory->create(['theme' => $theme]);
84+
$file = $info->getThemeFilesPath() .'/etc/' .$filename;
85+
if ($this->rootDir->isExist($file)) {
86+
$files[] = $file;
87+
}
88+
$theme = $theme->getParentTheme();
89+
}
90+
$configs = $this->iteratorFactory->create(
91+
['paths' => array_reverse($files), 'existingIterator' => $configs]
92+
);
93+
}
94+
95+
return $configs;
96+
}
97+
}

app/code/Magento/Csp/etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<arguments>
4747
<argument name="converter" xsi:type="object">Magento\Csp\Model\Collector\CspWhitelistXml\Converter</argument>
4848
<argument name="schemaLocator" xsi:type="object">Magento\Csp\Model\Collector\CspWhitelistXml\SchemaLocator</argument>
49+
<argument name="fileResolver" xsi:type="object">Magento\Csp\Model\Collector\CspWhitelistXml\FileResolver</argument>
4950
<argument name="fileName" xsi:type="string">csp_whitelist.xml</argument>
5051
</arguments>
5152
</type>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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\Framework\Config;
10+
11+
use Magento\Framework\Filesystem\File\ReadFactory;
12+
13+
/**
14+
* Combine existing file iterator and new files.
15+
*/
16+
class CompositeFileIterator extends FileIterator
17+
{
18+
/**
19+
* @var FileIterator
20+
*/
21+
private $existingIterator;
22+
23+
/**
24+
* @param ReadFactory $readFactory
25+
* @param array $paths
26+
* @param FileIterator $existingIterator
27+
*/
28+
public function __construct(ReadFactory $readFactory, array $paths, FileIterator $existingIterator)
29+
{
30+
parent::__construct($readFactory, $paths);
31+
$this->existingIterator = $existingIterator;
32+
}
33+
34+
/**
35+
* @inheritDoc
36+
*/
37+
public function rewind()
38+
{
39+
$this->existingIterator->rewind();
40+
parent::rewind();
41+
}
42+
43+
/**
44+
* @inheritDoc
45+
*/
46+
public function current()
47+
{
48+
if ($this->existingIterator->valid()) {
49+
return $this->existingIterator->current();
50+
}
51+
52+
return parent::current();
53+
}
54+
55+
/**
56+
* @inheritDoc
57+
*/
58+
public function key()
59+
{
60+
if ($this->existingIterator->valid()) {
61+
return $this->existingIterator->key();
62+
}
63+
64+
return parent::key();
65+
}
66+
67+
/**
68+
* @inheritDoc
69+
*/
70+
public function next()
71+
{
72+
if ($this->existingIterator->valid()) {
73+
$this->existingIterator->next();
74+
} else {
75+
parent::next();
76+
}
77+
}
78+
79+
/**
80+
* @inheritDoc
81+
*/
82+
public function valid()
83+
{
84+
return $this->existingIterator->valid() || parent::valid();
85+
}
86+
87+
/**
88+
* @inheritDoc
89+
*/
90+
public function toArray()
91+
{
92+
return array_merge($this->existingIterator->toArray(), parent::toArray());
93+
}
94+
95+
/**
96+
* @inheritDoc
97+
*/
98+
public function count()
99+
{
100+
return $this->existingIterator->count() + parent::count();
101+
}
102+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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\Framework\Config\Test\Unit;
10+
11+
use Magento\Framework\Config\CompositeFileIterator;
12+
use Magento\Framework\Config\FileIterator;
13+
use Magento\Framework\Filesystem\File\ReadFactory;
14+
use Magento\Framework\Filesystem\File\Read;
15+
use PHPUnit\Framework\MockObject\MockObject;
16+
use PHPUnit\Framework\TestCase;
17+
18+
/**
19+
* Test composition of file iterators.
20+
*/
21+
class CompositeFileIteratorTest extends TestCase
22+
{
23+
/**
24+
* @var ReadFactory|MockObject
25+
*/
26+
private $readFactoryMock;
27+
28+
/**
29+
* @inheritDoc
30+
*/
31+
protected function setUp()
32+
{
33+
parent::setUp();
34+
35+
$this->readFactoryMock = $this->createMock(ReadFactory::class);
36+
$this->readFactoryMock->method('create')
37+
->willReturnCallback(
38+
function (string $file): Read {
39+
$readMock = $this->createMock(Read::class);
40+
$readMock->method('readAll')->willReturn('Content of ' .$file);
41+
42+
return $readMock;
43+
}
44+
);
45+
}
46+
47+
/**
48+
* Test the composite.
49+
*/
50+
public function testComposition(): void
51+
{
52+
$existingFiles = [
53+
'/etc/magento/somefile.ext',
54+
'/etc/magento/somefile2.ext',
55+
'/etc/magento/somefile3.ext'
56+
];
57+
$newFiles = [
58+
'/etc/magento/some-other-file.ext',
59+
'/etc/magento/some-other-file2.ext'
60+
];
61+
62+
$existing = new FileIterator($this->readFactoryMock, $existingFiles);
63+
$composite = new CompositeFileIterator($this->readFactoryMock, $newFiles, $existing);
64+
$found = [];
65+
foreach ($composite as $file => $content) {
66+
$this->assertNotEmpty($content);
67+
$found[] = $file;
68+
}
69+
$this->assertEquals(array_merge($existingFiles, $newFiles), $found);
70+
$this->assertEquals(count($existingFiles) + count($newFiles), $composite->count());
71+
$this->assertEquals(array_merge($existingFiles, $newFiles), array_keys($composite->toArray()));
72+
}
73+
}

0 commit comments

Comments
 (0)