Completed
Push — master ( 9b8b24...6e1754 )
by Julito
58:58
created

AdvancedSubscriptionPlugin   F

Complexity

Total Complexity 164

Size/Duplication

Total Lines 1467
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1467
rs 0.6314
c 0
b 0
f 0
wmc 164

38 Methods

Rating   Name   Duplication   Size   Complexity  
A getSessionUrl() 0 5 1
B getSessionDetails() 0 52 7
A addAreaField() 0 17 2
A saveLastMessage() 0 19 1
A isSessionOpen() 0 14 2
B getQueueStatus() 0 24 4
C listAllStudentsInQueueBySession() 0 78 11
A uninstallHook() 0 7 1
B getTermsUrl() 0 33 5
A getQueueUrl() 0 14 1
B getOpenSessionUrl() 0 29 2
A installHook() 0 7 1
A uninstallDatabase() 0 10 1
A getLastMessageId() 0 21 4
B startSubscription() 0 16 5
A listAllSessions() 0 14 2
A __construct() 0 17 1
D isUserInTargetGroup() 0 28 10
C sendMailMessage() 0 52 11
B getApprovedInductionSessions() 0 53 7
A installDatabase() 0 15 1
A get_name() 0 3 1
A checkHash() 0 3 1
A generateHash() 0 12 1
F isAllowedToDoRequest() 0 152 23
A create() 0 5 2
A getErrorMessages() 0 3 1
A install() 0 5 1
A uninstall() 0 7 2
B getVacancy() 0 25 4
B updateQueueStatus() 0 31 5
A addToQueue() 0 18 1
C countQueueByParams() 0 24 9
A renderTemplateString() 0 9 1
C getStatusMessage() 0 29 8
B isAllowedSubscribeToOpenSession() 0 49 6
D sendMail() 0 263 17
A getRenderMailUrl() 0 6 1

How to fix   Complexity   

Complex Class

Complex classes like AdvancedSubscriptionPlugin often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AdvancedSubscriptionPlugin, and based on these observations, apply Extract Interface, too.

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
 * @package chamilo.plugin.advanced_subscription
9
 */
