Completed
Push — 1.x ( ca984d...e868bf )
by Akihito
11s
created

AppInjector::newModule()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 18
ccs 11
cts 11
cp 1
rs 9.2
cc 4
eloc 11
nc 5
nop 2
crap 4
1
<?php
2
/**
3
 * This file is part of the BEAR.Package package.
4
 *
5
 * @license http://opensource.org/licenses/MIT MIT
6
 */
7
namespace BEAR\Package;
8
9
use BEAR\AppMeta\AbstractAppMeta;
10
use BEAR\AppMeta\AppMeta;
11
use BEAR\Package\Exception\InvalidContextException;
12
use Ray\Compiler\DiCompiler;
13
use Ray\Compiler\Exception\NotCompiled;
14
use Ray\Compiler\ScriptInjector;
15
use Ray\Di\AbstractModule;
16
use Ray\Di\InjectorInterface;
17
use Ray\Di\Name;
18
19
final class AppInjector implements InjectorInterface
20
{
21
    /**
22
     * @var InjectorInterface
23
     */
24
    private $injector;
25
26
    /**
27
     * @var AppMeta
28
     */
29
    private $appMeta;
30
31 8
    public function __construct($name, $contexts)
32
    {
33 8
        $this->appMeta = new AppMeta($name, $contexts);
34 8
        $this->injector = $this->getInjector($this->appMeta, $contexts);
35 6
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40 6
    public function getInstance($interface, $name = Name::ANY)
41
    {
42
        try {
43 6
            return $this->injector->getInstance($interface, $name);
44 1
        } catch (NotCompiled $e) {
45 1
            file_put_contents(sprintf('%s/%s', $this->appMeta->logDir, 'compile-err.log'), (string) $e);
46
47 1
            throw $e;
48
        }
49
    }
50
51
    /**
52
     * @param AbstractAppMeta $appMeta
53
     * @param string          $contexts
54
     *
55
     * @return InjectorInterface
56
     */
57 8
    private function getInjector(AbstractAppMeta $appMeta, $contexts)
58
    {
59 8
        $module = $this->newModule($appMeta, $contexts);
60 6
        $module->override(new AppMetaModule($appMeta));
61 6
        $tmpDir = $appMeta->tmpDir;
62
        try {
63 6
            $injector = (new ScriptInjector($tmpDir))->getInstance(InjectorInterface::class);
64 4
        } catch (NotCompiled $e) {
65 4
            $compiler = new DiCompiler($module, $tmpDir);
66 4
            $compiler->compile();
67 4
            $injector = (new ScriptInjector($tmpDir))->getInstance(InjectorInterface::class);
68
        }
69
70 6
        return $injector;
71
    }
72
73
    /**
74
     * Return configured module
75
     *
76
     * @param AbstractAppMeta $appMeta
77
     * @param string          $contexts
78
     *
79
     * @return AbstractModule
80
     */
81 8
    private function newModule(AbstractAppMeta $appMeta, $contexts)
82
    {
83 8
        $contextsArray = array_reverse(explode('-', $contexts));
84 8
        $module = null;
85 8
        foreach ($contextsArray as $context) {
86 8
            $class = $appMeta->name . '\Module\\' . ucwords($context) . 'Module';
87 8
            if (! class_exists($class)) {
88 6
                $class = 'BEAR\Package\Context\\' . ucwords($context) . 'Module';
89
            }
90 8
            if (! is_a($class, AbstractModule::class, true)) {
91 2
                throw new InvalidContextException($class);
92
            }
93
            /* @var $module AbstractModule */
94 6
            $module = new $class($module);
95
        }
96
97 6
        return $module;
98
    }
99
}
100