Passed
Push — main ( 96556a...339d92 )
by Michael
13:01
created

HelpsProxies   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 25
Bugs 1 Features 1
Metric Value
eloc 34
c 25
b 1
f 1
dl 0
loc 153
ccs 39
cts 39
cp 1
rs 10
wmc 18

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getContextualConcrete() 0 3 1
A getClassForResolution() 0 5 3
A resolvePassedClass() 0 6 1
A getDependencies() 0 19 5
A getPassedParameters() 0 9 3
A getBindingConcrete() 0 7 1
A convertToNamespace() 0 5 2
A sliceParameters() 0 3 1
A makeContainerParameters() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MichaelRubel\EnhancedContainer\Traits;
6
7
use Illuminate\Support\Arr;
8
9
trait HelpsProxies
10
{
11
    /**
12
     * @param string      $class
13
     * @param array       $dependencies
14
     * @param string|null $context
15
     *
16
     * @return object
17
     */
18 56
    public function resolvePassedClass(string $class, array $dependencies = [], ?string $context = null): object
19
    {
20 56
        $class        = $this->getClassForResolution($class, $context);
21 56
        $dependencies = $this->getDependencies($class, $dependencies);
22
23 56
        return resolve($class, $dependencies);
24
    }
25
26
    /**
27
     * Get the class for resolution.
28
     *
29
     * @param string      $class
30
     * @param string|null $context
31
     *
32
     * @return string
33
     */
34 56
    public function getClassForResolution(string $class, ?string $context = null): string
35
    {
36 56
        return ! is_null($context) && isset(app()->contextual[$context])
37 1
            ? $this->getContextualConcrete($class, $context)
38 56
            : $class;
39
    }
40
41
    /**
42
     * Try to get the contextual concrete.
43
     *
44
     * @param string      $class
45
     * @param string|null $context
46
     *
47
     * @return string
48
     */
49 1
    public function getContextualConcrete(string $class, ?string $context = null): string
50
    {
51 1
        return app()->contextual[$context][$class] ?? $class;
52
    }
53
54
    /**
55
     * Try to get binding concrete.
56
     *
57
     * @param string $class
58
     *
59
     * @return string
60
     * @throws \ReflectionException
61
     */
62 1
    public function getBindingConcrete(string $class): string
63
    {
64
        return (
65 1
           new \ReflectionFunction(
66 1
               app()->getBindings()[$class]['concrete']
67
           )
68 1
        )->getStaticVariables()['concrete'];
69
    }
70
71
    /**
72
     * Resolve class dependencies.
73
     *
74
     * @param string $class
75
     * @param array  $dependencies
76
     *
77
     * @return array
78
     * @throws \ReflectionException
79
     */
80 56
    public function getDependencies(string $class, array $dependencies = []): array
81
    {
82 56
        if (! empty($dependencies) && ! Arr::isAssoc($dependencies)) {
83 3
            if (! class_exists($class)) {
84 1
                $class = $this->getBindingConcrete($class);
85
            }
86
87
            /** @var class-string $class */
88 3
            $constructor = (new \ReflectionClass($class))->getConstructor();
89
90 3
            if ($constructor) {
91 2
                $dependencies = $this->makeContainerParameters(
92 2
                    $constructor->getParameters(),
93
                    $dependencies
94
                );
95
            }
96
        }
97
98 56
        return $dependencies;
99
    }
100
101
    /**
102
     * @param object $class
103
     * @param string $method
104
     * @param array  $parameters
105
     *
106
     * @return array
107
     * @throws \ReflectionException
108
     */
109 56
    public function getPassedParameters(object $class, string $method, array $parameters): array
110
    {
111 56
        if (empty($parameters) || Arr::isAssoc($parameters)) {
112 31
            return $parameters;
113
        }
114
115 27
        return $this->makeContainerParameters(
116 27
            (new \ReflectionMethod($class, $method))->getParameters(),
117
            $parameters
118
        );
119
    }
120
121
    /**
122
     * Combine parameters to make it container-readable.
123
     *
124
     * @param array $reflectionParameters
125
     * @param array $methodParameters
126
     *
127
     * @return array
128
     */
129 26
    public function makeContainerParameters(array $reflectionParameters, array $methodParameters): array
130
    {
131 26
        return collect($this->sliceParameters($reflectionParameters, $methodParameters))
0 ignored issues
show
Bug introduced by
$this->sliceParameters($...ers, $methodParameters) of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

131
        return collect(/** @scrutinizer ignore-type */ $this->sliceParameters($reflectionParameters, $methodParameters))
Loading history...
132 26
            ->map->getName()
133 26
            ->combine($this->sliceParameters($methodParameters, $reflectionParameters))
134 26
            ->all();
135
    }
136
137
    /**
138
     * Slice an array to align the parameters.
139
     *
140
     * @param array $parameters
141
     * @param array $countable
142
     *
143
     * @return array
144
     */
145 26
    public function sliceParameters(array $parameters, array $countable): array
146
    {
147 26
        return array_slice($parameters, 0, count($countable));
148
    }
149
150
    /**
151
     * Convert the object to its namespace.
152
     *
153
     * @param object|string $object
154
     *
155
     * @return string
156
     */
157 54
    public function convertToNamespace(object|string $object): string
158
    {
159 54
        return is_string($object)
160 47
            ? $object
161 54
            : $object::class;
162
    }
163
}
164