Field::getForm()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
ccs 0
cts 0
cp 0
cc 1
eloc 2
nc 1
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 mixed
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
     * @return void
117
     */
118
    abstract public function setValueFromDefault();
119
120
    /**
121
     * Set value using a model.
122
     *
123
     * @param object  $model
124
     * @return void
125
     */    
126
    abstract public function setValueFromModel($model);
127
128
    /**
129
     * Set value from the request.
130
     *
131
     * @param \Helmut\Forms\Request  $request
132
     * @return void
133
     */    
134
    abstract public function setValueFromRequest($request);
135
136
    /**
137
     * Fill a model with field values.
138
     *
139
     * @param object  $model
140
     * @return void
141
     */    
142
    abstract public function fillModelWithValue($model);
143
144
    /**
145
     * Return if field validates required.
146
     *
147
     * @return boolean
148
     */    
149
    abstract public function validateRequired();
150
151 118
    /**
152
     * Set a unique id.
153 118
     *
154 118
     * @return void
155 118
     */
156
    public function setId()
157
    {
158
        $id = $this->type.'_'.substr(md5($this->name), 0, 5);
159
        $this->id = $this->form->id.'_'.$id;
160
    }
161
162 46
    /**
163
     * Return an array of keys.
164 46
     *
165
     * @return array
166
     */
167
    public function keys()
168
    {
169
        return array_keys($this->values());
170
    }
171
172 72
    /**
173
     * Return an array of values.
174 72
     *
175
     * @return array
176
     */
177
    public function values() 
178
    {
179
        $values = $this->getValue();
180
181
        if (is_null($values)) {
182 45
            return [];
183
        } 
184 45
185
        if ( ! is_array($values)) {
186
            return [$this->name => $values];
187
        }
188
189
        return $values;
190
    }
191
192 118
    /**
193
     * Return an array of properties to be passed
194 118
     * to the template during rendering.
195
     *
196
     * @return array
197
     */    
198
    public function properties() 
199
    {
200
        $properties = $this->renderWith();
201
202 111
        if (is_null($properties)) {
203
            return [];
204 111
        }
205 111
206
        return $properties;
207
    }
208
209
    /**
210
     * Return an array of button keys.
211
     *
212
     * @return array
213 7
     */    
214
    public function buttons()
215 7
    {
216 7
        $buttons = $this->getButtonName();
217
218
        if (is_null($buttons)) {
219
            return [];
220
        }
221
222
        if ( ! is_array($buttons)) {
223
            return [$buttons];
224 9
        }
225
226 9
        return $buttons;
227 9
    }
228
229
    /**
230
     * Set the field value using default.
231
     *
232
     * @return void
233
     */ 
234
    public function setFromDefault()
235 13
    {
236
        if ( ! is_null($this->default)) {
237 13
            $this->setValueFromDefault();
238 13
        }
239
    }
240
241
    /**
242
     * Set the field value using request.
243
     *
244
     * @param \Helmut\Forms\Request  $request
245
     * @return void
246
     */ 
247
    public function setFromRequest($request)
248
    {
249
        $this->setValueFromRequest($request);
250
    }
251
252
    /**
253
     * Set the field values using a model.
254
     *
255
     * @param object  $model
256
     * @return void
257
     */     
258
    public function setFromModel($model)
259
    {
260
        $this->setValueFromModel($model);
261
    }
262
263
    /**
264
     * Fill a model with field value;
265
     *
266
     * @param object  $model
267
     * @return void
268
     */     
269 27
    public function fillModel($model)
270
    {
271 27
        $this->fillModelWithValue($model);
272
    }
273 27
274
    /**
275
     * Return the name.
276
     *
277
     * @return string
278
     */
279
    public function getName()
280
    {
281
        return $this->name;
282 45
    }    
283
284 45
    /**
285
     * Set the label property.
286 45
     *
287
     * @param string  $label
288
     * @return $this
289
     */
290
    public function setLabel($label)
291
    {
292
        $this->label = $label;
293
294 72
        return $this;
295
    }
296 72
297
    /**
298
     * Set required status.
299
     *
300
     * @param boolean  $status
301
     * @return $this
302
     */
303
    public function setRequired($status = true)
304 72
    {
305
        $this->required = $status;
306 72
307
        return $this;
308
    } 
309
310
    /**
311
     * Set the default value.
312
     *
313
     * @param mixed  $value
314 28
     * @return $this
315
     */
316 28
    public function setDefault($value) 
317 24
    {
318
        $this->default = $value;
319
320 28
        return $this;
321
    }
322 22
323
    /**
324 22
     * Check if valid.
325 9
     *
326
     * @return boolean
327
     */
328 22
    public function isValid() 
329 17
    {
330
        return count($this->errors) == 0;
331
    }
332
333 28
    /**
334
     * Check if invalid.
335
     *
336
     * @return boolean
337
     */
338
    public function isInvalid() 
339
    {
340 27
        return ! $this->isValid();
341
    }
342 27
343
    /**
344 27
     * Add a validation.
345 27
     *
346 27
     * @param string  $method     
347
     * @param array  $parameters     
348
     * @return void
349 20
     */
