TicketManager::generateUnsubscribeLink()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\Ticket;
6
use Chamilo\CoreBundle\Entity\TicketMessage;
7
use Chamilo\CoreBundle\Entity\TicketMessageAttachment;
8
use Chamilo\CoreBundle\Entity\TicketPriority;
9
use Chamilo\CoreBundle\Entity\TicketProject;
10
use Chamilo\CoreBundle\Entity\TicketRelUser;
11
use Chamilo\CoreBundle\Entity\TicketStatus;
12
use Chamilo\CoreBundle\Entity\User;
13
use Chamilo\CoreBundle\Entity\ValidationToken;
14
use Chamilo\CoreBundle\Enums\ObjectIcon;
15
use Chamilo\CoreBundle\Enums\StateIcon;
16
use Chamilo\CoreBundle\Framework\Container;
17
use Chamilo\CoreBundle\Helpers\ValidationTokenHelper;
18
use Chamilo\CourseBundle\Entity\CLp;
19
use Symfony\Component\HttpFoundation\File\UploadedFile;
20
21
/**
22
 * Class TicketManager.
23
 */
24
class TicketManager
25
{
26
    public const PRIORITY_NORMAL = 1;
27
    public const PRIORITY_HIGH = 2;
28
    public const PRIORITY_LOW = 3;
29
30
    public const SOURCE_EMAIL = 'MAI';
31
    public const SOURCE_PHONE = 'TEL';
32
    public const SOURCE_PLATFORM = 'PLA';
33
    public const SOURCE_PRESENTIAL = 'PRE';
34
35
    public const STATUS_NEW = 1;
36
    public const STATUS_PENDING = 2;
37
    public const STATUS_UNCONFIRMED = 3;
38
    public const STATUS_CLOSE = 4;
39
    public const STATUS_FORWARDED = 5;
40
41
    public function __construct()
42
    {
43
    }
44
45
    /**
46
     * Get categories of tickets.
47
     *
48
     * @param int    $projectId
49
     * @param string $order
50
     *
51
     * @return array
52
     */
53
    public static function get_all_tickets_categories($projectId, $order = '')
54
    {
55
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
56
        $table_support_project = Database::get_main_table(TABLE_TICKET_PROJECT);
57
58
        $order = empty($order) ? 'category.total_tickets DESC' : $order;
59
        $order = Database::escape_string($order);
60
        $projectId = (int) $projectId;
61
        $accessUrlId = Container::getAccessUrlUtil()->getCurrent()->getId();
62
63
        $sql = "SELECT
64
                    category.*,
65
                    category.id category_id,
66
                    project.other_area,
67
                    project.email
68
                FROM
69
                $table_support_category category
70
                INNER JOIN $table_support_project project
71
                ON project.id = category.project_id
72
                WHERE project.id = $projectId
73
                ORDER BY $order";
74
        $result = Database::query($sql);
75
        $types = [];
76
        while ($row = Database::fetch_assoc($result)) {
77
            $types[] = $row;
78
        }
79
80
        return $types;
81
    }
82
83
    /**
84
     * @param $from
85
     * @param $numberItems
86
     * @param $column
87
     * @param $direction
88
     *
89
     * @return array
90
     */
91
    public static function getCategories($from, $numberItems, $column, $direction)
92
    {
93
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
94
        $sql = "SELECT id, title, description, total_tickets
95
                FROM $table";
96
97
        $projectId = isset($_GET['project_id']) ? (int) $_GET['project_id'] : 0;
98
        if (!empty($projectId)) {
99
            $sql .= " WHERE project_id = $projectId ";
100
        }
101
102
        if (!in_array($direction, ['ASC', 'DESC'])) {
103
            $direction = 'ASC';
104
        }
105
        $column = (int) $column;
106
        $from = (int) $from;
107
        $numberItems = (int) $numberItems;
108
109
        //$sql .= " ORDER BY col$column $direction ";
110
        $sql .= " LIMIT $from,$numberItems";
111
112
        $result = Database::query($sql);
113
        $types = [];
114
        while ($row = Database::fetch_array($result)) {
115
            $types[] = $row;
116
        }
117
118
        return $types;
119
    }
120
121
    /**
122
     * @param int $id
123
     *
124
     * @return array|mixed
125
     */
126
    public static function getCategory($id)
127
    {
128
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
129
        $id = (int) $id;
130
        $sql = "SELECT id, title, title as name, description, total_tickets
131
                FROM $table WHERE id = $id";
132
133
        $result = Database::query($sql);
134
        $category = Database::fetch_array($result);
135
136
        return $category;
137
    }
138
139
    /**
140
     * @return int
141
     */
142
    public static function getCategoriesCount()
143
    {
144
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
145
146
        $sql = "SELECT count(id) count
147
                FROM $table ";
148
        $projectId = isset($_GET['project_id']) ? (int) $_GET['project_id'] : 0;
149
        if (!empty($projectId)) {
150
            $sql .= " WHERE project_id = ".$projectId;
151
        }
152
        $result = Database::query($sql);
153
        $category = Database::fetch_array($result);
154
155
        return $category['count'];
156
    }
157
158
    /**
159
     * @param int   $id
160
     * @param array $params
161
     */
162
    public static function updateCategory($id, $params)
163
    {
164
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
165
        $id = (int) $id;
166
        Database::update($table, $params, ['id = ?' => $id]);
167
    }
168
169
    /**
170
     * @param array $params
171
     */
172
    public static function addCategory($params)
173
    {
174
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
175
        Database::insert($table, $params);
176
    }
177
178
    /**
179
     * @param int $id
180
     *
181
     * @return bool
182
     */
183
    public static function deleteCategory($id)
184
    {
185
        $id = (int) $id;
186
        if (empty($id)) {
187
            return false;
188
        }
189
190
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
191
        $sql = "UPDATE $table SET category_id = NULL WHERE category_id = $id";
192
        Database::query($sql);
193
194
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
195
        $sql = "DELETE FROM $table WHERE id = $id";
196
        Database::query($sql);
197
198
        return true;
199
    }
200
201
    /**
202
     * @param int   $categoryId
203
     * @param array $users
204
     *
205
     * @return bool
206
     */
207
    public static function addUsersToCategory($categoryId, $users)
208
    {
209
        if (empty($users) || empty($categoryId)) {
210
            return false;
211
        }
212
213
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
214
        foreach ($users as $userId) {
215
            if (false === self::userIsAssignedToCategory($userId, $categoryId)) {
216
                $params = [
217
                    'category_id' => $categoryId,
218
                    'user_id' => $userId,
219
                ];
220
                Database::insert($table, $params);
221
            }
222
        }
223
224
        return true;
225
    }
226
227
    /**
228
     * @param int $userId
229
     * @param int $categoryId
230
     *
231
     * @return bool
232
     */
233
    public static function userIsAssignedToCategory($userId, $categoryId)
234
    {
235
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
236
        $userId = (int) $userId;
237
        $categoryId = (int) $categoryId;
238
        $sql = "SELECT * FROM $table
239
                WHERE category_id = $categoryId AND user_id = $userId";
240
        $result = Database::query($sql);
241
242
        return Database::num_rows($result) > 0;
243
    }
244
245
    /**
246
     * @param int $categoryId
247
     *
248
     * @return array
249
     */
250
    public static function getUsersInCategory($categoryId)
251
    {
252
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
253
        $categoryId = (int) $categoryId;
254
        $sql = "SELECT * FROM $table WHERE category_id = $categoryId";
255
        $result = Database::query($sql);
256
257
        return Database::store_result($result);
258
    }
259
260
    /**
261
     * @param int $categoryId
262
     */
263
    public static function deleteAllUserInCategory($categoryId)
264
    {
265
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
266
        $categoryId = (int) $categoryId;
267
        $sql = "DELETE FROM $table WHERE category_id = $categoryId";
268
        Database::query($sql);
269
    }
270
271
    /**
272
     * Get all possible tickets statuses.
273
     *
274
     * @return array
275
     */
276
    public static function get_all_tickets_status()
277
    {
278
        $table = Database::get_main_table(TABLE_TICKET_STATUS);
279
        $sql = "SELECT * FROM $table";
280
        $result = Database::query($sql);
281
        $types = [];
282
        while ($row = Database::fetch_assoc($result)) {
283
            $types[] = $row;
284
        }
285
286
        return $types;
287
    }
288
289
    /**
290
     * Inserts a new ticket in the corresponding tables.
291
     *
292
     * @param int      $category_id
293
     * @param int      $course_id
294
     * @param int      $sessionId
295
     * @param int      $project_id
296
     * @param string   $other_area
297
     * @param string   $subject
298
     * @param string   $content
299
     * @param string   $personalEmail
300
     * @param array    $fileAttachments
301
     * @param string   $source
302
     * @param string   $priority
303
     * @param string   $status
304
     * @param int|null $assignedUserId
305
     * @param int      $exerciseId
306
     * @param int      $lpId
307
     *
308
     * @return bool
309
     */
310
    public static function add(
311
        $category_id,
312
        $course_id,
313
        $sessionId,
314
        $project_id,
315
        $other_area,
316
        $subject,
317
        $content,
318
        $personalEmail = '',
319
        $fileAttachments = [],
320
        $source = '',
321
        $priority = '',
322
        $status = '',
323
        $assignedUserId = null,
324
        $exerciseId = null,
325
        $lpId = null
326
    ) {
327
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
328
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
329
330
        if (empty($category_id)) {
331
            return false;
332
        }
333
334
        $currentUserId = api_get_user_id();
335
        $currentUserInfo = api_get_user_info();
336
        $now = api_get_utc_datetime();
337
        $course_id = (int) $course_id;
338
        $category_id = (int) $category_id;
339
        $project_id = (int) $project_id;
340
        $priority = empty($priority) ? self::PRIORITY_NORMAL : (int) $priority;
341
342
        if ('' === $status) {
343
            $status = self::STATUS_NEW;
344
            if ($other_area > 0) {
345
                $status = self::STATUS_FORWARDED;
346
            }
347
        }
348
349
        if (empty($assignedUserId)) {
350
            $usersInCategory = self::getUsersInCategory($category_id);
351
            if (!empty($usersInCategory) && count($usersInCategory) > 0) {
352
                $userCategoryInfo = $usersInCategory[0];
353
                if (isset($userCategoryInfo['user_id'])) {
354
                    $assignedUserId = $userCategoryInfo['user_id'];
355
                }
356
            }
357
        }
358
359
        $assignedUserInfo = [];
360
        if (!empty($assignedUserId)) {
361
            $assignedUserInfo = api_get_user_info($assignedUserId);
362
            if (empty($assignedUserInfo)) {
363
                return false;
364
            }
365
        }
366
367
        // insert_ticket
368
        $params = [
369
            'project_id' => $project_id,
370
            'category_id' => $category_id,
371
            'priority_id' => $priority,
372
            'personal_email' => $personalEmail,
373
            'status_id' => $status,
374
            'start_date' => $now,
375
            'sys_insert_user_id' => $currentUserId,
376
            'sys_insert_datetime' => $now,
377
            'sys_lastedit_user_id' => $currentUserId,
378
            'sys_lastedit_datetime' => $now,
379
            'source' => $source,
380
            'assigned_last_user' => $assignedUserId,
381
            'subject' => $subject,
382
            'message' => $content,
383
            'code' => '',
384
            'total_messages' => 0,
385
            'access_url_id' => Container::getAccessUrlUtil()->getCurrent()->getId(),
386
        ];
387
388
        if (!empty($exerciseId)) {
389
            $params['exercise_id'] = $exerciseId;
390
        }
391
392
        if (!empty($lpId)) {
393
            $params['lp_id'] = $lpId;
394
        }
395
        if (!empty($course_id)) {
396
            $params['course_id'] = $course_id;
397
        }
398
399
        if (!empty($sessionId)) {
400
            $params['session_id'] = $sessionId;
401
        }
402
        $ticketId = Database::insert($table_support_tickets, $params);
403
404
        if ($ticketId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ticketId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
405
            self::subscribeUserToTicket($ticketId, $currentUserId);
406
            $ticket_code = 'A'.str_pad($ticketId, 11, '0', STR_PAD_LEFT);
407
            $titleCreated = sprintf(
408
                get_lang('Ticket %s created'),
409
                $ticket_code
410
            );
411
412
            Display::addFlash(Display::return_message(
413
                $titleCreated,
414
                'normal',
415
                false
416
            ));
417
418
            if (0 != $assignedUserId) {
419
                self::assignTicketToUser(
420
                    $ticketId,
421
                    $assignedUserId
422
                );
423
424
                Display::addFlash(Display::return_message(
425
                    sprintf(
426
                        get_lang('Ticket <b>#%s</b> assigned to user <b>%s</b>'),
427
                        $ticket_code,
428
                        $assignedUserInfo['complete_name']
429
                    ),
430
                    'normal',
431
                    false
432
                ));
433
            }
434
435
            if (!empty($fileAttachments)) {
436
                $attachmentCount = 0;
437
                foreach ($fileAttachments as $attach) {
438
                    if (!empty($attach['tmp_name'])) {
439
                        $attachmentCount++;
440
                    }
441
                }
442
                if ($attachmentCount > 0) {
443
                    self::insertMessage(
444
                        $ticketId,
445
                        '',
446
                        '',
447
                        $fileAttachments,
448
                        $currentUserId
449
                    );
450
                }
451
            }
452
453
            // Update code
454
            $sql = "UPDATE $table_support_tickets
455
                    SET code = '$ticket_code'
456
                    WHERE id = '$ticketId'";
457
            Database::query($sql);
458
459
            // Update total
460
            $sql = "UPDATE $table_support_category
461
                    SET total_tickets = total_tickets + 1
462
                    WHERE id = $category_id";
463
            Database::query($sql);
464
465
            $helpDeskMessage =
466
                '<table>
467
                        <tr>
468
                            <td width="100px"><b>'.get_lang('User').'</b></td>
469
                            <td width="400px">'.$currentUserInfo['complete_name'].'</td>
470
                        </tr>
471
                        <tr>
472
                            <td width="100px"><b>'.get_lang('Username').'</b></td>
473
                            <td width="400px">'.$currentUserInfo['username'].'</td>
474
                        </tr>
475
                        <tr>
476
                            <td width="100px"><b>'.get_lang('E-mail').'</b></td>
477
                            <td width="400px">'.$currentUserInfo['email'].'</td>
478
                        </tr>
479
                        <tr>
480
                            <td width="100px"><b>'.get_lang('Phone').'</b></td>
481
                            <td width="400px">'.$currentUserInfo['phone'].'</td>
482
                        </tr>
483
                        <tr>
484
                            <td width="100px"><b>'.get_lang('Date').'</b></td>
485
                            <td width="400px">'.api_convert_and_format_date($now, DATE_TIME_FORMAT_LONG).'</td>
486
                        </tr>
487
                        <tr>
488
                            <td width="100px"><b>'.get_lang('Title').'</b></td>
489
                            <td width="400px">'.Security::remove_XSS($subject).'</td>
490
                        </tr>
491
                        <tr>
492
                            <td width="100px"><b>'.get_lang('Description').'</b></td>
493
                            <td width="400px">'.Security::remove_XSS($content).'</td>
494
                        </tr>
495
                    </table>';
496
497
            if (0 != $assignedUserId) {
498
                $href = api_get_path(WEB_CODE_PATH).'ticket/ticket_details.php?ticket_id='.$ticketId;
499
                $helpDeskMessage .= sprintf(
500
                    get_lang("Ticket assigned to %s. Follow-up at <a href='%s'>#%s</a>."),
501
                    $assignedUserInfo['complete_name'],
502
                    $href,
503
                    $ticketId
504
                );
505
            }
506
507
            if (empty($category_id)) {
508
                if ('true' === api_get_setting('ticket_send_warning_to_all_admins')) {
509
                    $warningSubject = sprintf(
510
                        get_lang('Ticket %s was created without a category'),
511
                        $ticket_code
512
                    );
513
                    Display::addFlash(Display::return_message($warningSubject));
514
515
                    $admins = UserManager::get_all_administrators();
516
                    foreach ($admins as $userId => $data) {
517
                        if ($data['active']) {
518
                            MessageManager::send_message_simple(
519
                                $userId,
520
                                $warningSubject,
521
                                $helpDeskMessage
522
                            );
523
                        }
524
                    }
525
                }
526
            } else {
527
                $categoryInfo = self::getCategory($category_id);
528
                $usersInCategory = self::getUsersInCategory($category_id);
529
                $message = '<h2>'.get_lang('Ticket info').'</h2><br />'.$helpDeskMessage;
530
531
                if ('true' === api_get_setting('ticket_warn_admin_no_user_in_category')) {
532
                    $usersInCategory = self::getUsersInCategory($category_id);
533
                    if (empty($usersInCategory)) {
534
                        $subject = sprintf(
535
                            get_lang('Warning: No one has been assigned to category %s'),
536
                            $categoryInfo['title']
537
                        );
538
539
                        if ('true' === api_get_setting('ticket_send_warning_to_all_admins')) {
540
                            Display::addFlash(Display::return_message(
541
                                sprintf(
542
                                    get_lang(
543
                                        'A notification was sent to the administrators to report this category has no user assigned'
544
                                    ),
545
                                    $categoryInfo['title']
546
                                ),
547
                                null,
548
                                false
549
                            ));
550
551
                            $admins = UserManager::get_all_administrators();
552
                            foreach ($admins as $userId => $data) {
553
                                if ($data['active']) {
554
                                    self::sendNotification(
555
                                        $ticketId,
556
                                        $subject,
557
                                        $message,
558
                                        $userId
559
                                    );
560
                                }
561
                            }
562
                        } else {
563
                            Display::addFlash(Display::return_message($subject));
564
                        }
565
                    }
566
                }
567
568
                // Send notification to all users
569
                if (!empty($usersInCategory)) {
570
                    foreach ($usersInCategory as $data) {
571
                        if ($data['user_id'] && $data['user_id'] !== $currentUserId) {
572
                            self::sendNotification(
573
                                $ticketId,
574
                                $titleCreated,
575
                                $helpDeskMessage,
576
                                $data['user_id']
577
                            );
578
                        }
579
                    }
580
                }
581
            }
582
583
            if (!empty($personalEmail)) {
584
                api_mail_html(
585
                    get_lang('Virtual support'),
586
                    $personalEmail,
587
                    get_lang('The incident has been sent to the virtual support team again'),
588
                    $helpDeskMessage
589
                );
590
            }
591
592
            self::sendNotification(
593
                $ticketId,
594
                $titleCreated,
595
                $helpDeskMessage
596
            );
597
598
            return true;
599
        }
600
601
        return false;
602
    }
603
604
    /**
605
     * Assign ticket to admin.
606
     *
607
     * @param int $ticketId
608
     * @param int $userId
609
     *
610
     * @return bool
611
     */
612
    public static function assignTicketToUser(
613
        $ticketId,
614
        $userId
615
    ) {
616
        $ticketId = (int) $ticketId;
617
        $userId = (int) $userId;
618
619
        if (empty($ticketId)) {
620
            return false;
621
        }
622
623
        $ticket = self::get_ticket_detail_by_id($ticketId);
624
625
        if ($ticket) {
626
            $table = Database::get_main_table(TABLE_TICKET_TICKET);
627
            $sql = "UPDATE $table
628
                    SET assigned_last_user = $userId
629
                    WHERE id = $ticketId";
630
            Database::query($sql);
631
632
            $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
633
            $params = [
634
                'ticket_id' => $ticketId,
635
                'user_id' => $userId,
636
                'sys_insert_user_id' => api_get_user_id(),
637
                'assigned_date' => api_get_utc_datetime(),
638
            ];
639
            Database::insert($table, $params);
640
641
            return true;
642
        } else {
643
            return false;
644
        }
645
    }
646
647
    /**
648
     * Insert message between Users and Admins.
649
     *
650
     * @param int    $ticketId
651
     * @param string $subject
652
     * @param string $content
653
     * @param array  $fileAttachments
654
     * @param int    $userId
655
     * @param string $status
656
     * @param bool   $sendConfirmation
657
     *
658
     * @return bool
659
     */
660
    public static function insertMessage(
661
        $ticketId,
662
        $subject,
663
        $content,
664
        $fileAttachments,
665
        $userId,
666
        $status = 'NOL',
667
        $sendConfirmation = false
668
    ) {
669
        $ticketId = (int) $ticketId;
670
        $userId = (int) $userId;
671
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
672
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
673
        if ($sendConfirmation) {
674
            $form =
675
                '<form action="ticket_details.php?ticket_id='.$ticketId.'" id="confirmticket" method="POST" >
676
                     <p>'.get_lang('Was this answer satisfactory?').'</p>
677
                     <button class="btn btn--primary responseyes" name="response" id="responseyes" value="1">'.
678
                get_lang('Yes').'</button>
679
                     <button class="btn btn--danger responseno" name="response" id="responseno" value="0">'.
680
                get_lang('No').'</button>
681
                 </form>';
682
            $content .= $form;
683
        }
684
685
        $now = api_get_utc_datetime();
686
687
        $params = [
688
            'ticket_id' => $ticketId,
689
            'subject' => $subject,
690
            'message' => $content,
691
            'ip_address' => api_get_real_ip(),
692
            'sys_insert_user_id' => $userId,
693
            'sys_insert_datetime' => $now,
694
            'sys_lastedit_user_id' => $userId,
695
            'sys_lastedit_datetime' => $now,
696
            'status' => $status,
697
        ];
698
        $messageId = Database::insert($table_support_messages, $params);
699
        if ($messageId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $messageId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
700
            // update_total_message
701
            $sql = "UPDATE $table_support_tickets
702
                    SET
703
                        sys_lastedit_user_id = $userId,
704
                        sys_lastedit_datetime = '$now',
705
                        total_messages = (
706
                            SELECT COUNT(*) as total_messages
707
                            FROM $table_support_messages
708
                            WHERE ticket_id = $ticketId
709
                        )
710
                    WHERE id = $ticketId ";
711
            Database::query($sql);
712
713
            if (is_array($fileAttachments)) {
714
                foreach ($fileAttachments as $file_attach) {
715
                    if (0 == $file_attach['error']) {
716
                        self::saveMessageAttachmentFile(
717
                            $file_attach,
718
                            $ticketId,
719
                            $messageId
720
                        );
721
                    } else {
722
                        if (UPLOAD_ERR_NO_FILE != $file_attach['error']) {
723
                            return false;
724
                        }
725
                    }
726
                }
727
            }
728
729
            if (!self::isUserSubscribedToTicket($ticketId, $userId)) {
730
                self::subscribeUserToTicket($ticketId, $userId);
731
            }
732
        }
733
734
        return true;
735
    }
736
737
    /**
738
     * Attachment files when a message is sent.
739
     *
740
     * @throws \Doctrine\ORM\ORMException
741
     * @throws \Doctrine\ORM\OptimisticLockException
742
     * @throws \Doctrine\ORM\TransactionRequiredException
743
     */
744
    public static function saveMessageAttachmentFile(
745
        $fileAttach,
746
        $ticketId,
747
        $messageId
748
    ): bool {
749
        if (!is_array($fileAttach) || UPLOAD_ERR_OK != $fileAttach['error']) {
750
            return false;
751
        }
752
753
        $em = Database::getManager();
754
755
        $ticket = $em->find(Ticket::class, $ticketId);
756
        $message = $em->find(TicketMessage::class, $messageId);
757
758
        $newFileName = add_ext_on_mime(
759
            stripslashes($fileAttach['name']),
760
            $fileAttach['type']
761
        );
762
763
        $fileName = $fileAttach['name'];
764
765
        if (!filter_extension($newFileName)) {
766
            Display::addFlash(
767
                Display::return_message(
768
                    get_lang('File upload failed: this file extension or file type is prohibited'),
769
                    'error'
770
                )
771
            );
772
773
            return false;
774
        }
775
776
        $currentUser = api_get_user_entity();
777
778
        $repo = Container::getTicketMessageAttachmentRepository();
779
        $attachment = (new TicketMessageAttachment())
780
            ->setFilename($fileName)
781
            ->setPath(uniqid('ticket_message', true))
782
            ->setMessage($message)
783
            ->setSize((int) $fileAttach['size'])
784
            ->setTicket($ticket)
785
            ->setInsertUserId($currentUser->getId())
786
            ->setInsertDateTime(api_get_utc_datetime(null, false, true))
787
            ->setParent($currentUser)
788
        ;
789
790
        if (null !== $ticket->getAssignedLastUser()) {
791
            $attachment->addUserLink($ticket->getAssignedLastUser());
792
        }
793
794
        $em->persist($attachment);
795
        $em->flush();
796
797
        $file = new UploadedFile($fileAttach['tmp_name'], $fileAttach['name'], $fileAttach['type'], $fileAttach['error']);
798
799
        $repo->addFile($attachment, $file);
800
801
        return true;
802
    }
803
804
    /**
805
     * Get tickets by userId.
806
     *
807
     * @param int $from
808
     * @param int $number_of_items
809
     * @param $column
810
     * @param $direction
811
     *
812
     * @return array
813
     */
814
    public static function getTicketsByCurrentUser($from, $number_of_items, $column, $direction)
815
    {
816
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
817
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
818
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
819
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
820
        $direction = !empty($direction) ? $direction : 'DESC';
821
        $userId = api_get_user_id();
822
        $userInfo = api_get_user_info($userId);
823
        $accessUrlId = Container::getAccessUrlUtil()->getCurrent()->getId();
824
825
        if (empty($userInfo)) {
826
            return [];
827
        }
828
        $isAdmin = UserManager::is_admin($userId);
829
830
        if (!isset($_GET['project_id'])) {
831
            $projectId = 1;
832
        } else {
833
            $projectId = (int) $_GET['project_id'];
834
        }
835
836
        switch ($column) {
837
            case 0:
838
                $column = 'ticket_id';
839
                break;
840
            case 1:
841
                $column = 'status_title';
842
                break;
843
            case 2:
844
                $column = 'start_date';
845
                break;
846
            case 3:
847
                $column = 'sys_lastedit_datetime';
848
                break;
849
            case 4:
850
                $column = 'category_title';
851
                break;
852
            case 5:
853
                $column = 'sys_insert_user_id';
854
                break;
855
            case 6:
856
                $column = 'assigned_last_user';
857
                break;
858
            case 7:
859
                $column = 'total_messages';
860
                break;
861
            case 8:
862
                $column = 'subject';
863
                break;
864
            default:
865
                $column = 'ticket_id';
866
        }
867
868
        $sql = "SELECT DISTINCT
869
                ticket.*,
870
                ticket.id ticket_id,
871
                status.title AS status_title,
872
                ticket.start_date,
873
                ticket.sys_lastedit_datetime,
874
                cat.title AS category_title,
875
                priority.title AS priority_title,
876
                ticket.total_messages AS total_messages,
877
                ticket.message AS message,
878
                ticket.subject AS subject,
879
                ticket.assigned_last_user
880
            FROM $table_support_tickets ticket
881
            INNER JOIN $table_support_category cat
882
            ON (cat.id = ticket.category_id)
883
            INNER JOIN $table_support_priority priority
884
            ON (ticket.priority_id = priority.id)
885
            INNER JOIN $table_support_status status
886
            ON (ticket.status_id = status.id)
887
            WHERE 1=1
888
        ";
889
        $sql .= " AND ticket.access_url_id = $accessUrlId ";
890
891
        $userIsAllowInProject = self::userIsAllowInProject($projectId);
0 ignored issues
show
Deprecated Code introduced by
The function TicketManager::userIsAllowInProject() has been deprecated: Use TicketProjectHelper::userIsAllowInProject instead ( Ignorable by Annotation )

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

891
        $userIsAllowInProject = /** @scrutinizer ignore-deprecated */ self::userIsAllowInProject($projectId);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
892
893
        // Check if a role was set to the project
894
        if (false == $userIsAllowInProject) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
895
            $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
896
        }
897
898
        // Search simple
899
        if (isset($_GET['submit_simple']) && '' != $_GET['keyword']) {
900
            $keyword = Database::escape_string(trim($_GET['keyword']));
901
            $sql .= " AND (
902
                      ticket.id LIKE '%$keyword%' OR
903
                      ticket.code LIKE '%$keyword%' OR
904
                      ticket.subject LIKE '%$keyword%' OR
905
                      ticket.message LIKE '%$keyword%' OR
906
                      ticket.keyword LIKE '%$keyword%' OR
907
                      ticket.source LIKE '%$keyword%' OR
908
                      cat.title LIKE '%$keyword%' OR
909
                      status.title LIKE '%$keyword%' OR
910
                      priority.title LIKE '%$keyword%' OR
911
                      ticket.personal_email LIKE '%$keyword%'
912
            )";
913
        }
