Passed
Pull Request — develop (#19)
by Kevin
02:49
created

MagiumConfigurationFactory   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 7

Test Coverage

Coverage 89.77%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 30
lcom 2
cbo 7
dl 0
loc 164
ccs 79
cts 88
cp 0.8977
rs 10
c 2
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 25 7
A buildContextFile() 0 19 4
A getContextFile() 0 7 2
A validateConfigurationFile() 0 12 2
A getCache() 0 5 1
A getBuilderFactory() 0 16 4
A getBuilder() 0 7 2
A getRemoteCache() 0 6 1
A getLocalCache() 0 9 2
B getManager() 0 25 5
1
<?php
2
3
namespace Magium\Configuration;
4
5
use Magium\Configuration\Config\Builder;
6
use Magium\Configuration\Config\BuilderFactory;
7
use Magium\Configuration\Config\BuilderFactoryInterface;
8
use Magium\Configuration\Config\BuilderInterface;
9
use Magium\Configuration\Config\InvalidConfigurationLocationException;
10
use Magium\Configuration\Config\MissingConfigurationException;
11
use Magium\Configuration\File\Context\AbstractContextConfigurationFile;
12
use Magium\Configuration\Manager\CacheFactory;
13
use Magium\Configuration\Manager\Manager;
14
use Magium\Configuration\Manager\ManagerInterface;
15
16
class MagiumConfigurationFactory implements MagiumConfigurationFactoryInterface
17
{
18
    protected $file;
19
    protected $xml;
20
21
    protected $manager;
22
    protected $builder;
23
    protected $baseDir;
24
    protected $contextFile;
25
    protected $builderFactory;
26
27 13
    public function __construct($magiumConfigurationFile = null)
28
    {
29 13
        if (!$magiumConfigurationFile) {
30 5
            $cwd = __DIR__;
31 5
            $baseDir = realpath(DIRECTORY_SEPARATOR);
32 5
            while ($cwd && $cwd != $baseDir && file_exists($cwd)) {
33 5
                $checkFile = $cwd . DIRECTORY_SEPARATOR . 'magium-configuration.xml';
34 5
                if (file_exists($checkFile)) {
35 4
                    $magiumConfigurationFile = $checkFile;
36 4
                    break;
37
                }
38 5
                $lastPos = strrpos($cwd, DIRECTORY_SEPARATOR);
39 5
                $cwd = substr($cwd, 0, $lastPos);
40
            }
41
        }
42
43 13
        if (file_exists($magiumConfigurationFile)) {
44 12
            $this->file = realpath($magiumConfigurationFile);
45
        } else {
46 1
            throw new InvalidConfigurationFileException('Unable to file configuration file: ' . $magiumConfigurationFile);
47
        }
48 12
        $this->baseDir = dirname($this->file);
49 12
        chdir($this->baseDir);
50 12
        $this->xml = simplexml_load_file($magiumConfigurationFile);
51 12
    }
52
53 3
    protected function buildContextFile()
54
    {
55 3
        chdir($this->baseDir);
56 3
        $contextFileCheck = (string)$this->xml->contextConfigurationFile['file'];
57 3
        $contextFileType = (string)$this->xml->contextConfigurationFile['type'];
58 3
        $contextFile = realpath($contextFileCheck);
59 3
        if (!$contextFile) {
60 1
            throw new MissingConfigurationException('Unable to find context file: ' . $contextFileCheck);
61
        }
62 2
        $class = 'Magium\Configuration\File\Context\\' . ucfirst($contextFileType) . 'File';
63 2
        $reflectionClass = new \ReflectionClass($class);
64 2
        if ($reflectionClass->isSubclassOf(AbstractContextConfigurationFile::class)) {
65 1
            $instance = $reflectionClass->newInstance($contextFile);
66 1
            if ($instance instanceof AbstractContextConfigurationFile) {
67 1
                return $instance;
68
            }
69
        }
70 1
        throw new InvalidConfigurationException('Unable to load context configuration file: ' . $contextFileCheck);
71
    }
72
73 3
    public function getContextFile()
74
    {
75 3
        if (!$this->contextFile instanceof AbstractContextConfigurationFile) {
76 3
            $this->contextFile = $this->buildContextFile();
77
        }
78 1
        return $this->contextFile;
79
    }
80
81 2
    public function validateConfigurationFile()
82
    {
83 2
        $result = false;
84
        try {
85 2
            $doc = new \DOMDocument();
86 2
            $doc->load($this->file);
87 2
            $result = $doc->schemaValidate(__DIR__ . '/../assets/magium-configuration.xsd');
88 1
        } catch (\Exception $e) {
89
            // $result value is already set
90
        }
91 2
        return $result;
92
    }
93
94
    /**
95
     * Retrieves an instance of the cache based off of the XML cache configuration
96
     *
97
     * @param \SimpleXMLElement $element
98
     * @return \Zend\Cache\Storage\StorageInterface
99
     */
100
101 1
    protected function getCache(\SimpleXMLElement $element)
102
    {
103 1
        $cacheFactory = new CacheFactory();
104 1
        return $cacheFactory->getCache($element);
105
    }
106
107 3
    public function getBuilderFactory()
108
    {
109 3
        if (!$this->builderFactory instanceof BuilderFactoryInterface) {
110 3
            $builderFactoryConfig = $this->xml->builderFactory;
111 3
            $class = (string)$builderFactoryConfig['class'];
112 3
            if (!$class) {
113 2
                $class = BuilderFactory::class; // das default
114
            }
115 3
            $reflection = new \ReflectionClass($class);
116 3
            if (!$reflection->implementsInterface(BuilderFactoryInterface::class)) {
117 1
                throw new InvalidConfigurationException($class . ' must implement ' . BuilderFactoryInterface::class);
118
            }
119 2
            $this->builderFactory = $reflection->newInstance($this->xml);
120
        }
121 2
        return $this->builderFactory;
122
    }
123
124
    /**
125
     * @return BuilderInterface
126
     */
127
128 2
    public function getBuilder()
129
    {
130 2
        if (!$this->builder instanceof BuilderInterface) {
131 2
            $this->builder = $this->getBuilderFactory()->getBuilder();
132
        }
133 1
        return $this->builder;
134
    }
135
136 3
    protected function getRemoteCache()
137
    {
138 3
        $cacheConfig = $this->xml->cache;
139 3
        $globalAdapter = $this->getCache($cacheConfig);
140 3
        return $globalAdapter;
141
    }
142
143 4
    protected function getLocalCache()
144
    {
145 4
        $localCache = null;
146 4
        $localCacheConfig = $this->xml->localCache;
147 4
        if ($localCacheConfig) {
148 1
            $localCache = $this->getCache($localCacheConfig);
149
        }
150 4
        return $localCache;
151
    }
152
153 4
    public function getManager()
154
    {
155 4
        if (!$this->manager instanceof ManagerInterface) {
156 4
            $managerClass = Manager::class;
157 4
            if (isset($this->xml->manager['class'])) {
158
                $managerClass = $this->xml->manager['class'];
159
            }
160 4
            $reflectionClass = new \ReflectionClass($managerClass);
161 4
            if ($managerClass == Manager::class) {
162
                // just a shortcut so I don't have to rewrite some complicated unit tests.  I'm just lazy.
163 4
                $this->manager = new Manager($this->getLocalCache(), $this->getBuilder(), $this->getRemoteCache());
164 3
                return $this->manager;
165
            }
166
            if (!$reflectionClass->implementsInterface(ManagerInterface::class)) {
167
                throw new InvalidConfigurationException('Manager class must implement ' . ManagerInterface::class);
168
            }
169
            $manager = $reflectionClass->newInstance();
170
            /* @var $manager ManagerInterface */
171
            $manager->setBuilder($this->getBuilder());
172
            $manager->setLocalCache($this->getLocalCache());
0 ignored issues
show
Bug introduced by
It seems like $this->getLocalCache() can be null; however, setLocalCache() 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...
173
            $manager->setRemoteCache($this->getRemoteCache());
174
            $this->manager = $manager;
175
        }
176
        return $this->manager;
177
    }
178
179
}
180