200 lines
6.5 KiB
PHP
200 lines
6.5 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Enums\InteractionType;
|
|
use Illuminate\Database\Eloquent\Attributes\Scope;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
/**
|
|
* @property int $id
|
|
* @property string $title
|
|
* @property string $slug
|
|
* @property string $description
|
|
* @property string|null $image
|
|
* @property string|null $link
|
|
* @property int $active
|
|
* @property int $deal_category_id
|
|
* @property int $user_id
|
|
* @property \Illuminate\Support\Carbon|null $created_at
|
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
|
* @property-read \App\Models\User|null $broker
|
|
* @property-read \App\Models\DealCategory|null $category
|
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Comment> $comments
|
|
* @property-read int|null $comments_count
|
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Interaction> $interactions
|
|
* @property-read int|null $interactions_count
|
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Report> $reports
|
|
* @property-read int|null $reports_count
|
|
*
|
|
* @method static Builder<static>|Deal WithActiveDeals()
|
|
* @method static Builder<static>|Deal WithCurrentUserInteractions()
|
|
* @method static Builder<static>|Deal WithLikePerDeal()
|
|
* @method static Builder<static>|Deal WithRedirectionPerDeal()
|
|
* @method static Builder<static>|Deal filterByCategory(string $category)
|
|
* @method static Builder<static>|Deal newModelQuery()
|
|
* @method static Builder<static>|Deal newQuery()
|
|
* @method static Builder<static>|Deal query()
|
|
* @method static Builder<static>|Deal search(string $search)
|
|
* @method static Builder<static>|Deal whereActive($value)
|
|
* @method static Builder<static>|Deal whereCreatedAt($value)
|
|
* @method static Builder<static>|Deal whereDealCategoryId($value)
|
|
* @method static Builder<static>|Deal whereDescription($value)
|
|
* @method static Builder<static>|Deal whereId($value)
|
|
* @method static Builder<static>|Deal whereImage($value)
|
|
* @method static Builder<static>|Deal whereLink($value)
|
|
* @method static Builder<static>|Deal whereSlug($value)
|
|
* @method static Builder<static>|Deal whereTitle($value)
|
|
* @method static Builder<static>|Deal whereUpdatedAt($value)
|
|
* @method static Builder<static>|Deal whereUserId($value)
|
|
* @method static Builder<static>|Deal withIsFollowedByCurrentUser()
|
|
* @method static Builder<static>|Deal withViewPerDeal()
|
|
*
|
|
* @mixin \Eloquent
|
|
*/
|
|
class Deal extends Model
|
|
{
|
|
public function broker(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'user_id');
|
|
}
|
|
|
|
public function category(): BelongsTo
|
|
{
|
|
return $this->belongsTo(DealCategory::class, 'deal_category_id');
|
|
}
|
|
|
|
public function interactions(): HasMany
|
|
{
|
|
return $this->hasMany(Interaction::class);
|
|
}
|
|
|
|
public function reports(): BelongsToMany
|
|
{
|
|
return $this->belongsToMany(Report::class);
|
|
}
|
|
|
|
public function comments(): HasMany
|
|
{
|
|
return $this->hasMany(Comment::class);
|
|
}
|
|
|
|
/**
|
|
* Scope a query to only include active deals
|
|
*/
|
|
#[Scope]
|
|
public function WithActiveDeals(Builder $query): Builder
|
|
{
|
|
return $query->where('active', true);
|
|
}
|
|
|
|
/**
|
|
* Scope a query to determine if the current user has liked and favorite a deal
|
|
*/
|
|
#[Scope]
|
|
public function WithCurrentUserInteractions(Builder $query): Builder
|
|
{
|
|
return $query->withExists([
|
|
'interactions as is_liked' => function ($query) {
|
|
$query->where('user_id', Auth::id())
|
|
->where('type', InteractionType::Like);
|
|
},
|
|
'interactions as is_favorite' => function ($query) {
|
|
$query->where('user_id', Auth::id())
|
|
->where('type', InteractionType::Favorite);
|
|
},
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Scope a query to get total like count per deal
|
|
*/
|
|
#[Scope]
|
|
public function WithLikePerDeal(Builder $query): Builder
|
|
{
|
|
return $query->withCount([
|
|
'interactions as total_likes' => function ($query) {
|
|
$query->where('type', InteractionType::Like);
|
|
},
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Scope a query to get click count per deal
|
|
*/
|
|
#[Scope]
|
|
public function WithRedirectionPerDeal(Builder $query): Builder
|
|
{
|
|
return $query->withSum([
|
|
'interactions as total_redirection' => function ($query) {
|
|
$query->where('type', InteractionType::Redirection);
|
|
},
|
|
], 'count');
|
|
}
|
|
|
|
/**
|
|
* Scope a query to get a view count per deal
|
|
*/
|
|
#[Scope]
|
|
public function withViewPerDeal(Builder $query): Builder
|
|
{
|
|
return $query->withSum([
|
|
'interactions as total_views' => function ($query) {
|
|
$query->where('type', InteractionType::View);
|
|
},
|
|
], 'count');
|
|
}
|
|
|
|
/**
|
|
* Scope a search in a query
|
|
*/
|
|
#[Scope]
|
|
public function search(Builder $query, string $search): Builder
|
|
{
|
|
return $query->where(function (Builder $query) use ($search) {
|
|
$query->where('title', 'LIKE', "%$search%")
|
|
->orWhereRelation('broker', 'name', 'LIKE', "%$search%");
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Scope a category filter in a query
|
|
*/
|
|
#[Scope]
|
|
public function filterByCategory(Builder $query, string $category): Builder
|
|
{
|
|
return $query->where('deal_category_id', $category);
|
|
}
|
|
|
|
// Add this to App\Models\Deal.php
|
|
|
|
/**
|
|
* Scope a query to check if the current user follows the deal's broker
|
|
*/
|
|
#[Scope]
|
|
public function withIsFollowedByCurrentUser(Builder $query): Builder
|
|
{
|
|
$user = Auth::user();
|
|
|
|
if (! $user || $user->role_type !== \App\Models\Customer::class) {
|
|
return $query->withExists(['broker as is_followed' => fn ($q) => $q->whereRaw('1 = 0')]);
|
|
}
|
|
|
|
return $query->withExists([
|
|
'broker as is_followed' => function ($query) use ($user) {
|
|
$query->where('role_type', \App\Models\Broker::class)
|
|
->whereHasMorph('type', [\App\Models\Broker::class], function ($query) use ($user) {
|
|
$query->whereHas('followers', function ($query) use ($user) {
|
|
$query->where('customer_id', $user->id);
|
|
});
|
|
});
|
|
},
|
|
]);
|
|
}
|
|
}
|