914
915
        $keywords = [
916
            'project_id' => 'ticket.project_id',
917
            'keyword_category' => 'ticket.category_id',
918
            'keyword_assigned_to' => 'ticket.assigned_last_user',
919
            'keyword_source' => 'ticket.source ',
920
            'keyword_status' => 'ticket.status_id',
921
            'keyword_priority' => 'ticket.priority_id',
922
        ];
923
924
        foreach ($keywords as $keyword => $label) {
925
            if (isset($_GET[$keyword])) {
926
                $data = Database::escape_string(trim($_GET[$keyword]));
927
                if (!empty($data)) {
928
                    $sql .= " AND $label = '$data' ";
929
                }
930
            }
931
        }
932
933
        // Search advanced
934
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
935
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
936
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
937
        $keyword_range = !empty($keyword_start_date_start) && !empty($keyword_start_date_end);
938
939
        if (false == $keyword_range && '' != $keyword_start_date_start) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
940
            $sql .= " AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start' ";
941
        }
942
        if ($keyword_range && '' != $keyword_start_date_start && '' != $keyword_start_date_end) {
943
            $sql .= " AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
944
                      AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
945
        }
946
947
        if ('' != $keyword_course) {
948
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
949
            $sql .= " AND ticket.course_id IN (
950
                     SELECT id FROM $course_table
951
                     WHERE (
952
                        title LIKE '%$keyword_course%' OR
953
                        code LIKE '%$keyword_course%' OR
954
                        visual_code LIKE '%$keyword_course%'
955
                     )
956
            )";
