Passed
Pull Request — 1.11.x (#6691)
by
unknown
10:24
created

TicketManager::add()   F

Complexity

Conditions 40
Paths > 20000

Size

Total Lines 313
Code Lines 188

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 188
c 1
b 0
f 0
dl 0
loc 313
rs 0
cc 40
nc 1851121
nop 15

How to fix   Long Method    Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\TicketBundle\Entity\MessageAttachment;
5
use Chamilo\TicketBundle\Entity\Priority;
6
use Chamilo\TicketBundle\Entity\Project;
7
use Chamilo\TicketBundle\Entity\Status;
8
use Chamilo\TicketBundle\Entity\Ticket;
9
10
/**
11
 * Class TicketManager.
12
 *
13
 * @package chamilo.plugin.ticket
14
 */
15
class TicketManager
16
{
17
    public const PRIORITY_NORMAL = 'NRM';
18
    public const PRIORITY_HIGH = 'HGH';
19
    public const PRIORITY_LOW = 'LOW';
20
21
    public const SOURCE_EMAIL = 'MAI';
22
    public const SOURCE_PHONE = 'TEL';
23
    public const SOURCE_PLATFORM = 'PLA';
24
    public const SOURCE_PRESENTIAL = 'PRE';
25
26
    public const STATUS_NEW = 'NAT';
27
    public const STATUS_PENDING = 'PND';
28
    public const STATUS_UNCONFIRMED = 'XCF';
29
    public const STATUS_CLOSE = 'CLS';
30
    public const STATUS_FORWARDED = 'REE';
31
32
    /**
33
     * Constructor.
34
     */
35
    public function __construct()
36
    {
37
    }
38
39
    /**
40
     * Get categories of tickets.
41
     *
42
     * @param int    $projectId
43
     * @param string $order
44
     *
45
     * @return array
46
     */
47
    public static function get_all_tickets_categories($projectId, $order = '')
48
    {
49
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
50
        $table_support_project = Database::get_main_table(TABLE_TICKET_PROJECT);
51
52
        $order = empty($order) ? 'category.total_tickets DESC' : $order;
53
        $order = Database::escape_string($order);
54
        $projectId = (int) $projectId;
55
56
        $sql = "SELECT
57
                    category.*,
58
                    category.id category_id,
59
                    project.other_area,
60
                    project.email
61
                FROM
62
                $table_support_category category
63
                INNER JOIN $table_support_project project
64
                ON project.id = category.project_id
65
                WHERE project.id  = $projectId
66
                ORDER BY $order";
67
        $result = Database::query($sql);
68
        $types = [];
69
        while ($row = Database::fetch_assoc($result)) {
70
            $types[] = $row;
71
        }
72
73
        return $types;
74
    }
75
76
    /**
77
     * @param $from
78
     * @param $numberItems
79
     * @param $column
80
     * @param $direction
81
     *
82
     * @return array
83
     */
84
    public static function getCategories($from, $numberItems, $column, $direction)
85
    {
86
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
87
        $sql = "SELECT id, name, description, total_tickets
88
                FROM $table";
89
90
        if (!in_array($direction, ['ASC', 'DESC'])) {
91
            $direction = 'ASC';
92
        }
93
        $column = (int) $column;
94
        $from = (int) $from;
95
        $numberItems = (int) $numberItems;
96
97
        //$sql .= " ORDER BY col$column $direction ";
98
        $sql .= " LIMIT $from,$numberItems";
99
100
        $result = Database::query($sql);
101
        $types = [];
102
        while ($row = Database::fetch_array($result)) {
103
            $types[] = $row;
104
        }
105
106
        return $types;
107
    }
108
109
    /**
110
     * @param int $id
111
     *
112
     * @return array|mixed
113
     */
114
    public static function getCategory($id)
115
    {
116
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
117
        $id = (int) $id;
118
        $sql = "SELECT id, name, description, total_tickets
119
                FROM $table WHERE id = $id";
120
121
        $result = Database::query($sql);
122
        $category = Database::fetch_array($result);
123
124
        return $category;
125
    }
126
127
    /**
128
     * @return int
129
     */
130
    public static function getCategoriesCount()
131
    {
132
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
133
134
        $sql = "SELECT count(id) count
135
                FROM $table ";
136
137
        $result = Database::query($sql);
138
        $category = Database::fetch_array($result);
139
140
        return $category['count'];
141
    }
142
143
    /**
144
     * @param int   $id
145
     * @param array $params
146
     */
147
    public static function updateCategory($id, $params)
148
    {
149
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
150
        $id = (int) $id;
151
        Database::update($table, $params, ['id = ?' => $id]);
152
    }
153
154
    /**
155
     * @param array $params
156
     */
157
    public static function addCategory($params)
158
    {
159
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
160
        Database::insert($table, $params);
161
    }
162
163
    /**
164
     * @param int $id
165
     *
166
     * @return bool
167
     */
168
    public static function deleteCategory($id)
169
    {
170
        $id = (int) $id;
171
        if (empty($id)) {
172
            return false;
173
        }
174
175
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
176
        $sql = "UPDATE $table SET category_id = NULL WHERE category_id = $id";
177
        Database::query($sql);
178
179
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
180
        $sql = "DELETE FROM $table WHERE id = $id";
181
        Database::query($sql);
182
183
        return true;
184
    }
185
186
    /**
187
     * @param int   $categoryId
188
     * @param array $users
189
     *
190
     * @return bool
191
     */
192
    public static function addUsersToCategory($categoryId, $users)
193
    {
194
        if (empty($users) || empty($categoryId)) {
195
            return false;
196
        }
197
198
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
199
        foreach ($users as $userId) {
200
            if (self::userIsAssignedToCategory($userId, $categoryId) === false) {
201
                $params = [
202
                    'category_id' => $categoryId,
203
                    'user_id' => $userId,
204
                ];
205
                Database::insert($table, $params);
206
            }
207
        }
208
209
        return true;
210
    }
211
212
    /**
213
     * @param int $userId
214
     * @param int $categoryId
215
     *
216
     * @return bool
217
     */
218
    public static function userIsAssignedToCategory($userId, $categoryId)
219
    {
220
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
221
        $userId = (int) $userId;
222
        $categoryId = (int) $categoryId;
223
        $sql = "SELECT * FROM $table
224
                WHERE category_id = $categoryId AND user_id = $userId";
225
        $result = Database::query($sql);
226
227
        return Database::num_rows($result) > 0;
228
    }
229
230
    /**
231
     * @param int $categoryId
232
     *
233
     * @return array
234
     */
235
    public static function getUsersInCategory($categoryId)
236
    {
237
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
238
        $categoryId = (int) $categoryId;
239
        $sql = "SELECT * FROM $table WHERE category_id = $categoryId";
240
        $result = Database::query($sql);
241
242
        return Database::store_result($result);
243
    }
244
245
        /**
246
     * Returns the list of category IDs assigned to a user.
247
     *
248
     * @param int $userId
249
     * @param int $projectId
250
     *
251
     * @return int[]
252
     */
253
    public static function getCategoryIdsByUser($userId, $projectId = 0)
254
    {
255
        $tableRel = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
256
        $tableCat = Database::get_main_table(TABLE_TICKET_CATEGORY);
257
        $userId = (int) $userId;
258
        $projectId = (int) $projectId;
259
260
        $sql = "SELECT rel.category_id
261
                FROM $tableRel rel
262
                INNER JOIN $tableCat cat ON (rel.category_id = cat.id)
263
                WHERE rel.user_id = $userId";
264
265
        if (!empty($projectId)) {
266
            $sql .= " AND cat.project_id = $projectId";
267
        }
268
269
        $result = Database::query($sql);
270
        $categories = [];
271
        while ($row = Database::fetch_array($result)) {
272
            $categories[] = (int) $row['category_id'];
273
        }
274
275
        return $categories;
276
    }
277
278
    /**
279
     * @param int $categoryId
280
     */
281
    public static function deleteAllUserInCategory($categoryId)
282
    {
283
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
284
        $categoryId = (int) $categoryId;
285
        $sql = "DELETE FROM $table WHERE category_id = $categoryId";
286
        Database::query($sql);
287
    }
288
289
    /**
290
     * Get all possible tickets statuses.
291
     *
292
     * @return array
293
     */
294
    public static function get_all_tickets_status()
295
    {
296
        $table = Database::get_main_table(TABLE_TICKET_STATUS);
297
        $sql = "SELECT * FROM $table";
298
        $result = Database::query($sql);
299
        $types = [];
300
        while ($row = Database::fetch_assoc($result)) {
301
            $types[] = $row;
302
        }
303
304
        return $types;
305
    }
306
307
    /**
308
     * Inserts a new ticket in the corresponding tables.
309
     *
310
     * @param int    $category_id
311
     * @param int    $course_id
312
     * @param int    $sessionId
313
     * @param int    $project_id
314
     * @param string $other_area
315
     * @param string $subject
316
     * @param string $content
317
     * @param string $personalEmail
318
     * @param array  $fileAttachments
319
     * @param string $source
320
     * @param string $priority
321
     * @param string $status
322
     * @param int    $assignedUserId
323
     * @param int    $exerciseId
324
     * @param int    $lpId
325
     *
326
     * @return bool
327
     */
328
    public static function add(
329
        $category_id,
330
        $course_id,
331
        $sessionId,
332
        $project_id,
333
        $other_area,
334
        $subject,
335
        $content,
336
        $personalEmail = '',
337
        $fileAttachments = [],
338
        $source = '',
339
        $priority = '',
340
        $status = '',
341
        $assignedUserId = 0,
342
        $exerciseId = null,
343
        $lpId = null
344
    ) {
345
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
346
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
347
348
        if (empty($category_id)) {
349
            return false;
350
        }
351
352
        $currentUserId = api_get_user_id();
353
        $currentUserInfo = api_get_user_info();
354
        $now = api_get_utc_datetime();
355
        $course_id = (int) $course_id;
356
        $category_id = (int) $category_id;
357
        $project_id = (int) $project_id;
358
359
        // Resolve priority to numeric ID (accepts ID or code like 'NRM')
360
        $priorityId = null;
361
        $priorityCodeOrId = $priority;
362
        if (empty($priorityCodeOrId)) {
363
            $priorityCodeOrId = self::PRIORITY_NORMAL;
364
        }
365
        if (is_numeric($priorityCodeOrId)) {
366
            $priorityId = (int) $priorityCodeOrId;
367
        } else {
368
            $priorityId = self::getPriorityIdFromCode((string) $priorityCodeOrId);
369
        }
370
        if (empty($priorityId)) {
371
            // Fallback to default priority if mapping failed
372
            $priorityId = self::getPriorityIdFromCode(self::PRIORITY_NORMAL);
373
        }
374
375
        // Resolve status to numeric ID (accepts ID or code like 'NAT')
376
        $statusId = null;
377
        $statusCodeOrId = $status;
378
        if ($statusCodeOrId === '' || $statusCodeOrId === null) {
379
            $statusCodeOrId = self::STATUS_NEW;
380
            if ($other_area > 0) {
381
                $statusCodeOrId = self::STATUS_FORWARDED;
382
            }
383
        }
384
        if (is_numeric($statusCodeOrId)) {
385
            $statusId = (int) $statusCodeOrId;
386
        } else {
387
            $statusId = self::getStatusIdFromCode((string) $statusCodeOrId);
388
        }
389
390
        if (!empty($category_id)) {
391
            if (empty($assignedUserId)) {
392
                $usersInCategory = self::getUsersInCategory($category_id);
393
                if (!empty($usersInCategory) && count($usersInCategory) > 0) {
394
                    $userCategoryInfo = $usersInCategory[0];
395
                    if (isset($userCategoryInfo['user_id'])) {
396
                        $assignedUserId = $userCategoryInfo['user_id'];
397
                    }
398
                }
399
            }
400
        }
401
402
        $assignedUserInfo = [];
403
        if (!empty($assignedUserId)) {
404
            $assignedUserInfo = api_get_user_info($assignedUserId);
405
            if (empty($assignedUserInfo)) {
406
                return false;
407
            }
408
        }
409
410
        // insert_ticket
411
        $params = [
412
            'project_id' => $project_id,
413
            'category_id' => $category_id,
414
            'priority_id' => $priorityId,
415
            'personal_email' => $personalEmail,
416
            'status_id' => $statusId,
417
            'start_date' => $now,
418
            'sys_insert_user_id' => $currentUserId,
419
            'sys_insert_datetime' => $now,
420
            'sys_lastedit_user_id' => $currentUserId,
421
            'sys_lastedit_datetime' => $now,
422
            'source' => $source,
423
            'assigned_last_user' => $assignedUserId,
424
            'subject' => $subject,
425
            'message' => $content,
426
        ];
427
428
        if (!empty($exerciseId)) {
429
            $params['exercise_id'] = $exerciseId;
430
        }
431
432
        if (!empty($lpId)) {
433
            $params['lp_id'] = $lpId;
434
        }
435
436
        if (!empty($course_id)) {
437
            $params['course_id'] = $course_id;
438
        }
439
440
        if (!empty($sessionId)) {
441
            $params['session_id'] = $sessionId;
442
        }
443
444
        $ticketId = Database::insert($table_support_tickets, $params);
445
446
        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...
447
            $ticket_code = 'A'.str_pad($ticketId, 11, '0', STR_PAD_LEFT);
448
            $titleCreated = sprintf(
449
                get_lang('TicketXCreated'),
450
                $ticket_code
451
            );
452
453
            Display::addFlash(Display::return_message(
454
                $titleCreated,
455
                'normal',
456
                false
457
            ));
458
459
            if ($assignedUserId != 0) {
460
                self::assignTicketToUser(
461
                    $ticketId,
462
                    $assignedUserId
463
                );
464
465
                Display::addFlash(Display::return_message(
466
                    sprintf(
467
                        get_lang('TicketXAssignedToUserX'),
468
                        $ticket_code,
469
                        $assignedUserInfo['complete_name']
470
                    ),
471
                    'normal',
472
                    false
473
                ));
474
            }
475
476
            if (!empty($fileAttachments)) {
477
                $attachmentCount = 0;
478
                foreach ($fileAttachments as $attach) {
479
                    if (!empty($attach['tmp_name'])) {
480
                        $attachmentCount++;
481
                    }
482
                }
483
                if ($attachmentCount > 0) {
484
                    self::insertMessage(
485
                        $ticketId,
486
                        '',
487
                        '',
488
                        $fileAttachments,
489
                        $currentUserId
490
                    );
491
                }
492
            }
493
494
            // Update code
495
            $sql = "UPDATE $table_support_tickets
496
                    SET code = '$ticket_code'
497
                    WHERE id = '$ticketId'";
498
            Database::query($sql);
499
500
            // Update total
501
            $sql = "UPDATE $table_support_category
502
                    SET total_tickets = total_tickets + 1
503
                    WHERE id = $category_id";
504
            Database::query($sql);
505
506
            $helpDeskMessage =
507
                '<table>
508
                        <tr>
509
                            <td width="100px"><b>'.get_lang('User').'</b></td>
510
                            <td width="400px">'.$currentUserInfo['complete_name'].'</td>
511
                        </tr>
512
                        <tr>
513
                            <td width="100px"><b>'.get_lang('Username').'</b></td>
514
                            <td width="400px">'.$currentUserInfo['username'].'</td>
515
                        </tr>
516
                        <tr>
517
                            <td width="100px"><b>'.get_lang('Email').'</b></td>
518
                            <td width="400px">'.$currentUserInfo['email'].'</td>
519
                        </tr>
520
                        <tr>
521
                            <td width="100px"><b>'.get_lang('Phone').'</b></td>
522
                            <td width="400px">'.$currentUserInfo['phone'].'</td>
523
                        </tr>
524
                        <tr>
525
                            <td width="100px"><b>'.get_lang('Date').'</b></td>
526
                            <td width="400px">'.api_convert_and_format_date($now, DATE_TIME_FORMAT_LONG).'</td>
527
                        </tr>
528
                        <tr>
529
                            <td width="100px"><b>'.get_lang('Title').'</b></td>
530
                            <td width="400px">'.Security::remove_XSS($subject).'</td>
531
                        </tr>
532
                        <tr>
533
                            <td width="100px"><b>'.get_lang('Description').'</b></td>
534
                            <td width="400px">'.Security::remove_XSS($content).'</td>
535
                        </tr>
536
                    </table>';
537
538
            if ($assignedUserId != 0) {
539
                $href = api_get_path(WEB_CODE_PATH).'/ticket/ticket_details.php?ticket_id='.$ticketId;
540
                $helpDeskMessage .= sprintf(
541
                    get_lang('TicketAssignedToXCheckZAtLinkY'),
542
                    $assignedUserInfo['complete_name'],
543
                    $href,
544
                    $ticketId
545
                );
546
            }
547
548
            if (empty($category_id)) {
549
                if (api_get_setting('ticket_send_warning_to_all_admins') === 'true') {
550
                    $warningSubject = sprintf(
551
                        get_lang('TicketXCreatedWithNoCategory'),
552
                        $ticket_code
553
                    );
554
                    Display::addFlash(Display::return_message($warningSubject));
555
556
                    $admins = UserManager::get_all_administrators();
557
                    foreach ($admins as $userId => $data) {
558
                        if ($data['active']) {
559
                            MessageManager::send_message_simple(
560
                                $userId,
561
                                $warningSubject,
562
                                $helpDeskMessage
563
                            );
564
                        }
565
                    }
566
                }
567
            } else {
568
                $categoryInfo = self::getCategory($category_id);
569
                $usersInCategory = self::getUsersInCategory($category_id);
570
571
                $message = '<h2>'.get_lang('TicketInformation').'</h2><br />'.$helpDeskMessage;
572
573
                if (api_get_setting('ticket_warn_admin_no_user_in_category') === 'true') {
574
                    if (empty($usersInCategory)) {
575
                        $subject = sprintf(
576
                            get_lang('WarningCategoryXDoesntHaveUsers'),
577
                            $categoryInfo['name']
578
                        );
579
580
                        if (api_get_setting('ticket_send_warning_to_all_admins') === 'true') {
581
                            Display::addFlash(Display::return_message(
582
                                sprintf(
583
                                    get_lang('CategoryWithNoUserNotificationSentToAdmins'),
584
                                    $categoryInfo['name']
585
                                ),
586
                                null,
587
                                false
588
                            ));
589
590
                            $admins = UserManager::get_all_administrators();
591
                            foreach ($admins as $userId => $data) {
592
                                if ($data['active']) {
593
                                    self::sendNotification(
594
                                        $ticketId,
595
                                        $subject,
596
                                        $message,
597
                                        $userId
598
                                    );
599
                                }
600
                            }
601
                        } else {
602
                            Display::addFlash(Display::return_message($subject));
603
                        }
604
                    }
605
                }
606
607
                // Send notification to all users
608
                if (!empty($usersInCategory)) {
609
                    foreach ($usersInCategory as $data) {
610
                        if ($data['user_id']) {
611
                            self::sendNotification(
612
                                $ticketId,
613
                                $subject,
614
                                $message,
615
                                $data['user_id']
616
                            );
617
                        }
618
                    }
619
                }
620
            }
621
622
            if (!empty($personalEmail)) {
623
                api_mail_html(
624
                    get_lang('VirtualSupport'),
625
                    $personalEmail,
626
                    get_lang('IncidentResentToVirtualSupport'),
627
                    $helpDeskMessage
628
                );
629
            }
630
631
            self::sendNotification(
632
                $ticketId,
633
                $titleCreated,
634
                $helpDeskMessage
635
            );
636
637
            return true;
638
        }
639
640
        return false;
641
    }
642
643
    /**
644
     * Assign ticket to admin.
645
     *
646
     * @param int $ticketId
647
     * @param int $userId
648
     *
649
     * @return bool
650
     */
651
    public static function assignTicketToUser(
652
        $ticketId,
653
        $userId
654
    ) {
655
        $ticketId = (int) $ticketId;
656
        $userId = (int) $userId;
657
658
        if (empty($ticketId)) {
659
            return false;
660
        }
661
662
        $ticket = self::get_ticket_detail_by_id($ticketId);
663
664
        if ($ticket) {
665
            $table = Database::get_main_table(TABLE_TICKET_TICKET);
666
            $sql = "UPDATE $table
667
                    SET assigned_last_user = $userId
668
                    WHERE id = $ticketId";
669
            Database::query($sql);
670
671
            $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
672
            $params = [
673
                'ticket_id' => $ticketId,
674
                'user_id' => $userId,
675
                'sys_insert_user_id' => api_get_user_id(),
676
                'assigned_date' => api_get_utc_datetime(),
677
            ];
678
            Database::insert($table, $params);
679
680
            return true;
681
        } else {
682
            return false;
683
        }
684
    }
685
686
    /**
687
     * Insert message between Users and Admins.
688
     *
689
     * @param int    $ticketId
690
     * @param string $subject
691
     * @param string $content
692
     * @param array  $fileAttachments
693
     * @param int    $userId
694
     * @param string $status
695
     * @param bool   $sendConfirmation
696
     *
697
     * @return bool
698
     */
699
    public static function insertMessage(
700
        $ticketId,
701
        $subject,
702
        $content,
703
        $fileAttachments,
704
        $userId,
705
        $status = 'NOL',
706
        $sendConfirmation = false
707
    ) {
708
        $ticketId = (int) $ticketId;
709
        $userId = (int) $userId;
710
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
711
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
712
        if ($sendConfirmation) {
713
            $form =
714
                '<form action="ticket_details.php?ticket_id='.$ticketId.'" id="confirmticket" method="POST" >
715
                     <p>'.get_lang('TicketWasThisAnswerSatisfying').'</p>
716
                     <button class="btn btn-primary responseyes" name="response" id="responseyes" value="1">'.
717
                get_lang('Yes').'</button>
718
                     <button class="btn btn-danger responseno" name="response" id="responseno" value="0">'.
719
                get_lang('No').'</button>
720
                 </form>';
721
            $content .= $form;
722
        }
723
724
        $now = api_get_utc_datetime();
725
726
        $params = [
727
            'ticket_id' => $ticketId,
728
            'subject' => $subject,
729
            'message' => $content,
730
            'ip_address' => api_get_real_ip(),
731
            'sys_insert_user_id' => $userId,
732
            'sys_insert_datetime' => $now,
733
            'sys_lastedit_user_id' => $userId,
734
            'sys_lastedit_datetime' => $now,
735
            'status' => $status,
736
        ];
737
        $messageId = Database::insert($table_support_messages, $params);
738
        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...
739
            // update_total_message
740
            $sql = "UPDATE $table_support_tickets
741
                    SET
742
                        sys_lastedit_user_id = $userId,
743
                        sys_lastedit_datetime = '$now',
744
                        total_messages = (
745
                            SELECT COUNT(*) as total_messages
746
                            FROM $table_support_messages
747
                            WHERE ticket_id = $ticketId
748
                        )
749
                    WHERE id = $ticketId ";
750
            Database::query($sql);
751
752
            if (is_array($fileAttachments)) {
753
                foreach ($fileAttachments as $file_attach) {
754
                    if ($file_attach['error'] == 0) {
755
                        self::saveMessageAttachmentFile(
756
                            $file_attach,
757
                            $ticketId,
758
                            $messageId
759
                        );
760
                    } else {
761
                        if ($file_attach['error'] != UPLOAD_ERR_NO_FILE) {
762
                            return false;
763
                        }
764
                    }
765
                }
766
            }
767
        }
768
769
        return true;
770
    }
