Passed
Pull Request — main (#3)
by Tan
02:37
created

Like::model()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 1
c 1
b 0
f 1
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace CSlant\LaravelLike\Models;
4
5
use CSlant\LaravelLike\Enums\InteractionTypeEnum;
6
use CSlant\LaravelLike\Traits\InteractionRelationship;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
use Illuminate\Database\Query\Builder;
10
use Illuminate\Support\Carbon;
11
12
/**
13
 * Class Like
14
 *
15
 * @package CSlant\LaravelLike\Models
16
 * @property int $id
17
 * @property int $user_id
18
 * @property int $model_id
19
 * @property string $model_type
20
 * @property InteractionTypeEnum $type
21
 * @property Carbon $created_at
22
 * @property Carbon $updated_at
23
 *
24
 * @property-read string $interaction_type getInteractionTypeAttribute()
25
 */
26
class Like extends Model
27
{
28
    /**
29
     * The attributes that are mass assignable.
30
     *
31
     * @var array<int, string>
32
     */
33
    protected $fillable = [
34
        'user_id',
35
        'model_id',
36
        'model_type',
37
        'type',
38
    ];
39
40
    /**
41
     * The attributes that should be cast.
42
     *
43
     * @var array<string, string>
44
     */
45
    protected $casts = [
46
        'model_type' => 'string',
47
        'type' => InteractionTypeEnum::class,
48
    ];
49
50
    /**
51
     * Check if the record is liked.
52
     *
53
     * @see InteractionRelationship::likeOne()
54
     *
55
     * @return bool
56
     */
57
    public function isLiked(): bool
58
    {
59
        // Use with likeOne() relationship. Can't use with likes() relationship.
60
        return $this->type->isLike();
61
    }
62
63
    /**
64
     * Check if the record is disliked.
65
     *
66
     * @see InteractionRelationship::likeOne()
67
     *
68
     * @return bool
69
     */
70
    public function isDisliked(): bool
71
    {
72
        // Use with likeOne() relationship. Can't use with likes() relationship.
73
        return $this->type->isDislike();
74
    }
75
76
    /**
77
     * Check if the record is loved.
78
     *
79
     * @see InteractionRelationship::likeOne()
80
     *
81
     * @return bool
82
     */
83
    public function isLove(): bool
84
    {
85
        // Use with likeOne() relationship. Can't use with likes() relationship.
86
        return $this->type->isLove();
87
    }
88
89
    /**
90
     * Scope a query to only include records of a given model type.
91
     *
92
     * @param  Builder  $query
93
     * @param  string  $modelType The model type. E.g. App\Models\Post::class
94
     *
95
     * @return Builder
96
     */
97
    public function scopeWithModelType(Builder $query, string $modelType): Builder
98
    {
99
        // Use with likes() relationship. Can't use with likeOne() relationship.
100
        return $query->where('model_type', $modelType);
101
    }
102
103
    /**
104
     * Get the interaction type attribute. Used for the accessor.
105
     *
106
     * @return string
107
     */
108
    public function getInteractionTypeAttribute(): string
109
    {
110
        return $this->type->value;
111
    }
112
113
    /**
114
     * Get the user that owns the like.
115
     *
116
     * @return BelongsTo
117
     */
118
    public function user(): BelongsTo
119
    {
120
        $userModel = (string) (config('like.users.model') ?? config('auth.providers.users.model'));
121
        $userForeignKey = (string) (config('like.users.foreign_key') ?? 'user_id');
122
123
        return $this->belongsTo($userModel, $userForeignKey);
124
    }
125
126
    /**
127
     * Get the model that the like belongs to.
128
     *
129
     * @return BelongsTo<Model, self>
130
     */
131
    public function model(): BelongsTo
132
    {
133
        return $this->morphTo();
134
    }
135
136
    /**
137
     * Toggle the like interaction.
138
     *
139
     * @return string
140
     */
141
    public function toggleLikeInteraction(): string
142
    {
143
        if ($this->isLiked()) {
144
            $this->type = InteractionTypeEnum::DISLIKE;
145
        } else {
146
            $this->type = InteractionTypeEnum::LIKE;
147
        }
148
149
        return $this->type->value;
150
    }
151
}
152