Completed
Pull Request — master (#11)
by Jodie
03:37
created

ModelInspector::getDefaultProperties()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Rexlabs\Laravel\Smokescreen\Console;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Support\Facades\Schema;
7
use ReflectionClass;
8
use ReflectionMethod;
9
10
/**
11
 * The includes listing.
12
 *
13
 */
14
class ModelInspector
15
{
16
    /**
17
     * Maps eloquent relationship methods to smokescreen resource types.
18
     *
19
     * @var array
20
     */
21
    protected $relationsMap = [
22
        'hasOne'         => 'item',
23
        'morphOne'       => 'item',
24
        'belongsTo'      => 'item',
25
        'morphTo'        => 'item',
26
        'hasMany'        => 'collection',
27
        'hasManyThrough' => 'collection',
28
        'morphMany'      => 'collection',
29
        'belongsToMany'  => 'collection',
30
        'morphToMany'    => 'collection',
31
        'morphedByMany'  => 'collection',
32
    ];
33
34
    /**
35
     * The map of property types.
36
     *
37
     * @var array
38
     */
39
    protected $typesMap = [
40
        'guid' => 'string',
41
        'boolean' => 'boolean',
42
        'datetime' => 'datetime',
43
        'string' => 'string',
44
        'json' => 'array',
45
        'integer' => 'integer',
46
        'date' => 'date',
47
        'smallint' => 'integer',
48
        'text' => 'string',
49
        'decimal' => 'float',
50
        'bigint' => 'integer',
51
    ];
52
53
    /** @var Model */
54
    protected $model;
55
56
    public function __construct(Model $model)
57
    {
58
        $this->model = $model;
59
    }
60
61
    /**
62
     * List the includes of the given Eloquent model.
63
     *
64
     * @return array
65
     * @throws \ReflectionException
66
     */
67
    public function getIncludes(): array
68
    {
69
        $list = [];
70
        $methods = (new ReflectionClass($this->getModelClass()))->getMethods(ReflectionMethod::IS_PUBLIC);
71
        $declaredMethods = array_filter($methods, function (ReflectionMethod $method) {
72
            return $method->getDeclaringClass()
73
                    ->getName() === $this->getModelClass();
74
        });
75
76
        foreach ($declaredMethods as $method) {
77
            if ($type = $this->getResourceTypeByMethodReturnType($method)) {
78
                $list[$method->getName()] = "relation|{$type}";
79
            } elseif ($type = $this->getResourceTypeByMethodDefinition($method)) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $type is correct as $this->getResourceTypeByMethodDefinition($method) targeting Rexlabs\Laravel\Smokescr...ypeByMethodDefinition() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

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

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

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

Loading history...
80
                $list[$method->getName()] = "relation|{$type}";
81
            }
82
        }
83
84
        return $list;
85
86
        // implement getResourceTypeByMethodDefinition
87
        // investigate custom relation names with actual relation name
88
        // ^ if different may not relate on $method->getName()
89
    }
90
91
    /**
92
     * List the declared properties of the given Eloquent model.
93
     *
94
     * @return array
95
     */
96
    public function getDeclaredProperties() : array
97
    {
98
        $list = [];
99
        $class = $this->getModelClass();
100
        $table = (new $class)->getTable();
101
        $columns = Schema::getColumnListing($table);
102
103
        foreach ($columns as $column) {
104
            $type = Schema::getColumnType($table, $column);
105
            $list[$column] = $this->typesMap[$type] ?? null;
106
        }
107
108
        return $list;
109
    }
110
111
    /**
112
     * Get the default properties.
113
     *
114
     * @return array
115
     */
116
    public function getDefaultProperties(): array
117
    {
118
        return [];
119
    }
120
121
    /**
122
     * Return the model class.
123
     * @return string
124
     */
125
    protected function getModelClass()
126
    {
127
        return \get_class($this->model);
128
    }
129
130
    /**
131
     * Retrieve the type of the resource based on the given method return type.
132
     *
133
     * @param ReflectionMethod $method
134
     *
135
     * @return string|null
136
     */
137
    protected function getResourceTypeByMethodReturnType(ReflectionMethod $method)
138
    {
139
        $returnType = (string)$method->getReturnType();
140
        $namespace = 'Illuminate\Database\Eloquent\Relations';
141
142
        if (!starts_with($returnType, $namespace)) {
143
            return null;
144
        }
145
146
        $relation = lcfirst(class_basename($returnType));
147
148
        return $this->relationsMap[$relation] ?? null;
149
    }
150
151
    /**
152
     * Retrieve the type of the resource based on the given method definition.
153
     *
154
     * @todo Implement
155
     *
156
     * @param ReflectionMethod $method
157
     *
158
     * @return string|null
159
     */
160
    protected function getResourceTypeByMethodDefinition(ReflectionMethod $method)
0 ignored issues
show
Unused Code introduced by
The parameter $method 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

160
    protected function getResourceTypeByMethodDefinition(/** @scrutinizer ignore-unused */ ReflectionMethod $method)

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...
161
    {
162
        return null;
163
    }
164
}
165