771
772
    /**
773
     * Attachment files when a message is sent.
774
     *
775
     * @param $file_attach
776
     * @param $ticketId
777
     * @param $message_id
778
     *
779
     * @return bool
780
     */
781
    public static function saveMessageAttachmentFile(
782
        $file_attach,
783
        $ticketId,
784
        $message_id
785
    ) {
786
        $now = api_get_utc_datetime();
787
        $userId = api_get_user_id();
788
        $ticketId = (int) $ticketId;
789
790
        $new_file_name = add_ext_on_mime(
791
            stripslashes($file_attach['name']),
792
            $file_attach['type']
793
        );
794
        $table_support_message_attachments = Database::get_main_table(TABLE_TICKET_MESSAGE_ATTACHMENTS);
795
        if (!filter_extension($new_file_name)) {
796
            echo Display::return_message(
797
                get_lang('UplUnableToSaveFileFilteredExtension'),
798
                'error'
799
            );
800
        } else {
801
            $result = api_upload_file('ticket_attachment', $file_attach, $ticketId);
802
            if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array<string,string> 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...
introduced by
$result is a non-empty array, thus is always true.
Loading history...
803
                $safe_file_name = Database::escape_string($new_file_name);
804
                $safe_new_file_name = Database::escape_string($result['path_to_save']);
805
                $sql = "INSERT INTO $table_support_message_attachments (
806
                        filename,
807
                        path,
808
                        ticket_id,
809
                        message_id,
810
                        size,
811
                        sys_insert_user_id,
812
                        sys_insert_datetime,
813
                        sys_lastedit_user_id,
814
                        sys_lastedit_datetime
815
                    ) VALUES (
816
                        '$safe_file_name',
817
                        '$safe_new_file_name',
818
                        '$ticketId',
819
                        '$message_id',
820
                        '".$file_attach['size']."',
821
                        '$userId',
822
                        '$now',
823
                        '$userId',
824
                        '$now'
825
                    )";
826
                Database::query($sql);
827
828
                return true;
829
            }