350
    protected function addValidation($method, $parameters) 
351 20
    {
352
        $this->validations[$method] = $parameters;
353
    }    
354
355
    /**
356
     * Perform all validations.
357
     *
358
     * @return void
359 45
     */
360
    public function runValidations() 
361 45
    {
362
        if ($this->required) {
363
            $this->callValidationMethod('validateRequired');
364
        }
365
366
        if ($this->isNotEmpty()) {
367
368
            if (method_exists($this, 'validate')) {
369 28
                $this->validate();
0 ignored issues
show
Bug introduced by
The method validate() does not exist on Helmut\Forms\Field. Did you maybe mean validateRequired()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
370
            }
371 28
372
            foreach ($this->validations as $validation => $parameters) {
373
                $this->callValidationMethod($validation, $parameters);
374
            }
375
        }
376
377
    }
378
379 1
    /**
380
     * Call a validation method.
381 1
     *
382
     * @return boolean
383
     */
384
    public function callValidationMethod($validation, $parameters = []) 
385
    {
386
        $method = Str::snake($validation);
387
388
        $validated = call_user_func_array([$this, $validation], $parameters);
389
390
        if ($validated) {
391
            $this->clearValidationError($method);
392
            return true;
393
        }
394
395
        $this->addValidationError($method, $parameters);
396
        return false;
397
    }    
398
399
    /**
400
     * Check if field is required.
401
     *
402 25
     * @return boolean
403
     */
404 25
    public function isRequired() 
405
    {
406 25
        return $this->required;
407
    }     
408 23
409 17
    /**
410
     * Check if field has been filled.
411
     *
412 23
     * @return boolean
413
     */
414
    public function isNotEmpty() 
415 2
    {
416
        return $this->validateRequired();
417 2
    }   
418 2
419
    /**
420
     * Return validation errors.
421
     *
422
     * @return array
423
     */
424
    public function errors() 
425
    {
426
        return $this->errors;
427 75
    }
428
429 75
    /**
430
     * Add a user defined validation error.
431
     *
432
     * @return array
433
     */
434
    public function error($message)
435
    {
436
        if ( ! isset($this->errors['userDefined'])) {
437
            $this->errors['userDefined'] = [];
438
        }
439
440
        $this->errors['userDefined'][] = $message;
441
    }
442
443
    /**
444
     * Add an internal validation error.
445
     *
446
     * @param string  $method     
447
     * @param array  $parameters     
448
     * @return void
449
     */
450
    protected function addValidationError($method, $parameters) 
451
    {
452
        $this->errors[$method] = $parameters;
453
    }
454
455 74
    /**
456
     * Remove all internal validation errors for a method.
457 74
     *
458
     * @param string  $method     
459 74
     * @return void
460
     */
461 74
    protected function clearValidationError($method) 
462 74
    {
463 74
        if (isset($this->errors[$method])) {
464
            unset($this->errors[$method]);
465
        }
466 14
    }    
467 14
468
    /**
469 14
     * Get the value of a field.
470
     *
471
     * @param  string  $key
472 14
     * @return mixed
473 14
     */
474 10
    public function value($key = null) 
475
    {
476
        $values = $this->values();
477 14
478
        if (is_null($key)) {
479 14
            
480
            if (count($values) == 0) {
481 14
                return null;
482
            }  
483
484
            if (count($values) == 1) {
485
                $values = current($values);
486
            }
487
488
            return $values;
489
        }
490
        
491
        $key = $this->name.'_'.$key;
492
493
        if (array_key_exists($key, $values)) {
494
            return $values[$key];
495
        }
496
    }
497
498
    /**
499
     * Translate a specific key.
500
     *
501
     * @param  string  $key
502
     * @return string
503
     */
504
    public function translate($key) 
505
    {
506
        return $this->form->translate($key, $this);
507
    }
508
509
    /**
510
     * Get the parent form.
511
     *
512
     * @return \Helmut\Forms\Form
513
     */
514
    public function getForm()
515
    {
516
        return $this->form;
517
    }   
518
519
    /**
520
     * Gives this class the ability to set and get any of the
521
     * properties of the instances that inherit from this class
522
     * using shorthand notation. Call label() instead of
523
     * setLabel() for example.
524
     *
525
     * Also it allows you to specify validations in the same dynamic
526
     * manner like required() or between(1, 10).
527
     *
528
     * @param string  $method
529
     * @param array  $parameters
530
     * @return mixed
531
     */
532
    public function __call($method, $parameters)
533
    {
534
        if ( ! method_exists($this, $method)) {
535
536
            $method = Str::studly($method);
537
538
            $name = 'set'.$method;
539
            if (method_exists($this, $name)) {
540
                return call_user_func_array([$this, $name], $parameters);
541
            }
542
543
            $name = 'validate'.$method;
544
            if (method_exists($this, $name)) {
545
                $arguments = Reflect::getParameters($this, $name);
546
                $parameters = array_pad($parameters, count($arguments), null);
547
                $this->addValidation($name, array_combine($arguments, $parameters));
548
                return $this;
549
            }           
550
        }
551
    }
552
553
}