Completed
Push — master ( d234f3...0a4926 )
by Jan Philipp
47s queued 12s
created

ConfigFactory   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 5
dl 0
loc 118
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
B loadImports() 0 34 6
A mergeConfigs() 0 10 2
A __construct() 0 11 1
A gatherConfigs() 0 31 5
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Psh\Config;
4
5
use function array_merge;
6
use function array_pop;
7
use function array_shift;
8
use function count;
9
use function dirname;
10
use function glob;
11
use function is_dir;
12
13
class ConfigFactory
14
{
15
    /**
16
     * @var ConfigMerger
17
     */
18
    private $configMerger;
19
20
    /**
21
     * @var ConfigFileFinder
22
     */
23
    private $configFileFinder;
24
25
    /**
26
     * @var ConfigFileLoader[]
27
     */
28
    private $configLoaders;
29
30
    /**
31
     * @var ConfigLogger
32
     */
33
    private $configLogger;
34
35
    public function __construct(
36
        ConfigMerger $configMerger,
37
        ConfigFileFinder $configFileFinder,
38
        ConfigLogger $configLogger,
39
        array $configLoaders
40
    ) {
41
        $this->configMerger = $configMerger;
42
        $this->configFileFinder = $configFileFinder;
43
        $this->configLoaders = $configLoaders;
44
        $this->configLogger = $configLogger;
45
    }
46
47
    /**
48
     * @return Config[]
49
     */
50
    public function gatherConfigs(
51
        array $configFiles,
52
        array $overwrittenConsts
53
    ): array {
54
        $configs = [];
55
        $additionalConfigs = [[]];
56
57
        foreach ($configFiles as $configFile) {
58
            foreach ($this->configLoaders as $configLoader) {
59
                if (!$configLoader->isSupported($configFile)) {
60
                    continue;
61
                }
62
63
                $config = $configLoader
64
                    ->load($configFile, $overwrittenConsts);
65
66
                $additionalConfigs[] = $this
67
                    ->loadImports($config, dirname($configFile), $overwrittenConsts);
68
69
                $configs[] = $config;
70
            }
71
        }
72
73
        if (!$configs) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $configs 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...
74
            return [];
75
        }
76
77
        $config = $this->configMerger->mergeOverride(...$configs);
0 ignored issues
show
Documentation introduced by
$configs is of type array, but the function expects a object<Shopware\Psh\Config\Config>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
78
79
        return array_merge([$config], ...array_merge(...$additionalConfigs));
80
    }
81
82
    private function loadImports(
83
        Config $config,
84
        string $fromPath,
85
        array $overwrittenConsts
86
    ): array {
87
        $additionalConfigs = [];
88
89
        foreach ($config->getImports() as $importPath) {
90
            $foundSomething = false;
91
            foreach (glob($fromPath . '/' . $importPath) as $foundOccurrence) {
92
                if (!is_dir($foundOccurrence)) {
93
                    continue;
94
                }
95
96
                $foundConfigFiles = $this->configFileFinder
97
                    ->discoverConfigInDirectory($foundOccurrence);
98
99
                if (count($foundConfigFiles) === 0) {
100
                    continue;
101
                }
102
103
                $foundSomething = true;
104
                $this->configLogger->importConfigFiles($importPath, ...$foundConfigFiles);
0 ignored issues
show
Documentation introduced by
$foundConfigFiles is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
105
                $additionalConfigs[] = $this
106
                    ->gatherConfigs($foundConfigFiles, $overwrittenConsts);
107
            }
108
109
            if (!$foundSomething) {
110
                $this->configLogger->notifyImportNotFound($importPath);
111
            }
112
        }
113
114
        return $additionalConfigs;
115
    }
116
117
    /**
118
     * @param Config[] $configs
119
     */
120
    public function mergeConfigs(array $configs): Config
121
    {
122
        $mainConfig = array_shift($configs);
123
124
        while (count($configs) !== 0) {
125
            $mainConfig = $this->configMerger->mergeImport($mainConfig, array_pop($configs));
0 ignored issues
show
Bug introduced by
It seems like $mainConfig can be null; however, mergeImport() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
126
        }
127
128
        return $mainConfig;
129
    }
130
}
131