10
class AdvancedSubscriptionPlugin extends Plugin implements HookPluginInterface
11
{
12
    protected $strings;
13
    private $errorMessages;
14
15
    /**
16
     * Constructor
17
     */
18
    public function __construct()
19
    {
20
        $parameters = array(
21
            'yearly_cost_limit' => 'text',
22
            'yearly_hours_limit' => 'text',
23
            'yearly_cost_unit_converter' => 'text',
24
            'courses_count_limit' => 'text',
25
            'course_session_credit_year_start_date' => 'text',
26
            'ws_url' => 'text',
27
            'min_profile_percentage' => 'text',
28
            'check_induction' => 'boolean',
29
            'secret_key' => 'text',
30
            'terms_and_conditions' => 'wysiwyg'
31
        );
32
33
        parent::__construct('1.0', 'Imanol Losada, Daniel Barreto', $parameters);
34
        $this->errorMessages = array();
35
    }
36
37
    /**
38
     * Instance the plugin
39
     * @staticvar null $result
40
     * @return AdvancedSubscriptionPlugin
41
     */
42
    public static function create()
43
    {
44
        static $result = null;
45
46
        return $result ? $result : $result = new self();
47
    }
48
49
    /**
50
     * Install the plugin
51
     * @return void
52
     */
53
    public function install()
54
    {
55
        $this->installDatabase();
56
        $this->addAreaField();
57
        $this->installHook();
58
    }
59
60
    /**
61
     * Uninstall the plugin
62
     * @return void
63
     */
64
    public function uninstall()
65
    {
66
        $setting = api_get_setting('advanced_subscription');
67
        if (!empty($setting)) {
68
            $this->uninstallHook();
69
            // Note: Keeping area field data is intended so it will not be removed
70
            $this->uninstallDatabase();
71
        }
72
    }
73
74
    /**
75
     * addAreaField() (adds an area field if it is not already created)
76
     * @return void
77
     */
78
    private function addAreaField()
79
    {
80
        $extraField = new ExtraField('user');
81
        $extraFieldHandler = $extraField->get_handler_field_info_by_field_variable('area');
82
        $areaExists = $extraFieldHandler !== false;
83
84
        if (!$areaExists) {
85
            $extraField = new ExtraField('user');
86
            $extraField->save(array(
87
                'field_type' => 1,
88
                'variable' => 'area',
89
                'display_text' => get_plugin_lang('Area', 'AdvancedSubscriptionPlugin'),
90
                'default_value' => null,
91
                'field_order' => null,
92
                'visible_to_self' => 1,
93
                'changeable' => 1,
94
                'filter' => null
95
            ));
96
        }
97
    }
98
99
    /**
100
     * Create the database tables for the plugin
101
     * @return void
102
     */
103
    private function installDatabase()
104
    {
105
        $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
106
107
        $sql = "CREATE TABLE IF NOT EXISTS $advancedSubscriptionQueueTable (".
108
            "id int UNSIGNED NOT NULL AUTO_INCREMENT, ".
109
            "session_id int UNSIGNED NOT NULL, ".
110
            "user_id int UNSIGNED NOT NULL, ".
111
            "status int UNSIGNED NOT NULL, ".
112
            "last_message_id int UNSIGNED NOT NULL, ".
113
            "created_at datetime NOT NULL, ".
114
            "updated_at datetime NULL, ".
115
            "PRIMARY KEY PK_advanced_subscription_queue (id), ".
116
            "UNIQUE KEY UK_advanced_subscription_queue (user_id, session_id)); ";
117
        Database::query($sql);
118
    }
119
120
    /**
121
     * Drop the database tables for the plugin
122
     * @return void
123
     */
124
    private function uninstallDatabase()
125
    {
126
        /* Drop plugin tables */
127
        $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
128
        $sql = "DROP TABLE IF EXISTS $advancedSubscriptionQueueTable; ";
129
        Database::query($sql);
130
131
        /* Delete settings */
132
        $settingsTable = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
133
        Database::query("DELETE FROM $settingsTable WHERE subkey = 'advanced_subscription'");
134
    }
135
136
    /**
137
     * Get the error messages list
138
     * @return array The message list
139
     */
140
    public function getErrorMessages()
141
    {
142
        return $this->errorMessages;
143
    }
144
145
    /**
146
     * Check if is allowed subscribe to open session
147
     * @param array $params WS params
148
     * @return boolean
149
     */
150
    public function isAllowedSubscribeToOpenSession($params)
151
    {
152
        $self = self::create();
153
        $wsUrl = $self->get('ws_url');
154
        $profileCompleted = 0;
155
        if (!empty($wsUrl)) {
156
            $client = new SoapClient(
157
                null,
158
                ['location' => $wsUrl, 'uri' => $wsUrl]
159
            );
160
            $userInfo = api_get_user_info(
161
                $params['user_id'],
162
                false,
163
                false,
164
                true
165
            );
166
167
            try {
168
                $profileCompleted = $client->__soapCall(
169
                    'getProfileCompletionPercentage',
170
                    $userInfo['extra']['drupal_user_id']
171
                );
172
            } catch (\Exception $e) {
173
                $profileCompleted = 0;
174
            }
175
        } elseif (isset($params['profile_completed'])) {
176
            $profileCompleted = (float) $params['profile_completed'];
177
        }
178
        $profileCompletedMin = (float) $self->get('min_profile_percentage');
179
180
        if ($profileCompleted < $profileCompletedMin) {
181
            $this->errorMessages[] = sprintf(
182
                $this->get_lang('AdvancedSubscriptionProfileIncomplete'),
183
                $profileCompletedMin,
184
                $profileCompleted
185
            );
186
        }
187
188
        $vacancy = $self->getVacancy($params['session_id']);
189
        $sessionInfo = api_get_session_info($params['session_id']);
190
191
        if ($sessionInfo['nbr_users'] >= $vacancy) {
192
            $this->errorMessages[] = sprintf(
193
                $this->get_lang('SessionXWithoutVacancies'),
194
                $sessionInfo['name']
195
            );
196
        }
197
198
        return empty($this->errorMessages);
199
    }
200
201
    /**
202
     * Return true if user is allowed to be added to queue for session subscription
203
     * @param int $userId
204
     * @param array $params MUST have keys:
205
     * "is_connected" Indicate if the user is online on external web
206
     * "profile_completed" Percentage of completed profile, given by WS
207
     * @param boolean $collectErrors Optional. Default is false. Whether collect all errors or throw exeptions
208
     * @throws Exception
209
     * @return bool
210
     */
211
    public function isAllowedToDoRequest($userId, $params = array(), $collectErrors = false)
212
    {
213
        $plugin = self::create();
214
        $wsUrl = $plugin->get('ws_url');
215
        // Student always is connected
216
        $isConnected = true;
217
218
        if (!$isConnected) {
219
            $this->errorMessages[] = $this->get_lang('AdvancedSubscriptionNotConnected');
220
221
            if (!$collectErrors) {
222
                throw new \Exception($this->get_lang('AdvancedSubscriptionNotConnected'));
223
            }
224
        }
225
226
        $profileCompletedMin = (float) $plugin->get('min_profile_percentage');
227
        $profileCompleted = 0;
228
229
        if (is_string($wsUrl) && !empty($wsUrl)) {
230
            $options = array(
231
                'location' => $wsUrl,
232
                'uri' => $wsUrl
233
            );
234
            $client = new SoapClient(null, $options);
235
            $userInfo = api_get_user_info($userId);
236
            try {
237
                $profileCompleted = $client->__soapCall('getProfileCompletionPercentage', $userInfo['extra']['drupal_user_id']);
238
            } catch (\Exception $e) {
239
                $profileCompleted = 0;
240
            }
241
        } elseif (isset($params['profile_completed'])) {
242
            $profileCompleted = (float) $params['profile_completed'];
243
        }
244
245
        if ($profileCompleted < $profileCompletedMin) {
246
            $errorMessage = sprintf(
247
                $this->get_lang('AdvancedSubscriptionProfileIncomplete'),
248
                $profileCompletedMin,
249
                $profileCompleted
250
            );
251
252
            $this->errorMessages[] = $errorMessage;
253
254
            if (!$collectErrors) {
255
                throw new \Exception($errorMessage);
256
            }
257
        }
258
259
        $yearlyCostLimit = $plugin->get('yearly_cost_limit');
260
        $maxCost = $plugin->get('yearly_cost_unit_converter');
261
        $maxCost *= $yearlyCostLimit;
262
        $userCost = 0;
263
        $now = new DateTime(api_get_utc_datetime());
264
        $newYearDate = $plugin->get('course_session_credit_year_start_date');
265
        $newYearDate = !empty($newYearDate) ?
266
            new \DateTime($newYearDate.$now->format('/Y')) : $now;
267
        $extra = new ExtraFieldValue('session');
268
        $joinSessionTable = Database::get_main_table(TABLE_MAIN_SESSION_USER).' su INNER JOIN '.
269
            Database::get_main_table(TABLE_MAIN_SESSION).' s ON s.id = su.session_id';
270
        $whereSessionParams = 'su.relation_type = ? AND s.access_start_date >= ? AND su.user_id = ?';
271
        $whereSessionParamsValues = array(
272
            0,
273
            $newYearDate->format('Y-m-d'),
274
            $userId
275
        );
276
        $whereSession = array(
277
            'where' => array(
278
                $whereSessionParams => $whereSessionParamsValues
279
            )
280
        );
281
        $selectSession = 's.id AS id';
282
        $sessions = Database::select(
283
            $selectSession,
284
            $joinSessionTable,
285
            $whereSession
286
        );
287
288
        $expendedTimeMax = $plugin->get('yearly_hours_limit');
289
        $expendedTime = 0;
290
291
        if (is_array($sessions) && count($sessions) > 0) {
292
            foreach ($sessions as $session) {
293
                $costField = $extra->get_values_by_handler_and_field_variable($session['id'], 'cost');
294
                $userCost += $costField['value'];
295
                $teachingHoursField = $extra->get_values_by_handler_and_field_variable($session['id'], 'teaching_hours');
296
                $expendedTime += $teachingHoursField['value'];
297
            }
298
        }
299
300
        if (isset($params['sessionId'])) {
301
            $costField = $extra->get_values_by_handler_and_field_variable($params['sessionId'], 'cost');
302
            $userCost += $costField['value'];
303
304
            $teachingHoursField = $extra->get_values_by_handler_and_field_variable($params['sessionId'], 'teaching_hours');
305
            $expendedTime += $teachingHoursField['value'];
306
        }
307
308
        if ($maxCost <= $userCost) {
309
            $errorMessage = sprintf(
310
                $this->get_lang('AdvancedSubscriptionCostXLimitReached'),
311
                $yearlyCostLimit
312
            );
313
314
            $this->errorMessages[] = $errorMessage;
315
316
            if (!$collectErrors) {
317
                throw new \Exception($errorMessage);
318
            }
319
        }
320
321
        if ($expendedTimeMax <= $expendedTime) {
322
            $errorMessage = sprintf(
323
                $this->get_lang('AdvancedSubscriptionTimeXLimitReached'),
324
                $expendedTimeMax
325
            );
326
327
            $this->errorMessages[] = $errorMessage;
328
329
            if (!$collectErrors) {
330
                throw new \Exception($errorMessage);
331
            }
332
        }
333
334
        $expendedNumMax = $plugin->get('courses_count_limit');
335
        $expendedNum = count($sessions);
336
337
        if ($expendedNumMax <= $expendedNum) {
338
            $errorMessage = sprintf(
339
                $this->get_lang('AdvancedSubscriptionCourseXLimitReached'),
340
                $expendedNumMax
341
            );
342
343
            $this->errorMessages[] = $errorMessage;
344
345
            if (!$collectErrors) {
346
                throw new \Exception($errorMessage);
347
            }
348
        }
349
350
        $checkInduction = $plugin->get('check_induction');
351
        $numberOfApprovedInductionSessions = $this->getApprovedInductionSessions($userId);
352
        $completedInduction = $numberOfApprovedInductionSessions > 0;
353
354
        if ($checkInduction == 'true' && !$completedInduction) {
355
            $this->errorMessages[] = $this->get_lang('AdvancedSubscriptionIncompleteInduction');
356
357
            if (!$collectErrors) {
358
                throw new \Exception($this->get_lang('AdvancedSubscriptionIncompleteInduction'));
359
            }
360
        }
361
362
        return empty($this->errorMessages);
363
    }
364
365
    /**
366
     * Register a user into a queue for a session
367
     * @param $userId
368
     * @param $sessionId
369
     * @return bool|int
370
     */
371
    public function addToQueue($userId, $sessionId)
372
    {
373
        // Filter input variables
374
        $userId = intval($userId);
375
        $sessionId = intval($sessionId);
376
        $now = api_get_utc_datetime();
377
        $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
378
        $attributes = array(
379
            'session_id' => $sessionId,
380
            'user_id' => $userId,
381
            'status' => 0,
382
            'created_at' => $now,
383
            'updated_at' => null,
384
        );
385
386
        $id = Database::insert($advancedSubscriptionQueueTable, $attributes);
387
388
        return $id;
389
    }
390
391
    /**
392
     * Register message with type and status
393
     * @param $mailId
394
     * @param $userId
395
     * @param $sessionId
396
     * @return bool|int
397
     */
398
    public function saveLastMessage($mailId, $userId, $sessionId)
399
    {
400
        // Filter variables
401
        $mailId = intval($mailId);
402
        $userId = intval($userId);
403
        $sessionId = intval($sessionId);
404
        $queueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
405
        $attributes = array(
406
            'last_message_id' => $mailId,
407
            'updated_at' => api_get_utc_datetime(),
408
        );
409
410
        $num = Database::update(
411
            $queueTable,
412
            $attributes,
413
            array('user_id = ? AND session_id = ?' => array($userId, $sessionId))
414
        );
415
416
        return $num;
417
    }
418
419
    /**
420
     * Check for requirements and register user into queue
421
     * @param $userId
422
     * @param $sessionId
423
     * @param $params
424
     * @return bool|string
425
     */
426
    public function startSubscription($userId, $sessionId, $params)
427
    {
428
        $result = 'Params not found';
429
        if (!empty($sessionId) && !empty($userId)) {
430
            $plugin = self::create();
431
            try {
432
                if ($plugin->isAllowedToDoRequest($userId, $params)) {
433
                    $result = (bool) $plugin->addToQueue($userId, $sessionId);
434
                } else {
435
                    throw new \Exception($this->get_lang('AdvancedSubscriptionNotMoreAble'));
436
                }
437
            } catch (Exception $e) {
438
                $result = $e->getMessage();
439
            }
440
        }
441
        return $result;
442
    }
443
444
    /**
445
     * Send message for the student subscription approval to a specific session
446
     * @param int|array $studentId
447
     * @param int $receiverId
448
     * @param string $subject
449
     * @param string $content
450
     * @param int $sessionId
451
     * @param bool $save
452
     * @param array $fileAttachments
453
     * @return bool|int
454
     */
455
    public function sendMailMessage(
456
        $studentId,
457
        $receiverId,
458
        $subject,
459
        $content,
460
        $sessionId,
461
        $save = false,
462
        $fileAttachments = []
463
    ) {
464
        if (!empty($fileAttachments) &&
465
            is_array($fileAttachments) &&
466
            isset($fileAttachments['files']) &&
467
            isset($fileAttachments['comments'])
468
        ) {
469
            $mailId = MessageManager::send_message(
470
                $receiverId,
471
                $subject,
472
                $content,
473
                $fileAttachments['files'],
474
                $fileAttachments['comments']
475
            );
476
        } else {
477
            $mailId = MessageManager::send_message(
478
                $receiverId,
479
                $subject,
480
                $content
481
            );
482
        }
483
484
        if ($save && !empty($mailId)) {
485
            // Save as sent message
486
            if (is_array($studentId) && !empty($studentId)) {
487
                foreach ($studentId as $student) {
488
                    $this->saveLastMessage($mailId, $student['user_id'], $sessionId);
489
                }
490
            } else {
491
                $studentId = intval($studentId);
492
                $this->saveLastMessage($mailId, $studentId, $sessionId);
493
            }
494
        } elseif (!empty($mailId)) {
495
            // Update queue row, updated_at
496
            Database::update(
497
                Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE),
498
                array(
499
                    'updated_at' => api_get_utc_datetime(),
500
                ),
501
                array(
502
                    'user_id = ? AND session_id = ?' => array($studentId, $sessionId)
503
                )
504
            );
505
        }
506
        return $mailId;
507
    }
