Passed
Push — master ( c22b6a...5f79f5 )
by Julito
11:21
created

PauseTraining::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 10
rs 10
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
class PauseTraining extends Plugin
6
{
7
    protected function __construct()
8
    {
9
        parent::__construct(
10
            '0.1',
11
            'Julio Montoya',
12
            [
13
                'tool_enable' => 'boolean',
14
                'allow_users_to_edit_pause_formation' => 'boolean',
15
                'cron_alert_users_if_inactive_days' => 'text', // Example: "5" or "5,10,15"
16
                'sender_id' => 'user',
17
            ]
18
        );
19
    }
20
21
    public static function create()
22
    {
23
        static $result = null;
24
25
        return $result ? $result : $result = new self();
26
    }
27
28
    public function updateUserPauseTraining($userId, $values)
29
    {
30
        $userInfo = api_get_user_info($userId);
31
        if (empty($userInfo)) {
32
            throw new Exception("User #$userId does not exists");
33
        }
34
35
        $variables = [
36
            'pause_formation',
37
            'start_pause_date',
38
            'end_pause_date',
39
            'disable_emails',
40
        ];
41
42
        $valuesToUpdate = [
43
            'item_id' => $userId,
44
        ];
45
46
        // Check if variables exist.
47
        foreach ($variables as $variable) {
48
            if (!isset($values[$variable])) {
49
                throw new Exception("Variable '$variable' is missing. Cannot updated.");
50
            }
51
52
            $valuesToUpdate['extra_'.$variable] = $values[$variable];
53
        }
54
55
        // Clean variables
56
        $pause = (int) $valuesToUpdate['extra_pause_formation'];
57
        if (empty($pause)) {
58
            $valuesToUpdate['extra_pause_formation'] = 0;
59
        } else {
60
            $valuesToUpdate['extra_pause_formation'] = [];
61
            $valuesToUpdate['extra_pause_formation']['extra_pause_formation'] = $pause;
62
        }
63
64
        $notification = (int) $valuesToUpdate['extra_disable_emails'];
65
        if (empty($notification)) {
66
            $valuesToUpdate['extra_disable_emails'] = 0;
67
        } else {
68
            $valuesToUpdate['extra_disable_emails'] = [];
69
            $valuesToUpdate['extra_disable_emails']['extra_disable_emails'] = $notification;
70
        }
71
72
        $check = DateTime::createFromFormat('Y-m-d H:i', $valuesToUpdate['extra_start_pause_date']);
73
74
        if (false === $check) {
75
            throw new Exception("start_pause_date is not valid date time format should be: Y-m-d H:i");
76
        }
77
78
        $check = DateTime::createFromFormat('Y-m-d H:i', $valuesToUpdate['extra_end_pause_date']);
79
        if (false === $check) {
80
            throw new Exception("end_pause_date is not valid date time format should be: Y-m-d H:i");
81
        }
82
83
        if (api_strtotime($valuesToUpdate['extra_start_pause_date']) > api_strtotime($valuesToUpdate['extra_end_pause_date'])) {
84
            throw new Exception("end_pause_date must be bigger than start_pause_date");
85
        }
86
87
        $extraField = new ExtraFieldValue('user');
88
        $extraField->saveFieldValues($valuesToUpdate, true, false, [], [], true);
89
90
        return (int) $userId;
91
    }
92
93
    public function runCron($date = '', $isTest = false)
94
    {
95
        $enable = $this->get('tool_enable');
96
        $senderId = $this->get('sender_id');
97
        $enableDays = $this->get('cron_alert_users_if_inactive_days');
98
99
        if ('true' !== $enable) {
100
            echo 'Plugin not enabled';
101
102
            return false;
103
        }
104
105
        if (empty($senderId)) {
106
            echo 'Sender id not configured';
107
108
            return false;
109
        }
110
111
        $senderInfo = api_get_user_info($senderId);
112
113
        if (empty($senderInfo)) {
114
            echo "Sender #$senderId not found in Chamilo";
115
116
            return false;
117
        }
118
119
        $enableDaysList = explode(',', $enableDays);
120
        rsort($enableDaysList);
121
122
        $track = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
123
        $login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
124
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
125
        $usersNotificationPerDay = [];
126
        $now = api_get_utc_datetime();
127
        if (!empty($date)) {
128
            $now = $date;
129
        }
130
131
        if ($isTest) {
132
            echo "-------------------------------------------".PHP_EOL;
133
            echo "----- Testing date $now ----".PHP_EOL;
134
            echo "-------------------------------------------".PHP_EOL;
135
        }
136
137
        $extraFieldValue = new ExtraFieldValue('user');
138
        $sql = "SELECT u.id
139
                FROM $userTable u
140
                WHERE u.status <> ".ANONYMOUS." AND u.active = 1";
141
        $rs = Database::query($sql);
142
143
        $users = [];
144
        while ($user = Database::fetch_array($rs)) {
145
            $userId = $user['id'];
146
147
            $sql = "SELECT
148
                        MAX(t.logout_course_date) max_course_date,
149
                        MAX(l.logout_date) max_login_date
150
                    FROM $userTable u
151
                    LEFT JOIN $track t
152
                    ON (u.id = t.user_id)
153
                    LEFT JOIN $login l
154
                    ON (u.id = l.login_user_id)
155
                    WHERE
156
                        u.id = $userId
157
                    LIMIT 1
158
                    ";
159
            $result = Database::query($sql);
160
            $data = Database::fetch_array($result);
161
            $maxCourseDate = '';
162
            $maxLoginDate = '';
163
164
            // Take max date value.
165
            if ($data) {
166
                $maxCourseDate = $data['max_course_date'];
167
                $maxLoginDate = $data['max_login_date'];
168
            }
169
170
            $maxEndPause = null;
171
            $pause = $extraFieldValue->get_values_by_handler_and_field_variable($userId, 'pause_formation');
172
            if (!empty($pause) && isset($pause['value']) && 1 == $pause['value']) {
173
                $endDate = $extraFieldValue->get_values_by_handler_and_field_variable(
174
                    $userId,
175
                    'end_pause_date'
176
                );
177
                if (!empty($endDate) && isset($endDate['value']) && !empty($endDate['value'])) {
178
                    $maxEndPause = $endDate['value'];
179
                }
180
            }
181
182
            $maxDate = $maxCourseDate;
183
            if ($maxLoginDate > $maxCourseDate) {
184
                $maxDate = $maxLoginDate;
185
            }
186
187
            if ($maxEndPause > $maxDate) {
188
                $maxDate = $maxEndPause;
189
            }
190
191
            if (empty($maxDate)) {
192
                // Nothing found for that user, skip.
193
                continue;
194
            }
195
            $users[$userId] = $maxDate;
196
        }
197
198
        $extraFieldValue = new ExtraFieldValue('user');
199
        foreach ($enableDaysList as $day) {
200
            $day = (int) $day;
201
202
            if (0 === $day) {
203
                echo 'Day = 0 avoided '.PHP_EOL;
204
                continue;
205
            }
206
            $dayToCheck = $day + 1;
207
            $hourStart = $dayToCheck * 24;
208
            $hourEnd = ($dayToCheck - 1) * 24;
209
210
            $date = new DateTime($now);
211
            $date->sub(new DateInterval('PT'.$hourStart.'H'));
212
            $hourStart = $date->format('Y-m-d H:i:s');
213
214
            $date = new DateTime($now);
215
            $date->sub(new DateInterval('PT'.$hourEnd.'H'));
216
            $hourEnd = $date->format('Y-m-d H:i:s');
217
218
            echo "Processing day $day: $hourStart - $hourEnd ".PHP_EOL.PHP_EOL;
219
220
            foreach ($users as $userId => $maxDate) {
221
                if (!($maxDate > $hourStart && $maxDate < $hourEnd)) {
222
                    //echo "Message skipped for user #$userId because max date found: $maxDate not in range $hourStart - $hourEnd ".PHP_EOL;
223
                    continue;
224
                }
225
226
                // Check if user has selected to pause formation.
227
                $pause = $extraFieldValue->get_values_by_handler_and_field_variable($userId, 'pause_formation');
228
                if (!empty($pause) && isset($pause['value']) && 1 == $pause['value']) {
229
                    $startDate = $extraFieldValue->get_values_by_handler_and_field_variable(
230
                        $userId,
231
                        'start_pause_date'
232
                    );
233
                    $endDate = $extraFieldValue->get_values_by_handler_and_field_variable(
234
                        $userId,
235
                        'end_pause_date'
236
                    );
237
238
                    if (
239
                        !empty($startDate) && isset($startDate['value']) && !empty($startDate['value']) &&
240
                        !empty($endDate) && isset($endDate['value']) && !empty($endDate['value'])
241
                    ) {
242
                        $startDate = $startDate['value'];
243
                        $endDate = $endDate['value'];
244
245
                        if ($startDate > $hourStart && $startDate < $hourStart) {
246
                            //echo "Message skipped for user #$userId because process date $hourStart is in start pause in $startDate - $endDate ".PHP_EOL;
247
                            continue;
248
                        }
249
250
                        if ($endDate > $hourEnd && $endDate < $hourEnd) {
251
                            //echo "Message skipped for user #$userId because process date $hourEnd is in start pause in $startDate - $endDate ".PHP_EOL;
252
                            continue;
253
                        }
254
                    }
255
                }
256
257
                echo "User #$userId added to message queue because latest login is $maxDate between $hourStart AND $hourEnd".PHP_EOL;
258
                $users[] = $userId;
259
                $usersNotificationPerDay[$day][] = $userId;
260
            }
261
        }
262
263
        if (!empty($usersNotificationPerDay)) {
264
            echo PHP_EOL.'Now processing messages ...'.PHP_EOL;
265
266
            ksort($usersNotificationPerDay);
267
            foreach ($usersNotificationPerDay as $day => $userList) {
268
                $template = new Template(
269
                    '',
270
                    true,
271
                    true,
272
                    false,
273
                    false,
274
                    true,
275
                    false
276
                );
277
                $title = sprintf($this->get_lang('InactivityXDays'), $day);
278
279
                foreach ($userList as $userId) {
280
                    $userInfo = api_get_user_info($userId);
281
                    $template->assign('days', $day);
282
                    $template->assign('user', $userInfo);
283
                    $content = $template->fetch('pausetraining/view/notification_content.tpl');
284
                    echo 'Ready to send a message "'.$title.'" to user #'.$userId.' '.$userInfo['complete_name'].PHP_EOL;
285
                    if (false === $isTest) {
286
                        MessageManager::send_message_simple($userId, $title, $content, $senderId);
287
                    } else {
288
                        echo 'Message not send because is in test mode.'.PHP_EOL;
289
                    }
290
                }
291
            }
292
        }
293
    }
294
295
    public function runCronTest()
296
    {
297
        $now = api_get_utc_datetime();
298
        $days = 15;
299
        $before = new DateTime($now);
300
        $before->sub(new DateInterval('P'.$days.'D'));
301
302
        $after = new DateTime($now);
303
        $after->add(new DateInterval('P'.$days.'D'));
304
305
        $period = new DatePeriod(
306
            $before,
307
            new DateInterval('P1D'),
308
            $after
309
        );
310
311
        foreach ($period as $key => $value) {
312
            self::runCron($value->format('Y-m-d H:i:s'), true);
313
        }
314
    }
315
316
    public function install()
317
    {
318
        UserManager::create_extra_field(
319
            'pause_formation',
320
            ExtraField::FIELD_TYPE_CHECKBOX,
321
            $this->get_lang('PauseFormation'),
322
            ''
323
        );
324
325
        UserManager::create_extra_field(
326
            'start_pause_date',
327
            ExtraField::FIELD_TYPE_DATETIME,
328
            $this->get_lang('StartPauseDateTime'),
329
            ''
330
        );
331
332
        UserManager::create_extra_field(
333
            'end_pause_date',
334
            ExtraField::FIELD_TYPE_DATETIME,
335
            $this->get_lang('EndPauseDateTime'),
336
            ''
337
        );
338
339
        UserManager::create_extra_field(
340
            'disable_emails',
341
            ExtraField::FIELD_TYPE_CHECKBOX,
342
            $this->get_lang('DisableEmails'),
343
            ''
344
        );
345
    }
346
347
    public function uninstall()
348
    {
349
    }
350
}
351