Passed
Push — 1.11.x ( bce6cd...c146d9 )
by Angel Fernando Quiroz
12:25
created

src/AdvancedSubscriptionPlugin.php (2 issues)

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class AdvancedSubscriptionPlugin
6
 * This class is used to add an advanced subscription allowing the admin to
7
 * create user queues requesting a subscribe to a session.
8
 *
9
 * @package chamilo.plugin.advanced_subscription
10
 */
11
class AdvancedSubscriptionPlugin extends Plugin implements HookPluginInterface
12
{
13
    protected $strings;
14
    private $errorMessages;
15
16
    /**
17
     * Constructor.
18
     */
19
    public function __construct()
20
    {
21
        $parameters = [
22
            'yearly_cost_limit' => 'text',
23
            'yearly_hours_limit' => 'text',
24
            'yearly_cost_unit_converter' => 'text',
25
            'courses_count_limit' => 'text',
26
            'course_session_credit_year_start_date' => 'text',
27
            'ws_url' => 'text',
28
            'min_profile_percentage' => 'text',
29
            'check_induction' => 'boolean',
30
            'secret_key' => 'text',
31
            'terms_and_conditions' => 'wysiwyg',
32
        ];
33
34
        parent::__construct('1.0', 'Imanol Losada, Daniel Barreto', $parameters);
35
        $this->errorMessages = [];
36
    }
37
38
    /**
39
     * Instance the plugin.
40
     *
41
     * @staticvar null $result
42
     *
43
     * @return AdvancedSubscriptionPlugin
44
     */
45
    public static function create()
46
    {
47
        static $result = null;
48
49
        return $result ? $result : $result = new self();
50
    }
51
52
    /**
53
     * Install the plugin.
54
     */
55
    public function install()
56
    {
57
        $this->installDatabase();
58
        $this->addAreaField();
59
        $this->installHook();
60
    }
61
62
    /**
63
     * Uninstall the plugin.
64
     */
65
    public function uninstall()
66
    {
67
        $setting = api_get_setting('advanced_subscription');
68
        if (!empty($setting)) {
69
            $this->uninstallHook();
70
            // Note: Keeping area field data is intended so it will not be removed
71
            $this->uninstallDatabase();
72
        }
73
    }
74
75
    /**
76
     * Get the error messages list.
77
     *
78
     * @return array The message list
79
     */
80
    public function getErrorMessages()
81
    {
82
        return $this->errorMessages;
83
    }
84
85
    /**
86
     * Check if is allowed subscribe to open session.
87
     *
88
     * @param array $params WS params
89
     *
90
     * @return bool
91
     */
92
    public function isAllowedSubscribeToOpenSession($params)
93
    {
94
        $self = self::create();
95
        $wsUrl = $self->get('ws_url');
96
        $profileCompleted = 0;
97
        if (!empty($wsUrl)) {
98
            $client = new SoapClient(
99
                null,
100
                ['location' => $wsUrl, 'uri' => $wsUrl]
101
            );
102
            $userInfo = api_get_user_info(
103
                $params['user_id'],
104
                false,
105
                false,
106
                true
107
            );
108
109
            try {
110
                $profileCompleted = $client->__soapCall(
111
                    'getProfileCompletionPercentage',
112
                    $userInfo['extra']['drupal_user_id']
113
                );
114
            } catch (\Exception $e) {
115
                $profileCompleted = 0;
116
            }
117
        } elseif (isset($params['profile_completed'])) {
118
            $profileCompleted = (float) $params['profile_completed'];
119
        }
120
        $profileCompletedMin = (float) $self->get('min_profile_percentage');
121
122
        if ($profileCompleted < $profileCompletedMin) {
123
            $this->errorMessages[] = sprintf(
124
                $this->get_lang('AdvancedSubscriptionProfileIncomplete'),
125
                $profileCompletedMin,
126
                $profileCompleted
127
            );
128
        }
129
130
        $vacancy = $self->getVacancy($params['session_id']);
131
        $sessionInfo = api_get_session_info($params['session_id']);
132
133
        if ($sessionInfo['nbr_users'] >= $vacancy) {
134
            $this->errorMessages[] = sprintf(
135
                $this->get_lang('SessionXWithoutVacancies'),
136
                $sessionInfo['name']
137
            );
138
        }
139
140
        return empty($this->errorMessages);
141
    }
142
143
    /**
144
     * Return true if user is allowed to be added to queue for session subscription.
145
     *
146
     * @param int   $userId
147
     * @param array $params        MUST have keys:
148
     *                             "is_connected" Indicate if the user is online on external web
149
     *                             "profile_completed" Percentage of completed profile, given by WS
150
     * @param bool  $collectErrors Optional. Default is false. Whether collect all errors or throw exeptions
151
     *
152
     * @throws Exception
153
     *
154
     * @return bool
155
     */
156
    public function isAllowedToDoRequest($userId, $params = [], $collectErrors = false)
157
    {
158
        $plugin = self::create();
159
        $wsUrl = $plugin->get('ws_url');
160
        // Student always is connected
161
        $isConnected = true;
162
163
        if (!$isConnected) {
164
            $this->errorMessages[] = $this->get_lang('AdvancedSubscriptionNotConnected');
165
166
            if (!$collectErrors) {
167
                throw new \Exception($this->get_lang('AdvancedSubscriptionNotConnected'));
168
            }
169
        }
170
171
        $profileCompletedMin = (float) $plugin->get('min_profile_percentage');
172
        $profileCompleted = 0;
173
174
        if (is_string($wsUrl) && !empty($wsUrl)) {
175
            $options = [
176
                'location' => $wsUrl,
177
                'uri' => $wsUrl,
178
            ];
179
            $client = new SoapClient(null, $options);
180
            $userInfo = api_get_user_info($userId);
181
            try {
182
                $profileCompleted = $client->__soapCall('getProfileCompletionPercentage', $userInfo['extra']['drupal_user_id']);
183
            } catch (\Exception $e) {
184
                $profileCompleted = 0;
185
            }
186
        } elseif (isset($params['profile_completed'])) {
187
            $profileCompleted = (float) $params['profile_completed'];
188
        }
189
190
        if ($profileCompleted < $profileCompletedMin) {
191
            $errorMessage = sprintf(
192
                $this->get_lang('AdvancedSubscriptionProfileIncomplete'),
193
                $profileCompletedMin,
194
                $profileCompleted
195
            );
196
197
            $this->errorMessages[] = $errorMessage;
198
199
            if (!$collectErrors) {
200
                throw new \Exception($errorMessage);
201
            }
202
        }
203
204
        $yearlyCostLimit = $plugin->get('yearly_cost_limit');
205
        $maxCost = $plugin->get('yearly_cost_unit_converter');
206
        $maxCost *= $yearlyCostLimit;
207
        $userCost = 0;
208
        $now = new DateTime(api_get_utc_datetime());
209
        $newYearDate = $plugin->get('course_session_credit_year_start_date');
210
        $newYearDate = !empty($newYearDate) ?
211
            new \DateTime($newYearDate.$now->format('/Y')) : $now;
212
        $extra = new ExtraFieldValue('session');
213
        $joinSessionTable = Database::get_main_table(TABLE_MAIN_SESSION_USER).' su INNER JOIN '.
214
            Database::get_main_table(TABLE_MAIN_SESSION).' s ON s.id = su.session_id';
215
        $whereSessionParams = 'su.relation_type = ? AND s.access_start_date >= ? AND su.user_id = ?';
216
        $whereSessionParamsValues = [
217
            0,
218
            $newYearDate->format('Y-m-d'),
219
            $userId,
220
        ];
221
        $whereSession = [
222
            'where' => [
223
                $whereSessionParams => $whereSessionParamsValues,
224
            ],
225
        ];
226
        $selectSession = 's.id AS id';
227
        $sessions = Database::select(
228
            $selectSession,
229
            $joinSessionTable,
230
            $whereSession
231
        );
232
233
        $expendedTimeMax = $plugin->get('yearly_hours_limit');
234
        $expendedTime = 0;
235
236
        if (is_array($sessions) && count($sessions) > 0) {
237
            foreach ($sessions as $session) {
238
                $costField = $extra->get_values_by_handler_and_field_variable($session['id'], 'cost');
239
                $userCost += $costField['value'];
240
                $teachingHoursField = $extra->get_values_by_handler_and_field_variable($session['id'], 'teaching_hours');
241
                $expendedTime += $teachingHoursField['value'];
242
            }
243
        }
244
245
        if (isset($params['sessionId'])) {
246
            $costField = $extra->get_values_by_handler_and_field_variable($params['sessionId'], 'cost');
247
            $userCost += $costField['value'];
248
249
            $teachingHoursField = $extra->get_values_by_handler_and_field_variable($params['sessionId'], 'teaching_hours');
250
            $expendedTime += $teachingHoursField['value'];
251
        }
252
253
        if ($maxCost <= $userCost) {
254
            $errorMessage = sprintf(
255
                $this->get_lang('AdvancedSubscriptionCostXLimitReached'),
256
                $yearlyCostLimit
257
            );
258
259
            $this->errorMessages[] = $errorMessage;
260
261
            if (!$collectErrors) {
262
                throw new \Exception($errorMessage);
263
            }
264
        }
265
266
        if ($expendedTimeMax <= $expendedTime) {
267
            $errorMessage = sprintf(
268
                $this->get_lang('AdvancedSubscriptionTimeXLimitReached'),
269
                $expendedTimeMax
270
            );
271
272
            $this->errorMessages[] = $errorMessage;
273
274
            if (!$collectErrors) {
275
                throw new \Exception($errorMessage);
276
            }
277
        }
278
279
        $expendedNumMax = $plugin->get('courses_count_limit');
280
        $expendedNum = count($sessions);
281
282
        if ($expendedNumMax <= $expendedNum) {
283
            $errorMessage = sprintf(
284
                $this->get_lang('AdvancedSubscriptionCourseXLimitReached'),
285
                $expendedNumMax
286
            );
287
288
            $this->errorMessages[] = $errorMessage;
289
290
            if (!$collectErrors) {
291
                throw new \Exception($errorMessage);
292
            }
293
        }
294
295
        $checkInduction = $plugin->get('check_induction');
296
        $numberOfApprovedInductionSessions = $this->getApprovedInductionSessions($userId);
297
        $completedInduction = $numberOfApprovedInductionSessions > 0;
298
299
        if ($checkInduction == 'true' && !$completedInduction) {
300
            $this->errorMessages[] = $this->get_lang('AdvancedSubscriptionIncompleteInduction');
301
302
            if (!$collectErrors) {
303
                throw new \Exception($this->get_lang('AdvancedSubscriptionIncompleteInduction'));
304
            }
305
        }
306
307
        return empty($this->errorMessages);
308
    }
309
310
    /**
311
     * Register a user into a queue for a session.
312
     *
313
     * @param $userId
314
     * @param $sessionId
315
     *
316
     * @return bool|int
317
     */
318
    public function addToQueue($userId, $sessionId)
319
    {
320
        // Filter input variables
321
        $userId = intval($userId);
322
        $sessionId = intval($sessionId);
323
        $now = api_get_utc_datetime();
324
        $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
325
        $attributes = [
326
            'session_id' => $sessionId,
327
            'user_id' => $userId,
328
            'status' => 0,
329
            'created_at' => $now,
330
            'updated_at' => null,
331
        ];
332
333
        $id = Database::insert($advancedSubscriptionQueueTable, $attributes);
334
335
        return $id;
336
    }
337
338
    /**
339
     * Register message with type and status.
340
     *
341
     * @param $mailId
342
     * @param $userId
343
     * @param $sessionId
344
     *
345
     * @return bool|int
346
     */
347
    public function saveLastMessage($mailId, $userId, $sessionId)
348
    {
349
        // Filter variables
350
        $mailId = intval($mailId);
351
        $userId = intval($userId);
352
        $sessionId = intval($sessionId);
353
        $queueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
354
        $attributes = [
355
            'last_message_id' => $mailId,
356
            'updated_at' => api_get_utc_datetime(),
357
        ];
358
359
        $num = Database::update(
360
            $queueTable,
361
            $attributes,
362
            ['user_id = ? AND session_id = ?' => [$userId, $sessionId]]
363
        );
364
365
        return $num;
366
    }
367
368
    /**
369
     * Check for requirements and register user into queue.
370
     *
371
     * @param $userId
372
     * @param $sessionId
373
     * @param $params
374
     *
375
     * @return bool|string
376
     */
377
    public function startSubscription($userId, $sessionId, $params)
378
    {
379
        $result = 'Params not found';
380
        if (!empty($sessionId) && !empty($userId)) {
381
            $plugin = self::create();
382
            try {
383
                if ($plugin->isAllowedToDoRequest($userId, $params)) {
384
                    $result = (bool) $plugin->addToQueue($userId, $sessionId);
385
                } else {
386
                    throw new \Exception($this->get_lang('AdvancedSubscriptionNotMoreAble'));
387
                }
388
            } catch (Exception $e) {
389
                $result = $e->getMessage();
390
            }
391
        }
392
393
        return $result;
394
    }
395
396
    /**
397
     * Send message for the student subscription approval to a specific session.
398
     *
399
     * @param int|array $studentId
400
     * @param int       $receiverId
401
     * @param string    $subject
402
     * @param string    $content
403
     * @param int       $sessionId
404
     * @param bool      $save
405
     * @param array     $fileAttachments
406
     *
407
     * @return bool|int
408
     */
409
    public function sendMailMessage(
410
        $studentId,
411
        $receiverId,
412
        $subject,
413
        $content,
414
        $sessionId,
415
        $save = false,
416
        $fileAttachments = []
417
    ) {
418
        if (!empty($fileAttachments) &&
419
            is_array($fileAttachments) &&
420
            isset($fileAttachments['files']) &&
421
            isset($fileAttachments['comments'])
422
        ) {
423
            $mailId = MessageManager::send_message(
424
                $receiverId,
425
                $subject,
426
                $content,
427
                $fileAttachments['files'],
428
                $fileAttachments['comments']
429
            );
430
        } else {
431
            $mailId = MessageManager::send_message(
432
                $receiverId,
433
                $subject,
434
                $content
435
            );
436
        }
437
438
        if ($save && !empty($mailId)) {
439
            // Save as sent message
440
            if (is_array($studentId) && !empty($studentId)) {
441
                foreach ($studentId as $student) {
442
                    $this->saveLastMessage($mailId, $student['user_id'], $sessionId);
443
                }
444
            } else {
445
                $studentId = intval($studentId);
446
                $this->saveLastMessage($mailId, $studentId, $sessionId);
447
            }
448
        } elseif (!empty($mailId)) {
449
            // Update queue row, updated_at
450
            Database::update(
451
                Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE),
452
                [
453
                    'updated_at' => api_get_utc_datetime(),
454
                ],
455
                [
456
                    'user_id = ? AND session_id = ?' => [$studentId, $sessionId],
457
                ]
458
            );
459
        }
460
461
        return $mailId;
462
    }
