|
8 | 8 |
|
9 | 9 | namespace App\Casts; |
10 | 10 |
|
| 11 | +use App\Models\Tag; |
11 | 12 | use Illuminate\Contracts\Database\Eloquent\CastsAttributes; |
12 | 13 | use Illuminate\Database\Eloquent\Model; |
13 | 14 |
|
14 | 15 | /** |
15 | | - * @implements CastsAttributes<array,(string|null)[]> |
| 16 | + * @implements CastsAttributes<array,(Tag|null)[]> |
16 | 17 | */ |
17 | | -class ArrayCast implements CastsAttributes |
| 18 | +class TagArrayCast implements CastsAttributes |
18 | 19 | { |
19 | 20 | /** |
20 | 21 | * @param Model $model the associated model class |
21 | 22 | * @param string $key the name of the SQL column holding the stringified array |
22 | 23 | * @param mixed $value the stringified array |
23 | 24 | * @param array<string,mixed> $attributes all SQL attributes of the entity |
24 | 25 | * |
25 | | - * @return array<int,string> the array |
| 26 | + * @return array<int,Tag> the array |
26 | 27 | */ |
27 | 28 | public function get(Model $model, string $key, mixed $value, array $attributes): array |
28 | 29 | { |
29 | | - return ($value === null || $value === '') ? [] : explode(',', strval($value)); |
| 30 | + if ($value === null || $value === '') { |
| 31 | + return []; |
| 32 | + } |
| 33 | + |
| 34 | + // Split the string by ' OR ' and return an array of Tag objects |
| 35 | + return Tag::whereIn('id', explode(' OR ', strval($value)))->get()->all(); |
30 | 36 | } |
31 | 37 |
|
32 | 38 | /** |
33 | | - * @param Model $model the associated model class |
34 | | - * @param string $key the name of the SQL column holding the stringified array |
35 | | - * @param (string|null)[]|null $value the array |
36 | | - * @param array<string,mixed> $attributes |
| 39 | + * @param Model $model the associated model class |
| 40 | + * @param string $key the name of the SQL column holding the stringified array |
| 41 | + * @param (Tag|null)[]|null $value the array |
| 42 | + * @param array<string,mixed> $attributes |
37 | 43 | * |
38 | 44 | * @return array<string,mixed> An associative map of SQL columns and their values |
39 | 45 | */ |
40 | 46 | public function set(Model $model, string $key, mixed $value, array $attributes): array |
41 | 47 | { |
42 | 48 | // Normalize the input value |
43 | | - // The array must not contain empty tags and tags which contain a comma |
44 | 49 | // TODO: Either use a separate table to store the tags or another encoding (e.g. JSON) which also allows commas in tags |
45 | 50 |
|
46 | 51 | $arr = !is_array($value) ? [] : array_values(array_filter( |
47 | 52 | $value, |
48 | | - fn ($elem) => ($elem !== null && $elem !== '' && !str_contains($elem, ',')), |
| 53 | + fn ($elem) => ($elem !== null && $elem !== '' && $elem instanceof Tag && $elem->name !== ''), |
49 | 54 | )); |
50 | 55 |
|
51 | 56 | return [ |
52 | | - $key => count($arr) === 0 ? null : implode(',', $arr), |
| 57 | + $key => count($arr) === 0 ? null : implode(' OR ', array_map(fn ($t) => $t->id, $arr)), |
53 | 58 | ]; |
54 | 59 | } |
55 | 60 | } |
0 commit comments