Passed
Push — master ( 84ec90...aaa5ed )
by Yannick
08:21 queued 22s
created

NotificationEvent   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 298
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 158
c 1
b 0
f 0
dl 0
loc 298
rs 9.44
wmc 37

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getEventsForSelect() 0 5 1
A eventTypeToString() 0 5 1
A getForm() 0 27 2
A getUserExtraData() 0 5 2
A getAddForm() 0 34 3
A isRead() 0 20 4
A markAsRead() 0 18 3
D getNotificationsByUser() 0 91 18
A showNotification() 0 13 2
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
class NotificationEvent extends Model
5
{
6
    const ACCOUNT_EXPIRATION = 1;
7
    const JUSTIFICATION_EXPIRATION = 2;
8
    public $table;
9
    public $columns = [
10
        'id',
11
        'title',
12
        'content',
13
        'link',
14
        'persistent',
15
        'day_diff',
16
        'event_type',
17
        'event_id',
18
    ];
19
    public string $extraFieldName;
20
21
    /**
22
     * Constructor.
23
     */
24
    public function __construct()
25
    {
26
        parent::__construct();
27
        $this->table = 'notification_event';
28
        $this->extraFieldName = 'notification_event';
29
    }
30
31
    public function eventTypeToString($eventTypeId)
32
    {
33
        $list = $this->getEventsForSelect();
34
35
        return $list[$eventTypeId];
36
    }
37
38
    public function getEventsForSelect()
39
    {
40
        return [
41
            self::ACCOUNT_EXPIRATION => get_lang('AccountExpiration'),
42
            self::JUSTIFICATION_EXPIRATION => get_lang('JustificationExpiration'),
43
        ];
44
    }
45
46
    /**
47
     * Get a prepared FormValidator form (passed as first param) with the justification fields
48
     * @param FormValidator $form
49
     * @param array $data
50
     * @return FormValidator
51
     * @throws Exception
52
     */
53
    public function getForm(FormValidator $form, array $data = []): FormValidator
54
    {
55
        $options = $this->getEventsForSelect();
56
        $form->addSelect('event_type', get_lang('EventType'), $options);
57
        $form->freeze('event_type');
58
59
        $eventType = $data['event_type'];
60
        switch ($eventType) {
61
            case self::JUSTIFICATION_EXPIRATION:
62
                $plugin = Justification::create();
63
                $list = $plugin->getList();
64
                $list = array_column($list, 'name', 'id');
65
                $form->addSelect('event_id', get_lang('JustificationType'), $list);
66
                $form->freeze('event_id');
67
68
                break;
69
            default:
70
                break;
71
        }
72
73
        $form->addText('title', get_lang('Title'));
74
        $form->addTextarea('content', get_lang('Content'));
75
        $form->addText('link', get_lang('Link'), false);
76
        $form->addCheckBox('persistent', get_lang('Persistent'));
77
        $form->addNumeric('day_diff', get_lang('DayDiff'), false);
78
79
        return $form;
80
    }
81
82
    /**
83
     * Get addition form for the justification notification
84
     * @param FormValidator $form
85
     * @return FormValidator
86
     * @throws Exception
87
     */
88
    public function getAddForm(FormValidator $form): FormValidator
89
    {
90
        $options = $this->getEventsForSelect();
91
        $eventType = $form->getSubmitValue('event_type');
92
93
        $form->addSelect(
94
            'event_type',
95
            get_lang('EventType'),
96
            $options,
97
            ['placeholder' => get_lang('Please select an option'), 'onchange' => 'document.add.submit()']
98
        );
99
100
        if (!empty($eventType)) {
101
            $form->freeze('event_type');
102
            $form->addText('title', get_lang('Title'));
103
            $form->addTextarea('content', get_lang('Content'));
104
            $form->addText('link', get_lang('Link'), false);
105
            $form->addCheckBox('persistent', get_lang('Persistent'));
106
            $form->addNumeric('day_diff', get_lang('Time difference'), false);
107
108
            switch ($eventType) {
109
                case self::JUSTIFICATION_EXPIRATION:
110
                    $plugin = Justification::create();
111
                    $list = $plugin->getList();
112
                    $list = array_column($list, 'name', 'id');
113
                    $form->addSelect('event_id', get_lang('Justification type'), $list);
114
                    break;
115
                default:
116
                    break;
117
            }
118
            $form->addButtonSave(get_lang('Save'));
119
        }
120
121
        return $form;
122
    }
123
124
    /**
125
     * Get notification-related user's extra field value
126
     * @param int $userId
127
     * @return string
128
     */
129
    public function getUserExtraData(int $userId): string
130
    {
131
        $data = UserManager::get_extra_user_data_by_field($userId, $this->extraFieldName);
132
133
        return isset($data['notification_event']) ? $data['notification_event'] : '';
134
    }
135
136
    public function getNotificationsByUser($userId)
137
    {
138
        $userInfo = api_get_user_info($userId);
139
        $events = $this->get_all();
140
        $extraFieldData = $this->getUserExtraData(api_get_user_id());
141
        $allowJustification = 'true' === api_get_plugin_setting('justification', 'tool_enable');
142
143
        $userJustificationList = [];
144
        if ($allowJustification) {
145
            $plugin = Justification::create();
146
            $userJustificationList = $plugin->getUserJustificationList($userId);
147
        }
148
149
        $notifications = [];
150
        foreach ($events as $event) {
151
            $days = (int) $event['day_diff'];
152
            $checkIsRead = 0 == $event['persistent'] ? true : false;
153
            $eventItemId = $event['event_id'];
154
155
            switch ($event['event_type']) {
156
                case self::ACCOUNT_EXPIRATION:
157
                    if (empty($userInfo['expiration_date'])) {
158
                        break;
159
                    }
160
161
                    $id = 'id_'.self::ACCOUNT_EXPIRATION.'_event_'.$event['id'].'_'.$userInfo['id'];
162
163
                    $read = false;
164
                    if ($checkIsRead) {
165
                        $read = $this->isRead($id, $extraFieldData);
166
                    }
167
168
                    $showNotification = $this->showNotification($userInfo['expiration_date'], $days);
169
                    if ($showNotification && false === $read) {
170
                        $notifications[] = [
171
                            'id' => $id,
172
                            'title' => $event['title'],
173
                            'content' => $event['content'],
174
                            'event_text' => get_lang('ExpirationDate').': '.api_get_local_time($userInfo['expiration_date']),
175
                            'link' => $event['link'],
176
                            'persistent' => $event['persistent'],
177
                        ];
178
                    }
179
                    break;
180
                case self::JUSTIFICATION_EXPIRATION:
181
                    if (!empty($userJustificationList)) {
182
                        foreach ($userJustificationList as $userJustification) {
183
                            if (empty($userJustification['date_validity'])) {
184
                                continue;
185
                            }
186
187
                            if ($eventItemId != $userJustification['justification_document_id']) {
188
                                continue;
189
                            }
190
191
                            $showNotification = $this->showNotification($userJustification['date_validity'], $days);
192
193
                            $id = 'id_'.self::JUSTIFICATION_EXPIRATION.'_event_'.$event['id'].'_'.$userJustification['id'];
194
195
                            $fieldData = $plugin->getJustification($userJustification['justification_document_id']);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $plugin does not seem to be defined for all execution paths leading up to this point.
Loading history...
196
197
                            $read = false;
198
                            if ($checkIsRead) {
199
                                $read = $this->isRead($id, $extraFieldData);
200
                            }
201
202
                            $eventText = $plugin->get_lang('Justification').': '.$fieldData['name'].' <br />';
203
                            $eventText .= $plugin->get_lang('Justification expiration').': '.$userJustification['date_validity'];
204
205
                            $url = $event['link'];
206
                            if (empty($url)) {
207
                                $url = api_get_path(WEB_CODE_PATH).'auth/justification.php#'.$fieldData['code'];
208
                            }
209
210
                            if ($showNotification && false === $read) {
211
                                $notifications[] = [
212
                                    'id' => $id,
213
                                    'title' => $event['title'],
214
                                    'content' => $event['content'],
215
                                    'event_text' => $eventText,
216
                                    'link' => $url,
217
                                    'persistent' => $event['persistent'],
218
                                ];
219
                            }
220
                        }
221
                    }
222
                    break;
223
            }
224
        }
225
226
        return $notifications;
227
    }
228
229
    /**
230
     * Returns whether a notification has already been read by the user or not
231
     * @param int    $id
232
     * @param string $extraData
233
     * @return bool
234
     */
235
    public function isRead(int $id, string $extraData): bool
236
    {
237
        $userId = api_get_user_id();
238
239
        if (empty($extraData)) {
240
            return false;
241
        }
242
243
        $data = $this->getUserExtraData($userId);
244
        if (empty($data)) {
245
            return false;
246
        }
247
248
        $data = json_decode($data);
249
250
        if (in_array($id, $data)) {
251
            return true;
252
        }
253
254
        return false;
255
    }
256
257
    /**
258
     * Mark a notification as read by the user
259
     * @param int $id
260
     * @return bool
261
     */
262
    public function markAsRead(int $id): bool
263
    {
264
        if (empty($id)) {
265
            return false;
266
        }
267
        $userId = api_get_user_id();
268
        $data = $this->getUserExtraData($userId);
269
        if (!empty($data)) {
270
            $data = json_decode($data);
271
        } else {
272
            $data = [];
273
        }
274
        $data[] = $id;
275
        $data = json_encode($data);
276
277
        UserManager::update_extra_field_value($userId, $this->extraFieldName, $data);
278
279
        return true;
280
    }
281
282
    /**
283
     * Returns whether to show some notification or not based on dates
284
     * @param string $date
285
     * @param int $dayDiff
286
     * @return bool
287
     * @throws Exception
288
     */
289
    public function showNotification(string $date, int $dayDiff): bool
290
    {
291
        $today = api_get_utc_datetime();
292
        $dayDiff = (string) $dayDiff;
293
        $expiration = api_get_utc_datetime($date, false, true);
294
        $interval = new DateInterval('P'.$dayDiff.'D');
295
        $diff = $expiration->sub($interval);
296
297
        if ($diff->format('Y-m-d H:i:s') < $today) {
298
            return true;
299
        }
300
301
        return false;
302
    }
303
}
304