Completed
Push — master ( 7f24b2...59bc14 )
by Adrian
10:04
created

Field::setValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
ccs 0
cts 6
cp 0
crap 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Anavel\Crud\Abstractor\Eloquent;
3
4
use Anavel\Crud\Contracts\Abstractor\Field as FieldAbstractorContract;
5
use Doctrine\DBAL\Schema\Column;
6
use FormManager\Fields\Field as FormManagerField;
7
use Request;
8
9
class Field implements FieldAbstractorContract
10
{
11
    /**
12
     * @var Column
13
     */
14
    protected $dbal;
15
    /**
16
     * @var FormManagerField
17
     */
18
    protected $formField;
19
    protected $name;
20
    protected $value;
21
    protected $presentation;
22
    protected $validationRules;
23
    protected $functions;
24
    protected $options;
25
    protected $hideValue;
26
    protected $saveIfEmpty;
27
    protected $noValidate;
28
29 5
    public function __construct(Column $column, FormManagerField $formField, $name, $presentation = null)
30
    {
31 5
        $this->dbal = $column;
32 5
        $this->formField = $formField;
33 5
        $this->name = $name;
34 5
        $this->presentation = $presentation;
35 5
        $this->validationRules = array();
36 5
        $this->functions = array();
37 5
        $this->options = [];
38 5
        $this->hideValue = false;
39 5
        $this->saveIfEmpty = true;
40 5
        $this->noValidate = false;
41 5
    }
42
43
    public function __clone()
44
    {
45
        $formField = clone $this->formField;
46
        $this->formField = $formField;
47
        $field = new Field($this->dbal, $formField, $this->name, $this->presentation);
48
49
        return $field;
50
    }
51
52
    public function getName()
53
    {
54
        return $this->name;
55
    }
56
57
    /**
58
     * @param string $name
59
     */
60
    public function setName($name)
61
    {
62
        $this->name = $name;
63
    }
64
65 1
    public function presentation()
66
    {
67 1
        if ($this->presentation) {
68 1
            return transcrud($this->presentation);
69
        }
70
71
        $nameWithSpaces = str_replace('_', ' ', $this->name);
72
        $namePieces = explode(' ', $nameWithSpaces);
73
        $namePieces = array_map('trim', $namePieces);
74
75
        return ucfirst(transcrud(implode(' ', $namePieces)));
76
    }
77
78 1
    public function type()
79
    {
80 1
        return $this->dbal->getType();
81
    }
82
83
    public function setValidationRules($rules)
84
    {
85
        $this->validationRules = explode('|', $rules);
86
    }
87
88 1
    public function getValidationRules()
89
    {
90 1
        if (count($this->validationRules) === 0 && $this->noValidate() === false) {
91 1
            if ($this->dbal->getNotnull()) {
92 1
                $this->validationRules[] = 'required';
93 1
            }
94 1
        }
95
96 1
        return implode('|', $this->validationRules);
97
    }
98
99
    /**
100
     * @return array
101
     */
102
    public function getValidationRulesArray()
103
    {
104
        return explode('|', $this->getValidationRules());
105
    }
106
107
    public function setFunctions($functions)
108
    {
109
        if (! is_array($functions)) {
110
            $functions = array($functions);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $functions. This often makes code more readable.
Loading history...
111
        }
112
113
        $this->functions = $functions;
114
    }
115
116
    public function applyFunctions($value)
117
    {
118
        foreach ($this->functions as $function) {
119
            if (! function_exists($function)) {
120
                throw new \Exception("Function ".$function." does not exist");
121
            }
122
123
            $value = call_user_func($function, $value);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $value. This often makes code more readable.
Loading history...
124
        }
125
126
        return $value;
127
    }
128
129
    /**
130
     * @param string $value
131
     * @return void
132
     */
133
    public function setValue($value)
134
    {
135
        $this->value = $value;
136
137
        if (! $this->hideValue()) {
138
            $this->formField->val($this->value);
139
        }
140
    }
141
142
    /**
143
     * @return mixed
144
     */
145
    public function getValue()
146
    {
147
        return $this->value;
148
    }
149
150
    /**
151
     * @param array $options
152
     * @return void
153
     */
154
    public function setOptions(array $options)
155
    {
156
        $this->options = $options;
157
158
        $this->formField->options($this->options);
159
    }
160
161
    /**
162
     * @return array
163
     */
164
    public function getOptions()
165
    {
166
        return $this->options;
167
    }
168
169
    public function getFormField()
170
    {
171
        if (! $this->hideValue()) {
172
            if (Request::old($this->name)) {
173
                $this->formField->val(Request::old($this->name));
174
            }
175
        }
176
177
        return $this->formField;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->formField; (FormManager\Fields\Field) is incompatible with the return type declared by the interface Anavel\Crud\Contracts\Ab...tor\Field::getFormField of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
178
    }
179
180
    /**
181
     *
182
     */
183
    public function hideValue($value = null)
184
    {
185
        if (! is_null($value)) {
186
            $this->hideValue = $value;
187
        }
188
189
        return $this->hideValue;
190
    }
191
192
    /**
193
     *
194
     */
195
    public function saveIfEmpty($value = null)
196
    {
197
        if (! is_null($value)) {
198
            $this->saveIfEmpty = $value;
199
        }
200
201
        return $this->saveIfEmpty;
202
    }
203
204
    /**
205
     *
206
     */
207 1
    public function noValidate($value = null)
208
    {
209 1
        if (! is_null($value)) {
210
            $this->noValidate = $value;
211
        }
212
213 1
        return $this->noValidate;
214
    }
215
216
    /**
217
     * @param array $attributes
218
     * @return void
219
     */
220
    public function setFormElementAttributes(array $attributes)
221
    {
222
        $this->formField->attr($attributes);
223
    }
224
}
225