508
509
    /**
510
     * Check if session is open for subscription
511
     * @param $sessionId
512
     * @param string $fieldVariable
513
     * @return bool
514
     */
515
    public function isSessionOpen($sessionId, $fieldVariable = 'is_open_session')
516
    {
517
        $extraFieldValue = new ExtraFieldValue('session');
518
        $result = $extraFieldValue->get_values_by_handler_and_field_variable(
519
            $sessionId,
520
            $fieldVariable
521
        );
522
523
        $isOpen = false;
524
        if (!empty($result)) {
525
            $isOpen = (bool) $result['value'];
526
        }
527
528
        return $isOpen;
529
    }
530
531
    /**
532
     * Check if user is in the session's target group based on its area
533
     * @param $userId
534
     * @param $sessionId
535
     * @param string $userFieldVariable
536
     * @param string $sessionFieldVariable
537
     * @return bool
538
     */
539
    public function isUserInTargetGroup(
540
        $userId,
541
        $sessionId,
542
        $userFieldVariable = 'area',
543
        $sessionFieldVariable = 'target'
544
    ) {
545
        $extraSessionFieldValue = new ExtraFieldValue('session');
546
        $sessionTarget = $extraSessionFieldValue->get_values_by_handler_and_field_variable(
547
            $sessionId,
548
            $sessionFieldVariable
549
        );
550
        $extraUserFieldValue = new ExtraFieldValue('user');
551
        $userArea = $extraUserFieldValue->get_values_by_handler_and_field_variable(
552
            $userId,
553
            $userFieldVariable
554
        );
555
        $isInTargetGroup = false;
556
        if (isset($sessionTarget) && (!empty($sessionTarget)) && $sessionTarget['value'] == 'minedu') {
557
            if (substr($userArea['value'], 0, 6) == 'MINEDU') {
558
                $isInTargetGroup = true;
559
            }
560
        }
561
        if (isset($sessionTarget) && (!empty($sessionTarget)) && $sessionTarget['value'] == 'regiones') {
562
            if ((substr($userArea['value'], 0, 4) == 'UGEL') || (substr($userArea['value'], 0, 3) == 'DRE')) {
563
                $isInTargetGroup = true;
564
            }
565
        }
566
        return $isInTargetGroup;
567
    }
568
569
    /**
570
     * Update the queue status for subscription approval rejected or accepted
571
     * @param $params
572
     * @param $newStatus
573
     * @return bool
574
     */
