TicketManager::deletePriority()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 6
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\Framework\Container;
15
use Chamilo\CoreBundle\ServiceHelper\ValidationTokenHelper;
16
use Chamilo\CourseBundle\Entity\CLp;
17
use Symfony\Component\HttpFoundation\File\UploadedFile;
18
use Chamilo\CoreBundle\Component\Utils\ObjectIcon;
19
use Chamilo\CoreBundle\Component\Utils\StateIcon;
20
21
/**
22
 * Class TicketManager.
23
 */
24
class TicketManager
25
{
26
    public const PRIORITY_NORMAL = 'NRM';
27
    public const PRIORITY_HIGH = 'HGH';
28
    public const PRIORITY_LOW = 'LOW';
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 = 'NAT';
36
    public const STATUS_PENDING = 'PND';
37
    public const STATUS_UNCONFIRMED = 'XCF';
38
    public const STATUS_CLOSE = 'CLS';
39
    public const STATUS_FORWARDED = 'REE';
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::getAccessUrlHelper()->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 AND project.access_url_id = $accessUrlId
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
        if (!in_array($direction, ['ASC', 'DESC'])) {
98
            $direction = 'ASC';
99
        }
100
        $column = (int) $column;
101
        $from = (int) $from;
102
        $numberItems = (int) $numberItems;
103
104
        //$sql .= " ORDER BY col$column $direction ";
105
        $sql .= " LIMIT $from,$numberItems";
106
107
        $result = Database::query($sql);
108
        $types = [];
109
        while ($row = Database::fetch_array($result)) {
110
            $types[] = $row;
111
        }
112
113
        return $types;
114
    }
115
116
    /**
117
     * @param int $id
118
     *
119
     * @return array|mixed
120
     */
121
    public static function getCategory($id)
122
    {
123
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
124
        $id = (int) $id;
125
        $sql = "SELECT id, title, title as name, description, total_tickets
126
                FROM $table WHERE id = $id";
127
128
        $result = Database::query($sql);
129
        $category = Database::fetch_array($result);
130
131
        return $category;
132
    }
133
134
    /**
135
     * @return int
136
     */
137
    public static function getCategoriesCount()
138
    {
139
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
140
141
        $sql = "SELECT count(id) count
142
                FROM $table ";
143
144
        $result = Database::query($sql);
145
        $category = Database::fetch_array($result);
146
147
        return $category['count'];
148
    }
149
150
    /**
151
     * @param int   $id
152
     * @param array $params
153
     */
154
    public static function updateCategory($id, $params)
155
    {
156
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
157
        $id = (int) $id;
158
        Database::update($table, $params, ['id = ?' => $id]);
159
    }
160
161
    /**
162
     * @param array $params
163
     */
164
    public static function addCategory($params)
165
    {
166
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
167
        Database::insert($table, $params);
168
    }
169
170
    /**
171
     * @param int $id
172
     *
173
     * @return bool
174
     */
175
    public static function deleteCategory($id)
176
    {
177
        $id = (int) $id;
178
        if (empty($id)) {
179
            return false;
180
        }
181
182
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
183
        $sql = "UPDATE $table SET category_id = NULL WHERE category_id = $id";
184
        Database::query($sql);
185
186
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
187
        $sql = "DELETE FROM $table WHERE id = $id";
188
        Database::query($sql);
189
190
        return true;
191
    }
192
193
    /**
194
     * @param int   $categoryId
195
     * @param array $users
196
     *
197
     * @return bool
198
     */
199
    public static function addUsersToCategory($categoryId, $users)
200
    {
201
        if (empty($users) || empty($categoryId)) {
202
            return false;
203
        }
204
205
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
206
        foreach ($users as $userId) {
207
            if (false === self::userIsAssignedToCategory($userId, $categoryId)) {
208
                $params = [
209
                    'category_id' => $categoryId,
210
                    'user_id' => $userId,
211
                ];
212
                Database::insert($table, $params);
213
            }
214
        }
215
216
        return true;
217
    }
218
219
    /**
220
     * @param int $userId
221
     * @param int $categoryId
222
     *
223
     * @return bool
224
     */
225
    public static function userIsAssignedToCategory($userId, $categoryId)
226
    {
227
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
228
        $userId = (int) $userId;
229
        $categoryId = (int) $categoryId;
230
        $sql = "SELECT * FROM $table
231
                WHERE category_id = $categoryId AND user_id = $userId";
232
        $result = Database::query($sql);
233
234
        return Database::num_rows($result) > 0;
235
    }
236
237
    /**
238
     * @param int $categoryId
239
     *
240
     * @return array
241
     */
242
    public static function getUsersInCategory($categoryId)
243
    {
244
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
245
        $categoryId = (int) $categoryId;
246
        $sql = "SELECT * FROM $table WHERE category_id = $categoryId";
247
        $result = Database::query($sql);
248
249
        return Database::store_result($result);
250
    }
251
252
    /**
253
     * @param int $categoryId
254
     */
255
    public static function deleteAllUserInCategory($categoryId)
256
    {
257
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
258
        $categoryId = (int) $categoryId;
259
        $sql = "DELETE FROM $table WHERE category_id = $categoryId";
260
        Database::query($sql);
261
    }
262
263
    /**
264
     * Get all possible tickets statuses.
265
     *
266
     * @return array
267
     */
268
    public static function get_all_tickets_status()
269
    {
270
        $table = Database::get_main_table(TABLE_TICKET_STATUS);
271
        $sql = "SELECT * FROM $table";
272
        $result = Database::query($sql);
273
        $types = [];
274
        while ($row = Database::fetch_assoc($result)) {
275
            $types[] = $row;
276
        }
277
278
        return $types;
279
    }
280
281
    /**
282
     * Inserts a new ticket in the corresponding tables.
283
     *
284
     * @param int      $category_id
285
     * @param int      $course_id
286
     * @param int      $sessionId
287
     * @param int      $project_id
288
     * @param string   $other_area
289
     * @param string   $subject
290
     * @param string   $content
291
     * @param string   $personalEmail
292
     * @param array    $fileAttachments
293
     * @param string   $source
294
     * @param string   $priority
295
     * @param string   $status
296
     * @param int|null $assignedUserId
297
     * @param int      $exerciseId
298
     * @param int      $lpId
299
     *
300
     * @return bool
301
     */
302
    public static function add(
303
        $category_id,
304
        $course_id,
305
        $sessionId,
306
        $project_id,
307
        $other_area,
308
        $subject,
309
        $content,
310
        $personalEmail = '',
311
        $fileAttachments = [],
312
        $source = '',
313
        $priority = '',
314
        $status = '',
315
        $assignedUserId = null,
316
        $exerciseId = null,
317
        $lpId = null
318
    ) {
319
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
320
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
321
322
        if (empty($category_id)) {
323
            return false;
324
        }
325
326
        $currentUserId = api_get_user_id();
327
        $currentUserInfo = api_get_user_info();
328
        $now = api_get_utc_datetime();
329
        $course_id = (int) $course_id;
330
        $category_id = (int) $category_id;
331
        $project_id = (int) $project_id;
332
        $priority = empty($priority) ? self::PRIORITY_NORMAL : (int) $priority;
333
334
        if ('' === $status) {
335
            $status = self::STATUS_NEW;
336
            if ($other_area > 0) {
337
                $status = self::STATUS_FORWARDED;
338
            }
339
        }
340
341
        if (empty($assignedUserId)) {
342
            $usersInCategory = self::getUsersInCategory($category_id);
343
            if (!empty($usersInCategory) && count($usersInCategory) > 0) {
344
                $userCategoryInfo = $usersInCategory[0];
345
                if (isset($userCategoryInfo['user_id'])) {
346
                    $assignedUserId = $userCategoryInfo['user_id'];
347
                }
348
            }
349
        }
350
351
        $assignedUserInfo = [];
352
        if (!empty($assignedUserId)) {
353
            $assignedUserInfo = api_get_user_info($assignedUserId);
354
            if (empty($assignedUserInfo)) {
355
                return false;
356
            }
357
        }
358
359
        // insert_ticket
360
        $params = [
361
            'project_id' => $project_id,
362
            'category_id' => $category_id,
363
            'priority_id' => $priority,
364
            'personal_email' => $personalEmail,
365
            'status_id' => $status,
366
            'start_date' => $now,
367
            'sys_insert_user_id' => $currentUserId,
368
            'sys_insert_datetime' => $now,
369
            'sys_lastedit_user_id' => $currentUserId,
370
            'sys_lastedit_datetime' => $now,
371
            'source' => $source,
372
            'assigned_last_user' => $assignedUserId,
373
            'subject' => $subject,
374
            'message' => $content,
375
            'code' => '',
376
            'total_messages' => 0,
377
            'access_url_id' => Container::getAccessUrlHelper()->getCurrent()->getId(),
378
        ];
379
380
        if (!empty($exerciseId)) {
381
            $params['exercise_id'] = $exerciseId;
382
        }
383
384
        if (!empty($lpId)) {
385
            $params['lp_id'] = $lpId;
386
        }
387
        if (!empty($course_id)) {
388
            $params['course_id'] = $course_id;
389
        }
390
391
        if (!empty($sessionId)) {
392
            $params['session_id'] = $sessionId;
393
        }
394
        $ticketId = Database::insert($table_support_tickets, $params);
395
396
        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...
397
            self::subscribeUserToTicket($ticketId, $currentUserId);
398
            $ticket_code = 'A'.str_pad($ticketId, 11, '0', STR_PAD_LEFT);
399
            $titleCreated = sprintf(
400
                get_lang('Ticket %s created'),
401
                $ticket_code
402
            );
403
404
            Display::addFlash(Display::return_message(
405
                $titleCreated,
406
                'normal',
407
                false
408
            ));
409
410
            if (0 != $assignedUserId) {
411
                self::assignTicketToUser(
412
                    $ticketId,
413
                    $assignedUserId
414
                );
415
416
                Display::addFlash(Display::return_message(
417
                    sprintf(
418
                        get_lang('Ticket <b>#%s</b> assigned to user <b>%s</b>'),
419
                        $ticket_code,
420
                        $assignedUserInfo['complete_name']
421
                    ),
422
                    'normal',
423
                    false
424
                ));
425
            }
426
427
            if (!empty($fileAttachments)) {
428
                $attachmentCount = 0;
429
                foreach ($fileAttachments as $attach) {
430
                    if (!empty($attach['tmp_name'])) {
431
                        $attachmentCount++;
432
                    }
433
                }
434
                if ($attachmentCount > 0) {
435
                    self::insertMessage(
436
                        $ticketId,
437
                        '',
438
                        '',
439
                        $fileAttachments,
440
                        $currentUserId
441
                    );
442
                }
443
            }
444
445
            // Update code
446
            $sql = "UPDATE $table_support_tickets
447
                    SET code = '$ticket_code'
448
                    WHERE id = '$ticketId'";
449
            Database::query($sql);
450
451
            // Update total
452
            $sql = "UPDATE $table_support_category
453
                    SET total_tickets = total_tickets + 1
454
                    WHERE id = $category_id";
455
            Database::query($sql);
456
457
            $helpDeskMessage =
458
                '<table>
459
                        <tr>
460
                            <td width="100px"><b>'.get_lang('User').'</b></td>
461
                            <td width="400px">'.$currentUserInfo['complete_name'].'</td>
462
                        </tr>
463
                        <tr>
464
                            <td width="100px"><b>'.get_lang('Username').'</b></td>
465
                            <td width="400px">'.$currentUserInfo['username'].'</td>
466
                        </tr>
467
                        <tr>
468
                            <td width="100px"><b>'.get_lang('Email').'</b></td>
469
                            <td width="400px">'.$currentUserInfo['email'].'</td>
470
                        </tr>
471
                        <tr>
472
                            <td width="100px"><b>'.get_lang('Phone').'</b></td>
473
                            <td width="400px">'.$currentUserInfo['phone'].'</td>
474
                        </tr>
475
                        <tr>
476
                            <td width="100px"><b>'.get_lang('Date').'</b></td>
477
                            <td width="400px">'.api_convert_and_format_date($now, DATE_TIME_FORMAT_LONG).'</td>
478
                        </tr>
479
                        <tr>
480
                            <td width="100px"><b>'.get_lang('Title').'</b></td>
481
                            <td width="400px">'.Security::remove_XSS($subject).'</td>
482
                        </tr>
483
                        <tr>
484
                            <td width="100px"><b>'.get_lang('Description').'</b></td>
485
                            <td width="400px">'.Security::remove_XSS($content).'</td>
486
                        </tr>
487
                    </table>';
488
489
            if (0 != $assignedUserId) {
490
                $href = api_get_path(WEB_CODE_PATH).'ticket/ticket_details.php?ticket_id='.$ticketId;
491
                $helpDeskMessage .= sprintf(
492
                    get_lang("Ticket assigned to %s. Follow-up at <a href='%s'>#%s</a>."),
493
                    $assignedUserInfo['complete_name'],
494
                    $href,
495
                    $ticketId
496
                );
497
            }
498
499
            if (empty($category_id)) {
500
                if ('true' === api_get_setting('ticket_send_warning_to_all_admins')) {
501
                    $warningSubject = sprintf(
502
                        get_lang('Ticket %s was created without a category'),
503
                        $ticket_code
504
                    );
505
                    Display::addFlash(Display::return_message($warningSubject));
506
507
                    $admins = UserManager::get_all_administrators();
508
                    foreach ($admins as $userId => $data) {
509
                        if ($data['active']) {
510
                            MessageManager::send_message_simple(
511
                                $userId,
512
                                $warningSubject,
513
                                $helpDeskMessage
514
                            );
515
                        }
516
                    }
517
                }
518
            } else {
519
                $categoryInfo = self::getCategory($category_id);
520
                $usersInCategory = self::getUsersInCategory($category_id);
521
                $message = '<h2>'.get_lang('Ticket info').'</h2><br />'.$helpDeskMessage;
522
523
                if ('true' === api_get_setting('ticket_warn_admin_no_user_in_category')) {
524
                    $usersInCategory = self::getUsersInCategory($category_id);
525
                    if (empty($usersInCategory)) {
526
                        $subject = sprintf(
527
                            get_lang('Warning: No one has been assigned to category %s'),
528
                            $categoryInfo['title']
529
                        );
530
531
                        if ('true' === api_get_setting('ticket_send_warning_to_all_admins')) {
532
                            Display::addFlash(Display::return_message(
533
                                sprintf(
534
                                    get_lang(
535
                                        'A notification was sent to the administrators to report this category has no user assigned'
536
                                    ),
537
                                    $categoryInfo['title']
538
                                ),
539
                                null,
540
                                false
541
                            ));
542
543
                            $admins = UserManager::get_all_administrators();
544
                            foreach ($admins as $userId => $data) {
545
                                if ($data['active']) {
546
                                    self::sendNotification(
547
                                        $ticketId,
548
                                        $subject,
549
                                        $message,
550
                                        $userId
551
                                    );
552
                                }
553
                            }
554
                        } else {
555
                            Display::addFlash(Display::return_message($subject));
556
                        }
557
                    }
558
                }
559
560
                // Send notification to all users
561
                if (!empty($usersInCategory)) {
562
                    foreach ($usersInCategory as $data) {
563
                        if ($data['user_id'] && $data['user_id'] !== $currentUserId) {
564
                            self::sendNotification(
565
                                $ticketId,
566
                                $titleCreated,
567
                                $helpDeskMessage,
568
                                $data['user_id']
569
                            );
570
                        }
571
                    }
572
                }
573
            }
574
575
            if (!empty($personalEmail)) {
576
                api_mail_html(
577
                    get_lang('Virtual support'),
578
                    $personalEmail,
579
                    get_lang('The incident has been sent to the virtual support team again'),
580
                    $helpDeskMessage
581
                );
582
            }
583
584
            self::sendNotification(
585
                $ticketId,
586
                $titleCreated,
587
                $helpDeskMessage
588
            );
589
590
            return true;
591
        }