957
        }
958
        $sql .= " ORDER BY `$column` $direction";
959
        $sql .= " LIMIT $from, $number_of_items";
960
961
        $result = Database::query($sql);
962
        $tickets = [];
963
        $webPath = api_get_path(WEB_PATH);
964
        while ($row = Database::fetch_assoc($result)) {
965
            $userInfo = api_get_user_info($row['sys_insert_user_id']);
966
            $hrefUser = $webPath.'main/admin/user_information.php?user_id='.$userInfo['user_id'];
967
            $name = "<a href='$hrefUser'> {$userInfo['complete_name_with_username']} </a>";
968
            if (0 != $row['assigned_last_user']) {
969
                $assignedUserInfo = api_get_user_info($row['assigned_last_user']);
970
                if (!empty($assignedUserInfo)) {
971
                    $hrefResp = $webPath.'main/admin/user_information.php?user_id='.$assignedUserInfo['user_id'];
972
                    $row['assigned_last_user'] = "<a href='$hrefResp'> {$assignedUserInfo['complete_name_with_username']} </a>";
973
                } else {
974
                    $row['assigned_last_user'] = get_lang('Unknown user');
975
                }
976
            } else {
977
                if (self::STATUS_FORWARDED !== $row['status_id']) {
978
                    $row['assigned_last_user'] = '<span style="color:#ff0000;">'.get_lang('To be assigned').'</span>';
979
                } else {
980
                    $row['assigned_last_user'] = '<span style="color:#00ff00;">'.get_lang('Message resent').'</span>';
981
                }
982
            }
983
984
            switch ($row['source']) {
985
                case self::SOURCE_PRESENTIAL:
986
                    $img_source = ObjectIcon::USER;
987
                    break;
988
                case self::SOURCE_EMAIL:
989
                    $img_source = ObjectIcon::EMAIL;
990
                    break;
991
                case self::SOURCE_PHONE:
992
                    $img_source = ObjectIcon::PHONE;
993
                    break;
994
                default:
995
                    $img_source = ObjectIcon::TICKET;
996
                    break;
997
            }
998
999
            $row['start_date'] = Display::dateToStringAgoAndLongDate($row['start_date']);
1000
            $row['sys_lastedit_datetime'] = Display::dateToStringAgoAndLongDate($row['sys_lastedit_datetime']);
1001
1002
            $icon = Display::getMdiIcon(
1003
                $img_source,
1004
                'ch-tool-icon',
1005
                'margin-right: 10px; float: left;',
1006
                ICON_SIZE_SMALL,
1007
                get_lang('Information'),
1008
            );
1009
1010
            $icon .= '<a href="ticket_details.php?ticket_id='.$row['id'].'">'.$row['code'].'</a>';
1011
1012
            if ($isAdmin) {
1013
                $ticket = [
1014
                    $icon.' '.Security::remove_XSS($row['subject']),
1015
                    $row['status_title'],
1016
                    $row['start_date'],
1017
                    $row['sys_lastedit_datetime'],
1018
                    $row['category_title'],
1019
                    $name,
1020
                    $row['assigned_last_user'],
1021
                    $row['total_messages'],
1022
                ];
1023
            } else {
1024
                $ticket = [
1025
                    $icon.' '.Security::remove_XSS($row['subject']),
1026
                    $row['status_title'],
1027
                    $row['start_date'],
1028
                    $row['sys_lastedit_datetime'],
1029
                    $row['category_title'],
1030
                ];
1031
            }
1032
            if ($isAdmin) {
1033
                $ticket['0'] .= '&nbsp;&nbsp;<a
1034
                href="javascript:void(0)"
1035
                onclick="load_history_ticket(\'div_'.$row['ticket_id'].'\','.$row['ticket_id'].')">
1036
                    <a
1037
                        onclick="load_course_list(\'div_'.$row['ticket_id'].'\','.$row['ticket_id'].')"
1038
					    onmouseover="clear_course_list (\'div_'.$row['ticket_id'].'\')"
1039
					    title="'.get_lang('History').'"
1040
					    alt="'.get_lang('History').'"
1041
                    >
1042
                    '.Display::getMdiIcon('history').'
1043
                    </a>
1044
1045
					<div class="blackboard_hide" id="div_'.$row['ticket_id'].'">&nbsp;&nbsp;</div>
1046
					</a>&nbsp;&nbsp;';
1047
            }
1048
            $tickets[] = $ticket;
1049
        }
1050
1051
        return $tickets;
1052
    }
1053
1054
    /**
1055
     * @return int
1056
     */
1057
    public static function getTotalTicketsCurrentUser()
