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

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

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