Passed
Push — 1.11.x ( 7afe6d...118e10 )
by Angel Fernando Quiroz
10:19
created

getCurrentTimeSlot()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 11
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 20
rs 9.9
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * New lp reminder.
6
 *
7
 * @package chamilo.cron
8
 *
9
 * @author  Carlos Alvarado <[email protected]>
10
 */
11
12
require_once __DIR__.'/../inc/global.inc.php';
13
14
// 24-hour format of an hour without leading zeros (in UTC timezone) to execute and search learning paths
15
$timeSlots = [
16
    7,
17
    16,
18
    20,
19
];
20
21
/**
22
 * Initialization.
23
 */
24
if ('cli' != php_sapi_name()) {
25
    exit; //do not run from browser
26
}
27
28
$field = new ExtraField('lp');
29
$activeMessageNewlp = $field->get_handler_field_info_by_field_variable('notify_student_and_hrm_when_available');
30
31
if ($activeMessageNewlp == false) {
32
    // field doesnt exist
33
    exit();
34
}
35
if (!isset($activeMessageNewlp['default_value'])) {
36
    // field dont have default value
37
    exit();
38
}
39
40
$currentHour = (int) api_get_utc_datetime(null, false, true)->format('G');
41
42
if (!in_array($currentHour, $timeSlots)) {
43
    exit("Execution nor allowed in this hour ($currentHour).");
44
}
45
46
/**
47
 * Send the message to the intended user, manage the corresponding template and send through
48
 * MessageManager::send_message_simple, using this for the option of human resources managers.
49
 *
50
 * @param array  $toUser
51
 * @param int    $fromUser
52
 * @param string $courseName
53
 * @param string $lpName
54
 * @param string $link
55
 *
56
 * @return bool|int
57
 */
58
function sendMessage(array $toUser, int $fromUser, string $courseName, string $lpName, string $link)
59
{
60
    $toUserId = $toUser['user_id'];
61
    $subjectTemplate = new Template(
62
        null,
63
        false,
64
        false,
65
        false,
66
        false,
67
        false
68
    );
69
70
    $subjectLayout = $subjectTemplate->get_template(
71
        'mail/learning_path_reminder_subject.tpl'
72
    );
73
74
    $bodyTemplate = new Template(
75
        null,
76
        false,
77
        false,
78
        false,
79
        false,
80
        false
81
    );
82
    $bodyTemplate->assign('courseName', $courseName);
83
    $bodyTemplate->assign('lpName', $lpName);
84
    $bodyTemplate->assign('link', $link);
85
86
    $bodyLayout = $bodyTemplate->get_template(
87
        'mail/learning_path_reminder_body.tpl'
88
    );
89
    $tittle = $subjectTemplate->fetch($subjectLayout);
90
    $content = $bodyTemplate->fetch($bodyLayout);
91
92
    return MessageManager::send_message_simple(
93
        $toUserId,
94
        $tittle,
95
        $content,
96
        $fromUser,
97
        true
98
    );
99
    // $drhList = UserManager::getDrhListFromUser($receiverUserId);
100
}
101
102
/**
103
 * Obtains the data of the learning path and course searched by the id of the LP.
104
 *
105
 * @param array $lpid
106
 *
107
 * @return array
108
 */
109
function getLpDataByArrayId(array $lpid = []): array
110
{
111
    if (count($lpid) == 0) {
112
        return [];
113
    }
114
    $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
115
    $lpTable = Database::get_course_table(TABLE_LP_MAIN);
116
    $sql = "SELECT
117
            tblCourse.title AS course_name,
118
            tblCourse.code AS code,
119
            tblLp.id AS lp_id,
120
            tblLp.c_id AS c_id,
121
            tblLp.name AS name
122
        FROM
123
            $lpTable AS tblLp
124
            INNER JOIN $tblCourse AS tblCourse ON tblLp.c_id = tblCourse.id
125
        WHERE
126
            tblLp.iid IN ( ".implode(',', $lpid)." )";
127
    $result = Database::query($sql);
128
    $return = [];
129
    while ($element = Database::fetch_array($result)) {
130
        $return[$element['lp_id']] = $element;
131
    }
132
133
    return $return;
134
}
135
136
/**
137
 * Returns the id of the LPs that have the notification option active through the extra
138
 * field 'notify_student_and_hrm_when_available'.
139
 */