1058
    {
1059
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1060
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1061
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1062
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1063
1064
        $userInfo = api_get_user_info();
1065
        if (empty($userInfo)) {
1066
            return 0;
1067
        }
1068
        $userId = $userInfo['id'];
1069
1070
        if (!isset($_GET['project_id'])) {
1071
            $projectId = 1;
1072
        } else {
1073
            $projectId = (int) $_GET['project_id'];
1074
        }
1075
1076
        $accessUrlId = Container::getAccessUrlUtil()->getCurrent()->getId();
1077
1078
        $sql = "SELECT COUNT(ticket.id) AS total
1079
                FROM $table_support_tickets ticket
1080
                INNER JOIN $table_support_category cat
1081
                ON (cat.id = ticket.category_id)
1082
                INNER JOIN $table_support_priority priority
1083
                ON (ticket.priority_id = priority.id)
1084
                INNER JOIN $table_support_status status
1085
                ON (ticket.status_id = status.id)
1086
	            WHERE 1 = 1";
1087
1088
        $sql .= " AND ticket.access_url_id = $accessUrlId ";
1089
1090
        $allowRoleList = self::getAllowedRolesFromProject($projectId);
0 ignored issues
show
Deprecated Code introduced by
The function TicketManager::getAllowedRolesFromProject() has been deprecated: Use TicketProjectHelper::getAllowedRolesFromProject instead ( Ignorable by Annotation )

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

1090
        $allowRoleList = /** @scrutinizer ignore-deprecated */ self::getAllowedRolesFromProject($projectId);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1091
1092
        // Check if a role was set to the project
1093
        if (!empty($allowRoleList) && is_array($allowRoleList)) {
1094
            $allowed = self::userIsAllowInProject($projectId);
0 ignored issues
show
Deprecated Code introduced by
The function TicketManager::userIsAllowInProject() has been deprecated: Use TicketProjectHelper::userIsAllowInProject instead ( Ignorable by Annotation )

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

1094
            $allowed = /** @scrutinizer ignore-deprecated */ self::userIsAllowInProject($projectId);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1095
            if (!$allowed) {
1096
                $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
1097
            }
1098
        } else {
1099
            if (!api_is_platform_admin()) {
1100
                $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
1101
            }
1102
        }
1103
1104
        // Search simple
1105
        if (isset($_GET['submit_simple'])) {
1106
            if ('' != $_GET['keyword']) {
1107
                $keyword = Database::escape_string(trim($_GET['keyword']));
1108
                $sql .= " AND (
1109
                          ticket.code LIKE '%$keyword%' OR
1110
                          ticket.subject LIKE '%$keyword%' OR
1111
                          ticket.message LIKE '%$keyword%' OR
1112
                          ticket.keyword LIKE '%$keyword%' OR
1113
                          ticket.personal_email LIKE '%$keyword%' OR
1114
                          ticket.source LIKE '%$keyword%'
1115
                )";
1116
            }
1117
        }
1118
1119
        $keywords = [
1120
            'project_id' => 'ticket.project_id',
1121
            'keyword_category' => 'ticket.category_id',
1122
            'keyword_assigned_to' => 'ticket.assigned_last_user',
1123
            'keyword_source' => 'ticket.source',
1124
            'keyword_status' => 'ticket.status_id',
1125
            'keyword_priority' => 'ticket.priority_id',
1126
        ];
1127
1128
        foreach ($keywords as $keyword => $sqlLabel) {
1129
            if (isset($_GET[$keyword])) {
1130
                $data = Database::escape_string(trim($_GET[$keyword]));
1131
                $sql .= " AND $sqlLabel = '$data' ";
1132
            }
1133
        }
1134
1135
        // Search advanced
1136
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
1137
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
1138
        $keyword_range = isset($_GET['keyword_dates']) ? Database::escape_string(trim($_GET['keyword_dates'])) : '';
1139
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
1140
1141
        if (false == $keyword_range && '' != $keyword_start_date_start) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $keyword_range of type string to the boolean false. If you are specifically checking for an empty string, consider using the more explicit === '' instead.
Loading history...
1142
            $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1143
        }
1144
        if ($keyword_range && '' != $keyword_start_date_start && '' != $keyword_start_date_end) {
1145
            $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1146
                      AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1147
        }
1148
        if ('' != $keyword_course) {
1149
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1150
            $sql .= " AND ticket.course_id IN (
1151
                        SELECT id
1152
                        FROM $course_table
1153
                        WHERE (
1154
                            title LIKE '%$keyword_course%' OR
1155
                            code LIKE '%$keyword_course%' OR
1156
                            visual_code LIKE '%$keyword_course%'
1157
                        )
1158
                   ) ";
1159
        }
1160
1161
        $res = Database::query($sql);
1162
        $obj = Database::fetch_object($res);
1163
1164
        return (int) $obj->total;
1165
    }
1166
1167
    /**
1168
     * @param int $id
1169
     *
1170
     * @return false|TicketMessageAttachment
1171
     */
1172
    public static function getTicketMessageAttachment($id)
1173
    {
1174
        $id = (int) $id;
1175
        $em = Database::getManager();
1176
        $item = $em->getRepository(TicketMessageAttachment::class)->find($id);
1177
        if ($item) {
1178
            return $item;
1179
        }
1180
1181
        return false;
1182
    }
1183
1184
    /**
1185
     * @param int $id
1186
     *
1187
     * @return array
1188
     */
1189
    public static function getTicketMessageAttachmentsByTicketId($id)
1190
    {
1191
        $id = (int) $id;
1192
        $em = Database::getManager();
1193
        $items = $em->getRepository(TicketMessageAttachment::class)->findBy(['ticket' => $id]);
1194
        if ($items) {
1195
            return $items;
1196
        }
1197
1198
        return false;
1199
    }
1200
1201
    /**
1202
     * @param int $ticketId
1203
     *
1204
     * @return array
1205
     */
1206
    public static function get_ticket_detail_by_id($ticketId)
1207
    {
1208
        $attachmentRepo = Container::getTicketMessageAttachmentRepository();
1209
1210
        $ticketId = (int) $ticketId;
1211
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1212
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1213
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1214
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1215
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1216
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1217
1218
        $sql = "SELECT
1219
                    ticket.*,
1220
                    cat.title,
1221
                    status.title as status,
1222
                    priority.title priority
1223
                FROM $table_support_tickets ticket
1224
                INNER JOIN $table_support_category cat
1225
                ON (cat.id = ticket.category_id)
1226
                INNER JOIN $table_support_priority priority
1227
                ON (priority.id = ticket.priority_id)
1228
                INNER JOIN $table_support_status status
1229
                ON (status.id = ticket.status_id)
1230
		        WHERE
1231
                    ticket.id = $ticketId ";
1232
        $result = Database::query($sql);
1233
        $ticket = [];
1234
1235
        $repo = Container::getLpRepository();
1236
        if (Database::num_rows($result) > 0) {
1237
            while ($row = Database::fetch_assoc($result)) {
1238
                $row['course'] = null;
1239
                $row['start_date_from_db'] = $row['start_date'];
1240
                $row['start_date'] = api_convert_and_format_date(
1241
                    api_get_local_time($row['start_date']),
1242
                    DATE_TIME_FORMAT_LONG,
1243
                    api_get_timezone()
1244
                );
1245
                $row['end_date_from_db'] = $row['end_date'];
1246
                $row['end_date'] = api_convert_and_format_date(
1247
                    api_get_local_time($row['end_date']),
1248
                    DATE_TIME_FORMAT_LONG,
1249
                    api_get_timezone()
1250
                );
1251
                $row['sys_lastedit_datetime_from_db'] = $row['sys_lastedit_datetime'];
1252
                $row['sys_lastedit_datetime'] = api_convert_and_format_date(
1253
                    api_get_local_time($row['sys_lastedit_datetime']),
1254
                    DATE_TIME_FORMAT_LONG,
1255
                    api_get_timezone()
1256
                );
1257
                $row['course_url'] = null;
1258
                if (0 != $row['course_id']) {
1259
                    $course = api_get_course_info_by_id($row['course_id']);
1260
                    $sessionId = 0;
1261
                    if ($row['session_id']) {
1262
                        $sessionId = $row['session_id'];
1263
                    }
1264
                    if ($course) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $course of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1265
                        $row['course_url'] = '<a href="'.$course['course_public_url'].'?id_session='.$sessionId.'">'.$course['name'].'</a>';
1266
                    }
1267
                    $row['exercise_url'] = null;
1268
1269
                    if (!empty($row['exercise_id'])) {
1270
                        $exerciseTitle = ExerciseLib::getExerciseTitleById($row['exercise_id']);
1271
                        $dataExercise = [
1272
                            'cidReq' => $course['code'],
1273
                            'id_session' => $sessionId,
1274
                            'exerciseId' => $row['exercise_id'],
1275
                        ];
1276
                        $urlParamsExercise = http_build_query($dataExercise);
1277
1278
                        $row['exercise_url'] = '<a href="'.api_get_path(WEB_CODE_PATH).'exercise/overview.php?'.$urlParamsExercise.'">'.$exerciseTitle.'</a>';
1279
                    }
1280
1281
                    $row['lp_url'] = null;
1282
1283
                    if (!empty($row['lp_id'])) {
1284
                        /** @var CLp $lp */
1285
                        $lp = $repo->find($row['lp_id']);
1286
                        $dataLp = [
1287
                            'cidReq' => $course['code'],
1288
                            'id_session' => $sessionId,
1289
                            'lp_id' => $row['lp_id'],
1290
                            'action' => 'view',
1291
                        ];
1292
                        $urlParamsLp = http_build_query($dataLp);
1293
1294
                        $row['lp_url'] = '<a
1295
                            href="'.api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.$urlParamsLp.'">'.
1296
                            $lp->getTitle().
1297
                        '</a>';
1298
                    }
1299
                }
1300
1301
                $userInfo = api_get_user_info($row['sys_insert_user_id']);
1302
                $row['user_url'] = '<a href="'.api_get_path(WEB_PATH).'main/admin/user_information.php?user_id='.$userInfo['user_id'].'">
1303
                '.$userInfo['complete_name'].'</a>';
1304
                $ticket['user'] = $userInfo;
1305
                $ticket['ticket'] = $row;
1306
            }
1307
1308
            $sql = "SELECT *, message.id as message_id, user.id AS user_id
1309
                    FROM $table_support_messages message
1310
                    INNER JOIN $table_main_user user
1311
                    ON (message.sys_insert_user_id = user.id)
1312
                    WHERE user.active <> ".USER_SOFT_DELETED." AND
1313
                        message.ticket_id = '$ticketId' ";
1314
            $result = Database::query($sql);
1315
            $ticket['messages'] = [];
1316
            $attach_icon = Display::getMdiIcon(ObjectIcon::ATTACHMENT, 'ch-tool-icon', null, ICON_SIZE_SMALL);
1317
1318
            while ($row = Database::fetch_assoc($result)) {
1319
                $message = $row;
1320
                $message['admin'] = UserManager::is_admin($message['user_id']);
1321
                $message['user_info'] = api_get_user_info($message['user_id']);
1322
1323
                $messageAttachments = $attachmentRepo->findBy(['ticket' => $ticketId, 'message' => $row['message_id']]);
1324
1325
                /** @var TicketMessageAttachment $messageAttachment */
1326
                foreach ($messageAttachments as $messageAttachment) {
1327
                    $archiveURL = $attachmentRepo->getResourceFileDownloadUrl($messageAttachment);
1328
                    $link = Display::url(
1329
                        sprintf("%s (%d)", $messageAttachment->getFilename(), $messageAttachment->getSize()),
1330
                        $archiveURL
1331
                    );
1332
1333
                    $message['attachments'][] = $attach_icon.PHP_EOL.$link;
1334
                }
1335
                $ticket['messages'][] = $message;
1336
            }
1337
        }
1338
1339
        return $ticket;
1340
    }
1341
1342
    /**
1343
     * @param int $ticketId
1344
     * @param int $userId
1345
     *
1346
     * @return bool
1347
     */
1348
    public static function update_message_status($ticketId, $userId)
1349
    {
1350
        $ticketId = (int) $ticketId;
1351
        $userId = (int) $userId;
1352
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1353
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1354
        $now = api_get_utc_datetime();
1355
        $sql = "UPDATE $table_support_messages
1356
                SET
1357
                    status = 'LEI',
1358
                    sys_lastedit_user_id ='".api_get_user_id()."',
1359
                    sys_lastedit_datetime ='".$now."'
1360
                WHERE ticket_id = $ticketId ";
1361
1362
        if (api_is_platform_admin()) {
1363
            $sql .= " AND sys_insert_user_id = '$userId'";
1364
        } else {
1365
            $sql .= " AND sys_insert_user_id != '$userId'";
1366
        }
1367
        $result = Database::query($sql);
1368
        if (Database::affected_rows($result) > 0) {
1369
            Database::query(
1370
                "UPDATE $table_support_tickets SET
1371
                    status_id = ".self::STATUS_PENDING."
1372
                 WHERE id = $ticketId AND status_id = ".self::STATUS_NEW
1373
            );
1374
1375
            return true;
1376
        }
1377
1378
        return false;
1379
    }
