Completed
Push — master ( a13290...ae4efa )
by Song
30s
created

src/Form/Field/MultipleSelect.php (2 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Encore\Admin\Form\Field;
4
5
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Str;
8
9
class MultipleSelect extends Select
10
{
11
    /**
12
     * Other key for many-to-many relation.
13
     *
14
     * @var string
15
     */
16
    protected $otherKey;
17
18
    /**
19
     * Get other key for this many-to-many relation.
20
     *
21
     * @throws \Exception
22
     *
23
     * @return string
24
     */
25
    protected function getOtherKey()
26
    {
27
        if ($this->otherKey) {
28
            return $this->otherKey;
29
        }
30
31
        if (is_callable([$this->form->model(), $this->column]) &&
0 ignored issues
show
The method model does only exist in Encore\Admin\Form, but not in Encore\Admin\Widgets\Form.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
32
            ($relation = $this->form->model()->{$this->column}()) instanceof BelongsToMany
33
        ) {
34
            /* @var BelongsToMany $relation */
35
            $fullKey = $relation->getQualifiedRelatedPivotKeyName();
36
            $fullKeyArray = explode('.', $fullKey);
37
38
            return $this->otherKey = end($fullKeyArray);
39
        }
40
41
        throw new \Exception('Column of this field must be a `BelongsToMany` relation.');
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47
    public function fill($data)
48
    {
49
        if ($this->form && $this->form->shouldSnakeAttributes()) {
0 ignored issues
show
The method shouldSnakeAttributes does only exist in Encore\Admin\Form, but not in Encore\Admin\Widgets\Form.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
50
            $key = Str::snake($this->column);
51
        } else {
52
            $key = $this->column;
53
        }
54
55
        $relations = Arr::get($data, $key);
56
57
        if (is_string($relations)) {
58
            $this->value = explode(',', $relations);
59
        }
60
61
        if (!is_array($relations)) {
62
            $this->applyCascadeConditions();
63
64
            return;
65
        }
66
67
        $first = current($relations);
68
69 View Code Duplication
        if (is_null($first)) {
70
            $this->value = null;
71
72
        // MultipleSelect value store as an ont-to-many relationship.
73
        } elseif (is_array($first)) {
74
            foreach ($relations as $relation) {
75
                $this->value[] = Arr::get($relation, "pivot.{$this->getOtherKey()}");
76
            }
77
78
            // MultipleSelect value store as a column.
79
        } else {
80
            $this->value = $relations;
81
        }
82
83
        $this->applyCascadeConditions();
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function setOriginal($data)
90
    {
91
        $relations = Arr::get($data, $this->column);
92
93
        if (is_string($relations)) {
94
            $this->original = explode(',', $relations);
95
        }
96
97
        if (!is_array($relations)) {
98
            return;
99
        }
100
101
        $first = current($relations);
102
103 View Code Duplication
        if (is_null($first)) {
104
            $this->original = null;
105
106
        // MultipleSelect value store as an ont-to-many relationship.
107
        } elseif (is_array($first)) {
108
            foreach ($relations as $relation) {
109
                $this->original[] = Arr::get($relation, "pivot.{$this->getOtherKey()}");
110
            }
111
112
            // MultipleSelect value store as a column.
113
        } else {
114
            $this->original = $relations;
115
        }
116
    }
117
118
    public function prepare($value)
119
    {
120
        $value = (array) $value;
121
122
        return array_filter($value, 'strlen');
123
    }
124
}
125