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

ErrorHandlerContainer   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Test Coverage

Coverage 90.91%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
eloc 22
c 1
b 0
f 0
dl 0
loc 82
ccs 20
cts 22
cp 0.9091
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A get() 0 17 6
A getFactory() 0 9 3
A has() 0 4 3
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