1380
1381
    /**
1382
     * Send notification to a user through the internal messaging system.
1383
     */
1384
    public static function sendNotification($ticketId, $title, $message, $onlyToUserId = 0, $debug = false)
1385
    {
1386
        $ticketInfo = self::get_ticket_detail_by_id($ticketId);
1387
1388
        if (empty($ticketInfo)) {
1389
            return false;
1390
        }
1391
1392
        $assignedUserInfo = api_get_user_info($ticketInfo['ticket']['assigned_last_user']);
1393
        $requestUserInfo = $ticketInfo['user'];
1394
        $ticketCode = $ticketInfo['ticket']['code'];
1395
        $status = $ticketInfo['ticket']['status'];
1396
        $priority = $ticketInfo['ticket']['priority'];
1397
        $creatorId = $ticketInfo['ticket']['sys_insert_user_id'];
1398
1399
        // Subject
1400
        $titleEmail = "[$ticketCode] ".Security::remove_XSS($title);
1401
1402
        // Content
1403
        $href = api_get_path(WEB_CODE_PATH) . 'ticket/ticket_details.php?ticket_id=' . $ticketId;
1404
        $ticketUrl = Display::url($ticketCode, $href);
1405
        $messageEmailBase = get_lang('Ticket number') . ": $ticketUrl <br />";
1406
        $messageEmailBase .= get_lang('Status') . ": $status <br />";
1407
        $messageEmailBase .= get_lang('Priority') . ": $priority <br />";
1408
        $messageEmailBase .= '<hr /><br />';
1409
        $messageEmailBase .= $message;
1410
1411
        $currentUserId = api_get_user_id();
1412
        $recipients = [];
1413
1414
        if (!empty($onlyToUserId) && $currentUserId != $onlyToUserId) {
1415
            $recipients[$onlyToUserId] = $onlyToUserId;
1416
        } else {
1417
            if (
1418
                $requestUserInfo &&
1419
                $currentUserId != $requestUserInfo['id'] &&
1420
                self::isUserSubscribedToTicket($ticketId, $requestUserInfo['id'])
1421
            ) {
1422
                $recipients[$requestUserInfo['id']] = $requestUserInfo['complete_name_with_username'];
1423
            }
1424
1425
            if ($assignedUserInfo && $currentUserId != $assignedUserInfo['id']) {
1426
                $recipients[$assignedUserInfo['id']] = $assignedUserInfo['complete_name_with_username'];
1427
            }
1428
1429
            $followers = self::getFollowers($ticketId);
1430
            /* @var User $follower */
1431
            foreach ($followers as $follower) {
1432
                if (
1433
                    $follower->getId() !== $currentUserId &&
1434
                    (
1435
                        $follower->getId() !== $creatorId ||
1436
                        self::isUserSubscribedToTicket($ticketId, $follower->getId())
1437
                    )
1438
                ) {
1439
                    $recipients[$follower->getId()] = $follower->getFullName();
1440
                }
1441
            }
1442
        }
1443
1444
        if ($debug) {
1445
            echo "<pre>";
1446
            echo "Title: $titleEmail\n";
1447
            echo "Message Preview:\n\n";
1448
1449
            foreach ($recipients as $recipientId => $recipientName) {
1450
                $unsubscribeLink = self::generateUnsubscribeLink($ticketId, $recipientId);
1451
                $finalMessageEmail = $messageEmailBase;
1452
                $finalMessageEmail .= '<br /><hr /><br />';
1453
                $finalMessageEmail .= '<small>'.sprintf(get_lang('To unsubscribe from notifications, click here: %s'), '<a href="' . $unsubscribeLink . '">' . $unsubscribeLink . '</a>').'</small>';
1454
1455
                echo "------------------------------------\n";
1456
                echo "Recipient: $recipientName (User ID: $recipientId)\n";
1457
                echo "Message:\n$finalMessageEmail\n";
1458
                echo "------------------------------------\n\n";
1459
            }
1460
1461
            echo "</pre>";
1462
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1463
        }
1464
1465
        foreach ($recipients as $recipientId => $recipientName) {
1466
            $unsubscribeLink = self::generateUnsubscribeLink($ticketId, $recipientId);
1467
1468
            $finalMessageEmail = $messageEmailBase;
1469
            $finalMessageEmail .= '<br /><hr /><br />';
1470
            $finalMessageEmail .= '<small>'.sprintf(get_lang('To unsubscribe from notifications, click here: %s'), '<a href="' . $unsubscribeLink . '">' . $unsubscribeLink . '</a>').'</small>';
1471
1472
            MessageManager::send_message_simple(
1473
                $recipientId,
1474
                $titleEmail,
1475
                $finalMessageEmail,
1476
                0,
1477
                false,
1478
                false,
1479
                false
1480
            );
1481
        }
1482
1483
        return true;
1484
    }
1485
1486
    /**
1487
     * @param array $params
1488
     * @param int   $ticketId
1489
     * @param int   $userId
1490
     *
1491
     * @return bool
1492
     */
1493
    public static function updateTicket(
1494
        $params,
1495
        $ticketId,
1496
        $userId
1497
    ) {
1498
        $now = api_get_utc_datetime();
1499
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1500
        $newParams = [
1501
            'priority_id' => isset($params['priority_id']) ? (int) $params['priority_id'] : '',
1502
            'status_id' => isset($params['status_id']) ? (int) $params['status_id'] : '',
1503
            'sys_lastedit_user_id' => (int) $userId,
1504
            'sys_lastedit_datetime' => $now,
1505
        ];
1506
        Database::update($table, $newParams, ['id = ? ' => $ticketId]);
1507
1508
        return true;
1509
    }
1510
1511
    /**
1512
     * @param int $status_id
1513
     * @param int $ticketId
1514
     * @param int $userId
1515
     *
1516
     * @return bool
1517
     */
1518
    public static function update_ticket_status(
1519
        $status_id,
1520
        $ticketId,
1521
        $userId
1522
    ) {
1523
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1524
1525
        $ticketId = (int) $ticketId;
1526
        $status_id = (int) $status_id;
1527
        $userId = (int) $userId;
1528
        $now = api_get_utc_datetime();
1529
1530
        $sql = "UPDATE $table_support_tickets
1531
                SET
1532
                    status_id = '$status_id',
1533
                    sys_lastedit_user_id ='$userId',
1534
                    sys_lastedit_datetime ='".$now."'
1535
                WHERE id ='$ticketId'";
1536
        $result = Database::query($sql);
1537
1538
        if (Database::affected_rows($result) > 0) {
1539
            self::sendNotification(
1540
                $ticketId,
1541
                get_lang('Ticket updated'),
1542
                get_lang('Ticket updated')
1543
            );
1544
1545
            return true;
1546
        }
1547
1548
        return false;
1549
    }
1550
1551
    /**
1552
     * @return mixed
1553
     */
1554
    public static function getNumberOfMessages()
1555
    {
1556
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1557
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1558
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1559
        $table_main_admin = Database::get_main_table(TABLE_MAIN_ADMIN);
1560
        $user_info = api_get_user_info();
1561
        $userId = $user_info['user_id'];
1562
        $sql = "SELECT COUNT(DISTINCT ticket.id) AS unread
1563
                FROM $table_support_tickets ticket,
1564
                $table_support_messages message ,
1565
                $table_main_user user
1566
                WHERE
1567
                    ticket.id = message.ticket_id AND
1568
                    message.status = 'NOL' AND
1569
                    user.user_id = message.sys_insert_user_id ";
1570
        if (!api_is_platform_admin()) {
1571
            $sql .= " AND ticket.request_user = '$userId'
1572
                      AND user_id IN (SELECT user_id FROM $table_main_admin)  ";
1573
        } else {
1574
            $sql .= " AND user_id NOT IN (SELECT user_id FROM $table_main_admin)
1575
                      AND ticket.status_id != '".self::STATUS_FORWARDED."'";
1576
        }
1577
        $sql .= ' AND ticket.access_url_id = '.(int) Container::getAccessUrlUtil()->getCurrent()->getId();
1578
        $sql .= "  AND ticket.project_id != '' ";
1579
        $res = Database::query($sql);
1580
        $obj = Database::fetch_object($res);
1581
1582
        return $obj->unread;
1583
    }
1584
1585
    /**
1586
     * @param int $ticketId
1587
     * @param int $userId
1588
     */
1589
    public static function send_alert($ticketId, $userId)
1590
    {
1591
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1592
        $now = api_get_utc_datetime();
1593
1594
        $ticketId = (int) $ticketId;
1595
        $userId = (int) $userId;
1596
1597
        $sql = "UPDATE $table_support_tickets SET
1598
                  priority_id = '".self::PRIORITY_HIGH."',
1599
                  sys_lastedit_user_id = $userId,
1600
                  sys_lastedit_datetime = '$now'
1601
                WHERE id = $ticketId";
1602
        Database::query($sql);
1603
    }
1604
1605
    /**
1606
     * @param int $ticketId
1607
     * @param int $userId
1608
     */
1609
    public static function close_ticket($ticketId, $userId)
1610
    {
1611
        $ticketId = (int) $ticketId;
1612
        $userId = (int) $userId;
1613
1614
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1615
        $now = api_get_utc_datetime();
1616
        $sql = "UPDATE $table_support_tickets SET
1617
                    status_id = ".self::STATUS_CLOSE.",
1618
                    sys_lastedit_user_id = $userId,
1619
                    sys_lastedit_datetime = '$now',
1620
                    end_date ='$now'
1621
                WHERE id = $ticketId";
1622
        Database::query($sql);
1623
1624
        self::sendNotification(
1625
            $ticketId,
1626
            get_lang('Ticket closed'),
1627
            get_lang('Ticket closed')
1628
        );
1629
    }
1630
1631
    /**
1632
     * Close old tickets.
1633
     */
1634
    public static function close_old_tickets()
1635
    {
1636
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1637
        $now = api_get_utc_datetime();
1638
        $userId = api_get_user_id();
1639
        $accessUrlId = (int) Container::getAccessUrlUtil()->getCurrent()->getId();
1640
1641
        $sql = "UPDATE $table
1642
            SET
1643
                status_id = '".self::STATUS_CLOSE."',
1644
                sys_lastedit_user_id ='$userId',
1645
                sys_lastedit_datetime ='$now',
1646
                end_date = '$now'
1647
            WHERE
1648
                DATEDIFF('$now', sys_lastedit_datetime) > 7 AND
1649
                status_id != '".self::STATUS_CLOSE."' AND
1650
                status_id != '".self::STATUS_NEW."' AND
1651
                status_id != '".self::STATUS_FORWARDED."' AND
1652
                access_url_id = $accessUrlId";
1653
1654
        Database::query($sql);
1655
    }
1656
1657
    /**
1658
     * @param int $ticketId
1659
     *
1660
     * @return array
1661
     */
1662
    public static function get_assign_log($ticketId)
