Passed
Push — develop ( a6220b...8d9e7b )
by Kevin
06:18 queued 02:39
created

MagiumConfigurationFactory::getManager()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 5

Importance

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