463
464
    /**
465
     * Check if session is open for subscription.
466
     *
467
     * @param $sessionId
468
     * @param string $fieldVariable
469
     *
470
     * @return bool
471
     */
472
    public function isSessionOpen($sessionId, $fieldVariable = 'is_open_session')
473
    {
474
        $extraFieldValue = new ExtraFieldValue('session');
475
        $result = $extraFieldValue->get_values_by_handler_and_field_variable(
476
            $sessionId,
477
            $fieldVariable
478
        );
479
480
        $isOpen = false;
481
        if (!empty($result)) {
482
            $isOpen = (bool) $result['value'];
483
        }
484
485
        return $isOpen;
486
    }
487
488
    /**
489
     * Check if user is in the session's target group based on its area.
490
     *
491
     * @param $userId
492
     * @param $sessionId
493
     * @param string $userFieldVariable
494
     * @param string $sessionFieldVariable
495
     *
496
     * @return bool
497
     */
498
    public function isUserInTargetGroup(
499
        $userId,
500
        $sessionId,
501
        $userFieldVariable = 'area',
502
        $sessionFieldVariable = 'target'
503
    ) {
504
        $extraSessionFieldValue = new ExtraFieldValue('session');
505
        $sessionTarget = $extraSessionFieldValue->get_values_by_handler_and_field_variable(
506
            $sessionId,
507
            $sessionFieldVariable
508
        );
509
        $extraUserFieldValue = new ExtraFieldValue('user');
510
        $userArea = $extraUserFieldValue->get_values_by_handler_and_field_variable(
511
            $userId,
512
            $userFieldVariable
513
        );
514
        $isInTargetGroup = false;
515
        if (isset($sessionTarget) && (!empty($sessionTarget)) && $sessionTarget['value'] == 'minedu') {
516
            if (substr($userArea['value'], 0, 6) == 'MINEDU') {
517
                $isInTargetGroup = true;
518
            }
519
        }
520
        if (isset($sessionTarget) && (!empty($sessionTarget)) && $sessionTarget['value'] == 'regiones') {
521
            if ((substr($userArea['value'], 0, 4) == 'UGEL') || (substr($userArea['value'], 0, 3) == 'DRE')) {
522
                $isInTargetGroup = true;
523
            }
524
        }
525
526
        return $isInTargetGroup;
527
    }
