Passed
Push — develop ( 91c1d2...446210 )
by Schlaefer
41s
created

Container   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 14
lcom 2
cbo 2
dl 0
loc 102
ccs 34
cts 34
cp 1
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setInstance() 0 4 1
A getInstance() 0 4 1
A has() 0 4 1
A get() 0 17 4
A set() 0 7 2
A typeCheck() 0 12 4
1
<?php
2
/**
3
 * @author PhileCMS
4
 * @link https://github.com/PhileCMS/Phile
5
 * @license http://opensource.org/licenses/MIT
6
 */
7
8
namespace Phile\Core;
9
10
use Psr\Container\ContainerInterface;
11
use Phile\Exception\ContainerNotFoundException as NotFoundException;
12
13
/**
14
 * Implements a simple PSR-11 container
15
 */
16
class Container implements ContainerInterface
17
{
18
    protected $config = [];
19
20
    /** @var ContainerInterface */
21
    protected static $instance;
22
23
    /** @var array raw items */
24
    protected $raw = [];
25
26
    /** @var evaluated items */
27
    protected $build = [];
28
29 30
    public function __construct($config = [])
30
    {
31 30
        $this->config = $config;
32 30
    }
33
34
    /**
35
     * Sets instance for static usage
36
     *
37
     * @param ContainerInterface $instance
38
     */
39 27
    public static function setInstance(ContainerInterface $instance)
40
    {
41 27
        self::$instance = $instance;
42 27
    }
43
44
    /**
45
     * Gets instance for static usage
46
     *
47
     * @return ContainerInterface
48
     */
49 53
    public static function getInstance()
50
    {
51 53
        return self::$instance;
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 55
    public function has($id)
58
    {
59 55
        return array_key_exists($id, $this->raw);
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65 49
    public function get($id)
66
    {
67 49
        if (!$this->has($id)) {
68 1
            throw new NotFoundException(
69 1
                sprintf('Item "%s" not found in Container.', $id),
70 1
                1519111836
71
            );
72
        }
73 48
        if (!is_callable($this->raw[$id])) {
74 48
            return $this->raw[$id];
75
        }
76 32
        if (!isset($this->build[$id])) {
77 27
            $this->build[$id] = call_user_func($this->raw[$id], $this);
78 27
            $this->typeCheck($id, $this->build[$id]);
79
        }
80 32
        return $this->build[$id];
81
    }
82
83
    /**
84
     * Set an object
85
     *
86
     * @param string $id Identifier for the object to set
87
     * @param type $object Object to set
88
     */
89 39
    public function set($id, $object)
90
    {
91 39
        if (!is_callable($object)) {
92 39
            $this->typeCheck($id, $object);
93
        }
94 38
        $this->raw[$id] = $object;
95 38
    }
96
97
    /**
98
     * Check object-type matches required type for that ID
99
     *
100
     * @param string $id
101
     * @param mixed $object
102
     * @return void
103
     * @throws \Phile\Exception\ContainerException
104
     */
105 39
    protected function typeCheck($id, $object)
106
    {
107 39
        if (!isset($this->config['types'][$id])) {
108 12
            return;
109
        }
110 38
        $requirement = $this->config['types'][$id];
111 38
        if (get_class($object) === $requirement || is_subclass_of($object, $requirement)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if $requirement can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
112 37
            return;
113
        }
114 1
        $msg = sprintf('The Container-item "%s" must implement the interface: "%s"', $id, $requirement);
115 1
        throw new \Phile\Exception\ContainerException($msg, 1398536617);
116
    }
117
}
118