Passed
Branch master (7f48e0)
by Felipe
06:05
created

ErrorHandlerContainer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
/**
4
 * This file is part of coisa/error-handler.
5
 *
6
 * (c) Felipe Sayão Lobato Abreu <[email protected]>
7
 *
8
 * This source file is subject to the license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
declare(strict_types=1);
13
14
namespace CoiSA\ErrorHandler\Container;
15
16
use Psr\Container\ContainerInterface;
17
18
/**
19
 * Class ErrorHandlerContainer
20
 *
21
 * @package CoiSA\ErrorHandler\Container
22
 */
23
final class ErrorHandlerContainer implements ContainerInterface
24
{
25
    /**
26
     * @var null|ContainerInterface
27
     */
28
    private $container;
29
30
    /**
31
     * @var string[]
32
     */
33
    private $factories;
34
35
    /**
36
     * @var object[]
37
     */
38
    private $instances;
39
40
    /**
41
     * ErrorHandlerContainer constructor.
42
     *
43
     * @param null|ContainerInterface $container
44
     */
45 28
    public function __construct(ContainerInterface $container = null)
46
    {
47 28
        $this->factories = (new ConfigProvider())->getFactories();
48 28
        $this->container = $container;
49 28
    }
50
51
    /**
52
     * @param string $id
53
     *
54
     * @return bool
55
     */
56 28
    public function has($id)
57
    {
58 28
        return ($this->container && $this->container->has($id))
59 28
            || \array_key_exists($id, $this->factories);
60
    }
61
62
    /**
63
     * @param string $id
64
     *
65
     * @throws Exception\ContainerException
66
     * @throws Exception\NotFoundException
67
     *
68
     * @return mixed
69
     */
70 18
    public function get($id)
71
    {
72 18
        if ($this->container && $this->container->has($id)) {
73 16
            return $this->container->get($id);
74
        }
75
76 18
        if (!isset($this->instances[$id])) {
77
            try {
78 18
                $this->instances[$id] = ($this->getFactory($id))($this);
79 2
            } catch (Exception\NotFoundException $notFoundException) {
80 2
                throw $notFoundException;
81
            } catch (\Throwable $throwable) {
82
                throw Exception\ContainerException::createFromThrowable($throwable);
83
            }
84
        }
85
86 16
        return $this->instances[$id];
87
    }
88
89
    /**
90
     * @param string $id
91
     *
92
     * @throws Exception\NotFoundException
93
     *
94
     * @return callable
95
     */
96 18
    private function getFactory(string $id): callable
97
    {
98 18
        if (false === $this->has($id)) {
99 2
            throw new Exception\NotFoundException(\sprintf('Factory for class %s was not found', $id));
100
        }
101
102 16
        $factory = $this->factories[$id];
103
104 16
        return \is_callable($factory) ? $factory : new $factory();
1 ignored issue
show
Bug Best Practice introduced by
The expression return is_callable($fact...actory : new $factory() could return the type object which is incompatible with the type-hinted return callable. Consider adding an additional type-check to rule them out.
Loading history...
105
    }
106
}
107