Completed
Push — master ( 194c1c...04f3fb )
by Helmut
02:53
created

Field::setId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
ccs 1
cts 1
cp 1
rs 9.4285
nc 1
cc 1
eloc 3
nop 0
crap 1
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 validates.
147
     *
148
     * @return boolean
149
     */    
150
    abstract public function validate();
151 118
152
    /**
153 118
     * Return if field validates required.
154 118
     *
155 118
     * @return boolean
156
     */    
157
    abstract public function validateRequired();
158
159
    /**
160
     * Set a unique id.
161
     *
162 46
     * @return void
163
     */
164 46
    public function setId()
165
    {
166
        $id = $this->type.'_'.substr(md5($this->name), 0, 5);
167
        $this->id = $this->form->id.'_'.$id;
168
    }
169
170
    /**
171
     * Return an array of keys.
172 72
     *
173
     * @return array
174 72
     */
175
    public function keys()
176
    {
177
        return array_keys($this->values());
178
    }
179
180
    /**
181
     * Return an array of values.
182 45
     *
183
     * @return array
184 45
     */
185
    public function values() 
186
    {
187
        $values = $this->getValue();
188
189
        if (is_null($values)) $values = [];
190
191
        else if ( ! is_array($values)) $values = [$this->name => $values];
192 118
193
        return $values;
194 118
    }
195
196
    /**
197
     * Return an array of properties to be passed
198
     * to the template during rendering.
199
     *
200
     * @return array
201
     */    
202 111
    public function properties() 
203
    {
204 111
        $properties = $this->renderWith();
205 111
206
        if (is_null($properties)) $properties = [];
207
208
        return $properties;
209
    }
210
211
    /**
212
     * Return an array of button keys.
213 7
     *
214
     * @return array
215 7
     */    
216 7
    public function buttons()
217
    {
218
        $buttons = $this->getButtonName();
219
220
        if (is_null($buttons)) $buttons = [];
221
222
        else if ( ! is_array($buttons)) $buttons = [$buttons];
223
224 9
        return $buttons;
225
    }
226 9
227 9
    /**
228
     * Set the field value using default.
229
     *
230
     * @return void
231
     */ 
232
    public function setFromDefault()
233
    {
234
        if ( ! is_null($this->default)) $this->setValueFromDefault();
235 13
    }
236
237 13
    /**
238 13
     * Set the field value using request.
239
     *
240
     * @param \Helmut\Forms\Request  $request
241
     * @return void
242
     */ 
243
    public function setFromRequest($request)
244
    {
245
        $this->setValueFromRequest($request);
246
    }
247
248
    /**
249
     * Set the field values using a model.
250
     *
251
     * @param object  $model
252
     * @return void
253
     */     
254
    public function setFromModel($model)
255
    {
256
        $this->setValueFromModel($model);
257
    }
258
259
    /**
260
     * Fill a model with field value;
261
     *
262
     * @param object  $model
263
     * @return void
264
     */     
265
    public function fillModel($model)
266
    {
267
        $this->fillModelWithValue($model);
268
    }
269 27
270
    /**
271 27
     * Return the name.
272
     *
273 27
     * @return string
274
     */
275
    public function getName()
276
    {
277
        return $this->name;
278
    }    
279
280
    /**
281
     * Set the label property.
282 45
     *
283
     * @param string  $label
284 45
     * @return $this
285
     */
286 45
    public function setLabel($label)
287
    {
288
        $this->label = $label;
289
290
        return $this;
291
    }
292
293
    /**
294 72
     * Set required status.
295
     *
296 72
     * @param boolean  $status
297
     * @return $this
298
     */
299
    public function setRequired($status = true)
300
    {
301
        $this->required = $status;
302
303
        return $this;
304 72
    } 
305
306 72
    /**
307
     * Set the default value.
308
     *
309
     * @param mixed  $value
310
     * @return $this
311
     */
312
    public function setDefault($value) 
313
    {
314 28
        $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...
315
316 28
        return $this;
317 24
    }
318
319
    /**
320 28
     * Check if valid.
321
     *
322 22
     * @return boolean
323
     */
324 22
    public function isValid() 
325 9
    {
326
        return count($this->errors) == 0;
327
    }
328 22
329 17
    /**
330
     * Check if invalid.
331
     *
332
     * @return boolean
333 28
     */
334
    public function isInvalid() 
335
    {
336
        return ! $this->isValid();
337
    }
338
339
    /**
340 27
     * Perform all validations.
341
     *
342 27
     * @return void
343
     */
344 27
    public function runValidations() 
