Passed
Branch master (8e52e7)
by Mihail
01:35
created

DIException::forReflectionError()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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