Passed
Push — master ( f2e35b...cd03c9 )
by Allan
04:05 queued 15s
created

ConfigFactory::create()   B

Complexity

Conditions 8
Paths 18

Size

Total Lines 45
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 26
nc 18
nop 1
dl 0
loc 45
rs 8.4444
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright © Vaimo Group. All rights reserved.
4
 * See LICENSE_VAIMO.txt for license details.
5
 */
6
namespace Vaimo\ComposerPatches\Factories;
7
8
use Vaimo\ComposerPatches\Config as PluginConfig;
9
use Vaimo\ComposerPatches\Environment;
10
11
class ConfigFactory
12
{
13
    /**
14
     * @var \Composer\Composer
15
     */
16
    private $composer;
17
18
    /**
19
     * @var \Vaimo\ComposerPatches\Config\Defaults
20
     */
21
    private $defaultsProvider;
22
23
    /**
24
     * @var \Vaimo\ComposerPatches\Utils\ConfigUtils
25
     */
26
    private $configUtils;
27
28
    /**
29
     * @var \Vaimo\ComposerPatches\Config\Context
30
     */
31
    private $context;
32
33
    /**
34
     * @var array
35
     */
36
    private $defaults;
37
    
38
    /**
39
     * @var \Vaimo\ComposerPatches\Utils\DataUtils
40
     */
41
    private $dataUtils;
42
    
43
    /**
44
     * @param \Composer\Composer $composer
45
     * @param array $defaults
46
     */
47
    public function __construct(
48
        \Composer\Composer $composer,
49
        array $defaults = array()
50
    ) {
51
        $this->composer = $composer;
52
        $this->defaults = $defaults;
53
54
        $this->defaultsProvider = new \Vaimo\ComposerPatches\Config\Defaults();
55
        $this->configUtils = new \Vaimo\ComposerPatches\Utils\ConfigUtils();
56
        $this->context = new \Vaimo\ComposerPatches\Config\Context();
57
        $this->dataUtils = new \Vaimo\ComposerPatches\Utils\DataUtils();
58
    }
59
60
    public function create(array $configSources = array())
61
    {
62
        $composer = $this->composer;
63
64
        $defaults = array_replace(
65
            $this->defaultsProvider->getPatcherConfig(),
66
            $this->defaults,
67
            array_filter(array(PluginConfig::PATCHER_GRACEFUL => (bool)getenv(Environment::GRACEFUL_MODE)))
68
        );
69
70
        $extra = $composer->getPackage()->getExtra();
71
72
        if (isset($extra['patcher-config']) && !isset($extra[PluginConfig::PATCHER_CONFIG_ROOT])) {
73
            $extra[PluginConfig::PATCHER_CONFIG_ROOT] = $extra['patcher-config'];
74
        }
75
76
        $subConfigKeys = array(
77
            $this->context->getOperationSystemName(),
78
            $this->context->getOperationSystemFamily(),
79
            '',
80
        );
81
82
        foreach (array_unique($subConfigKeys) as $key) {
83
            $configRootKey = PluginConfig::PATCHER_CONFIG_ROOT . ($key ? ('-' . $key) : '');
84
85
            $patcherConfig = $this->resolvePatcherConfigBase($extra, $configRootKey);
86
            
87
            if (isset($patcherConfig['patchers']) && !isset($patcherConfig[PluginConfig::PATCHER_APPLIERS])) {
88
                $patcherConfig[PluginConfig::PATCHER_APPLIERS] = $patcherConfig['patchers'];
89
                unset($patcherConfig['patchers']);
90
            }
91
            
92
            if ($patcherConfig) {
93
                array_unshift($configSources, $patcherConfig);
94
            }
95
        }
96
97
        $config = array_reduce(
98
            $configSources,
99
            array($this->configUtils, 'mergeApplierConfig'),
100
            $defaults
101
        );
102
        
103
        return new PluginConfig(
104
            $this->resolveValidSubOperations($config, $subConfigKeys)
105
        );
106
    }
107
    
108
    private function resolvePatcherConfigBase(array $extra, $rootKey)
109
    {
110
        $patcherConfig = isset($extra[$rootKey]) ? $extra[$rootKey] : array();
111
112
        if ($patcherConfig === false) {
113
            $patcherConfig = array(
114
                PluginConfig::PATCHER_SOURCES => false
115
            );
116
        }
117
        
118
        if (!isset($patcherConfig[PluginConfig::PATCHER_SOURCES])) {
119
            if (isset($extra['enable-patching']) && !$extra['enable-patching']) {
120
                $patcherConfig[PluginConfig::PATCHER_SOURCES] = false;
121
            } elseif (isset($extra['enable-patching-from-packages']) && !$extra['enable-patching-from-packages']) {
122
                $patcherConfig[PluginConfig::PATCHER_SOURCES] = array('packages' => false, 'vendors' => false);
123
            }
124
        }
125
        
126
        return $patcherConfig;
127
    }
128
    
129
    private function resolveValidSubOperations(array $config, array $subConfigKeys)
130
    {
131
        $subOperationKeys = array_merge(
132
            array_filter($subConfigKeys),
133
            array(PluginConfig::OS_DEFAULT)
134
        );
135
136
        $baseOperations = $config[PluginConfig::PATCHER_APPLIERS][PluginConfig::APPLIER_DEFAULT];
137
138
        foreach ($config[PluginConfig::PATCHER_APPLIERS] as $applierCode => $operations) {
139
            if ($applierCode === PluginConfig::APPLIER_DEFAULT) {
140
                continue;
141
            }
142
143
            $operations = array_replace($baseOperations, $operations);
144
145
            foreach ($operations as $opCode => $operation) {
146
                if (!is_array($operation)) {
147
                    continue;
148
                }
149
150
                if (array_filter($operation, 'is_numeric')) {
151
                    continue;
152
                }
153
154
                $subOperations = $this->dataUtils->extractOrderedItems($operation, $subOperationKeys);
155
156
                if (!$subOperations) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $subOperations of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
157
                    continue;
158
                }
159
160
                $config[PluginConfig::PATCHER_APPLIERS][$applierCode][$opCode] = reset($subOperations);
161
            }
162
        }
163
        
164
        return $config;
165
    }
166
}
167