Completed
Push — 1.x ( f31c2f...718f40 )
by Akihito
77:59 queued 73:47
created

AppInjector::getOverrideInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 3
crap 1
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 BEAR\Package\Provide\Resource\ResourceObjectModule;
13
use Ray\Compiler\DiCompiler;
14
use Ray\Compiler\Exception\NotCompiled;
15
use Ray\Compiler\ScriptInjector;
16
use Ray\Di\AbstractModule;
17
use Ray\Di\Injector;
18
use Ray\Di\InjectorInterface;
19
use Ray\Di\Name;
20
21
final class AppInjector implements InjectorInterface
22
{
23
    /**
24
     * @var AbstractModule
25
     */
26
    private $appModule;
27
28
    /**
29
     * @var string
30
     */
31
    private $scriptDir;
32
33
    /**
34
     * @var string
35
     */
36
    private $logDir;
37
38 20
    public function __construct($name, $contexts)
39
    {
40 20
        $appMeta = new AppMeta($name, $contexts);
41 20
        $this->scriptDir = $appMeta->tmpDir;
42 20
        $this->logDir = $appMeta->logDir;
43 20
        $this->appModule = $this->newModule($appMeta, $contexts);
44 18
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49 17
    public function getInstance($interface, $name = Name::ANY)
50
    {
51
        try {
52 17
            return $this->getInjector()->getInstance($interface, $name);
53 1
        } catch (NotCompiled $e) {
54 1
            file_put_contents(sprintf('%s/%s', $this->logDir, 'compile-err.log'), (string) $e);
55
56 1
            throw $e;
57
        }
58
    }
59
60 1
    public function getOverrideInstance(AbstractModule $module, $inteface, $name = Name::ANY)
61
    {
62 1
        $appModule = clone $this->appModule;
63 1
        $appModule->override($module);
64
65 1
        return (new Injector($appModule, $this->scriptDir))->getInstance($inteface, $name);
66
    }
67
68 17
    private function getInjector() : InjectorInterface
69
    {
70 17
        $scriptInjector = new ScriptInjector($this->scriptDir);
71
        try {
72 17
            $injector = $scriptInjector->getInstance(InjectorInterface::class);
73 5
        } catch (NotCompiled $e) {
74 5
            $this->compile($this->appModule, $this->scriptDir);
75 5
            $injector = $scriptInjector->getInstance(InjectorInterface::class);
76
        }
77
78 17
        return $injector;
79
    }
80
81 5
    private function compile(AbstractModule $module, string $scriptDir)
82
    {
83 5
        $compiler = new DiCompiler($module, $scriptDir);
84 5
        $compiler->compile();
85 5
    }
86
87
    /**
88
     * Return configured module
89
     */
90 20
    private function newModule(AbstractAppMeta $appMeta, string $contexts) : AbstractModule
91
    {
92 20
        $contextsArray = array_reverse(explode('-', $contexts));
93 20
        $module = null;
94 20
        foreach ($contextsArray as $context) {
95 20
            $class = $appMeta->name . '\Module\\' . ucwords($context) . 'Module';
96 20
            if (! class_exists($class)) {
97 18
                $class = 'BEAR\Package\Context\\' . ucwords($context) . 'Module';
98
            }
99 20
            if (! is_a($class, AbstractModule::class, true)) {
100 2
                throw new InvalidContextException($class);
101
            }
102
            /* @var $module AbstractModule */
103 18
            $module = new $class($module);
104
        }
105 18
        $module->install(new ResourceObjectModule($appMeta));
106 18
        $module->override(new AppMetaModule($appMeta));
107
108 18
        return $module;
109
    }
110
}
111