528
529
    /**
530
     * Update the queue status for subscription approval rejected or accepted.
531
     *
532
     * @param $params
533
     * @param $newStatus
534
     *
535
     * @return bool
536
     */
537
    public function updateQueueStatus($params, $newStatus)
538
    {
539
        $newStatus = intval($newStatus);
540
        $res = false;
541
542
        if (isset($params['queue']['id'])) {
543
            $where = [
544
                'id = ?' => intval($params['queue']['id']),
545
            ];
546
        } elseif (isset($params['studentUserId']) && isset($params['sessionId'])) {
547
            $where = [
548
                'user_id = ? AND session_id = ? AND status <> ? AND status <> ?' => [
549
                    intval($params['studentUserId']),
550
                    intval($params['sessionId']),
551
                    $newStatus,
552
                    ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED,
553
                ],
554
            ];
555
        }
556
        if (isset($where)) {
557
            $res = (bool) Database::update(
558
                Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE),
559
                [
560
                    'status' => $newStatus,
561
                    'updated_at' => api_get_utc_datetime(),
562
                ],
563
                $where
564
            );
565
        }
566
567
        return $res;
568
    }
569
570
    /**
571
     * Render and send mail by defined advanced subscription action.
572
     *
573
     * @param $data
574
     * @param $actionType
575
     *
576
     * @return array
577
     */
578
    public function sendMail($data, $actionType)