140
function getLpIdWithNotify(): array
141
{
142
    $extraFieldValuesTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
143
    $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
144
    $sql = "SELECT
145
            tblExtraFieldValues.item_id as lp_id
146
        FROM
147
            $extraFieldValuesTable AS tblExtraFieldValues
148
        INNER JOIN $extraFieldTable AS tblExtraField ON (
149
            tblExtraFieldValues.field_id = tblExtraField.id AND
150
            tblExtraField.variable = 'notify_student_and_hrm_when_available'
151
            )
152
        where
153
              tblExtraFieldValues.value = 1";
154
    $result = Database::query($sql);
155
    $return = [];
156
    while ($element = Database::fetch_array($result)) {
157
        $return[] = $element['lp_id'];
158
    }
159
160
    return $return;
161
}
162
163
function getTutorIdFromCourseRelUser($cId = 0, $lpId = 0): int
164
{
165
    $lpTable = Database::get_course_table(TABLE_LP_MAIN);
166
    $tblCourseRelUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
167
    $sql = "SELECT DISTINCT
168
            tblCourseRelUser.user_id AS user_id
169
        FROM
170
            $lpTable AS tblLp
171
            INNER JOIN $tblCourseRelUser AS tblCourseRelUser ON ( tblCourseRelUser.c_id = tblLp.c_id)
172
        WHERE
173
            tblCourseRelUser.user_id  IS NOT NULL AND
174
            tblCourseRelUser.status = 1 AND
175
            tblLp.id = $lpId AND
176
            tblLp.c_id = $cId";
177
    $result = Database::query($sql);
178
    $data = Database::fetch_assoc($result);
179
180
    return (isset($data['user_id'])) ? (int) $data['user_id'] : 0;
181
}
182
183
function sendToArray(&$data, &$type, &$message, $lpId = 0)
184
{
185
    foreach ($data as $user) {
186
        $userName = $user['userInfo']['complete_name'];
187
        $userId = $user['userInfo']['user_id'];
188
        $fromUser = $user['fromUser'];
189
        $courseName = $user['courseName'];
190
        $lpName = $user['lpName'];
191
        $send = sendMessage(
192
            $user['userInfo'],
193
            $fromUser,
194
            $courseName,
195
            $lpName,
196
            $user['link']
197
        );
198
        $message .= "\n$type - Lp Id '$lpId' User Id '$userId' Sent to '$userName' Message id '$send' Lp name '$lpName'";
199
    }
200
}
201
202
function getCurrentTimeSlot(int $currentHour, array $timeSlots = []): ?array
203
{
204
    $index = array_search($currentHour, $timeSlots);
205
206
    if (false === $index){
207
        return null;
208
    }
209
210
    if (0 === $index) {
211
        $index = count($timeSlots) - 1;
212
    } else {
213
        $index--;
214
    }
215
216
    $startHour = $timeSlots[$index];
217
218
    $startDate = api_get_utc_datetime(null, false, true)->modify("yesterday $startHour:00");
219
    $endDate = api_get_utc_datetime(null, false, true)->modify("today $currentHour:00");
220
221
    return [$startDate, $endDate];
222
}
223
224
function learningPaths(int $currentHour, array $timeSlots = [])
225
{
226
    $lpItems = getLpIdWithNotify();
227
    if (count($lpItems) == 0) {
228
        return null;
229
    }
230
231
    [$startDate, $endDate] = getCurrentTimeSlot($currentHour, $timeSlots);
232
233
    $tutors = [];
234
    $lpItemsString = implode(',', $lpItems);
235
    $lpsData = getLpDataByArrayId($lpItems);
236
    $itemProcessed = [];
237
    $lpTable = Database::get_course_table(TABLE_LP_MAIN);
238
    $tblCourseRelUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
239
    $tblSessionCourseUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
240
    $tblItempProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
241
    /* Gets subscribed users individually in lp's by LearnpathSubscription */
242
    $sql = "SELECT DISTINCT
243
            tblItemProperty.session_id as session_id,
244
            tblItemProperty.to_user_id as user_id,
245
            tblItemProperty.insert_user_id as from_user_id,
246
            tblLp.id AS lp_id,
247
            tblItemProperty.lastedit_type
248
        FROM
249
            $tblItempProperty as tblItemProperty
250
            INNER JOIN $lpTable as tblLp ON
251
                (
252
                    tblLp.iid = tblItemProperty.ref AND
253
                    tblItemProperty.lastedit_type = 'LearnpathSubscription'
254
                )
255
        WHERE
256
            publicated_on < '".$endDate->format('Y-m-d H:i:s')."' AND
257
            publicated_on >= '".$startDate->format('Y-m-d H:i:s')."' AND
258
            tblItemProperty.to_user_id IS NOT NULL AND
259
            tblLp.id in ($lpItemsString)";
260
    $result = Database::query($sql);
261
    $groupUsers = [];
262
263
    while ($row = Database::fetch_array($result)) {
264
        $lpId = (int) $row['lp_id'];
265
        $lpData = [];
266
        if (isset($lpsData[$lpId])) {
267
            $lpData = $lpsData[$lpId];
268
        }
269
        $courseName = $lpData['course_name'] ?? null;
270
        $courseCode = $lpData['code'] ?? null;
271
        $lpName = $lpData['name'] ?? null;
272
273
        $sessionId = (int) $row['session_id'];
274
        $toUser = (int) $row['user_id'];
275
        $fromUser = (int) $row['from_user_id'];
276
        $userInfo = api_get_user_info($toUser);
277
        $href = api_get_path(WEB_CODE_PATH).
278
            'lp/lp_controller.php?cidReq='.htmlspecialchars($courseCode).
279
            "&id_session=$sessionId &action=view&lp_id=$lpId&gidReq=0&gradebook=0&origin=";
280
        $link = "<a href='$href'>$href</a>";
281
        $groupUsers[$lpId][$sessionId][$toUser] = [
282
            'userInfo' => $userInfo,
283
            'fromUser' => $fromUser,
284
            'courseName' => $courseName,
285
            'lpName' => $lpName,
286
            'link' => $link,
287
        ];
288
        $itemProcessed[$lpId][$sessionId]['LearnpathSubscription'][$toUser] = $groupUsers[$lpId][$sessionId][$toUser];
289
    }
290
    /* Gets subscribed users by classes in lp's by LearnpathSubscription */
291
    $sql = "SELECT DISTINCT
292
             tblItemProperty.session_id as session_id,
293
            tblItemProperty.to_group_id as group_id,
294
            tblUsergroupRelUser.user_id as user_id,
295
            tblItemProperty.insert_user_id as from_user_id,
296
            tblLp.id AS lp_id,
297
            tblItemProperty.lastedit_type
298
        FROM
299
            $tblItempProperty as tblItemProperty
300
            INNER JOIN $lpTable as tblLp ON
301
                (
302
                    tblLp.iid = tblItemProperty.ref AND
303
                    tblItemProperty.lastedit_type = 'LearnpathSubscription'
304
                )
305
        INNER JOIN usergroup_rel_user as tblUsergroupRelUser on (
306
            tblItemProperty.to_group_id = tblUsergroupRelUser.usergroup_id
307
            )
308
        WHERE
309
            publicated_on < '".$endDate->format('Y-m-d H:i:s')."' AND
310
            publicated_on >= '".$startDate->format('Y-m-d H:i:s')."' AND
311
            tblItemProperty.to_group_id IS NOT NULL AND
312
            tblLp.id in ($lpItemsString)";
313
    $result = Database::query($sql);
314
    $groupUsers = [];
315
    while ($row = Database::fetch_array($result)) {
316
        $lpId = (int) $row['lp_id'];
317
        $lpData = [];
318
        if (isset($lpsData[$lpId])) {
319
            $lpData = $lpsData[$lpId];
320
        }
321
        $courseName = $lpData['course_name'] ?? null;
322
        $courseCode = $lpData['code'] ?? null;
323
        $lpName = $lpData['name'] ?? null;
324
325
        $sessionId = (int) $row['session_id'];
326
        $toUser = (int) $row['user_id'];
327
        $fromUser = (int) $row['from_user_id'];
328
        $userInfo = api_get_user_info($toUser);
329
        $href = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'
330
            .api_get_cidreq_params($courseCode, $sessionId).'&'
331
            .http_build_query(
332
                [
333
                    'gradebook' => '0',
334
                    'origin' => '',
335
                    'lp_id' => $lpId,
336
                    'action' => 'view',
337
                ]
338
            );
339
        $link = "<a href='$href'>$href</a>";
340
        $groupUsers[$lpId][$sessionId][$toUser] = [
341
            'userInfo' => $userInfo,
342
            'fromUser' => $fromUser,
343
            'courseName' => $courseName,
344
            'lpName' => $lpName,
345
            'link' => $link,
346
        ];
347
        $itemProcessed[$lpId][$sessionId]['LearnpathSubscription'][$toUser] = $groupUsers[$lpId][$sessionId][$toUser];
348
    }
349
    /* Get users who are enrolled in the course */
350
351
    $sql = "SELECT DISTINCT
352
            tblCourseRelUser.user_id AS user_id,
353
            tblLp.id AS lp_id,
354
            tblLp.c_id AS c_id
355
        FROM
356
            $lpTable AS tblLp
357
            INNER JOIN $tblCourseRelUser AS tblCourseRelUser ON ( tblCourseRelUser.c_id = tblLp.c_id)
358
        WHERE
359
            publicated_on < '".$endDate->format('Y-m-d H:i:s')."' AND
360
            publicated_on >= '".$startDate->format('Y-m-d H:i:s')."' AND
361
            tblCourseRelUser.user_id  IS NOT NULL AND
362
            tblCourseRelUser.status = 5 AND
363
            tblLp.id in ($lpItemsString)";
364
365
    $result = Database::query($sql);
366
    while ($row = Database::fetch_array($result)) {
367
        $lpId = (int) $row['lp_id'];
368
        $sessionId = 0;
369
        if (isset($lpsData[$lpId])) {
370
            $lpData = $lpsData[$lpId];
371
        }
372
        if (!isset($tutors[$row['c_id']][$row['lp_id']])) {
373
            $tutors[$row['c_id']][$row['lp_id']] = getTutorIdFromCourseRelUser($row['c_id'], $row['lp_id']);
374
        }
375
        $courseName = $lpData['course_name'] ?? null;
376
        $courseCode = $lpData['code'] ?? null;
377
        $lpName = $lpData['name'] ?? null;
378
        $toUser = (int) $row['user_id'];
379
        $fromUser = $tutors[$row['c_id']][$row['lp_id']];
380
        $userInfo = api_get_user_info($toUser);
381
        $href = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'
382
            .api_get_cidreq_params($courseCode, $sessionId).'&'
383
            .http_build_query(
384
                [
385
                    'gradebook' => '0',
386
                    'origin' => '',
387
                    'lp_id' => $lpId,
388
                    'action' => 'view',
389
                ]
390
            );
391
        $link = "<a href='$href'>$href</a>";
392
        if (!isset($itemProcessed[$lpId][$sessionId]['LearnpathSubscription'])) {
393
            $groupUsers[$lpId][$sessionId][$toUser] = [
394
                'userInfo' => $userInfo,
395
                'fromUser' => $fromUser,
396
                'courseName' => $courseName,
397
                'lpName' => $lpName,
398
                'link' => $link,
399
            ];
400
            $itemProcessed[$lpId][$sessionId]['NoLpSubscription'][$toUser] = $groupUsers[$lpId][$sessionId][$toUser];
401
        }
402
    }
403
    /** Get the users who are registered in the sessions */
404
    $sql = "SELECT DISTINCT
405
            tblSessionRelCourseRelUser.user_id AS user_id,
406
            tblLp.id AS lp_id,
407
            tblSessionRelCourseRelUser.session_id AS session_id,
408
            tblLp.c_id AS c_id,
409
            tblSessionRelCourseRelUser.status AS status
410
        FROM
411
            $lpTable AS tblLp
412
            INNER JOIN $tblSessionCourseUser AS tblSessionRelCourseRelUser ON (
413
                tblSessionRelCourseRelUser.c_id = tblLp.c_id)
414
        WHERE
415
            publicated_on < '".$endDate->format('Y-m-d H:i:s')."' AND
416
            publicated_on >= '".$startDate->format('Y-m-d H:i:s')."' AND
417
            tblSessionRelCourseRelUser.user_id  IS NOT NULL AND
418
            tblLp.id in ($lpItemsString) AND
419
            tblSessionRelCourseRelUser.status = 0
420
        ORDER BY tblSessionRelCourseRelUser.status";
421
    $result = Database::query($sql);
422
    while ($row = Database::fetch_array($result)) {
423
        $lpId = (int) $row['lp_id'];
424
        $sessionId = 0;
425
        if (isset($lpsData[$lpId])) {
426
            $lpData = $lpsData[$lpId];
427
        }
428
        $courseName = $lpData['course_name'] ?? null;
429
        $courseCode = $lpData['code'] ?? null;
430
        $lpName = $lpData['name'] ?? null;
431
        $toUser = (int) $row['user_id'];
432
        if (!isset($tutors[$row['c_id']][$row['lp_id']])) {
433
            $tutors[$row['c_id']][$row['lp_id']] = getTutorIdFromCourseRelUser($row['c_id'], $row['lp_id']);
434
        }
435
        $fromUser = $tutors[$row['c_id']][$row['lp_id']];
436
        $userInfo = api_get_user_info($toUser);
437
        $href = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'
438
            .api_get_cidreq_params($courseCode, $sessionId).'&'
439
            .http_build_query(
440
                [
441
                    'gradebook' => '0',
442
                    'origin' => '',
443
                    'lp_id' => $lpId,
444
                    'action' => 'view',
445
                ]
446
            );
447
        $link = "<a href='$href'>$href</a>";
448
        if (!isset($itemProcessed[$lpId][$sessionId]['LearnpathSubscription'])) {
449
            $groupUsers[$lpId][$sessionId][$toUser] = [
450
                'userInfo' => $userInfo,
451
                'fromUser' => $fromUser,
452
                'courseName' => $courseName,
453
                'lpName' => $lpName,
454
                'link' => $link,
455
            ];
456
            $itemProcessed[$lpId][$sessionId]['NoLpSubscription'][$toUser] = $groupUsers[$lpId][$sessionId][$toUser];
457
        }
458
    }
459
460
    /**
461
     * Send the emails to the corresponding students and their DRHs, Bearing in mind that if they exist through
462
     * LearnpathSubscription, it will not send anything in the other elements.
463
     */
464
    $message = '';
465
    foreach ($itemProcessed as $lpId => $sessions) {
466
        foreach ($sessions as $sessionId => $types) {
467
            foreach ($types as $type => $users) {
468
                if ('LearnpathSubscription' == $type) {
469
                    sendToArray($users, $type, $message, $lpId);
470
                } elseif (!isset($itemProcessed[$lpId][$sessionId]['LearnpathSubscription'])) {
471
                    sendToArray($users, $type, $message, $lpId);
472
                }
473
            }
474
        }
475
    }
476
    echo "$message\n\n";
477
}
478
479
learningPaths($currentHour, $timeSlots);
480
481
exit();
482