575
    public function updateQueueStatus($params, $newStatus)
576
    {
577
        $newStatus = intval($newStatus);
578
        $res = false;
579
580
        if (isset($params['queue']['id'])) {
581
            $where = array(
582
                'id = ?' => intval($params['queue']['id']),
583
            );
584
        } elseif (isset($params['studentUserId']) && isset($params['sessionId'])) {
585
            $where = array(
586
                'user_id = ? AND session_id = ? AND status <> ? AND status <> ?' => array(
587
                    intval($params['studentUserId']),
588
                    intval($params['sessionId']),
589
                    $newStatus,
590
                    ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED,
591
                ),
592
            );
593
        }
594
        if (isset($where)) {
595
            $res = (bool) Database::update(
596
                Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE),
597
                array(
598
                    'status' => $newStatus,
599
                    'updated_at' => api_get_utc_datetime(),
600
                ),
601
                $where
602
            );
603
        }
604
605
        return $res;
606
    }
607
608
    /**
609
     * Render and send mail by defined advanced subscription action
610
     * @param $data
611
     * @param $actionType
612
     * @return array
613
     */
614
    public function sendMail($data, $actionType)
615
    {
616
        $template = new Template($this->get_lang('plugin_title'));
617
        $template->assign('data', $data);
618
        $templateParams = array(
619
            'user',
620
            'student',
621
            'students',
622
            'superior',
623
            'admins',
624
            'session',
625
            'signature',
626
            'admin_view_url',
627
            'acceptUrl',
628
            'rejectUrl'
629
        );
630
        foreach ($templateParams as $templateParam) {
631
            $template->assign($templateParam, $data[$templateParam]);
632
        }
633
        $mailIds = array();
634
        switch ($actionType) {
635
            case ADVANCED_SUBSCRIPTION_ACTION_STUDENT_REQUEST:
636
                // Mail to student
637
                $mailIds['render'] = $this->sendMailMessage(
638
                    $data['studentUserId'],
639
                    $data['student']['user_id'],
640
                    $this->get_lang('MailStudentRequest'),
641
                    $template->fetch('/advanced_subscription/views/student_notice_student.tpl'),
642
                    $data['sessionId'],
643
                    true
644
                );
645
                // Mail to superior
646
                $mailIds[] = $this->sendMailMessage(
647
                    $data['studentUserId'],
648
                    $data['superior']['user_id'],
649
                    $this->get_lang('MailStudentRequest'),
650
                    $template->fetch('/advanced_subscription/views/student_notice_superior.tpl'),
651
                    $data['sessionId']
652
                );
653
                break;
654
            case ADVANCED_SUBSCRIPTION_ACTION_SUPERIOR_APPROVE:
655
                // Mail to student
656
                $mailIds[] = $this->sendMailMessage(
657
                    $data['studentUserId'],
658
                    $data['student']['user_id'],
659
                    $this->get_lang('MailBossAccept'),
660
                    $template->fetch('/advanced_subscription/views/superior_accepted_notice_student.tpl'),
661
                    $data['sessionId'],
662
                    true
663
                );
664
                // Mail to superior
665
                $mailIds['render'] = $this->sendMailMessage(
666
                    $data['studentUserId'],
667
                    $data['superior']['user_id'],
668
                    $this->get_lang('MailBossAccept'),
669
                    $template->fetch('/advanced_subscription/views/superior_accepted_notice_superior.tpl'),
670
                    $data['sessionId']
671
                );
672
                // Mail to admin
673
                foreach ($data['admins'] as $adminId => $admin) {
674
                    $template->assign('admin', $admin);
675
                    $mailIds[] = $this->sendMailMessage(
676
                        $data['studentUserId'],
677
                        $adminId,
678
                        $this->get_lang('MailBossAccept'),
679
                        $template->fetch('/advanced_subscription/views/superior_accepted_notice_admin.tpl'),
680
                        $data['sessionId']
681
                    );
682
                }
683
                break;
684
            case ADVANCED_SUBSCRIPTION_ACTION_SUPERIOR_DISAPPROVE:
685
                // Mail to student
686
                $mailIds[] = $this->sendMailMessage(
687
                    $data['studentUserId'],
688
                    $data['student']['user_id'],
689
                    $this->get_lang('MailBossReject'),
690
                    $template->fetch('/advanced_subscription/views/superior_rejected_notice_student.tpl'),
691
                    $data['sessionId'],
692
                    true
693
                );
694
                // Mail to superior
695
                $mailIds['render'] = $this->sendMailMessage(
696
                    $data['studentUserId'],
697
                    $data['superior']['user_id'],
698
                    $this->get_lang('MailBossReject'),
699
                    $template->fetch('/advanced_subscription/views/superior_rejected_notice_superior.tpl'),
700
                    $data['sessionId']
701
                );
702
                break;
703
            case ADVANCED_SUBSCRIPTION_ACTION_SUPERIOR_SELECT:
704
                // Mail to student
705
                $mailIds[] = $this->sendMailMessage(
706
                    $data['studentUserId'],
707
                    $data['student']['user_id'],
708
                    $this->get_lang('MailStudentRequestSelect'),
709
                    $template->fetch('/advanced_subscription/views/student_notice_student.tpl'),
710
                    $data['sessionId'],
711
                    true
712
                );
713
                // Mail to superior
714
                $mailIds['render'] = $this->sendMailMessage(
715
                    $data['studentUserId'],
716
                    $data['superior']['user_id'],
717
                    $this->get_lang('MailStudentRequestSelect'),
718
                    $template->fetch('/advanced_subscription/views/student_notice_superior.tpl'),
719
                    $data['sessionId']
720
                );
721
                break;
722
            case ADVANCED_SUBSCRIPTION_ACTION_ADMIN_APPROVE:
723
                $fileAttachments = array();
724
                if (api_get_plugin_setting('courselegal', 'tool_enable')) {
725
                    $courseLegal = CourseLegalPlugin::create();
726
                    $courses = SessionManager::get_course_list_by_session_id($data['sessionId']);
727
                    $course = current($courses);
0 ignored issues
show
Bug introduced by
It seems like $courses can also be of type integer; however, parameter $array of current() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

727
                    $course = current(/** @scrutinizer ignore-type */ $courses);
Loading history...
728
                    $data['courseId'] = $course['id'];
729
                    $data['course'] = api_get_course_info_by_id($data['courseId']);
730
                    $termsAndConditions = $courseLegal->getData($data['courseId'], $data['sessionId']);
731
                    $termsAndConditions = $termsAndConditions['content'];
732
                    $termsAndConditions = $this->renderTemplateString($termsAndConditions, $data);
733
                    $tpl = new Template(get_lang('TermsAndConditions'));
734
                    $tpl->assign('session', $data['session']);
735
                    $tpl->assign('student', $data['student']);
736
                    $tpl->assign('sessionId', $data['sessionId']);
737
                    $tpl->assign('termsContent', $termsAndConditions);
738
                    $termsAndConditions = $tpl->fetch('/advanced_subscription/views/terms_and_conditions_to_pdf.tpl');
739
                    $pdf = new PDF();
740
                    $filename = 'terms'.sha1(rand(0, 99999));
741
                    $pdf->content_to_pdf($termsAndConditions, null, $filename, null, 'F');
742
                    $fileAttachments['file'][] = array(
743
                        'name' => $filename.'.pdf',
744
                        'application/pdf' => $filename.'.pdf',
745
                        'tmp_name' => api_get_path(SYS_ARCHIVE_PATH).$filename.'.pdf',
746
                        'error' => UPLOAD_ERR_OK,
747
                        'size' => filesize(api_get_path(SYS_ARCHIVE_PATH).$filename.'.pdf'),
748
                    );
749
                    $fileAttachments['comments'][] = get_lang('TermsAndConditions');
750
                }
751
                // Mail to student
752
                $mailIds[] = $this->sendMailMessage(
753
                    $data['studentUserId'],
754
                    $data['student']['user_id'],
755
                    $this->get_lang('MailAdminAccept'),
756
                    $template->fetch('/advanced_subscription/views/admin_accepted_notice_student.tpl'),
757
                    $data['sessionId'],
758
                    true,
759
                    $fileAttachments
760
                );
761
                // Mail to superior
762
                $mailIds[] = $this->sendMailMessage(
763
                    $data['studentUserId'],
764
                    $data['superior']['user_id'],
765
                    $this->get_lang('MailAdminAccept'),
766
                    $template->fetch('/advanced_subscription/views/admin_accepted_notice_superior.tpl'),
767
                    $data['sessionId']
768
                );
769
                // Mail to admin
770
                $adminId = $data['currentUserId'];
771
                $template->assign('admin', $data['admins'][$adminId]);
772
                $mailIds['render'] = $this->sendMailMessage(
773
                    $data['studentUserId'],
774
                    $adminId,
775
                    $this->get_lang('MailAdminAccept'),
776
                    $template->fetch('/advanced_subscription/views/admin_accepted_notice_admin.tpl'),
777
                    $data['sessionId']
778
                );
779
                break;
780
            case ADVANCED_SUBSCRIPTION_ACTION_ADMIN_DISAPPROVE:
781
                // Mail to student
782
                $mailIds[] = $this->sendMailMessage(
783
                    $data['studentUserId'],
784
                    $data['student']['user_id'],
785
                    $this->get_lang('MailAdminReject'),
786
                    $template->fetch('/advanced_subscription/views/admin_rejected_notice_student.tpl'),
787
                    $data['sessionId'],
788
                    true
789
                );
790
                // Mail to superior
791
                $mailIds[] = $this->sendMailMessage(
792
                    $data['studentUserId'],
793
                    $data['superior']['user_id'],
794
                    $this->get_lang('MailAdminReject'),
795
                    $template->fetch('/advanced_subscription/views/admin_rejected_notice_superior.tpl'),
796
                    $data['sessionId']
797
                );
798
                // Mail to admin
799
                $adminId = $data['currentUserId'];
800
                $template->assign('admin', $data['admins'][$adminId]);
801
                $mailIds['render'] = $this->sendMailMessage(
802
                    $data['studentUserId'],
803
                    $adminId,
804
                    $this->get_lang('MailAdminReject'),
805
                    $template->fetch('/advanced_subscription/views/admin_rejected_notice_admin.tpl'),
806
                    $data['sessionId']
807
                );
808
                break;
809
            case ADVANCED_SUBSCRIPTION_ACTION_STUDENT_REQUEST_NO_BOSS:
810
                // Mail to student
811
                $mailIds['render'] = $this->sendMailMessage(
812
                    $data['studentUserId'],
813
                    $data['student']['user_id'],
814
                    $this->get_lang('MailStudentRequestNoBoss'),
815
                    $template->fetch('/advanced_subscription/views/student_no_superior_notice_student.tpl'),
816
                    $data['sessionId'],
817
                    true
818
                );
819
                // Mail to admin
820
                foreach ($data['admins'] as $adminId => $admin) {
821
                    $template->assign('admin', $admin);
822
                    $mailIds[] = $this->sendMailMessage(
823
                        $data['studentUserId'],
824
                        $adminId,
825
                        $this->get_lang('MailStudentRequestNoBoss'),
826
                        $template->fetch('/advanced_subscription/views/student_no_superior_notice_admin.tpl'),
827
                        $data['sessionId']
828
                    );
829
                }
830
                break;
831
            case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_STUDENT:
832
                $mailIds['render'] = $this->sendMailMessage(
833
                    $data['student']['user_id'],
834
                    $data['student']['user_id'],
835
                    $this->get_lang('MailRemindStudent'),
836
                    $template->fetch('/advanced_subscription/views/reminder_notice_student.tpl'),
837
                    $data['sessionId'],
838
                    true
839
                );
840
                break;
841
            case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_SUPERIOR:
842
                $mailIds['render'] = $this->sendMailMessage(
843
                    $data['students'],
844
                    $data['superior']['user_id'],
845
                    $this->get_lang('MailRemindSuperior'),
846
                    $template->fetch('/advanced_subscription/views/reminder_notice_superior.tpl'),
847
                    $data['sessionId']
848
                );
849
                break;
850
            case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_SUPERIOR_MAX:
851
                $mailIds['render'] = $this->sendMailMessage(
852
                    $data['students'],
853
                    $data['superior']['user_id'],
854
                    $this->get_lang('MailRemindSuperior'),
855
                    $template->fetch('/advanced_subscription/views/reminder_notice_superior_max.tpl'),
856
                    $data['sessionId']
857
                );
858
                break;
859
            case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_ADMIN:
860
                // Mail to admin
861
                foreach ($data['admins'] as $adminId => $admin) {
862
                    $template->assign('admin', $admin);
863
                    $mailIds[] = $this->sendMailMessage(
864
                        $data['students'],
865
                        $adminId,
866
                        $this->get_lang('MailRemindAdmin'),
867
                        $template->fetch('/advanced_subscription/views/reminder_notice_admin.tpl'),
868
                        $data['sessionId']
869
                    );
870
                }
871
                break;
872
            default:
873
                break;
874
        }
875
876
        return $mailIds;
877
    }