579
    {
580
        $template = new Template($this->get_lang('plugin_title'));
581
        $template->assign('data', $data);
582
        $templateParams = [
583
            'user',
584
            'student',
585
            'students',
586
            'superior',
587
            'admins',
588
            'session',
589
            'signature',
590
            'admin_view_url',
591
            'acceptUrl',
592
            'rejectUrl',
593
        ];
594
        foreach ($templateParams as $templateParam) {
595
            $template->assign($templateParam, $data[$templateParam]);
596
        }
597
        $mailIds = [];
598
        switch ($actionType) {
599
            case ADVANCED_SUBSCRIPTION_ACTION_STUDENT_REQUEST:
600
                // Mail to student
601
                $mailIds['render'] = $this->sendMailMessage(
602
                    $data['studentUserId'],
603
                    $data['student']['user_id'],
604
                    $this->get_lang('MailStudentRequest'),
605
                    $template->fetch('/advanced_subscription/views/student_notice_student.tpl'),
606
                    $data['sessionId'],
607
                    true
608
                );
609
                // Mail to superior
610
                $mailIds[] = $this->sendMailMessage(
611
                    $data['studentUserId'],
612
                    $data['superior']['user_id'],
613
                    $this->get_lang('MailStudentRequest'),
614
                    $template->fetch('/advanced_subscription/views/student_notice_superior.tpl'),
615
                    $data['sessionId']
616
                );
617
                break;
618
            case ADVANCED_SUBSCRIPTION_ACTION_SUPERIOR_APPROVE:
619
                // Mail to student
620
                $mailIds[] = $this->sendMailMessage(
621
                    $data['studentUserId'],
622
                    $data['student']['user_id'],
623
                    $this->get_lang('MailBossAccept'),
624
                    $template->fetch('/advanced_subscription/views/superior_accepted_notice_student.tpl'),
625
                    $data['sessionId'],
626
                    true
627
                );
628
                // Mail to superior
629
                $mailIds['render'] = $this->sendMailMessage(
630
                    $data['studentUserId'],
631
                    $data['superior']['user_id'],
632
                    $this->get_lang('MailBossAccept'),
633
                    $template->fetch('/advanced_subscription/views/superior_accepted_notice_superior.tpl'),
634
                    $data['sessionId']
635
                );
636
                // Mail to admin
637
                foreach ($data['admins'] as $adminId => $admin) {
638
                    $template->assign('admin', $admin);
639
                    $mailIds[] = $this->sendMailMessage(
640
                        $data['studentUserId'],
641
                        $adminId,
642
                        $this->get_lang('MailBossAccept'),
643
                        $template->fetch('/advanced_subscription/views/superior_accepted_notice_admin.tpl'),
644
                        $data['sessionId']
645
                    );
646
                }
647
                break;
648
            case ADVANCED_SUBSCRIPTION_ACTION_SUPERIOR_DISAPPROVE:
649
                // Mail to student
650
                $mailIds[] = $this->sendMailMessage(
651
                    $data['studentUserId'],
652
                    $data['student']['user_id'],
653
                    $this->get_lang('MailBossReject'),
654
                    $template->fetch('/advanced_subscription/views/superior_rejected_notice_student.tpl'),
655
                    $data['sessionId'],
656
                    true
657
                );
658
                // Mail to superior
659
                $mailIds['render'] = $this->sendMailMessage(
660
                    $data['studentUserId'],
661
                    $data['superior']['user_id'],
662
                    $this->get_lang('MailBossReject'),
663
                    $template->fetch('/advanced_subscription/views/superior_rejected_notice_superior.tpl'),
664
                    $data['sessionId']
665
                );
666
                break;
667
            case ADVANCED_SUBSCRIPTION_ACTION_SUPERIOR_SELECT:
668
                // Mail to student
669
                $mailIds[] = $this->sendMailMessage(
670
                    $data['studentUserId'],
671
                    $data['student']['user_id'],
672
                    $this->get_lang('MailStudentRequestSelect'),
673
                    $template->fetch('/advanced_subscription/views/student_notice_student.tpl'),
674
                    $data['sessionId'],
675
                    true
676
                );
677
                // Mail to superior
678
                $mailIds['render'] = $this->sendMailMessage(
679
                    $data['studentUserId'],
680
                    $data['superior']['user_id'],
681
                    $this->get_lang('MailStudentRequestSelect'),
682
                    $template->fetch('/advanced_subscription/views/student_notice_superior.tpl'),
683
                    $data['sessionId']
684
                );
685
                break;
686
            case ADVANCED_SUBSCRIPTION_ACTION_ADMIN_APPROVE:
687
                $fileAttachments = [];
688
                if (api_get_plugin_setting('courselegal', 'tool_enable')) {
689
                    $courseLegal = CourseLegalPlugin::create();
690
                    $courses = SessionManager::get_course_list_by_session_id($data['sessionId']);
691
                    $course = current($courses);
692
                    $data['courseId'] = $course['id'];
693
                    $data['course'] = api_get_course_info_by_id($data['courseId']);
694
                    $termsAndConditions = $courseLegal->getData($data['courseId'], $data['sessionId']);
695
                    $termsAndConditions = $termsAndConditions['content'];
696
                    $termsAndConditions = $this->renderTemplateString($termsAndConditions, $data);
697
                    $tpl = new Template(get_lang('TermsAndConditions'));
698
                    $tpl->assign('session', $data['session']);
699
                    $tpl->assign('student', $data['student']);
700
                    $tpl->assign('sessionId', $data['sessionId']);
701
                    $tpl->assign('termsContent', $termsAndConditions);
702
                    $termsAndConditions = $tpl->fetch('/advanced_subscription/views/terms_and_conditions_to_pdf.tpl');
703
                    $pdf = new PDF();
704
                    $filename = 'terms'.sha1(rand(0, 99999));
705
                    $pdf->content_to_pdf($termsAndConditions, null, $filename, null, 'F');
706
                    $fileAttachments['file'][] = [
707
                        'name' => $filename.'.pdf',
708
                        'application/pdf' => $filename.'.pdf',
709
                        'tmp_name' => api_get_path(SYS_ARCHIVE_PATH).$filename.'.pdf',
710
                        'error' => UPLOAD_ERR_OK,
711
                        'size' => filesize(api_get_path(SYS_ARCHIVE_PATH).$filename.'.pdf'),
712
                    ];
713
                    $fileAttachments['comments'][] = get_lang('TermsAndConditions');
714
                }
715
                // Mail to student
716
                $mailIds[] = $this->sendMailMessage(
717
                    $data['studentUserId'],
718
                    $data['student']['user_id'],
719
                    $this->get_lang('MailAdminAccept'),
720
                    $template->fetch('/advanced_subscription/views/admin_accepted_notice_student.tpl'),
721
                    $data['sessionId'],
722
                    true,
723
                    $fileAttachments
724
                );
725
                // Mail to superior
726
                $mailIds[] = $this->sendMailMessage(
727
                    $data['studentUserId'],
728
                    $data['superior']['user_id'],
729
                    $this->get_lang('MailAdminAccept'),
730
                    $template->fetch('/advanced_subscription/views/admin_accepted_notice_superior.tpl'),
731
                    $data['sessionId']
732
                );
733
                // Mail to admin
734
                $adminId = $data['currentUserId'];
735
                $template->assign('admin', $data['admins'][$adminId]);
736
                $mailIds['render'] = $this->sendMailMessage(
737
                    $data['studentUserId'],
738
                    $adminId,
739
                    $this->get_lang('MailAdminAccept'),
740
                    $template->fetch('/advanced_subscription/views/admin_accepted_notice_admin.tpl'),
741
                    $data['sessionId']
742
                );
743
                break;
744
            case ADVANCED_SUBSCRIPTION_ACTION_ADMIN_DISAPPROVE:
745
                // Mail to student
746
                $mailIds[] = $this->sendMailMessage(
747
                    $data['studentUserId'],
748
                    $data['student']['user_id'],
749
                    $this->get_lang('MailAdminReject'),
750
                    $template->fetch('/advanced_subscription/views/admin_rejected_notice_student.tpl'),
751
                    $data['sessionId'],
752
                    true
753
                );
754
                // Mail to superior
755
                $mailIds[] = $this->sendMailMessage(
756
                    $data['studentUserId'],
757
                    $data['superior']['user_id'],
758
                    $this->get_lang('MailAdminReject'),
759
                    $template->fetch('/advanced_subscription/views/admin_rejected_notice_superior.tpl'),
760
                    $data['sessionId']
761
                );
762
                // Mail to admin
763
                $adminId = $data['currentUserId'];
764
                $template->assign('admin', $data['admins'][$adminId]);
765
                $mailIds['render'] = $this->sendMailMessage(
766
                    $data['studentUserId'],
767
                    $adminId,
768
                    $this->get_lang('MailAdminReject'),
769
                    $template->fetch('/advanced_subscription/views/admin_rejected_notice_admin.tpl'),
770
                    $data['sessionId']
771
                );
772
                break;
773
            case ADVANCED_SUBSCRIPTION_ACTION_STUDENT_REQUEST_NO_BOSS:
774
                // Mail to student
775
                $mailIds['render'] = $this->sendMailMessage(
776
                    $data['studentUserId'],
777
                    $data['student']['user_id'],
778
                    $this->get_lang('MailStudentRequestNoBoss'),
779
                    $template->fetch('/advanced_subscription/views/student_no_superior_notice_student.tpl'),
780
                    $data['sessionId'],
781
                    true
782
                );
783
                // Mail to admin
784
                foreach ($data['admins'] as $adminId => $admin) {
785
                    $template->assign('admin', $admin);
786
                    $mailIds[] = $this->sendMailMessage(
787
                        $data['studentUserId'],
788
                        $adminId,
789
                        $this->get_lang('MailStudentRequestNoBoss'),
790
                        $template->fetch('/advanced_subscription/views/student_no_superior_notice_admin.tpl'),
791
                        $data['sessionId']
792
                    );
793
                }
794
                break;
795
            case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_STUDENT:
796
                $mailIds['render'] = $this->sendMailMessage(
797
                    $data['student']['user_id'],
798
                    $data['student']['user_id'],
799
                    $this->get_lang('MailRemindStudent'),
800
                    $template->fetch('/advanced_subscription/views/reminder_notice_student.tpl'),
801
                    $data['sessionId'],
802
                    true
803
                );
804
                break;
805
            case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_SUPERIOR:
806
                $mailIds['render'] = $this->sendMailMessage(
807
                    $data['students'],
808
                    $data['superior']['user_id'],
809
                    $this->get_lang('MailRemindSuperior'),
810
                    $template->fetch('/advanced_subscription/views/reminder_notice_superior.tpl'),
811
                    $data['sessionId']
812
                );
813
                break;
814
            case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_SUPERIOR_MAX:
815
                $mailIds['render'] = $this->sendMailMessage(
816
                    $data['students'],
817
                    $data['superior']['user_id'],
818
                    $this->get_lang('MailRemindSuperior'),
819
                    $template->fetch('/advanced_subscription/views/reminder_notice_superior_max.tpl'),
820
                    $data['sessionId']
821
                );
822
                break;
823
            case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_ADMIN:
824
                // Mail to admin
825
                foreach ($data['admins'] as $adminId => $admin) {
826
                    $template->assign('admin', $admin);
827
                    $mailIds[] = $this->sendMailMessage(
828
                        $data['students'],
829
                        $adminId,
830
                        $this->get_lang('MailRemindAdmin'),
831
                        $template->fetch('/advanced_subscription/views/reminder_notice_admin.tpl'),
832
                        $data['sessionId']
833
                    );
834
                }
835
                break;
836
            default:
837
                break;
838
        }
839
840
        return $mailIds;
841
    }