592
593
        return false;
594
    }
595
596
    /**
597
     * Assign ticket to admin.
598
     *
599
     * @param int $ticketId
600
     * @param int $userId
601
     *
602
     * @return bool
603
     */
604
    public static function assignTicketToUser(
605
        $ticketId,
606
        $userId
607
    ) {
608
        $ticketId = (int) $ticketId;
609
        $userId = (int) $userId;
610
611
        if (empty($ticketId)) {
612
            return false;
613
        }
614
615
        $ticket = self::get_ticket_detail_by_id($ticketId);
616
617
        if ($ticket) {
618
            $table = Database::get_main_table(TABLE_TICKET_TICKET);
619
            $sql = "UPDATE $table
620
                    SET assigned_last_user = $userId
621
                    WHERE id = $ticketId";
622
            Database::query($sql);
623
624
            $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
625
            $params = [
626
                'ticket_id' => $ticketId,
627
                'user_id' => $userId,
628
                'sys_insert_user_id' => api_get_user_id(),
629
                'assigned_date' => api_get_utc_datetime(),
630
            ];
631
            Database::insert($table, $params);
632
633
            return true;
634
        } else {
635
            return false;
636
        }
637
    }
638
639
    /**
640
     * Insert message between Users and Admins.
641
     *
642
     * @param int    $ticketId
643
     * @param string $subject
644
     * @param string $content
645
     * @param array  $fileAttachments
646
     * @param int    $userId
647
     * @param string $status
648
     * @param bool   $sendConfirmation
649
     *
650
     * @return bool
651
     */
652
    public static function insertMessage(
653
        $ticketId,
654
        $subject,
655
        $content,
656
        $fileAttachments,
657
        $userId,
658
        $status = 'NOL',
659
        $sendConfirmation = false
660
    ) {
661
        $ticketId = (int) $ticketId;
662
        $userId = (int) $userId;
663
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
664
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
665
        if ($sendConfirmation) {
666
            $form =
667
                '<form action="ticket_details.php?ticket_id='.$ticketId.'" id="confirmticket" method="POST" >
668
                     <p>'.get_lang('Was this answer satisfactory?').'</p>
669
                     <button class="btn btn--primary responseyes" name="response" id="responseyes" value="1">'.
670
                get_lang('Yes').'</button>
671
                     <button class="btn btn--danger responseno" name="response" id="responseno" value="0">'.
672
                get_lang('No').'</button>
673
                 </form>';
674
            $content .= $form;
675
        }
676
677
        $now = api_get_utc_datetime();
678
679
        $params = [
680
            'ticket_id' => $ticketId,
681
            'subject' => $subject,
682
            'message' => $content,
683
            'ip_address' => api_get_real_ip(),
684
            'sys_insert_user_id' => $userId,
685
            'sys_insert_datetime' => $now,
686
            'sys_lastedit_user_id' => $userId,
687
            'sys_lastedit_datetime' => $now,
688
            'status' => $status,
689
        ];
690
        $messageId = Database::insert($table_support_messages, $params);
691
        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...
692
            // update_total_message
693
            $sql = "UPDATE $table_support_tickets
694
                    SET
695
                        sys_lastedit_user_id = $userId,
696
                        sys_lastedit_datetime = '$now',
697
                        total_messages = (
698
                            SELECT COUNT(*) as total_messages
699
                            FROM $table_support_messages
700
                            WHERE ticket_id = $ticketId
701
                        )
702
                    WHERE id = $ticketId ";
703
            Database::query($sql);
704
705
            if (is_array($fileAttachments)) {
706
                foreach ($fileAttachments as $file_attach) {
707
                    if (0 == $file_attach['error']) {
708
                        self::saveMessageAttachmentFile(
709
                            $file_attach,
710
                            $ticketId,
711
                            $messageId
712
                        );
713
                    } else {
714
                        if (UPLOAD_ERR_NO_FILE != $file_attach['error']) {
715
                            return false;
716
                        }
717
                    }
718
                }
719
            }
720
721
            if (!self::isUserSubscribedToTicket($ticketId, $userId)) {
722
                self::subscribeUserToTicket($ticketId, $userId);
723
            }
724
        }
725
726
        return true;
727
    }
728
729
    /**
730
     * Attachment files when a message is sent.
731
     *
732
     * @throws \Doctrine\ORM\ORMException
733
     * @throws \Doctrine\ORM\OptimisticLockException
734
     * @throws \Doctrine\ORM\TransactionRequiredException
735
     */
736
    public static function saveMessageAttachmentFile(
737
        $fileAttach,
738
        $ticketId,
739
        $messageId
740
    ): bool {
741
        if (!is_array($fileAttach) || UPLOAD_ERR_OK != $fileAttach['error']) {
742
            return false;
743
        }
744
745
        $em = Database::getManager();
746
747
        $ticket = $em->find(Ticket::class, $ticketId);
748
        $message = $em->find(TicketMessage::class, $messageId);
749
750
        $newFileName = add_ext_on_mime(
751
            stripslashes($fileAttach['name']),
752
            $fileAttach['type']
753
        );
754
755
        $fileName = $fileAttach['name'];
756
757
        if (!filter_extension($newFileName)) {
758
            Display::addFlash(
759
                Display::return_message(
760
                    get_lang('File upload failed: this file extension or file type is prohibited'),
761
                    'error'
762
                )
763
            );
764
765
            return false;
766
        }
767
768
        $currentUser = api_get_user_entity();
769
770
        $repo = Container::getTicketMessageAttachmentRepository();
771
        $attachment = (new TicketMessageAttachment())
772
            ->setFilename($fileName)
773
            ->setPath(uniqid('ticket_message', true))
774
            ->setMessage($message)
775
            ->setSize((int) $fileAttach['size'])
776
            ->setTicket($ticket)
777
            ->setInsertUserId($currentUser->getId())
778
            ->setInsertDateTime(api_get_utc_datetime(null, false, true))
779
            ->setParent($currentUser)
780
        ;
781
782
        if (null !== $ticket->getAssignedLastUser()) {
783
            $attachment->addUserLink($ticket->getAssignedLastUser());
784
        }
785
786
        $em->persist($attachment);
787
        $em->flush();
788
789
        $file = new UploadedFile($fileAttach['tmp_name'], $fileAttach['name'], $fileAttach['type'], $fileAttach['error']);
790
791
        $repo->addFile($attachment, $file);
792
793
        return true;
794
    }
