Completed
Push — master ( ab5ce3...f55930 )
by Helmut
02:51
created

Field::setFromDefault()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
nc 2
cc 2
eloc 2
nop 0
crap 2
1
<?php 
2
3
namespace Helmut\Forms;
4
5
use Helmut\Forms\Utility\Str;
6
use Helmut\Forms\Utility\Reflect;
7
8
abstract class Field {
9
10
    /**
11
     * The parent form.
12
     *
13
     * @var \Helmut\Forms\Form
14
     */
15
    protected $form;
16
17
    /**
18
     * The type of the field.
19
     *
20
     * @var string
21
     */
22
    public $type;
23
24
    /**
25
     * The name of the field.
26
     *
27
     * @var string
28
     */
29
    public $name;
30
31
    /**
32
     * The unique id of the field.
33
     *
34
     * @var string
35
     */
36
    public $id;     
37
38
    /**
39
     * The label property of the field.
40
     *
41
     * @var string
42
     */
43
    public $label;
44
45
    /**
46
     * The default value of the field.
47
     *
48
     * @var array
49
     */
50
    protected $default;
51
52
    /**
53
     * Field is required.
54
     *
55
     * @var boolean
56
     */
57
    protected $required = false;
58
59
    /**
60
     * An array of validation methods.
61
     *
62
     * @var array
63
     */
64
    protected $validations = [];
65
66
    /**
67
     * An array of validation errors.
68
     *
69
     * @var array
70
     */
71
    protected $errors = [];
72
73
    /**
74
     * Create a field instance.
75
     *
76
     * @param  \Helmut\Forms\Form  $form
77 118
     * @param  string  $type
78
     * @param  string  $name
79 118
     */
80 118
    public function __construct(\Helmut\Forms\Form $form, $type, $name)
81 118
    {
82
        $this->form = $form;
83 118
        $this->type = $type;
84 118
        $this->name = $name;
85
86
        $this->setId();
87
    }
88
89
    /**
90
     * Return an the value of the field. For fields 
91
     * with multiple values return an array of values
92
     * using associative key names.
93
     *
94
     * @return array
95
     */
96
    abstract public function getValue();
97
98
    /**
99
     * Provide the key names of any buttons. Multiple
100
     * buttons may be returned using an array.
101
     *
102
     * @return mixed
103
     */    
104
    abstract public function getButtonName();
105
106
    /**
107
     * Return array of properties for renderering.
108
     *
109
     * @return array
110
     */
111
    abstract public function renderWith();
112
113
    /**
114
     * Set field value using provided default.
115
     *
116
     * @param mixed  $default
0 ignored issues
show
Bug introduced by
There is no parameter named $default. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
117
     * @return void
118
     */
119
    abstract public function setValueFromDefault();
120
121
    /**
122
     * Set value using a model.
123
     *
124
     * @param object  $model
125
     * @return void
126
     */    
127
    abstract public function setValueFromModel($model);
128
129
    /**
130
     * Set value from the request.
131
     *
132
     * @param \Helmut\Forms\Request  $request
133
     * @return void
134
     */    
135
    abstract public function setValueFromRequest($request);
136
137
    /**
138
     * Fill a model with field values.
139
     *
140
     * @param object  $model
141
     * @return void
142
     */    
143
    abstract public function fillModelWithValue($model);
144
145
    /**
146
     * Return if field passes required validation.
147
     *
148
     * @return boolean
149
     */    
150
    abstract public function validateRequired();
151 118
152
    /**
153 118
     * Set a unique id.
154 118
     *
155 118
     * @return void
156
     */
157
    public function setId()
158
    {
159
        $id = $this->type.'_'.substr(md5($this->name), 0, 5);
160
        $this->id = $this->form->id.'_'.$id;
161
    }
162 46
163
    /**
164 46
     * Return an array of keys.
165
     *
166
     * @return array
167
     */
168
    public function keys()
169
    {
170
        return array_keys($this->values());
171
    }
172 72
173
    /**
174 72
     * Return an array of values.
175
     *
176
     * @return array
177
     */
178
    public function values() 
179
    {
180
        $values = $this->getValue();
181
182 45
        if (is_null($values)) $values = [];
183
184 45
        else if ( ! is_array($values)) $values = [$this->name => $values];
185
186
        return $values;
187
    }
188
189
    /**
190
     * Return an array of properties to be passed
191
     * to the template during rendering.
192 118
     *
193
     * @return array
194 118
     */    
195
    public function properties() 
196
    {
197
        $properties = $this->renderWith();
198
199
        if (is_null($properties)) $properties = [];
200
201
        return $properties;
202 111
    }
203
204 111
    /**
205 111
     * Return an array of button keys.
206
     *
207
     * @return array
208
     */    
209
    public function buttons()
210
    {
211
        $buttons = $this->getButtonName();
212
213 7
        if (is_null($buttons)) $buttons = [];
214
215 7
        else if ( ! is_array($buttons)) $buttons = [$buttons];
216 7
217
        return $buttons;
218
    }
219
220
    /**
221
     * Set the field value using default.
222
     *
223
     * @return void
224 9
     */ 
225
    public function setFromDefault()
226 9
    {
227 9
        if ( ! is_null($this->default)) $this->setValueFromDefault();
228
    }
229
230
    /**
231
     * Set the field value using request.
232
     *
233
     * @param \Helmut\Forms\Request  $request
234
     * @return void
235 13
     */ 
236
    public function setFromRequest($request)
237 13
    {
238 13
        $this->setValueFromRequest($request);
239
    }
240
241
    /**
242
     * Set the field values using a model.
243
     *
244
     * @param object  $model
245
     * @return void
246
     */     
247
    public function setFromModel($model)
248
    {
249
        $this->setValueFromModel($model);
250
    }
251
252
    /**
253
     * Fill a model with field value;
254
     *
255
     * @param object  $model
256
     * @return void
257
     */     
258
    public function fillModel($model)
259
    {
260
        $this->fillModelWithValue($model);
261
    }
262
263
    /**
264
     * Return the name.
265
     *
266
     * @return string
267
     */
268
    public function getName()
269 27
    {
270
        return $this->name;
271 27
    }    
272
273 27
    /**
274
     * Set the label property.
275
     *
276
     * @param string  $label
277
     * @return $this
278
     */
279
    public function setLabel($label)
280
    {
281
        $this->label = $label;
282 45
283
        return $this;
284 45
    }
285
286 45
    /**
287
     * Set required status.
288
     *
289
     * @param boolean  $status
290
     * @return $this
291
     */
292
    public function setRequired($status = true)
293
    {
294 72
        $this->required = $status;
295
296 72
        return $this;
297
    } 
298
299
    /**
300
     * Set the default value.
301
     *
302
     * @param mixed  $value
303
     * @return $this
304 72
     */
305
    public function setDefault($value) 
306 72
    {
307
        $this->default = $value;
0 ignored issues
show
Documentation Bug introduced by
It seems like $value of type * is incompatible with the declared type array of property $default.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
308
309
        return $this;
310
    }
311
312
    /**
313
     * Check if valid.
314 28
     *
315
     * @return boolean
316 28
     */
317 24
    public function isValid() 
318
    {
319
        return count($this->errors) == 0;
320 28
    }
321
322 22
    /**
323
     * Check if invalid.
324 22
     *
325 9
     * @return boolean
326
     */
327
    public function isInvalid() 
328 22
    {
329 17
        return ! $this->isValid();
330
    }
331
332
    /**
333 28
     * Perform all validations.
334
     *
335
     * @return void
336
     */
337
    public function runValidations() 
338
    {
339
        if ($this->required) {
340 27
            $this->callValidationMethod('validateRequired');
341
        }
342 27
343
        if ($this->isNotEmpty()) {
344 27
345 27
            $validations = $this->validations;          
346 27
347
            if (method_exists($this, 'validate')) {
348
                $validations = array_merge(['validate' => []], $validations);
349 20
            }
350
351 20
            foreach ($validations as $validation => $parameters) {
352
                $this->callValidationMethod($validation, $parameters);
353
            }
354
        }
355
356
    }
357
358
    /**
359 45
     * Call a validation method.
360
     *
361 45
     * @return boolean
362
     */
363
    public function callValidationMethod($validation, $parameters = []) 
364
    {
365
        $method = Str::snake($validation);
366
        
367
        if ( ! call_user_func_array([$this, $validation], $parameters)) {   
368
            $this->errors[$method] = $parameters;
369 28
            return false;
370
        }
371 28
372
        if (isset($this->errors[$method])) unset($this->errors[$method]);
373
374
        return true;
375
    }
376
377
    /**
378
     * Check if field is required.
379 1
     *
380
     * @return boolean
381 1
     */
382
    public function isRequired() 
383
    {
384
        return $this->required;
385
    }     
386
387
    /**
388
     * Check if field has been filled.
389
     *
390
     * @return boolean
391
     */
392
    public function isNotEmpty() 
393
    {
394
        return $this->validateRequired();
395
    }   
396
397
    /**
398
     * Return validation errors.
399
     *
400
     * @return array
401
     */
402 25
    public function errors() 
403
    {
404 25
        return $this->errors;
405
    }
406 25
407
    /**
408 23
     * Add a user defined validation error.
409 17
     *
410
     * @return array
411
     */
412 23
    public function error($message)
413
    {
414
        if ( ! isset($this->errors['userDefined'])) $this->errors['userDefined'] = [];
415 2
416
        $this->errors['userDefined'][] = $message;
417 2
    }
418 2
419
    /**
420
     * Get the value of a field.
421
     *
422
     * @param  string  $key
423
     * @return mixed
424
     */
425
    public function value($key = null) 
426
    {
427 75
        $values = $this->values();
428
429 75
        if (is_null($key)) {
430
            
431
            if (count($values) == 1) {
432
                $values = current($values);
433
            }
434
435
            return $values;
436
        }
437
        
438
        $key = $this->name.'_'.$key;
439
440
        if (array_key_exists($key, $values)) {
441
            return $values[$key];
442
        }
443
    }
444
445
    /**
446
     * Get the parent form.
447
     *
448
     * @return \Helmut\Forms\Form
449
     */
450
    public function getForm()
451
    {
452
        return $this->form;
453
    }   
454
455 74
    /**
456
     * Gives this class the ability to set and get any of the
457 74
     * properties of the instances that inherit from this class
458
     * using shorthand notation. Call label() instead of
459 74
     * setLabel() for example.
460
     *
461 74
     * Also it allows you to specify validations in the same dynamic
462 74
     * manner like required() or between(1, 10).
463 74
     *
464
     * @param string  $method
465
     * @param array  $parameters
466 14
     * @return mixed
467 14
     */
468
    public function __call($method, $parameters)
469 14
    {
470
        if ( ! method_exists($this, $method)) {
471
472 14
            $method = Str::studly($method);
473 14
474 10
            $name = 'set'.$method;
475
            if (method_exists($this, $name)) {
476
                return call_user_func_array([$this, $name], $parameters);
477 14
            }
478
479 14
            $name = 'validate'.$method;
480
            if (method_exists($this, $name)) {
481 14
482
                $arguments = Reflect::getParameters($this, $name);
483
                $parameters = array_pad($parameters, count($arguments), null);
484
                $this->validations[$name] = array_combine($arguments, $parameters);
485
486
                return $this;
487
            }           
488
        }
489
    }
490
491
}