842
843
    /**
844
     * Count the users in queue filtered by params (sessions, status).
845
     *
846
     * @param array $params Input array containing the set of
847
     *                      session and status to count from queue
848
     *                      e.g:
849
     *                      array('sessions' => array(215, 218, 345, 502),
850
     *                      'status' => array(0, 1, 2))
851
     *
852
     * @return int
853
     */
854
    public function countQueueByParams($params)
855
    {
856
        $count = 0;
857
        if (!empty($params) && is_array($params)) {
858
            $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
859
            $where['1 = ? '] = 1;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$where was never initialized. Although not strictly required by PHP, it is generally a good practice to add $where = array(); before regardless.
Loading history...
860
            if (isset($params['sessions']) && is_array($params['sessions'])) {
861
                foreach ($params['sessions'] as &$sessionId) {
862
                    $sessionId = intval($sessionId);
863
                }
864
                $where['AND session_id IN ( ? ) '] = implode($params['sessions']);
865
            }
866
            if (isset($params['status']) && is_array($params['status'])) {
867
                foreach ($params['status'] as &$status) {
868
                    $status = intval($status);
869
                }
870
                $where['AND status IN ( ? ) '] = implode($params['status']);
871
            }
872
            $where['where'] = $where;
873
            $count = Database::select('COUNT(*)', $advancedSubscriptionQueueTable, $where);
874
            $count = $count[0]['COUNT(*)'];
875
        }
876
877
        return $count;
878
    }
879
880
    /**
881
     * This method will call the Hook management insertHook to add Hook observer from this plugin.
882
     */
883
    public function installHook()
884
    {
885
        $hookObserver = HookAdvancedSubscription::create();
886
        HookAdminBlock::create()->attach($hookObserver);
887
        HookWSRegistration::create()->attach($hookObserver);
888
        HookNotificationContent::create()->attach($hookObserver);
889
        HookNotificationTitle::create()->attach($hookObserver);
890
    }
891
892
    /**
893
     * This method will call the Hook management deleteHook to disable Hook observer from this plugin.
894
     */
895
    public function uninstallHook()
896
    {
897
        $hookObserver = HookAdvancedSubscription::create();
898
        HookAdminBlock::create()->detach($hookObserver);
899
        HookWSRegistration::create()->detach($hookObserver);
900
        HookNotificationContent::create()->detach($hookObserver);
901
        HookNotificationTitle::create()->detach($hookObserver);
902
    }
903
904
    /**
905
     * Return the status from user in queue to session subscription.
906
     *
907
     * @param int $userId
908
     * @param int $sessionId
909
     *
910
     * @return bool|int
911
     */
912
    public function getQueueStatus($userId, $sessionId)
913
    {
914
        $userId = intval($userId);
915
        $sessionId = intval($sessionId);
916
        if (!empty($userId) && !empty($sessionId)) {
917
            $queueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
918
            $row = Database::select(
919
                'status',
920
                $queueTable,
921
                [
922
                    'where' => [
923
                        'user_id = ? AND session_id = ?' => [$userId, $sessionId],
924
                    ],
925
                ]
926
            );
927
928
            if (count($row) == 1) {
929
                return $row[0]['status'];
930
            } else {
931
                return ADVANCED_SUBSCRIPTION_QUEUE_STATUS_NO_QUEUE;
932
            }
933
        }
934
935
        return false;
936
    }
937
938
    /**
939
     * Return the remaining vacancy.
940
     *
941
     * @param $sessionId
942
     *
943
     * @return bool|int
944
     */
945
    public function getVacancy($sessionId)
946
    {
947
        if (!empty($sessionId)) {
948
            $extra = new ExtraFieldValue('session');
949
            $var = $extra->get_values_by_handler_and_field_variable(
950
                $sessionId,
951
                'vacancies'
952
            );
953
            $vacancy = intval($var['value']);
954
            if (!empty($vacancy)) {
955
                $vacancy -= $this->countQueueByParams(
956
                    [
957
                        'sessions' => [$sessionId],
958
                        'status' => [ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED],
959
                    ]
960
                );
961
                if ($vacancy >= 0) {
962
                    return $vacancy;
963
                } else {
964
                    return 0;
965
                }
966
            }
967
        }
968
969
        return false;
970
    }