1663
    {
1664
        $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
1665
        $ticketId = (int) $ticketId;
1666
1667
        $sql = "SELECT * FROM $table
1668
                WHERE ticket_id = $ticketId
1669
                ORDER BY assigned_date DESC";
1670
        $result = Database::query($sql);
1671
        $history = [];
1672
        $webpath = api_get_path(WEB_PATH);
1673
        while ($row = Database::fetch_assoc($result)) {
1674
            if (0 != $row['user_id']) {
1675
                $assignuser = api_get_user_info($row['user_id']);
1676
                $row['assignuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['user_id'].'"  target="_blank">'.
1677
                $assignuser['username'].'</a>';
1678
            } else {
1679
                $row['assignuser'] = get_lang('Unassign');
1680
            }
1681
            $row['assigned_date'] = Display::dateToStringAgoAndLongDate($row['assigned_date']);
1682
            $insertuser = api_get_user_info($row['sys_insert_user_id']);
1683
            $row['insertuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['sys_insert_user_id'].'"  target="_blank">'.
1684
                $insertuser['username'].'</a>';
1685
            $history[] = $row;
1686
        }
1687
1688
        return $history;
1689
    }
1690
1691
    /**
1692
     * @param $from
1693
     * @param $number_of_items
1694
     * @param $column
1695
     * @param $direction
1696
     * @param null $userId
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $userId is correct as it would always require null to be passed?
Loading history...
1697
     *
1698
     * @return array
1699
     */
1700
    public static function export_tickets_by_user_id(
1701
        $from,
1702
        $number_of_items,
1703
        $column,
1704
        $direction,
1705
        $userId = null
1706
    ) {
1707
        $from = (int) $from;
1708
        $number_of_items = (int) $number_of_items;
1709
        $table_support_category = Database::get_main_table(
1710
            TABLE_TICKET_CATEGORY
1711
        );
1712
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1713
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1714
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1715
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1716
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1717
1718
        if (is_null($direction)) {
1719
            $direction = 'DESC';
1720
        }
1721
        if (is_null($userId) || 0 == $userId) {
1722
            $userId = api_get_user_id();
1723
        }
1724
1725
        $sql = "SELECT
1726
                    ticket.code,
1727
                    ticket.sys_insert_datetime,
1728
                    ticket.sys_lastedit_datetime,
1729
                    cat.title as category,
1730
                    CONCAT(user.lastname,' ', user.firstname) AS fullname,
1731
                    status.title as status,
1732
                    ticket.total_messages as messages,
1733
                    ticket.assigned_last_user as responsable
1734
                FROM $table_support_tickets ticket,
1735
                $table_support_category cat ,
1736
                $table_support_priority priority,
1737
                $table_support_status status ,
1738
                $table_main_user user
1739
                WHERE
1740
                    cat.id = ticket.category_id
1741
                    AND ticket.priority_id = priority.id
1742
                    AND ticket.status_id = status.id
1743
                    AND user.user_id = ticket.request_user ";
1744
        $sql .= ' AND ticket.access_url_id = '.(int) Container::getAccessUrlUtil()->getCurrent()->getId();
1745
1746
        // Search simple
1747
        if (isset($_GET['submit_simple'])) {
1748
            if ('' !== $_GET['keyword']) {
1749
                $keyword = Database::escape_string(trim($_GET['keyword']));
1750
                $sql .= " AND (ticket.code = '$keyword'
1751
                          OR user.firstname LIKE '%$keyword%'
1752
                          OR user.lastname LIKE '%$keyword%'
1753
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword%'
1754
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword%'
1755
                          OR user.username LIKE '%$keyword%')  ";
1756
            }
1757
        }
1758
        // Search advanced
1759
        if (isset($_GET['submit_advanced'])) {
1760
            $keyword_category = Database::escape_string(
1761
                trim($_GET['keyword_category'])
1762
            );
1763
            $keyword_request_user = Database::escape_string(
1764
                trim($_GET['keyword_request_user'])
1765
            );
1766
            $keywordAssignedTo = (int) $_GET['keyword_assigned_to'];
1767
            $keyword_start_date_start = Database::escape_string(
1768
                trim($_GET['keyword_start_date_start'])
1769
            );
1770
            $keyword_start_date_end = Database::escape_string(
1771
                trim($_GET['keyword_start_date_end'])
1772
            );
1773
            $keyword_status = Database::escape_string(
1774
                trim($_GET['keyword_status'])
1775
            );
1776
            $keyword_source = Database::escape_string(
1777
                trim($_GET['keyword_source'])
1778
            );
1779
            $keyword_priority = Database::escape_string(
1780
                trim($_GET['keyword_priority'])
1781
            );
1782
            $keyword_range = Database::escape_string(
1783
                trim($_GET['keyword_dates'])
1784
            );
1785
            $keyword_unread = Database::escape_string(
1786
                trim($_GET['keyword_unread'])
1787
            );
1788
            $keyword_course = Database::escape_string(
1789
                trim($_GET['keyword_course'])
1790
            );
1791
1792
            if ('' != $keyword_category) {
1793
                $sql .= " AND ticket.category_id = '$keyword_category'  ";
1794
            }
1795
            if ('' != $keyword_request_user) {
1796
                $sql .= " AND (ticket.request_user = '$keyword_request_user'
1797
                          OR user.firstname LIKE '%$keyword_request_user%'
1798
                          OR user.official_code LIKE '%$keyword_request_user%'
1799
                          OR user.lastname LIKE '%$keyword_request_user%'
1800
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword_request_user%'
1801
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword_request_user%'
1802
                          OR user.username LIKE '%$keyword_request_user%') ";
1803
            }
1804
            if (!empty($keywordAssignedTo)) {
1805
                $sql .= " AND ticket.assigned_last_user = $keywordAssignedTo ";
1806
            }
1807
            if ('' != $keyword_status) {
1808
                $sql .= " AND ticket.status_id = '$keyword_status'  ";
1809
            }
1810
            if ('' == $keyword_range && '' != $keyword_start_date_start) {
1811
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1812
            }
1813
            if ('1' == $keyword_range && '' != $keyword_start_date_start && '' != $keyword_start_date_end) {
1814
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1815
                          AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1816
            }
1817
            if ('' != $keyword_priority) {
1818
                $sql .= " AND ticket.priority_id = '$keyword_priority'  ";
1819
            }
1820
            if ('' != $keyword_source) {
1821
                $sql .= " AND ticket.source = '$keyword_source' ";
1822
            }
1823
            if ('' != $keyword_priority) {
1824
                $sql .= " AND ticket.priority_id = '$keyword_priority' ";
1825
            }
1826
            if ('' != $keyword_course) {
1827
                $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1828
                $sql .= " AND ticket.course_id IN ( ";
1829
                $sql .= "SELECT id
1830
                         FROM $course_table
1831
                         WHERE (title LIKE '%$keyword_course%'
1832
                         OR code LIKE '%$keyword_course%'
1833
                         OR visual_code LIKE '%$keyword_course%' )) ";
1834
            }
1835
            if ('yes' == $keyword_unread) {
1836
                $sql .= " AND ticket.id IN (
1837
                          SELECT ticket.id
1838
                          FROM $table_support_tickets ticket,
1839
                          $table_support_messages message,
1840
                          $table_main_user user
1841
                          WHERE ticket.id = message.ticket_id
1842
                          AND message.status = 'NOL'
1843
                          AND message.sys_insert_user_id = user.user_id
1844
                          AND user.status != 1   AND ticket.status_id != '".self::STATUS_FORWARDED."'
1845
                          GROUP BY ticket.id)";
1846
            } else {
1847
                if ('no' == $keyword_unread) {
1848
                    $sql .= " AND ticket.id NOT IN (
1849
                              SELECT ticket.id
1850
                              FROM  $table_support_tickets ticket,
1851
                              $table_support_messages message,
1852
                              $table_main_user user
1853
                              WHERE ticket.id = message.ticket_id
1854
                              AND message.status = 'NOL'
1855
                              AND message.sys_insert_user_id = user.user_id
1856
                              AND user.status != 1
1857
                              AND ticket.status_id != '".self::STATUS_FORWARDED."'
1858
                             GROUP BY ticket.id)";
1859
                }
1860
            }
1861
        }
1862
1863
        $sql .= !str_contains($sql, 'WHERE') ? ' WHERE user.active <> '.USER_SOFT_DELETED : ' AND user.active <> '.USER_SOFT_DELETED;
1864
        $sql .= " LIMIT $from,$number_of_items";
1865
1866
        $result = Database::query($sql);
1867
        $tickets[0] = [
0 ignored issues
show
Comprehensibility Best Practice introduced by
$tickets was never initialized. Although not strictly required by PHP, it is generally a good practice to add $tickets = array(); before regardless.
Loading history...
1868
            utf8_decode('Ticket#'),
1869
            utf8_decode('Fecha'),
1870
            utf8_decode('Fecha Edicion'),
1871
            utf8_decode('Categoria'),
1872
            utf8_decode('Usuario'),
1873
            utf8_decode('Estado'),
1874
            utf8_decode('Mensajes'),
1875
            utf8_decode('Responsable'),
1876
            utf8_decode('Programa'),
1877
        ];
1878
1879
        while ($row = Database::fetch_assoc($result)) {
1880
            if (0 != $row['responsable']) {
1881
                $row['responsable'] = api_get_user_info($row['responsable']);
1882
                $row['responsable'] = $row['responsable']['firstname'].' '.$row['responsable']['lastname'];
1883
            }
1884
            $row['sys_insert_datetime'] = api_format_date(
1885
                $row['sys_insert_datetime'],
1886
                '%d/%m/%y - %I:%M:%S %p'
1887
            );
1888
            $row['sys_lastedit_datetime'] = api_format_date(
1889
                $row['sys_lastedit_datetime'],
1890
                '%d/%m/%y - %I:%M:%S %p'
1891
            );
1892
            $row['category'] = utf8_decode($row['category']);
1893
            $row['programa'] = utf8_decode($row['fullname']);
1894
            $row['fullname'] = utf8_decode($row['fullname']);
1895
            $row['responsable'] = utf8_decode($row['responsable']);
1896
            $tickets[] = $row;
1897
        }
1898
1899
        return $tickets;
1900
    }
1901
1902
    /**
1903
     * @param string $url
1904
     * @param int    $projectId
1905
     *
1906
     * @return FormValidator
1907
     */
1908
    public static function getCategoryForm($url, $projectId)
1909
    {
1910
        $form = new FormValidator('category', 'post', $url);
1911
        $form->addText('name', get_lang('Name'));
1912
        $form->addHtmlEditor('description', get_lang('Description'));
1913
        $form->addHidden('project_id', $projectId);
1914
        $form->addButtonUpdate(get_lang('Save'));
1915
1916
        return $form;
1917
    }
1918
1919
    /**
1920
     * @return array
1921
     */
1922
    public static function getStatusList()
1923
    {
1924
        $accessUrl = Container::getAccessUrlUtil()->getCurrent();
1925
        $items = Database::getManager()
1926
            ->getRepository(TicketStatus::class)
1927
            ->findBy(['accessUrl' => $accessUrl]);
1928
1929
        if (empty($items)) {
1930
            $items = Database::getManager()
1931
                ->getRepository(TicketStatus::class)
1932
                ->findBy(['accessUrl' => NULL]);
1933
        }
1934
        $list = [];
1935
        /** @var TicketStatus $row */
1936
        foreach ($items as $row) {
1937
            $list[$row->getId()] = $row->getTitle();
1938
        }
1939
1940
        return $list;
1941
    }
1942
1943
    /**
1944
     * @param array $criteria
1945
     *
1946
     * @return array
1947
     */
1948
    public static function getTicketsFromCriteria($criteria)
1949
    {
1950
        $items = Database::getManager()->getRepository(Ticket::class)->findBy($criteria);
1951
        $list = [];
1952
        /** @var Ticket $row */
1953
        foreach ($items as $row) {
1954
            $list[$row->getId()] = $row->getCode();
1955
        }
1956
1957
        return $list;
1958
    }
1959
1960
    /**
1961
     * @param string $code
1962
     *
1963
     * @return int
1964
     */
1965
    public static function getStatusIdFromCode($code)
1966
    {
1967
        $item = Database::getManager()
1968
            ->getRepository(TicketStatus::class)
1969
            ->findOneBy(['code' => $code])
1970
        ;
1971
1972
        if ($item) {
1973
            return $item->getId();
1974
        }
1975
1976
        return 0;
1977
    }
1978
1979
    /**
1980
     * @return array
1981
     */
