ParameterResolver::searchPrimitiveParameter()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 3
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Spatie\ResourceLinks;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Routing\Route;
7
use Illuminate\Support\Arr;
8
use ReflectionParameter;
9
10
class ParameterResolver
11
{
12
    /** @var \Illuminate\Database\Eloquent\Model|null */
13
    private $model;
14
15
    /** @var array */
16
    private $defaultParameters;
17
18
    public function __construct(?Model $model, array $defaultParameters = [])
19
    {
20
        $this->model = $model;
21
22
        $this->defaultParameters = $defaultParameters;
23
    }
24
25
    public function forRoute(Route $route): array
26
    {
27
        $providedParameters = $this->getProvidedParameters();
28
29
        return collect($route->signatureParameters())
30
            ->mapWithKeys(function (ReflectionParameter $signatureParameter) use ($providedParameters) {
31
                return [
32
                    $signatureParameter->getName() => $this->findParameter(
33
                        $signatureParameter,
34
                        $providedParameters
35
                    ),
36
                ];
37
            })
38
            ->reject(function ($parameter) {
39
                return $parameter === null;
40
            })
41
            ->all();
42
    }
43
44
    private function getProvidedParameters(): array
45
    {
46
        return $this->defaultParameters;
47
    }
48
49
    private function findParameter(ReflectionParameter $signatureParameter, array &$providedParameters)
50
    {
51
        if ($this->expectsModelAsParameter($signatureParameter)) {
52
            return $this->model;
53
        }
54
55
        if ($this->parameterWithKeyExists($signatureParameter, $providedParameters)) {
56
            return Arr::pull($providedParameters, $signatureParameter->getName());
57
        }
58
59
        if ($this->expectsPrimitiveParameter($signatureParameter)) {
60
            return $this->searchPrimitiveParameter($signatureParameter, $providedParameters);
61
        }
62
63
        foreach ($providedParameters as $index => $providedParameter) {
64
            if (! is_object($providedParameter) || $signatureParameter->getClass() === null) {
65
                continue;
66
            }
67
68
            if ($signatureParameter->getClass()->isInstance($providedParameter)) {
69
                return Arr::pull($providedParameters, $index);
70
            }
71
        }
72
    }
73
74
    private function expectsModelAsParameter(ReflectionParameter $signatureParameter): bool
75
    {
76
        if ($this->model === null) {
77
            return false;
78
        }
79
80
        if ($signatureParameter->getClass() === null) {
81
            return false;
82
        }
83
84
        return $signatureParameter->getClass()->isInstance($this->model);
85
    }
86
87
    private function parameterWithKeyExists(
88
        ReflectionParameter $signatureParameter,
89
        array $providedParameters
90
    ): bool {
91
        return array_key_exists(
92
            $signatureParameter->getName(),
93
            $providedParameters
94
        );
95
    }
96
97
    private function expectsPrimitiveParameter(
98
        ReflectionParameter $signatureParameter
99
    ): bool {
100
        if ($signatureParameter->getType() === null) {
101
            return false;
102
        }
103
104
        return $signatureParameter->getType()->isBuiltin();
105
    }
106
107
    private function searchPrimitiveParameter(
108
        ReflectionParameter $signatureParameter,
109
        array &$providedParameters
110
    ) {
111
        foreach ($providedParameters as $index => $providedParameter) {
112
            if ($this->getParameterPrimitiveType($providedParameter) === $signatureParameter->getType()->getName()) {
113
                return Arr::pull($providedParameters, $index);
114
            }
115
        }
116
    }
117
118
    private function getParameterPrimitiveType($parameter): string
119
    {
120
        $typeName = gettype($parameter);
121
122
        return strtr($typeName, [
123
            'boolean' => 'bool',
124
            'integer' => 'int',
125
        ]);
126
    }
127
}
128