795
796
    /**
797
     * Get tickets by userId.
798
     *
799
     * @param int $from
800
     * @param int $number_of_items
801
     * @param $column
802
     * @param $direction
803
     *
804
     * @return array
805
     */
806
    public static function getTicketsByCurrentUser($from, $number_of_items, $column, $direction)
807
    {
808
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
809
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
810
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
811
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
812
        $direction = !empty($direction) ? $direction : 'DESC';
813
        $userId = api_get_user_id();
814
        $userInfo = api_get_user_info($userId);
815
        $accessUrlId = Container::getAccessUrlHelper()->getCurrent()->getId();
816
817
        if (empty($userInfo)) {
818
            return [];
819
        }
820
        $isAdmin = UserManager::is_admin($userId);
821
822
        if (!isset($_GET['project_id'])) {
823
            return [];
824
        }
825
826
        switch ($column) {
827
            case 0:
828
                $column = 'ticket_id';
829
                break;
830
            case 1:
831
                $column = 'status_title';
832
                break;
833
            case 2:
834
                $column = 'start_date';
835
                break;
836
            case 3:
837
                $column = 'sys_lastedit_datetime';
838
                break;
839
            case 4:
840
                $column = 'category_title';
841
                break;
842
            case 5:
843
                $column = 'sys_insert_user_id';
844
                break;
845
            case 6:
846
                $column = 'assigned_last_user';
847
                break;
848
            case 7:
849
                $column = 'total_messages';
850
                break;
851
            case 8:
852
                $column = 'subject';
853
                break;
854
            default:
855
                $column = 'ticket_id';
856
        }
857
858
        $sql = "SELECT DISTINCT
859
                ticket.*,
860
                ticket.id ticket_id,
861
                status.title AS status_title,
862
                ticket.start_date,
863
                ticket.sys_lastedit_datetime,
864
                cat.title AS category_title,
865
                priority.title AS priority_title,
866
                ticket.total_messages AS total_messages,
867
                ticket.message AS message,
868
                ticket.subject AS subject,
869
                ticket.assigned_last_user
870
            FROM $table_support_tickets ticket
871
            INNER JOIN $table_support_category cat
872
            ON (cat.id = ticket.category_id)
873
            INNER JOIN $table_support_priority priority
874
            ON (ticket.priority_id = priority.id)
875
            INNER JOIN $table_support_status status
876
            ON (ticket.status_id = status.id)
877
            WHERE 1=1
878
        ";
879
        $sql .= " AND ticket.access_url_id = $accessUrlId ";
880
881
        $projectId = (int) $_GET['project_id'];
882
        $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

882
        $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...
883
884
        // Check if a role was set to the project
885
        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...
886
            $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
887
        }
888
889
        // Search simple
890
        if (isset($_GET['submit_simple']) && '' != $_GET['keyword']) {
891
            $keyword = Database::escape_string(trim($_GET['keyword']));
892
            $sql .= " AND (
893
                      ticket.id LIKE '%$keyword%' OR
894
                      ticket.code LIKE '%$keyword%' OR
895
                      ticket.subject LIKE '%$keyword%' OR
896
                      ticket.message LIKE '%$keyword%' OR
897
                      ticket.keyword LIKE '%$keyword%' OR
898
                      ticket.source LIKE '%$keyword%' OR
899
                      cat.title LIKE '%$keyword%' OR
900
                      status.title LIKE '%$keyword%' OR
901
                      priority.title LIKE '%$keyword%' OR
902
                      ticket.personal_email LIKE '%$keyword%'
903
            )";
904
        }
905
906
        $keywords = [
907
            'project_id' => 'ticket.project_id',
908
            'keyword_category' => 'ticket.category_id',
909
            'keyword_assigned_to' => 'ticket.assigned_last_user',
910
            'keyword_source' => 'ticket.source ',
911
            'keyword_status' => 'ticket.status_id',
912
            'keyword_priority' => 'ticket.priority_id',
913
        ];
914
915
        foreach ($keywords as $keyword => $label) {
916
            if (isset($_GET[$keyword])) {
917
                $data = Database::escape_string(trim($_GET[$keyword]));
918
                if (!empty($data)) {
919
                    $sql .= " AND $label = '$data' ";
920
                }
921
            }
922
        }
923
924
        // Search advanced
925
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
926
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
927
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
928
        $keyword_range = !empty($keyword_start_date_start) && !empty($keyword_start_date_end);
929
930
        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...
931
            $sql .= " AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start' ";
932
        }
933
        if ($keyword_range && '' != $keyword_start_date_start && '' != $keyword_start_date_end) {
934
            $sql .= " AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
935
                      AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
936
        }
937
938
        if ('' != $keyword_course) {
939
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
940
            $sql .= " AND ticket.course_id IN (
941
                     SELECT id FROM $course_table
942
                     WHERE (
943
                        title LIKE '%$keyword_course%' OR
944
                        code LIKE '%$keyword_course%' OR
945
                        visual_code LIKE '%$keyword_course%'
946
                     )
947
            )";
948
        }
949
        $sql .= " ORDER BY `$column` $direction";
950
        $sql .= " LIMIT $from, $number_of_items";
951
952
        $result = Database::query($sql);
953
        $tickets = [];
954
        $webPath = api_get_path(WEB_PATH);
955
        while ($row = Database::fetch_assoc($result)) {
956
            $userInfo = api_get_user_info($row['sys_insert_user_id']);
957
            $hrefUser = $webPath.'main/admin/user_information.php?user_id='.$userInfo['user_id'];
958
            $name = "<a href='$hrefUser'> {$userInfo['complete_name_with_username']} </a>";
959
            if (0 != $row['assigned_last_user']) {
960
                $assignedUserInfo = api_get_user_info($row['assigned_last_user']);
961
                if (!empty($assignedUserInfo)) {
962
                    $hrefResp = $webPath.'main/admin/user_information.php?user_id='.$assignedUserInfo['user_id'];
963
                    $row['assigned_last_user'] = "<a href='$hrefResp'> {$assignedUserInfo['complete_name_with_username']} </a>";
964
                } else {
965
                    $row['assigned_last_user'] = get_lang('Unknown user');
966
                }
967
            } else {
968
                if (self::STATUS_FORWARDED !== $row['status_id']) {
969
                    $row['assigned_last_user'] = '<span style="color:#ff0000;">'.get_lang('To be assigned').'</span>';
970
                } else {
971
                    $row['assigned_last_user'] = '<span style="color:#00ff00;">'.get_lang('Message resent').'</span>';
972
                }
973
            }
974
975
            switch ($row['source']) {
976
                case self::SOURCE_PRESENTIAL:
977
                    $img_source = ObjectIcon::USER;
978
                    break;
979
                case self::SOURCE_EMAIL:
980
                    $img_source = ObjectIcon::EMAIL;
981
                    break;
982
                case self::SOURCE_PHONE:
983
                    $img_source = ObjectIcon::PHONE;
984
                    break;
985
                default:
986
                    $img_source = ObjectIcon::TICKET;
987
                    break;
988
            }
989
990
            $row['start_date'] = Display::dateToStringAgoAndLongDate($row['start_date']);
991
            $row['sys_lastedit_datetime'] = Display::dateToStringAgoAndLongDate($row['sys_lastedit_datetime']);
992
993
            $icon = Display::getMdiIcon(
994
                $img_source,
995
                'ch-tool-icon',
996
                'margin-right: 10px; float: left;',
997
                ICON_SIZE_SMALL,
998
                get_lang('Information'),
999
            );
1000
1001
            $icon .= '<a href="ticket_details.php?ticket_id='.$row['id'].'">'.$row['code'].'</a>';
1002
1003
            if ($isAdmin) {
1004
                $ticket = [
1005
                    $icon.' '.Security::remove_XSS($row['subject']),
1006
                    $row['status_title'],
1007
                    $row['start_date'],
1008
                    $row['sys_lastedit_datetime'],
1009
                    $row['category_title'],
1010
                    $name,
1011
                    $row['assigned_last_user'],
1012
                    $row['total_messages'],
1013
                ];
1014
            } else {
1015
                $ticket = [
1016
                    $icon.' '.Security::remove_XSS($row['subject']),
1017
                    $row['status_title'],
1018
                    $row['start_date'],
1019
                    $row['sys_lastedit_datetime'],
1020
                    $row['category_title'],
1021
                ];
1022
            }
1023
            if ($isAdmin) {
1024
                $ticket['0'] .= '&nbsp;&nbsp;<a
1025
                href="javascript:void(0)"
1026
                onclick="load_history_ticket(\'div_'.$row['ticket_id'].'\','.$row['ticket_id'].')">
1027
                    <a
1028
                        onclick="load_course_list(\'div_'.$row['ticket_id'].'\','.$row['ticket_id'].')"
1029
					    onmouseover="clear_course_list (\'div_'.$row['ticket_id'].'\')"
1030
					    title="'.get_lang('History').'"
1031
					    alt="'.get_lang('History').'"
1032
                    >
1033
                    '.Display::getMdiIcon('history').'
1034
                    </a>
1035
1036
					<div class="blackboard_hide" id="div_'.$row['ticket_id'].'">&nbsp;&nbsp;</div>
1037
					</a>&nbsp;&nbsp;';
1038
            }
1039
            $tickets[] = $ticket;
1040
        }
1041
1042
        return $tickets;
1043
    }
1044
1045
    /**
1046
     * @return int
1047
     */
1048
    public static function getTotalTicketsCurrentUser()
1049
    {
1050
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1051
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1052
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1053
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1054
1055
        $userInfo = api_get_user_info();
1056
        if (empty($userInfo)) {
1057
            return 0;
1058
        }
1059
        $userId = $userInfo['id'];
1060
1061
        if (!isset($_GET['project_id'])) {
1062
            return 0;
1063
        }
1064
1065
        $accessUrlId = Container::getAccessUrlHelper()->getCurrent()->getId();
1066
1067
        $sql = "SELECT COUNT(ticket.id) AS total
1068
                FROM $table_support_tickets ticket
1069
                INNER JOIN $table_support_category cat
1070
                ON (cat.id = ticket.category_id)
1071
                INNER JOIN $table_support_priority priority
1072
                ON (ticket.priority_id = priority.id)
1073
                INNER JOIN $table_support_status status
1074
                ON (ticket.status_id = status.id)
1075
	            WHERE 1 = 1";
1076
1077
        $sql .= " AND ticket.access_url_id = $accessUrlId ";
1078
1079
        $projectId = (int) $_GET['project_id'];
1080
        $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

1080
        $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...
1081
1082
        // Check if a role was set to the project
1083
        if (!empty($allowRoleList) && is_array($allowRoleList)) {
1084
            $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

1084
            $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...
1085
            if (!$allowed) {
1086
                $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
1087
            }
1088
        } else {
1089
            if (!api_is_platform_admin()) {
1090
                $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
1091
            }
1092
        }
1093
1094
        // Search simple
1095
        if (isset($_GET['submit_simple'])) {
1096
            if ('' != $_GET['keyword']) {
1097
                $keyword = Database::escape_string(trim($_GET['keyword']));
1098
                $sql .= " AND (
1099
                          ticket.code LIKE '%$keyword%' OR
1100
                          ticket.subject LIKE '%$keyword%' OR
1101
                          ticket.message LIKE '%$keyword%' OR
1102
                          ticket.keyword LIKE '%$keyword%' OR
1103
                          ticket.personal_email LIKE '%$keyword%' OR
1104
                          ticket.source LIKE '%$keyword%'
1105
                )";
1106
            }
1107
        }