1982
    public static function getPriorityList()
1983
    {
1984
        $accessUrl = Container::getAccessUrlUtil()->getCurrent();
1985
        $priorities = Database::getManager()
1986
            ->getRepository(TicketPriority::class)
1987
            ->findBy(['accessUrl' => $accessUrl]);
1988
1989
        if (empty($priorities)) {
1990
            $priorities = Database::getManager()
1991
                ->getRepository(TicketPriority::class)
1992
                ->findBy(['accessUrl' => NULL]);
1993
        }
1994
        $list = [];
1995
        /** @var TicketPriority $row */
1996
        foreach ($priorities as $row) {
1997
            $list[$row->getId()] = $row->getTitle();
1998
        }
1999
2000
        return $list;
2001
    }
2002
2003
    /**
2004
     * @return array
2005
     */
2006
    public static function getProjects()
2007
    {
2008
        $accessUrl = Container::getAccessUrlUtil()->getCurrent();
2009
        $projects = Database::getManager()
2010
            ->getRepository(TicketProject::class)
2011
            ->findBy(['accessUrl' => $accessUrl]);
2012
2013
        if (empty($projects)) {
2014
            $projects = Database::getManager()
2015
                ->getRepository(TicketProject::class)
2016
                ->findBy(['accessUrl' => NULL]);
2017
        }
2018
2019
        $list = [];
2020
        /** @var TicketProject $row */
2021
        foreach ($projects as $row) {
2022
            $list[] = [
2023
                'id' => $row->getId(),
2024
                '0' => $row->getId(),
2025
                '1' => $row->getTitle(),
2026
                '2' => $row->getDescription(),
2027
                '3' => $row->getId(),
2028
            ];
2029
        }
2030
2031
        return $list;
2032
    }
2033
2034
    /**
2035
     * @return array
2036
     */
2037
    public static function getProjectsSimple()
2038
    {
2039
        $accessUrl = Container::getAccessUrlUtil()->getCurrent();
2040
        $projects = Database::getManager()
2041
            ->getRepository(TicketProject::class)
2042
            ->findBy(['accessUrl' => $accessUrl]);
2043
2044
        if (empty($projects)) {
2045
            $projects = Database::getManager()
2046
                ->getRepository(TicketProject::class)
2047
                ->findBy(['accessUrl' => NULL]);
2048
        }
2049
        $list = [];
2050
        /** @var TicketProject $row */
2051
        foreach ($projects as $row) {
2052
            $list[] = [
2053
                'id' => $row->getId(),
2054
                '0' => $row->getId(),
2055
                '1' => Display::url(
2056
                    $row->getTitle(),
2057
                    api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id='.$row->getId()
2058
                ),
2059
                '2' => $row->getDescription(),
2060
            ];
2061
        }
2062
2063
        return $list;
2064
    }
2065
2066
    /**
2067
     * @return int
2068
     */
2069
    public static function getProjectsCount()
2070
    {
2071
        return Database::getManager()->getRepository(TicketProject::class)->createQueryBuilder('p')
2072
            ->select('COUNT(p.id)')
2073
            ->getQuery()
2074
            ->getSingleScalarResult();
2075
    }
2076
2077
    /**
2078
     * @param array $params
2079
     */
2080
    public static function addProject($params)
2081
    {
2082
        $project = new TicketProject();
2083
        $project->setTitle($params['title']);
2084
        $project->setDescription($params['description']);
2085
        $project->setInsertUserId(api_get_user_id());
2086
        $project->setAccessUrl(Container::getAccessUrlUtil()->getCurrent());
2087
2088
        Database::getManager()->persist($project);
2089
        Database::getManager()->flush();
2090
    }
2091
2092
    /**
2093
     * @param int $id
2094
     *
2095
     * @return TicketProject
2096
     */
2097
    public static function getProject($id)
2098
    {
2099
        return Database::getManager()->getRepository(TicketProject::class)->find($id);
2100
    }
2101
2102
    /**
2103
     * @param int   $id
2104
     * @param array $params
2105
     */
2106
    public static function updateProject($id, $params)
2107
    {
2108
        $project = self::getProject($id);
2109
        $project->setTitle($params['title']);
2110
        $project->setDescription($params['description']);
2111
        $project->setLastEditDateTime(new DateTime($params['sys_lastedit_datetime']));
2112
        $project->setLastEditUserId($params['sys_lastedit_user_id']);
2113
        $project->setAccessUrl(Container::getAccessUrlUtil()->getCurrent());
2114
2115
        Database::getManager()->persist($project);
2116
        Database::getManager()->flush();
2117
    }
2118
2119
    /**
2120
     * @param int $id
2121
     */
2122
    public static function deleteProject($id)
2123
    {
2124
        $project = self::getProject($id);
2125
        if ($project) {
0 ignored issues
show
introduced by
$project is of type Chamilo\CoreBundle\Entity\TicketProject, thus it always evaluated to true.
Loading history...
2126
            Database::getManager()->remove($project);
2127
            Database::getManager()->flush();
2128
        }
2129
    }
2130
2131
    /**
2132
     * @param string $url
2133
     *
2134
     * @return FormValidator
2135
     */
2136
    public static function getProjectForm($url)
2137
    {
2138
        $form = new FormValidator('project', 'post', $url);
2139
        $form->addText('name', get_lang('Name'));
2140
        $form->addHtmlEditor('description', get_lang('Description'));
2141
        $form->addButtonUpdate(get_lang('Save'));
2142
2143
        return $form;
2144
    }
2145
2146
    /**
2147
     * @return array
2148
     */
2149
    public static function getStatusAdminList()
2150
    {
2151
        $accessUrl = Container::getAccessUrlUtil()->getCurrent();
2152
        $items = Database::getManager()
2153
            ->getRepository(TicketStatus::class)
2154
            ->findBy(['accessUrl' => $accessUrl]);
2155
2156
        if (empty($items)) {
2157
            $items = Database::getManager()
2158
                ->getRepository(TicketStatus::class)
2159
                ->findBy(['accessUrl' => NULL]);
2160
        }
2161
2162
        $list = [];
2163
        /** @var TicketStatus $row */
2164
        foreach ($items as $row) {
2165
            $list[] = [
2166
                'id' => $row->getId(),
2167
                'code' => $row->getCode(),
2168
                '0' => $row->getId(),
2169
                '1' => $row->getTitle(),
2170
                '2' => $row->getDescription(),
2171
                '3' => $row->getId(),
2172
            ];
2173
        }
2174
2175
        return $list;
2176
    }
2177
2178
    /**
2179
     * @return array
2180
     */
2181
    /*public static function getStatusSimple()
2182
    {
2183
        $projects = Database::getManager()->getRepository(TicketStatus::class)->findAll();
2184
        $list = [];
2185
        // @var TicketProject $row
2186
        foreach ($projects as $row) {
2187
            $list[] = [
2188
                'id' => $row->getId(),
2189
                '0' => $row->getId(),
2190
                '1' => Display::url($row->getName()),
2191
                '2' => $row->getDescription(),
2192
            ];
2193
        }
2194
2195
        return $list;
2196
    }*/
2197
2198
    /**
2199
     * @return int
2200
     */
2201
    public static function getStatusCount()
2202
    {
2203
        return Database::getManager()->getRepository(TicketStatus::class)->createQueryBuilder('p')
2204
            ->select('COUNT(p.id)')
2205
            ->getQuery()
2206
            ->getSingleScalarResult();
2207
    }
2208
2209
    /**
2210
     * @param array $params
2211
     */
2212
    public static function addStatus($params)
2213
    {
2214
        $item = new TicketStatus();
2215
        $item->setCode(URLify::filter($params['title']));
2216
        $item->setTitle($params['title']);
2217
        $item->setDescription($params['description']);
2218
        $item->setAccessUrl(Container::getAccessUrlUtil()->getCurrent());
2219
2220
        Database::getManager()->persist($item);
2221
        Database::getManager()->flush();
2222
    }
2223
2224
    /**
2225
     * @param $id
2226
     *
2227
     * @return TicketProject
2228
     */
2229
    public static function getStatus($id)
2230
    {
2231
        return Database::getManager()->getRepository(TicketStatus::class)->find($id);
2232
    }
2233
2234
    /**
2235
     * @param int   $id
2236
     * @param array $params
2237
     */
2238
    public static function updateStatus($id, $params)
2239
    {
2240
        $item = self::getStatus($id);
2241
        $item->setTitle($params['title']);
2242
        $item->setDescription($params['description']);
2243
        $item->setAccessUrl(Container::getAccessUrlUtil()->getCurrent());
2244
2245
        Database::getManager()->persist($item);
2246
        Database::getManager()->flush();
2247
    }
2248
2249
    /**
2250
     * @param int $id
2251
     */
2252
    public static function deleteStatus($id)
2253
    {
2254
        $item = self::getStatus($id);
2255
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\CoreBundle\Entity\TicketProject, thus it always evaluated to true.
Loading history...
2256
            Database::getManager()->remove($item);
2257
            Database::getManager()->flush();
2258
        }
2259
    }
2260
2261
    /**
2262
     * @param string $url
2263
     *
2264
     * @return FormValidator
2265
     */
2266
    public static function getStatusForm($url)
2267
    {
2268
        $form = new FormValidator('status', 'post', $url);
2269
        $form->addText('name', get_lang('Name'));
2270
        $form->addHtmlEditor('description', get_lang('Description'));
2271
        $form->addButtonUpdate(get_lang('Save'));
2272
2273
        return $form;
2274
    }
2275
2276
    /**
2277
     * @return array
2278
     */
2279
    public static function getPriorityAdminList(): array
2280
    {
2281
        $accessUrl = Container::getAccessUrlUtil()->getCurrent();
2282
        $items = Database::getManager()
2283
            ->getRepository(TicketPriority::class)
2284
            ->findBy(['accessUrl' => $accessUrl]);
2285
2286
        if (empty($items)) {
2287
            $items = Database::getManager()
2288
                ->getRepository(TicketPriority::class)
2289
                ->findBy(['accessUrl' => NULL]);
2290
        }
2291
2292
        $list = [];
2293
        /** @var TicketPriority $row */
2294
        foreach ($items as $row) {
2295
            $list[] = [
2296
                'id' => $row->getId(),
2297
                'code' => $row->getCode(),
2298
                '0' => $row->getId(),
2299
                '1' => $row->getTitle(),
2300
                '2' => $row->getDescription(),
2301
                '3' => $row->getId(),
2302
            ];
2303
        }
2304
2305
        return $list;
2306
    }
2307
2308
    /**
2309
     * @return int
2310
     */
2311
    public static function getPriorityCount()
2312
    {
2313
        return Database::getManager()->getRepository(TicketPriority::class)->createQueryBuilder('p')
2314
            ->select('COUNT(p.id)')
2315
            ->getQuery()
2316
            ->getSingleScalarResult();
2317
    }
2318
2319
    /**
2320
     * @param array $params
2321
     */
2322
    public static function addPriority($params)
2323
    {
2324
        $item = new TicketPriority();
2325
        $item
2326
            ->setCode(URLify::filter($params['title']))
2327
            ->setTitle($params['title'])
2328
            ->setDescription($params['description'])
2329
            ->setColor('')
2330
            ->setInsertUserId(api_get_user_id())
2331
            ->setUrgency('')
2332
            ->setAccessUrl(Container::getAccessUrlUtil()->getCurrent());
2333
2334
        Database::getManager()->persist($item);
2335
        Database::getManager()->flush();
2336
    }
2337
2338
    /**
2339
     * @param $id
2340
     *
2341
     * @return TicketPriority
2342
     */
2343
    public static function getPriority($id)
2344
    {
2345
        return Database::getManager()->getRepository(TicketPriority::class)->find($id);
2346
    }
2347
2348
    /**
2349
     * @param int   $id
2350
     * @param array $params
2351
     */
2352
    public static function updatePriority($id, $params)
