Completed
Push — master ( 0b5561...462480 )
by Helmut
05:00
created

Field::clearValidationError()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 0
cts 1
cp 0
rs 10
cc 2
eloc 2
nc 2
nop 1
crap 6
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
        $validated = call_user_func_array([$this, $validation], $parameters);
368
369 28
        if ($validated) {
370
            $this->clearValidationError($method);
371 28
            return true;
372
        }
373
374
        $this->addValidationError($method, $parameters);
375
        return false;
376
    }    
377
378
    /**
379 1
     * Check if field is required.
380
     *
381 1
     * @return boolean
382
     */
383
    public function isRequired() 
384
    {
385
        return $this->required;
386
    }     
387
388
    /**
389
     * Check if field has been filled.
390
     *
391
     * @return boolean
392
     */
393
    public function isNotEmpty() 
394
    {
395
        return $this->validateRequired();
396
    }   
397
398
    /**
399
     * Return validation errors.
400
     *
401
     * @return array
402 25
     */
403
    public function errors() 
404 25
    {
405
        return $this->errors;
406 25
    }
407
408 23
    /**
409 17
     * Add a user defined validation error.
410
     *
411
     * @return array
412 23
     */
413
    public function error($message)
414
    {
415 2
        if ( ! isset($this->errors['userDefined'])) $this->errors['userDefined'] = [];
416
417 2
        $this->errors['userDefined'][] = $message;
418 2
    }
419
420
    /**
421
     * Add an internal validation error.
422
     *
423
     * @param string  $method     
424
     * @param array  $parameters     
425
     * @return void
426
     */
427 75
    protected function addValidationError($method, $parameters) 
428
    {
429 75
        $this->errors[$method] = $parameters;
430
    }
431
432
    /**
433
     * Remove all internal validation error for method.
434
     *
435
     * @param string  $method     
436
     * @return void
437
     */
438
    protected function clearValidationError($method) 
439
    {
440
        if (isset($this->errors[$method])) unset($this->errors[$method]);
441
    }    
442
443
    /**
444
     * Get the value of a field.
445
     *
446
     * @param  string  $key
447
     * @return mixed
448
     */
449
    public function value($key = null) 
450
    {
451
        $values = $this->values();
452
453
        if (is_null($key)) {
454
            
455 74
            if (count($values) == 1) {
456
                $values = current($values);
457 74
            }
458
459 74
            return $values;
460
        }
461 74
        
462 74
        $key = $this->name.'_'.$key;
463 74
464
        if (array_key_exists($key, $values)) {
465
            return $values[$key];
466 14
        }
467 14
    }
468
469 14
    /**
470
     * Get the parent form.
471
     *
472 14
     * @return \Helmut\Forms\Form
473 14
     */
474 10
    public function getForm()
475
    {
476
        return $this->form;
477 14
    }   
478
479 14
    /**
480
     * Gives this class the ability to set and get any of the
481 14
     * properties of the instances that inherit from this class
482
     * using shorthand notation. Call label() instead of
483
     * setLabel() for example.
484
     *
485
     * Also it allows you to specify validations in the same dynamic
486
     * manner like required() or between(1, 10).
487
     *
488
     * @param string  $method
489
     * @param array  $parameters
490
     * @return mixed
491
     */
492
    public function __call($method, $parameters)
493
    {
494
        if ( ! method_exists($this, $method)) {
495
496
            $method = Str::studly($method);
497
498
            $name = 'set'.$method;
499
            if (method_exists($this, $name)) {
500
                return call_user_func_array([$this, $name], $parameters);
501
            }
502
503
            $name = 'validate'.$method;
504
            if (method_exists($this, $name)) {
505
506
                $arguments = Reflect::getParameters($this, $name);
507
                $parameters = array_pad($parameters, count($arguments), null);
508
                $this->validations[$name] = array_combine($arguments, $parameters);
509
510
                return $this;
511
            }           
512
        }
513
    }
514
515
}