878
879
    /**
880
     * Count the users in queue filtered by params (sessions, status)
881
     * @param array $params Input array containing the set of
882
     * session and status to count from queue
883
     * e.g:
884
     * array('sessions' => array(215, 218, 345, 502),
885
     * 'status' => array(0, 1, 2))
886
     * @return int
887
     */
888
    public function countQueueByParams($params)
889
    {
890
        $count = 0;
891
        if (!empty($params) && is_array($params)) {
892
            $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
893
            $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...
894
            if (isset($params['sessions']) && is_array($params['sessions'])) {
895
                foreach ($params['sessions'] as &$sessionId) {
896
                    $sessionId = intval($sessionId);
897
                }
898
                $where['AND session_id IN ( ? ) '] = implode($params['sessions']);
0 ignored issues
show
Bug introduced by
The call to implode() has too few arguments starting with pieces. ( Ignorable by Annotation )

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

898
                $where['AND session_id IN ( ? ) '] = /** @scrutinizer ignore-call */ implode($params['sessions']);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
899
            }
900
            if (isset($params['status']) && is_array($params['status'])) {
901
                foreach ($params['status'] as &$status) {
902
                    $status = intval($status);
903
                }
904
                $where['AND status IN ( ? ) '] = implode($params['status']);
905
            }
906
            $where['where'] = $where;
907
            $count = Database::select('COUNT(*)', $advancedSubscriptionQueueTable, $where);
908
            $count = $count[0]['COUNT(*)'];
909
        }
910
911
        return $count;
912
    }
