Passed
Pull Request — develop (#44)
by Kevin
02:41
created

MagiumConfigurationFactory::setContext()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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