From ef3c871570c24e30e721b4b7d76a389adc9c7e20 Mon Sep 17 00:00:00 2001 From: digitalSloth <104867337+digitalSloth@users.noreply.github.com> Date: Mon, 21 Aug 2023 15:54:25 +0100 Subject: [PATCH] ADD allow saving additional fields via add method (#48) --- README.md | 20 ++++++++++++++++++++ src/Mark.php | 22 ++++++++++++++++------ tests/MarkTest.php | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 97c29ec..96b2849 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,26 @@ Like::has($course, $user); // returns whether the given user has marked as liked Like::count($course); // returns the amount of like marks for the given course ``` +### Custom metadata + +If needed, you may also add custom metadata when assigning a mark: + +``` php +use App\Models\Course; +use Maize\Markable\Models\Like; + +$course = Course::firstOrFail(); +$user = auth()->user(); + +Like::add($course, $user, [ + 'topic' => $course->topic, +]); + +Like::toggle($course, $user, [ + 'topic' => $course->topic, +]); +``` + ### Custom mark model The package allows you to define custom marks. diff --git a/src/Mark.php b/src/Mark.php index e055ace..02440bd 100644 --- a/src/Mark.php +++ b/src/Mark.php @@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Relations\MorphPivot; use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Support\Arr; +use Illuminate\Support\Collection; use Illuminate\Support\Str; use Maize\Markable\Exceptions\InvalidMarkableInstanceException; use Maize\Markable\Exceptions\InvalidMarkValueException; @@ -15,6 +16,10 @@ abstract class Mark extends MorphPivot { public $incrementing = true; + protected $casts = [ + 'metadata' => 'array', + ]; + abstract public static function markableRelationName(): string; public static function markRelationName(): string @@ -37,7 +42,7 @@ public static function getMarkClassName(): string ->__toString(); } - public static function add(Model $markable, Model $user, string $value = null): self + public static function add(Model $markable, Model $user, string $value = null, array $metadata = []): self { static::validMarkable($markable); @@ -51,9 +56,14 @@ public static function add(Model $markable, Model $user, string $value = null): 'markable_type' => $markable->getMorphClass(), 'value' => $value, ]; - $values = static::forceSingleValuePerUser() - ? [Arr::pull($attributes, 'value')] - : []; + + $values = collect([ + 'metadata' => $metadata, + ])->when( + value: static::forceSingleValuePerUser(), + callback: fn (Collection $values) => $values + ->add(Arr::pull($attributes, 'value')) + )->toArray(); return static::firstOrCreate($attributes, $values); } @@ -91,11 +101,11 @@ public static function has(Model $markable, Model $user, string $value = null): ])->exists(); } - public static function toggle(Model $markable, Model $user, string $value = null) + public static function toggle(Model $markable, Model $user, string $value = null, array $metadata = []) { return static::has($markable, $user, $value) ? static::remove($markable, $user, $value) - : static::add($markable, $user, $value); + : static::add($markable, $user, $value, $metadata); } public static function hasAllowedValues(?string $value): bool diff --git a/tests/MarkTest.php b/tests/MarkTest.php index d165f84..4deee35 100644 --- a/tests/MarkTest.php +++ b/tests/MarkTest.php @@ -4,6 +4,7 @@ use Maize\Markable\Exceptions\InvalidMarkableInstanceException; use Maize\Markable\Models\Bookmark; +use Maize\Markable\Models\Favorite; use Maize\Markable\Models\Like; use Maize\Markable\Tests\Models\Article; use Maize\Markable\Tests\Models\Post; @@ -27,6 +28,37 @@ public function can_add_a_mark() ]); } + /** @test */ + public function can_add_metadata() + { + $article = Article::factory()->create(); + $user = User::factory()->create(); + + Favorite::add($article, $user, null, [ + 'test_data' => true, + ]); + + $this->assertDatabaseHas((new Favorite)->getTable(), [ + 'user_id' => $user->getKey(), + 'markable_id' => $article->getKey(), + 'markable_type' => $article->getMorphClass(), + 'value' => null, + 'metadata' => json_encode(['test_data' => true]), + ]); + + Like::toggle($article, $user, null, [ + 'test_data' => true, + ]); + + $this->assertDatabaseHas((new Like)->getTable(), [ + 'user_id' => $user->getKey(), + 'markable_id' => $article->getKey(), + 'markable_type' => $article->getMorphClass(), + 'value' => null, + 'metadata' => json_encode(['test_data' => true]), + ]); + } + /** @test */ public function cannot_remove_with_an_invalid_markable_type_fail() {