Passed
Push — Leaderboard ( 298845 )
by Fèvre
06:39
created

BadgeSubscriber::onNewLeaderboard()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Xetaravel\Listeners\Subscribers;
3
4
use Carbon\Carbon;
5
use Illuminate\Database\Eloquent\Collection;
6
use Xetaravel\Events\Badges\ExperiencesEvent;
7
use Xetaravel\Events\Badges\PostEvent;
8
use Xetaravel\Events\Badges\PostSolvedEvent;
9
use Xetaravel\Events\Badges\LeaderboardEvent;
10
use Xetaravel\Events\RegisterEvent;
0 ignored issues
show
Bug introduced by
The type Xetaravel\Events\RegisterEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Xetaravel\Events\CommentEvent;
0 ignored issues
show
Bug introduced by
The type Xetaravel\Events\CommentEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Xetaravel\Models\Badge;
13
use Xetaravel\Models\DiscussPost;
14
use Xetaravel\Models\User;
15
use Xetaravel\Notifications\BadgeNotification;
16
17
class BadgeSubscriber
18
{
19
    /**
20
     * The events mapping to the listener function.
21
     *
22
     * @var array
23
     */
24
    protected $events = [
25
        RegisterEvent::class => 'onNewRegister',
26
        PostEvent::class => 'onNewPost',
27
        PostSolvedEvent::class => 'onNewPostSolved',
28
        ExperiencesEvent::class => 'onNewExperiences',
29
        LeaderboardEvent::class => 'onNewLeaderboard'
30
    ];
31
32
    /**
33
     * Register the listeners for the subscriber.
34
     *
35
     * @param Illuminate\Events\Dispatcher $events
0 ignored issues
show
Bug introduced by
The type Xetaravel\Listeners\Subs...inate\Events\Dispatcher was not found. Did you mean Illuminate\Events\Dispatcher? If so, make sure to prefix the type with \.
Loading history...
36
     *
37
     * @return void
38
     */
39
    public function subscribe($events)
40
    {
41
        foreach ($this->events as $event => $action) {
42
            $events->listen($event, BadgeSubscriber::class . '@' . $action);
43
        }
44
    }
45
46
    /**
47
     * Listener related to the comment badge.
48
     *
49
     * @param \Xetaravel\Events\CommentEvent $event The event that was fired.
50
     *
51
     * @return bool
52
     */
53
    public function onNewComment(CommentEvent $event): bool
54
    {
55
        $user = $event->user;
56
        $badges = Badge::where('type', 'onNewComment')->get();
57
58
        $collection = $badges->filter(function ($badge) use ($user) {
59
            return $badge->rule <= $user->comment_count;
60
        });
61
62
        $result = $user->badges()->syncWithoutDetaching($collection);
63
64
        return $this->sendNotifications($result, $badges, $user);
65
    }
66
67
    /**
68
     * Listener related to the posts badge.
69
     *
70
     * @param \Xetaravel\Events\PostEvent $event The event that was fired.
0 ignored issues
show
Bug introduced by
The type Xetaravel\Events\PostEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
71
     *
72
     * @return bool
73
     */
74
    public function onNewPost(PostEvent $event): bool
75
    {
76
        $user = $event->user;
77
        $badges = Badge::where('type', 'onNewPost')->get();
78
79
        $collection = $badges->filter(function ($badge) use ($user) {
80
            return $badge->rule <= $user->discuss_post_count;
81
        });
82
83
        $result = $user->badges()->syncWithoutDetaching($collection);
84
85
        return $this->sendNotifications($result, $badges, $user);
86
    }
87
88
    /**
89
     * Listener related to the post solved badge.
90
     *
91
     * @param \Xetaravel\Events\PostSolvedEvent $event The event that was fired.
0 ignored issues
show
Bug introduced by
The type Xetaravel\Events\PostSolvedEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
92
     *
93
     * @return bool
94
     */
95
    public function onNewPostSolved(PostSolvedEvent $event): bool
96
    {
97
        $user = $event->user;
98
        $badges = Badge::where('type', 'onNewPostSolved')->get();
99
100
        $collection = $badges->filter(function ($badge) use ($user) {
101
            $postsSolved = DiscussPost::where('user_id', $user->id)
102
                    ->where('is_solved', true)
103
                    ->count();
104
105
            return $badge->rule <= $postsSolved;
106
        });
107
108
        $result = $user->badges()->syncWithoutDetaching($collection);
109
110
        return $this->sendNotifications($result, $badges, $user);
111
    }
112
113
    /**
114
     * Listener related to the experiences badge.
115
     *
116
     * @param \Xetaravel\Events\ExperiencesEvent $event The event that was fired.
0 ignored issues
show
Bug introduced by
The type Xetaravel\Events\ExperiencesEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
117
     *
118
     * @return bool
119
     */
120
    public function onNewExperiences(ExperiencesEvent $event): bool
121
    {
122
        $user = $event->user;
123
        $badges = Badge::where('type', 'onNewExperiences')->get();
124
125
        $collection = $badges->filter(function ($badge) use ($user) {
126
            return $badge->rule <= $user->experiences_total;
127
        });
128
129
        $result = $user->badges()->syncWithoutDetaching($collection);
130
131
        return $this->sendNotifications($result, $badges, $user);
132
    }
133
134
    /**
135
     * Listener related to the register badge.
136
     *
137
     * @param \Xetaravel\Events\RegisterEvent $event The event that was fired.
138
     *
139
     * @return bool
140
     */
141
    public function onNewRegister(RegisterEvent $event): bool
142
    {
143
        $user = $event->user;
144
        $badges = Badge::where('type', 'onNewRegister')->get();
145
146
        $today = new Carbon();
147
        $diff = $today->diff($user->created_at)->y;
148
149
        $collection = $badges->filter(function ($badge) use ($diff) {
150
            return $badge->rule <= $diff;
151
        });
152
153
        $result = $user->badges()->syncWithoutDetaching($collection);
154
155
        return $this->sendNotifications($result, $badges, $user);
156
    }
157
158
    /**
159
     * Listener related to the leaderboard badge.
160
     *
161
     * @param \Xetaravel\Events\RegisterEvent $event The event that was fired.
162
     *
163
     * @return bool
164
     */
165
    public function onNewLeaderboard(LeaderboardEvent $event): bool
166
    {
167
        $user = $event->user;
168
        $badges = Badge::where('type', 'topLeaderboard')->get();
169
170
        $result = $user->badges()->syncWithoutDetaching($badges);
171
172
        return $this->sendNotifications($result, $badges, $user);
173
    }
174
175
    /**
176
     * Send a notification for each new badge unlocked.
177
     *
178
     * @param array $result The result of the synchronization.
179
     * @param \Illuminate\Database\Eloquent\Collection $badges The badges collection related to the listener.
180
     * @param \Xetaravel\Models\User $user The user to notify.
181
     *
182
     * @return bool
183
     */
184
    protected function sendNotifications(array $result, Collection $badges, User $user): bool
185
    {
186
        if (empty($result['attached'])) {
187
            return true;
188
        }
189
190
        $sendNotification = function ($badgeId, $key, $badges) use ($user) {
191
            $badgeCollection = $badges->filter(function ($badge) use ($badgeId) {
192
                return $badge->id == $badgeId;
193
            })->first();
194
195
            $user->notify(new BadgeNotification($badgeCollection));
196
        };
197
198
        return array_walk($result['attached'], $sendNotification, $badges);
199
    }
200
}
201