971
972
    /**
973
     * Return the session details data from a session ID (including the extra
974
     * fields used for the advanced subscription mechanism).
975
     *
976
     * @param $sessionId
977
     *
978
     * @return bool|mixed
979
     */
980
    public function getSessionDetails($sessionId)
981
    {
982
        if (!empty($sessionId)) {
983
            // Assign variables
984
            $fieldsArray = [
985
                'code',
986
                'cost',
987
                'place',
988
                'allow_visitors',
989
                'teaching_hours',
990
                'brochure',
991
                'banner',
992
            ];
993
            $extraField = new ExtraField('session');
994
            // Get session fields
995
            $fieldList = $extraField->get_all([
996
                'variable IN ( ?, ?, ?, ?, ?, ?, ? )' => $fieldsArray,
997
            ]);
998
            // Index session fields
999
            $fields = [];
1000
            foreach ($fieldList as $field) {
1001
                $fields[$field['id']] = $field['variable'];
1002
            }
1003
1004
            $mergedArray = array_merge([$sessionId], array_keys($fields));
1005
1006
            $sql = "SELECT * FROM ".Database::get_main_table(TABLE_EXTRA_FIELD_VALUES)."
1007
                    WHERE item_id = %d AND field_id IN (%d, %d, %d, %d, %d, %d, %d)";
1008
            $sql = vsprintf($sql, $mergedArray);
1009
            $sessionFieldValueList = Database::query($sql);
1010
            while ($sessionFieldValue = Database::fetch_assoc($sessionFieldValueList)) {
1011
                // Check if session field value is set in session field list
1012
                if (isset($fields[$sessionFieldValue['field_id']])) {
1013
                    $var = $fields[$sessionFieldValue['field_id']];
1014
                    $val = $sessionFieldValue['value'];
1015
                    // Assign session field value to session
1016
                    $sessionArray[$var] = $val;
1017
                }
1018
            }
1019
            $sessionArray['description'] = SessionManager::getDescriptionFromSessionId($sessionId);
1020
1021
            if (isset($sessionArray['brochure'])) {
1022
                $sessionArray['brochure'] = api_get_path(WEB_UPLOAD_PATH).$sessionArray['brochure'];
1023
            }
1024
            if (isset($sessionArray['banner'])) {
1025
                $sessionArray['banner'] = api_get_path(WEB_UPLOAD_PATH).$sessionArray['banner'];
1026
            }
1027
1028
            return $sessionArray;
1029
        }
1030
1031
        return false;
1032
    }
1033
1034
    /**
1035
     * Get status message.
1036
     *
1037
     * @param int  $status
1038
     * @param bool $isAble
1039
     *
1040
     * @return string
1041
     */
1042
    public function getStatusMessage($status, $isAble = true)
1043
    {
1044
        switch ($status) {
1045
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_NO_QUEUE:
1046
                $message = $this->get_lang('AdvancedSubscriptionNoQueue');
1047
                if ($isAble) {
1048
                    $message = $this->get_lang('AdvancedSubscriptionNoQueueIsAble');
1049
                }
1050
                break;
1051
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_START:
1052
                $message = $this->get_lang('AdvancedSubscriptionQueueStart');
1053
                break;
1054
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_DISAPPROVED:
1055
                $message = $this->get_lang('AdvancedSubscriptionQueueBossDisapproved');
1056
                break;
1057
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_APPROVED:
1058
                $message = $this->get_lang('AdvancedSubscriptionQueueBossApproved');
1059
                break;
1060
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_DISAPPROVED:
1061
                $message = $this->get_lang('AdvancedSubscriptionQueueAdminDisapproved');
1062
                break;
1063
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED:
1064
                $message = $this->get_lang('AdvancedSubscriptionQueueAdminApproved');
1065
                break;
1066
            default:
1067
                $message = sprintf($this->get_lang('AdvancedSubscriptionQueueDefault'), $status);
1068
        }
1069
1070
        return $message;
1071
    }
1072
1073
    /**
1074
     * Return the url to go to session.
1075
     *
1076
     * @param $sessionId
1077
     *
1078
     * @return string
1079
     */
1080
    public function getSessionUrl($sessionId)
1081
    {
1082
        $url = api_get_path(WEB_CODE_PATH).'session/?session_id='.intval($sessionId);
1083
1084
        return $url;
1085
    }
1086
1087
    /**
1088
     * Get a url for subscribe a user in session.
1089
     *
1090
     * @param int   $userId The user ID
1091
     * @param array $params Params from WS
1092
     *
1093
     * @return string
1094
     */
1095
    public function getOpenSessionUrl($userId, $params)
1096
    {
1097
        $userIsSubscribed = SessionManager::isUserSubscribedAsStudent(
1098
            $params['session_id'],
1099
            $userId
1100
        );
1101
1102
        if ($userIsSubscribed) {
1103
            return api_get_path(WEB_CODE_PATH)
1104
                .'session/index.php?session_id='
1105
                .intval($params['session_id']);
1106
        }
1107
1108
        $params['secret_key'] = null;
1109
        $params['user_id'] = null;
1110
        $params['user_field'] = null;
1111
        $params['is_connected'] = null;
1112
1113
        $urlParams = array_merge($params, ['user_id' => $userId]);
1114
1115
        $url = api_get_path(WEB_PLUGIN_PATH);
1116
        $url .= 'advanced_subscription/src/open_session.php?';
1117
        $url .= http_build_query($urlParams);
1118
1119
        return 'javascript:void(window.open(\''
1120
            .$url
1121
            .'\',\'AdvancedSubscriptionTerms\', \'toolbar=no,location=no,'
1122
            .'status=no,menubar=no,scrollbars=yes,resizable=yes,width=700px,'
1123
            .'height=600px\', \'100\' ))';
1124
    }
1125
1126
    /**
1127
     * Return the url to enter to subscription queue to session.
1128
     *
1129
     * @param $params
1130
     *
1131
     * @return string
1132
     */
1133
    public function getQueueUrl($params)
1134
    {
1135
        $url = api_get_path(WEB_PLUGIN_PATH).'advanced_subscription/ajax/advanced_subscription.ajax.php?'.
1136
            'a='.Security::remove_XSS($params['action']).'&'.
1137
            's='.intval($params['sessionId']).'&'.
1138
            'current_user_id='.intval($params['currentUserId']).'&'.
1139
            'e='.intval($params['newStatus']).'&'.
1140
            'u='.intval($params['studentUserId']).'&'.
1141
            'q='.intval($params['queueId']).'&'.
1142
            'is_connected=1&'.
1143
            'profile_completed='.intval($params['profile_completed']).'&'.
1144
            'v='.$this->generateHash($params);
1145
1146
        return $url;
1147
    }
