Passed
Push — master ( 9b17c0...e46d42 )
by Biao
02:00 queued 10s
created

ListPropertiesCommand::outputTable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 0
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Hhxsv5\LaravelS\Console;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Routing\Controller;
7
use Illuminate\Support\Collection;
8
9
/**
10
 * This command is writing for those who want to know if there's any controller properties defined.
11
 * As controller is a singleton in laravel-s, all properties defined in controller will be retained after the request is finished.
12
 * So if you want to migrate to laravel-s, or just debug your app to find out potential problems, you can try this.
13
 */
14
class ListPropertiesCommand extends Command
15
{
16
    public $signature = 'laravels:list-properties';
17
18
    public $description = 'List all properties of all controllers (not include parent\'s).';
19
20
    /**
21
     * @throws \ReflectionException
22
     */
23
    public function fire()
24
    {
25
        return $this->handle();
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->handle() targeting Hhxsv5\LaravelS\Console\...ertiesCommand::handle() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
26
    }
27
28
    /**
29
     * @throws \ReflectionException
30
     */
31
    public function handle()
32
    {
33
        $this->outputTable();
34
    }
35
36
    /**
37
     * Output all properties of all controllers as table.
38
     *
39
     * @throws \ReflectionException
40
     */
41
    private function outputTable()
42
    {
43
        $properties = $this->allControllerProperties();
44
45
        $properties->each(function ($properties, $action) {
46
            $controllerName = explode('@', $action)[0];
47
48
            $this->comment($controllerName);
49
50
            $this->table(
51
                $this->headers(),
52
                $properties
53
            );
54
        });
55
    }
56
57
    /**
58
     * Table headers.
59
     *
60
     * @return array
61
     */
62
    private function headers()
63
    {
64
        return ['property', 'name'];
65
    }
66
67
    /**
68
     * Get all properties of all controllers.
69
     *
70
     * @return Collection
71
     * @throws \ReflectionException
72
     */
73
    private function allControllerProperties()
74
    {
75
        $controllers = $this->allControllers();
76
77
        $properties = $controllers
78
            ->map(function (Controller $controller) {
79
                // Get related controller's properties
80
                $reflectController = new \ReflectionClass($controller);
81
                $properties = $reflectController->getProperties();
82
83
                // Get parent's properties
84
                $parent = get_parent_class(get_class($controller));
85
                $reflectParentController = new \ReflectionClass($parent);
86
                $parentProperties = collect($reflectParentController->getProperties())
87
                    ->map
0 ignored issues
show
Bug introduced by
The property map does not seem to exist on Illuminate\Support\Collection.
Loading history...
88
                    ->getName()
89
                    ->flip()
90
                    ->toArray();
91
92
                return collect($properties)
93
                    ->map(function (\ReflectionProperty $reflectionProperty) use ($controller, $parentProperties) {
0 ignored issues
show
Unused Code introduced by
The import $controller is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
94
                        // Exclude parent's properties
95
                        if (!array_key_exists($reflectionProperty->getName(), $parentProperties)) {
96
                            return [
97
                                'name' => $reflectionProperty->getName(),
98
                                'property' => $this->resolveModifiers($reflectionProperty)  . '$' . $reflectionProperty->getName(),
99
                            ];
100
                        }
101
                    })
102
                    ->filter()
103
                    ->toArray();
104
105
            });
106
107
        return $properties;
108
    }
109
110
    /**
111
     * Get all controllers
112
     *
113
     * @return Collection
114
     * @throws \ReflectionException
115
     */
116
    private function allControllers()
117
    {
118
        $actionList = $this->actionList();
119
120
        return collect($actionList)->map->getController();
0 ignored issues
show
Bug introduced by
The property map does not seem to exist on Illuminate\Support\Collection.
Loading history...
121
    }
122
123
    /**
124
     * Get actionList from RouteCollection
125
     *
126
     * @return array
127
     * @throws \ReflectionException
128
     */
129
    private function actionList()
130
    {
131
        $routeCollection = app('router')->getRoutes();
132
133
        $actionListReflectProperty = new \ReflectionProperty(get_class($routeCollection), 'actionList');
134
        $actionListReflectProperty->setAccessible(true);
135
136
        return $actionListReflectProperty->getValue($routeCollection);
137
    }
138
139
    /**
140
     * Resolve modifiers from \ReflectionProperty
141
     *
142
     * @param \ReflectionProperty $reflectionProperty
143
     * @return string
144
     */
145
    private function resolveModifiers(\ReflectionProperty $reflectionProperty)
146
    {
147
        if ($reflectionProperty->isPublic()) {
148
            $prefix = 'public';
149
        } elseif ($reflectionProperty->isProtected()) {
150
            $prefix = 'protected';
151
        } elseif ($reflectionProperty->isPrivate()) {
152
            $prefix = 'private';
153
        } else {
154
            $prefix = ' ';
155
        }
156
157
        return $reflectionProperty->isStatic() ? "{$prefix} static " : $prefix . ' ';
158
    }
159
}