Skip to content

Commit 5fd65e9

Browse files
authored
Merge pull request #26 from givebutter/develop
Develop
2 parents db4fc06 + 17d680d commit 5fd65e9

9 files changed

+254
-63
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
/vendor/
22
.phpunit.result.cache
3-
composer.lock
3+
composer.lock
4+
/.idea
5+
.DS_Store

src/Exceptions/FieldDoesNotBelongToModelException.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
class FieldDoesNotBelongToModelException extends Exception
88
{
9+
/**
10+
* FieldDoesNotBelongToModelException constructor.
11+
*
12+
* @param $field
13+
* @param $model
14+
*/
915
public function __construct($field, $model)
1016
{
1117
$class = get_class($model);

src/Exceptions/WrongNumberOfFieldsForOrderingException.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
class WrongNumberOfFieldsForOrderingException extends Exception
88
{
9+
/**
10+
* WrongNumberOfFieldsForOrderingException constructor.
11+
*
12+
* @param $given
13+
* @param $expected
14+
*/
915
public function __construct($given, $expected)
1016
{
1117
parent::__construct("Wrong number of fields passed for ordering. {$given} given, {$expected} expected.");

src/Interfaces/CustomFieldable.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Givebutter\LaravelCustomFields\Interfaces;
4+
5+
interface CustomFieldable
6+
{
7+
/**
8+
* Get the custom fields belonging to this model.
9+
*
10+
* @return mixed
11+
*/
12+
public function customFields();
13+
}

src/LaravelCustomFieldsServiceProvider.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
class LaravelCustomFieldsServiceProvider extends ServiceProvider
88
{
9+
/**
10+
* Bootstrap any application services.
11+
*
12+
* @return void
13+
*/
914
public function boot()
1015
{
1116
$this->publishes([

src/Models/CustomField.php

Lines changed: 107 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,42 +9,139 @@
99

1010
class CustomField extends Model
1111
{
12+
use SoftDeletes, HasFactory;
13+
14+
/**
15+
* @var string
16+
*/
1217
const TYPE_CHECKBOX = 'checkbox';
18+
19+
/**
20+
* @var string
21+
*/
1322
const TYPE_NUMBER = 'number';
23+
24+
/**
25+
* @var string
26+
*/
1427
const TYPE_RADIO = 'radio';
28+
29+
/**
30+
* @var string
31+
*/
1532
const TYPE_SELECT = 'select';
33+
34+
/**
35+
* @var string
36+
*/
1637
const TYPE_TEXT = 'text';
38+
39+
/**
40+
* @var string
41+
*/
1742
const TYPE_TEXTAREA = 'textarea';
1843

19-
use SoftDeletes, HasFactory;
20-
44+
/**
45+
* The attributes that aren't mass assignable.
46+
*
47+
* @var string[]|bool
48+
*/
2149
protected $guarded = ['id'];
2250

51+
/**
52+
* The attributes that are mass assignable.
53+
*
54+
* @var string[]
55+
*/
2356
protected $fillable = [
24-
'type',
25-
'title',
26-
'description',
27-
'answers',
28-
'required',
29-
'default_value',
57+
'type',
58+
'title',
59+
'description',
60+
'answers',
61+
'required',
62+
'default_value',
3063
'order',
3164
];
3265

66+
/**
67+
* The attributes that should be cast.
68+
*
69+
* @var array
70+
*/
3371
protected $casts = [
3472
'answers' => 'array',
3573
];
3674

75+
/**
76+
* CustomField constructor.
77+
*
78+
* @param array $attributes
79+
*/
3780
public function __construct(array $attributes = [])
3881
{
3982
parent::__construct($attributes);
4083

4184
$this->table = config('custom-fields.tables.fields', 'custom_fields');
4285
}
4386

44-
private function fieldValidationRules($required)
87+
/**
88+
* Bootstrap the model and its traits.
89+
*
90+
* @return void
91+
*/
92+
protected static function boot()
93+
{
94+
parent::boot();
95+
96+
self::creating(function ($field) {
97+
$lastFieldOnCurrentModel = $field->model->customFields()->orderBy('order', 'desc')->first();
98+
$field->order = ($lastFieldOnCurrentModel ? $lastFieldOnCurrentModel->order : 0) + 1;
99+
});
100+
}
101+
102+
/**
103+
* Get the morphable model.
104+
*
105+
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
106+
*/
107+
public function model()
108+
{
109+
return $this->morphTo();
110+
}
111+
112+
/**
113+
* Get the responses belonging to the model.
114+
*
115+
* @return \Illuminate\Database\Eloquent\Relations\HasMany
116+
*/
117+
public function responses()
118+
{
119+
return $this->hasMany(CustomFieldResponse::class, 'field_id');
120+
}
121+
122+
/**
123+
* Get the validation rules attribute.
124+
*
125+
* @return mixed
126+
*/
127+
public function getValidationRulesAttribute()
128+
{
129+
$typeRules = $this->getFieldValidationRules($this->required)[$this->type];
130+
array_unshift($typeRules, $this->required ? 'required' : 'nullable');
131+
132+
return $typeRules;
133+
}
134+
135+
/**
136+
* Get the field validation rules.
137+
*
138+
* @param $required
139+
* @return array
140+
*/
141+
protected function getFieldValidationRules($required)
45142
{
46143
return [
47-
self::TYPE_CHECKBOX => $required ? ['accepted','in:0,1'] : ['in:0,1'],
144+
self::TYPE_CHECKBOX => $required ? ['accepted', 'in:0,1'] : ['in:0,1'],
48145
self::TYPE_NUMBER => [
49146
'integer',
50147
],
@@ -67,31 +164,4 @@ private function fieldValidationRules($required)
67164
],
68165
];
69166
}
70-
71-
public function model()
72-
{
73-
return $this->morphTo();
74-
}
75-
76-
public function responses()
77-
{
78-
return $this->hasMany(CustomFieldResponse::class, 'field_id');
79-
}
80-
81-
public function getValidationRulesAttribute()
82-
{
83-
$typeRules = $this->fieldValidationRules($this->required)[$this->type];
84-
array_unshift($typeRules, $this->required ? 'required' : 'nullable');
85-
86-
return $typeRules;
87-
}
88-
89-
public static function boot()
90-
{
91-
parent::boot();
92-
self::creating(function ($field) {
93-
$lastFieldOnCurrentModel = $field->model->customFields()->orderBy('order', 'desc')->first();
94-
$field->order = ($lastFieldOnCurrentModel ? $lastFieldOnCurrentModel->order : 0) + 1;
95-
});
96-
}
97167
}

src/Models/CustomFieldResponse.php

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,39 @@
66

77
class CustomFieldResponse extends Model
88
{
9+
/**
10+
* The attributes that aren't mass assignable.
11+
*
12+
* @var string[]|bool
13+
*/
914
protected $guarded = ['id'];
10-
15+
16+
/**
17+
* The attributes that are mass assignable.
18+
*
19+
* @var string[]
20+
*/
1121
protected $fillable = [
1222
'value',
1323
];
1424

25+
/**
26+
* @var string[]
27+
*/
1528
const VALUE_FIELDS = [
16-
CustomField::TYPE_NUMBER => 'value_int',
29+
CustomField::TYPE_NUMBER => 'value_int',
1730
CustomField::TYPE_CHECKBOX => 'value_int',
18-
CustomField::TYPE_RADIO => 'value_str',
19-
CustomField::TYPE_SELECT => 'value_str',
20-
CustomField::TYPE_TEXT => 'value_str',
31+
CustomField::TYPE_RADIO => 'value_str',
32+
CustomField::TYPE_SELECT => 'value_str',
33+
CustomField::TYPE_TEXT => 'value_str',
2134
CustomField::TYPE_TEXTAREA => 'value_text',
2235
];
2336

37+
/**
38+
* CustomFieldResponse constructor.
39+
*
40+
* @param array $attributes
41+
*/
2442
public function __construct(array $attributes = [])
2543
{
2644
// We have to do this because the `value` mutator depends on
@@ -36,16 +54,33 @@ public function __construct(array $attributes = [])
3654
$this->table = config('custom-fields.tables.field-responses', 'custom_field_responses');
3755
}
3856

57+
/**
58+
* Get the morphable model.
59+
*
60+
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
61+
*/
3962
public function model()
4063
{
4164
return $this->morphTo();
4265
}
4366

67+
/**
68+
* Get the field belonging to the model.
69+
*
70+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
71+
*/
4472
public function field()
4573
{
4674
return $this->belongsTo(CustomField::class, 'field_id');
4775
}
4876

77+
/**
78+
* Add a scope to return models that match the given value.
79+
*
80+
* @param $query
81+
* @param $value
82+
* @return mixed
83+
*/
4984
public function scopeHasValue($query, $value)
5085
{
5186
return $query
@@ -54,18 +89,33 @@ public function scopeHasValue($query, $value)
5489
->orWhere('value_text', $value);
5590
}
5691

57-
private function valueField()
92+
/**
93+
* @param $value
94+
* @return bool|mixed
95+
*/
96+
public function formatValue($value)
5897
{
59-
return self::VALUE_FIELDS[$this->field->type];
98+
// checkboxes send a default value of `on` so we need to booleanize it.
99+
if ($this->field->type === 'checkbox') {
100+
$value = ! ! $value;
101+
}
102+
103+
return $value;
60104
}
61105

106+
/**
107+
* @return bool|mixed
108+
*/
62109
public function getValueAttribute()
63110
{
64111
return $this->formatValue(
65112
$this->attributes[$this->valueField()]
66113
);
67114
}
68115

116+
/**
117+
* @return mixed|string
118+
*/
69119
public function getValueFriendlyAttribute()
70120
{
71121
if ($this->field->type === 'checkbox') {
@@ -75,16 +125,9 @@ public function getValueFriendlyAttribute()
75125
return $this->value;
76126
}
77127

78-
public function formatValue($value)
79-
{
80-
// checkboxes send a default value of `on` so we need to booleanize it.
81-
if ($this->field->type === 'checkbox') {
82-
$value = !!$value;
83-
}
84-
85-
return $value;
86-
}
87-
128+
/**
129+
* @param $value
130+
*/
88131
public function setValueAttribute($value)
89132
{
90133
$this->attributes['value_int'] = null;
@@ -94,4 +137,12 @@ public function setValueAttribute($value)
94137

95138
$this->attributes[$this->valueField()] = $this->formatValue($value);
96139
}
140+
141+
/**
142+
* @return string
143+
*/
144+
protected function valueField()
145+
{
146+
return self::VALUE_FIELDS[$this->field->type];
147+
}
97148
}

0 commit comments

Comments
 (0)