1 | <?php |
||||||
2 | |||||||
3 | namespace Larapie\Actions\Concerns; |
||||||
4 | |||||||
5 | use Illuminate\Database\Eloquent\ModelNotFoundException; |
||||||
6 | use Illuminate\Support\Facades\Validator; |
||||||
7 | use Illuminate\Support\Str; |
||||||
8 | use Illuminate\Validation\ValidationException; |
||||||
9 | use Larapie\Actions\Exception\MethodDoesNotExistException; |
||||||
10 | use ReflectionMethod; |
||||||
11 | use ReflectionParameter; |
||||||
12 | |||||||
13 | trait ResolvesMethodDependencies |
||||||
14 | { |
||||||
15 | 54 | protected function resolveAndCall($instance, $method, $extras = []) |
|||||
16 | { |
||||||
17 | 54 | if (! method_exists($instance, $method)) { |
|||||
18 | 1 | throw new MethodDoesNotExistException("method $method not found on ".get_class($instance)); |
|||||
19 | } |
||||||
20 | |||||||
21 | 53 | $parameters = $this->resolveMethodDependencies($instance, $method, $extras); |
|||||
22 | |||||||
23 | 52 | return $instance->{$method}(...$parameters); |
|||||
24 | } |
||||||
25 | |||||||
26 | 53 | protected function resolveMethodDependencies($instance, $method, $extras = []) |
|||||
27 | { |
||||||
28 | 53 | $reflector = new ReflectionMethod($instance, $method); |
|||||
29 | |||||||
30 | 53 | $handler = function ($parameter) use ($extras) { |
|||||
31 | 28 | return $this->resolveDependency($parameter, $extras); |
|||||
32 | 53 | }; |
|||||
33 | |||||||
34 | 53 | return array_map($handler, $reflector->getParameters()); |
|||||
35 | } |
||||||
36 | |||||||
37 | 28 | protected function resolveDependency(ReflectionParameter $parameter, $extras = []) |
|||||
38 | { |
||||||
39 | 28 | [$key, $value] = $this->findAttributeFromParameter($parameter->name, $extras); |
|||||
40 | 28 | $class = $parameter->getClass(); |
|||||
41 | |||||||
42 | 28 | if ($key && (! $class || $value instanceof $class->name)) { |
|||||
0 ignored issues
–
show
introduced
by
![]() |
|||||||
43 | 22 | return $value; |
|||||
44 | } |
||||||
45 | |||||||
46 | 14 | if ($class) { |
|||||
0 ignored issues
–
show
|
|||||||
47 | 6 | return $this->resolveContainerDependency($class->name, $key, $value, $parameter->name); |
|||||
48 | } |
||||||
49 | |||||||
50 | 8 | if ($parameter->isDefaultValueAvailable()) { |
|||||
51 | 1 | return $parameter->getDefaultValue(); |
|||||
52 | } |
||||||
53 | 8 | } |
|||||
54 | |||||||
55 | 6 | protected function resolveContainerDependency($class, $key, $value, ?string $parameterName = null) |
|||||
56 | { |
||||||
57 | 6 | $instance = app($class); |
|||||
58 | |||||||
59 | 6 | if (method_exists($instance, 'resolveRouteBinding')) { |
|||||
60 | 5 | if (! $key) { |
|||||
61 | throw (new ValidationException(Validator::make([], [ |
||||||
62 | $parameterName => 'required', |
||||||
63 | ])))->redirectTo($this->getRedirectUrl()); |
||||||
0 ignored issues
–
show
It seems like
getRedirectUrl() 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
![]() |
|||||||
64 | } |
||||||
65 | |||||||
66 | 5 | $instance = $this->resolveRouteBinding($instance, $value); |
|||||
67 | } |
||||||
68 | |||||||
69 | 5 | if ($key) { |
|||||
70 | 4 | $this->updateAttributeWithResolvedInstance($key, $instance); |
|||||
71 | } |
||||||
72 | |||||||
73 | 5 | return $instance; |
|||||
74 | } |
||||||
75 | |||||||
76 | 5 | protected function resolveRouteBinding($instance, $value) |
|||||
77 | { |
||||||
78 | 5 | if (! $model = $instance->resolveRouteBinding($value)) { |
|||||
79 | 1 | throw (new ModelNotFoundException())->setModel(get_class($instance)); |
|||||
80 | } |
||||||
81 | |||||||
82 | 4 | return $model; |
|||||
83 | } |
||||||
84 | |||||||
85 | 28 | protected function findAttributeFromParameter($name, $extras = []) |
|||||
86 | { |
||||||
87 | 28 | $routeAttributes = $this->runningAs('controller') ? $this->getAttributesFromRoute($this->request) : []; |
|||||
0 ignored issues
–
show
It seems like
runningAs() 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
![]() It seems like
getAttributesFromRoute() 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
![]() |
|||||||
88 | 28 | $attributes = array_merge($this->attributes, $routeAttributes, $extras); |
|||||
89 | |||||||
90 | 28 | if (array_key_exists($name, $attributes)) { |
|||||
91 | 25 | return [$name, $attributes[$name]]; |
|||||
92 | } |
||||||
93 | 10 | if (array_key_exists($snakedName = Str::snake($name), $attributes)) { |
|||||
94 | 1 | return [$snakedName, $attributes[$snakedName]]; |
|||||
95 | } |
||||||
96 | 9 | } |
|||||
97 | |||||||
98 | 4 | public function updateAttributeWithResolvedInstance($key, $instance) |
|||||
99 | { |
||||||
100 | 4 | if ($this->runningAs('controller') && $this->request->has($key)) { |
|||||
101 | 1 | return; |
|||||
102 | } |
||||||
103 | |||||||
104 | 3 | return $this->attributes[$key] = $instance; |
|||||
0 ignored issues
–
show
|
|||||||
105 | } |
||||||
106 | } |
||||||
107 |