1108
1109
        $keywords = [
1110
            'project_id' => 'ticket.project_id',
1111
            'keyword_category' => 'ticket.category_id',
1112
            'keyword_assigned_to' => 'ticket.assigned_last_user',
1113
            'keyword_source' => 'ticket.source',
1114
            'keyword_status' => 'ticket.status_id',
1115
            'keyword_priority' => 'ticket.priority_id',
1116
        ];
1117
1118
        foreach ($keywords as $keyword => $sqlLabel) {
1119
            if (isset($_GET[$keyword])) {
1120
                $data = Database::escape_string(trim($_GET[$keyword]));
1121
                $sql .= " AND $sqlLabel = '$data' ";
1122
            }
1123
        }
1124
1125
        // Search advanced
1126
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
1127
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
1128
        $keyword_range = isset($_GET['keyword_dates']) ? Database::escape_string(trim($_GET['keyword_dates'])) : '';
1129
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
1130
1131
        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...
1132
            $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1133
        }
1134
        if ($keyword_range && '' != $keyword_start_date_start && '' != $keyword_start_date_end) {
1135
            $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1136
                      AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1137
        }
1138
        if ('' != $keyword_course) {
1139
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1140
            $sql .= " AND ticket.course_id IN (
1141
                        SELECT id
1142
                        FROM $course_table
1143
                        WHERE (
1144
                            title LIKE '%$keyword_course%' OR
1145
                            code LIKE '%$keyword_course%' OR
1146
                            visual_code LIKE '%$keyword_course%'
1147
                        )
1148
                   ) ";
1149
        }
1150
1151
        $res = Database::query($sql);
1152
        $obj = Database::fetch_object($res);
1153
1154
        return (int) $obj->total;
1155
    }
1156
1157
    /**
1158
     * @param int $id
1159
     *
1160
     * @return false|TicketMessageAttachment
1161
     */
1162
    public static function getTicketMessageAttachment($id)
1163
    {
1164
        $id = (int) $id;
1165
        $em = Database::getManager();
1166
        $item = $em->getRepository(TicketMessageAttachment::class)->find($id);
1167
        if ($item) {
1168
            return $item;
1169
        }
1170
1171
        return false;
1172
    }
1173
1174
    /**
1175
     * @param int $id
1176
     *
1177
     * @return array
1178
     */
1179
    public static function getTicketMessageAttachmentsByTicketId($id)
1180
    {
1181
        $id = (int) $id;
1182
        $em = Database::getManager();
1183
        $items = $em->getRepository(TicketMessageAttachment::class)->findBy(['ticket' => $id]);
1184
        if ($items) {
1185
            return $items;
1186
        }
1187
1188
        return false;
1189
    }
1190
1191
    /**
1192
     * @param int $ticketId
1193
     *
1194
     * @return array
1195
     */
1196
    public static function get_ticket_detail_by_id($ticketId)
1197
    {
1198
        $attachmentRepo = Container::getTicketMessageAttachmentRepository();
1199
1200
        $ticketId = (int) $ticketId;
1201
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1202
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1203
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1204
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1205
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1206
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1207
1208
        $sql = "SELECT
1209
                    ticket.*,
1210
                    cat.title,
1211
                    status.title as status,
1212
                    priority.title priority
1213
                FROM $table_support_tickets ticket
1214
                INNER JOIN $table_support_category cat
1215
                ON (cat.id = ticket.category_id)
1216
                INNER JOIN $table_support_priority priority
1217
                ON (priority.id = ticket.priority_id)
1218
                INNER JOIN $table_support_status status
1219
                ON (status.id = ticket.status_id)
1220
		        WHERE
1221
                    ticket.id = $ticketId ";
1222
        $result = Database::query($sql);
1223
        $ticket = [];
1224
1225
        $repo = Container::getLpRepository();
1226
        if (Database::num_rows($result) > 0) {
1227
            while ($row = Database::fetch_assoc($result)) {
1228
                $row['course'] = null;
1229
                $row['start_date_from_db'] = $row['start_date'];
1230
                $row['start_date'] = api_convert_and_format_date(
1231
                    api_get_local_time($row['start_date']),
1232
                    DATE_TIME_FORMAT_LONG,
1233
                    api_get_timezone()
1234
                );
1235
                $row['end_date_from_db'] = $row['end_date'];
1236
                $row['end_date'] = api_convert_and_format_date(
1237
                    api_get_local_time($row['end_date']),
1238
                    DATE_TIME_FORMAT_LONG,
1239
                    api_get_timezone()
1240
                );
1241
                $row['sys_lastedit_datetime_from_db'] = $row['sys_lastedit_datetime'];
1242
                $row['sys_lastedit_datetime'] = api_convert_and_format_date(
1243
                    api_get_local_time($row['sys_lastedit_datetime']),
1244
                    DATE_TIME_FORMAT_LONG,
1245
                    api_get_timezone()
1246
                );
1247
                $row['course_url'] = null;
1248
                if (0 != $row['course_id']) {
1249
                    $course = api_get_course_info_by_id($row['course_id']);
1250
                    $sessionId = 0;
1251
                    if ($row['session_id']) {
1252
                        $sessionId = $row['session_id'];
1253
                    }
1254
                    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...
1255
                        $row['course_url'] = '<a href="'.$course['course_public_url'].'?id_session='.$sessionId.'">'.$course['name'].'</a>';
1256
                    }
1257
                    $row['exercise_url'] = null;
1258
1259
                    if (!empty($row['exercise_id'])) {
1260
                        $exerciseTitle = ExerciseLib::getExerciseTitleById($row['exercise_id']);
1261
                        $dataExercise = [
1262
                            'cidReq' => $course['code'],
1263
                            'id_session' => $sessionId,
1264
                            'exerciseId' => $row['exercise_id'],
1265
                        ];
1266
                        $urlParamsExercise = http_build_query($dataExercise);
1267
1268
                        $row['exercise_url'] = '<a href="'.api_get_path(WEB_CODE_PATH).'exercise/overview.php?'.$urlParamsExercise.'">'.$exerciseTitle.'</a>';
1269
                    }
1270
1271
                    $row['lp_url'] = null;
1272
1273
                    if (!empty($row['lp_id'])) {
1274
                        /** @var CLp $lp */
1275
                        $lp = $repo->find($row['lp_id']);
1276
                        $dataLp = [
1277
                            'cidReq' => $course['code'],
1278
                            'id_session' => $sessionId,
1279
                            'lp_id' => $row['lp_id'],
1280
                            'action' => 'view',
1281
                        ];
1282
                        $urlParamsLp = http_build_query($dataLp);
1283
1284
                        $row['lp_url'] = '<a
1285
                            href="'.api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.$urlParamsLp.'">'.
1286
                            $lp->getTitle().
1287
                        '</a>';
1288
                    }
1289
                }
1290
1291
                $userInfo = api_get_user_info($row['sys_insert_user_id']);
1292
                $row['user_url'] = '<a href="'.api_get_path(WEB_PATH).'main/admin/user_information.php?user_id='.$userInfo['user_id'].'">
1293
                '.$userInfo['complete_name'].'</a>';
1294
                $ticket['user'] = $userInfo;
1295
                $ticket['ticket'] = $row;
1296
            }
1297
1298
            $sql = "SELECT *, message.id as message_id, user.id AS user_id
1299
                    FROM $table_support_messages message
1300
                    INNER JOIN $table_main_user user
1301
                    ON (message.sys_insert_user_id = user.id)
1302
                    WHERE user.active <> ".USER_SOFT_DELETED." AND
1303
                        message.ticket_id = '$ticketId' ";
1304
            $result = Database::query($sql);
1305
            $ticket['messages'] = [];
1306
            $attach_icon = Display::getMdiIcon(ObjectIcon::ATTACHMENT, 'ch-tool-icon', null, ICON_SIZE_SMALL);
1307
1308
            while ($row = Database::fetch_assoc($result)) {
1309
                $message = $row;
1310
                $message['admin'] = UserManager::is_admin($message['user_id']);
1311
                $message['user_info'] = api_get_user_info($message['user_id']);
1312
1313
                $messageAttachments = $attachmentRepo->findBy(['ticket' => $ticketId, 'message' => $row['message_id']]);
1314
1315
                /** @var TicketMessageAttachment $messageAttachment */
1316
                foreach ($messageAttachments as $messageAttachment) {
1317
                    $archiveURL = $attachmentRepo->getResourceFileDownloadUrl($messageAttachment);
1318
                    $link = Display::url(
1319
                        sprintf("%s (%d)", $messageAttachment->getFilename(), $messageAttachment->getSize()),
1320
                        $archiveURL
1321
                    );
1322
1323
                    $message['attachments'][] = $attach_icon.PHP_EOL.$link;
1324
                }
1325
                $ticket['messages'][] = $message;
1326
            }
1327
        }
1328
1329
        return $ticket;
1330
    }
1331
1332
    /**
1333
     * @param int $ticketId
1334
     * @param int $userId
1335
     *
1336
     * @return bool
1337
     */
1338
    public static function update_message_status($ticketId, $userId)
1339
    {
1340
        $ticketId = (int) $ticketId;
1341
        $userId = (int) $userId;
1342
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1343
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1344
        $now = api_get_utc_datetime();
1345
        $sql = "UPDATE $table_support_messages
1346
                SET
1347
                    status = 'LEI',
1348
                    sys_lastedit_user_id ='".api_get_user_id()."',
1349
                    sys_lastedit_datetime ='".$now."'
1350
                WHERE ticket_id ='$ticketId' ";
1351
1352
        if (api_is_platform_admin()) {
1353
            $sql .= " AND sys_insert_user_id = '$userId'";
1354
        } else {
1355
            $sql .= " AND sys_insert_user_id != '$userId'";
1356
        }
1357
        $result = Database::query($sql);
1358
        if (Database::affected_rows($result) > 0) {
1359
            Database::query(
1360
                "UPDATE $table_support_tickets SET
1361
                    status_id = '".self::STATUS_PENDING."'
1362
                 WHERE id ='$ticketId' AND status_id = '".self::STATUS_NEW."'"
1363
            );
1364
1365
            return true;
1366
        }
1367
1368
        return false;
1369
    }
1370
1371
    /**
1372
     * Send notification to a user through the internal messaging system.
1373
     */
1374
    public static function sendNotification($ticketId, $title, $message, $onlyToUserId = 0, $debug = false)