1148
1149
    /**
1150
     * Return the list of student, in queue used by admin view.
1151
     *
1152
     * @param int $sessionId
1153
     *
1154
     * @return array
1155
     */
1156
    public function listAllStudentsInQueueBySession($sessionId)
1157
    {
1158
        // Filter input variable
1159
        $sessionId = intval($sessionId);
1160
        // Assign variables
1161
        $fieldsArray = [
1162
            'target',
1163
            'publication_end_date',
1164
            'mode',
1165
            'recommended_number_of_participants',
1166
            'vacancies',
1167
        ];
1168
        $sessionArray = api_get_session_info($sessionId);
1169
        $extraSession = new ExtraFieldValue('session');
1170
        $extraField = new ExtraField('session');
1171
        // Get session fields
1172
        $fieldList = $extraField->get_all([
1173
            'variable IN ( ?, ?, ?, ?, ?)' => $fieldsArray,
1174
        ]);
1175
        // Index session fields
1176
        $fields = [];
1177
        foreach ($fieldList as $field) {
1178
            $fields[$field['id']] = $field['variable'];
1179
        }
1180
1181
        $mergedArray = array_merge([$sessionId], array_keys($fields));
1182
        $sessionFieldValueList = $extraSession->get_all(
1183
            [
1184
                'item_id = ? field_id IN ( ?, ?, ?, ?, ?, ?, ? )' => $mergedArray,
1185
            ]
1186
        );
1187
        foreach ($sessionFieldValueList as $sessionFieldValue) {
1188
            // Check if session field value is set in session field list
1189
            if (isset($fields[$sessionFieldValue['field_id']])) {
1190
                $var = $fields[$sessionFieldValue['field_id']];
1191
                $val = $sessionFieldValue['value'];
1192
                // Assign session field value to session
1193
                $sessionArray[$var] = $val;
1194
            }
1195
        }
1196
        $queueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
1197
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
1198
        $userJoinTable = $queueTable.' q INNER JOIN '.$userTable.' u ON q.user_id = u.user_id';
1199
        $where = [
1200
            'where' => [
1201
                'q.session_id = ?' => [
1202
                    $sessionId,
1203
                ],
1204
            ],
1205
            'order' => 'q.status DESC, u.lastname ASC',
1206
        ];
1207
        $select = 'u.user_id, u.firstname, u.lastname, q.created_at, q.updated_at, q.status, q.id as queue_id';
1208
        $students = Database::select($select, $userJoinTable, $where);
1209
        foreach ($students as &$student) {
1210
            $status = intval($student['status']);
1211
            switch ($status) {
1212
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_NO_QUEUE:
1213
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_START:
1214
                    $student['validation'] = '';
1215
                    break;
1216
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_DISAPPROVED:
1217
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_DISAPPROVED:
1218
                    $student['validation'] = 'No';
1219
                    break;
1220
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_APPROVED:
1221
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED:
1222
                    $student['validation'] = 'Yes';
1223
                    break;
1224
                default:
1225
                    error_log(__FILE__.' '.__FUNCTION__.' Student status no detected');
1226
            }
1227
        }
1228
        $return = [
1229
            'session' => $sessionArray,
1230
            'students' => $students,
1231
        ];
1232
1233
        return $return;
1234
    }
1235
1236
    /**
1237
     * List all session (id, name) for select input.
1238
     *
1239
     * @param int $limit
1240
     *
1241
     * @return array
1242
     */
1243
    public function listAllSessions($limit = 100)
1244
    {
1245
        $limit = intval($limit);
1246
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
1247
        $columns = 'id, name';
1248
        $conditions = [];
1249
        if ($limit > 0) {
1250
            $conditions = [
1251
                'order' => 'name',
1252
                'limit' => $limit,
1253
            ];
1254
        }
1255
1256
        return Database::select($columns, $sessionTable, $conditions);
1257
    }
1258
1259
    /**
1260
     * Generate security hash to check data send by url params.
1261
     *
1262
     * @param string $data
1263
     *
1264
     * @return string
1265
     */
1266
    public function generateHash($data)
1267
    {
1268
        $key = sha1($this->get('secret_key'));
1269
        // Prepare array to have specific type variables
1270
        $dataPrepared['action'] = strval($data['action']);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$dataPrepared was never initialized. Although not strictly required by PHP, it is generally a good practice to add $dataPrepared = array(); before regardless.
Loading history...
1271
        $dataPrepared['sessionId'] = intval($data['sessionId']);
1272
        $dataPrepared['currentUserId'] = intval($data['currentUserId']);
1273
        $dataPrepared['studentUserId'] = intval($data['studentUserId']);
1274
        $dataPrepared['queueId'] = intval($data['queueId']);
1275
        $dataPrepared['newStatus'] = intval($data['newStatus']);
1276
        $dataPrepared = serialize($dataPrepared);
1277
1278
        return sha1($dataPrepared.$key);
1279
    }
1280
1281
    /**
1282
     * Verify hash from data.
1283
     *
1284
     * @param string $data
1285
     * @param string $hash
1286
     *
1287
     * @return bool
1288
     */
1289
    public function checkHash($data, $hash)
1290
    {
1291
        return $this->generateHash($data) == $hash;
1292
    }
1293
1294
    /**
1295
     * Copied and fixed from plugin.class.php
1296
     * Returns the "system" name of the plugin in lowercase letters.
1297
     *
1298
     * @return string
1299
     */
1300
    public function get_name()
1301
    {
1302
        return 'advanced_subscription';
1303
    }
1304
1305
    /**
1306
     * Return the url to show subscription terms.
1307
     *
1308
     * @param array $params
1309
     * @param int   $mode
1310
     *
1311
     * @return string
1312
     */
1313
    public function getTermsUrl($params, $mode = ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP)
1314
    {
1315
        $urlParams = [
1316
            'a' => Security::remove_XSS($params['action']),
1317
            's' => intval($params['sessionId']),
1318
            'current_user_id' => intval($params['currentUserId']),
1319
            'e' => intval($params['newStatus']),
1320
            'u' => intval($params['studentUserId']),
1321
            'q' => intval($params['queueId']),
1322
            'is_connected' => 1,
1323
            'profile_completed' => intval($params['profile_completed']),
1324
            'v' => $this->generateHash($params),
1325
        ];
1326
1327
        switch ($mode) {
1328
            case ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP:
1329
            case ADVANCED_SUBSCRIPTION_TERMS_MODE_FINAL:
1330
                $urlParams['r'] = 0;
1331
                break;
1332
            case ADVANCED_SUBSCRIPTION_TERMS_MODE_REJECT:
1333
                $urlParams['r'] = 1;
1334
                break;
1335
        }
1336
1337
        $url = api_get_path(WEB_PLUGIN_PATH)."advanced_subscription/src/terms_and_conditions.php?";
1338
        $url .= http_build_query($urlParams);
1339
1340
        // Launch popup
1341
        if ($mode == ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP) {
1342
            $url = 'javascript:void(window.open(\''.$url.'\',\'AdvancedSubscriptionTerms\', \'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=700px,height=600px\', \'100\' ))';
1343
        }
1344
1345
        return $url;
1346
    }
