1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Theme\Model\Theme;
use Magento\Theme\Model\Theme\Data\Collection as ThemeCollection;
/**
* Class checks theme dependencies
*/
class ThemeDependencyChecker
{
/**
* Theme Collection
*
* @var ThemeCollection
*/
private $themeCollection;
/**
* Provider for themes registered in db
*
* @var ThemeProvider
*/
private $themeProvider;
/**
* Package name finder
*
* @var ThemePackageInfo
*/
private $themePackageInfo;
/**
* Constructor
*
* @param ThemeCollection $themeCollection
* @param ThemeProvider $themeProvider
* @param ThemePackageInfo $themePackageInfo,
*/
public function __construct(
ThemeCollection $themeCollection,
ThemeProvider $themeProvider,
ThemePackageInfo $themePackageInfo
) {
$this->themeCollection = $themeCollection;
$this->themeProvider = $themeProvider;
$this->themePackageInfo = $themePackageInfo;
}
/**
* Check theme by package name(s) if has child virtual and physical theme
*
* @param string[] $packages
* @return string[]
*/
public function checkChildThemeByPackagesName($packages)
{
$themePaths = [];
foreach ($packages as $package) {
$themePath = $this->themePackageInfo->getFullThemePath($package);
if ($themePath) {
$themePaths[] = $themePath;
}
}
if ($themePaths) {
return $this->checkChildTheme($themePaths);
}
return [];
}
/**
* Check theme if has child virtual and physical theme
*
* @param string[] $themePaths
* @return string[]
*/
public function checkChildTheme($themePaths)
{
$messages = [];
$themeHasVirtualChildren = [];
$themeHasPhysicalChildren = [];
$parentChildMap = $this->getParentChildThemeMap();
foreach ($themePaths as $themePath) {
$theme = $this->themeProvider->getThemeByFullPath($themePath);
if ($theme->hasChildThemes()) {
$themeHasVirtualChildren[] = $themePath;
}
if (isset($parentChildMap[$themePath])) {
$themeHasPhysicalChildren[] = $themePath;
}
}
if (!empty($themeHasVirtualChildren)) {
$text = count($themeHasVirtualChildren) > 1 ? ' are parents of' : ' is a parent of';
$messages[] = implode(', ', $themeHasVirtualChildren) . $text . ' virtual theme.'
. ' Parent themes cannot be uninstalled.';
}
if (!empty($themeHasPhysicalChildren)) {
$text = count($themeHasPhysicalChildren) > 1 ? ' are parents of' : ' is a parent of';
$messages[] = implode(', ', $themeHasPhysicalChildren) . $text . ' physical theme.'
. ' Parent themes cannot be uninstalled.';
}
return $messages;
}
/**
* Obtain a parent theme -> children themes map from the filesystem
*
* @return array
*/
private function getParentChildThemeMap()
{
$map = [];
$this->themeCollection->resetConstraints();
$this->themeCollection->clear();
/** @var \Magento\Theme\Model\Theme\Data $theme */
foreach ($this->themeCollection as $theme) {
if ($theme->getParentTheme()) {
$map[$theme->getParentTheme()->getFullPath()][] = $theme->getFullPath();
}
}
return $map;
}
}