Completed
Pull Request — master (#77)
by Thomas
05:39
created

getModuleResources()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 27
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
cc 7
eloc 13
c 0
b 0
f 0
nc 7
nop 3
dl 0
loc 27
ccs 0
cts 13
cp 0
crap 56
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the ekino Drupal Debug project.
7
 *
8
 * (c) ekino
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Ekino\Drupal\Debug\Action;
15
16
use Ekino\Drupal\Debug\Configuration\CacheDirectoryPathConfigurationTrait;
17
use Ekino\Drupal\Debug\Configuration\Model\ActionConfiguration;
18
use Ekino\Drupal\Debug\Configuration\Model\DefaultsConfiguration;
19
use Ekino\Drupal\Debug\Exception\NotImplementedException;
20
use Ekino\Drupal\Debug\Extension\CustomExtensionDiscovery;
21
use Ekino\Drupal\Debug\Extension\Model\CustomModule;
22
use Ekino\Drupal\Debug\Extension\Model\CustomTheme;
23
use Ekino\Drupal\Debug\Option\OptionsInterface;
24
use Ekino\Drupal\Debug\Resource\Model\CustomExtensionFileResource;
25
use Ekino\Drupal\Debug\Resource\Model\ResourcesCollection;
26
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
27
use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;
28
29
abstract class AbstractFileBackendDependantOptions implements OptionsInterface
30
{
31
    use CacheDirectoryPathConfigurationTrait;
32
33
    /**
34
     * @var string
35
     */
36
    private $cacheFilePath;
37
38
    /**
39
     * @var ResourcesCollection
40
     */
41
    private $resourcesCollection;
42
43
    /**
44
     * @var bool|null
45
     */
46
    private static $canHaveBothExtensionTypeFileResourceMasks;
47
48
    /**
49
     * @param string              $cacheFilePath
50
     * @param ResourcesCollection $resourcesCollection
51
     */
52 7
    public function __construct(string $cacheFilePath, ResourcesCollection $resourcesCollection)
53
    {
54 7
        $this->cacheFilePath = $cacheFilePath;
55 7
        $this->resourcesCollection = $resourcesCollection;
56 7
    }
57
58
    /**
59
     * @return string
60
     */
61 1
    public function getCacheFilePath(): string
62
    {
63 1
        return $this->cacheFilePath;
64
    }
65
66
    /**
67
     * @return ResourcesCollection
68
     */
69 1
    public function getResourcesCollection(): ResourcesCollection
70
    {
71 1
        return $this->resourcesCollection;
72
    }
73
74
    /**
75
     * @param string[] $enabledModules
76
     * @param string[] $enabledThemes
77
     *
78
     * @return ResourcesCollection
79
     */
80 2
    public function getFilteredResourcesCollection(array $enabledModules, array $enabledThemes): ResourcesCollection
81
    {
82
        return new ResourcesCollection(\array_filter($this->resourcesCollection->all(), static function (SelfCheckingResourceInterface $resource) use ($enabledModules, $enabledThemes): bool {
83 2
            if (!$resource instanceof CustomExtensionFileResource) {
84 1
                return true;
85
            }
86
87 2
            $customExtension = $resource->getCustomExtension();
88 2
            switch (\get_class($customExtension)) {
89
                case CustomModule::class:
90 1
                    return \in_array($customExtension->getMachineName(), $enabledModules);
91
                case CustomTheme::class:
92 1
                    return \in_array($customExtension->getMachineName(), $enabledThemes);
93
                default:
94 1
                    throw new NotImplementedException(\sprintf('The behavior for the "%s" custom extension file resource class is not implemented.', \get_class($customExtension)));
95
            }
96 2
        }));
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102 18
    public static function addConfiguration(NodeBuilder $nodeBuilder, DefaultsConfiguration $defaultsConfiguration): void
103
    {
104 18
        $childrenNodeBuilders = array($nodeBuilder);
105
106 18
        if ($canHaveBothExtensionTypeFileResourceMasks = self::canHaveBothExtensionTypeFileResourceMasks()) {
107
            $childrenNodeBuilders = array();
108
            foreach (array('module', 'theme') as $extensionType) {
109
                $childrenNodeBuilders[] = $nodeBuilder
110
                    ->arrayNode($extensionType)
111
                        ->children();
112
            }
113
        }
114
115
        /** @var NodeBuilder $childrenNodeBuilder */
116 18
        foreach ($childrenNodeBuilders as $childrenNodeBuilder) {
117
            $childrenNodeBuilder
118 18
                ->booleanNode('include_defaults')
119 18
                    ->defaultTrue()
120 18
                ->end()
121 18
                ->arrayNode('custom_file_resource_masks')
122 18
                    ->scalarPrototype()
123 18
                ->end();
124
125 18
            if ($canHaveBothExtensionTypeFileResourceMasks) {
126
                $childrenNodeBuilder->end();
127
            }
128
        }
129
130 18
        self::addCacheDirectoryPathConfigurationNodeFromDefaultsConfiguration($nodeBuilder, $defaultsConfiguration);
131 18
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public static function getOptions(string $appRoot, ActionConfiguration $actionConfiguration): OptionsInterface
137
    {
138
        $processedConfiguration = $actionConfiguration->getProcessedConfiguration();
139
140
        $resources = array();
141
142
        $customExtensionDiscovery = new CustomExtensionDiscovery($appRoot);
143
144
        if (static::canHaveModuleFileResourceMasks()) {
145
            $includeDefaults = $canHaveBothExtensionTypeFileResourceMasks = self::canHaveBothExtensionTypeFileResourceMasks() ? $processedConfiguration['module']['include_defaults'] : $processedConfiguration['include_defaults'];
146
            $customFileResourceMasks = $canHaveBothExtensionTypeFileResourceMasks ? $processedConfiguration['module']['custom_file_resource_masks'] : $processedConfiguration['custom_file_resource_masks'];
147
148
            $resources = self::getModuleResources($customExtensionDiscovery->getCustomModules(), $includeDefaults, $customFileResourceMasks);
149
        }
150
151
        if (static::canHaveThemeFileResourceMasks()) {
152
            $includeDefaults = $canHaveBothExtensionTypeFileResourceMasks ?? ($canHaveBothExtensionTypeFileResourceMasks = self::canHaveBothExtensionTypeFileResourceMasks() ? $processedConfiguration['theme']['include_defaults'] : $processedConfiguration['include_defaults']);
153
            $customFileResourceMasks = $canHaveBothExtensionTypeFileResourceMasks ? $processedConfiguration['theme']['custom_file_resource_masks'] : $processedConfiguration['custom_file_resource_masks'];
154
155
            $resources = \array_merge($resources, self::getThemeResources($customExtensionDiscovery->getCustomThemes(), $includeDefaults, $customFileResourceMasks));
156
        }
157
158
        return new static(
159
            \sprintf('%s/%s', self::getConfiguredCacheDirectoryPath($actionConfiguration), static::getCacheFileName()),
160
            new ResourcesCollection($resources)
161
        );
162
    }
163
164
    protected static function canHaveModuleFileResourceMasks(): bool
165
    {
166
        return false;
167
    }
168
169
    /**
170
     * @return string[]
171
     */
172
    protected static function getDefaultModuleFileResourceMasks(): array
173
    {
174
        return array();
175
    }
176
177 18
    protected static function canHaveThemeFileResourceMasks(): bool
178
    {
179 18
        return false;
180
    }
181
182
    /**
183
     * @return string[]
184
     */
185
    protected static function getDefaultThemeFileResourceMasks(): array
186
    {
187
        return array();
188
    }
189
190
    /**
191
     * @return string
192
     */
193
    protected static function getCacheFileName(): string
194
    {
195
        return \rtrim((new \ReflectionClass(static::class))->getShortName(), 'Action');
196
    }
197
198
    /**
199
     * @param CustomModule[] $customModules
200
     * @param bool           $includeDefaults
201
     * @param string[]       $fileResourceMasks
202
     *
203
     * @return CustomExtensionFileResource[]
204
     */
205
    private static function getModuleResources(array $customModules, bool $includeDefaults, array $fileResourceMasks): array
206
    {
207
        if (empty($customModules) || (!$includeDefaults && empty($fileResourceMasks))) {
208
            return array();
209
        }
210
211
        $resources = array();
212
213
        if ($includeDefaults) {
214
            $fileResourceMasks = \array_merge($fileResourceMasks, static::getDefaultModuleFileResourceMasks());
215
        }
216
217
        /** @var CustomModule $customModule */
218
        foreach ($customModules as $customModule) {
219
            $replacePairs = array(
220
                '%machine_name%' => $customModule->getMachineName(),
221
                '%camel_case_machine_name%' => $customModule->getCamelCaseMachineName(),
222
            );
223
224
            foreach ($fileResourceMasks as $fileResourceMask) {
225
                $filePath = \sprintf('%s/%s', $customModule->getRootPath(), \strtr($fileResourceMask, $replacePairs));
226
227
                $resources[] = new CustomExtensionFileResource($filePath, $customModule);
228
            }
229
        }
230
231
        return $resources;
232
    }
233
234
    /**
235
     * @param CustomTheme[] $customThemes
236
     * @param bool          $includeDefaults
237
     * @param string[]      $fileResourceMasks
238
     *
239
     * @return CustomExtensionFileResource[]
240
     */
241
    private static function getThemeResources(array $customThemes, bool $includeDefaults, array $fileResourceMasks): array
242
    {
243
        if (empty($customThemes) || (!$includeDefaults && empty($fileResourceMasks))) {
244
            return array();
245
        }
246
247
        $resources = array();
248
249
        if ($includeDefaults) {
250
            $fileResourceMasks = \array_merge($fileResourceMasks, static::getDefaultThemeFileResourceMasks());
251
        }
252
253
        /** @var CustomTheme $customTheme */
254
        foreach ($customThemes as $customTheme) {
255
            $replacePairs = array(
256
                '%machine_name%' => $customTheme->getMachineName(),
257
            );
258
259
            foreach ($fileResourceMasks as $fileResourceMask) {
260
                $filePath = \sprintf('%s/%s', $customTheme->getRootPath(), \strtr($fileResourceMask, $replacePairs));
261
262
                $resources[] = new CustomExtensionFileResource($filePath, $customTheme);
263
            }
264
        }
265
266
        return $resources;
267
    }
268
269 18
    private static function canHaveBothExtensionTypeFileResourceMasks(): bool
270
    {
271 18
        if (!\is_bool(self::$canHaveBothExtensionTypeFileResourceMasks)) {
272 18
            self::$canHaveBothExtensionTypeFileResourceMasks = static::canHaveModuleFileResourceMasks() && static::canHaveThemeFileResourceMasks();
273
        }
274
275 18
        return self::$canHaveBothExtensionTypeFileResourceMasks;
276
    }
277
}
278