830
        }
831
    }
832
833
    public static function deleteTicket($ticketId)
834
    {
835
        $ticketId = (int) $ticketId;
836
        if ($ticketId <= 0) {
837
            return false;
838
        }
839
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
840
        $table_ticket_message = Database::get_main_table('ticket_message');
841
        $table_ticket_assigned_log = Database::get_main_table('ticket_assigned_log');
842
        $table_ticket_message_attachments = Database::get_main_table('ticket_message_attachments');
843
844
        $sql_get_message_ids = "SELECT id FROM $table_ticket_message WHERE ticket_id = $ticketId";
845
        $sql_delete_attachments = "DELETE FROM $table_ticket_message_attachments WHERE message_id IN ($sql_get_message_ids)";
846
        Database::query($sql_delete_attachments);
847
        
848
        $sql_assigned_log = "DELETE FROM $table_ticket_assigned_log WHERE ticket_id = $ticketId";
849
        Database::query($sql_assigned_log);
850
851
        $sql_messages = "DELETE FROM $table_ticket_message WHERE ticket_id = $ticketId";
852
        Database::query($sql_messages);
853
854
        $sql_get_category = "SELECT category_id FROM $table_support_tickets WHERE id = $ticketId";
855
        $res = Database::query($sql_get_category);
856
        if ($row = Database::fetch_array($res)) {
857
            $category_id = (int)$row['category_id'];
858
            $table_ticket_category = Database::get_main_table('ticket_category');
859
            $sql_update_category = "UPDATE $table_ticket_category SET total_tickets = total_tickets - 1 WHERE id = $category_id AND total_tickets > 0";
860
            Database::query($sql_update_category);
861
        }
862
863
        $sql_ticket = "DELETE FROM $table_support_tickets WHERE id = $ticketId";
864
        Database::query($sql_ticket);
865
866
        return true;
867
    }
868
869
    /**
870
     * Get tickets by userId.
871
     *
872
     * @param int $from
873
     * @param int $number_of_items
874
     * @param $column
875
     * @param $direction
876
     *
877
     * @return array
878
     */
879
    public static function getTicketsByCurrentUser(
880
        $from,
881
        $number_of_items,
882
        $column,
883
        $direction
884
    ) {
885
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
886
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
887
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
888
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
889
        $direction = !empty($direction) ? $direction : 'DESC';
890
        $userId = api_get_user_id();
891
        $userInfo = api_get_user_info($userId);
892
893
        if (empty($userInfo)) {
894
            return [];
895
        }
896
        $isAdmin = UserManager::is_admin($userId) || (api_get_configuration_value('allow_session_admin_manage_tickets_and_export_ticket_report') && api_is_session_admin($userId));
897
898
        if (!isset($_GET['project_id'])) {
899
            return [];
900
        }
901
902
        switch ($column) {
903
            case 0:
904
                $column = 'ticket_id';
905
                break;
906
            case 1:
907
                $column = 'status_name';
908
                break;
909
            case 2:
910
                $column = 'start_date';
911
                break;
912
            case 3:
913
                $column = 'sys_lastedit_datetime';
914
                break;
915
            case 4:
916
                $column = 'category_name';
917
                break;
918
            case 5:
919
                $column = 'sys_insert_user_id';
920
                break;
921
            case 6:
922
                $column = 'assigned_last_user';
923
                break;
924
            case 7:
925
                $column = 'total_messages';
926
                break;
927
            case 8:
928
                $column = 'subject';
929
                break;
930
            default:
931
                $column = 'ticket_id';
932
        }
933
934
        $sql = "SELECT DISTINCT
935
                ticket.*,
936
                ticket.id ticket_id,
937
                status.name AS status_name,
938
                ticket.start_date,
939
                ticket.sys_lastedit_datetime,
940
                cat.name AS category_name,
941
                priority.name AS priority_name,
942
                ticket.total_messages AS total_messages,
943
                ticket.message AS message,
944
                ticket.subject AS subject,
945
                ticket.assigned_last_user
946
            FROM $table_support_tickets ticket
947
            INNER JOIN $table_support_category cat
948
            ON (cat.id = ticket.category_id)
949
            INNER JOIN $table_support_priority priority
950
            ON (ticket.priority_id = priority.id)
951
            INNER JOIN $table_support_status status
952
            ON (ticket.status_id = status.id)
953
            WHERE 1=1
954
        ";
955
956
        $projectId = (int) $_GET['project_id'];
957
        $userIsAllowInProject = self::userIsAllowInProject($userInfo, $projectId);
958
959
        // Check if a role was set to the project
960
        if ($userIsAllowInProject == false) {
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...
961
                        $categoryList = self::getCategoryIdsByUser($userId, $projectId);
962
            $categoryCondition = '';
963
            if (!empty($categoryList)) {
964
                $categoryIds = implode(',', array_map('intval', $categoryList));
965
                $categoryCondition = " OR ticket.category_id IN ($categoryIds)";
966
            }
967
968
            $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId".$categoryCondition.")";
969
        }
970
971
972
        // Search simple
973
        if (isset($_GET['submit_simple']) && $_GET['keyword'] != '') {
974
            $keyword = Database::escape_string(trim($_GET['keyword']));
975
            $sql .= " AND (
976
                      ticket.id LIKE '%$keyword%' OR
977
                      ticket.code LIKE '%$keyword%' OR
978
                      ticket.subject LIKE '%$keyword%' OR
979
                      ticket.message LIKE '%$keyword%' OR
980
                      ticket.keyword LIKE '%$keyword%' OR
981
                      ticket.source LIKE '%$keyword%' OR
982
                      cat.name LIKE '%$keyword%' OR
983
                      status.name LIKE '%$keyword%' OR
984
                      priority.name LIKE '%$keyword%' OR
985
                      ticket.personal_email LIKE '%$keyword%'
986
            )";
987
        }
988
989
        $keywords = [
990
            'project_id' => 'ticket.project_id',
991
            'keyword_category' => 'ticket.category_id',
992
            'keyword_assigned_to' => 'ticket.assigned_last_user',
993
            'keyword_source' => 'ticket.source ',
994
            'keyword_status' => 'ticket.status_id',
995
            'keyword_priority' => 'ticket.priority_id',
996
            'keyword_created_by' => 'ticket.sys_insert_user_id',
997
        ];
998
999
        foreach ($keywords as $keyword => $label) {
1000
            if (isset($_GET[$keyword])) {
1001
                $data = Database::escape_string(trim($_GET[$keyword]));
1002
                if (!empty($data)) {
1003
                    $sql .= " AND $label = '$data' ";
1004
                }
1005
            }
1006
        }
1007
1008
        // Search advanced
1009
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
1010
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
1011
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
1012
        $keyword_range = !empty($keyword_start_date_start) && !empty($keyword_start_date_end);
1013
1014
        if ($keyword_range == false && $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...
1015
            $sql .= " AND ticket.start_date >= '$keyword_start_date_start' ";
1016
        }
1017
        if ($keyword_range && $keyword_start_date_start != '' && $keyword_start_date_end != '') {
1018
            $sql .= " AND ticket.start_date >= '$keyword_start_date_start'
1019
                      AND ticket.start_date <= '$keyword_start_date_end'";
1020
        }
1021
1022
        if ($keyword_course != '') {
1023
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1024
            $sql .= " AND ticket.course_id IN (
1025
                     SELECT id FROM $course_table
1026
                     WHERE (
1027
                        title LIKE '%$keyword_course%' OR
1028
                        code LIKE '%$keyword_course%' OR
1029
                        visual_code LIKE '%$keyword_course%'
1030
                     )
1031
            )";
1032
        }
1033
        $sql .= " ORDER BY `$column` $direction";
1034
        $sql .= " LIMIT $from, $number_of_items";
1035
1036
        $result = Database::query($sql);
1037
        $tickets = [];
1038
        $webPath = api_get_path(WEB_PATH);
