Passed
Push — main ( d73681...8fb716 )
by Sammy
01:46
created

LeMarchand   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Importance

Changes 13
Bugs 2 Features 2
Metric Value
wmc 26
eloc 55
c 13
b 2
f 2
dl 0
loc 120
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A __debugInfo() 0 8 2
A register() 0 3 1
A has() 0 11 3
A getSettings() 0 13 3
A cascadeControllers() 0 13 4
A getInstance() 0 22 5
B get() 0 25 7
1
<?php
2
3
namespace HexMakina\LeMarchand;
4
5
use Psr\Container\{ContainerInterface, ContainerExceptionInterface, NotFoundExceptionInterface};
6
7
class LeMarchand implements ContainerInterface
8
{
9
    private $configurations = [];
10
11
    public function __construct($settings)
12
    {
13
        $this->configurations['settings'] = $settings;
14
    }
15
16
    public function __debugInfo(): array
17
    {
18
        $dbg = get_object_vars($this);
19
        if (isset($dbg['configurations']['template_engine'])) {
20
          // way too long of an object
21
            $dbg['configurations']['template_engine'] = get_class($dbg['configurations']['template_engine']);
22
        }
23
        return $dbg;
24
    }
25
26
    public function register($configuration, $instance)
27
    {
28
        $this->configurations[$configuration] = $instance;
29
    }
30
31
    public function has($configuration)
32
    {
33
      try{
34
        $this->get($configuration);
35
        return true;
36
      }
37
      catch(NotFoundExceptionInterface $e){
38
        return false;
39
      }
40
      catch(ContainerExceptionInterface $e){
41
        return false;
42
      }
43
    }
44
45
46
    public function get($configuration)
47
    {
48
        if (!is_string($configuration)) {
49
            throw new LamentException($configuration);
50
        }
51
        // 1. is it a first level key ?
52
        if (isset($this->configurations[$configuration])) {
53
            return $this->configurations[$configuration];
54
        }
55
56
        // 2. is it configuration data ?
57
        if (preg_match('/^settings\./', $configuration, $m) === 1) {
58
            return $this->getSettings($configuration);
59
        }
60
        // 3. is it a controller ?
61
        if (preg_match('/.+Controller$/', $configuration, $m) === 1) {
62
            return $this->cascadeControllers($configuration);
63
        }
64
        if (preg_match('/.+Interface$/', $configuration, $m) === 1) {
65
            $wire = $this->get('settings.interface_implementations');
66
            if(isset($wire[$configuration]))
67
              return $this->getInstance($wire[$configuration]);
68
        }
69
70
        throw new ConfigurationException($configuration);
71
    }
72
73
    private function cascadeControllers($controller_name)
74
    {
75
        // is the controller name already instantiable ?
76
        if (!is_null($instance = $this->getInstance($controller_name))) {
77
            return $instance;
78
        }
79
        // not fully namespaced, lets cascade
80
        foreach ($this->getSettings('settings.controller_namespaces') as $cns) {
81
            if (!is_null($instance = $this->getInstance($cns . $controller_name))) {
82
                return $instance;
83
            }
84
        }
85
        throw new ConfigurationException($controller_name);
86
    }
87
88
    private function getInstance($class)
89
    {
90
        try {
91
            $rc = new \ReflectionClass($class);
92
            $instance = null;
93
            $construction_args = [];
94
            if (!is_null($rc->getConstructor())) {
95
                foreach ($rc->getConstructor()->getParameters() as $param) {
96
                    $construction_args [] = $this->get($param->getType() . '');
97
                }
98
                $instance = $rc->newInstanceArgs($construction_args);
99
            } else {
100
                $instance = $rc->newInstanceArgs();
101
            }
102
103
            if ($rc->hasMethod('set_container')) {
104
                $instance->set_container($this);
105
            }
106
107
            return $instance;
108
        } catch (\ReflectionException $e) {
109
            return null;
110
        }
111
    }
112
113
114
    private function getSettings($setting)
115
    {
116
        $ret = $this->configurations;
117
118
      //dot based hierarchy, parse and climb
119
        foreach (explode('.', $setting) as $k) {
120
            if (!isset($ret[$k])) {
121
                throw new ConfigurationException($setting);
122
            }
123
            $ret = $ret[$k];
124
        }
125
126
        return $ret;
127
    }
128
}
129