GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

FormDefault::saveBelongsToRelations()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 4
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 6
ccs 0
cts 0
cp 0
crap 20
rs 10
1
<?php
2
3
namespace SleepingOwl\Admin\Form;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Database\Eloquent\Relations\BelongsTo;
7
use Illuminate\Database\Eloquent\Relations\HasOneOrMany;
8
use Illuminate\Validation\ValidationException;
9
use KodiComponents\Support\HtmlAttributes;
10
use SleepingOwl\Admin\Contracts\Display\DisplayInterface;
11
use SleepingOwl\Admin\Contracts\Form\FormButtonsInterface;
12
use SleepingOwl\Admin\Contracts\Form\FormInterface;
13
use SleepingOwl\Admin\Contracts\ModelConfigurationInterface;
14
use SleepingOwl\Admin\Contracts\Repositories\RepositoryInterface;
15
use SleepingOwl\Admin\Exceptions\Form\FormException;
16
use SleepingOwl\Admin\Form\Element\Upload;
17
18
class FormDefault extends FormElements implements DisplayInterface, FormInterface
19
{
20
    use HtmlAttributes;
21
22
    /**
23
     * View to render.
24
     * @var string|\Illuminate\View\View
25
     */
26
    protected $view = 'form.default';
27
28
    /**
29
     * Form related class.
30
     * @var string
31
     */
32
    protected $class;
33
34
    /**
35
     * @var FormButtons
36
     */
37
    protected $buttons;
38
39
    /**
40
     * Form related repository.
41
     * @var RepositoryInterface
42
     */
43
    protected $repository;
44
45
    /**
46
     * Form action url.
47
     * @var string
48
     */
49
    protected $action;
50
51
    /**
52
     * Form related model instance.
53
     * @var Model
54
     */
55
    protected $model;
56
57
    /**
58
     * Currently loaded model id.
59
     * @var int
60
     */
61
    protected $id;
62
63
    /**
64
     * Is form already initialized?
65
     * @var bool
66
     */
67
    protected $initialized = false;
68
69
    /**
70
     * FormDefault constructor.
71
     *
72
     * @param array $elements
73
     */
74
    public function __construct(array $elements = [])
75 12
    {
76
        parent::__construct($elements);
77 12
78
        $this->setButtons(
79 12
            app(FormButtonsInterface::class)
80 12
        );
81 12
    }
82 12
83
    /**
84
     * Initialize form.
85
     * @throws \SleepingOwl\Admin\Exceptions\RepositoryException
86
     */
87 4
    public function initialize()
88
    {
89 4
        if ($this->initialized) {
90
            return;
91
        }
92
93 4
        $this->initialized = true;
94 4
        $this->repository = app(RepositoryInterface::class);
95 4
        $this->repository->setClass($this->class);
96
97 4
        $model = $this->makeModel();
98 4
        parent::setModel($model);
99 4
        $this->getButtons()->setModel($model);
100
101 4
        parent::initialize();
102
103 4
        if (! $this->hasHtmlAttribute('enctype')) {
104
105 4
            // Recursive iterate subset of form elements
106
            // and if subset contains an upload element then add to for
107 4
            $this->recursiveIterateElements(function ($element) {
108 1
                if ($element instanceof Upload) {
109 1
                    $this->withFiles();
110 4
111 4
                    return true;
112
                }
113 4
            });
114 4
        }
115 4
116 4
        $this->getButtons()->setModelConfiguration(
117
            $this->getModelConfiguration()
118
        );
119
    }
120
121 6
    /**
122
     * Set enctype multipart/form-data.
123 6
     *
124
     * @return $this
125
     */
126
    public function withFiles()
127
    {
128
        $this->setHtmlAttribute('enctype', 'multipart/form-data');
129
130
        return $this;
131 12
    }
132
133 12
    /**
134
     * @return FormButtons
135 12
     */
136
    public function getButtons()
137
    {
138
        return $this->buttons;
139
    }
140
141 2
    /**
142
     * @param FormButtonsInterface $buttons
143 2
     *
144
     * @return $this
145
     */
146
    public function setButtons(FormButtonsInterface $buttons)
147
    {
148
        $this->buttons = $buttons;
0 ignored issues
show
Documentation Bug introduced by
$buttons is of type SleepingOwl\Admin\Contra...rm\FormButtonsInterface, but the property $buttons was declared to be of type SleepingOwl\Admin\Form\FormButtons. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
149 1
150
        return $this;
151 1
    }
152
153
    /**
154
     * @return RepositoryInterface
155
     */
156
    public function getRepository()
157
    {
158
        return $this->repository;
159 2
    }
160
161 2
    /**
162 2
     * @return string
163 2
     */
164
    public function getAction()
165 2
    {
166
        return $this->action;
167
    }
168
169
    /**
170
     * @param string $action
171 6
     *
172
     * @return $this
173 6
     */
174
    public function setAction($action)
175
    {
176
        if (is_null($this->action)) {
0 ignored issues
show
introduced by
The condition is_null($this->action) is always false.
Loading history...
177
            $this->action = $action;
178
        }
179
180
        return $this;
181
    }
182 7
183
    /**
184 7
     * @return string
185 7
     */
186 7
    public function getClass()
187
    {
188 7
        return $this->class;
189
    }
190
191
    /**
192
     * @param string $class
193
     *
194
     * @return $this
195
     * @throws FormException
196
     */
197
    public function setModelClass($class)
198
    {
199
        if (is_null($this->class)) {
0 ignored issues
show
introduced by
The condition is_null($this->class) is always false.
Loading history...
200
            $this->class = $class;
201
        }
202
203
        return $this;
204
    }
205
206
    /**
207
     * @return \SleepingOwl\Admin\Form\FormElementsCollection
208
     * @see getElements()
209
     *
210
     * @deprecated 4.5.0
211
     */
212
    public function getItems()
213
    {
214
        return $this->getElements();
215
    }
216
217
    /**
218
     * @param array|\SleepingOwl\Admin\Contracts\Form\FormElementInterface $items
219
     *
220
     * @return $this
221
     * @deprecated 4.5.0
222
     * @see setElements()
223
     */
224
    public function setItems($items)
225
    {
226
        if (! is_array($items)) {
227
            $items = func_get_args();
228
        }
229
230
        return $this->setElements($items);
231
    }
232
233
    /**
234
     * @param \SleepingOwl\Admin\Contracts\Form\FormElementInterface $item
235
     *
236
     * @return $this
237 1
     * @deprecated 4.5.0
238
     * @see addElement()
239 1
     */
240 1
    public function addItem($item)
241
    {
242 1
        return $this->addElement($item);
243 1
    }
244 1
245 1
    /**
246 1
     * Set currently loaded model id.
247
     *
248
     * @param int $id
249
     * @throws \SleepingOwl\Admin\Exceptions\Form\FormException
250
     */
251
    public function setId($id)
252 5
    {
253
        if (is_null($this->id)) {
0 ignored issues
show
introduced by
The condition is_null($this->id) is always false.
Loading history...
254 5
            // Get Model from ModelConfiguration
255
            $model = null;
256 5
            $model_configuration = $this->getModelConfiguration();
257
            if (method_exists($model_configuration, 'getModelValue')) {
258
                $model = $model_configuration->getModelValue();
259
            }
260 5
            // Get Model from Repository
261
            if (! $model && ! is_null($id)) {
262
                $model = $this->getRepository()->find($id);
263
            }
264
            if ($model) {
265
                $this->id = $id;
266 3
267
                parent::setModel($model);
268 3
                $this->getButtons()->setModel($model);
269
                $this->setModelClass(get_class($model));
270
            }
271
        }
272
    }
273
274
    /**
275
     * Get related form model configuration.
276
     * @return ModelConfigurationInterface
277
     */
278
    public function getModelConfiguration()
279
    {
280
        $class = $this->class;
281
282
        if (is_null($class) && $this->getModel() instanceof Model) {
0 ignored issues
show
introduced by
The condition is_null($class) is always false.
Loading history...
283
            $class = $this->getModel();
284
        }
285 3
286
        return app('sleeping_owl')->getModel($class);
0 ignored issues
show
Bug introduced by
The method getModel() does not exist on Illuminate\Contracts\Foundation\Application. ( Ignorable by Annotation )

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

286
        return app('sleeping_owl')->/** @scrutinizer ignore-call */ getModel($class);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
287 3
    }
288
289
    /**
290
     * @return Model
291
     */
292
    public function getModel()
293
    {
294
        return $this->model;
295
    }
296
297
    /**
298 1
     * @param Model $model
299
     *
300 1
     * @return $this
301
     */
302
    public function setModel(Model $model)
303
    {
304 1
        $this->model = $model;
305
306 1
        return $this;
307
    }
308 1
309
    /**
310 1
     * @param ModelConfigurationInterface $modelConfiguration
311
     *
312 1
     * @return bool
313
     */
314
    public function validModelConfiguration(ModelConfigurationInterface $modelConfiguration = null)
315
    {
316 1
        return is_null($modelConfiguration) || $modelConfiguration === $this->getModelConfiguration();
317
    }
318
319
    /**
320 1
     * Save instance.
321
     *
322 1
     * @param \Illuminate\Http\Request $request
323
     * @param ModelConfigurationInterface $modelConfiguration
324 1
     *
325
     * @return bool
326 1
     */
327 1
    public function saveForm(\Illuminate\Http\Request $request, ModelConfigurationInterface $modelConfiguration = null)
328
    {
329 1
        if (! $this->validModelConfiguration($modelConfiguration)) {
330
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...rmInterface::saveForm() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
331
        }
332
333
        $model = $this->getModel();
334
        $loaded = $model->exists;
335
336
        if ($this->getModelConfiguration()->fireEvent($loaded ? 'updating' : 'creating', true, $model) === false) {
0 ignored issues
show
Bug introduced by
The method fireEvent() does not exist on SleepingOwl\Admin\Contra...lConfigurationInterface. Did you maybe mean fireEdit()? ( Ignorable by Annotation )

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

336
        if ($this->getModelConfiguration()->/** @scrutinizer ignore-call */ fireEvent($loaded ? 'updating' : 'creating', true, $model) === false) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
337 1
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...rmInterface::saveForm() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
338
        }
339 1
340
        if ($this->getModelConfiguration()->fireEvent('saving', true, $model) === false) {
341
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...rmInterface::saveForm() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
342
        }
343
344 1
        parent::save($request);
345 1
        $this->saveBelongsToRelations($model);
346
347
        $model->save();
348
349
        $this->saveHasOneRelations($model);
350
351
        parent::afterSave($request);
352 1
353
        $this->getModelConfiguration()->fireEvent($loaded ? 'updated' : 'created', false, $model);
354 1
        $this->getModelConfiguration()->fireEvent('saved', false, $model);
355
356
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...rmInterface::saveForm() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
357
    }
358
359
    /**
360
     * @param Model $model
361
     *
362 1
     * @return void
363 1
     */
364
    protected function saveBelongsToRelations(Model $model)
365
    {
366
        foreach ($model->getRelations() as $name => $relation) {
367
            if ($model->{$name}() instanceof BelongsTo && ! is_null($relation)) {
368
                $relation->save();
369
                $model->{$name}()->associate($relation);
370
            }
371 2
        }
372
    }
373 2
374
    /**
375
     * @param Model $model
376
     *
377 2
     * @return void
378
     */
379 2
    protected function saveHasOneRelations(Model $model)
380
    {
381 2
        foreach ($model->getRelations() as $name => $relation) {
382 2
            if ($model->{$name}() instanceof HasOneOrMany && ! is_null($relation)) {
383 2
                if (is_array($relation) || $relation instanceof \Traversable) {
384 2
                    $model->{$name}()->saveMany($relation);
385 2
                } else {
386 2
                    $model->{$name}()->save($relation);
387
                }
388 2
            }
389
        }
390 2
    }
391
392 2
    /**
393 1
     * @param \Illuminate\Http\Request $request
394
     * @param ModelConfigurationInterface $modelConfiguration
395 1
     *
396
     * @throws ValidationException
397
     */
398
    public function validateForm(\Illuminate\Http\Request $request, ModelConfigurationInterface $modelConfiguration = null)
399
    {
400
        if (! $this->validModelConfiguration($modelConfiguration)) {
401
            return;
402
        }
403
404
        $verifier = app('validation.presence');
405
406
        $verifier->setConnection($this->getModel()->getConnectionName());
407
408
        $validator = \Validator::make(
409
            $request->all(),
410
            $this->getValidationRules(),
411
            $this->getValidationMessages(),
412
            $this->getValidationLabels()
413
        );
414
415
        $validator->setPresenceVerifier($verifier);
416
417
        $this->getModelConfiguration()->fireEvent('validate', false, $this->getModel(), $validator);
418
419
        if ($validator->fails()) {
420 4
            throw new ValidationException($validator);
421
        }
422 4
    }
423
424 4
    /**
425
     * Get the instance as an array.
426
     *
427
     * @return array
428
     */
429
    public function toArray()
430
    {
431
        // This element needs only in template
432
        $this->setHtmlAttribute('method', 'POST');
433
        $this->setHtmlAttribute('action', $this->getAction());
434
435
        return [
436
            'items' => $this->getElements()->onlyVisible(),
437
            'instance' => $this->getModel(),
438
            'attributes' => $this->htmlAttributesToString(),
439
            'buttons' => $this->getButtons(),
440
            'backUrl' => session('_redirectBack', \URL::previous()),
441
        ];
442
    }
443
444
    /**
445
     * @return Model
446
     */
447
    protected function makeModel()
448
    {
449
        $class = $this->getClass();
450
451
        return new $class();
452
    }
453
}
454