dealhub/app/Models/Deal.php
kusowl 5cae04884a feature(users can follow a broker)
- add schema and endpoints to make follows relationship with customer
and broker

- show and update states of follow button on ui
2026-02-05 18:19:52 +05:30

197 lines
6.3 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\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 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);
});
});
},
]);
}
}