1375
    {
1376
        $ticketInfo = self::get_ticket_detail_by_id($ticketId);
1377
1378
        if (empty($ticketInfo)) {
1379
            return false;
1380
        }
1381
1382
        $assignedUserInfo = api_get_user_info($ticketInfo['ticket']['assigned_last_user']);
1383
        $requestUserInfo = $ticketInfo['user'];
1384
        $ticketCode = $ticketInfo['ticket']['code'];
1385
        $status = $ticketInfo['ticket']['status'];
1386
        $priority = $ticketInfo['ticket']['priority'];
1387
        $creatorId = $ticketInfo['ticket']['sys_insert_user_id'];
1388
1389
        // Subject
1390
        $titleEmail = "[$ticketCode] ".Security::remove_XSS($title);
1391
1392
        // Content
1393
        $href = api_get_path(WEB_CODE_PATH) . 'ticket/ticket_details.php?ticket_id=' . $ticketId;
1394
        $ticketUrl = Display::url($ticketCode, $href);
1395
        $messageEmailBase = get_lang('Ticket number') . ": $ticketUrl <br />";
1396
        $messageEmailBase .= get_lang('Status') . ": $status <br />";
1397
        $messageEmailBase .= get_lang('Priority') . ": $priority <br />";
1398
        $messageEmailBase .= '<hr /><br />';
1399
        $messageEmailBase .= $message;
1400
1401
        $currentUserId = api_get_user_id();
1402
        $recipients = [];
1403
1404
        if (!empty($onlyToUserId) && $currentUserId != $onlyToUserId) {
1405
            $recipients[$onlyToUserId] = $onlyToUserId;
1406
        } else {
1407
            if (
1408
                $requestUserInfo &&
1409
                $currentUserId != $requestUserInfo['id'] &&
1410
                self::isUserSubscribedToTicket($ticketId, $requestUserInfo['id'])
1411
            ) {
1412
                $recipients[$requestUserInfo['id']] = $requestUserInfo['complete_name_with_username'];
1413
            }
1414
1415
            if ($assignedUserInfo && $currentUserId != $assignedUserInfo['id']) {
1416
                $recipients[$assignedUserInfo['id']] = $assignedUserInfo['complete_name_with_username'];
1417
            }
1418
1419
            $followers = self::getFollowers($ticketId);
1420
            /* @var User $follower */
1421
            foreach ($followers as $follower) {
1422
                if (
1423
                    $follower->getId() !== $currentUserId &&
1424
                    (
1425
                        $follower->getId() !== $creatorId ||
1426
                        self::isUserSubscribedToTicket($ticketId, $follower->getId())
1427
                    )
1428
                ) {
1429
                    $recipients[$follower->getId()] = $follower->getFullname();
1430
                }
1431
            }
1432
        }
1433
1434
        if ($debug) {
1435
            echo "<pre>";
1436
            echo "Title: $titleEmail\n";
1437
            echo "Message Preview:\n\n";
1438
1439
            foreach ($recipients as $recipientId => $recipientName) {
1440
                $unsubscribeLink = self::generateUnsubscribeLink($ticketId, $recipientId);
1441
                $finalMessageEmail = $messageEmailBase;
1442
                $finalMessageEmail .= '<br /><hr /><br />';
1443
                $finalMessageEmail .= '<small>' . get_lang('To unsubscribe from notifications, click here') . ': ';
1444
                $finalMessageEmail .= '<a href="' . $unsubscribeLink . '">' . $unsubscribeLink . '</a></small>';
1445
1446
                echo "------------------------------------\n";
1447
                echo "Recipient: $recipientName (User ID: $recipientId)\n";
1448
                echo "Message:\n$finalMessageEmail\n";
1449
                echo "------------------------------------\n\n";
1450
            }
1451
1452
            echo "</pre>";
1453
            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...
1454
        }
1455
1456
        foreach ($recipients as $recipientId => $recipientName) {
1457
            $unsubscribeLink = self::generateUnsubscribeLink($ticketId, $recipientId);
1458
1459
            $finalMessageEmail = $messageEmailBase;
1460
            $finalMessageEmail .= '<br /><hr /><br />';
1461
            $finalMessageEmail .= '<small>' . get_lang('To unsubscribe from notifications, click here') . ': ';
1462
            $finalMessageEmail .= '<a href="' . $unsubscribeLink . '">' . $unsubscribeLink . '</a></small>';
1463
1464
            MessageManager::send_message_simple(
1465
                $recipientId,
1466
                $titleEmail,
1467
                $finalMessageEmail,
1468
                0,
1469
                false,
1470
                false,
1471
                false
1472
            );
1473
        }
1474
1475
        return true;
1476
    }
1477
1478
    /**
1479
     * @param array $params
1480
     * @param int   $ticketId
1481
     * @param int   $userId
1482
     *
1483
     * @return bool
1484
     */
1485
    public static function updateTicket(
1486
        $params,
1487
        $ticketId,
1488
        $userId
1489
    ) {
1490
        $now = api_get_utc_datetime();
1491
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1492
        $newParams = [
1493
            'priority_id' => isset($params['priority_id']) ? (int) $params['priority_id'] : '',
1494
            'status_id' => isset($params['status_id']) ? (int) $params['status_id'] : '',
1495
            'sys_lastedit_user_id' => (int) $userId,
1496
            'sys_lastedit_datetime' => $now,
1497
        ];
1498
        Database::update($table, $newParams, ['id = ? ' => $ticketId]);
1499
1500
        return true;
1501
    }
1502
1503
    /**
1504
     * @param int $status_id
1505
     * @param int $ticketId
1506
     * @param int $userId
1507
     *
1508
     * @return bool
1509
     */
1510
    public static function update_ticket_status(
1511
        $status_id,
1512
        $ticketId,
1513
        $userId
1514
    ) {
1515
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1516
1517
        $ticketId = (int) $ticketId;
1518
        $status_id = (int) $status_id;
1519
        $userId = (int) $userId;
1520
        $now = api_get_utc_datetime();
1521
1522
        $sql = "UPDATE $table_support_tickets
1523
                SET
1524
                    status_id = '$status_id',
1525
                    sys_lastedit_user_id ='$userId',
1526
                    sys_lastedit_datetime ='".$now."'
1527
                WHERE id ='$ticketId'";
1528
        $result = Database::query($sql);
1529
1530
        if (Database::affected_rows($result) > 0) {
1531
            self::sendNotification(
1532
                $ticketId,
1533
                get_lang('Ticket updated'),
1534
                get_lang('Ticket updated')
1535
            );
1536
1537
            return true;
1538
        }
1539
1540
        return false;
1541
    }
1542
1543
    /**
1544
     * @return mixed
1545
     */
1546
    public static function getNumberOfMessages()
1547
    {
1548
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1549
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1550
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1551
        $table_main_admin = Database::get_main_table(TABLE_MAIN_ADMIN);
1552
        $user_info = api_get_user_info();
1553
        $userId = $user_info['user_id'];
1554
        $sql = "SELECT COUNT(DISTINCT ticket.id) AS unread
1555
                FROM $table_support_tickets ticket,
1556
                $table_support_messages message ,
1557
                $table_main_user user
1558
                WHERE
1559
                    ticket.id = message.ticket_id AND
1560
                    message.status = 'NOL' AND
1561
                    user.user_id = message.sys_insert_user_id ";
1562
        if (!api_is_platform_admin()) {
1563
            $sql .= " AND ticket.request_user = '$userId'
1564
                      AND user_id IN (SELECT user_id FROM $table_main_admin)  ";
1565
        } else {
1566
            $sql .= " AND user_id NOT IN (SELECT user_id FROM $table_main_admin)
1567
                      AND ticket.status_id != '".self::STATUS_FORWARDED."'";
1568
        }
1569
        $sql .= ' AND ticket.access_url_id = '.(int) Container::getAccessUrlHelper()->getCurrent()->getId();
1570
        $sql .= "  AND ticket.project_id != '' ";
1571
        $res = Database::query($sql);
1572
        $obj = Database::fetch_object($res);
1573
1574
        return $obj->unread;
1575
    }
1576
1577
    /**
1578
     * @param int $ticketId
1579
     * @param int $userId
1580
     */
1581
    public static function send_alert($ticketId, $userId)
1582
    {
1583
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1584
        $now = api_get_utc_datetime();
1585
1586
        $ticketId = (int) $ticketId;
1587
        $userId = (int) $userId;
1588
1589
        $sql = "UPDATE $table_support_tickets SET
1590
                  priority_id = '".self::PRIORITY_HIGH."',
1591
                  sys_lastedit_user_id = $userId,
1592
                  sys_lastedit_datetime = '$now'
1593
                WHERE id = $ticketId";
1594
        Database::query($sql);
1595
    }
1596
1597
    /**
1598
     * @param int $ticketId
1599
     * @param int $userId
1600
     */
1601
    public static function close_ticket($ticketId, $userId)
1602
    {
1603
        $ticketId = (int) $ticketId;
1604
        $userId = (int) $userId;
1605
1606
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1607
        $now = api_get_utc_datetime();
1608
        $sql = "UPDATE $table_support_tickets SET
1609
                    status_id = '".self::STATUS_CLOSE."',
1610
                    sys_lastedit_user_id ='$userId',
1611
                    sys_lastedit_datetime ='".$now."',
1612
                    end_date ='$now'
1613
                WHERE id ='$ticketId'";
1614
        Database::query($sql);
1615
1616
        self::sendNotification(
1617
            $ticketId,
1618
            get_lang('Ticket closed'),
1619
            get_lang('Ticket closed')
1620
        );
1621
    }
1622
1623
    /**
1624
     * Close old tickets.
1625
     */
1626
    public static function close_old_tickets()
1627
    {
1628
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1629
        $now = api_get_utc_datetime();
1630
        $userId = api_get_user_id();
1631
        $accessUrlId = (int) Container::getAccessUrlHelper()->getCurrent()->getId();
1632
1633
        $sql = "UPDATE $table
1634
            SET
1635
                status_id = '".self::STATUS_CLOSE."',
1636
                sys_lastedit_user_id ='$userId',
1637
                sys_lastedit_datetime ='$now',
1638
                end_date = '$now'
1639
            WHERE
1640
                DATEDIFF('$now', sys_lastedit_datetime) > 7 AND
1641
                status_id != '".self::STATUS_CLOSE."' AND
1642
                status_id != '".self::STATUS_NEW."' AND
1643
                status_id != '".self::STATUS_FORWARDED."' AND
1644
                access_url_id = $accessUrlId";
1645
1646
        Database::query($sql);
1647
    }
1648
1649
    /**
1650
     * @param int $ticketId
1651
     *
1652
     * @return array
1653
     */
1654
    public static function get_assign_log($ticketId)
