Issues (7)

src/Traits/InteractsWithContainer.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MichaelRubel\EnhancedContainer\Traits;
6
7
use Illuminate\Support\Arr;
8
9
trait InteractsWithContainer
10
{
11
    /**
12
     * Get the class instance.
13
     */
14 60
    protected function getInstance(string|object $class, array $dependencies = [], ?string $context = null): object
15
    {
16 60
        if (is_object($class)) {
17 13
            return $class;
18
        }
19
20 47
        $class        = $this->getClassForResolution($class, $context);
21 47
        $dependencies = $this->getDependencies($class, $dependencies);
22
23 47
        return app($class, $dependencies);
24
    }
25
26
    /**
27
     * Get the class for resolution.
28
     */
29 47
    protected function getClassForResolution(string $class, ?string $context = null): string
30
    {
31 47
        return isset(app()->contextual[$context])
32 1
            ? $this->getContextualConcrete($class, $context)
33 47
            : $class;
34
    }
35
36
    /**
37
     * Try to get the contextual concrete.
38
     */
39 1
    protected function getContextualConcrete(string $class, ?string $context = null): string
40
    {
41 1
        return app()->contextual[$context][$class] ?? $class;
42
    }
43
44
    /**
45
     * Try to get binding concrete.
46
     *
47
     *
48
     * @throws \ReflectionException
49
     */
50 1
    protected function getBindingConcrete(string $class): string
51
    {
52 1
        return (
53 1
           new \ReflectionFunction(
54 1
               app()->getBindings()[$class]['concrete']
55 1
           )
56 1
        )->getStaticVariables()['concrete'];
57
    }
58
59
    /**
60
     * Resolve class dependencies.
61
     *
62
     *
63
     * @throws \ReflectionException
64
     */
65 47
    protected function getDependencies(string $class, array $dependencies = []): array
66
    {
67 47
        if (! Arr::isAssoc($dependencies)) {
68 44
            if (! class_exists($class) && ! interface_exists($class)) {
69 1
                $class = $this->getBindingConcrete($class);
70
            }
71
72
            /** @var class-string $class */
73 44
            $constructor = (new \ReflectionClass($class))->getConstructor();
74
75 44
            if ($constructor) {
76 26
                $dependencies = $this->makeContainerParameters(
77 26
                    $constructor->getParameters(),
78 26
                    $dependencies
79 26
                );
80
            }
81
        }
82
83 47
        return $dependencies;
84
    }
85
86
    /**
87
     * @throws \ReflectionException
88
     */
89 46
    protected function getParameters(object $class, string $method, array $parameters): array
90
    {
91 46
        if (empty($parameters) || Arr::isAssoc($parameters)) {
92 21
            return $parameters;
93
        }
94
95 27
        return $this->makeContainerParameters(
96 27
            (new \ReflectionMethod($class, $method))->getParameters(),
97 27
            $parameters
98 27
        );
99
    }
100
101
    /**
102
     * Combine parameters to make it container-readable.
103
     */
104 50
    protected function makeContainerParameters(array $reflectionParameters, array $methodParameters): array
105
    {
106 50
        return collect($this->sliceParameters($reflectionParameters, $methodParameters))
0 ignored issues
show
$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

106
        return collect(/** @scrutinizer ignore-type */ $this->sliceParameters($reflectionParameters, $methodParameters))
Loading history...
107 50
            ->map->getName()
108 50
            ->combine($this->sliceParameters($methodParameters, $reflectionParameters))
109 50
            ->all();
110
    }
111
112
    /**
113
     * Slice an array to align the parameters.
114
     */
115 50
    protected function sliceParameters(array $parameters, array $countable): array
116
    {
117 50
        return array_slice($parameters, 0, count($countable));
118
    }
119
120
    /**
121
     * Convert the object to its namespace.
122
     */
123 15
    protected function convertToNamespace(object|string $object): string
124
    {
125 15
        return is_string($object) ? $object : $object::class;
126
    }
127
}
128