Completed
Push — master ( 69acbc...a97ac2 )
by Younes
01:55
created

Voteable::isVoted()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Yoeunes\Voteable\Traits;
4
5
use Yoeunes\Voteable\Models\Vote;
6
use Yoeunes\Voteable\VoteBuilder;
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
    public function votesCount()
25
    {
26
        return $this->votes()->sum('amount');
27
    }
28
29
    /**
30
     * @return mixed
31
     */
32
    public function upVotesCount()
33
    {
34
        return $this->votes()->where('amount', '>=', 0)->sum('amount');
35
    }
36
37
    /**
38
     * @return mixed
39
     */
40
    public function downVotesCount()
41
    {
42
        return $this->votes()->where('amount', '<', 0)->sum('amount');
43
    }
44
45
    public function isVoted()
46
    {
47
        return $this->votes()->exists();
48
    }
49
50
    /**
51
     * @return bool
52
     */
53
    public function isUpVoted()
54
    {
55
        return $this->votes()->where('amount', '>=', 0)->exists();
56
    }
57
58
    /**
59
     * @return bool
60
     */
61
    public function isDownVoted()
62
    {
63
        return $this->votes()->where('amount', '<', 0)->exists();
64
    }
65
66
    public function isVotedByUser(int $user_id)
67
    {
68
        return $this->votes()->where('user_id', $user_id)->exists();
69
    }
70
71
    /**
72
     * @param int $user_id
73
     *
74
     * @return bool
75
     */
76
    public function isUpVotedByUser(int $user_id)
77
    {
78
        return $this->votes()->where('amount', '>=', 0)->where('user_id', $user_id)->exists();
79
    }
80
81
    /**
82
     * @param int $user_id
83
     *
84
     * @return bool
85
     */
86
    public function isDownVotedByUser(int $user_id)
87
    {
88
        return $this->votes()->where('amount', '<', 0)->where('user_id', $user_id)->exists();
89
    }
90
91
    /**
92
     * @param Builder $query
93
     * @param string $direction
94
     * @param string $type
95
     *
96
     * @return Builder
97
     */
98
    public function scopeOrderByUpVotes(Builder $query, string $direction = 'asc', string $type = '>=')
99
    {
100
        return $query
101
            ->leftJoin('votes', function (JoinClause $join) {
102
                $join
103
                    ->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...
104
                    ->where('votes.voteable_type', Relation::getMorphedModel(__CLASS__) ?? __CLASS__);
105
            })
106
            ->where('amount', $type, 0)
107
            ->addSelect(DB::raw('SUM(votes.value) as count_votes'))
108
            ->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...
109
            ->orderBy('count_votes', $direction);
110
    }
111
112
    /**
113
     * @param Builder $query
114
     * @param string $direction
115
     *
116
     * @return Builder
117
     */
118
    public function scopeOrderByDownVotes(Builder $query, string $direction = 'asc')
119
    {
120
        return $this->scopeOrderByUpVotes($query, $direction, '<');
121
    }
122
123
    /**
124
     * @param int $vote_id
125
     *
126
     * @return mixed
127
     */
128
    public function cancelVote(int $vote_id)
129
    {
130
        return $this->votes()->where('id', $vote_id)->delete();
131
    }
132
133
    /**
134
     * @return mixed
135
     */
136
    public function resetVotes()
137
    {
138
        return $this->votes()->delete();
139
    }
140
141
    /**
142
     * @param int $user_id
143
     *
144
     * @return mixed
145
     */
146
    public function cancelVotesForUser(int $user_id)
147
    {
148
        return $this->votes()->where('user_id', $user_id)->delete();
149
    }
150
151
    /**
152
     * @param int $user_id
153
     * @param int $amount
154
     *
155
     * @return int
156
     */
157
    public function updateVotesForUser(int $user_id, int $amount)
158
    {
159
        return $this->votes()->where('user_id', $user_id)->update(['amount' => $amount]);
160
    }
161
162
    /**
163
     * @param int $vote_id
164
     * @param int $amount
165
     *
166
     * @return int
167
     */
168
    public function updateVote(int $vote_id, int $amount)
169
    {
170
        return $this->votes()->where('id', $vote_id)->update(['amount' => $amount]);
171
    }
172
173
    /**
174
     * @return VoteBuilder
175
     *
176
     * @throws \Throwable
177
     */
178
    public function getVoteBuilder()
179
    {
180
        return (new VoteBuilder())
181
            ->voteable($this);
182
    }
183
184
    public function voters()
185
    {
186
        return $this->morphToMany(config('voteable.user'), 'voteable', 'votes');
0 ignored issues
show
Bug introduced by
It seems like morphToMany() 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...
187
    }
188
189
    public function countVotesByDate($from = null, $to = null)
190
    {
191
        $query = $this->votes();
192
193
        if (! empty($from) && empty($to)) {
194
            $query->where('created_at', '>=', date_transformer($from));
195
        } elseif (empty($from) && ! empty($to)) {
196
            $query->where('created_at', '<=', date_transformer($to));
197
        } elseif (! empty($from) && ! empty($to)) {
198
            $query->whereBetween('created_at', [date_transformer($from), date_transformer($to)]);
199
        }
200
201
        return $query->sum('amount');
202
    }
203
}
204