Passed
Push — master ( 13d5af...21d735 )
by Adam
11:07
created

NotificationsController::ajax()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 1
dl 0
loc 14
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Coyote\Http\Controllers\User;
4
5
use Coyote\Events\NotificationRead;
6
use Coyote\Notification;
7
use Coyote\Repositories\Contracts\NotificationRepositoryInterface as NotificationRepository;
8
use Coyote\Http\Resources\NotificationResource;
9
use Illuminate\Http\Request;
10
use Carbon;
11
12
class NotificationsController extends BaseController
13
{
14
    use SettingsTrait, HomeTrait {
0 ignored issues
show
introduced by
The trait Coyote\Http\Controllers\User\HomeTrait requires some properties which are not provided by Coyote\Http\Controllers\...NotificationsController: $pm_unread, $pm
Loading history...
15
        SettingsTrait::getSideMenu as settingsSideMenu;
16
        HomeTrait::getSideMenu as homeSideMenu;
17
    }
18
19
    public function __construct(private NotificationRepository $notification)
20
    {
21
        parent::__construct();
22
    }
23
24
    /**
25
     * @return mixed
26
     */
27
    public function getSideMenu()
28
    {
29
        if ($this->request->route()->getName() == 'user.notifications') {
30
            return $this->homeSideMenu();
31
        } else {
32
            return $this->settingsSideMenu();
33
        }
34
    }
35
36
    /**
37
     * @return \Illuminate\View\View
38
     */
39
    public function index()
40
    {
41
        $this->breadcrumb->push('Powiadomienia', route('user.notifications'));
42
43
        $pagination = $this->notification->lengthAwarePaginate($this->userId);
44
        // mark as read
45
        $this->mark($pagination);
46
47
        $pagination->setCollection(
48
            collect(NotificationResource::collection($pagination->getCollection())->toArray($this->request))
49
        );
50
51
        return $this->view('user.notifications.home', [
52
            'pagination'          => $pagination
53
        ]);
54
    }
55
56
    /**
57
     * @return \Illuminate\View\View
58
     */
59
    public function settings()
60
    {
61
        $this->breadcrumb->push('Ustawienia powiadomień', route('user.notifications.settings'));
62
63
        return $this->view('user.notifications.settings', [
64
            'groups'        => $this->notification->notificationTypes()->groupBy('category'),
65
            'settings'      => $this->auth->notificationSettings()->get()->sortBy('channel')->groupBy('type_id'),
66
            'channels'      => Notification::getChannels()
67
        ]);
68
    }
69
70
    /**
71
     * @param Request $request
72
     * @return \Illuminate\Http\RedirectResponse
73
     */
74
    public function save(Request $request)
75
    {
76
        $this->notification->updateSettings($this->userId, $request->input('settings'));
77
78
        return back()->with('success', 'Zmiany zostały zapisane');
79
    }
80
81
    /**
82
     * @param Request $request
83
     * @return \Illuminate\Http\JsonResponse
84
     */
85
    public function ajax(Request $request)
86
    {
87
        $unread = $this->auth->notifications_unread;
88
        $offset = $request->query('offset', 0);
89
90
        $notifications = $this->notification->takeForUser($this->userId, max(10, $unread), $offset);
91
        $unread -= $this->mark($notifications);
92
93
        // format notification's headline
94
        $notifications = array_filter(NotificationResource::collection($notifications)->toArray($this->request));
0 ignored issues
show
Bug introduced by
It seems like Coyote\Http\Resources\No...toArray($this->request) can also be of type Illuminate\Contracts\Support\Arrayable and JsonSerializable; however, parameter $array of array_filter() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

94
        $notifications = array_filter(/** @scrutinizer ignore-type */ NotificationResource::collection($notifications)->toArray($this->request));
Loading history...
95
96
        return response()->json([
97
            'count'             => $unread,
98
            'notifications'     => $notifications
99
        ]);
100
    }
101
102
    /**
103
     * @param int $id
104
     */
105
    public function delete($id)
106
    {
107
        $this->notification->delete($id);
108
    }
109
110
    /**
111
     * Marks all alerts as read
112
     */
113
    public function markAsRead()
114
    {
115
        if ($this->auth->notifications_unread) {
116
            $this->notification->where('user_id', $this->userId)->whereNull('read_at')->update([
0 ignored issues
show
Bug introduced by
The method where() does not exist on Coyote\Repositories\Cont...tionRepositoryInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Coyote\Repositories\Cont...tionRepositoryInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

116
            $this->notification->/** @scrutinizer ignore-call */ 
117
                                 where('user_id', $this->userId)->whereNull('read_at')->update([
Loading history...
117
                'read_at' => Carbon\Carbon::now()
118
            ]);
119
        }
120
121
        $this->notification->where('user_id', $this->userId)->update(['is_clicked' => true]);
122
    }
123
124
    /**
125
     * @param string $id
126
     * @return \Illuminate\Http\RedirectResponse
127
     *
128
     * @deprecated
129
     */
130
    public function url(string $id)
131
    {
132
        /** @var \Coyote\Notification $notification */
133
        $notification = $this->notification->findOrFail($id, ['id', 'url', 'read_at', 'user_id', 'is_clicked']);
134
135
        $notification->is_clicked = true;
136
137
        if (!$notification->read_at) {
138
            $notification->read_at = Carbon\Carbon::now();
139
140
            broadcast(new NotificationRead($notification));
141
        }
142
143
        $notification->save();
144
145
        return redirect()->to($notification->url);
146
    }
147
148
    public function redirectToUrl()
149
    {
150
        $path = urldecode($this->request->get('path'));
0 ignored issues
show
Bug introduced by
It seems like $this->request->get('path') can also be of type null; however, parameter $string of urldecode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

150
        $path = urldecode(/** @scrutinizer ignore-type */ $this->request->get('path'));
Loading history...
151
152
        /** @var \Coyote\Notification $notification */
153
        $notification = $this->auth->notifications()->where('url', $path)->first();
154
155
        if ($notification) {
0 ignored issues
show
introduced by
$notification is of type Coyote\Notification, thus it always evaluated to true.
Loading history...
156
            $notification->is_clicked = true;
157
158
            if (!$notification->read_at) {
159
                $notification->read_at = now();
160
161
                broadcast(new NotificationRead($notification));
162
            }
163
164
            $notification->save();
165
        }
166
167
        return redirect()->to($path);
168
    }
169
170
    /**
171
     * Mark alerts as read and returns number of marked alerts
172
     *
173
     * @param \Illuminate\Support\Collection $notifications
174
     * @return int
175
     */
176
    private function mark($notifications)
177
    {
178
        $ids = $notifications
179
            ->reject(fn (Notification $notification) => $notification->read_at !== null)
180
            ->pluck('id')
181
            ->all();
182
183
        if (!empty($ids)) {
184
            $this->notification->markAsRead($ids);
185
        }
186
187
        return count($ids);
188
    }
189
}
190