913
914
    /**
915
     * This method will call the Hook management insertHook to add Hook observer from this plugin
916
     */
917
    public function installHook()
918
    {
919
        $hookObserver = HookAdvancedSubscription::create();
920
        HookAdminBlock::create()->attach($hookObserver);
921
        HookWSRegistration::create()->attach($hookObserver);
922
        HookNotificationContent::create()->attach($hookObserver);
923
        HookNotificationTitle::create()->attach($hookObserver);
924
    }
925
926
    /**
927
     * This method will call the Hook management deleteHook to disable Hook observer from this plugin
928
     */
929
    public function uninstallHook()
930
    {
931
        $hookObserver = HookAdvancedSubscription::create();
932
        HookAdminBlock::create()->detach($hookObserver);
933
        HookWSRegistration::create()->detach($hookObserver);
934
        HookNotificationContent::create()->detach($hookObserver);
935
        HookNotificationTitle::create()->detach($hookObserver);
936
    }
937
938
    /**
939
     * Return the status from user in queue to session subscription
940
     * @param int $userId
941
     * @param int $sessionId
942
     *
943
     * @return bool|int
944
     */
945
    public function getQueueStatus($userId, $sessionId)
946
    {
947
        $userId = intval($userId);
948
        $sessionId = intval($sessionId);
949
        if (!empty($userId) && !empty($sessionId)) {
950
            $queueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
951
            $row = Database::select(
952
                'status',
953
                $queueTable,
954
                array(
955
                    'where' => array(
956
                        'user_id = ? AND session_id = ?' => array($userId, $sessionId),
957
                    )
958
                )
959
            );
960
961
            if (count($row) == 1) {
962
                return $row[0]['status'];
963
            } else {
964
                return ADVANCED_SUBSCRIPTION_QUEUE_STATUS_NO_QUEUE;
965
            }
966
        }
967
968
        return false;
969
    }
970
971
    /**
972
     * Return the remaining vacancy
973
     * @param $sessionId
974
     * @return bool|int
975
     */
976
    public function getVacancy($sessionId)
977
    {
978
        if (!empty($sessionId)) {
979
            $extra = new ExtraFieldValue('session');
980
            $var = $extra->get_values_by_handler_and_field_variable(
981
                $sessionId,
982
                'vacancies'
983
            );
984
            $vacancy = intval($var['value']);
985
            if (!empty($vacancy)) {
986
                $vacancy -= $this->countQueueByParams(
987
                    array(
988
                        'sessions' => array($sessionId),
989
                        'status' => array(ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED),
990
                    )
991
                );
992
                if ($vacancy >= 0) {
993
                    return $vacancy;
994
                } else {
995
                    return 0;
996
                }
997
            }
998
        }
999
1000
        return false;
1001
    }
1002
1003
    /**
1004
     * Return the session details data from a session ID (including the extra
1005
     * fields used for the advanced subscription mechanism)
1006
     * @param $sessionId
1007
     * @return bool|mixed
1008
     */
1009
    public function getSessionDetails($sessionId)
1010
    {
1011
        if (!empty($sessionId)) {
1012
            // Assign variables
1013
            $fieldsArray = array(
1014
                'code',
1015
                'cost',
1016
                'place',
1017
                'allow_visitors',
1018
                'teaching_hours',
1019
                'brochure',
1020
                'banner',
1021
            );
1022
            $extraField = new ExtraField('session');
1023
            // Get session fields
1024
            $fieldList = $extraField->get_all(array(
1025
                'variable IN ( ?, ?, ?, ?, ?, ?, ? )' => $fieldsArray
1026
            ));
1027
            // Index session fields
1028
            $fields = array();
1029
            foreach ($fieldList as $field) {
1030
                $fields[$field['id']] = $field['variable'];
1031
            }
1032
1033
            $mergedArray = array_merge(array($sessionId), array_keys($fields));
1034
1035
            $sql = "SELECT * FROM ".Database::get_main_table(TABLE_EXTRA_FIELD_VALUES)."
1036
                    WHERE item_id = %d AND field_id IN (%d, %d, %d, %d, %d, %d, %d)";
1037
            $sql = vsprintf($sql, $mergedArray);
1038
            $sessionFieldValueList = Database::query($sql);
1039
            while ($sessionFieldValue = Database::fetch_assoc($sessionFieldValueList)) {
1040
                // Check if session field value is set in session field list
1041
                if (isset($fields[$sessionFieldValue['field_id']])) {
1042
                    $var = $fields[$sessionFieldValue['field_id']];
1043
                    $val = $sessionFieldValue['value'];
1044
                    // Assign session field value to session
1045
                    $sessionArray[$var] = $val;
1046
                }
1047
            }
1048
            $sessionArray['description'] = SessionManager::getDescriptionFromSessionId($sessionId);
1049
1050
            if (isset($sessionArray['brochure'])) {
1051
                $sessionArray['brochure'] = api_get_path(WEB_UPLOAD_PATH).$sessionArray['brochure'];
1052
            }
1053
            if (isset($sessionArray['banner'])) {
1054
                $sessionArray['banner'] = api_get_path(WEB_UPLOAD_PATH).$sessionArray['banner'];
1055
            }
1056
1057
            return $sessionArray;
1058
        }
1059
1060
        return false;
1061
    }
1062
1063
    /**
1064
     * Get status message
1065
     * @param int $status
1066
     * @param bool $isAble
1067
     *
1068
     * @return string
1069
     */
1070
    public function getStatusMessage($status, $isAble = true)
1071
    {
1072
        switch ($status) {
1073
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_NO_QUEUE:
1074
                $message = $this->get_lang('AdvancedSubscriptionNoQueue');
1075
                if ($isAble) {
1076
                    $message = $this->get_lang('AdvancedSubscriptionNoQueueIsAble');
1077
                }
1078
                break;
1079
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_START:
1080
                $message = $this->get_lang('AdvancedSubscriptionQueueStart');
1081
                break;
1082
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_DISAPPROVED:
1083
                $message = $this->get_lang('AdvancedSubscriptionQueueBossDisapproved');
1084
                break;
1085
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_APPROVED:
1086
                $message = $this->get_lang('AdvancedSubscriptionQueueBossApproved');
1087
                break;
1088
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_DISAPPROVED:
1089
                $message = $this->get_lang('AdvancedSubscriptionQueueAdminDisapproved');
1090
                break;
1091
            case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED:
1092
                $message = $this->get_lang('AdvancedSubscriptionQueueAdminApproved');
1093
                break;
1094
            default:
1095
                $message = sprintf($this->get_lang('AdvancedSubscriptionQueueDefault'), $status);
1096
        }
1097
1098
        return $message;
1099
    }
