Skip to content

Commit 550060b

Browse files
committed
MAGETWO-38567: Dependency Validation of Physical Non-Composer Theme from Uninstalled Theme
- added physical child theme check
1 parent 1d4a31a commit 550060b

File tree

5 files changed

+136
-42
lines changed

5 files changed

+136
-42
lines changed

app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ protected function _prepareLayout()
7070
}
7171

7272
if ($theme->isDeletable()) {
73-
if ($theme->hasChildThemes()) {
73+
if ($theme->hasVirtualChildThemes()) {
7474
$message = __('Are you sure you want to delete this theme?');
7575
$onClick = sprintf(
7676
"deleteConfirm('%s', '%s')",

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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ protected function execute(InputInterface $input, OutputInterface $output)
200200
$output->writeln($validationMessages);
201201
return;
202202
}
203-
$childVirtualThemeCheckMessages = $this->checkChildVirtualTheme($themePaths);
204-
if (!empty($childVirtualThemeCheckMessages)) {
205-
$output->writeln($childVirtualThemeCheckMessages);
203+
$childThemeCheckMessages = $this->checkChildTheme($themePaths);
204+
if (!empty($childThemeCheckMessages)) {
205+
$output->writeln($childThemeCheckMessages);
206206
return;
207207
}
208208
$dependencyMessages = $this->checkDependencies($themePaths);
@@ -295,25 +295,34 @@ private function checkDependencies($themePaths)
295295
}
296296

297297
/**
298-
* Check theme if has child virtual theme
298+
* Check theme if has child virtual and physical theme
299299
*
300300
* @param string[] $themePaths
301301
* @return string[] $messages
302302
*/
303-
private function checkChildVirtualTheme($themePaths)
303+
private function checkChildTheme($themePaths)
304304
{
305305
$messages = [];
306-
$themeHasChildren = [];
306+
$themeHasVirtualChildren = [];
307+
$themeHasPhysicalChildren = [];
307308
foreach ($themePaths as $themePath) {
308309
$theme = $this->themeProvider->getThemeByFullPath($themePath);
309-
if ($theme->hasChildThemes()) {
310-
$themeHasChildren[] = $themePath;
310+
if ($theme->hasVirtualChildThemes()) {
311+
$themeHasVirtualChildren[] = $themePath;
311312
}
313+
if ($theme->hasPhysicalChildThemes()) {
314+
$themeHasPhysicalChildren[] = $themePath;
315+
}
316+
}
317+
if (!empty($themeHasVirtualChildren)) {
318+
$text = count($themeHasVirtualChildren) > 1 ? ' are parents of' : ' is a parent of';
319+
$messages[] = '<error>Unable to uninstall. '
320+
. implode(', ', $themeHasVirtualChildren) . $text . ' virtual theme</error>';
312321
}
313-
if (!empty($themeHasChildren)) {
314-
$text = count($themeHasChildren) > 1 ? ' are parents of' : ' is a parent of';
322+
if (!empty($themeHasPhysicalChildren)) {
323+
$text = count($themeHasPhysicalChildren) > 1 ? ' are parents of' : ' is a parent of';
315324
$messages[] = '<error>Unable to uninstall. '
316-
. implode(', ', $themeHasChildren) . $text . ' virtual theme</error>';
325+
. implode(', ', $themeHasPhysicalChildren) . $text . ' physical theme</error>';
317326
}
318327
return $messages;
319328
}

app/code/Magento/Theme/Model/Theme.php

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -201,18 +201,38 @@ public function isVisible()
201201
}
202202

203203
/**
204-
* Check is theme has child virtual themes
204+
* Check is theme has virtual child themes
205205
*
206206
* @return bool
207207
*/
208-
public function hasChildThemes()
208+
public function hasVirtualChildThemes()
209209
{
210-
return (bool)$this->getCollection()->addTypeFilter(
211-
self::TYPE_VIRTUAL
212-
)->addFieldToFilter(
213-
'parent_id',
214-
['eq' => $this->getId()]
215-
)->getSize();
210+
return $this->hasChildThemes(true);
211+
}
212+
213+
/**
214+
* Check is theme has physical child themes
215+
*
216+
* @return bool
217+
*/
218+
public function hasPhysicalChildThemes()
219+
{
220+
return $this->hasChildThemes(false);
221+
}
222+
223+
/**
224+
* Helper method for checking child themes
225+
*
226+
* @param $isVirtual
227+
* @return bool
228+
*/
229+
private function hasChildThemes($isVirtual)
230+
{
231+
$type = $isVirtual ? self::TYPE_VIRTUAL : self::TYPE_PHYSICAL;
232+
return (bool)$this->getCollection()
233+
->addTypeFilter($type)
234+
->addFieldToFilter('parent_id', ['eq' => $this->getId()])
235+
->getSize();
216236
}
217237

218238
/**

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

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -235,43 +235,87 @@ public function setUpPassValidation()
235235
$this->collection->expects($this->any())->method('hasTheme')->willReturn(true);
236236
}
237237

238-
public function setupPassChildVirtualThemeCheck()
238+
public function setupPassChildThemeCheck()
239239
{
240240
$theme = $this->getMock('Magento\Theme\Model\Theme', [], [], '', false);
241-
$theme->expects($this->any())->method('hasChildThemes')->willReturn(false);
241+
$theme->expects($this->any())->method('hasVirtualChildThemes')->willReturn(false);
242+
$theme->expects($this->any())->method('hasPhysicalChildThemes')->willReturn(false);
242243
$this->themeProvider->expects($this->any())->method('getThemeByFullPath')->willReturn($theme);
243244
}
244245

245-
public function testExecuteFailedChildVirtualThemeCheck()
246+
/**
247+
* @dataProvider executeFailedChildThemeCheckDataProvider
248+
* @param bool $hasVirtual
249+
* @param bool $hasPhysical
250+
* @param array $input
251+
* @param string $expected
252+
* @return void
253+
*/
254+
public function testExecuteFailedChildThemeCheck($hasVirtual, $hasPhysical, array $input, $expected)
246255
{
247256
$this->setUpPassValidation();
248257
$theme = $this->getMock('Magento\Theme\Model\Theme', [], [], '', false);
249-
$theme->expects($this->any())->method('hasChildThemes')->willReturn(true);
258+
$theme->expects($this->any())->method('hasVirtualChildThemes')->willReturn($hasVirtual);
259+
$theme->expects($this->any())->method('hasPhysicalChildThemes')->willReturn($hasPhysical);
250260
$this->themeProvider->expects($this->any())->method('getThemeByFullPath')->willReturn($theme);
251-
$this->tester->execute(['theme' => ['frontend/Magento/a']]);
261+
$this->tester->execute($input);
252262
$this->assertContains(
253-
'Unable to uninstall. frontend/Magento/a is a parent of virtual theme',
263+
$expected,
254264
$this->tester->getDisplay()
255265
);
256266
}
257267

258-
public function testExecuteFailedMultipleChildVirtualThemeCheck()
268+
/**
269+
* @return array
270+
*/
271+
public function executeFailedChildThemeCheckDataProvider()
259272
{
260-
$this->setUpPassValidation();
261-
$theme = $this->getMock('Magento\Theme\Model\Theme', [], [], '', false);
262-
$theme->expects($this->any())->method('hasChildThemes')->willReturn(true);
263-
$this->themeProvider->expects($this->any())->method('getThemeByFullPath')->willReturn($theme);
264-
$this->tester->execute(['theme' => ['frontend/Magento/a', 'frontend/Magento/b']]);
265-
$this->assertContains(
266-
'Unable to uninstall. frontend/Magento/a, frontend/Magento/b are parents of virtual theme',
267-
$this->tester->getDisplay()
268-
);
273+
return [
274+
[
275+
true,
276+
false,
277+
['theme' => ['frontend/Magento/a']],
278+
'Unable to uninstall. frontend/Magento/a is a parent of virtual theme'
279+
],
280+
[
281+
true,
282+
false,
283+
['theme' => ['frontend/Magento/a', 'frontend/Magento/b']],
284+
'Unable to uninstall. frontend/Magento/a, frontend/Magento/b are parents of virtual theme'
285+
],
286+
[
287+
false,
288+
true,
289+
['theme' => ['frontend/Magento/a']],
290+
'Unable to uninstall. frontend/Magento/a is a parent of physical theme'
291+
],
292+
[
293+
false,
294+
true,
295+
['theme' => ['frontend/Magento/a', 'frontend/Magento/b']],
296+
'Unable to uninstall. frontend/Magento/a, frontend/Magento/b are parents of physical theme'
297+
],
298+
[
299+
true,
300+
true,
301+
['theme' => ['frontend/Magento/a']],
302+
'Unable to uninstall. frontend/Magento/a is a parent of virtual theme' . PHP_EOL .
303+
'Unable to uninstall. frontend/Magento/a is a parent of physical theme'
304+
],
305+
[
306+
true,
307+
true,
308+
['theme' => ['frontend/Magento/a', 'frontend/Magento/b']],
309+
'Unable to uninstall. frontend/Magento/a, frontend/Magento/b are parents of virtual theme' . PHP_EOL .
310+
'Unable to uninstall. frontend/Magento/a, frontend/Magento/b are parents of physical theme'
311+
],
312+
];
269313
}
270314

271315
public function testExecuteFailedDependencyCheck()
272316
{
273317
$this->setUpPassValidation();
274-
$this->setupPassChildVirtualThemeCheck();
318+
$this->setupPassChildThemeCheck();
275319
$this->dependencyChecker->expects($this->once())
276320
->method('checkDependencies')
277321
->willReturn(['magento/theme-a' => ['magento/theme-b', 'magento/theme-c']]);
@@ -286,6 +330,7 @@ public function testExecuteFailedDependencyCheck()
286330
public function setUpExecute()
287331
{
288332
$this->setUpPassValidation();
333+
$this->setupPassChildThemeCheck();
289334
$this->dependencyChecker->expects($this->once())->method('checkDependencies')->willReturn([]);
290335
$this->remove->expects($this->once())->method('remove');
291336
$this->cache->expects($this->once())->method('clean');

dev/tests/integration/testsuite/Magento/Theme/Model/ThemeTest.php

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,41 @@ protected function _getThemeValidData()
4343
}
4444

4545
/**
46-
* Test theme on child relations
46+
* Test theme on virtual child relations
4747
*/
48-
public function testChildRelation()
48+
public function testVirtualChildRelation()
4949
{
5050
/** @var $theme \Magento\Framework\View\Design\ThemeInterface */
5151
$theme = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
5252
'Magento\Framework\View\Design\ThemeInterface'
5353
);
54-
$collection = $theme->getCollection()
54+
$virtualCollection = $theme->getCollection()
5555
->addTypeFilter(\Magento\Framework\View\Design\ThemeInterface::TYPE_VIRTUAL);
5656
/** @var $currentTheme \Magento\Framework\View\Design\ThemeInterface */
57-
foreach ($collection as $currentTheme) {
57+
foreach ($virtualCollection as $currentTheme) {
5858
$parentTheme = $currentTheme->getParentTheme();
5959
if (!empty($parentTheme)) {
60-
$this->assertTrue($parentTheme->hasChildThemes());
60+
$this->assertTrue($parentTheme->hasVirtualChildThemes());
61+
}
62+
}
63+
}
64+
65+
/**
66+
* Test theme on physical child relations
67+
*/
68+
public function testPhysicalChildRelation()
69+
{
70+
/** @var $theme \Magento\Framework\View\Design\ThemeInterface */
71+
$theme = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
72+
'Magento\Framework\View\Design\ThemeInterface'
73+
);
74+
$physicalCollection = $theme->getCollection()
75+
->addTypeFilter(\Magento\Framework\View\Design\ThemeInterface::TYPE_PHYSICAL);
76+
/** @var $currentTheme \Magento\Framework\View\Design\ThemeInterface */
77+
foreach ($physicalCollection as $currentTheme) {
78+
$parentTheme = $currentTheme->getParentTheme();
79+
if (!empty($parentTheme)) {
80+
$this->assertTrue($parentTheme->hasPhysicalChildThemes());
6181
}
6282
}
6383
}

0 commit comments

Comments
 (0)