1655
    {
1656
        $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
1657
        $ticketId = (int) $ticketId;
1658
1659
        $sql = "SELECT * FROM $table
1660
                WHERE ticket_id = $ticketId
1661
                ORDER BY assigned_date DESC";
1662
        $result = Database::query($sql);
1663
        $history = [];
1664
        $webpath = api_get_path(WEB_PATH);
1665
        while ($row = Database::fetch_assoc($result)) {
1666
            if (0 != $row['user_id']) {
1667
                $assignuser = api_get_user_info($row['user_id']);
1668
                $row['assignuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['user_id'].'"  target="_blank">'.
1669
                $assignuser['username'].'</a>';
1670
            } else {
1671
                $row['assignuser'] = get_lang('Unassign');
1672
            }
1673
            $row['assigned_date'] = Display::dateToStringAgoAndLongDate($row['assigned_date']);
1674
            $insertuser = api_get_user_info($row['sys_insert_user_id']);
1675
            $row['insertuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['sys_insert_user_id'].'"  target="_blank">'.
1676
                $insertuser['username'].'</a>';
1677
            $history[] = $row;
1678
        }
1679
1680
        return $history;
1681
    }
1682
1683
    /**
1684
     * @param $from
1685
     * @param $number_of_items
1686
     * @param $column
1687
     * @param $direction
1688
     * @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...
1689
     *
1690
     * @return array
1691
     */
1692
    public static function export_tickets_by_user_id(
1693
        $from,
1694
        $number_of_items,
1695
        $column,
1696
        $direction,
1697
        $userId = null
1698
    ) {
1699
        $from = (int) $from;
1700
        $number_of_items = (int) $number_of_items;
1701
        $table_support_category = Database::get_main_table(
1702
            TABLE_TICKET_CATEGORY
1703
        );
1704
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1705
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1706
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1707
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1708
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1709
1710
        if (is_null($direction)) {
1711
            $direction = 'DESC';
1712
        }
1713
        if (is_null($userId) || 0 == $userId) {
1714
            $userId = api_get_user_id();
1715
        }
1716
1717
        $sql = "SELECT
1718
                    ticket.code,
1719
                    ticket.sys_insert_datetime,
1720
                    ticket.sys_lastedit_datetime,
1721
                    cat.title as category,
1722
                    CONCAT(user.lastname,' ', user.firstname) AS fullname,
1723
                    status.title as status,
1724
                    ticket.total_messages as messages,
1725
                    ticket.assigned_last_user as responsable
1726
                FROM $table_support_tickets ticket,
1727
                $table_support_category cat ,
1728
                $table_support_priority priority,
1729
                $table_support_status status ,
1730
                $table_main_user user
1731
                WHERE
1732
                    cat.id = ticket.category_id
1733
                    AND ticket.priority_id = priority.id
1734
                    AND ticket.status_id = status.id
1735
                    AND user.user_id = ticket.request_user ";
1736
        $sql .= ' AND ticket.access_url_id = '.(int) Container::getAccessUrlHelper()->getCurrent()->getId();
1737
1738
        // Search simple
1739
        if (isset($_GET['submit_simple'])) {
1740
            if ('' !== $_GET['keyword']) {
1741
                $keyword = Database::escape_string(trim($_GET['keyword']));
1742
                $sql .= " AND (ticket.code = '$keyword'
1743
                          OR user.firstname LIKE '%$keyword%'
1744
                          OR user.lastname LIKE '%$keyword%'
1745
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword%'
1746
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword%'
1747
                          OR user.username LIKE '%$keyword%')  ";
1748
            }
1749
        }
1750
        // Search advanced
1751
        if (isset($_GET['submit_advanced'])) {
1752
            $keyword_category = Database::escape_string(
1753
                trim($_GET['keyword_category'])
1754
            );
1755
            $keyword_request_user = Database::escape_string(
1756
                trim($_GET['keyword_request_user'])
1757
            );
1758
            $keywordAssignedTo = (int) $_GET['keyword_assigned_to'];
1759
            $keyword_start_date_start = Database::escape_string(
1760
                trim($_GET['keyword_start_date_start'])
1761
            );
1762
            $keyword_start_date_end = Database::escape_string(
1763
                trim($_GET['keyword_start_date_end'])
1764
            );
1765
            $keyword_status = Database::escape_string(
1766
                trim($_GET['keyword_status'])
1767
            );
1768
            $keyword_source = Database::escape_string(
1769
                trim($_GET['keyword_source'])
1770
            );
1771
            $keyword_priority = Database::escape_string(
1772
                trim($_GET['keyword_priority'])
1773
            );
1774
            $keyword_range = Database::escape_string(
1775
                trim($_GET['keyword_dates'])
1776
            );
1777
            $keyword_unread = Database::escape_string(
1778
                trim($_GET['keyword_unread'])
1779
            );
1780
            $keyword_course = Database::escape_string(
1781
                trim($_GET['keyword_course'])
1782
            );
1783
1784
            if ('' != $keyword_category) {
1785
                $sql .= " AND ticket.category_id = '$keyword_category'  ";
1786
            }
1787
            if ('' != $keyword_request_user) {
1788
                $sql .= " AND (ticket.request_user = '$keyword_request_user'
1789
                          OR user.firstname LIKE '%$keyword_request_user%'
1790
                          OR user.official_code LIKE '%$keyword_request_user%'
1791
                          OR user.lastname LIKE '%$keyword_request_user%'
1792
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword_request_user%'
1793
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword_request_user%'
1794
                          OR user.username LIKE '%$keyword_request_user%') ";
1795
            }
1796
            if (!empty($keywordAssignedTo)) {
1797
                $sql .= " AND ticket.assigned_last_user = $keywordAssignedTo ";
1798
            }
1799
            if ('' != $keyword_status) {
1800
                $sql .= " AND ticket.status_id = '$keyword_status'  ";
1801
            }
1802
            if ('' == $keyword_range && '' != $keyword_start_date_start) {
1803
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1804
            }
1805
            if ('1' == $keyword_range && '' != $keyword_start_date_start && '' != $keyword_start_date_end) {
1806
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1807
                          AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1808
            }
1809
            if ('' != $keyword_priority) {
1810
                $sql .= " AND ticket.priority_id = '$keyword_priority'  ";
1811
            }
1812
            if ('' != $keyword_source) {
1813
                $sql .= " AND ticket.source = '$keyword_source' ";
1814
            }
1815
            if ('' != $keyword_priority) {
1816
                $sql .= " AND ticket.priority_id = '$keyword_priority' ";
1817
            }
1818
            if ('' != $keyword_course) {
1819
                $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1820
                $sql .= " AND ticket.course_id IN ( ";
1821
                $sql .= "SELECT id
1822
                         FROM $course_table
1823
                         WHERE (title LIKE '%$keyword_course%'
1824
                         OR code LIKE '%$keyword_course%'
1825
                         OR visual_code LIKE '%$keyword_course%' )) ";
1826
            }
1827
            if ('yes' == $keyword_unread) {
1828
                $sql .= " AND ticket.id IN (
1829
                          SELECT ticket.id
1830
                          FROM $table_support_tickets ticket,
1831
                          $table_support_messages message,
1832
                          $table_main_user user
1833
                          WHERE ticket.id = message.ticket_id
1834
                          AND message.status = 'NOL'
1835
                          AND message.sys_insert_user_id = user.user_id
1836
                          AND user.status != 1   AND ticket.status_id != '".self::STATUS_FORWARDED."'
1837
                          GROUP BY ticket.id)";
1838
            } else {
1839
                if ('no' == $keyword_unread) {
1840
                    $sql .= " AND ticket.id NOT IN (
1841
                              SELECT ticket.id
1842
                              FROM  $table_support_tickets ticket,
1843
                              $table_support_messages message,
1844
                              $table_main_user user
1845
                              WHERE ticket.id = message.ticket_id
1846
                              AND message.status = 'NOL'
1847
                              AND message.sys_insert_user_id = user.user_id
1848
                              AND user.status != 1
1849
                              AND ticket.status_id != '".self::STATUS_FORWARDED."'
1850
                             GROUP BY ticket.id)";
1851
                }
1852
            }
1853
        }
1854
1855
        $sql .= !str_contains($sql, 'WHERE') ? ' WHERE user.active <> '.USER_SOFT_DELETED : ' AND user.active <> '.USER_SOFT_DELETED;
1856
        $sql .= " LIMIT $from,$number_of_items";
1857
1858
        $result = Database::query($sql);
1859
        $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...
1860
            utf8_decode('Ticket#'),
1861
            utf8_decode('Fecha'),
1862
            utf8_decode('Fecha Edicion'),
1863
            utf8_decode('Categoria'),
1864
            utf8_decode('Usuario'),
1865
            utf8_decode('Estado'),
1866
            utf8_decode('Mensajes'),
1867
            utf8_decode('Responsable'),
1868
            utf8_decode('Programa'),
1869
        ];
1870
1871
        while ($row = Database::fetch_assoc($result)) {
1872
            if (0 != $row['responsable']) {
1873
                $row['responsable'] = api_get_user_info($row['responsable']);
1874
                $row['responsable'] = $row['responsable']['firstname'].' '.$row['responsable']['lastname'];
1875
            }
1876
            $row['sys_insert_datetime'] = api_format_date(
1877
                $row['sys_insert_datetime'],
1878
                '%d/%m/%y - %I:%M:%S %p'
1879
            );
1880
            $row['sys_lastedit_datetime'] = api_format_date(
1881
                $row['sys_lastedit_datetime'],
1882
                '%d/%m/%y - %I:%M:%S %p'
1883
            );
1884
            $row['category'] = utf8_decode($row['category']);
1885
            $row['programa'] = utf8_decode($row['fullname']);
1886
            $row['fullname'] = utf8_decode($row['fullname']);
1887
            $row['responsable'] = utf8_decode($row['responsable']);
1888
            $tickets[] = $row;
1889
        }
1890
1891
        return $tickets;
1892
    }
1893
1894
    /**
1895
     * @param string $url
1896
     * @param int    $projectId
1897
     *
1898
     * @return FormValidator
1899
     */
1900
    public static function getCategoryForm($url, $projectId)
1901
    {
1902
        $form = new FormValidator('category', 'post', $url);
1903
        $form->addText('name', get_lang('Name'));
1904
        $form->addHtmlEditor('description', get_lang('Description'));
1905
        $form->addHidden('project_id', $projectId);
1906
        $form->addButtonUpdate(get_lang('Save'));
1907
1908
        return $form;
1909
    }
1910
1911
    /**
1912
     * @return array
1913
     */
1914
    public static function getStatusList()
1915
    {
1916
        $accessUrl = Container::getAccessUrlHelper()->getCurrent();
1917
        $items = Database::getManager()
1918
            ->getRepository(TicketStatus::class)
1919
            ->findBy(['accessUrl' => $accessUrl]);
1920
1921
        $list = [];
1922
        /** @var TicketStatus $row */
1923
        foreach ($items as $row) {
1924
            $list[$row->getId()] = $row->getTitle();
1925
        }
1926
1927
        return $list;
1928
    }
1929
1930
    /**
1931
     * @param array $criteria
1932
     *
1933
     * @return array
1934
     */
1935
    public static function getTicketsFromCriteria($criteria)
1936
    {
1937
        $items = Database::getManager()->getRepository(Ticket::class)->findBy($criteria);
1938
        $list = [];
1939
        /** @var Ticket $row */
1940
        foreach ($items as $row) {
1941
            $list[$row->getId()] = $row->getCode();
1942
        }
1943
1944
        return $list;
1945
    }
1946
1947
    /**
1948
     * @param string $code
1949
     *
1950
     * @return int
1951
     */
1952
    public static function getStatusIdFromCode($code)
1953
    {
1954
        $item = Database::getManager()
1955
            ->getRepository(TicketStatus::class)
1956
            ->findOneBy(['code' => $code])
1957
        ;
1958
1959
        if ($item) {
1960
            return $item->getId();
1961
        }
1962
1963
        return 0;
1964
    }
1965
1966
    /**
1967
     * @return array
1968
     */