1039
        while ($row = Database::fetch_assoc($result)) {
1040
            $userInfo = api_get_user_info($row['sys_insert_user_id']);
1041
            $hrefUser = $webPath.'main/admin/user_information.php?user_id='.$userInfo['user_id'];
1042
            $name = "<a href='$hrefUser'> {$userInfo['complete_name_with_username']} </a>";
1043
            if ($row['assigned_last_user'] != 0) {
1044
                $assignedUserInfo = api_get_user_info($row['assigned_last_user']);
1045
                if (!empty($assignedUserInfo)) {
1046
                    $hrefResp = $webPath.'main/admin/user_information.php?user_id='.$assignedUserInfo['user_id'];
1047
                    $row['assigned_last_user'] = "<a href='$hrefResp'> {$assignedUserInfo['complete_name_with_username']} </a>";
1048
                } else {
1049
                    $row['assigned_last_user'] = get_lang('UnknownUser');
1050
                }
1051
            } else {
1052
                if ($row['status_id'] !== self::STATUS_FORWARDED) {
1053
                    $row['assigned_last_user'] = '<span style="color:#ff0000;">'.get_lang('ToBeAssigned').'</span>';
1054
                } else {
1055
                    $row['assigned_last_user'] = '<span style="color:#00ff00;">'.get_lang('MessageResent').'</span>';
1056
                }
1057
            }
1058
1059
            switch ($row['source']) {
1060
                case self::SOURCE_PRESENTIAL:
1061
                    $img_source = 'icons/32/user.png';
1062
                    break;
1063
                case self::SOURCE_EMAIL:
1064
                    $img_source = 'icons/32/mail.png';
1065
                    break;
1066
                case self::SOURCE_PHONE:
1067
                    $img_source = 'icons/32/event.png';
1068
                    break;
1069
                default:
1070
                    $img_source = 'icons/32/ticket.png';
1071
                    break;
1072
            }
1073
1074
            $row['start_date'] = Display::dateToStringAgoAndLongDate($row['start_date']);
1075
            $row['sys_lastedit_datetime'] = Display::dateToStringAgoAndLongDate($row['sys_lastedit_datetime']);
1076
1077
            $icon = Display::return_icon(
1078
                $img_source,
1079
                get_lang('Info'),
1080
                ['style' => 'margin-right: 10px; float: left;']
1081
            );
1082
1083
            $icon .= '<a href="ticket_details.php?ticket_id='.$row['id'].'">'.$row['code'].'</a>';
1084
1085
            if ($isAdmin) {
1086
                $ticket = [
1087
                    $icon.' '.Security::remove_XSS($row['subject']),
1088
                    $row['status_name'],
1089
                    $row['start_date'],
1090
                    $row['sys_lastedit_datetime'],
1091
                    $row['category_name'],
1092
                    $name,
1093
                    $row['assigned_last_user'],
1094
                    $row['total_messages'],
1095
                ];
1096
            } else {
1097
                $ticket = [
1098
                    $icon.' '.Security::remove_XSS($row['subject']),
1099
                    $row['status_name'],
1100
                    $row['start_date'],
1101
                    $row['sys_lastedit_datetime'],
1102
                    $row['category_name'],
1103
                ];
1104
            }
1105
            if ($isAdmin) {
1106
                $ticket['0'] .= '&nbsp;&nbsp;<a href="javascript:void(0)" onclick="load_history_ticket(\'div_'.$row['ticket_id'].'\','.$row['ticket_id'].')">
1107
					<img onclick="load_course_list(\'div_'.$row['ticket_id'].'\','.$row['ticket_id'].')" onmouseover="clear_course_list (\'div_'.$row['ticket_id'].'\')" src="'.Display::returnIconPath('history.gif').'" title="'.get_lang('Historial').'" alt="'.get_lang('Historial').'"/>
1108
					<div class="blackboard_hide" id="div_'.$row['ticket_id'].'">&nbsp;&nbsp;</div>
1109
					</a>&nbsp;&nbsp;';
1110
            }
1111
            if ($isAdmin) {
1112
                $project_id = isset($row['project_id']) ? $row['project_id'] : (isset($_GET['project_id']) ? $_GET['project_id'] : 0);
1113
                $delete_link = '<a href="tickets.php?action=delete&ticket_id='.$row['ticket_id'].'&project_id='.$project_id.'" onclick="return confirm(\''.htmlentities(get_lang('AreYouSureYouWantToDeleteThisTicket')).'\')">'
1114
                . Display::return_icon('delete.png', get_lang('Delete')) .
1115
                '</a>';
1116
                $ticket[] = $delete_link;
1117
            }
1118
1119
            $tickets[] = $ticket;
1120
        }
1121
1122
        return $tickets;
1123
    }
1124
1125
    /**
1126
     * @return int
1127
     */
1128
    public static function getTotalTicketsCurrentUser()
1129
    {
1130
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1131
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1132
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1133
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1134
1135
        $userInfo = api_get_user_info();
1136
        if (empty($userInfo)) {
1137
            return 0;
1138
        }
1139
        $userId = (int) $userInfo['id'];
1140
1141
        if (!isset($_GET['project_id'])) {
1142
            return 0;
1143
        }
1144
1145
        $sql = "SELECT COUNT(DISTINCT ticket.id) AS total
1146
                FROM $table_support_tickets ticket
1147
                INNER JOIN $table_support_category cat
1148
                    ON (cat.id = ticket.category_id)
1149
                INNER JOIN $table_support_priority priority
1150
                    ON (ticket.priority_id = priority.id)
1151
                INNER JOIN $table_support_status status
1152
                    ON (ticket.status_id = status.id)
1153
                WHERE 1 = 1";
1154
1155
        $projectId = (int) $_GET['project_id'];
1156
        $userIsAllowInProject = self::userIsAllowInProject($userInfo, $projectId);
1157
1158
        // Apply same permission constraints as getTicketsByCurrentUser
1159
        if ($userIsAllowInProject == false) {
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...
1160
            $categoryList = self::getCategoryIdsByUser($userId, $projectId);
1161
            $categoryCondition = '';
1162
            if (!empty($categoryList)) {
1163
                $categoryIds = implode(',', array_map('intval', $categoryList));
1164
                $categoryCondition = " OR ticket.category_id IN ($categoryIds)";
1165
            }
1166
            $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId".$categoryCondition.")";
1167
        }
1168
1169
        // Simple search (align with getTicketsByCurrentUser)
1170
        if (isset($_GET['submit_simple']) && $_GET['keyword'] !== '') {
1171
            $keyword = Database::escape_string(trim($_GET['keyword']));
1172
            $sql .= " AND (
1173
                ticket.id LIKE '%$keyword%' OR
1174
                ticket.code LIKE '%$keyword%' OR
1175
                ticket.subject LIKE '%$keyword%' OR
1176
                ticket.message LIKE '%$keyword%' OR
1177
                ticket.keyword LIKE '%$keyword%' OR
1178
                ticket.source LIKE '%$keyword%' OR
1179
                cat.name LIKE '%$keyword%' OR
1180
                status.name LIKE '%$keyword%' OR
1181
                priority.name LIKE '%$keyword%' OR
1182
                ticket.personal_email LIKE '%$keyword%'
1183
            )";
1184
        }
1185
1186
        // Exact-match filters
1187
        $keywords = [
1188
            'project_id' => 'ticket.project_id',
1189
            'keyword_category' => 'ticket.category_id',
1190
            'keyword_assigned_to' => 'ticket.assigned_last_user',
1191
            'keyword_source' => 'ticket.source',
1192
            'keyword_status' => 'ticket.status_id',
1193
            'keyword_priority' => 'ticket.priority_id',
1194
            'keyword_created_by' => 'ticket.sys_insert_user_id',
1195
        ];
1196
1197
        foreach ($keywords as $keyword => $sqlLabel) {
1198
            if (isset($_GET[$keyword])) {
1199
                $data = Database::escape_string(trim($_GET[$keyword]));
1200
                if ($data !== '') {
1201
                    $sql .= " AND $sqlLabel = '$data' ";
1202
                }
1203
            }
1204
        }
1205
1206
        // Advanced search: date range and course
1207
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
1208
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
1209
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
1210
        $keyword_range = !empty($keyword_start_date_start) && !empty($keyword_start_date_end);
1211
1212
        if (!$keyword_range && $keyword_start_date_start !== '') {
1213
            $sql .= " AND ticket.start_date >= '$keyword_start_date_start' ";
1214
        }
1215
        if ($keyword_range) {
1216
            $sql .= " AND ticket.start_date >= '$keyword_start_date_start' AND ticket.start_date <= '$keyword_start_date_end'";
1217
        }
1218
        if ($keyword_course !== '') {
1219
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1220
            $sql .= " AND ticket.course_id IN (
1221
                SELECT id FROM $course_table
1222
                WHERE (
1223
                    title LIKE '%$keyword_course%' OR
1224
                    code LIKE '%$keyword_course%' OR
1225
                    visual_code LIKE '%$keyword_course%'
1226
                )
1227
            )";
1228
        }
1229
1230
        $res = Database::query($sql);
1231
        $obj = Database::fetch_object($res);
1232
        return $obj ? (int) $obj->total : 0;
1233
    }
1234
1235
    /**
1236
     * @param int $id
1237
     *
1238
     * @return false|MessageAttachment
1239
     */
1240
    public static function getTicketMessageAttachment($id)
1241
    {
1242
        $id = (int) $id;
1243
        $em = Database::getManager();
1244
        $item = $em->getRepository('ChamiloTicketBundle:MessageAttachment')->find($id);
1245
        if ($item) {
1246
            return $item;
1247
        }
1248
1249
        return false;
1250
    }
1251
1252
    /**
1253
     * @param int $id
1254
     *
1255
     * @return array
1256
     */
1257
    public static function getTicketMessageAttachmentsByTicketId($id)
1258
    {
1259
        $id = (int) $id;
1260
        $em = Database::getManager();
1261
        $items = $em->getRepository('ChamiloTicketBundle:MessageAttachment')->findBy(['ticket' => $id]);
1262
        if ($items) {
1263
            return $items;
1264
        }
1265
1266
        return false;
1267
    }
1268
1269
    /**
1270
     * @param int $ticketId
1271
     *
1272
     * @return array
1273
     */
1274
    public static function get_ticket_detail_by_id($ticketId)
