Completed
Push — develop ( 722f70...af048b )
by Jaap
15:12 queued 05:04
created

Application/Configuration/ConfigurationFactory.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * This file is part of phpDocumentor.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @copyright 2010-2015 Mike van Riel<[email protected]>
9
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
10
 * @link      http://phpdoc.org
11
 */
12
13
namespace phpDocumentor\Application\Configuration;
14
15
use phpDocumentor\Application\Configuration\Factory\Strategy;
16
use phpDocumentor\DomainModel\Uri;
17
18
/**
19
 * The ConfigurationFactory converts the configuration xml from a Uri into an array.
20
 */
21
class ConfigurationFactory
22
{
23
    /** @var Uri The Uri that contains the path to the configuration file. */
24
    private $uri;
25
26
    /** @var string[] The cached configuration as an array so that we improve performance */
27
    private $cachedConfiguration = [];
28
29
    /** @var Strategy[] All strategies that are used by the ConfigurationFactory. */
30
    private $strategies = [];
31
32
    /**
33
     * A series of callables that take the configuration array as parameter and should return that array or a modified
34
     * version of it.
35
     *
36
     * @var callable[]
37
     */
38
    private $middlewares = [];
39
40
    /**
41
     * Initializes the ConfigurationFactory.
42
     *
43
     * @param Strategy[] $strategies
44
     * @param Uri        $uri
45
     * @param callable[] $middlewares
46
     */
47
    public function __construct(array $strategies, Uri $uri, array $middlewares = [])
48
    {
49
        foreach ($strategies as $strategy) {
50
            $this->registerStrategy($strategy);
51
        }
52
53
        $this->replaceLocation($uri);
54
        $this->middlewares = $middlewares;
55
    }
56
57
    /**
58
     * Adds a middleware callback that allows the consumer to alter the configuration array when it is constructed.
59
     *
60
     * @param callable $middleware
61
     *
62
     * @return void
63
     */
64
    public function addMiddleware(callable $middleware)
65
    {
66
        $this->middlewares[] = $middleware;
67
68
        // Middleware's changed; we must rebuild the cache
69
        $this->clearCache();
70
    }
71
72
    /**
73
     * Replaces the location of the configuration file if it differs from the existing one.
74
     *
75
     * @param Uri $uri
76
     *
77
     * @return void
78
     */
79
    public function replaceLocation(Uri $uri)
80
    {
81
        if (!isset($this->uri) || !$this->uri->equals($uri)) {
82
            $this->uri = $uri;
83
            $this->clearCache();
84
        }
85
    }
86
87
    /**
88
     * Converts the phpDocumentor configuration xml to an array.
89
     *
90
     * @return array
91
     *
92
     * @throws \RuntimeException if no matching strategy can be found.
93
     */
94
    public function get()
95
    {
96
        if ($this->cachedConfiguration) {
97
            return $this->cachedConfiguration;
98
        }
99
100
        $xml = new \SimpleXMLElement($this->uri, 0, true);
101
        $this->cachedConfiguration = $this->extractConfigurationArray($xml);
102
        $this->applyMiddleware();
103
104
        return $this->cachedConfiguration;
105
    }
106
107
    /**
108
     * Clears the cache for the configuration.
109
     *
110
     * @return null
111
     */
112
    public function clearCache()
113
    {
114
        return $this->cachedConfiguration = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array<integer,string> of property $cachedConfiguration.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
115
    }
116
117
    /**
118
     * Adds strategies that are used in the ConfigurationFactory.
119
     *
120
     * @param Strategy $strategy
121
     *
122
     * @return void
123
     */
124
    private function registerStrategy(Strategy $strategy)
125
    {
126
        $this->strategies[] = $strategy;
127
    }
128
129
    /**
130
     * Converts the given XML structure into an array containing the configuration.
131
     *
132
     * @param \SimpleXMLElement $xml
133
     *
134
     * @return array
135
     */
136
    private function extractConfigurationArray($xml)
137
    {
138
        foreach ($this->strategies as $strategy) {
139
            if ($strategy->match($xml) === true) {
140
                return $strategy->convert($xml);
141
            }
142
        };
143
144
        throw new \RuntimeException('No strategy found that matches the configuration xml');
145
    }
146
147
    /**
148
     * Applies all middleware callbacks onto the configuration.
149
     */
150
    private function applyMiddleware()
151
    {
152
        foreach ($this->middlewares as $middleware) {
153
            $this->cachedConfiguration = $middleware($this->cachedConfiguration);
154
        }
155
    }
156
}
157