1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Rinvex\Attributes\Models; |
6
|
|
|
|
7
|
|
|
use Illuminate\Support\Str; |
8
|
|
|
use Spatie\Sluggable\SlugOptions; |
9
|
|
|
use Rinvex\Support\Traits\HasSlug; |
10
|
|
|
use Spatie\EloquentSortable\Sortable; |
11
|
|
|
use Illuminate\Database\Eloquent\Model; |
12
|
|
|
use Rinvex\Support\Traits\HasTranslations; |
13
|
|
|
use Rinvex\Support\Traits\ValidatingTrait; |
14
|
|
|
use Spatie\EloquentSortable\SortableTrait; |
15
|
|
|
use Illuminate\Database\Eloquent\Relations\HasMany; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Rinvex\Attributes\Models\Attribute. |
19
|
|
|
* |
20
|
|
|
* @property int $id |
21
|
|
|
* @property string $slug |
22
|
|
|
* @property array $name |
23
|
|
|
* @property array $description |
24
|
|
|
* @property int $sort_order |
25
|
|
|
* @property string $group |
26
|
|
|
* @property string $type |
27
|
|
|
* @property bool $is_required |
28
|
|
|
* @property bool $is_collection |
29
|
|
|
* @property string $default |
30
|
|
|
* @property \Carbon\Carbon|null $created_at |
31
|
|
|
* @property \Carbon\Carbon|null $updated_at |
32
|
|
|
* @property array $entities |
33
|
|
|
* @property-read \Rinvex\Attributes\Support\ValueCollection|\Rinvex\Attributes\Models\Value[] $values |
34
|
|
|
* |
35
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute ordered($direction = 'asc') |
36
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereCreatedAt($value) |
37
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereDefault($value) |
38
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereDescription($value) |
39
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereGroup($value) |
40
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereId($value) |
41
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereIsCollection($value) |
42
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereIsRequired($value) |
43
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereSlug($value) |
44
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereSortOrder($value) |
45
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereName($value) |
46
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereType($value) |
47
|
|
|
* @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Attributes\Models\Attribute whereUpdatedAt($value) |
48
|
|
|
* @mixin \Eloquent |
49
|
|
|
*/ |
50
|
|
|
class Attribute extends Model implements Sortable |
51
|
|
|
{ |
52
|
|
|
use HasSlug; |
53
|
|
|
use SortableTrait; |
54
|
|
|
use HasTranslations; |
55
|
|
|
use ValidatingTrait; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* {@inheritdoc} |
59
|
|
|
*/ |
60
|
|
|
protected $fillable = [ |
61
|
|
|
'name', |
62
|
|
|
'slug', |
63
|
|
|
'description', |
64
|
|
|
'sort_order', |
65
|
|
|
'group', |
66
|
|
|
'type', |
67
|
|
|
'is_required', |
68
|
|
|
'is_collection', |
69
|
|
|
'default', |
70
|
|
|
'entities', |
71
|
|
|
]; |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* {@inheritdoc} |
75
|
|
|
*/ |
76
|
|
|
protected $casts = [ |
77
|
|
|
'slug' => 'string', |
78
|
|
|
'sort_order' => 'integer', |
79
|
|
|
'group' => 'string', |
80
|
|
|
'type' => 'string', |
81
|
|
|
'is_required' => 'boolean', |
82
|
|
|
'is_collection' => 'boolean', |
83
|
|
|
'default' => 'string', |
84
|
|
|
]; |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* {@inheritdoc} |
88
|
|
|
*/ |
89
|
|
|
protected $observables = [ |
90
|
|
|
'validating', |
91
|
|
|
'validated', |
92
|
|
|
]; |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* {@inheritdoc} |
96
|
|
|
*/ |
97
|
|
|
public $translatable = [ |
98
|
|
|
'name', |
99
|
|
|
'description', |
100
|
|
|
]; |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* {@inheritdoc} |
104
|
|
|
*/ |
105
|
|
|
public $sortable = [ |
106
|
|
|
'order_column_name' => 'sort_order', |
107
|
|
|
]; |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* The default rules that the model will validate against. |
111
|
|
|
* |
112
|
|
|
* @var array |
113
|
|
|
*/ |
114
|
|
|
protected $rules = []; |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Whether the model should throw a |
118
|
|
|
* ValidationException if it fails validation. |
119
|
|
|
* |
120
|
|
|
* @var bool |
121
|
|
|
*/ |
122
|
|
|
protected $throwValidationExceptions = true; |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* An array to map class names to their type names in database. |
126
|
|
|
* |
127
|
|
|
* @var array |
128
|
|
|
*/ |
129
|
|
|
protected static $typeMap = []; |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Create a new Eloquent model instance. |
133
|
|
|
* |
134
|
|
|
* @param array $attributes |
135
|
|
|
*/ |
136
|
|
|
public function __construct(array $attributes = []) |
137
|
|
|
{ |
138
|
|
|
parent::__construct($attributes); |
139
|
|
|
|
140
|
|
|
$this->setTable(config('rinvex.attributes.tables.attributes')); |
141
|
|
|
$this->setRules([ |
142
|
|
|
'name' => 'required|string|strip_tags|max:150', |
143
|
|
|
'description' => 'nullable|string|max:32768', |
144
|
|
|
'slug' => 'required|alpha_dash|max:150|unique:'.config('rinvex.attributes.tables.attributes').',slug', |
145
|
|
|
'sort_order' => 'nullable|integer|max:100000', |
146
|
|
|
'group' => 'nullable|string|strip_tags|max:150', |
147
|
|
|
'type' => 'required|string|strip_tags|max:150', |
148
|
|
|
'is_required' => 'sometimes|boolean', |
149
|
|
|
'is_collection' => 'sometimes|boolean', |
150
|
|
|
'default' => 'nullable|string|strip_tags|max:32768', |
151
|
|
|
]); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Enforce clean slugs. |
156
|
|
|
* |
157
|
|
|
* @param string $value |
158
|
|
|
* |
159
|
|
|
* @return void |
160
|
|
|
*/ |
161
|
|
|
public function setSlugAttribute($value): void |
162
|
|
|
{ |
163
|
|
|
$this->attributes['slug'] = Str::slug($value, $this->getSlugOptions()->slugSeparator, $this->getSlugOptions()->slugLanguage); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Set or get the type map for attribute types. |
168
|
|
|
* |
169
|
|
|
* @param array|null $map |
170
|
|
|
* @param bool $merge |
171
|
|
|
* |
172
|
|
|
* @return array |
173
|
|
|
*/ |
174
|
|
|
public static function typeMap(array $map = null, $merge = true) |
175
|
|
|
{ |
176
|
|
|
if (is_array($map)) { |
177
|
|
|
static::$typeMap = $merge && static::$typeMap |
|
|
|
|
178
|
|
|
? $map + static::$typeMap : $map; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
return static::$typeMap; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* Get the model associated with a custom attribute type. |
186
|
|
|
* |
187
|
|
|
* @param string $alias |
188
|
|
|
* |
189
|
|
|
* @return string|null |
190
|
|
|
*/ |
191
|
|
|
public static function getTypeModel($alias) |
192
|
|
|
{ |
193
|
|
|
return self::$typeMap[$alias] ?? null; |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* Access entities relation and retrieve entity types as an array, |
198
|
|
|
* Accessors/Mutators preceeds relation value when called dynamically. |
199
|
|
|
* |
200
|
|
|
* @return array |
201
|
|
|
*/ |
202
|
|
|
public function getEntitiesAttribute(): array |
203
|
|
|
{ |
204
|
|
|
return $this->entities()->pluck('entity_type')->toArray(); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* Set the attribute attached entities. |
209
|
|
|
* |
210
|
|
|
* @param \Illuminate\Support\Collection|array $value |
|
|
|
|
211
|
|
|
* @param mixed $entities |
212
|
|
|
* |
213
|
|
|
* @return void |
214
|
|
|
*/ |
215
|
|
|
public function setEntitiesAttribute($entities): void |
216
|
|
|
{ |
217
|
|
|
static::saved(function ($model) use ($entities) { |
|
|
|
|
218
|
|
|
$this->entities()->delete(); |
219
|
|
|
! $entities || $this->entities()->createMany(array_map(function ($entity) { |
|
|
|
|
220
|
|
|
return ['entity_type' => $entity]; |
221
|
|
|
}, $entities)); |
222
|
|
|
}); |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Get the options for generating the slug. |
227
|
|
|
* |
228
|
|
|
* @return \Spatie\Sluggable\SlugOptions |
229
|
|
|
*/ |
230
|
|
|
public function getSlugOptions(): SlugOptions |
231
|
|
|
{ |
232
|
|
|
return SlugOptions::create() |
233
|
|
|
->usingSeparator('_') |
234
|
|
|
->doNotGenerateSlugsOnUpdate() |
235
|
|
|
->generateSlugsFrom('name') |
236
|
|
|
->saveSlugsTo('slug'); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Get the entities attached to this attribute. |
241
|
|
|
* |
242
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany |
243
|
|
|
*/ |
244
|
|
|
public function entities(): HasMany |
245
|
|
|
{ |
246
|
|
|
return $this->hasMany(config('rinvex.attributes.models.attribute_entity'), 'attribute_id', 'id'); |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* Get the entities attached to this attribute. |
251
|
|
|
* |
252
|
|
|
* @param string $value |
253
|
|
|
* |
254
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany |
255
|
|
|
*/ |
256
|
|
|
public function values(string $value): HasMany |
257
|
|
|
{ |
258
|
|
|
return $this->hasMany($value, 'attribute_id', 'id'); |
259
|
|
|
} |
260
|
|
|
} |
261
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.