Container::hasDefinition()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
namespace Palmtree\Container;
4
5
use Palmtree\Container\Definition\Definition;
6
use Palmtree\Container\Exception\ParameterNotFoundException;
7
use Palmtree\Container\Exception\ServiceNotFoundException;
8
use Palmtree\Container\Exception\ServiceNotPublicException;
9
use Psr\Container\ContainerInterface;
10
11
class Container implements ContainerInterface
12
{
13
    /** @var Definition[] */
14
    private $definitions = [];
15
    /** @var mixed[] */
16
    private $services = [];
17
    /** @var array */
18
    private $parameters = [];
19
    /** @var Resolver */
20
    private $resolver;
21
22 27
    public function __construct(array $definitions = [], array $parameters = [])
23
    {
24 27
        foreach ($definitions as $key => $definitionArgs) {
25 24
            $this->addDefinition($key, Definition::fromYaml($definitionArgs, $key));
26
        }
27
28 27
        $this->resolver = new Resolver($this, $this->services);
29
30 27
        $this->parameters = $parameters;
31 27
        $this->parameters = $this->resolver->resolveArgs($this->parameters);
32 27
    }
33
34
    /**
35
     * Instantiates non-lazy services.
36
     */
37 26
    public function instantiateServices()
38
    {
39 26
        foreach ($this->definitions as $key => $definition) {
40 24
            if (!$definition->isLazy()) {
41 24
                $this->services[$key] = $this->create($definition);
42
            }
43
        }
44 26
    }
45
46
    /**
47
     * Returns whether a service with the given key exists within the container.
48
     *
49
     * @param string $key
50
     *
51
     * @return bool
52
     */
53 25
    public function has($key)
54
    {
55 25
        return isset($this->services[$key]);
56
    }
57
58
    /**
59
     * Returns a service object with the given key.
60
     *
61
     * @param string $key
62
     *
63
     * @return mixed
64
     *
65
     * @throws ServiceNotFoundException
66
     * @throws ServiceNotPublicException
67
     */
68 25
    public function get($key)
69
    {
70 25
        if (!$this->has($key)) {
71 24
            if (!$this->hasDefinition($key)) {
72 1
                throw new ServiceNotFoundException($key);
73
            }
74
75 24
            $this->services[$key] = $this->create($this->definitions[$key]);
76
        }
77
78 25
        if (!$this->definitions[$key]->isPublic()) {
79 23
            throw new ServiceNotPublicException($key);
80
        }
81
82 25
        return $this->services[$key];
83
    }
84
85
    /**
86
     * Returns whether a definition with the given key exists within the container.
87
     */
88 24
    public function hasDefinition(string $key): bool
89
    {
90 24
        return isset($this->definitions[$key]);
91
    }
92
93 25
    public function addDefinition(string $key, Definition $definition)
94
    {
95 25
        $this->definitions[$key] = $definition;
96 25
    }
97
98
    /**
99
     * Returns a parameter with the given key or a default value if given.
100
     *
101
     * @param mixed $default
102
     *
103
     * @return mixed
104
     *
105
     * @throws ParameterNotFoundException
106
     */
107 24
    public function getParameter(string $key, $default = null)
108
    {
109 24
        if (!$this->hasParameter($key)) {
110 2
            if (\func_num_args() < 2) {
111 1
                throw new ParameterNotFoundException($key);
112
            }
113
114 1
            return $default;
115
        }
116
117 24
        return $this->parameters[$key];
118
    }
119
120
    /**
121
     * Sets a parameter within the container.
122
     *
123
     * @param mixed $value
124
     *
125
     * @throws ParameterNotFoundException
126
     * @throws ServiceNotFoundException
127
     */
128 23
    public function setParameter(string $key, $value)
129
    {
130 23
        $this->parameters[$key] = $this->resolver->resolveArg($value);
131 23
    }
132
133
    /**
134
     * Returns whether a parameter with the given key exists within the container.
135
     */
136 24
    public function hasParameter(string $key): bool
137
    {
138 24
        return isset($this->parameters[$key]) || \array_key_exists($key, $this->parameters);
139
    }
140
141
    /**
142
     * Creates a service as defined by the Definition object.
143
     *
144
     * @return mixed
145
     */
146 25
    private function create(Definition $definition)
147
    {
148 25
        $args = $this->resolver->resolveArgs($definition->getArguments());
149
150 25
        if ($factory = $definition->getFactory()) {
151 23
            list($class, $method) = $factory;
152
153 23
            $class   = $this->resolver->resolveArg($class);
154 23
            $method  = $this->resolver->resolveArg($method);
155 23
            $service = $class::$method(...$args);
156
        } else {
157 25
            $class   = $this->resolver->resolveArg($definition->getClass());
158 25
            $service = new $class(...$args);
159
        }
160
161 25
        foreach ($definition->getMethodCalls() as $methodCall) {
162 24
            $methodName = $methodCall->getName();
163 24
            $methodArgs = $this->resolver->resolveArgs($methodCall->getArguments());
164 24
            $service->$methodName(...$methodArgs);
165
        }
166
167 25
        return $service;
168
    }
169
}
170