Passed
Push — main ( 5ca287...d84479 )
by Thierry
05:24
created

DiAutoTrait::getParameter()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
c 0
b 0
f 0
nc 4
nop 2
dl 0
loc 21
rs 9.9666
1
<?php
2
3
/**
4
 * DiAutoTrait.php
5
 *
6
 * Di auto wiring.
7
 *
8
 * @package jaxon-core
9
 * @author Thierry Feuzeu <[email protected]>
10
 * @copyright 2025 Thierry Feuzeu <[email protected]>
11
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
12
 * @link https://github.com/jaxon-php/jaxon-core
13
 */
14
15
namespace Jaxon\Di\Traits;
16
17
use Jaxon\Di\Container;
18
use Jaxon\Exception\SetupException;
19
use ReflectionClass;
20
use ReflectionException;
21
use ReflectionNamedType;
22
use ReflectionParameter;
23
24
use function array_map;
25
use function is_string;
26
27
trait DiAutoTrait
28
{
29
    /**
30
     * The container for parameters
31
     *
32
     * @return Container
33
     */
34
    abstract protected function cn(): Container;
35
36
    /**
37
     * @param ReflectionClass $xClass
38
     * @param ReflectionParameter $xParameter
39
     *
40
     * @return mixed
41
     * @throws SetupException
42
     */
43
    private function getParameter(ReflectionClass $xClass, ReflectionParameter $xParameter)
0 ignored issues
show
Unused Code introduced by
The parameter $xClass is not used and could be removed. ( Ignorable by Annotation )

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

43
    private function getParameter(/** @scrutinizer ignore-unused */ ReflectionClass $xClass, ReflectionParameter $xParameter)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
44
    {
45
        $xType = $xParameter->getType();
46
        $sParameterName = '$' . $xParameter->getName();
47
        // Check the parameter class first.
48
        if($xType instanceof ReflectionNamedType)
49
        {
50
            $sParameterType = $xType->getName();
51
            // The class + the name
52
            if($this->cn()->has("$sParameterType $sParameterName"))
53
            {
54
                return $this->cn()->get("$sParameterType $sParameterName");
55
            }
56
            // The class only
57
            if($this->cn()->has($sParameterType))
58
            {
59
                return $this->cn()->get($sParameterType);
60
            }
61
        }
62
        // Check the name only
63
        return $this->cn()->get($sParameterName);
64
    }
65
66
    /**
67
     * Create an instance of a class, getting the constructor parameters from the DI container
68
     *
69
     * @param class-string|ReflectionClass $xClass The class name or the reflection class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string|ReflectionClass at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string|ReflectionClass.
Loading history...
70
     *
71
     * @return object|null
72
     * @throws ReflectionException
73
     * @throws SetupException
74
     */
75
    public function make(string|ReflectionClass $xClass): mixed
76
    {
77
        if(is_string($xClass))
78
        {
79
            // Create the reflection class instance
80
            $xClass = new ReflectionClass($xClass);
81
        }
82
        // Use the Reflection class to get the parameters of the constructor
83
        if(($constructor = $xClass->getConstructor()) === null)
84
        {
85
            return $xClass->newInstance();
86
        }
87
88
        $aParameters = array_map(fn($xParameter) =>
89
            $this->getParameter($xClass, $xParameter), $constructor->getParameters());
90
        return $xClass->newInstanceArgs($aParameters);
91
    }
92
93
    /**
94
     * Create an instance of a class by automatically fetching the dependencies in the constructor.
95
     *
96
     * @param class-string $sClass    The class name
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...
97
     *
98
     * @return void
99
     */
100
    public function auto(string $sClass): void
101
    {
102
        $this->set($sClass, fn() => $this->make($sClass));
0 ignored issues
show
Bug introduced by
It seems like set() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

102
        $this->/** @scrutinizer ignore-call */ 
103
               set($sClass, fn() => $this->make($sClass));
Loading history...
103
    }
104
}
105