1275
    {
1276
        $ticketId = (int) $ticketId;
1277
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1278
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1279
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1280
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1281
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1282
        $table_support_message_attachments = Database::get_main_table(TABLE_TICKET_MESSAGE_ATTACHMENTS);
1283
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1284
1285
        $sql = "SELECT
1286
                    ticket.*,
1287
                    cat.name,
1288
                    status.name as status,
1289
                    priority.name priority
1290
                FROM $table_support_tickets ticket
1291
                INNER JOIN $table_support_category cat
1292
                ON (cat.id = ticket.category_id)
1293
                INNER JOIN $table_support_priority priority
1294
                ON (priority.id = ticket.priority_id)
1295
                INNER JOIN $table_support_status status
1296
                ON (status.id = ticket.status_id)
1297
		        WHERE
1298
                    ticket.id = $ticketId ";
1299
        $result = Database::query($sql);
1300
        $ticket = [];
1301
        if (Database::num_rows($result) > 0) {
1302
            while ($row = Database::fetch_assoc($result)) {
1303
                $row['course'] = null;
1304
                $row['start_date_from_db'] = $row['start_date'];
1305
                $row['start_date'] = api_convert_and_format_date(
1306
                    api_get_local_time($row['start_date']),
1307
                    DATE_TIME_FORMAT_LONG,
1308
                    api_get_timezone()
1309
                );
1310
                $row['end_date_from_db'] = $row['end_date'];
1311
                $row['end_date'] = api_convert_and_format_date(
1312
                    api_get_local_time($row['end_date']),
1313
                    DATE_TIME_FORMAT_LONG,
1314
                    api_get_timezone()
1315
                );
1316
                $row['sys_lastedit_datetime_from_db'] = $row['sys_lastedit_datetime'];
1317
                $row['sys_lastedit_datetime'] = api_convert_and_format_date(
1318
                    api_get_local_time($row['sys_lastedit_datetime']),
1319
                    DATE_TIME_FORMAT_LONG,
1320
                    api_get_timezone()
1321
                );
1322
                $row['course_url'] = null;
1323
                if ($row['course_id'] != 0) {
1324
                    $course = api_get_course_info_by_id($row['course_id']);
1325
                    $sessionId = 0;
1326
                    if ($row['session_id']) {
1327
                        $sessionId = $row['session_id'];
1328
                    }
1329
                    if ($course) {
1330
                        $row['course_url'] = '<a href="'.$course['course_public_url'].'?id_session='.$sessionId.'">'.$course['name'].'</a>';
1331
                    }
1332
1333
                    $row['exercise_url'] = null;
1334
1335
                    if (!empty($row['exercise_id'])) {
1336
                        $exerciseTitle = ExerciseLib::getExerciseTitleById($row['exercise_id']);
1337
                        $dataExercise = [
1338
                            'cidReq' => $course['code'],
1339
                            'id_session' => $sessionId,
1340
                            'exerciseId' => $row['exercise_id'],
1341
                        ];
1342
                        $urlParamsExercise = http_build_query($dataExercise);
1343
1344
                        $row['exercise_url'] = '<a href="'.api_get_path(WEB_CODE_PATH).'exercise/overview.php?'.$urlParamsExercise.'">'.$exerciseTitle.'</a>';
1345
                    }
1346
1347
                    $row['lp_url'] = null;
1348
1349
                    if (!empty($row['lp_id'])) {
1350
                        $lpName = learnpath::getLpNameById($row['lp_id']);
1351
                        $dataLp = [
1352
                            'cidReq' => $course['code'],
1353
                            'id_session' => $sessionId,
1354
                            'lp_id' => $row['lp_id'],
1355
                            'action' => 'view',
1356
                        ];
1357
                        $urlParamsLp = http_build_query($dataLp);
1358
1359
                        $row['lp_url'] = '<a href="'.api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.$urlParamsLp.'">'.$lpName.'</a>';
1360
                    }
1361
                }
1362
1363
                $userInfo = api_get_user_info($row['sys_insert_user_id']);
1364
                $row['user_url'] = '<a href="'.api_get_path(WEB_PATH).'main/admin/user_information.php?user_id='.$userInfo['user_id'].'">
1365
                '.$userInfo['complete_name'].'</a>';
1366
                $ticket['usuario'] = $userInfo;
1367
                $ticket['ticket'] = $row;
1368
            }
1369
1370
            $sql = "SELECT *, message.id as message_id
1371
                    FROM $table_support_messages message
1372
                    INNER JOIN $table_main_user user
1373
                    ON (message.sys_insert_user_id = user.user_id)
1374
                    WHERE
1375
                        message.ticket_id = '$ticketId' ";
1376
            $result = Database::query($sql);
1377
            $ticket['messages'] = [];
1378
            $attach_icon = Display::return_icon('attachment.gif', '');
1379
            $webPath = api_get_path(WEB_CODE_PATH);
1380
            while ($row = Database::fetch_assoc($result)) {
1381
                $message = $row;
1382
                $message['admin'] = UserManager::is_admin($message['user_id']);
1383
                $message['user_info'] = api_get_user_info($message['user_id']);
1384
                $sql = "SELECT *
1385
                        FROM $table_support_message_attachments
1386
                        WHERE
1387
                            message_id = ".$row['message_id']." AND
1388
                            ticket_id = $ticketId";
1389
1390
                $result_attach = Database::query($sql);
1391
                while ($row2 = Database::fetch_assoc($result_attach)) {
1392
                    $row2['filename'] = Security::remove_XSS($row2['filename']);
1393
                    $archiveURL = $webPath.'ticket/download.php?ticket_id='.$ticketId.'&id='.$row2['id'];
1394
                    $row2['attachment_link'] = $attach_icon.
1395
                        '&nbsp;<a href="'.$archiveURL.'">'.$row2['filename'].'</a>&nbsp;('.$row2['size'].')';
1396
                    $message['attachments'][] = $row2;
1397
                }
1398
                $ticket['messages'][] = $message;
1399
            }
1400
        }
1401
1402
        return $ticket;
1403
    }
1404
1405
    /**
1406
     * @param int $ticketId
1407
     * @param int $userId
1408
     *
1409
     * @return bool
1410
     */
1411
    public static function update_message_status($ticketId, $userId)
1412
    {
1413
        $ticketId = (int) $ticketId;
1414
        $userId = (int) $userId;
1415
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1416
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1417
        $now = api_get_utc_datetime();
1418
        $sql = "UPDATE $table_support_messages
1419
                SET
1420
                    status = 'LEI',
1421
                    sys_lastedit_user_id ='".api_get_user_id()."',
1422
                    sys_lastedit_datetime ='".$now."'
1423
                WHERE ticket_id ='$ticketId' ";
1424
1425
        if (api_is_platform_admin()) {
1426
            $sql .= " AND sys_insert_user_id = '$userId'";
1427
        } else {
1428
            $sql .= " AND sys_insert_user_id != '$userId'";
1429
        }
1430
        $result = Database::query($sql);
1431
        if (Database::affected_rows($result) > 0) {
1432
            Database::query(
1433
                "UPDATE $table_support_tickets SET
1434
                    status_id = '".self::STATUS_PENDING."'
1435
                 WHERE id ='$ticketId' AND status_id = '".self::STATUS_NEW."'"
1436
            );
1437
1438
            return true;
1439
        }
1440
1441
        return false;
1442
    }
1443
1444
    /**
1445
     * Send notification to a user through the internal messaging system.
1446
     *
1447
     * @param int    $ticketId
1448
     * @param string $title
1449
     * @param string $message
1450
     * @param int    $onlyToUserId
1451
     *
1452
     * @return bool
1453
     */
1454
    public static function sendNotification($ticketId, $title, $message, $onlyToUserId = 0)
1455
    {
1456
        $ticketInfo = self::get_ticket_detail_by_id($ticketId);
1457
1458
        if (empty($ticketInfo)) {
1459
            return false;
1460
        }
1461
1462
        $assignedUserInfo = api_get_user_info($ticketInfo['ticket']['assigned_last_user']);
1463
        $requestUserInfo = $ticketInfo['usuario'];
1464
        $ticketCode = $ticketInfo['ticket']['code'];
1465
        $status = $ticketInfo['ticket']['status'];
1466
        $priority = $ticketInfo['ticket']['priority'];
1467
1468
        // Subject
1469
        $titleEmail = "[$ticketCode] $title";
1470
1471
        // Content
1472
        $href = api_get_path(WEB_CODE_PATH).'ticket/ticket_details.php?ticket_id='.$ticketId;
1473
        $ticketUrl = Display::url($ticketCode, $href);
1474
        $messageEmail = get_lang('TicketNum').": $ticketUrl <br />";
1475
        $messageEmail .= get_lang('Status').": $status <br />";
1476
        $messageEmail .= get_lang('Priority').": $priority <br />";
1477
        $messageEmail .= '<hr /><br />';
1478
        $messageEmail .= $message;
1479
        $currentUserId = api_get_user_id();
1480
        $attachmentList = [];
1481
        $attachments = self::getTicketMessageAttachmentsByTicketId($ticketId);
1482
        if (!empty($attachments)) {
1483
            /** @var MessageAttachment $attachment */
1484
            foreach ($attachments as $attachment) {
1485
                $file = api_get_uploaded_file(
1486
                    'ticket_attachment',
1487
                    $ticketId,
1488
                    $attachment->getPath()
1489
                );
1490
                if (!empty($file)) {
1491
                    $attachmentList[] = [
1492
                        'tmp_name' => api_get_uploaded_file(
1493
                            'ticket_attachment',
1494
                            $ticketId,
1495
                            $attachment->getPath()
1496
                        ),
1497
                        'size' => $attachment->getSize(),
1498
                        'name' => $attachment->getFilename(),
1499
                        'error' => 0,
1500
                    ];
1501
                }
1502
            }
1503
        }
1504
1505
        if (!empty($onlyToUserId)) {
1506
            // Send only to specific user
1507
            if ($currentUserId != $onlyToUserId) {
1508
                MessageManager::send_message_simple(
1509
                    $onlyToUserId,
1510
                    $titleEmail,
1511
                    $messageEmail,
1512
                    0,
1513
                    false,
1514
                    false,
1515
                    [],
1516
                    false,
1517
                    $attachmentList
1518
                );
1519
            }
1520
        } else {
1521
            // Send to assigned user and to author
1522
            if ($requestUserInfo && $currentUserId != $requestUserInfo['id']) {
1523
                MessageManager::send_message_simple(
1524
                    $requestUserInfo['id'],
1525
                    $titleEmail,
1526
                    $messageEmail,
1527
                    0,
1528
                    false,
1529
                    false,
1530
                    [],
1531
                    false,
1532
                    $attachmentList
1533
                );
1534
            }
1535
1536
            if ($assignedUserInfo &&
1537
                $requestUserInfo['id'] != $assignedUserInfo['id'] &&
1538
                $currentUserId != $assignedUserInfo['id']
1539
            ) {
1540
                MessageManager::send_message_simple(
1541
                    $assignedUserInfo['id'],
1542
                    $titleEmail,
1543
                    $messageEmail,
1544
                    0,
1545
                    false,
1546
                    false,
1547
                    [],
1548
                    false,
1549
                    $attachmentList
1550
                );
1551
            }
1552
        }
1553
    }
1554
1555
    /**
1556
     * @param array $params
1557
     * @param int   $ticketId
1558
     * @param int   $userId
1559
     *
1560
     * @return bool
1561
     */
1562
    public static function updateTicket(
1563
        $params,
1564
        $ticketId,
1565
        $userId
1566
    ) {
1567
        $now = api_get_utc_datetime();
1568
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1569
        $newParams = [
1570
            'priority_id' => isset($params['priority_id']) ? (int) $params['priority_id'] : '',
1571
            'status_id' => isset($params['status_id']) ? (int) $params['status_id'] : '',
1572
            'sys_lastedit_user_id' => (int) $userId,
1573
            'sys_lastedit_datetime' => $now,
1574
        ];
1575
        Database::update($table, $newParams, ['id = ? ' => $ticketId]);
1576
1577
        return true;
1578
    }
1579
1580
    /**
1581
     * @param int $status_id
1582
     * @param int $ticketId
1583
     * @param int $userId
1584
     *
1585
     * @return bool
1586
     */
1587
    public static function update_ticket_status(
1588
        $status_id,
1589
        $ticketId,
1590
        $userId
1591
    ) {
1592
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1593
1594
        $ticketId = (int) $ticketId;
1595
        $status_id = (int) $status_id;
1596
        $userId = (int) $userId;
1597
        $now = api_get_utc_datetime();
1598
1599
        $sql = "UPDATE $table_support_tickets
1600
                SET
1601
                    status_id = '$status_id',
1602
                    sys_lastedit_user_id ='$userId',
1603
                    sys_lastedit_datetime ='".$now."'
1604
                WHERE id ='$ticketId'";
1605
        $result = Database::query($sql);
1606
1607
        if (Database::affected_rows($result) > 0) {
1608
            self::sendNotification(
1609
                $ticketId,
1610
                get_lang('TicketUpdated'),
1611
                get_lang('TicketUpdated')
1612
            );
1613
1614
            return true;
1615
        }
1616
1617
        return false;
1618
    }
1619
1620
    /**
1621
     * @return mixed
1622
     */
1623
    public static function getNumberOfMessages()
