Skip to content

Commit 996cd6c

Browse files
Fred Sungeddielau
authored andcommitted
MAGETWO-38178: Check if Theme in use
- Detect the theme if in use in default, websites, or stores level. - Test cases updated.
1 parent 4a83403 commit 996cd6c

File tree

4 files changed

+206
-2
lines changed

4 files changed

+206
-2
lines changed

app/code/Magento/Theme/Console/Command/ThemeUninstallCommand.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Magento\Framework\Setup\BackupRollbackFactory;
2525
use Magento\Framework\App\Filesystem\DirectoryList;
2626
use Magento\Framework\Exception\LocalizedException;
27+
use Magento\Theme\Model\ThemeValidator;
2728

2829
/**
2930
* Command for uninstalling theme and backup-code feature
@@ -110,6 +111,13 @@ class ThemeUninstallCommand extends Command
110111
*/
111112
private $backupRollbackFactory;
112113

114+
/**
115+
* Theme Validator
116+
*
117+
* @var ThemeValidator
118+
*/
119+
private $themeValidator;
120+
113121
/**
114122
* Constructor
115123
*
@@ -123,6 +131,7 @@ class ThemeUninstallCommand extends Command
123131
* @param ThemeProvider $themeProvider
124132
* @param Remove $remove
125133
* @param BackupRollbackFactory $backupRollbackFactory
134+
* @param ThemeValidator $themeValidator
126135
* @throws LocalizedException
127136
*/
128137
public function __construct(
@@ -135,7 +144,8 @@ public function __construct(
135144
Collection $themeCollection,
136145
ThemeProvider $themeProvider,
137146
Remove $remove,
138-
BackupRollbackFactory $backupRollbackFactory
147+
BackupRollbackFactory $backupRollbackFactory,
148+
ThemeValidator $themeValidator
139149
) {
140150
$this->cache = $cache;
141151
$this->cleanupFiles = $cleanupFiles;
@@ -147,6 +157,7 @@ public function __construct(
147157
$this->themeCollection = $themeCollection;
148158
$this->themeProvider = $themeProvider;
149159
$this->backupRollbackFactory = $backupRollbackFactory;
160+
$this->themeValidator = $themeValidator;
150161
parent::__construct();
151162
}
152163

@@ -189,6 +200,11 @@ protected function execute(InputInterface $input, OutputInterface $output)
189200
$output->writeln($validationMessages);
190201
return;
191202
}
203+
$isThemeInUseMessages = $this->themeValidator->validateIsThemeInUse($themePaths);
204+
if (!empty($isThemeInUseMessages)) {
205+
$output->writeln($isThemeInUseMessages);
206+
return;
207+
}
192208
$childThemeCheckMessages = $this->checkChildTheme($themePaths);
193209
if (!empty($childThemeCheckMessages)) {
194210
$output->writeln($childThemeCheckMessages);
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Theme\Model;
7+
8+
use Magento\Store\Model\StoreManagerInterface;
9+
use Magento\Framework\View\DesignInterface;
10+
use Magento\Framework\View\Design\Theme\ThemeProviderInterface;
11+
use Magento\Framework\App\Config\ValueInterface;
12+
use Magento\Store\Model\ScopeInterface;
13+
14+
/**
15+
* Class ThemeValidator
16+
*/
17+
class ThemeValidator
18+
{
19+
20+
/**
21+
* Store Manager
22+
*
23+
* @var StoreManagerInterface $storeManager
24+
*/
25+
private $storeManager;
26+
27+
/**
28+
* Provider for themes registered in db
29+
*
30+
* @var ThemeProviderInterface $themeProvider
31+
*/
32+
private $themeProvider;
33+
34+
/**
35+
* Configuration Data
36+
*
37+
* @var ValueInterface $configData
38+
*/
39+
private $configData;
40+
41+
42+
/**
43+
* @param StoreManagerInterface $storeManager
44+
* @param ThemeProviderInterface $themeProvider
45+
* @param ValueInterface $configData
46+
*/
47+
public function __construct(
48+
StoreManagerInterface $storeManager,
49+
ThemeProviderInterface $themeProvider,
50+
ValueInterface $configData
51+
)
52+
{
53+
$this->storeManager = $storeManager;
54+
$this->themeProvider = $themeProvider;
55+
$this->configData = $configData;
56+
}
57+
58+
/**
59+
*
60+
* @param string[] $themePaths
61+
* @return array
62+
*/
63+
public function validateIsThemeInUse($themePaths)
64+
{
65+
$messages = [];
66+
$themesById = [];
67+
foreach ($themePaths as $themePath) {
68+
$theme = $this->themeProvider->getThemeByFullPath($themePath);
69+
$themesById[$theme->getId()] = $themePath;
70+
}
71+
$configData = $this->configData
72+
->getCollection()
73+
->addFieldToFilter('path', DesignInterface::XML_PATH_THEME_ID)
74+
->addFieldToFilter('value', ['in' => array_keys($themesById)]);
75+
foreach ($configData as $row) {
76+
switch($row['scope']) {
77+
case 'default':
78+
$messages[] = $themesById[$row['value']] . ' is in use in default config';
79+
break;
80+
case ScopeInterface::SCOPE_WEBSITES:
81+
$messages[] = $themesById[$row['value']] . ' is in use in website '
82+
. $this->storeManager->getWebsite($row['scope_id'])->getName();
83+
break;
84+
case ScopeInterface::SCOPE_STORES:
85+
$messages[] = $themesById[$row['value']] . ' is in use in website '
86+
. $this->storeManager->getStore($row['scope_id'])->getName();
87+
break;
88+
}
89+
}
90+
return $messages;
91+
}
92+
}

app/code/Magento/Theme/Test/Unit/Console/Command/ThemeUninstallCommandTest.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ class ThemeUninstallCommandTest extends \PHPUnit_Framework_TestCase
6666
*/
6767
private $backupRollbackFactory;
6868

69+
/**
70+
* Theme Validator
71+
*
72+
* @var ThemeValidator|\PHPUnit_Framework_MockObject_MockObject
73+
*/
74+
private $themeValidator;
75+
6976
/**
7077
* @var CommandTester
7178
*/
@@ -98,6 +105,7 @@ public function setUp()
98105
'',
99106
false
100107
);
108+
$this->themeValidator = $this->getMock('Magento\Theme\Model\ThemeValidator',[], [], '', false);
101109
$this->command = new ThemeUninstallCommand(
102110
$this->cache,
103111
$this->cleanupFiles,
@@ -108,7 +116,8 @@ public function setUp()
108116
$this->collection,
109117
$this->themeProvider,
110118
$this->remove,
111-
$this->backupRollbackFactory
119+
$this->backupRollbackFactory,
120+
$this->themeValidator
112121
);
113122
$this->tester = new CommandTester($this->command);
114123
}
@@ -326,6 +335,16 @@ public function executeFailedChildThemeCheckDataProvider()
326335
];
327336
}
328337

