DIException::cannotInstantiate()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 8
c 5
b 0
f 0
dl 0
loc 13
ccs 8
cts 8
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
/*
4
 * This file is part of the Koded package.
5
 *
6
 * (c) Mihail Binev <[email protected]>
7
 *
8
 * Please view the LICENSE distributed with this source code
9
 * for the full copyright and license information.
10
 *
11
 */
12
13
namespace Koded;
14
15
use Psr\Container\{ContainerExceptionInterface, NotFoundExceptionInterface};
16
use LogicException;
17
use ReflectionClass;
18
use ReflectionException;
19
use ReflectionParameter;
20
use Throwable;
21
use function array_filter;
22
use function join;
23
use function strtr;
24
25
class DIException extends LogicException implements ContainerExceptionInterface
26
{
27
    public const
28
        E_CIRCULAR_DEPENDENCY = 7001,
29
        E_NON_PUBLIC_METHOD = 7002,
30
        E_CANNOT_INSTANTIATE = 7003,
31
        E_INVALID_PARAMETER_NAME = 7004,
32
        E_INSTANCE_NOT_FOUND = 7005,
33
        E_MISSING_ARGUMENT = 7006,
34
        E_REFLECTION_ERROR = 7007,
35
        E_CANNOT_BIND_INTERFACE = 7008;
36
37
    protected array $messages = [
38
        self::E_CIRCULAR_DEPENDENCY => 'Circular dependency detected while creating an instance for :class',
39
        self::E_NON_PUBLIC_METHOD => 'Failed to create an instance, because the method ":class:::method" is not public',
40
        self::E_CANNOT_INSTANTIATE => 'Cannot instantiate :type :name',
41
        self::E_INVALID_PARAMETER_NAME => 'Provide a valid name for the global parameter: ":name"',
42
        self::E_INSTANCE_NOT_FOUND => 'The requested instance :id is not found in the container',
43
        self::E_MISSING_ARGUMENT => 'Required parameter ":name" is missing at position :position in :function()',
44
        self::E_CANNOT_BIND_INTERFACE => 'Only interface to class binding is allowed. Cannot bind interface ":dependency" to interface ":interface"',
45
        self::E_REFLECTION_ERROR => ':message',
46
    ];
47
48 18
    public function __construct(int $code, array $arguments = [], Throwable $previous = null)
49
    {
50 18
        parent::__construct(
51 18
            strtr($this->messages[$code] ?? ':message', $arguments + [':message' => $this->message]),
52
            $code,
53
            $previous
54
        );
55 18
    }
56
57 1
    public static function forCircularDependency(string $class): static
58
    {
59 1
        return new static(static::E_CIRCULAR_DEPENDENCY, [
60 1
            ':class' => $class
61
        ]);
62
    }
63
64 1
    public static function forNonPublicMethod(string $class, string $method): static
65
    {
66 1
        return new static(static::E_NON_PUBLIC_METHOD, [
67 1
            ':class' => $class,
68 1
            ':method' => $method
69
        ]);
70
    }
71
72 5
    public static function cannotInstantiate(ReflectionClass $dependency): static
73
    {
74 5
        $type = match (true) {
75 5
            $dependency->isInterface() => 'interface',
76 3
            $dependency->isAbstract() => 'abstract class',
77 1
            $dependency->isTrait() => 'trait',
78
            // @codeCoverageIgnoreStart
79
            default => 'class',
80
            // @codeCoverageIgnoreEnd
81
        };
82 5
        return new static(static::E_CANNOT_INSTANTIATE, [
83 5
            ':name' => $dependency->name,
84 5
            ':type' => $type
85
        ]);
86
    }
87
88 7
    public static function forInvalidParameterName(string $name): static
89
    {
90 7
        return new static(static::E_INVALID_PARAMETER_NAME, [
91 7
            ':name' => $name
92
        ]);
93
    }
94
95 1
    public static function forMissingArgument(
96
        string              $name,
97
        ReflectionParameter $parameter,
98
        Throwable           $previous = null): static
99
    {
100 1
        return new static(static::E_MISSING_ARGUMENT, [
101 1
            ':name' => $name,
102 1
            ':position' => $parameter->getPosition(),
103 1
            ':function' => join('::', array_filter([
104 1
                $parameter->getDeclaringClass()?->name,
105 1
                $parameter->getDeclaringFunction()?->name
106
            ]))
107
        ], $previous);
108
    }
109
110 1
    public static function forReflectionError(ReflectionException $exception): static
111
    {
112 1
        return new static(static::E_REFLECTION_ERROR, [
113 1
            ':message' => $exception->getMessage()
114
        ], $exception);
115
    }
116
117 1
    public static function forInterfaceBinding(string $dependency, string $interface): static
118
    {
119 1
        return new static(static::E_CANNOT_BIND_INTERFACE, [
120 1
            ':dependency' => $dependency,
121 1
            ':interface' => $interface
122
        ]);
123
    }
124
}
125
126
127
class DIInstanceNotFound extends DIException implements NotFoundExceptionInterface
128
{
129 1
    public static function for(string $id): NotFoundExceptionInterface
130
    {
131 1
        return new static(static::E_INSTANCE_NOT_FOUND, [':id' => $id]);
132
    }
133
}
134