1347
1348
    /**
1349
     * Return the url to get mail rendered.
1350
     *
1351
     * @param array $params
1352
     *
1353
     * @return string
1354
     */
1355
    public function getRenderMailUrl($params)
1356
    {
1357
        $url = api_get_path(WEB_PLUGIN_PATH).'advanced_subscription/src/render_mail.php?'.
1358
            'q='.$params['queueId'].'&'.
1359
            'v='.$this->generateHash($params);
1360
1361
        return $url;
1362
    }
1363
1364
    /**
1365
     * Return the last message id from queue row.
1366
     *
1367
     * @param int $studentUserId
1368
     * @param int $sessionId
1369
     *
1370
     * @return int|bool
1371
     */
1372
    public function getLastMessageId($studentUserId, $sessionId)
1373
    {
1374
        $studentUserId = intval($studentUserId);
1375
        $sessionId = intval($sessionId);
1376
        if (!empty($sessionId) && !empty($studentUserId)) {
1377
            $row = Database::select(
1378
                'last_message_id',
1379
                Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE),
1380
                [
1381
                    'where' => [
1382
                        'user_id = ? AND session_id = ?' => [$studentUserId, $sessionId],
1383
                    ],
1384
                ]
1385
            );
1386
1387
            if (count($row) > 0) {
1388
                return $row[0]['last_message_id'];
1389
            }
1390
        }
1391
1392
        return false;
1393
    }
1394
1395
    /**
1396
     * Return string replacing tags "{{}}"with variables assigned in $data.
1397
     *
1398
     * @param string $templateContent
1399
     * @param array  $data
1400
     *
1401
     * @return string
1402
     */
1403
    public function renderTemplateString($templateContent, $data = [])
1404
    {
1405
        $twigString = new \Twig_Environment(new \Twig_Loader_String());
1406
        $templateContent = $twigString->render(
1407
            $templateContent,
1408
            $data
1409
        );
1410
1411
        return $templateContent;
1412
    }
1413
1414
    /**
1415
     * addAreaField() (adds an area field if it is not already created).
1416
     */
1417
    private function addAreaField()
1418
    {
1419
        $extraField = new ExtraField('user');
1420
        $extraFieldHandler = $extraField->get_handler_field_info_by_field_variable('area');
1421
        $areaExists = $extraFieldHandler !== false;
1422
1423
        if (!$areaExists) {
1424
            $extraField = new ExtraField('user');
1425
            $extraField->save([
1426
                'field_type' => 1,
1427
                'variable' => 'area',
1428
                'display_text' => get_plugin_lang('Area', 'AdvancedSubscriptionPlugin'),
1429
                'default_value' => null,
1430
                'field_order' => null,
1431
                'visible_to_self' => 1,
1432
                'changeable' => 1,
1433
                'filter' => null,
1434
            ]);
1435
        }
1436
    }
1437
1438
    /**
1439
     * Create the database tables for the plugin.
1440
     */
1441
    private function installDatabase()
1442
    {
1443
        $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
1444
1445
        $sql = "CREATE TABLE IF NOT EXISTS $advancedSubscriptionQueueTable (".
1446
            "id int UNSIGNED NOT NULL AUTO_INCREMENT, ".
1447
            "session_id int UNSIGNED NOT NULL, ".
1448
            "user_id int UNSIGNED NOT NULL, ".
1449
            "status int UNSIGNED NOT NULL, ".
1450
            "last_message_id int UNSIGNED NOT NULL, ".
1451
            "created_at datetime NOT NULL, ".
1452
            "updated_at datetime NULL, ".
1453
            "PRIMARY KEY PK_advanced_subscription_queue (id), ".
1454
            "UNIQUE KEY UK_advanced_subscription_queue (user_id, session_id)); ";
1455
        Database::query($sql);
1456
    }
1457
1458
    /**
1459
     * Drop the database tables for the plugin.
1460
     */
1461
    private function uninstallDatabase()
1462
    {
1463
        /* Drop plugin tables */
1464
        $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
1465
        $sql = "DROP TABLE IF EXISTS $advancedSubscriptionQueueTable; ";
1466
        Database::query($sql);
1467
1468
        /* Delete settings */
1469
        $settingsTable = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
1470
        Database::query("DELETE FROM $settingsTable WHERE subkey = 'advanced_subscription'");
1471
    }
1472
1473
    /**
1474
     * Get the count of approved induction sessions by a user.
1475
     *
1476
     * @param int $userId The user id
1477
     *
1478
     * @return int The count of approved sessions
1479
     */
1480
    private function getApprovedInductionSessions($userId)
1481
    {
1482
        $tSession = Database::get_main_table(TABLE_MAIN_SESSION);
1483
        $tSessionField = Database::get_main_table(TABLE_EXTRA_FIELD);
1484
        $tSessionFieldValues = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
1485
        $tSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1486
        $extraFieldType = \Chamilo\CoreBundle\Entity\ExtraField::SESSION_FIELD_TYPE;
1487
        $sql = "SELECT s.id FROM $tSession AS s
1488
            INNER JOIN $tSessionFieldValues AS sfv ON s.id = sfv.item_id
1489
            INNER JOIN $tSessionField AS sf ON sfv.field_id = sf.id
1490
            INNER JOIN $tSessionUser AS su ON s.id = su.session_id
1491
            WHERE
1492
                sf.extra_field_type = $extraFieldType AND
1493
                sf.variable = 'is_induction_session' AND
1494
                su.relation_type = 0 AND
1495
                su.user_id = ".intval($userId);
1496
1497
        $result = Database::query($sql);
1498
1499
        if ($result === false) {
1500
            return 0;
1501
        }
1502
1503
        $numberOfApproved = 0;
1504
1505
        while ($session = Database::fetch_assoc($result)) {
1506
            $numberOfApprovedCourses = 0;
1507
            $courses = SessionManager::get_course_list_by_session_id($session['id']);
1508
1509
            foreach ($courses as $course) {
1510
                $courseCategories = Category::load(
1511
                    null,
1512
                    null,
1513
                    $course['code'],
1514
                    null,
1515
                    null,
1516
                    $session['id'],
1517
                    false
1518
                );
1519
1520
                if (count($courseCategories) > 0 &&
1521
                    Category::userFinishedCourse($userId, $courseCategories[0])
1522
                ) {
1523
                    $numberOfApprovedCourses++;
1524
                }
1525
            }
1526
1527
            if ($numberOfApprovedCourses === count($courses)) {
1528
                $numberOfApproved++;
1529
            }
1530
        }
1531
1532
        return $numberOfApproved;
1533
    }
1534
}
1535