1624
    {
1625
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1626
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1627
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1628
        $table_main_admin = Database::get_main_table(TABLE_MAIN_ADMIN);
1629
        $user_info = api_get_user_info();
1630
        $userId = $user_info['user_id'];
1631
        $sql = "SELECT COUNT(DISTINCT ticket.id) AS unread
1632
                FROM $table_support_tickets ticket,
1633
                $table_support_messages message ,
1634
                $table_main_user user
1635
                WHERE
1636
                    ticket.id = message.ticket_id AND
1637
                    message.status = 'NOL' AND
1638
                    user.user_id = message.sys_insert_user_id ";
1639
        if (!api_is_platform_admin()) {
1640
            $sql .= " AND ticket.request_user = '$userId'
1641
                      AND user_id IN (SELECT user_id FROM $table_main_admin)  ";
1642
        } else {
1643
            $sql .= " AND user_id NOT IN (SELECT user_id FROM $table_main_admin)
1644
                      AND ticket.status_id != '".self::STATUS_FORWARDED."'";
1645
        }
1646
        $sql .= "  AND ticket.project_id != '' ";
1647
        $res = Database::query($sql);
1648
        $obj = Database::fetch_object($res);
1649
1650
        return $obj->unread;
1651
    }
1652
1653
    /**
1654
     * @param int $ticketId
1655
     * @param int $userId
1656
     */
1657
    public static function send_alert($ticketId, $userId)
1658
    {
1659
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1660
        $now = api_get_utc_datetime();
1661
1662
        $ticketId = (int) $ticketId;
1663
        $userId = (int) $userId;
1664
1665
        $sql = "UPDATE $table_support_tickets SET
1666
                  priority_id = '".self::PRIORITY_HIGH."',
1667
                  sys_lastedit_user_id = $userId,
1668
                  sys_lastedit_datetime = '$now'
1669
                WHERE id = $ticketId";
1670
        Database::query($sql);
1671
    }
1672
1673
    /**
1674
     * @param int $ticketId
1675
     * @param int $userId
1676
     */
1677
    public static function close_ticket($ticketId, $userId)
1678
    {
1679
        $ticketId = (int) $ticketId;
1680
        $userId = (int) $userId;
1681
1682
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1683
        $now = api_get_utc_datetime();
1684
        $sql = "UPDATE $table_support_tickets SET
1685
                    status_id = '".self::STATUS_CLOSE."',
1686
                    sys_lastedit_user_id ='$userId',
1687
                    sys_lastedit_datetime ='".$now."',
1688
                    end_date ='$now'
1689
                WHERE id ='$ticketId'";
1690
        Database::query($sql);
1691
1692
        self::sendNotification(
1693
            $ticketId,
1694
            get_lang('TicketClosed'),
1695
            get_lang('TicketClosed')
1696
        );
1697
    }
1698
1699
    /**
1700
     * Close old tickets.
1701
     */
1702
    public static function close_old_tickets()
1703
    {
1704
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1705
        $now = api_get_utc_datetime();
1706
        $userId = api_get_user_id();
1707
        $sql = "UPDATE $table
1708
                SET
1709
                    status_id = '".self::STATUS_CLOSE."',
1710
                    sys_lastedit_user_id ='$userId',
1711
                    sys_lastedit_datetime ='$now',
1712
                    end_date = '$now'
1713
                WHERE
1714
                    DATEDIFF('$now', sys_lastedit_datetime) > 7 AND
1715
                    status_id != '".self::STATUS_CLOSE."' AND
1716
                    status_id != '".self::STATUS_NEW."' AND
1717
                    status_id != '".self::STATUS_FORWARDED."'";
1718
        Database::query($sql);
1719
    }
1720
1721
    /**
1722
     * @param int $ticketId
1723
     *
1724
     * @return array
1725
     */
1726
    public static function get_assign_log($ticketId)
1727
    {
1728
        $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
1729
        $ticketId = (int) $ticketId;
1730
1731
        $sql = "SELECT * FROM $table
1732
                WHERE ticket_id = $ticketId
1733
                ORDER BY assigned_date DESC";
1734
        $result = Database::query($sql);
1735
        $history = [];
1736
        $webpath = api_get_path(WEB_PATH);
1737
        while ($row = Database::fetch_assoc($result)) {
1738
            if ($row['user_id'] != 0) {
1739
                $assignuser = api_get_user_info($row['user_id']);
1740
                $row['assignuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['user_id'].'"  target="_blank">'.
1741
                $assignuser['username'].'</a>';
1742
            } else {
1743
                $row['assignuser'] = get_lang('Unassign');
1744
            }
1745
            $row['assigned_date'] = Display::dateToStringAgoAndLongDate($row['assigned_date']);
1746
            $insertuser = api_get_user_info($row['sys_insert_user_id']);
1747
            $row['insertuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['sys_insert_user_id'].'"  target="_blank">'.
1748
                $insertuser['username'].'</a>';
1749
            $history[] = $row;
1750
        }
1751
1752
        return $history;
1753
    }
1754
1755
    /**
1756
     * @param $from
1757
     * @param $number_of_items
1758
     * @param $column
1759
     * @param $direction
1760
     * @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...
1761
     *
1762
     * @return array
1763
     */
1764
    public static function export_tickets_by_user_id(
1765
        $from,
1766
        $number_of_items,
1767
        $column,
1768
        $direction,
1769
        $userId = null
1770
    ) {
1771
        $from = (int) $from;
1772
        $number_of_items = (int) $number_of_items;
1773
        $table_support_category = Database::get_main_table(
1774
            TABLE_TICKET_CATEGORY
1775
        );
1776
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1777
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1778
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1779
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1780
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1781
1782
        if (is_null($direction)) {
1783
            $direction = 'DESC';
1784
        }
1785
        if (is_null($userId) || $userId == 0) {
1786
            $userId = api_get_user_id();
1787
        }
1788
1789
        $sql = "SELECT
1790
                    ticket.code,
1791
                    ticket.sys_insert_datetime,
1792
                    ticket.sys_lastedit_datetime,
1793
                    cat.name as category,
1794
                    CONCAT(user.lastname,' ', user.firstname) AS fullname,
1795
                    status.name as status,
1796
                    ticket.total_messages as messages,
1797
                    ticket.assigned_last_user as responsable
1798
                FROM $table_support_tickets ticket,
1799
                $table_support_category cat ,
1800
                $table_support_priority priority,
1801
                $table_support_status status ,
1802
                $table_main_user user
1803
                WHERE
1804
                    cat.id = ticket.category_id
1805
                    AND ticket.priority_id = priority.id
1806
                    AND ticket.status_id = status.id
1807
                    AND user.user_id = ticket.request_user ";
1808
        // Search simple
1809
        if (isset($_GET['submit_simple'])) {
1810
            if ($_GET['keyword'] !== '') {
1811
                $keyword = Database::escape_string(trim($_GET['keyword']));
1812
                $sql .= " AND (ticket.code = '$keyword'
1813
                          OR user.firstname LIKE '%$keyword%'
1814
                          OR user.lastname LIKE '%$keyword%'
1815
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword%'
1816
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword%'
1817
                          OR user.username LIKE '%$keyword%')  ";
1818
            }
1819
        }
1820
        // Search advanced
1821
        if (isset($_GET['submit_advanced'])) {
1822
            $keyword_category = Database::escape_string(
1823
                trim($_GET['keyword_category'])
1824
            );
1825
            $keyword_request_user = Database::escape_string(
1826
                trim($_GET['keyword_request_user'])
1827
            );
1828
            $keywordAssignedTo = (int) $_GET['keyword_assigned_to'];
1829
            $keyword_start_date_start = Database::escape_string(
1830
                trim($_GET['keyword_start_date_start'])
1831
            );
1832
            $keyword_start_date_end = Database::escape_string(
1833
                trim($_GET['keyword_start_date_end'])
1834
            );
1835
            $keyword_status = Database::escape_string(
1836
                trim($_GET['keyword_status'])
1837
            );
1838
            $keyword_source = Database::escape_string(
1839
                trim($_GET['keyword_source'])
1840
            );
1841
            $keyword_priority = Database::escape_string(
1842
                trim($_GET['keyword_priority'])
1843
            );
1844
            $keyword_range = Database::escape_string(
1845
                trim($_GET['keyword_dates'])
1846
            );
1847
            $keyword_unread = Database::escape_string(
1848
                trim($_GET['keyword_unread'])
1849
            );
1850
            $keyword_course = Database::escape_string(
1851
                trim($_GET['keyword_course'])
1852
            );
1853
1854
            if ($keyword_category != '') {
1855
                $sql .= " AND ticket.category_id = '$keyword_category'  ";
1856
            }
1857
            if ($keyword_request_user != '') {
1858
                $sql .= " AND (ticket.request_user = '$keyword_request_user'
1859
                          OR user.firstname LIKE '%$keyword_request_user%'
1860
                          OR user.official_code LIKE '%$keyword_request_user%'
1861
                          OR user.lastname LIKE '%$keyword_request_user%'
1862
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword_request_user%'
1863
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword_request_user%'
1864
                          OR user.username LIKE '%$keyword_request_user%') ";
1865
            }
1866
            if (!empty($keywordAssignedTo)) {
1867
                $sql .= " AND ticket.assigned_last_user = $keywordAssignedTo ";
1868
            }
1869
            if ($keyword_status != '') {
1870
                $sql .= " AND ticket.status_id = '$keyword_status'  ";
1871
            }
1872
            if ($keyword_range == '' && $keyword_start_date_start != '') {
1873
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1874
            }
1875
            if ($keyword_range == '1' && $keyword_start_date_start != '' && $keyword_start_date_end != '') {
1876
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1877
                          AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1878
            }
1879
            if ($keyword_priority != '') {
1880
                $sql .= " AND ticket.priority_id = '$keyword_priority'  ";
1881
            }
1882
            if ($keyword_source != '') {
1883
                $sql .= " AND ticket.source = '$keyword_source' ";
1884
            }
1885
            if ($keyword_priority != '') {
1886
                $sql .= " AND ticket.priority_id = '$keyword_priority' ";
1887
            }
1888
            if ($keyword_course != '') {
1889
                $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1890
                $sql .= " AND ticket.course_id IN ( ";
1891
                $sql .= "SELECT id
1892
                         FROM $course_table
1893
                         WHERE (title LIKE '%$keyword_course%'
1894
                         OR code LIKE '%$keyword_course%'
1895
                         OR visual_code LIKE '%$keyword_course%' )) ";
1896
            }
1897
            if ($keyword_unread == 'yes') {
1898
                $sql .= " AND ticket.id IN (
1899
                          SELECT ticket.id
1900
                          FROM $table_support_tickets ticket,
1901
                          $table_support_messages message,
1902
                          $table_main_user user
1903
                          WHERE ticket.id = message.ticket_id
1904
                          AND message.status = 'NOL'
1905
                          AND message.sys_insert_user_id = user.user_id
1906
                          AND user.status != 1   AND ticket.status_id != '".self::STATUS_FORWARDED."'
1907
                          GROUP BY ticket.id)";
1908
            } else {
1909
                if ($keyword_unread == 'no') {
1910
                    $sql .= " AND ticket.id NOT IN (
1911
                              SELECT ticket.id
1912
                              FROM  $table_support_tickets ticket,
1913
                              $table_support_messages message,
1914
                              $table_main_user user
1915
                              WHERE ticket.id = message.ticket_id
1916
                              AND message.status = 'NOL'
1917
                              AND message.sys_insert_user_id = user.user_id
1918
                              AND user.status != 1
1919
                              AND ticket.status_id != '".self::STATUS_FORWARDED."'
1920
                             GROUP BY ticket.id)";
1921
                }