1100
1101
    /**
1102
     * Return the url to go to session
1103
     * @param $sessionId
1104
     *
1105
     * @return string
1106
     */
1107
    public function getSessionUrl($sessionId)
1108
    {
1109
        $url = api_get_path(WEB_CODE_PATH).'session/?session_id='.intval($sessionId);
1110
1111
        return $url;
1112
    }
1113
1114
    /**
1115
     * Get a url for subscribe a user in session
1116
     * @param int $userId The user ID
1117
     * @param array $params Params from WS
1118
     * @return string
1119
     */
1120
    public function getOpenSessionUrl($userId, $params)
1121
    {
1122
        $userIsSubscribed = SessionManager::isUserSubscribedAsStudent(
1123
            $params['session_id'],
1124
            $userId
1125
        );
1126
1127
        if ($userIsSubscribed) {
1128
            return api_get_path(WEB_CODE_PATH)
1129
                . 'session/index.php?session_id='
1130
                . intval($params['session_id']);
1131
        }
1132
1133
        $params['secret_key'] = null;
1134
        $params['user_id'] = null;
1135
        $params['user_field'] = null;
1136
        $params['is_connected'] = null;
1137
1138
        $urlParams = array_merge($params, ['user_id' => $userId]);
1139
1140
        $url = api_get_path(WEB_PLUGIN_PATH);
1141
        $url .= 'advanced_subscription/src/open_session.php?';
1142
        $url .= http_build_query($urlParams);
1143
1144
        return 'javascript:void(window.open(\''
1145
            . $url
1146
            .'\',\'AdvancedSubscriptionTerms\', \'toolbar=no,location=no,'
1147
            . 'status=no,menubar=no,scrollbars=yes,resizable=yes,width=700px,'
1148
            . 'height=600px\', \'100\' ))';
1149
    }
1150
1151
    /**
1152
     * Return the url to enter to subscription queue to session
1153
     * @param $params
1154
     * @return string
1155
     */
1156
    public function getQueueUrl($params)
1157
    {
1158
        $url = api_get_path(WEB_PLUGIN_PATH).'advanced_subscription/ajax/advanced_subscription.ajax.php?'.
1159
            'a='.Security::remove_XSS($params['action']).'&'.
1160
            's='.intval($params['sessionId']).'&'.
1161
            'current_user_id='.intval($params['currentUserId']).'&'.
1162
            'e='.intval($params['newStatus']).'&'.
1163
            'u='.intval($params['studentUserId']).'&'.
1164
            'q='.intval($params['queueId']).'&'.
1165
            'is_connected=1&'.
1166
            'profile_completed='.intval($params['profile_completed']).'&'.
1167
            'v='.$this->generateHash($params);
1168
1169
        return $url;
1170
    }
1171
1172
    /**
1173
     * Return the list of student, in queue used by admin view
1174
     * @param int $sessionId
1175
     *
1176
     * @return array
1177
     */
1178
    public function listAllStudentsInQueueBySession($sessionId)
1179
    {
1180
        // Filter input variable
1181
        $sessionId = intval($sessionId);
1182
        // Assign variables
1183
        $fieldsArray = array(
1184
            'target',
1185
            'publication_end_date',
1186
            'mode',
1187
            'recommended_number_of_participants',
1188
            'vacancies'
1189
        );
1190
        $sessionArray = api_get_session_info($sessionId);
1191
        $extraSession = new ExtraFieldValue('session');
1192
        $extraField = new ExtraField('session');
1193
        // Get session fields
1194
        $fieldList = $extraField->get_all(array(
1195
            'variable IN ( ?, ?, ?, ?, ?)' => $fieldsArray
1196
        ));
1197
        // Index session fields
1198
        $fields = array();
1199
        foreach ($fieldList as $field) {
1200
            $fields[$field['id']] = $field['variable'];
1201
        }
1202
1203
        $mergedArray = array_merge(array($sessionId), array_keys($fields));
1204
        $sessionFieldValueList = $extraSession->get_all(
1205
            array(
1206
                'item_id = ? field_id IN ( ?, ?, ?, ?, ?, ?, ? )' => $mergedArray
1207
            )
1208
        );
1209
        foreach ($sessionFieldValueList as $sessionFieldValue) {
1210
            // Check if session field value is set in session field list
1211
            if (isset($fields[$sessionFieldValue['field_id']])) {
1212
                $var = $fields[$sessionFieldValue['field_id']];
1213
                $val = $sessionFieldValue['value'];
1214
                // Assign session field value to session
1215
                $sessionArray[$var] = $val;
1216
            }
1217
        }
1218
        $queueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
1219
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
1220
        $userJoinTable = $queueTable.' q INNER JOIN '.$userTable.' u ON q.user_id = u.user_id';
1221
        $where = array(
1222
            'where' => array(
1223
                'q.session_id = ?' => array(
1224
                    $sessionId
1225
                )
1226
            ),
1227
            'order' => 'q.status DESC, u.lastname ASC'
1228
        );
1229
        $select = 'u.user_id, u.firstname, u.lastname, q.created_at, q.updated_at, q.status, q.id as queue_id';
1230
        $students = Database::select($select, $userJoinTable, $where);
1231
        foreach ($students as &$student) {
1232
            $status = intval($student['status']);
1233
            switch ($status) {
1234
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_NO_QUEUE:
1235
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_START:
1236
                    $student['validation'] = '';
1237
                    break;
1238
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_DISAPPROVED:
1239
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_DISAPPROVED:
1240
                    $student['validation'] = 'No';
1241
                    break;
1242
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_APPROVED:
1243
                case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED:
1244
                    $student['validation'] = 'Yes';
1245
                    break;
1246
                default:
1247
                    error_log(__FILE__.' '.__FUNCTION__.' Student status no detected');
1248
            }
1249
        }
1250
        $return = array(
1251
            'session' => $sessionArray,
1252
            'students' => $students,
1253
        );
1254
1255
        return $return;
1256
    }
1257
1258
    /**
1259
     * List all session (id, name) for select input
1260
     * @param int $limit
1261
     * @return array
1262
     */
1263
    public function listAllSessions($limit = 100)
1264
    {
1265
        $limit = intval($limit);
1266
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
1267
        $columns = 'id, name';
1268
        $conditions = array();
1269
        if ($limit > 0) {
1270
            $conditions = array(
1271
                'order' => 'name',
1272
                'limit' => $limit,
1273
            );
1274
        }
1275
1276
        return Database::select($columns, $sessionTable, $conditions);
1277
    }
1278
1279
    /**
1280
     * Generate security hash to check data send by url params
1281
     * @param string $data
1282
     * @return string
1283
     */
1284
    public function generateHash($data)
1285
    {
1286
        $key = sha1($this->get('secret_key'));
1287
        // Prepare array to have specific type variables
1288
        $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...
1289
        $dataPrepared['sessionId'] = intval($data['sessionId']);
1290
        $dataPrepared['currentUserId'] = intval($data['currentUserId']);
1291
        $dataPrepared['studentUserId'] = intval($data['studentUserId']);
1292
        $dataPrepared['queueId'] = intval($data['queueId']);
1293
        $dataPrepared['newStatus'] = intval($data['newStatus']);
1294
        $dataPrepared = serialize($dataPrepared);
1295
        return sha1($dataPrepared.$key);
1296
    }
