Completed
Push — master ( d15c72...9c95f5 )
by Paweł
95:59 queued 38:59
created

convertAuthorsArraysToAuthorsObjects()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Superdesk Web Publisher Core Bundle.
5
 *
6
 * Copyright 2016 Sourcefabric z.u. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2016 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Bundle\CoreBundle\Theme\Loader;
16
17
use Sylius\Bundle\ThemeBundle\Configuration\ConfigurationProviderInterface;
18
use Sylius\Bundle\ThemeBundle\Factory\ThemeAuthorFactoryInterface;
19
use Sylius\Bundle\ThemeBundle\Factory\ThemeFactoryInterface;
20
use Sylius\Bundle\ThemeBundle\Factory\ThemeScreenshotFactoryInterface;
21
use Sylius\Bundle\ThemeBundle\Loader\CircularDependencyCheckerInterface;
22
use Sylius\Bundle\ThemeBundle\Loader\ThemeLoaderInterface;
23
use Sylius\Bundle\ThemeBundle\Model\ThemeAuthor;
24
use Sylius\Bundle\ThemeBundle\Model\ThemeInterface;
25
use Sylius\Bundle\ThemeBundle\Model\ThemeScreenshot;
26
use Zend\Hydrator\HydrationInterface;
27
28
/**
29
 * @author Kamil Kokot <[email protected]>
30
 * @author Paweł Mikołajczuk <[email protected]>
31
 */
32
final class TenantAwareThemeLoader implements ThemeLoaderInterface
33
{
34
    /**
35
     * @var ConfigurationProviderInterface
36
     */
37
    private $configurationProvider;
38
39
    /**
40
     * @var ThemeFactoryInterface
41
     */
42
    private $themeFactory;
43
44
    /**
45
     * @var ThemeAuthorFactoryInterface
46
     */
47
    private $themeAuthorFactory;
48
49
    /**
50
     * @var ThemeScreenshotFactoryInterface
51
     */
52
    private $themeScreenshotFactory;
53
54
    /**
55
     * @var HydrationInterface
56
     */
57
    private $themeHydrator;
58
59
    /**
60
     * @var CircularDependencyCheckerInterface
61
     */
62
    private $circularDependencyChecker;
63
64
    /**
65
     * @param ConfigurationProviderInterface     $configurationProvider
66
     * @param ThemeFactoryInterface              $themeFactory
67
     * @param ThemeAuthorFactoryInterface        $themeAuthorFactory
68
     * @param ThemeScreenshotFactoryInterface    $themeScreenshotFactory
69
     * @param HydrationInterface                 $themeHydrator
70
     * @param CircularDependencyCheckerInterface $circularDependencyChecker
71
     */
72
    public function __construct(
73
        ConfigurationProviderInterface $configurationProvider,
74
        ThemeFactoryInterface $themeFactory,
75
        ThemeAuthorFactoryInterface $themeAuthorFactory,
76
        ThemeScreenshotFactoryInterface $themeScreenshotFactory,
77
        HydrationInterface $themeHydrator,
78
        CircularDependencyCheckerInterface $circularDependencyChecker
79
    ) {
80
        $this->configurationProvider = $configurationProvider;
81
        $this->themeFactory = $themeFactory;
82
        $this->themeAuthorFactory = $themeAuthorFactory;
83
        $this->themeScreenshotFactory = $themeScreenshotFactory;
84
        $this->themeHydrator = $themeHydrator;
85
        $this->circularDependencyChecker = $circularDependencyChecker;
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91
    public function load()
92
    {
93
        $configurations = $this->configurationProvider->getConfigurations();
94
95
        $themes = $this->initializeThemes($configurations);
96
        $themes = $this->hydrateThemes($configurations, $themes);
97
98
        $this->checkForCircularDependencies($themes);
99
100
        return array_values($themes);
101
    }
102
103
    /**
104
     * @param array $configurations
105
     *
106
     * @return ThemeInterface[]
107
     */
108
    private function initializeThemes(array $configurations)
109
    {
110
        $themes = [];
111
        foreach ($configurations as $configuration) {
112
            /* @var ThemeInterface $theme */
113
            $themes[$configuration['name']] = $this->themeFactory->create($configuration['name'], $configuration['path']);
114
        }
115
116
        return $themes;
117
    }
118
119
    /**
120
     * @param array            $configurations
121
     * @param ThemeInterface[] $themes
122
     *
123
     * @return ThemeInterface[]
124
     */
125
    private function hydrateThemes(array $configurations, array $themes)
126
    {
127
        foreach ($configurations as $configuration) {
128
            $themeName = $configuration['name'];
129
            $configuration['parents'] = $this->convertParentsNamesToParentsObjects($themeName, $configuration['parents'], $themes);
130
            $configuration['authors'] = $this->convertAuthorsArraysToAuthorsObjects($configuration['authors']);
131
            $configuration['screenshots'] = $this->convertScreenshotsArraysToScreenshotsObjects($configuration['screenshots']);
132
133
            $themes[$themeName] = $this->themeHydrator->hydrate($configuration, $themes[$themeName]);
134
        }
135
136
        return $themes;
137
    }
138
139
    /**
140
     * @param ThemeInterface[] $themes
141
     */
142
    private function checkForCircularDependencies(array $themes)
143
    {
144
        try {
145
            foreach ($themes as $theme) {
146
                $this->circularDependencyChecker->check($theme);
147
            }
148
        } catch (CircularDependencyFoundException $exception) {
0 ignored issues
show
Bug introduced by
The class SWP\Bundle\CoreBundle\Th...ependencyFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
149
            throw new ThemeLoadingFailedException('Circular dependency found.', 0, $exception);
150
        }
151
    }
152
153
    /**
154
     * @param string $themeName
155
     * @param array  $parentsNames
156
     * @param array  $existingThemes
157
     *
158
     * @return ThemeInterface[]
159
     */
160
    private function convertParentsNamesToParentsObjects($themeName, array $parentsNames, array $existingThemes)
161
    {
162
        $tenantCode = substr($themeName, strpos($themeName, '@') + 1);
163
164
        return array_map(function ($parentName) use ($themeName, $existingThemes, $tenantCode) {
165
            $parentName .= '@'.$tenantCode;
166
            if (!isset($existingThemes[$parentName])) {
167
                throw new ThemeLoadingFailedException(sprintf(
168
                    'Unexisting theme "%s" is required by "%s".',
169
                    $parentName,
170
                    $themeName
171
                ));
172
            }
173
174
            return $existingThemes[$parentName];
175
        }, $parentsNames);
176
    }
177
178
    /**
179
     * @param array $authorsArrays
180
     *
181
     * @return ThemeAuthor[]
182
     */
183
    private function convertAuthorsArraysToAuthorsObjects(array $authorsArrays)
184
    {
185
        return array_map(function (array $authorArray) {
186
            return $this->themeAuthorFactory->createFromArray($authorArray);
187
        }, $authorsArrays);
188
    }
189
190
    /**
191
     * @param array $screenshotsArrays
192
     *
193
     * @return ThemeScreenshot[]
194
     */
195
    private function convertScreenshotsArraysToScreenshotsObjects(array $screenshotsArrays)
196
    {
197
        return array_map(function (array $screenshotArray) {
198
            return $this->themeScreenshotFactory->createFromArray($screenshotArray);
199
        }, $screenshotsArrays);
200
    }
201
}
202