1969
    public static function getPriorityList()
1970
    {
1971
        $accessUrl = Container::getAccessUrlHelper()->getCurrent();
1972
        $priorities = Database::getManager()
1973
            ->getRepository(TicketPriority::class)
1974
            ->findBy(['accessUrl' => $accessUrl]);
1975
1976
        $list = [];
1977
        /** @var TicketPriority $row */
1978
        foreach ($priorities as $row) {
1979
            $list[$row->getId()] = $row->getTitle();
1980
        }
1981
1982
        return $list;
1983
    }
1984
1985
    /**
1986
     * @return array
1987
     */
1988
    public static function getProjects()
1989
    {
1990
        $accessUrl = Container::getAccessUrlHelper()->getCurrent();
1991
        $projects = Database::getManager()
1992
            ->getRepository(TicketProject::class)
1993
            ->findBy(['accessUrl' => $accessUrl]);
1994
1995
        $list = [];
1996
        /** @var TicketProject $row */
1997
        foreach ($projects as $row) {
1998
            $list[] = [
1999
                'id' => $row->getId(),
2000
                '0' => $row->getId(),
2001
                '1' => $row->getTitle(),
2002
                '2' => $row->getDescription(),
2003
                '3' => $row->getId(),
2004
            ];
2005
        }
2006
2007
        return $list;
2008
    }
2009
2010
    /**
2011
     * @return array
2012
     */
2013
    public static function getProjectsSimple()
2014
    {
2015
        $accessUrl = Container::getAccessUrlHelper()->getCurrent();
2016
        $projects = Database::getManager()
2017
            ->getRepository(TicketProject::class)
2018
            ->findBy(['accessUrl' => $accessUrl]);
2019
2020
        $list = [];
2021
        /** @var TicketProject $row */
2022
        foreach ($projects as $row) {
2023
            $list[] = [
2024
                'id' => $row->getId(),
2025
                '0' => $row->getId(),
2026
                '1' => Display::url(
2027
                    $row->getTitle(),
2028
                    api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id='.$row->getId()
2029
                ),
2030
                '2' => $row->getDescription(),
2031
            ];
2032
        }
2033
2034
        return $list;
2035
    }
2036
2037
    /**
2038
     * @return int
2039
     */
2040
    public static function getProjectsCount()
2041
    {
2042
        return Database::getManager()->getRepository(TicketProject::class)->createQueryBuilder('p')
2043
            ->select('COUNT(p.id)')
2044
            ->getQuery()
2045
            ->getSingleScalarResult();
2046
    }
2047
2048
    /**
2049
     * @param array $params
2050
     */
2051
    public static function addProject($params)
2052
    {
2053
        $project = new TicketProject();
2054
        $project->setTitle($params['title']);
2055
        $project->setDescription($params['description']);
2056
        $project->setInsertUserId(api_get_user_id());
2057
        $project->setAccessUrl(Container::getAccessUrlHelper()->getCurrent());
2058
2059
        Database::getManager()->persist($project);
2060
        Database::getManager()->flush();
2061
    }
2062
2063
    /**
2064
     * @param int $id
2065
     *
2066
     * @return TicketProject
2067
     */
2068
    public static function getProject($id)
2069
    {
2070
        return Database::getManager()->getRepository(TicketProject::class)->find($id);
2071
    }
2072
2073
    /**
2074
     * @param int   $id
2075
     * @param array $params
2076
     */
2077
    public static function updateProject($id, $params)
2078
    {
2079
        $project = self::getProject($id);
2080
        $project->setTitle($params['title']);
2081
        $project->setDescription($params['description']);
2082
        $project->setLastEditDateTime(new DateTime($params['sys_lastedit_datetime']));
2083
        $project->setLastEditUserId($params['sys_lastedit_user_id']);
2084
        $project->setAccessUrl(Container::getAccessUrlHelper()->getCurrent());
2085
2086
        Database::getManager()->persist($project);
2087
        Database::getManager()->flush();
2088
    }
2089
2090
    /**
2091
     * @param int $id
2092
     */
2093
    public static function deleteProject($id)
2094
    {
2095
        $project = self::getProject($id);
2096
        if ($project) {
0 ignored issues
show
introduced by
$project is of type Chamilo\CoreBundle\Entity\TicketProject, thus it always evaluated to true.
Loading history...
2097
            Database::getManager()->remove($project);
2098
            Database::getManager()->flush();
2099
        }
2100
    }
2101
2102
    /**
2103
     * @param string $url
2104
     *
2105
     * @return FormValidator
2106
     */
2107
    public static function getProjectForm($url)
2108
    {
2109
        $form = new FormValidator('project', 'post', $url);
2110
        $form->addText('name', get_lang('Name'));
2111
        $form->addHtmlEditor('description', get_lang('Description'));
2112
        $form->addButtonUpdate(get_lang('Save'));
2113
2114
        return $form;
2115
    }
2116
2117
    /**
2118
     * @return array
2119
     */
2120
    public static function getStatusAdminList()
2121
    {
2122
        $accessUrl = Container::getAccessUrlHelper()->getCurrent();
2123
        $items = Database::getManager()
2124
            ->getRepository(TicketStatus::class)
2125
            ->findBy(['accessUrl' => $accessUrl]);
2126
2127
        $list = [];
2128
        /** @var TicketStatus $row */
2129
        foreach ($items as $row) {
2130
            $list[] = [
2131
                'id' => $row->getId(),
2132
                'code' => $row->getCode(),
2133
                '0' => $row->getId(),
2134
                '1' => $row->getTitle(),
2135
                '2' => $row->getDescription(),
2136
                '3' => $row->getId(),
2137
            ];
2138
        }
2139
2140
        return $list;
2141
    }
2142
2143
    /**
2144
     * @return array
2145
     */
2146
    /*public static function getStatusSimple()
2147
    {
2148
        $projects = Database::getManager()->getRepository(TicketStatus::class)->findAll();
2149
        $list = [];
2150
        // @var TicketProject $row
2151
        foreach ($projects as $row) {
2152
            $list[] = [
2153
                'id' => $row->getId(),
2154
                '0' => $row->getId(),
2155
                '1' => Display::url($row->getName()),
2156
                '2' => $row->getDescription(),
2157
            ];
2158
        }
2159
2160
        return $list;
2161
    }*/
2162
2163
    /**
2164
     * @return int
2165
     */
2166
    public static function getStatusCount()
2167
    {
2168
        return Database::getManager()->getRepository(TicketStatus::class)->createQueryBuilder('p')
2169
            ->select('COUNT(p.id)')
2170
            ->getQuery()
2171
            ->getSingleScalarResult();
2172
    }
2173
2174
    /**
2175
     * @param array $params
2176
     */
2177
    public static function addStatus($params)
2178
    {
2179
        $item = new TicketStatus();
2180
        $item->setCode(URLify::filter($params['title']));
2181
        $item->setTitle($params['title']);
2182
        $item->setDescription($params['description']);
2183
        $item->setAccessUrl(Container::getAccessUrlHelper()->getCurrent());
2184
2185
        Database::getManager()->persist($item);
2186
        Database::getManager()->flush();
2187
    }
2188
2189
    /**
2190
     * @param $id
2191
     *
2192
     * @return TicketProject
2193
     */
2194
    public static function getStatus($id)
2195
    {
2196
        return Database::getManager()->getRepository(TicketStatus::class)->find($id);
2197
    }
2198
2199
    /**
2200
     * @param int   $id
2201
     * @param array $params
2202
     */
2203
    public static function updateStatus($id, $params)
2204
    {
2205
        $item = self::getStatus($id);
2206
        $item->setTitle($params['title']);
2207
        $item->setDescription($params['description']);
2208
        $item->setAccessUrl(Container::getAccessUrlHelper()->getCurrent());
2209
2210
        Database::getManager()->persist($item);
2211
        Database::getManager()->flush();
2212
    }
2213
2214
    /**
2215
     * @param int $id
2216
     */
2217
    public static function deleteStatus($id)
2218
    {
2219
        $item = self::getStatus($id);
2220
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\CoreBundle\Entity\TicketProject, thus it always evaluated to true.
Loading history...
2221
            Database::getManager()->remove($item);
2222
            Database::getManager()->flush();
2223
        }
2224
    }
2225
2226
    /**
2227
     * @param string $url
2228
     *
2229
     * @return FormValidator
2230
     */
2231
    public static function getStatusForm($url)
2232
    {
2233
        $form = new FormValidator('status', 'post', $url);
2234
        $form->addText('name', get_lang('Name'));
2235
        $form->addHtmlEditor('description', get_lang('Description'));
2236
        $form->addButtonUpdate(get_lang('Save'));
2237
2238
        return $form;
2239
    }
2240
2241
    /**
2242
     * @return array
2243
     */
2244
    public static function getPriorityAdminList(): array
2245
    {
2246
        $accessUrl = Container::getAccessUrlHelper()->getCurrent();
2247
        $items = Database::getManager()
2248
            ->getRepository(TicketPriority::class)
2249
            ->findBy(['accessUrl' => $accessUrl]);
2250
2251
        $list = [];
2252
        /** @var TicketPriority $row */
2253
        foreach ($items as $row) {
2254
            $list[] = [
2255
                'id' => $row->getId(),
2256
                'code' => $row->getCode(),
2257
                '0' => $row->getId(),
2258
                '1' => $row->getTitle(),
2259
                '2' => $row->getDescription(),
2260
                '3' => $row->getId(),
2261
            ];
2262
        }
2263
2264
        return $list;
2265
    }
2266
2267
    /**
2268
     * @return int
2269
     */
2270
    public static function getPriorityCount()
2271
    {
2272
        return Database::getManager()->getRepository(TicketPriority::class)->createQueryBuilder('p')
2273
            ->select('COUNT(p.id)')
2274
            ->getQuery()
2275
            ->getSingleScalarResult();
2276
    }
2277
2278
    /**
2279
     * @param array $params
2280
     */
2281
    public static function addPriority($params)
2282
    {
2283
        $item = new TicketPriority();
2284
        $item
2285
            ->setCode(URLify::filter($params['title']))
2286
            ->setTitle($params['title'])
2287
            ->setDescription($params['description'])
2288
            ->setColor('')
2289
            ->setInsertUserId(api_get_user_id())
2290
            ->setUrgency('')
2291
            ->setAccessUrl(Container::getAccessUrlHelper()->getCurrent());
2292
2293
        Database::getManager()->persist($item);
2294
        Database::getManager()->flush();
2295
    }
2296
2297
    /**
2298
     * @param $id
2299
     *
2300
     * @return TicketPriority
2301
     */
2302
    public static function getPriority($id)
2303
    {
2304
        return Database::getManager()->getRepository(TicketPriority::class)->find($id);
2305
    }
2306
2307
    /**
2308
     * @param int   $id
2309
     * @param array $params
2310
     */
2311
    public static function updatePriority($id, $params)
2312
    {
2313
        $item = self::getPriority($id);
2314
        $item->setTitle($params['title']);
2315
        $item->setDescription($params['description']);
2316
        $item->setAccessUrl(Container::getAccessUrlHelper()->getCurrent());
2317
2318
        Database::getManager()->persist($item);
2319
        Database::getManager()->flush();
2320
    }