1922
            }
1923
        }
1924
1925
        $sql .= " LIMIT $from,$number_of_items";
1926
1927
        $result = Database::query($sql);
1928
        $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...
1929
            utf8_decode('Ticket#'),
1930
            utf8_decode('Fecha'),
1931
            utf8_decode('Fecha Edicion'),
1932
            utf8_decode('Categoria'),
1933
            utf8_decode('Usuario'),
1934
            utf8_decode('Estado'),
1935
            utf8_decode('Mensajes'),
1936
            utf8_decode('Responsable'),
1937
            utf8_decode('Programa'),
1938
        ];
1939
1940
        while ($row = Database::fetch_assoc($result)) {
1941
            if ($row['responsable'] != 0) {
1942
                $row['responsable'] = api_get_user_info($row['responsable']);
1943
                $row['responsable'] = $row['responsable']['firstname'].' '.$row['responsable']['lastname'];
1944
            }
1945
            $row['sys_insert_datetime'] = api_format_date(
1946
                $row['sys_insert_datetime'],
1947
                '%d/%m/%y - %I:%M:%S %p'
1948
            );
1949
            $row['sys_lastedit_datetime'] = api_format_date(
1950
                $row['sys_lastedit_datetime'],
1951
                '%d/%m/%y - %I:%M:%S %p'
1952
            );
1953
            $row['category'] = utf8_decode($row['category']);
1954
            $row['programa'] = utf8_decode($row['fullname']);
1955
            $row['fullname'] = utf8_decode($row['fullname']);
1956
            $row['responsable'] = utf8_decode($row['responsable']);
1957
            $tickets[] = $row;
1958
        }
1959
1960
        return $tickets;
1961
    }
1962
1963
    /**
1964
     * @param string $url
1965
     * @param int    $projectId
1966
     *
1967
     * @return FormValidator
1968
     */
1969
    public static function getCategoryForm($url, $projectId)
1970
    {
1971
        $form = new FormValidator('category', 'post', $url);
1972
        $form->addText('name', get_lang('Name'));
1973
        $form->addHtmlEditor('description', get_lang('Description'));
1974
        $form->addHidden('project_id', $projectId);
1975
        $form->addButtonUpdate(get_lang('Save'));
1976
1977
        return $form;
1978
    }
1979
1980
    /**
1981
     * @return array
1982
     */
1983
    public static function getStatusList()
1984
    {
1985
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->findAll();
1986
1987
        $list = [];
1988
        /** @var Status $row */
1989
        foreach ($items as $row) {
1990
            $list[$row->getId()] = $row->getName();
1991
        }
1992
1993
        return $list;
1994
    }
1995
1996
    /**
1997
     * @param array $criteria
1998
     *
1999
     * @return array
2000
     */
2001
    public static function getTicketsFromCriteria($criteria)
2002
    {
2003
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Ticket')->findBy($criteria);
2004
2005
        $list = [];
2006
        /** @var Ticket $row */
2007
        foreach ($items as $row) {
2008
            $list[$row->getId()] = $row->getCode();
2009
        }
2010
2011
        return $list;
2012
    }
2013
2014
    /**
2015
     * @param string $code
2016
     *
2017
     * @return int
2018
     */
2019
    public static function getStatusIdFromCode($code)
2020
    {
2021
        $item = Database::getManager()
2022
            ->getRepository('ChamiloTicketBundle:Status')
2023
            ->findOneBy(['code' => $code])
2024
        ;
2025
2026
        if ($item) {
2027
            return $item->getId();
2028
        }
2029
2030
        return 0;
2031
    }
2032
2033
    /**
2034
     * Returns the numeric priority ID from its code (e.g. 'NRM', 'HGH').
2035
     *
2036
     * @param string $code
2037
     *
2038
     * @return int
2039
     */
2040
    public static function getPriorityIdFromCode($code)
2041
    {
2042
        $item = Database::getManager()
2043
            ->getRepository('ChamiloTicketBundle:Priority')
2044
            ->findOneBy(['code' => $code])
2045
        ;
2046
2047
        if ($item) {
2048
            return $item->getId();
2049
        }
2050
2051
        return 0;
2052
    }
2053
2054
    /**
2055
     * @return array
2056
     */
2057
    public static function getPriorityList()
2058
    {
2059
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->findAll();
2060
2061
        $list = [];
2062
        /** @var Priority $row */
2063
        foreach ($projects as $row) {
2064
            $list[$row->getId()] = $row->getName();
2065
        }
2066
2067
        return $list;
2068
    }
2069
2070
    /**
2071
     * @return array
2072
     */
2073
    public static function getProjects()
2074
    {
2075
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Project')->findAll();
2076
2077
        $list = [];
2078
        /** @var Project $row */
2079
        foreach ($projects as $row) {
2080
            $list[] = [
2081
                'id' => $row->getId(),
2082
                '0' => $row->getId(),
2083
                '1' => $row->getName(),
2084
                '2' => $row->getDescription(),
2085
                '3' => $row->getId(),
2086
            ];
2087
        }
2088
2089
        return $list;
2090
    }
2091
2092
    /**
2093
     * @return array
2094
     */
2095
    public static function getProjectsSimple()
2096
    {
2097
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Project')->findAll();
2098
2099
        $list = [];
2100
        /** @var Project $row */
2101
        foreach ($projects as $row) {
2102
            $list[] = [
2103
                'id' => $row->getId(),
2104
                '0' => $row->getId(),
2105
                '1' => Display::url(
2106
                    $row->getName(),
2107
                    api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id='.$row->getId()
2108
                ),
2109
                '2' => $row->getDescription(),
2110
            ];
2111
        }
2112
2113
        return $list;
2114
    }
2115
2116
    /**
2117
     * @return int
2118
     */
2119
    public static function getProjectsCount()
2120
    {
2121
        $count = Database::getManager()->getRepository('ChamiloTicketBundle:Project')->createQueryBuilder('p')
2122
            ->select('COUNT(p.id)')
2123
            ->getQuery()
2124
            ->getSingleScalarResult();
2125
2126
        return $count;
2127
    }
2128
2129
    /**
2130
     * @param array $params
2131
     */
2132
    public static function addProject($params)
2133
    {
2134
        $project = new Project();
2135
        $project->setName($params['name']);
2136
        $project->setDescription($params['description']);
2137
        $project->setInsertUserId(api_get_user_id());
2138
2139
        Database::getManager()->persist($project);
2140
        Database::getManager()->flush();
2141
    }
2142
2143
    /**
2144
     * @param int $id
2145
     *
2146
     * @return Project
2147
     */
2148
    public static function getProject($id)
2149
    {
2150
        return Database::getManager()->getRepository('ChamiloTicketBundle:Project')->find($id);
2151
    }
2152
2153
    /**
2154
     * @param int   $id
2155
     * @param array $params
2156
     */
2157
    public static function updateProject($id, $params)
2158
    {
2159
        $project = self::getProject($id);
2160
        $project->setName($params['name']);
2161
        $project->setDescription($params['description']);
2162
        $project->setLastEditDateTime(new DateTime($params['sys_lastedit_datetime']));
2163
        $project->setLastEditUserId($params['sys_lastedit_user_id']);
2164
2165
        Database::getManager()->merge($project);
2166
        Database::getManager()->flush();
2167
    }
2168
2169
    /**
2170
     * @param int $id
2171
     */
2172
    public static function deleteProject($id)
2173
    {
2174
        $project = self::getProject($id);
2175
        if ($project) {
0 ignored issues
show
introduced by
$project is of type Chamilo\TicketBundle\Entity\Project, thus it always evaluated to true.
Loading history...
2176
            Database::getManager()->remove($project);
2177
            Database::getManager()->flush();
2178
        }
2179
    }
2180
2181
    /**
2182
     * @param string $url
2183
     *
2184
     * @return FormValidator
2185
     */
2186
    public static function getProjectForm($url)
2187
    {
2188
        $form = new FormValidator('project', 'post', $url);
2189
        $form->addText('name', get_lang('Name'));
2190
        $form->addHtmlEditor('description', get_lang('Description'));
2191
        $form->addButtonUpdate(get_lang('Save'));
2192
2193
        return $form;
2194
    }
2195
2196
    /**
2197
     * @return array
2198
     */
2199
    public static function getStatusAdminList()
2200
    {
2201
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->findAll();
2202
2203
        $list = [];
2204
        /** @var Status $row */
2205
        foreach ($items as $row) {
2206
            $list[] = [
2207
                'id' => $row->getId(),
2208
                'code' => $row->getCode(),
2209
                '0' => $row->getId(),
2210
                '1' => $row->getName(),
2211
                '2' => $row->getDescription(),
2212
                '3' => $row->getId(),
2213
            ];
2214
        }
2215
2216
        return $list;
2217
    }
2218
2219
    /**
2220
     * @return array
2221
     */
2222
    public static function getStatusSimple()
2223
    {
2224
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->findAll();
2225
2226
        $list = [];
2227
        /** @var Project $row */
2228
        foreach ($projects as $row) {
2229
            $list[] = [
2230
                'id' => $row->getId(),
2231
                '0' => $row->getId(),
2232
                '1' => Display::url($row->getName()),
0 ignored issues
show
Bug introduced by
The call to Display::url() has too few arguments starting with url. ( Ignorable by Annotation )

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

2232
                '1' => Display::/** @scrutinizer ignore-call */ url($row->getName()),

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

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

Loading history...
2233
                '2' => $row->getDescription(),
2234
            ];
2235
        }
2236
2237
        return $list;
2238
    }
2239
2240
    /**
2241
     * @return int
2242
     */
2243
    public static function getStatusCount()
2244
    {
2245
        $count = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->createQueryBuilder('p')
2246
            ->select('COUNT(p.id)')
2247
            ->getQuery()
2248
            ->getSingleScalarResult();
2249
2250
        return $count;
2251
    }
2252
2253
    /**
2254
     * @param array $params
2255
     */
2256
    public static function addStatus($params)
2257
    {
2258
        $item = new Status();
2259
        $item->setCode(URLify::filter($params['name']));
2260
        $item->setName($params['name']);
2261
        $item->setDescription($params['description']);
2262
2263
        Database::getManager()->persist($item);
2264
        Database::getManager()->flush();
2265
    }
2266
2267
    /**
2268
     * @param $id
2269
     *
2270
     * @return Project
2271
     */
2272
    public static function getStatus($id)
2273
    {
2274
        return Database::getManager()->getRepository('ChamiloTicketBundle:Status')->find($id);
2275
    }
2276
2277
    /**
2278
     * @param int   $id
2279
     * @param array $params
2280
     */
2281
    public static function updateStatus($id, $params)
2282
    {
2283
        $item = self::getStatus($id);
2284
        $item->setName($params['name']);
2285
        $item->setDescription($params['description']);
2286
2287
        Database::getManager()->merge($item);
2288
        Database::getManager()->flush();
2289
    }
2290
2291
    /**
2292
     * @param int $id
2293
     */
2294
    public static function deleteStatus($id)
2295
    {
2296
        $item = self::getStatus($id);
2297
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\TicketBundle\Entity\Project, thus it always evaluated to true.
Loading history...
2298
            Database::getManager()->remove($item);
2299
            Database::getManager()->flush();
2300
        }
2301
    }
2302
2303
    /**
2304
     * @param string $url
2305
     *
2306
     * @return FormValidator
2307
     */
2308
    public static function getStatusForm($url)
