Skip to content

Commit

Permalink
Merge pull request #3 from cslant/update-like-model
Browse files Browse the repository at this point in the history
 Interaction of Like
  • Loading branch information
tanhongit authored Sep 27, 2024
2 parents 13c4b66 + e938f86 commit f711068
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 41 deletions.
29 changes: 23 additions & 6 deletions config/like.php
Original file line number Diff line number Diff line change
@@ -1,21 +1,38 @@
<?php

return [
'name' => 'Like',
'name' => 'The interactions configuration',

/*
* The flag to determine if the likes table should use UUIDs.
* If you want to use UUIDs instead of auto-incrementing integers for your likes table, set this to true.
* The flag to determine if the interactions table should use UUIDs.
* If you want to use UUIDs instead of auto-incrementing integers for your interactions table, set this to true.
*/
'is_uuids' => false,

/*
* The table name for likes records.
* The table name for interaction records.
*/
'table_name' => 'likes',

/*
* User tables foreign key name.
* The model class for the interaction table.
*/
'user_foreign_key' => 'user_id',
'interaction_model' => 'CSlant\LaravelLike\Models\Like',

/*
* The model and foreign key for the user relationship.
*/
'users' => [
/*
* User model class.
* Use this to set the user model class for the user relationship.
*/
'model' => 'App\Models\User',

/*
* User tables foreign key name.
* Use this to set the foreign key name for the user relationship.
*/
'foreign_key' => 'user_id',
],
];
4 changes: 2 additions & 2 deletions migrations/2024_09_23_163615_create_likes_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ public function up(): void
$table->uuid()->index();
}

$table->unsignedBigInteger(config('like.user_foreign_key'))->index();
$table->unsignedBigInteger(config('like.users.foreign_key'))->index();
$table->morphs('model');
$table->string('type')->default('like');

$table->unique(['user_id', 'model_id', 'model_type', 'type'], 'unique_user_model_type_interaction');
$table->unique([config('like.users.foreign_key'), 'model_id', 'model_type', 'type'], 'unique_user_model_type_interaction');

$table->timestamps();
});
Expand Down
7 changes: 6 additions & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
parameters:
excludePaths:
ignoreErrors:
- message: '#Cannot cast mixed to string#'
path: src/*

- message: '#Method CSlant\\LaravelLike\\Models\\Like::user\(\) return type with generic class Illuminate\\Database\\Eloquent\\Relations\\BelongsTo does not specify its types: TRelatedModel, TChildModel#'
path: src/Models/Like.php
58 changes: 56 additions & 2 deletions src/Models/Like.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use CSlant\LaravelLike\Enums\InteractionTypeEnum;
use CSlant\LaravelLike\Traits\InteractionRelationship;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Carbon;

Expand All @@ -19,6 +20,10 @@
* @property InteractionTypeEnum $type
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Model $user
* @property Model $model
*
* @property-read string $interaction_type getInteractionTypeAttribute()
*/
class Like extends Model
{
Expand All @@ -44,6 +49,29 @@ class Like extends Model
'type' => InteractionTypeEnum::class,
];

/**
* Get the user that owns the like.
*
* @return BelongsTo
*/
public function user(): BelongsTo
{
$userModel = (string) (config('like.users.model') ?? config('auth.providers.users.model'));
$userForeignKey = (string) (config('like.users.foreign_key') ?? 'user_id');

return $this->belongsTo($userModel, $userForeignKey);
}

/**
* Get the model that the like belongs to.
*
* @return BelongsTo<Model, self>
*/
public function model(): BelongsTo
{
return $this->morphTo();
}

/**
* Check if the record is liked.
*
Expand Down Expand Up @@ -87,13 +115,39 @@ public function isLove(): bool
* Scope a query to only include records of a given model type.
*
* @param Builder $query
* @param string $modelType
* @param string $modelType The model type. E.g. App\Models\Post::class
*
* @return Builder
*/
public function scopeWithModelType(Builder $query, string $modelType): Builder
{
// Use with likes() relationship. Can't use with likeOne() relationship.
return $query->where('model_type', app($modelType)->getMorphClass());
return $query->where('model_type', $modelType);
}

/**
* Get the interaction type attribute. Used for the accessor.
*
* @return string
*/
public function getInteractionTypeAttribute(): string
{
return $this->type->value;
}

/**
* Toggle the like interaction.
*
* @return string
*/
public function toggleLikeInteraction(): string
{
if ($this->isLiked()) {
$this->type = InteractionTypeEnum::DISLIKE;
} else {
$this->type = InteractionTypeEnum::LIKE;
}

return $this->type->value;
}
}
18 changes: 4 additions & 14 deletions src/Traits/InteractionRelationship.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,22 @@
trait InteractionRelationship
{
/**
* Like has one relationship with the model.
* Interaction has one relationship with the model.
*
* @return MorphOne
*/
public function likeOne(): MorphOne
{
return $this->morphOne(Like::class, 'model');
return $this->morphOne((string) config('like.interaction_model') ?? Like::class, 'model');
}

/**
* Like has many relationship with the model.
* Interaction has many relationship with the model.
*
* @return MorphMany
*/
public function likes(): MorphMany
{
return $this->morphMany(Like::class, 'model');
}

/**
* Get the interaction type.
*
* @return string
*/
public function interactionType(): string
{
return $this->type->value;
return $this->morphMany((string) config('like.interaction_model') ?? Like::class, 'model');
}
}
16 changes: 0 additions & 16 deletions src/Traits/Like/LikeScopes.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,4 @@ public function dislikesTo(): MorphMany
{
return $this->likes()->where('type', InteractionTypeEnum::DISLIKE);
}

/**
* Implement change like interaction. (like/dislike)
*
* @return string
*/
public function toggleLikeInteraction(): string
{
if ($this->likeOne->isLiked()) {
$this->likeOne->type = InteractionTypeEnum::DISLIKE;
} else {
$this->likeOne->type = InteractionTypeEnum::LIKE;
}

return $this->likeOne->type->value;
}
}

0 comments on commit f711068

Please sign in to comment.