Passed
Push — main ( 958b85...c1db04 )
by Michael
03:34
created

HelpsProxies::resolvePassedClass()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 9
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 9
b 0
f 0
nc 3
nop 3
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MichaelRubel\EnhancedContainer\Traits;
6
7
use Illuminate\Support\Arr;
8
use MichaelRubel\EnhancedContainer\Exceptions\PropertyNotFoundException;
9
10
trait HelpsProxies
11
{
12
    /**
13
     * @param class-string $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
14
     * @param array        $dependencies
15
     * @param string|null  $context
16
     *
17
     * @return object
18
     */
19 57
    public function resolvePassedClass(string $class, array $dependencies = [], ?string $context = null): object
20
    {
21 57
        $class = $this->getContextualConcrete($class, $context);
22
23
        try {
24 57
            $dependencies = $this->getDependencies($class, $dependencies);
25
26 57
            return resolve($class, $dependencies);
27 2
        } catch (\Throwable $exception) {
28 2
            throw new \BadMethodCallException(
29 2
                $exception->getMessage()
30
            );
31
        }
32
    }
33
34
    /**
35
     * Get the contextual concrete.
36
     *
37
     * @param string      $class
38
     * @param string|null $context
39
     *
40
     * @return string
41
     */
42 57
    public function getContextualConcrete(string $class, ?string $context = null): string
43
    {
44 57
        if (! is_null($context) && isset(app()->contextual[$context])) {
45 1
            return app()->contextual[$context][$class] ?? $class;
46
        }
47
48 57
        return $class;
49
    }
50
51
    /**
52
     * Resolve class dependencies.
53
     *
54
     * @param class-string $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
55
     * @param array        $dependencies
56
     *
57
     * @return array
58
     * @throws \ReflectionException
59
     */
60 57
    public function getDependencies(string $class, array $dependencies = []): array
61
    {
62 57
        if (! empty($dependencies) && ! Arr::isAssoc($dependencies)) {
63 2
            $constructor = (new \ReflectionClass($class))->getConstructor();
64
65 2
            if ($constructor) {
66 2
                $dependencies = $this->makeContainerParameters(
67 2
                    $constructor->getParameters(),
68
                    $dependencies
69
                );
70
            }
71
        }
72
73 57
        return $dependencies;
74
    }
75
76
    /**
77
     * @param object       $class
78
     * @param string       $method
79
     * @param array $parameters
80
     *
81
     * @return array
82
     * @throws \ReflectionException
83
     */
84 47
    public function getPassedParameters(object $class, string $method, array $parameters): array
85
    {
86 47
        if (empty($parameters)) {
87 24
            return $parameters;
88
        }
89
90 25
        $reflectionMethod = new \ReflectionMethod($class, $method);
91
92 25
        return $this->makeContainerParameters(
93 25
            $reflectionMethod->getParameters(),
94
            $parameters
95
        );
96
    }
97
98
    /**
99
     * Combine parameters to make it container-readable.
100
     *
101
     * @param array $parameters
102
     * @param array $toCombine
103
     *
104
     * @return array
105
     */
106 26
    public function makeContainerParameters(array $parameters, array $toCombine): array
107
    {
108 26
        return collect($parameters)
109 26
            ->slice(0, count($toCombine))
110 26
            ->map(fn ($param) => $param->getName())
111 26
            ->combine(array_slice($toCombine, 0, count($parameters)))
112 26
            ->all();
113
    }
114
115
    /**
116
     * Convert the object to its namespace.
117
     *
118
     * @param object|string $object
119
     *
120
     * @return string
121
     */
122 66
    public function convertToNamespace(object|string $object): string
123
    {
124 66
        return is_string($object)
125 53
            ? $object
126 66
            : $object::class;
127
    }
128
129
    /**
130
     * Handle property error.
131
     *
132
     * @param string $name
133
     * @param object $instance
134
     *
135
     * @throws PropertyNotFoundException
136
     */
137 3
    public function throwPropertyNotFoundException(string $name, object $instance): self
138
    {
139 3
        throw new PropertyNotFoundException(sprintf(
140 3
            'Call to undefined property %s::%s()',
141
            $name,
142 3
            $instance::class
143
        ));
144
    }
145
}
146