345 27
    {
346 27
        if ($this->required) {
347
            $this->callValidationMethod('validateRequired');
348
        }
349 20
350
        if ($this->isNotEmpty()) {
351 20
352
            $validations = $this->validations;          
353
354
            if (method_exists($this, 'validate')) {
355
                $validations = array_merge(['validate' => []], $validations);
356
            }
357
358
            foreach ($validations as $validation => $parameters) {
359 45
                $this->callValidationMethod($validation, $parameters);
360
            }
361 45
        }
362
363
    }
364
365
    /**
366
     * Call a validation method.
367
     *
368
     * @return boolean
369 28
     */
370
    public function callValidationMethod($validation, $parameters = []) 
371 28
    {
372
        $method = Str::snake($validation);
373
374
        $validated = call_user_func_array([$this, $validation], $parameters);
375
376
        if ($validated) {
377
            $this->clearValidationError($method);
378
            return true;
379 1
        }
380
381 1
        $this->addValidationError($method, $parameters);
382
        return false;
383
    }    
384
385
    /**
386
     * Check if field is required.
387
     *
388
     * @return boolean
389
     */
390
    public function isRequired() 
391
    {
392
        return $this->required;
393
    }     
394
395
    /**
396
     * Check if field has been filled.
397
     *
398
     * @return boolean
399
     */
400
    public function isNotEmpty() 
401
    {
402 25
        return $this->validateRequired();
403
    }   
404 25
405
    /**
406 25
     * Return validation errors.
407
     *
408 23
     * @return array
409 17
     */
410
    public function errors() 
411
    {
412 23
        return $this->errors;
413
    }
414
415 2
    /**
416
     * Add a user defined validation error.
417 2
     *
418 2
     * @return array
419
     */
420
    public function error($message)
421
    {
422
        if ( ! isset($this->errors['userDefined'])) $this->errors['userDefined'] = [];
423
424
        $this->errors['userDefined'][] = $message;
425
    }
426
427 75
    /**
428
     * Add an internal validation error.
429 75
     *
430
     * @param string  $method     
431
     * @param array  $parameters     
432
     * @return void
433
     */
434
    protected function addValidationError($method, $parameters) 
435
    {
436
        $this->errors[$method] = $parameters;
437
    }
438
439
    /**
440
     * Remove all internal validation error for method.
441
     *
442
     * @param string  $method     
443
     * @return void
444
     */
445
    protected function clearValidationError($method) 
446
    {
447
        if (isset($this->errors[$method])) unset($this->errors[$method]);
448
    }    
449
450
    /**
451
     * Get the value of a field.
452
     *
453
     * @param  string  $key
454
     * @return mixed
455 74
     */
456
    public function value($key = null) 
457 74
    {
458
        $values = $this->values();
459 74
460
        if (is_null($key)) {
461 74
            
462 74
            if (count($values) == 1) {
463 74
                $values = current($values);
464
            }
465
466 14
            return $values;
467 14
        }
468
        
469 14
        $key = $this->name.'_'.$key;
470
471
        if (array_key_exists($key, $values)) {
472 14
            return $values[$key];
473 14
        }
474 10
    }
475
476
    /**
477 14
     * Translate a specific key.
478
     *
479 14
     * @param  string  $key
480
     * @return string
481 14
     */
482
    public function translate($key) 
483
    {
484
        return $this->form->translate($key, $this);
485
    }
486
487
    /**
488
     * Get the parent form.
489
     *
490
     * @return \Helmut\Forms\Form
491
     */
492
    public function getForm()
493
    {
494
        return $this->form;
495
    }   
496
497
    /**
498
     * Gives this class the ability to set and get any of the
499
     * properties of the instances that inherit from this class
500
     * using shorthand notation. Call label() instead of
501
     * setLabel() for example.
502
     *
503
     * Also it allows you to specify validations in the same dynamic
504
     * manner like required() or between(1, 10).
505
     *
506
     * @param string  $method
507
     * @param array  $parameters
508
     * @return mixed
509
     */
510
    public function __call($method, $parameters)
511
    {
512
        if ( ! method_exists($this, $method)) {
513
514
            $method = Str::studly($method);
515
516
            $name = 'set'.$method;
517
            if (method_exists($this, $name)) {
518
                return call_user_func_array([$this, $name], $parameters);
519
            }
520
521
            $name = 'validate'.$method;
522
            if (method_exists($this, $name)) {
523
524
                $arguments = Reflect::getParameters($this, $name);
525
                $parameters = array_pad($parameters, count($arguments), null);
526
                $this->validations[$name] = array_combine($arguments, $parameters);
527
528
                return $this;
529
            }           
530
        }
531
    }
532
533
}