Passed
Push — master ( 0bc6fd...4cd429 )
by Younes
01:43
created

Voteable::cancelVotesForUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Yoeunes\Voteable\Traits;
4
5
use Yoeunes\Rateable\VoteBuilder;
6
use Yoeunes\Voteable\Models\Vote;
7
use Illuminate\Support\Facades\DB;
8
use Illuminate\Database\Eloquent\Builder;
9
use Illuminate\Database\Query\JoinClause;
10
use Illuminate\Database\Eloquent\Relations\Relation;
11
12
trait Voteable
13
{
14
    /**
15
     * This model has many votes.
16
     *
17
     * @return \Illuminate\Database\Eloquent\Relations\MorphMany
18
     */
19
    public function votes()
20
    {
21
        return $this->morphMany(Vote::class, 'voteable');
0 ignored issues
show
Bug introduced by
It seems like morphMany() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
22
    }
23
24
    /**
25
     * @return mixed
26
     */
27
    public function upVotesCount()
28
    {
29
        return $this->votes()->where('amount', '>=', 0)->sum('amount');
30
    }
31
32
    /**
33
     * @return mixed
34
     */
35
    public function downVotesCount()
36
    {
37
        return $this->votes()->where('amount', '<', 0)->sum('amount');
38
    }
39
40
    /**
41
     * @return bool
42
     */
43
    public function isUpVoted()
44
    {
45
        return $this->votes()->where('amount', '>=', 0)->exists();
46
    }
47
48
    /**
49
     * @return bool
50
     */
51
    public function isDownVoted()
52
    {
53
        return $this->votes()->where('amount', '<', 0)->exists();
54
    }
55
56
    /**
57
     * @param int $user_id
58
     *
59
     * @return bool
60
     */
61
    public function isUpVotedByUser(int $user_id)
62
    {
63
        return $this->votes()->where('amount', '>=', 0)->where('user_id', $user_id)->exists();
64
    }
65
66
    /**
67
     * @param int $user_id
68
     *
69
     * @return bool
70
     */
71
    public function isDownVotedByUser(int $user_id)
72
    {
73
        return $this->votes()->where('amount', '<', 0)->where('user_id', $user_id)->exists();
74
    }
75
76
    /**
77
     * @param Builder $query
78
     * @param string $direction
79
     * @param string $type
80
     *
81
     * @return Builder
82
     */
83
    public function scopeOrderByUpVotes(Builder $query, string $direction = 'asc', string $type = '>=')
84
    {
85
        return $query
86
            ->leftJoin('votes', function (JoinClause $join) {
87
                $join
88
                    ->on('votes.voteable_id', $this->getTable() . '.id')
0 ignored issues
show
Bug introduced by
It seems like getTable() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
89
                    ->where('votes.voteable_type', Relation::getMorphedModel(__CLASS__) ?? __CLASS__);
90
            })
91
            ->where('amount', $type, 0)
92
            ->addSelect(DB::raw('SUM(votes.value) as count_votes'))
93
            ->groupBy($this->getTable(). '.id')
0 ignored issues
show
Bug introduced by
It seems like getTable() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
94
            ->orderBy('count_votes', $direction);
95
    }
96
97
    /**
98
     * @param Builder $query
99
     * @param string $direction
100
     *
101
     * @return Builder
102
     */
103
    public function scopeOrderByDownVotes(Builder $query, string $direction = 'asc')
104
    {
105
        return $this->scopeOrderByUpVotes($query, $direction, '<');
106
    }
107
108
    /**
109
     * @param int $vote_id
110
     *
111
     * @return mixed
112
     */
113
    public function cancelVote(int $vote_id)
114
    {
115
        return $this->votes()->where('id', $vote_id)->delete();
116
    }
117
118
    /**
119
     * @return mixed
120
     */
121
    public function resetVotes()
122
    {
123
        return $this->votes()->delete();
124
    }
125
126
    /**
127
     * @param int $user_id
128
     *
129
     * @return mixed
130
     */
131
    public function cancelVotesForUser(int $user_id)
132
    {
133
        return $this->votes()->where('user_id', $user_id)->delete();
134
    }
135
136
    /**
137
     * @param int $user_id
138
     * @param int $amount
139
     *
140
     * @return int
141
     */
142
    public function updateVotesForUser(int $user_id, int $amount)
143
    {
144
        return $this->votes()->where('user_id', $user_id)->update(['amount' => $amount]);
145
    }
146
147
    /**
148
     * @param int $vote_id
149
     * @param int $amount
150
     *
151
     * @return int
152
     */
153
    public function updateVote(int $vote_id, int $amount)
154
    {
155
        return $this->votes()->where('id', $vote_id)->update(['amount' => $amount]);
156
    }
157
158
    /**
159
     * @return VoteBuilder
160
     *
161
     * @throws \Throwable
162
     */
163
    public function getRatingBuilder()
164
    {
165
        return (new VoteBuilder())
166
            ->voteable($this);
167
    }
168
169
    public function voters()
170
    {
171
        $user = config('voteable.user');
172
173
        return (new $user)
174
            ->votes()
175
            ->where('voteable_id', $this->id)
0 ignored issues
show
Bug introduced by
The property id does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
176
            ->where('voteable_type', Relation::getMorphedModel(__CLASS__) ?? __CLASS__);
177
    }
178
}
179