2353
    {
2354
        $item = self::getPriority($id);
2355
        $item->setTitle($params['title']);
2356
        $item->setDescription($params['description']);
2357
        $item->setAccessUrl(Container::getAccessUrlUtil()->getCurrent());
2358
2359
        Database::getManager()->persist($item);
2360
        Database::getManager()->flush();
2361
    }
2362
2363
    /**
2364
     * @param int $id
2365
     */
2366
    public static function deletePriority($id)
2367
    {
2368
        $item = self::getPriority($id);
2369
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\CoreBundle\Entity\TicketPriority, thus it always evaluated to true.
Loading history...
2370
            Database::getManager()->remove($item);
2371
            Database::getManager()->flush();
2372
        }
2373
    }
2374
2375
    /**
2376
     * @param string $url
2377
     *
2378
     * @return FormValidator
2379
     */
2380
    public static function getPriorityForm($url)
2381
    {
2382
        $form = new FormValidator('priority', 'post', $url);
2383
        $form->addText('name', get_lang('Name'));
2384
        $form->addHtmlEditor('description', get_lang('Description'));
2385
        $form->addButtonUpdate(get_lang('Save'));
2386
2387
        return $form;
2388
    }
2389
2390
    /**
2391
     * Returns a list of menu elements for the tickets system's configuration.
2392
     *
2393
     * @param ?string $exclude The element to exclude from the list
2394
     *
2395
     * @return array
2396
     */
2397
    public static function getSettingsMenuItems(?string $exclude = null): array
2398
    {
2399
        $project = [
2400
            'icon' => ObjectIcon::PROJECT,
2401
            'url' => 'projects.php',
2402
            'content' => get_lang('Projects'),
2403
        ];
2404
        $status = [
2405
            'icon' => StateIcon::COMPLETE,
2406
            'url' => 'status.php',
2407
            'content' => get_lang('Status'),
2408
        ];
2409
        $priority = [
2410
            'icon' => StateIcon::EXPIRED,
2411
            'url' => 'priorities.php',
2412
            'content' => get_lang('Priority'),
2413
        ];
2414
        switch ($exclude) {
2415
            case 'project':
2416
                $items = [$status, $priority];
2417
                break;
2418
            case 'status':
2419
                $items = [$project, $priority];
2420
                break;
2421
            case 'priority':
2422
                $items = [$project, $status];
2423
                break;
2424
            default:
2425
                $items = [$project, $status, $priority];
2426
                break;
2427
        }
2428
2429
        return $items;
2430
    }
2431
2432
    /**
2433
     * Returns a list of strings representing the default statuses.
2434
     *
2435
     * @return array
2436
     */
2437
    public static function getDefaultStatusList()
2438
    {
2439
        return [
2440
            self::STATUS_NEW,
2441
            self::STATUS_PENDING,
2442
            self::STATUS_UNCONFIRMED,
2443
            self::STATUS_CLOSE,
2444
            self::STATUS_FORWARDED,
2445
        ];
2446
    }
2447
2448
    /**
2449
     * @return array
2450
     */
2451
    public static function getDefaultPriorityList()
2452
    {
2453
        return [
2454
            self::PRIORITY_NORMAL,
2455
            self::PRIORITY_HIGH,
2456
            self::PRIORITY_LOW,
2457
            self::STATUS_CLOSE,
2458
            self::STATUS_FORWARDED,
2459
        ];
2460
    }
2461
2462
    /**
2463
     * Deletes the user from all the ticket system.
2464
     *
2465
     * @param int $userId
2466
     */
2467
    public static function deleteUserFromTicketSystem($userId)
2468
    {
2469
        $userId = (int) $userId;
2470
        $schema = Database::getManager()->getConnection()->createSchemaManager();
2471
2472
        if ($schema->tablesExist('ticket_assigned_log')) {
2473
            $sql = "UPDATE ticket_assigned_log SET user_id = NULL WHERE user_id = $userId";
2474
            Database::query($sql);
2475
2476
            $sql = "UPDATE ticket_assigned_log SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2477
            Database::query($sql);
2478
        }
2479
2480
        if ($schema->tablesExist('ticket_ticket')) {
2481
            $sql = "UPDATE ticket_ticket SET assigned_last_user = NULL WHERE assigned_last_user = $userId";
2482
            Database::query($sql);
2483
2484
            $sql = "UPDATE ticket_ticket SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2485
            Database::query($sql);
2486
2487
            $sql = "UPDATE ticket_ticket SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2488
            Database::query($sql);
2489
        }
2490
2491
        if ($schema->tablesExist('ticket_category')) {
2492
            $sql = "UPDATE ticket_category SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2493
            Database::query($sql);
2494
2495
            $sql = "UPDATE ticket_category SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2496
            Database::query($sql);
2497
        }
2498
2499
        if ($schema->tablesExist('ticket_category_rel_user')) {
2500
            $sql = "DELETE FROM ticket_category_rel_user WHERE user_id = $userId";
2501
            Database::query($sql);
2502
        }
2503
2504
        if ($schema->tablesExist('ticket_message')) {
2505
            $sql = "UPDATE ticket_message SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2506
            Database::query($sql);
2507
2508
            $sql = "UPDATE ticket_message SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2509
            Database::query($sql);
2510
        }
2511
2512
        if ($schema->tablesExist('ticket_message_attachments')) {
2513
            $sql = "UPDATE ticket_message_attachments SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2514
            Database::query($sql);
2515
2516
            $sql = "UPDATE ticket_message_attachments SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2517
            Database::query($sql);
2518
        }
2519
2520
        if ($schema->tablesExist('ticket_priority')) {
2521
            $sql = "UPDATE ticket_priority SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2522
            Database::query($sql);
2523
2524
            $sql = "UPDATE ticket_priority SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2525
            Database::query($sql);
2526
        }
2527
2528
        if ($schema->tablesExist('ticket_project')) {
2529
            $sql = "UPDATE ticket_project SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2530
            Database::query($sql);
2531
2532
            $sql = "UPDATE ticket_project SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2533
            Database::query($sql);
2534
        }
2535
    }
2536
2537
    /**
2538
     * @deprecated Use TicketProjectHelper::userIsAllowInProject instead
2539
     */
2540
    public static function userIsAllowInProject(int $projectId): bool
2541
    {
2542
        $authorizationChecked = Container::getAuthorizationChecker();
2543
2544
        if ($authorizationChecked->isGranted('ROLE_ADMIN')) {
2545
            return true;
2546
        }
2547
2548
        $allowRoleList = self::getAllowedRolesFromProject($projectId);
0 ignored issues
show
Deprecated Code introduced by
The function TicketManager::getAllowedRolesFromProject() has been deprecated: Use TicketProjectHelper::getAllowedRolesFromProject instead ( Ignorable by Annotation )

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

2548
        $allowRoleList = /** @scrutinizer ignore-deprecated */ self::getAllowedRolesFromProject($projectId);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
2549
2550
        // Check if a role was set to the project.
2551
        // Project 1 is considered the default and is accessible to all users
2552
        if (!empty($allowRoleList)) {
2553
            $result = false;
2554
            foreach ($allowRoleList as $role) {
2555
                if ($authorizationChecked->isGranted($role)) {
2556
                    $result = true;
2557
                    break;
2558
                }
2559
            }
2560
2561
            return $result;
2562
        }
2563
2564
        return false;
2565
    }
2566
2567
    /**
2568
     * @deprecated Use TicketProjectHelper::getAllowedRolesFromProject instead
2569
     */
2570
    public static function getAllowedRolesFromProject(int $projectId): array
2571
    {
2572
        // Define a mapping from role IDs to role names
2573
        $roleMap = [
2574
            1 => 'ROLE_TEACHER',
2575
            17 => 'ROLE_STUDENT_BOSS',
2576
            4 => 'ROLE_HR',
2577
            3 => 'ROLE_SESSION_MANAGER',
2578
            // ... other mappings can be added as needed
2579
        ];
2580
2581
        $jsonString = Container::getSettingsManager()->getSetting('ticket.ticket_project_user_roles');
2582
2583
        if (empty($jsonString)) {
2584
            return [];
2585
        }
2586
2587
        $data = json_decode($jsonString, true);
2588
2589
        if (JSON_ERROR_NONE !== json_last_error()) {
2590
            // Invalid JSON
2591
            return [];
2592
        }
2593
2594
        if (!isset($data['permissions'][$projectId])) {
2595
            // No permissions for the given projectId
2596
            return [];
2597
        }
2598
2599
        $roleIds = $data['permissions'][$projectId];
2600
2601
        // Transform role IDs into role names using the defined mapping
2602
        return array_map(function ($roleId) use ($roleMap) {
2603
            return $roleMap[$roleId] ?? "$roleId";
2604
        }, $roleIds);
2605
    }
2606
2607
    /**
2608
     * Subscribes a user to a ticket.
2609
     */
2610
    public static function subscribeUserToTicket(int $ticketId, int $userId): void
2611
    {
2612
        $em = Database::getManager();
2613
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2614
        $user = $em->getRepository(User::class)->find($userId);
2615
2616
        if ($ticket && $user) {
2617
            $repository = $em->getRepository(TicketRelUser::class);
2618
            $repository->subscribeUserToTicket($user, $ticket);
2619
2620
            Event::addEvent(
0 ignored issues
show
Bug introduced by
The method addEvent() does not exist on Event. ( Ignorable by Annotation )

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

2620
            Event::/** @scrutinizer ignore-call */ 
2621
                   addEvent(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
2621
                'ticket_subscribe',
2622
                'ticket_event',
2623
                ['user_id' => $userId, 'ticket_id' => $ticketId, 'action' => 'subscribe']
2624
            );
2625
        }
2626
    }
2627
2628
    /**
2629
     * Unsubscribes a user from a ticket.
2630
     */
2631
    public static function unsubscribeUserFromTicket(int $ticketId, int $userId): void
2632
    {
2633
        $em = Database::getManager();
2634
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2635
        $user = $em->getRepository(User::class)->find($userId);
2636
2637
        if ($ticket && $user) {
2638
            $repository = $em->getRepository(TicketRelUser::class);
2639
            $repository->unsubscribeUserFromTicket($user, $ticket);
2640
2641
            Event::addEvent(
2642
                'ticket_unsubscribe',
2643
                'ticket_event',
2644
                ['user_id' => $userId, 'ticket_id' => $ticketId, 'action' => 'unsubscribe']
2645
            );
2646
        }
2647
    }
2648
2649
    /**
2650
     * Checks if a user is subscribed to a ticket.
2651
     */
2652
    public static function isUserSubscribedToTicket(int $ticketId, int $userId): bool
2653
    {
2654
        $em = Database::getManager();
2655
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2656
        $user = $em->getRepository(User::class)->find($userId);
2657
2658
        if ($ticket && $user) {
2659
            $repository = $em->getRepository(TicketRelUser::class);
2660
            return $repository->isUserSubscribedToTicket($user, $ticket);
2661
        }
2662
2663
        return false;
2664
    }
2665
2666
    /**
2667
     * Retrieves the followers of a ticket.
2668
     */
2669
    public static function getFollowers($ticketId): array
2670
    {
2671
        $em = Database::getManager();
2672
        $repository = $em->getRepository(TicketRelUser::class);
2673
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2674
2675
        $followers = $repository->findBy(['ticket' => $ticket]);
2676
2677
        $users = [];
2678
        foreach ($followers as $follower) {
2679
            $users[] = $follower->getUser();
2680
        }
2681
2682
        return $users;
2683
    }
2684
2685
    /**
2686
     * Generates an unsubscribe link for a ticket.
2687
     */
2688
    public static function generateUnsubscribeLink($ticketId, $userId): string
2689
    {
2690
        $token = new ValidationToken(ValidationTokenHelper::TYPE_TICKET, $ticketId);
2691
        Database::getManager()->persist($token);
2692
        Database::getManager()->flush();
2693
2694
        return api_get_path(WEB_PATH).'validate/ticket/'.$token->getHash().'?user_id='.$userId;
2695
    }
2696
}
2697