338+
public function testExecuteFailedThemeInUseCheck()
339+
{
340+
$this->setUpPassValidation();
341+
$this->themeValidator
342+
->expects($this->once())
343+
->method('validateIsThemeInUse')
344+
->willReturn(['frontend/Magento/a']);
345+
$this->tester->execute(['theme' => ['frontend/Magento/a']]);
346+
}
347+
329348
public function testExecuteFailedDependencyCheck()
330349
{
331350
$this->setUpPassValidation();
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
/**
8+
* Test theme model
9+
*/
10+
namespace Magento\Theme\Test\Unit\Model;
11+
12+
class ThemeValidatorTest extends \PHPUnit_Framework_TestCase
13+
{
14+
/**
15+
* @var \Magento\Theme\Model\ThemeValidator|\PHPUnit_Framework_MockObject_MockObject
16+
*/
17+
protected $themeValidator;
18+
19+
/**
20+
* @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
21+
*/
22+
protected $storeManager;
23+
24+
/**
25+
* @var \Magento\Framework\View\Design\Theme\ThemeProviderInterface|\PHPUnit_Framework_MockObject_MockObject
26+
*/
27+
protected $themeProvider;
28+
29+
/**
30+
* @var \Magento\Framework\App\Config\Value|\PHPUnit_Framework_MockObject_MockObject
31+
*/
32+
protected $configData;
33+
34+
protected function setUp()
35+
{
36+
$this->storeManager = $this->getMock('Magento\Store\Model\StoreManagerInterface', [], [], '', false);
37+
$this->themeProvider = $this->getMock(
38+
'Magento\Framework\View\Design\Theme\ThemeProviderInterface', [], [], '', false
39+
);
40+
$this->configData = $this->getMock(
41+
'Magento\Framework\App\Config\Value',
42+
['getCollection', 'addFieldToFilter'],
43+
[],
44+
'',
45+
false
46+
);
47+
$this->themeValidator = new \Magento\Theme\Model\ThemeValidator(
48+
$this->storeManager,
49+
$this->themeProvider,
50+
$this->configData
51+
);
52+
}
53+
54+
public function testValidateIsThemeInUse()
55+
{
56+
$theme = $this->getMock('Magento\Theme\Model\Theme', [], [], '', false);
57+
$theme->expects($this->once())->method('getId')->willReturn(6);
58+
$defaultEntity = new \Magento\Framework\Object(['value' => 6, 'scope' => 'default', 'scope_id' => 8]);
59+
$websitesEntity = new \Magento\Framework\Object(['value' => 6, 'scope' => 'websites', 'scope_id' => 8]);
60+
$storesEntity = new \Magento\Framework\Object(['value' => 6, 'scope' => 'stores', 'scope_id' => 8]);
61+
$this->themeProvider->expects($this->once())->method('getThemeByFullPath')->willReturn($theme);
62+
$this->configData->expects($this->once())->method('getCollection')->willReturn($this->configData);
63+
$this->configData
64+
->expects($this->at(1))
65+
->method('addFieldToFilter')
66+
->willReturn($this->configData);
67+
$this->configData
68+
->expects($this->at(2))
69+
->method('addFieldToFilter')
70+
->willReturn([$defaultEntity, $websitesEntity, $storesEntity]);
71+
$website = $this->getMock('Magento\Store\Model\Website', [], [], '', false);
72+
$store = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
73+
$this->storeManager->expects($this->once())->method('getWebsite')->willReturn($website);
74+
$this->storeManager->expects($this->once())->method('getStore')->willReturn($store);
75+
$this->themeValidator->validateIsThemeInUse(['frontend/Magento/a']);
76+
}
77+
}

0 commit comments

Comments
 (0)