2309
    {
2310
        $form = new FormValidator('status', 'post', $url);
2311
        $form->addText('name', get_lang('Name'));
2312
        $form->addHtmlEditor('description', get_lang('Description'));
2313
        $form->addButtonUpdate(get_lang('Save'));
2314
2315
        return $form;
2316
    }
2317
2318
    /**
2319
     * @return array
2320
     */
2321
    public static function getPriorityAdminList()
2322
    {
2323
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->findAll();
2324
2325
        $list = [];
2326
        /** @var Status $row */
2327
        foreach ($items as $row) {
2328
            $list[] = [
2329
                'id' => $row->getId(),
2330
                'code' => $row->getCode(),
2331
                '0' => $row->getId(),
2332
                '1' => $row->getName(),
2333
                '2' => $row->getDescription(),
2334
                '3' => $row->getId(),
2335
            ];
2336
        }
2337
2338
        return $list;
2339
    }
2340
2341
    /**
2342
     * @return array
2343
     */
2344
    public static function getPrioritySimple()
2345
    {
2346
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->findAll();
2347
2348
        $list = [];
2349
        /** @var Priority $row */
2350
        foreach ($projects as $row) {
2351
            $list[] = [
2352
                'id' => $row->getId(),
2353
                '0' => $row->getId(),
2354
                '1' => Display::url($row->getName()),
0 ignored issues
show
Bug introduced by
The call to Display::url() has too few arguments starting with url. ( Ignorable by Annotation )

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

2354
                '1' => Display::/** @scrutinizer ignore-call */ url($row->getName()),

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

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

Loading history...
2355
                '2' => $row->getDescription(),
2356
            ];
2357
        }
2358
2359
        return $list;
2360
    }
2361
2362
    /**
2363
     * @return int
2364
     */
2365
    public static function getPriorityCount()
2366
    {
2367
        $count = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->createQueryBuilder('p')
2368
            ->select('COUNT(p.id)')
2369
            ->getQuery()
2370
            ->getSingleScalarResult();
2371
2372
        return $count;
2373
    }
2374
2375
    /**
2376
     * @param array $params
2377
     */
2378
    public static function addPriority($params)
2379
    {
2380
        $item = new Priority();
2381
        $item
2382
            ->setCode(URLify::filter($params['name']))
2383
            ->setName($params['name'])
2384
            ->setDescription($params['description'])
2385
            ->setColor('')
2386
            ->setInsertUserId(api_get_user_id())
2387
            ->setUrgency('')
2388
        ;
2389
2390
        Database::getManager()->persist($item);
2391
        Database::getManager()->flush();
2392
    }
2393
2394
    /**
2395
     * @param $id
2396
     *
2397
     * @return Priority
2398
     */
2399
    public static function getPriority($id)
2400
    {
2401
        return Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->find($id);
2402
    }
2403
2404
    /**
2405
     * @param int   $id
2406
     * @param array $params
2407
     */
2408
    public static function updatePriority($id, $params)
2409
    {
2410
        $item = self::getPriority($id);
2411
        $item->setName($params['name']);
2412
        $item->setDescription($params['description']);
2413
2414
        Database::getManager()->merge($item);
2415
        Database::getManager()->flush();
2416
    }
2417
2418
    /**
2419
     * @param int $id
2420
     */
2421
    public static function deletePriority($id)
2422
    {
2423
        $item = self::getPriority($id);
2424
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\TicketBundle\Entity\Priority, thus it always evaluated to true.
Loading history...
2425
            Database::getManager()->remove($item);
2426
            Database::getManager()->flush();
2427
        }
2428
    }
2429
2430
    /**
2431
     * @param string $url
2432
     *
2433
     * @return FormValidator
2434
     */
2435
    public static function getPriorityForm($url)
2436
    {
2437
        $form = new FormValidator('priority', 'post', $url);
2438
        $form->addText('name', get_lang('Name'));
2439
        $form->addHtmlEditor('description', get_lang('Description'));
2440
        $form->addButtonUpdate(get_lang('Save'));
2441
2442
        return $form;
2443
    }
2444
2445
    /**
2446
     * Returns a list of menu elements for the tickets system's configuration.
2447
     *
2448
     * @param string $exclude The element to exclude from the list
2449
     *
2450
     * @return array
2451
     */
2452
    public static function getSettingsMenuItems($exclude = null)
2453
    {
2454
        $project = [
2455
            'icon' => 'project.png',
2456
            'url' => 'projects.php',
2457
            'content' => get_lang('Projects'),
2458
        ];
2459
        $status = [
2460
            'icon' => 'check-circle.png',
2461
            'url' => 'status.php',
2462
            'content' => get_lang('Status'),
2463
        ];
2464
        $priority = [
2465
            'icon' => 'tickets_urgent.png',
2466
            'url' => 'priorities.php',
2467
            'content' => get_lang('Priority'),
2468
        ];
2469
        switch ($exclude) {
2470
            case 'project':
2471
                $items = [$status, $priority];
2472
                break;
2473
            case 'status':
2474
                $items = [$project, $priority];
2475
                break;
2476
            case 'priority':
2477
                $items = [$project, $status];
2478
                break;
2479
            default:
2480
                $items = [$project, $status, $priority];
2481
                break;
2482
        }
2483
2484
        return $items;
2485
    }
2486
2487
    /**
2488
     * Returns a list of strings representing the default statuses.
2489
     *
2490
     * @return array
2491
     */
2492
    public static function getDefaultStatusList()
2493
    {
2494
        return [
2495
            self::STATUS_NEW,
2496
            self::STATUS_PENDING,
2497
            self::STATUS_UNCONFIRMED,
2498
            self::STATUS_CLOSE,
2499
            self::STATUS_FORWARDED,
2500
        ];
2501
    }
2502
2503
    /**
2504
     * @return array
2505
     */
2506
    public static function getDefaultPriorityList()
2507
    {
2508
        return [
2509
            self::PRIORITY_NORMAL,
2510
            self::PRIORITY_HIGH,
2511
            self::PRIORITY_LOW,
2512
            self::STATUS_CLOSE,
2513
            self::STATUS_FORWARDED,
2514
        ];
2515
    }
2516
2517
    /**
2518
     * Deletes the user from all the ticket system.
2519
     *
2520
     * @param int $userId
2521
     */
2522
    public static function deleteUserFromTicketSystem($userId)
2523
    {
2524
        $userId = (int) $userId;
2525
        $schema = Database::getManager()->getConnection()->getSchemaManager();
2526
2527
        if ($schema->tablesExist('ticket_assigned_log')) {
2528
            $sql = "UPDATE ticket_assigned_log SET user_id = NULL WHERE user_id = $userId";
2529
            Database::query($sql);
2530
2531
            $sql = "UPDATE ticket_assigned_log SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2532
            Database::query($sql);
2533
        }
2534
2535
        if ($schema->tablesExist('ticket_ticket')) {
2536
            $sql = "UPDATE ticket_ticket SET assigned_last_user = NULL WHERE assigned_last_user = $userId";
2537
            Database::query($sql);
2538
2539
            $sql = "UPDATE ticket_ticket SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2540
            Database::query($sql);
2541
2542
            $sql = "UPDATE ticket_ticket SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2543
            Database::query($sql);
2544
        }
2545
2546
        if ($schema->tablesExist('ticket_category')) {
2547
            $sql = "UPDATE ticket_category SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2548
            Database::query($sql);
2549
2550
            $sql = "UPDATE ticket_category SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2551
            Database::query($sql);
2552
        }
2553
2554
        if ($schema->tablesExist('ticket_category_rel_user')) {
2555
            $sql = "DELETE FROM ticket_category_rel_user WHERE user_id = $userId";
2556
            Database::query($sql);
2557
        }
2558
2559
        if ($schema->tablesExist('ticket_message')) {
2560
            $sql = "UPDATE ticket_message SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2561
            Database::query($sql);
2562
2563
            $sql = "UPDATE ticket_message SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2564
            Database::query($sql);
2565
        }
2566
2567
        if ($schema->tablesExist('ticket_message_attachments')) {
2568
            $sql = "UPDATE ticket_message_attachments SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2569
            Database::query($sql);
2570
2571
            $sql = "UPDATE ticket_message_attachments SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2572
            Database::query($sql);
2573
        }
2574
2575
        if ($schema->tablesExist('ticket_priority')) {
2576
            $sql = "UPDATE ticket_priority SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2577
            Database::query($sql);
2578
2579
            $sql = "UPDATE ticket_priority SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2580
            Database::query($sql);
2581
        }
2582
2583
        if ($schema->tablesExist('ticket_project')) {
2584
            $sql = "UPDATE ticket_project SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2585
            Database::query($sql);
2586
2587
            $sql = "UPDATE ticket_project SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2588
            Database::query($sql);
2589
        }
2590
    }
2591
2592
    /**
2593
     * @param array $userInfo
2594
     * @param int   $projectId
2595
     *
2596
     * @return bool
2597
     */
2598
    public static function userIsAllowInProject($userInfo, $projectId)
2599
    {
2600
        if (api_is_platform_admin()) {
2601
            return true;
2602
        }
2603
2604
        $allowRoleList = self::getAllowedRolesFromProject($projectId);
2605
2606
        // Check if a role was set to the project
2607
        // Project 1 is considered the default and is accessible to all users
2608
        if (!empty($allowRoleList) && is_array($allowRoleList)) {
2609
            if (in_array($userInfo['status'], $allowRoleList)) {
2610
                return true;
2611
            }
2612
        }
2613
2614
        return false;
2615
    }
2616
2617
    /**
2618
     * @param int $projectId
2619
     *
2620
     * @todo load from database instead of configuration.php setting
2621
     *
2622
     * @return array
2623
     */
2624
    public static function getAllowedRolesFromProject($projectId)
2625
    {
2626
        $options = api_get_configuration_value('ticket_project_user_roles');
2627
        if ($options) {
2628
            if (isset($options['permissions'][$projectId])) {
2629
                return $options['permissions'][$projectId];
2630
            }
2631
        }
2632
2633
        return [];
2634
    }
2635
2636
    public static function notifiyTicketUpdated(int $ticketId, int $categoryId, string $message)
2637
    {
2638
        $subject = get_lang('TicketUpdated');
2639
2640
        TicketManager::sendNotification($ticketId, $subject, $message);
2641
2642
        if (empty($categoryId)) {
2643
            return;
2644
        }
2645
2646
        $usersInCategory = self::getUsersInCategory($categoryId);
2647
2648
        if (!empty($usersInCategory)) {
2649
            foreach ($usersInCategory as $data) {
2650
                if ($data['user_id']) {
2651
                    self::sendNotification($ticketId, $subject, $message, $data['user_id']);
2652
                }
2653
            }
2654
2655
            return;
2656
        }
2657
2658
        if ('true' === api_get_setting('ticket_send_warning_to_all_admins')) {
2659
            $categoryInfo = self::getCategory($categoryId);
2660
2661
            $warningNoUsers = sprintf(
2662
                get_lang('WarningCategoryXDoesntHaveUsers'),
2663
                $categoryInfo['name']
2664
            );
2665
2666
            $message = Display::return_message($warningNoUsers, 'warning')
2667
                .$message;
2668
2669
            $adminsToNotify = UserManager::get_all_administrators();
2670
2671
            foreach ($adminsToNotify as $userId => $data) {
2672
                if ($data['active']) {
2673
                    self::sendNotification($ticketId, $subject, $message, $userId);
2674
                }
2675
            }
2676
        }
2677
    }
2678
}
2679