resolveViewControllerInvokeMethod()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 13
rs 10
cc 2
nc 2
nop 0
1
<?php
2
3
namespace TypeHints\Unused\Parser\Action;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Routing\Route;
7
use Illuminate\Support\Arr;
8
use ReflectionClass;
9
use ReflectionMethod;
10
11
class ControllerParser implements ParserActionInterface
12
{
13
    /**
14
     * @var Route
15
     */
16
    protected $route;
17
18
    /**
19
     * @var array
20
     */
21
    protected $content = [];
22
23
    /**
24
     * @var array
25
     */
26
    protected $errors = [];
27
28
    /**
29
     * @param Route $route
30
     */
31
    public function __construct(Route $route)
32
    {
33
        $this->route = $route;
34
    }
35
36
    /**
37
     * @return TypeHints\Unused\Parser\Action\ControllerParser
0 ignored issues
show
Bug introduced by
The type TypeHints\Unused\Parser\...Action\ControllerParser was not found. Did you mean TypeHints\Unused\Parser\Action\ControllerParser? If so, make sure to prefix the type with \.
Loading history...
38
     */
39
    public function parse(): ParserActionInterface
40
    {
41
        $this->content = $this->fetchContent();
42
43
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type TypeHints\Unused\Parser\Action\ControllerParser which is incompatible with the documented return type TypeHints\Unused\Parser\...Action\ControllerParser.
Loading history...
44
    }
45
46
    /**
47
     * @return array
48
     */
49
    protected function fetchContent(): ?array
50
    {
51
        if ($this->isViewController()) {
52
            return $this->resolveViewControllerInvokeMethod();
53
        }
54
55
        $method = $this->resolveMethod();
56
57
        if (!$method) {
58
            return null;
59
        }
60
61
        return array_slice(
62
            file($method->getFileName()),
0 ignored issues
show
Bug introduced by
It seems like file($method->getFileName()) can also be of type false; however, parameter $array of array_slice() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

62
            /** @scrutinizer ignore-type */ file($method->getFileName()),
Loading history...
63
            $method->getStartLine() - 1,
64
            $method->getEndLine() - $method->getStartLine() + 1
65
        );
66
    }
67
68
    /**
69
     * @return ReflectionMethod
70
     */
71
    protected function resolveMethod(): ?ReflectionMethod
72
    {
73
        try {
74
            return (new ReflectionClass($this->getName()))
75
                ->getMethod($this->getMethod());
76
        } catch (\Exception $exception) {
77
            if ($exception->getCode() === -1) {
78
                $this->errors[] = "{$this->getName()} Controller does not exists !";
79
80
                return null;
81
            }
82
83
            $this->errors[] = "{$this->getMethod()} Method does not exists on {$this->getName()} !";
84
85
            return null;
86
        }
87
    }
88
89
    /**
90
     * @return bool
91
     */
92
    public function isViewController(): bool
93
    {
94
        return strpos($this->getName(), 'ViewController') !== false;
95
    }
96
97
    /**
98
     * @return array
99
     */
100
    public function resolveViewControllerInvokeMethod(): array
101
    {
102
        $this->route->bind(new Request());
103
104
        $params = $this->route->parametersWithoutNulls();
105
106
        if (array_key_exists('view', $params)) {
107
            return [
108
                'view' => $params['view'],
109
            ];
110
        }
111
112
        return $this->route->parametersWithoutNulls();
113
    }
114
115
    /**
116
     * @return string
117
     */
118
    public function getMethod(): string
119
    {
120
        return Arr::last(explode('@', $this->route->getAction('uses')));
0 ignored issues
show
Bug Best Practice introduced by
The expression return Illuminate\Suppor...te->getAction('uses'))) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
121
    }
122
123
    /**
124
     * @return string
125
     */
126
    public function getName(): string
127
    {
128
        return Arr::first(explode('@', $this->route->getAction('controller')));
0 ignored issues
show
Bug Best Practice introduced by
The expression return Illuminate\Suppor...tAction('controller'))) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
129
    }
130
131
    /**
132
     * @return array
133
     */
134
    public function getContent(): ?array
135
    {
136
        return $this->content;
137
    }
138
139
    /**
140
     * @return array
141
     */
142
    public function getErrors(): ?array
143
    {
144
        return $this->errors;
145
    }
146
147
    /**
148
     * @return array
149
     */
150
    public function getRoute(): ?array
151
    {
152
        return array_merge($this->route->getAction(), [
0 ignored issues
show
Bug introduced by
It seems like $this->route->getAction() can also be of type null; however, parameter $array1 of array_merge() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

152
        return array_merge(/** @scrutinizer ignore-type */ $this->route->getAction(), [
Loading history...
153
            'methods' => $this->route->methods(),
154
            'uri'     => $this->route->uri,
155
        ]);
156
    }
157
}
158