Skip to content

Commit 075ddb4

Browse files
committed
Fix URL generation for new store
Emulate adminhtml area where url rewrites are created
1 parent 57c527e commit 075ddb4

File tree

3 files changed

+148
-13
lines changed

3 files changed

+148
-13
lines changed

app/code/Magento/Deploy/Console/Command/App/ConfigImportCommand.php

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,21 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Deploy\Console\Command\App;
78

9+
use Magento\Config\Console\Command\EmulatedAdminhtmlAreaProcessor;
10+
use Magento\Deploy\Console\Command\App\ConfigImport\Processor;
11+
use Magento\Framework\App\Area;
12+
use Magento\Framework\App\AreaList;
13+
use Magento\Framework\App\DeploymentConfig;
14+
use Magento\Framework\App\ObjectManager;
15+
use Magento\Framework\Console\Cli;
16+
use Magento\Framework\Exception\FileSystemException;
817
use Magento\Framework\Exception\RuntimeException;
918
use Symfony\Component\Console\Command\Command;
1019
use Symfony\Component\Console\Input\InputInterface;
1120
use Symfony\Component\Console\Output\OutputInterface;
12-
use Magento\Framework\Console\Cli;
13-
use Magento\Deploy\Console\Command\App\ConfigImport\Processor;
1421

