Passed
Push — main ( 649c5d...191e86 )
by Sammy
01:50
created

LeMarchand::get()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 21
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 1
Metric Value
eloc 9
c 6
b 0
f 1
dl 0
loc 21
rs 9.6111
cc 5
nc 5
nop 1
1
<?php
2
3
namespace HexMakina\LeMarchand;
4
5
use Psr\Container\ContainerInterface;
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
        $dbg['configurations']['template_engine'] = isset($dbg['configurations']['template_engine']) ? get_class($dbg['configurations']['template_engine']) : 'NOT SET';
20
21
        return $dbg;
22
    }
23
24
    public function register($configuration, $instance)
25
    {
26
        $this->configurations[$configuration] = $instance;
27
    }
28
29
    public function has($configuration)
30
    {
31
        return isset($this->configurations[$configuration]);
32
    }
33
34
35
    public function get($configuration)
36
    {
37
        if (!is_string($configuration)) {
38
            throw new \InvalidArgumentException($configuration);
39
        }
40
41
        if ($this->has($configuration)) {
42
            return $this->configurations[$configuration];
43
        }
44
45
        // fallbacks
46
        // 1. configuration data
47
        if (preg_match('/^settings\./', $configuration, $m) === 1) {
48
            return $this->getSettings($configuration);
49
        }
50
        // 2. creating instances
51
        if (preg_match('/.+Controller$/', $configuration, $m) === 1) {
52
            return $this->cascadeControllers($configuration);
53
        }
54
55
        throw new ConfigurationException($configuration);
56
    }
57
58
    private function cascadeControllers($controller_name)
59
    {
60
      foreach ($this->getSettings('settings.controllers_namespaces') as $cns) {
61
          if (!is_null($instance = $this->getInstance($cns . $controller_name))) {
62
              return $instance;
63
          }
64
      }
65
      throw new ConfigurationException($controller_name);
66
    }
67
68
    private function getInstance($class)
69
    {
70
      try{
71
        $rc = new \ReflectionClass($class);
72
        $instance=null;
73
        $construction_args = [];
74
        if (!is_null($rc->getConstructor())) {
75
            foreach ($rc->getConstructor()->getParameters() as $param) {
76
                $construction_args [] = $this->get($param->getType() . '');
77
            }
78
            $instance = $rc->newInstanceArgs($construction_args);
79
        } else {
80
            $instance = $rc->newInstanceArgs();
81
        }
82
83
        if ($rc->hasMethod('set_container')) {
84
            $instance->set_container($this);
85
        }
86
87
        return $instance;
88
      }
89
      catch(\ReflectionException $e)
90
      {
91
        return null;
92
      }
93
    }
94
95
96
    private function getSettings($setting)
97
    {
98
        $ret = $this->configurations;
99
100
      //dot based hierarchy, parse and climb
101
        foreach (explode('.', $setting) as $k) {
102
            if (!isset($ret[$k])) {
103
                throw new ConfigurationException($setting);
104
            }
105
            $ret = $ret[$k];
106
        }
107
108
        return $ret;
109
    }
110
}
111