Completed
Push — master ( de7ce3...708b8c )
by Younes
01:51
created

RatingBuilder::rate()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 2
nop 1
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
1
<?php
2
3
namespace Yoeunes\Rateable;
4
5
use Yoeunes\Rateable\Models\Rating;
6
use Yoeunes\Rateable\Traits\Rateable;
7
use Illuminate\Database\Eloquent\Model;
8
use Yoeunes\Rateable\Exceptions\EmptyUser;
9
use Yoeunes\Rateable\Exceptions\InvalidRatingValue;
10
use Yoeunes\Rateable\Exceptions\UserDoestNotHaveID;
11
use Illuminate\Database\Eloquent\Relations\Relation;
12
use Yoeunes\Rateable\Exceptions\RateableModelNotFound;
13
use Yoeunes\Rateable\Exceptions\ModelDoesNotUseRateableTrait;
14
15
class RatingBuilder
16
{
17
    protected $user;
18
19
    protected $rateable;
20
21
    protected $uniqueRatingForUsers = true;
22
23
    /**
24
     * @param Model|int $user
25
     *
26
     * @return RatingBuilder
27
     *
28
     * @throws \Throwable
29
     */
30
    public function user($user)
31
    {
32
        throw_if($user instanceof Model && empty($user->id), UserDoestNotHaveID::class, 'User object does not have ID');
33
34
        $this->user = $user instanceof Model ? $user->id : $user;
35
36
        return $this;
37
    }
38
39
    /**
40
     * @param Model $rateable
41
     *
42
     * @return $this
43
     *
44
     * @throws \Throwable
45
     */
46
    public function rateable(Model $rateable)
47
    {
48
        throw_unless(in_array(Rateable::class, class_uses_recursive($rateable)), ModelDoesNotUseRateableTrait::class, get_class($rateable) . ' does not use the Rateable Trait');
49
50
        $this->rateable = $rateable;
51
52
        return $this;
53
    }
54
55
    public function uniqueRatingForUsers(bool $unique)
56
    {
57
        $this->uniqueRatingForUsers = $unique;
58
59
        return $this;
60
    }
61
62
    /**
63
     * @param int $value
64
     *
65
     * @return Rating
66
     *
67
     * @throws \Throwable
68
     */
69
    public function rate(int $value)
70
    {
71
        throw_if($value < config('rateable.min_rating') || $value > config('rateable.max_rating'), InvalidRatingValue::class, 'Invalid rating value');
72
73
        throw_if(empty($this->user), EmptyUser::class, 'Empty user');
74
75
        throw_if(empty($this->rateable->id), RateableModelNotFound::class, 'Rateable model not found');
76
77
        $data = [
78
            'user_id'       => $this->user,
79
            'rateable_id'   => $this->rateable->id,
80
            'rateable_type' => Relation::getMorphedModel(get_class($this->rateable)) ?? get_class($this->rateable),
81
        ];
82
83
        $ratingModel = config('rateable.rating');
84
85
        $rating = $this->uniqueRatingForUsers ? (new $ratingModel)->firstOrNew($data) : (new $ratingModel)->fill($data);
86
87
        $rating->value = $value;
88
89
        $rating->save();
90
91
        return $rating;
92
    }
93
}
94