Completed
Push — dev ( b65692...5bc640 )
by Marc
13:01
created

Model::getCurrent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 4
rs 10
cc 2
eloc 2
nc 2
nop 0
1
<?php namespace Mascame\Artificer\Model;
2
3
use Illuminate\Contracts\Database\ModelIdentifier;
4
use View;
5
use Route;
6
use \Illuminate\Support\Str as Str;
7
use Mascame\Artificer\Options\AdminOption;
8
9
// Todo: get column type http://stackoverflow.com/questions/18562684/how-to-get-database-field-type-in-laravel
10
class Model
11
{
12
13
    /**
14
     * @var ModelSchema
15
     */
16
    public $schema;
17
18
    /**
19
     * @var array
20
     */
21
    public $models;
22
23
    /**
24
     * @var array
25
     */
26
    public $columns;
27
28
    /**
29
     * @var \Illuminate\Database\Eloquent\Model
30
     */
31
    public $model;
32
33
    /**
34
     * @var string
35
     */
36
    public $class;
37
38
    /**
39
     * @var
40
     */
41
    public $name;
42
43
    /**
44
     * @var string
45
     */
46
    public $keyname;
47
48
    /**
49
     * @var
50
     */
51
    public $table;
52
53
    /**
54
     * @var
55
     */
56
    public $fillable;
57
58
    /**
59
     * @var array|mixed
60
     */
61
    protected $options = [];
62
    protected $defaultOptions = null;
63
64
    /**
65
     * @var array|mixed
66
     */
67
    public $relations = [];
68
69
    /**
70
     * @var
71
     */
72
    public static $current = null;
73
74
    /**
75
     * @param ModelSchema $schema
76
     */
77
    public function __construct(ModelSchema $schema)
78
    {
79
        $this->schema = $schema;
80
        $this->relations = new ModelRelation();
81
82
        if (Str::startsWith(Route::currentRouteName(), 'admin.model.')) {
83
            $this->prepareCurrentModel();
84
        }
85
86
        $this->share();
87
    }
88
89
90
    public function share()
91
    {
92
        View::share('tables', $this->schema->tables);
93
        View::share('models', $this->models = $this->getModelsData());
94
        View::share('model', $this->getCurrentModelData());
95
    }
96
97
    /**
98
     * @return array
99
     */
100
    private function getModelsData()
101
    {
102
        foreach ($this->schema->models as $modelName => $model) {
103
            $this->schema->models[$modelName]['options'] = $this->getOptions($modelName);
104
            $this->schema->models[$modelName]['hidden'] = $this->isHidden($modelName);
105
106
            $title = null;
0 ignored issues
show
Unused Code introduced by
$title is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
107
            if (isset($this->schema->models[$modelName]['title'])) {
108
                $title = $this->schema->models[$modelName]['title'];
109
            } else {
110
                $title = Str::title(
111
                  str_replace('_', ' ', $this->schema->models[$modelName]['table'])
112
                );
113
            }
114
115
            $this->schema->models[$modelName]['title'] = $title;
116
        }
117
118
        return $this->schema->models;
119
    }
120
121
    /**
122
     * @param $modelName
123
     * @return bool
124
     */
125
    public function isHidden($modelName)
126
    {
127
        return in_array($modelName, config('admin.model.hidden'));
128
    }
129
130
    /**
131
     * @return bool
132
     */
133
    public function hasGuarded()
134
    {
135
        return ! empty($this->getGuarded());
136
    }
137
138
    /**
139
     * Look for admin model config, if there is nothing fallback to Model property
140
     *
141
     * @return array|mixed
142
     */
143
    public function getGuarded()
144
    {
145
        return $this->getOption('guarded', $this->model->getGuarded());
146
    }
147
148
    /**
149
     * Look for admin model config, if there is nothing fallback to Model property
150
     *
151
     * @return array|mixed
152
     */
153
    public function getFillable()
154
    {
155
        return $this->getOption('fillable', $this->model->getFillable());
156
    }
157
158
    /**
159
     * @return bool
160
     */
161
    public function hasFillable()
162
    {
163
        return ! empty($this->getFillable());
164
    }
165
166
    /**
167
     * @return int|null|string
168
     */
169
    private function getCurrentModelName()
170
    {
171
        if ($this->name) return $this->name;
172
173
        foreach ($this->schema->models as $modelName => $model) {
174
            if ($this->isCurrent($modelName)) {
175
                $this->setCurrent($modelName);
176
177
                return $this->name = $modelName;
178
            }
179
        }
180
181
        return null;
182
    }
183
184
    protected function prepareCurrentModel()
185
    {
186
        $this->name = $this->getCurrentModelName();
187
        $this->class = $this->schema->getClass($this->name);
188
        $this->model = $this->schema->getInstance($this->name);
0 ignored issues
show
Bug introduced by
It seems like $this->name can also be of type integer or string; however, Mascame\Artificer\Model\ModelSchema::getInstance() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
189
        $this->table = $this->model->getTable();
190
        $this->columns = $this->schema->getColumns($this->table);
191
        $this->fillable = $this->model->getFillable();
192
193
        $this->addFieldOptions($this->columns);
194
    }
195
196
    /**
197
     * Fills all fields in config if they are not declared and applies default attributes
198
     *
199
     * @param $columns
200
     * @param null $model
201
     * @return mixed
202
     */
203
    protected function addFieldOptions($columns, $model = null) {
204
        $model = ($model) ? $model : $this->name;
205
206
        $this->getOptions($model);
0 ignored issues
show
Bug introduced by
It seems like $model defined by $model ? $model : $this->name on line 204 can also be of type integer or string; however, Mascame\Artificer\Model\Model::getOptions() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
207
208
        foreach ($columns as $column) {
209
            if (! isset($this->options[$model]['fields'][$column])) {
210
                $this->options[$model]['fields'][$column] = [];
211
            }
212
213
            if (! isset($this->options[$model]['fields'][$column]['attributes'])) {
214
                $this->options[$model]['fields'][$column]['attributes'] = $this->options[$model]['attributes'];
215
            }
216
        }
217
    }
218
219
    /**
220
     * @return array
221
     */
222
    private function getCurrentModelData()
223
    {
224
        return array(
225
            'class' => $this->class,
226
            'name' => $this->getCurrentModelName(),
227
            'route' => $this->getRouteName(),
228
            'table' => $this->table,
229
            'columns' => $this->schema->columns,
230
            'fillable' => $this->fillable,
231
            'hidden' => $this->isHidden($this->name),
232
        );
233
    }
234
235
    /**
236
     * @param $model
237
     * @return bool
238
     */
239
    protected function isCurrent($modelName)
240
    {
241
        if ( ! Route::current()) return null;
242
        
243
        $slug = Route::current()->parameter('slug');
244
245
        return (isset($this->schema->models[$modelName]['route']) && $this->schema->models[$modelName]['route'] == $slug);
246
    }
247
248
    /**
249
     * @return Model
250
     */
251
    public static function getCurrent()
252
    {
253
        return (isset(self::$current)) ? self::$current : null;
254
    }
255
256
    /**
257
     * @param null $model
258
     * @return null
259
     */
260
    public function getRouteName($model = null)
261
    {
262
        if ($model) return $this->schema->models[$model]['route'];
263
264
        return (isset($this->schema->models[self::$current]['route'])) ? $this->schema->models[self::$current]['route'] : null;
265
    }
266
267
    /**
268
     * @param $modelName
269
     */
270
    protected function setCurrent($modelName)
271
    {
272
        self::$current = $modelName;
273
//        ModelOption::set('current', $modelName);
274
    }
275
276
    /**
277
     * @param null $model
278
     * @return mixed
279
     */
280
    public function getOptions($model = null)
281
    {
282
        $model = ($model) ? $model : $this->name;
283
284
        if (isset($this->options[$model])) return $this->options[$model];
285
286
        return $this->options[$model] = array_merge(
287
            $this->getDefaultOptions(),
288
            config('admin.models.' . $model, [])
289
        );
290
    }
291
292
    public function getDefaultOptions()
293
    {
294
        if ($this->defaultOptions) return $this->defaultOptions;
295
296
        return $this->defaultOptions = config('admin.model.default');
297
    }
298
299
    /**
300
     * Take care! This are the options reflected in config files.
301
     * Processed guarded/fillable should used with their own getters.
302
     *
303
     * @param $key
304
     * @param null $model
305
     * @return mixed
306
     */
307
    public function getOption($key, $default = null, $model = null)
308
    {
309
        $model = ($model) ? $model : $this->name;
310
        $options = $this->getOptions($model);
0 ignored issues
show
Bug introduced by
It seems like $model defined by $model ? $model : $this->name on line 309 can also be of type integer or string; however, Mascame\Artificer\Model\Model::getOptions() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
311
312
        return (isset($options[$key])) ? $options[$key] : $default;
313
    }
314
315
    /**
316
     * @return array|mixed
317
     */
318
    public function getRelations()
319
    {
320
        return $this->relations->get();
321
    }
322
323
}