2321
2322
    /**
2323
     * @param int $id
2324
     */
2325
    public static function deletePriority($id)
2326
    {
2327
        $item = self::getPriority($id);
2328
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\CoreBundle\Entity\TicketPriority, thus it always evaluated to true.
Loading history...
2329
            Database::getManager()->remove($item);
2330
            Database::getManager()->flush();
2331
        }
2332
    }
2333
2334
    /**
2335
     * @param string $url
2336
     *
2337
     * @return FormValidator
2338
     */
2339
    public static function getPriorityForm($url)
2340
    {
2341
        $form = new FormValidator('priority', 'post', $url);
2342
        $form->addText('name', get_lang('Name'));
2343
        $form->addHtmlEditor('description', get_lang('Description'));
2344
        $form->addButtonUpdate(get_lang('Save'));
2345
2346
        return $form;
2347
    }
2348
2349
    /**
2350
     * Returns a list of menu elements for the tickets system's configuration.
2351
     *
2352
     * @param string $exclude The element to exclude from the list
2353
     *
2354
     * @return array
2355
     */
2356
    public static function getSettingsMenuItems($exclude = null)
2357
    {
2358
        $project = [
2359
            'icon' => ObjectIcon::PROJECT,
2360
            'url' => 'projects.php',
2361
            'content' => get_lang('Projects'),
2362
        ];
2363
        $status = [
2364
            'icon' => StateIcon::COMPLETE,
2365
            'url' => 'status.php',
2366
            'content' => get_lang('Status'),
2367
        ];
2368
        $priority = [
2369
            'icon' => StateIcon::EXPIRED,
2370
            'url' => 'priorities.php',
2371
            'content' => get_lang('Priority'),
2372
        ];
2373
        switch ($exclude) {
2374
            case 'project':
2375
                $items = [$status, $priority];
2376
                break;
2377
            case 'status':
2378
                $items = [$project, $priority];
2379
                break;
2380
            case 'priority':
2381
                $items = [$project, $status];
2382
                break;
2383
            default:
2384
                $items = [$project, $status, $priority];
2385
                break;
2386
        }
2387
2388
        return $items;
2389
    }
2390
2391
    /**
2392
     * Returns a list of strings representing the default statuses.
2393
     *
2394
     * @return array
2395
     */
2396
    public static function getDefaultStatusList()
2397
    {
2398
        return [
2399
            self::STATUS_NEW,
2400
            self::STATUS_PENDING,
2401
            self::STATUS_UNCONFIRMED,
2402
            self::STATUS_CLOSE,
2403
            self::STATUS_FORWARDED,
2404
        ];
2405
    }
2406
2407
    /**
2408
     * @return array
2409
     */
2410
    public static function getDefaultPriorityList()
2411
    {
2412
        return [
2413
            self::PRIORITY_NORMAL,
2414
            self::PRIORITY_HIGH,
2415
            self::PRIORITY_LOW,
2416
            self::STATUS_CLOSE,
2417
            self::STATUS_FORWARDED,
2418
        ];
2419
    }
2420
2421
    /**
2422
     * Deletes the user from all the ticket system.
2423
     *
2424
     * @param int $userId
2425
     */
2426
    public static function deleteUserFromTicketSystem($userId)
2427
    {
2428
        $userId = (int) $userId;
2429
        $schema = Database::getManager()->getConnection()->createSchemaManager();
2430
2431
        if ($schema->tablesExist('ticket_assigned_log')) {
2432
            $sql = "UPDATE ticket_assigned_log SET user_id = NULL WHERE user_id = $userId";
2433
            Database::query($sql);
2434
2435
            $sql = "UPDATE ticket_assigned_log SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2436
            Database::query($sql);
2437
        }
2438
2439
        if ($schema->tablesExist('ticket_ticket')) {
2440
            $sql = "UPDATE ticket_ticket SET assigned_last_user = NULL WHERE assigned_last_user = $userId";
2441
            Database::query($sql);
2442
2443
            $sql = "UPDATE ticket_ticket SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2444
            Database::query($sql);
2445
2446
            $sql = "UPDATE ticket_ticket SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2447
            Database::query($sql);
2448
        }
2449
2450
        if ($schema->tablesExist('ticket_category')) {
2451
            $sql = "UPDATE ticket_category SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2452
            Database::query($sql);
2453
2454
            $sql = "UPDATE ticket_category SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2455
            Database::query($sql);
2456
        }
2457
2458
        if ($schema->tablesExist('ticket_category_rel_user')) {
2459
            $sql = "DELETE FROM ticket_category_rel_user WHERE user_id = $userId";
2460
            Database::query($sql);
2461
        }
2462
2463
        if ($schema->tablesExist('ticket_message')) {
2464
            $sql = "UPDATE ticket_message SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2465
            Database::query($sql);
2466
2467
            $sql = "UPDATE ticket_message SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2468
            Database::query($sql);
2469
        }
2470
2471
        if ($schema->tablesExist('ticket_message_attachments')) {
2472
            $sql = "UPDATE ticket_message_attachments SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2473
            Database::query($sql);
2474
2475
            $sql = "UPDATE ticket_message_attachments SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2476
            Database::query($sql);
2477
        }
2478
2479
        if ($schema->tablesExist('ticket_priority')) {
2480
            $sql = "UPDATE ticket_priority SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2481
            Database::query($sql);
2482
2483
            $sql = "UPDATE ticket_priority SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2484
            Database::query($sql);
2485
        }
2486
2487
        if ($schema->tablesExist('ticket_project')) {
2488
            $sql = "UPDATE ticket_project SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2489
            Database::query($sql);
2490
2491
            $sql = "UPDATE ticket_project SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2492
            Database::query($sql);
2493
        }
2494
    }
2495
2496
    /**
2497
     * @deprecated Use TicketProjectHelper::userIsAllowInProject instead
2498
     */
2499
    public static function userIsAllowInProject(int $projectId): bool
2500
    {
2501
        $authorizationChecked = Container::getAuthorizationChecker();
2502
2503
        if ($authorizationChecked->isGranted('ROLE_ADMIN')) {
2504
            return true;
2505
        }
2506
2507
        $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

2507
        $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...
2508
2509
        // Check if a role was set to the project.
2510
        // Project 1 is considered the default and is accessible to all users
2511
        if (!empty($allowRoleList)) {
2512
            $result = false;
2513
            foreach ($allowRoleList as $role) {
2514
                if ($authorizationChecked->isGranted($role)) {
2515
                    $result = true;
2516
                    break;
2517
                }
2518
            }
2519
2520
            return $result;
2521
        }
2522
2523
        return false;
2524
    }
2525
2526
    /**
2527
     * @deprecated Use TicketProjectHelper::getAllowedRolesFromProject instead
2528
     */
2529
    public static function getAllowedRolesFromProject(int $projectId): array
2530
    {
2531
        // Define a mapping from role IDs to role names
2532
        $roleMap = [
2533
            1 => 'ROLE_TEACHER',
2534
            17 => 'ROLE_STUDENT_BOSS',
2535
            4 => 'ROLE_HR',
2536
            3 => 'ROLE_SESSION_MANAGER',
2537
            // ... other mappings can be added as needed
2538
        ];
2539
2540
        $jsonString = Container::getSettingsManager()->getSetting('ticket.ticket_project_user_roles');
2541
2542
        if (empty($jsonString)) {
2543
            return [];
2544
        }
2545
2546
        $data = json_decode($jsonString, true);
2547
2548
        if (JSON_ERROR_NONE !== json_last_error()) {
2549
            // Invalid JSON
2550
            return [];
2551
        }
2552
2553
        if (!isset($data['permissions'][$projectId])) {
2554
            // No permissions for the given projectId
2555
            return [];
2556
        }
2557
2558
        $roleIds = $data['permissions'][$projectId];
2559
2560
        // Transform role IDs into role names using the defined mapping
2561
        return array_map(function ($roleId) use ($roleMap) {
2562
            return $roleMap[$roleId] ?? "$roleId";
2563
        }, $roleIds);
2564
    }
2565
2566
    /**
2567
     * Subscribes a user to a ticket.
2568
     */
2569
    public static function subscribeUserToTicket(int $ticketId, int $userId): void
2570
    {
2571
        $em = Database::getManager();
2572
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2573
        $user = $em->getRepository(User::class)->find($userId);
2574
2575
        if ($ticket && $user) {
2576
            $repository = $em->getRepository(TicketRelUser::class);
2577
            $repository->subscribeUserToTicket($user, $ticket);
2578
2579
            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

2579
            Event::/** @scrutinizer ignore-call */ 
2580
                   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...
2580
                'ticket_subscribe',
2581
                'ticket_event',
2582
                ['user_id' => $userId, 'ticket_id' => $ticketId, 'action' => 'subscribe']
2583
            );
2584
        }
2585
    }
2586
2587
    /**
2588
     * Unsubscribes a user from a ticket.
2589
     */
2590
    public static function unsubscribeUserFromTicket(int $ticketId, int $userId): void
2591
    {
2592
        $em = Database::getManager();
2593
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2594
        $user = $em->getRepository(User::class)->find($userId);
2595
2596
        if ($ticket && $user) {
2597
            $repository = $em->getRepository(TicketRelUser::class);
2598
            $repository->unsubscribeUserFromTicket($user, $ticket);
2599
2600
            Event::addEvent(
2601
                'ticket_unsubscribe',
2602
                'ticket_event',
2603
                ['user_id' => $userId, 'ticket_id' => $ticketId, 'action' => 'unsubscribe']
2604
            );
2605
        }
2606
    }
2607
2608
    /**
2609
     * Checks if a user is subscribed to a ticket.
2610
     */
2611
    public static function isUserSubscribedToTicket(int $ticketId, int $userId): bool
2612
    {
2613
        $em = Database::getManager();
2614
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2615
        $user = $em->getRepository(User::class)->find($userId);
2616
2617
        if ($ticket && $user) {
2618
            $repository = $em->getRepository(TicketRelUser::class);
2619
            return $repository->isUserSubscribedToTicket($user, $ticket);
2620
        }
2621
2622
        return false;
2623
    }
2624
2625
    /**
2626
     * Retrieves the followers of a ticket.
2627
     */
2628
    public static function getFollowers($ticketId): array
2629
    {
2630
        $em = Database::getManager();
2631
        $repository = $em->getRepository(TicketRelUser::class);
2632
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2633
2634
        $followers = $repository->findBy(['ticket' => $ticket]);
2635
2636
        $users = [];
2637
        foreach ($followers as $follower) {
2638
            $users[] = $follower->getUser();
2639
        }
2640
2641
        return $users;
2642
    }
2643
2644
    /**
2645
     * Generates an unsubscribe link for a ticket.
2646
     */
2647
    public static function generateUnsubscribeLink($ticketId, $userId): string
2648
    {
2649
        $token = new ValidationToken(ValidationTokenHelper::TYPE_TICKET, $ticketId);
2650
        Database::getManager()->persist($token);
2651
        Database::getManager()->flush();
2652
2653
        return api_get_path(WEB_PATH).'validate/ticket/'.$token->getHash().'?user_id='.$userId;
2654
    }
2655
}
2656