1297
1298
    /**
1299
     * Verify hash from data
1300
     * @param string $data
1301
     * @param string $hash
1302
     * @return bool
1303
     */
1304
    public function checkHash($data, $hash)
1305
    {
1306
        return $this->generateHash($data) == $hash;
1307
    }
1308
1309
    /**
1310
     * Copied and fixed from plugin.class.php
1311
     * Returns the "system" name of the plugin in lowercase letters
1312
     * @return string
1313
     */
1314
    public function get_name()
1315
    {
1316
        return 'advanced_subscription';
1317
    }
1318
1319
    /**
1320
     * Return the url to show subscription terms
1321
     * @param array $params
1322
     * @param int $mode
1323
     * @return string
1324
     */
1325
    public function getTermsUrl($params, $mode = ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP)
1326
    {
1327
        $urlParams = array(
1328
            'a' => Security::remove_XSS($params['action']),
1329
            's' => intval($params['sessionId']),
1330
            'current_user_id' => intval($params['currentUserId']),
1331
            'e' => intval($params['newStatus']),
1332
            'u' => intval($params['studentUserId']),
1333
            'q' => intval($params['queueId']),
1334
            'is_connected' => 1,
1335
            'profile_completed' => intval($params['profile_completed']),
1336
            'v' => $this->generateHash($params)
1337
        );
1338
1339
        switch ($mode) {
1340
            case ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP:
1341
                // no break
1342
            case ADVANCED_SUBSCRIPTION_TERMS_MODE_FINAL:
1343
                $urlParams['r'] = 0;
1344
                break;
1345
            case ADVANCED_SUBSCRIPTION_TERMS_MODE_REJECT:
1346
                $urlParams['r'] = 1;
1347
                break;
1348
        }
1349
1350
        $url = api_get_path(WEB_PLUGIN_PATH)."advanced_subscription/src/terms_and_conditions.php?";
1351
        $url .= http_build_query($urlParams);
1352
1353
        // Launch popup
1354
        if ($mode == ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP) {
1355
            $url = 'javascript:void(window.open(\''.$url.'\',\'AdvancedSubscriptionTerms\', \'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=700px,height=600px\', \'100\' ))';
1356
        }
1357
        return $url;
1358
    }
1359
1360
    /**
1361
     * Return the url to get mail rendered
1362
     * @param array $params
1363
     * @return string
1364
     */
1365
    public function getRenderMailUrl($params)
1366
    {
1367
        $url = api_get_path(WEB_PLUGIN_PATH).'advanced_subscription/src/render_mail.php?'.
1368
            'q='.$params['queueId'].'&'.
1369
            'v='.$this->generateHash($params);
1370
        return $url;
1371
    }
1372
1373
    /**
1374
     * Return the last message id from queue row
1375
     * @param int $studentUserId
1376
     * @param int $sessionId
1377
     * @return int|bool
1378
     */
1379
    public function getLastMessageId($studentUserId, $sessionId)
1380
    {
1381
        $studentUserId = intval($studentUserId);
1382
        $sessionId = intval($sessionId);
1383
        if (!empty($sessionId) && !empty($studentUserId)) {
1384
            $row = Database::select(
1385
                'last_message_id',
1386
                Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE),
1387
                array(
1388
                    'where' => array(
1389
                        'user_id = ? AND session_id = ?' => array($studentUserId, $sessionId),
1390
                    )
1391
                )
1392
            );
1393
1394
            if (count($row) > 0) {
1395
                return $row[0]['last_message_id'];
1396
            }
1397
        }
1398
1399
        return false;
1400
    }
1401
1402
    /**
1403
     * Return string replacing tags "{{}}"with variables assigned in $data
1404
     * @param string $templateContent
1405
     * @param array $data
1406
     * @return string
1407
     */
1408
    public function renderTemplateString($templateContent, $data = array())
1409
    {
1410
        $twigString = new \Twig_Environment(new \Twig_Loader_String());
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Loader_String has been deprecated: since 1.18.1 (to be removed in 2.0) ( Ignorable by Annotation )

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

1410
        $twigString = new \Twig_Environment(/** @scrutinizer ignore-deprecated */ new \Twig_Loader_String());
Loading history...
1411
        $templateContent = $twigString->render(
1412
            $templateContent,
1413
            $data
1414
        );
1415
1416
        return $templateContent;
1417
    }
1418
1419
    /**
1420
     * Get the count of approved induction sessions by a user
1421
     * @param int $userId The user id
1422
     * @return int The count of approved sessions
1423
     */
1424
    private function getApprovedInductionSessions($userId)
1425
    {
1426
        $tSession = Database::get_main_table(TABLE_MAIN_SESSION);
1427
        $tSessionField = Database::get_main_table(TABLE_EXTRA_FIELD);
1428
        $tSessionFieldValues = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
1429
        $tSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1430
        $extraFieldType = \Chamilo\CoreBundle\Entity\ExtraField::SESSION_FIELD_TYPE;
1431
        $sql = "SELECT s.id FROM $tSession AS s
1432
            INNER JOIN $tSessionFieldValues AS sfv ON s.id = sfv.item_id
1433
            INNER JOIN $tSessionField AS sf ON sfv.field_id = sf.id
1434
            INNER JOIN $tSessionUser AS su ON s.id = su.session_id
1435
            WHERE
1436
                sf.extra_field_type = $extraFieldType AND
1437
                sf.variable = 'is_induction_session' AND
1438
                su.relation_type = 0 AND
1439
                su.user_id = ".intval($userId);
1440
1441
        $result = Database::query($sql);
1442
1443
        if ($result === false) {
1444
            return 0;
1445
        }
1446
1447
        $numberOfApproved = 0;
1448
1449
        while ($session = Database::fetch_assoc($result)) {
1450
            $numberOfApprovedCourses = 0;
1451
            $courses = SessionManager::get_course_list_by_session_id($session['id']);
1452
1453
            foreach ($courses as $course) {
1454
                $courseCategories = Category::load(
1455
                    null,
1456
                    null,
1457
                    $course['code'],
1458
                    null,
1459
                    null,
1460
                    $session['id'],
1461
                    false
1462
                );
1463
1464
                if (count($courseCategories) > 0 &&
1465
                    Category::userFinishedCourse($userId, $courseCategories[0])
1466
                ) {
1467
                    $numberOfApprovedCourses++;
1468
                }
1469
            }
1470
1471
            if ($numberOfApprovedCourses === count($courses)) {
0 ignored issues
show
Bug introduced by
It seems like $courses can also be of type integer; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

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

1471
            if ($numberOfApprovedCourses === count(/** @scrutinizer ignore-type */ $courses)) {
Loading history...
1472
                $numberOfApproved++;
1473
            }
1474
        }
1475
1476
        return $numberOfApproved;
1477
    }
1478
}
1479