TicketManager::getTicketsByCurrentUser()   F
last analyzed

Complexity

Conditions 38
Paths > 20000

Size

Total Lines 238
Code Lines 166

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 38
eloc 166
nc 5324802
nop 4
dl 0
loc 238
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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