1522
/**
1623
* Runs the process of importing configuration data from shared source to appropriate application sources
@@ -21,9 +28,6 @@
2128
*/
2229
class ConfigImportCommand extends Command
2330
{
24-
/**
25-
* Command name.
26-
*/
2731
const COMMAND_NAME = 'app:config:import';
2832

2933
/**
@@ -33,12 +37,40 @@ class ConfigImportCommand extends Command
3337
*/
3438
private $processor;
3539

40+
/**
41+
* @var EmulatedAdminhtmlAreaProcessor
42+
*/
43+
private $adminhtmlAreaProcessor;
44+
45+
/**
46+
* @var DeploymentConfig
47+
*/
48+
private $deploymentConfig;
49+
50+
/**
51+
* @var AreaList
52+
*/
53+
private $areaList;
54+
3655
/**
3756
* @param Processor $processor the configuration importer
57+
* @param DeploymentConfig|null $deploymentConfig
58+
* @param EmulatedAdminhtmlAreaProcessor|null $adminhtmlAreaProcessor
59+
* @param AreaList|null $areaList
3860
*/
39-
public function __construct(Processor $processor)
40-
{
61+
public function __construct(
62+
Processor $processor,
63+
DeploymentConfig $deploymentConfig = null,
64+
EmulatedAdminhtmlAreaProcessor $adminhtmlAreaProcessor = null,
65+
AreaList $areaList = null
66+
) {
4167
$this->processor = $processor;
68+
$this->deploymentConfig = $deploymentConfig
69+
?? ObjectManager::getInstance()->get(DeploymentConfig::class);
70+
$this->adminhtmlAreaProcessor = $adminhtmlAreaProcessor
71+
?? ObjectManager::getInstance()->get(EmulatedAdminhtmlAreaProcessor::class);
72+
$this->areaList = $areaList
73+
?? ObjectManager::getInstance()->get(AreaList::class);
4274

4375
parent::__construct();
4476
}
@@ -55,12 +87,26 @@ protected function configure()
5587
}
5688

5789
/**
58-
* Imports data from deployment configuration files to the DB. {@inheritdoc}
90+
* Imports data from deployment configuration files to the DB.
91+
* {@inheritdoc}
92+
*
93+
* @param InputInterface $input
94+
* @param OutputInterface $output
95+
* @return int
96+
* @throws \Exception
5997
*/
6098
protected function execute(InputInterface $input, OutputInterface $output)
6199
{
62100
try {
63-
$this->processor->execute($input, $output);
101+
if ($this->canEmulateAdminhtmlArea()) {
102+
// Emulate adminhtml area in order to execute all needed plugins declared only for this area
103+
// For instance URL rewrite generation during creating store view
104+
$this->adminhtmlAreaProcessor->process(function () use ($input, $output) {
105+
$this->processor->execute($input, $output);
106+
});
107+
} else {
108+
$this->processor->execute($input, $output);
109+
}
64110
} catch (RuntimeException $e) {
65111
$output->writeln('<error>' . $e->getMessage() . '</error>');
66112

@@ -69,4 +115,19 @@ protected function execute(InputInterface $input, OutputInterface $output)
69115

70116
return Cli::RETURN_SUCCESS;
71117
}
118+
119+
/**
120+
* Detects if we can emulate adminhtml area
121+
*
122+
* This area could be not available for instance during setup:install
123+
*
124+
* @return bool
125+
* @throws RuntimeException
126+
* @throws FileSystemException
127+
*/
128+
private function canEmulateAdminhtmlArea(): bool
129+
{
130+
return $this->deploymentConfig->isAvailable()
131+
&& in_array(Area::AREA_ADMINHTML, $this->areaList->getCodes());
132+
}
72133
}

app/code/Magento/Deploy/Test/Unit/Console/Command/App/ConfigImportCommandTest.php

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77

88
namespace Magento\Deploy\Test\Unit\Console\Command\App;
99

10+
use Magento\Config\Console\Command\EmulatedAdminhtmlAreaProcessor;
1011
use Magento\Deploy\Console\Command\App\ConfigImport\Processor;
1112
use Magento\Deploy\Console\Command\App\ConfigImportCommand;
13+
use Magento\Framework\App\AreaList;
14+
use Magento\Framework\App\DeploymentConfig;
1215
use Magento\Framework\Console\Cli;
1316
use Magento\Framework\Exception\RuntimeException;
1417
use PHPUnit\Framework\MockObject\MockObject;
@@ -27,16 +30,37 @@ class ConfigImportCommandTest extends TestCase
2730
*/
2831
private $commandTester;
2932

33+
/**
34+
* @var DeploymentConfig|MockObject
35+
*/
36+
private $deploymentConfigMock;
37+
38+
/**
39+
* @var EmulatedAdminhtmlAreaProcessor|MockObject
40+
*/
41+
private $adminhtmlAreaProcessorMock;
42+
43+
/**
44+
* @var AreaList|MockObject
45+
*/
46+
private $areaListMock;
47+
3048
/**
3149
* @return void
3250
*/
3351
protected function setUp(): void
3452
{
35-
$this->processorMock = $this->getMockBuilder(Processor::class)
36-
->disableOriginalConstructor()
37-
->getMock();
53+
$this->processorMock = $this->createMock(Processor::class);
54+
$this->deploymentConfigMock = $this->createMock(DeploymentConfig::class);
55+
$this->adminhtmlAreaProcessorMock = $this->createMock(EmulatedAdminhtmlAreaProcessor::class);
56+
$this->areaListMock = $this->createMock(AreaList::class);
3857

39-
$configImportCommand = new ConfigImportCommand($this->processorMock);
58+
$configImportCommand = new ConfigImportCommand(
59+
$this->processorMock,
60+
$this->deploymentConfigMock,
61+
$this->adminhtmlAreaProcessorMock,
62+
$this->areaListMock
63+
);
4064

4165
$this->commandTester = new CommandTester($configImportCommand);
4266
}
@@ -46,6 +70,13 @@ protected function setUp(): void
4670
*/
4771
public function testExecute()
4872
{
73+
$this->deploymentConfigMock->expects($this->once())->method('isAvailable')->willReturn(true);
74+
$this->adminhtmlAreaProcessorMock->expects($this->once())
75+
->method('process')->willReturnCallback(function (callable $callback, array $params = []) {
76+
return $callback(...$params);
77+
});
78+
$this->areaListMock->expects($this->once())->method('getCodes')->willReturn(['adminhtml']);
79+
4980
$this->processorMock->expects($this->once())
5081
->method('execute');
5182

@@ -57,11 +88,48 @@ public function testExecute()
5788
*/
5889
public function testExecuteWithException()
5990
{
91+
$this->deploymentConfigMock->expects($this->once())->method('isAvailable')->willReturn(true);
92+
$this->adminhtmlAreaProcessorMock->expects($this->once())
93+
->method('process')->willReturnCallback(function (callable $callback, array $params = []) {
94+
return $callback(...$params);
95+
});
96+
$this->areaListMock->expects($this->once())->method('getCodes')->willReturn(['adminhtml']);
97+
6098
$this->processorMock->expects($this->once())
6199
->method('execute')
62100
->willThrowException(new RuntimeException(__('Some error')));
63101

64102
$this->assertSame(Cli::RETURN_FAILURE, $this->commandTester->execute([]));
65103
$this->assertStringContainsString('Some error', $this->commandTester->getDisplay());
66104
}
105+
106+
/**
107+
* @return void
108+
*/
109+
public function testExecuteWithDeploymentConfigNotAvailable()
110+
{
111+
$this->deploymentConfigMock->expects($this->once())->method('isAvailable')->willReturn(false);
112+
$this->adminhtmlAreaProcessorMock->expects($this->never())->method('process');
113+
$this->areaListMock->expects($this->never())->method('getCodes');
114+
115+
$this->processorMock->expects($this->once())
116+
->method('execute');
117+
118+
$this->assertSame(Cli::RETURN_SUCCESS, $this->commandTester->execute([]));
119+
}
120+
121+
/**
122+
* @return void
123+
*/
124+
public function testExecuteWithMissingAdminhtmlLocale()
125+
{
126+
$this->deploymentConfigMock->expects($this->once())->method('isAvailable')->willReturn(true);
127+
$this->adminhtmlAreaProcessorMock->expects($this->never())->method('process');
128+
$this->areaListMock->expects($this->once())->method('getCodes')->willReturn([]);
129+
130+
$this->processorMock->expects($this->once())
131+
->method('execute');
132+
133+
$this->assertSame(Cli::RETURN_SUCCESS, $this->commandTester->execute([]));
134+
}
67135
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@
3535
</argument>
3636
</arguments>
3737
</type>
38+
<type name="Magento\Deploy\Console\Command\App\ConfigImportCommand">
39+
<arguments>
40+
<argument name="adminhtmlAreaProcessor" xsi:type="object">Magento\Config\Console\Command\EmulatedAdminhtmlAreaProcessor\Proxy</argument>
41+
<argument name="areaList" xsi:type="object">Magento\Framework\App\AreaList\Proxy</argument>
42+
</arguments>
43+
</type>
3844
<type name="Magento\Deploy\Model\Filesystem">
3945
<arguments>
4046
<argument name="shell" xsi:type="object">Magento\Framework\App\Shell</argument>

0 commit comments

Comments
 (0)