Add all files
This commit is contained in:
0
extensions/Others/SocialBase/Traits/HasMessages.php
Normal file
0
extensions/Others/SocialBase/Traits/HasMessages.php
Normal file
181
extensions/Others/SocialBase/Traits/HasReactions.php
Normal file
181
extensions/Others/SocialBase/Traits/HasReactions.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
namespace Paymenter\Extensions\Others\SocialBase\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Paymenter\Extensions\Others\SocialBase\Models\Reaction;
|
||||
use App\Models\User;
|
||||
|
||||
trait HasReactions
|
||||
{
|
||||
/**
|
||||
* Get all reactions for this model
|
||||
*/
|
||||
public function reactions(): MorphMany
|
||||
{
|
||||
return $this->morphMany(Reaction::class, 'reactable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reaction counts grouped by type
|
||||
*/
|
||||
public function getReactionCountsAttribute(): array
|
||||
{
|
||||
return $this->reactions
|
||||
->groupBy('type')
|
||||
->map(function ($reactions) {
|
||||
return $reactions->count();
|
||||
})
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total reaction count
|
||||
*/
|
||||
public function getTotalReactionsAttribute(): int
|
||||
{
|
||||
return $this->reactions->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user has reacted to this model
|
||||
*/
|
||||
public function hasReactionFromUser(?User $user = null, ?string $type = null): bool
|
||||
{
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->reactions()->where('user_id', $user->id);
|
||||
|
||||
if ($type) {
|
||||
$query->where('type', $type);
|
||||
}
|
||||
|
||||
return $query->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's reaction to this model
|
||||
*/
|
||||
public function getUserReaction(?User $user = null): ?Reaction
|
||||
{
|
||||
if (!$user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->reactions()->where('user_id', $user->id)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or update a reaction from a user
|
||||
*/
|
||||
public function addReaction(User $user, string $type): Reaction
|
||||
{
|
||||
return $this->reactions()->updateOrCreate(
|
||||
['user_id' => $user->id],
|
||||
['type' => $type]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a reaction from a user
|
||||
*/
|
||||
public function removeReaction(User $user, ?string $type = null): bool
|
||||
{
|
||||
$query = $this->reactions()->where('user_id', $user->id);
|
||||
|
||||
if ($type) {
|
||||
$query->where('type', $type);
|
||||
}
|
||||
|
||||
return $query->delete() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle a reaction from a user
|
||||
* Returns: 'added', 'updated', or 'removed'
|
||||
*/
|
||||
public function toggleReaction(User $user, string $type): string
|
||||
{
|
||||
$existingReaction = $this->getUserReaction($user);
|
||||
|
||||
if ($existingReaction) {
|
||||
if ($existingReaction->type === $type) {
|
||||
// Same reaction - remove it
|
||||
$existingReaction->delete();
|
||||
return 'removed';
|
||||
} else {
|
||||
// Different reaction - update it
|
||||
$existingReaction->update(['type' => $type]);
|
||||
return 'updated';
|
||||
}
|
||||
} else {
|
||||
// No existing reaction - create new one
|
||||
$this->addReaction($user, $type);
|
||||
return 'added';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reactions grouped by type with user information
|
||||
*/
|
||||
public function getReactionsWithUsersAttribute(): array
|
||||
{
|
||||
return $this->reactions()
|
||||
->with('user:id,name')
|
||||
->get()
|
||||
->groupBy('type')
|
||||
->map(function ($reactions) {
|
||||
return $reactions->map(function ($reaction) {
|
||||
return [
|
||||
'user_id' => $reaction->user->id,
|
||||
'user_name' => $reaction->user->name,
|
||||
'created_at' => $reaction->created_at->diffForHumans(),
|
||||
];
|
||||
});
|
||||
})
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the most popular reaction type
|
||||
*/
|
||||
public function getMostPopularReactionAttribute(): ?string
|
||||
{
|
||||
$counts = $this->reaction_counts;
|
||||
|
||||
if (empty($counts)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return array_keys($counts, max($counts))[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope to order by reaction count
|
||||
*/
|
||||
public function scopeOrderByReactions($query, string $direction = 'desc')
|
||||
{
|
||||
return $query->withCount('reactions')
|
||||
->orderBy('reactions_count', $direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope to filter models with reactions
|
||||
*/
|
||||
public function scopeWithReactions($query)
|
||||
{
|
||||
return $query->has('reactions');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope to filter models by specific reaction type
|
||||
*/
|
||||
public function scopeWithReactionType($query, string $type)
|
||||
{
|
||||
return $query->whereHas('reactions', function ($q) use ($type) {
|
||||
$q->where('type', $type);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user