Passed
Push — master ( 50f297...79202c )
by Christian
11:34 queued 10s
created

ThemeInheritanceBuilder   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 54
c 1
b 0
f 0
dl 0
loc 122
rs 10
wmc 20

5 Methods

Rating   Name   Duplication   Size   Complexity  
A isTheme() 0 17 4
A __construct() 0 3 1
A getThemeInheritance() 0 36 5
A build() 0 31 6
A injectPluginWildcard() 0 17 4
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Storefront\Theme\Twig;
4
5
use Shopware\Storefront\Theme\StorefrontPluginRegistry;
6
use Shopware\Storefront\Theme\StorefrontPluginRegistryInterface;
7
8
class ThemeInheritanceBuilder implements ThemeInheritanceBuilderInterface
9
{
10
    /**
11
     * @var StorefrontPluginRegistryInterface
12
     */
13
    private $themeRegistry;
14
15
    public function __construct(StorefrontPluginRegistryInterface $themeRegistry)
16
    {
17
        $this->themeRegistry = $themeRegistry;
18
    }
19
20
    /**
21
     * {@inheritdoc}
22
     */
23
    public function build(array $bundles, array $themes): array
24
    {
25
        $keys = array_keys($themes);
26
27
        $theme = array_shift($keys);
28
29
        $inheritance = $this->getThemeInheritance($theme, $themes);
30
31
        foreach ($bundles as $bundle) {
32
            $key = '@' . $bundle;
33
34
            if (isset($inheritance[$key])) {
35
                $inheritance[$key][] = $bundle;
36
37
                continue;
38
            }
39
            if ($this->isTheme($bundle)) {
40
                continue;
41
            }
42
43
            $inheritance['@Plugins'][] = $bundle;
44
        }
45
46
        $flat = [];
47
        foreach ($inheritance as $namespace) {
48
            foreach ($namespace as $bundle) {
49
                $flat[] = $bundle;
50
            }
51
        }
52
53
        return array_reverse($flat);
54
    }
55
56
    private function getThemeInheritance(string $theme, array $themes): array
57
    {
58
        $names = array_keys($themes);
59
60
        $default = [
61
            // ensure storefront to be first
62
            '@Storefront' => [],
63
        ];
64
65
        foreach ($names as $name) {
66
            $name = '@' . $name;
67
            $default[$name] = [];
68
        }
69
70
        $default = $this->injectPluginWildcard($default);
71
72
        $themeConfig = $this->themeRegistry
73
            ->getConfigurations()
74
            ->getByTechnicalName($theme);
75
76
        if (!$themeConfig) {
77
            return $default;
78
        }
79
80
        $inheritance = $themeConfig->getViewInheritance();
81
82
        if (empty($inheritance)) {
83
            return $default;
84
        }
85
86
        $tree = [];
87
        foreach ($inheritance as $name) {
88
            $tree[$name] = [];
89
        }
90
91
        return $this->injectPluginWildcard($tree);
92
    }
93
94
    private function injectPluginWildcard(array $inheritance): array
95
    {
96
        // ensure plugin support
97
        if (isset($inheritance['@Plugins'])) {
98
            return $inheritance;
99
        }
100
101
        $sorted = [];
102
        foreach ($inheritance as $index => $name) {
103
            $sorted[$index] = $name;
104
105
            if ($index === '@Storefront') {
106
                $sorted['@Plugins'] = [];
107
            }
108
        }
109
110
        return $sorted;
111
    }
112
113
    private function isTheme(string $bundle): bool
114
    {
115
        $themeConfig = $this->themeRegistry->getConfigurations()->getByTechnicalName($bundle);
116
117
        if ($themeConfig === null) {
118
            return false;
119
        }
120
121
        if ($themeConfig->getIsTheme()) {
122
            return true;
123
        }
124
125
        if ($bundle === StorefrontPluginRegistry::BASE_THEME_NAME) {
126
            return true;
127
        }
128
129
        return false;
130
    }
131
}
132