Completed
Push — develop ( b41f33...6cf259 )
by Mike
07:20
created

ConfigurationFactory::fromFile()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 11
ccs 2
cts 2
cp 1
crap 3
rs 9.9
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of phpDocumentor.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @author    Mike van Riel <[email protected]>
11
 * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com)
12
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
13
 * @link      http://phpdoc.org
14
 */
15
16
namespace phpDocumentor\Application\Configuration;
17
18
use phpDocumentor\Application\Configuration\Factory\Strategy;
19
use phpDocumentor\Application\Configuration\Factory\Version3;
20
use phpDocumentor\DomainModel\Uri;
21
use RuntimeException;
22
23
/**
24
 * The ConfigurationFactory converts the configuration xml from a Uri into an array.
25
 */
26
final class ConfigurationFactory
27
{
28
    /**
29
     * @var Strategy[] All strategies that are used by the ConfigurationFactory.
30
     */
31
    private $strategies = [];
32
33
    /**
34
     * A series of callables that take the configuration array as parameter and should return that array or a modified
35
     * version of it.
36
     *
37
     * @var callable[]
38
     */
39
    private $middlewares = [];
40
    private $defaultFiles = [];
41
42
    /**
43
     * Initializes the ConfigurationFactory.
44
     *
45
     * @param Strategy[]|iterable $strategies
46 3
     * @param array|null $defaultFiles
47
     */
48 3
    public function __construct(iterable $strategies, array $defaultFiles = null)
49 3
    {
50
        if ($defaultFiles === null) {
51
            $defaultFiles = [
52 3
                getcwd() . '/phpdoc.xml',
53 3
                getcwd() . '/phpdoc.dist.xml',
54
                getcwd() . '/phpdoc.xml.dist'
55
            ];
56
        }
57
58 2
        foreach ($strategies as $strategy) {
59
            $this->registerStrategy($strategy);
60 2
        }
61 2
        $this->defaultFiles = $defaultFiles;
62
    }
63
64
    /**
65
     * Adds a middleware callback that allows the consumer to alter the configuration array when it is constructed.
66
     *
67
     * @param callable $middleware
68
     */
69
    public function addMiddleware(callable $middleware): void
70
    {
71 4
        $this->middlewares[] = $middleware;
72
    }
73 4
74
    /**
75 4
     * Attempts to load a configuration from the default locations for phpDocumentor
76
     *
77
     * @return Configuration
78
     */
79 4
    public function fromDefaultLocations(): Configuration
80 4
    {
81 4
        foreach ($this->defaultFiles as $file) {
82
            try {
83
                return $this->fromUri(new Uri($file));
84
            } catch (\InvalidArgumentException $e) {
85
                continue;
86
            }
87
        }
88
89 1
        return new Configuration($this->applyMiddleware(Version3::buildDefault()));
90
    }
91
92 1
    /**
93 1
     * Converts the phpDocumentor configuration xml to an array.
94
     *
95
     * @param Uri $uri The location of the file to be loaded.
96 1
     *
97
     * @return Configuration
98
     * @throws RuntimeException if no matching strategy can be found.
99
     */
100
    public function fromUri(Uri $uri): Configuration
101
    {
102
        $filename = (string) $uri;
103 3
104
        if (!file_exists($filename)) {
105 3
            throw new \InvalidArgumentException(sprintf('File %s could not be found', $filename));
106 3
        }
107
108
        return new Configuration($this->applyMiddleware($this->fromFile($filename)));
109
    }
110
111
    /**
112
     * Adds strategies that are used in the ConfigurationFactory.
113 4
     *
114
     * @param Strategy $strategy
115 4
     */
116 3
    private function registerStrategy(Strategy $strategy): void
117 3
    {
118
        $this->strategies[] = $strategy;
119
    }
120
121 2
    /**
122
     * Converts the given XML structure into an array containing the configuration.
123
     *
124
     * @param string $file the (xml) file that we try to import.
125
     *
126
     * @return array a structure containing all configuration options.
127 3
     *
128
     * @throws RuntimeException
129 3
     */
130 2
    private function fromFile(string $file): array
131
    {
132
        $xml = new \SimpleXMLElement($file, 0, true);
133 3
        foreach ($this->strategies as $strategy) {
134
            if ($strategy->supports($xml) === true) {
135
                return $strategy->convert($xml);
136
            }
137
        }
138
139
        throw new RuntimeException('No strategy found that matches the configuration xml');
140
    }
141
142
    /**
143
     * Applies all middleware callbacks onto the configuration.
144
     *
145
     * @param array $configuration
146
     *
147
     * @return array
148
     */
149
    private function applyMiddleware(array $configuration): array
150
    {
151
        foreach ($this->middlewares as $middleware) {
152
            $configuration = $middleware($configuration);
153
        }
154
155
        return $configuration;
156
    }
157
}
158