TicketManager::add()   F
last analyzed

Complexity

Conditions 36
Paths > 20000

Size

Total Lines 290
Code Lines 173

Duplication

Lines 0
Ratio 0 %

Importance

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

2145
                '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...
2146
                '2' => $row->getDescription(),
2147
            ];
2148
        }
2149
2150
        return $list;
2151
    }
2152
2153
    /**
2154
     * @return int
2155
     */
2156
    public static function getStatusCount()
2157
    {
2158
        $count = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->createQueryBuilder('p')
2159
            ->select('COUNT(p.id)')
2160
            ->getQuery()
2161
            ->getSingleScalarResult();
2162
2163
        return $count;
2164
    }
2165
2166
    /**
2167
     * @param array $params
2168
     */
2169
    public static function addStatus($params)
2170
    {
2171
        $item = new Status();
2172
        $item->setCode(URLify::filter($params['name']));
2173
        $item->setName($params['name']);
2174
        $item->setDescription($params['description']);
2175
2176
        Database::getManager()->persist($item);
2177
        Database::getManager()->flush();
2178
    }
2179
2180
    /**
2181
     * @param $id
2182
     *
2183
     * @return Project
2184
     */
2185
    public static function getStatus($id)
2186
    {
2187
        return Database::getManager()->getRepository('ChamiloTicketBundle:Status')->find($id);
2188
    }
2189
2190
    /**
2191
     * @param int   $id
2192
     * @param array $params
2193
     */
2194
    public static function updateStatus($id, $params)
2195
    {
2196
        $item = self::getStatus($id);
2197
        $item->setName($params['name']);
2198
        $item->setDescription($params['description']);
2199
2200
        Database::getManager()->merge($item);
2201
        Database::getManager()->flush();
2202
    }
2203
2204
    /**
2205
     * @param int $id
2206
     */
2207
    public static function deleteStatus($id)
2208
    {
2209
        $item = self::getStatus($id);
2210
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\TicketBundle\Entity\Project, thus it always evaluated to true.
Loading history...
2211
            Database::getManager()->remove($item);
2212
            Database::getManager()->flush();
2213
        }
2214
    }
2215
2216
    /**
2217
     * @param string $url
2218
     *
2219
     * @return FormValidator
2220
     */
2221
    public static function getStatusForm($url)
2222
    {
2223
        $form = new FormValidator('status', 'post', $url);
2224
        $form->addText('name', get_lang('Name'));
2225
        $form->addHtmlEditor('description', get_lang('Description'));
2226
        $form->addButtonUpdate(get_lang('Save'));
2227
2228
        return $form;
2229
    }
2230
2231
    /**
2232
     * @return array
2233
     */
2234
    public static function getPriorityAdminList()
2235
    {
2236
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->findAll();
2237
2238
        $list = [];
2239
        /** @var Status $row */
2240
        foreach ($items as $row) {
2241
            $list[] = [
2242
                'id' => $row->getId(),
2243
                'code' => $row->getCode(),
2244
                '0' => $row->getId(),
2245
                '1' => $row->getName(),
2246
                '2' => $row->getDescription(),
2247
                '3' => $row->getId(),
2248
            ];
2249
        }
2250
2251
        return $list;
2252
    }
2253
2254
    /**
2255
     * @return array
2256
     */
2257
    public static function getPrioritySimple()
2258
    {
2259
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->findAll();
2260
2261
        $list = [];
2262
        /** @var Priority $row */
2263
        foreach ($projects as $row) {
2264
            $list[] = [
2265
                'id' => $row->getId(),
2266
                '0' => $row->getId(),
2267
                '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

2267
                '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...
2268
                '2' => $row->getDescription(),
2269
            ];
2270
        }
2271
2272
        return $list;
2273
    }
2274
2275
    /**
2276
     * @return int
2277
     */
2278
    public static function getPriorityCount()
2279
    {
2280
        $count = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->createQueryBuilder('p')
2281
            ->select('COUNT(p.id)')
2282
            ->getQuery()
2283
            ->getSingleScalarResult();
2284
2285
        return $count;
2286
    }
2287
2288
    /**
2289
     * @param array $params
2290
     */
2291
    public static function addPriority($params)
2292
    {
2293
        $item = new Priority();
2294
        $item
2295
            ->setCode(URLify::filter($params['name']))
2296
            ->setName($params['name'])
2297
            ->setDescription($params['description'])
2298
            ->setColor('')
2299
            ->setInsertUserId(api_get_user_id())
2300
            ->setUrgency('')
2301
        ;
2302
2303
        Database::getManager()->persist($item);
2304
        Database::getManager()->flush();
2305
    }
2306
2307
    /**
2308
     * @param $id
2309
     *
2310
     * @return Priority
2311
     */
2312
    public static function getPriority($id)
2313
    {
2314
        return Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->find($id);
2315
    }
2316
2317
    /**
2318
     * @param int   $id
2319
     * @param array $params
2320
     */
2321
    public static function updatePriority($id, $params)
2322
    {
2323
        $item = self::getPriority($id);
2324
        $item->setName($params['name']);
2325
        $item->setDescription($params['description']);
2326
2327
        Database::getManager()->merge($item);
2328
        Database::getManager()->flush();
2329
    }
2330
2331
    /**
2332
     * @param int $id
2333
     */
2334
    public static function deletePriority($id)
2335
    {
2336
        $item = self::getPriority($id);
2337
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\TicketBundle\Entity\Priority, thus it always evaluated to true.
Loading history...
2338
            Database::getManager()->remove($item);
2339
            Database::getManager()->flush();
2340
        }
2341
    }
2342
2343
    /**
2344
     * @param string $url
2345
     *
2346
     * @return FormValidator
2347
     */
2348
    public static function getPriorityForm($url)
2349
    {
2350
        $form = new FormValidator('priority', 'post', $url);
2351
        $form->addText('name', get_lang('Name'));
2352
        $form->addHtmlEditor('description', get_lang('Description'));
2353
        $form->addButtonUpdate(get_lang('Save'));
2354
2355
        return $form;
2356
    }
2357
2358
    /**
2359
     * Returns a list of menu elements for the tickets system's configuration.
2360
     *
2361
     * @param string $exclude The element to exclude from the list
2362
     *
2363
     * @return array
2364
     */
2365
    public static function getSettingsMenuItems($exclude = null)
2366
    {
2367
        $project = [
2368
            'icon' => 'project.png',
2369
            'url' => 'projects.php',
2370
            'content' => get_lang('Projects'),
2371
        ];
2372
        $status = [
2373
            'icon' => 'check-circle.png',
2374
            'url' => 'status.php',
2375
            'content' => get_lang('Status'),
2376
        ];
2377
        $priority = [
2378
            'icon' => 'tickets_urgent.png',
2379
            'url' => 'priorities.php',
2380
            'content' => get_lang('Priority'),
2381
        ];
2382
        switch ($exclude) {
2383
            case 'project':
2384
                $items = [$status, $priority];
2385
                break;
2386
            case 'status':
2387
                $items = [$project, $priority];
2388
                break;
2389
            case 'priority':
2390
                $items = [$project, $status];
2391
                break;
2392
            default:
2393
                $items = [$project, $status, $priority];
2394
                break;
2395
        }
2396
2397
        return $items;
2398
    }
2399
2400
    /**
2401
     * Returns a list of strings representing the default statuses.
2402
     *
2403
     * @return array
2404
     */
2405
    public static function getDefaultStatusList()
2406
    {
2407
        return [
2408
            self::STATUS_NEW,
2409
            self::STATUS_PENDING,
2410
            self::STATUS_UNCONFIRMED,
2411
            self::STATUS_CLOSE,
2412
            self::STATUS_FORWARDED,
2413
        ];
2414
    }
2415
2416
    /**
2417
     * @return array
2418
     */
2419
    public static function getDefaultPriorityList()
2420
    {
2421
        return [
2422
            self::PRIORITY_NORMAL,
2423
            self::PRIORITY_HIGH,
2424
            self::PRIORITY_LOW,
2425
            self::STATUS_CLOSE,
2426
            self::STATUS_FORWARDED,
2427
        ];
2428
    }
2429
2430
    /**
2431
     * Deletes the user from all the ticket system.
2432
     *
2433
     * @param int $userId
2434
     */
2435
    public static function deleteUserFromTicketSystem($userId)
2436
    {
2437
        $userId = (int) $userId;
2438
        $schema = Database::getManager()->getConnection()->getSchemaManager();
2439
2440
        if ($schema->tablesExist('ticket_assigned_log')) {
2441
            $sql = "UPDATE ticket_assigned_log SET user_id = NULL WHERE user_id = $userId";
2442
            Database::query($sql);
2443
2444
            $sql = "UPDATE ticket_assigned_log SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2445
            Database::query($sql);
2446
        }
2447
2448
        if ($schema->tablesExist('ticket_ticket')) {
2449
            $sql = "UPDATE ticket_ticket SET assigned_last_user = NULL WHERE assigned_last_user = $userId";
2450
            Database::query($sql);
2451
2452
            $sql = "UPDATE ticket_ticket SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2453
            Database::query($sql);
2454
2455
            $sql = "UPDATE ticket_ticket SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2456
            Database::query($sql);
2457
        }
2458
2459
        if ($schema->tablesExist('ticket_category')) {
2460
            $sql = "UPDATE ticket_category SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2461
            Database::query($sql);
2462
2463
            $sql = "UPDATE ticket_category SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2464
            Database::query($sql);
2465
        }
2466
2467
        if ($schema->tablesExist('ticket_category_rel_user')) {
2468
            $sql = "DELETE FROM ticket_category_rel_user WHERE user_id = $userId";
2469
            Database::query($sql);
2470
        }
2471
2472
        if ($schema->tablesExist('ticket_message')) {
2473
            $sql = "UPDATE ticket_message SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2474
            Database::query($sql);
2475
2476
            $sql = "UPDATE ticket_message SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2477
            Database::query($sql);
2478
        }
2479
2480
        if ($schema->tablesExist('ticket_message_attachments')) {
2481
            $sql = "UPDATE ticket_message_attachments SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2482
            Database::query($sql);
2483
2484
            $sql = "UPDATE ticket_message_attachments SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2485
            Database::query($sql);
2486
        }
2487
2488
        if ($schema->tablesExist('ticket_priority')) {
2489
            $sql = "UPDATE ticket_priority SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2490
            Database::query($sql);
2491
2492
            $sql = "UPDATE ticket_priority SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2493
            Database::query($sql);
2494
        }
2495
2496
        if ($schema->tablesExist('ticket_project')) {
2497
            $sql = "UPDATE ticket_project SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2498
            Database::query($sql);
2499
2500
            $sql = "UPDATE ticket_project SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2501
            Database::query($sql);
2502
        }
2503
    }
2504
2505
    /**
2506
     * @param array $userInfo
2507
     * @param int   $projectId
2508
     *
2509
     * @return bool
2510
     */
2511
    public static function userIsAllowInProject($userInfo, $projectId)
2512
    {
2513
        if (api_is_platform_admin()) {
2514
            return true;
2515
        }
2516
2517
        $allowRoleList = self::getAllowedRolesFromProject($projectId);
2518
2519
        // Check if a role was set to the project
2520
        // Project 1 is considered the default and is accessible to all users
2521
        if (!empty($allowRoleList) && is_array($allowRoleList)) {
2522
            if (in_array($userInfo['status'], $allowRoleList)) {
2523
                return true;
2524
            }
2525
        }
2526
2527
        return false;
2528
    }
2529
2530
    /**
2531
     * @param int $projectId
2532
     *
2533
     * @todo load from database instead of configuration.php setting
2534
     *
2535
     * @return array
2536
     */
2537
    public static function getAllowedRolesFromProject($projectId)
2538
    {
2539
        $options = api_get_configuration_value('ticket_project_user_roles');
2540
        if ($options) {
2541
            if (isset($options['permissions'][$projectId])) {
2542
                return $options['permissions'][$projectId];
2543
            }
2544
        }
2545
2546
        return [];
2547
    }
2548
2549
    public static function notifiyTicketUpdated(int $ticketId, int $categoryId, string $message)
2550
    {
2551
        $subject = get_lang('TicketUpdated');
2552
2553
        TicketManager::sendNotification($ticketId, $subject, $message);
2554
2555
        if (empty($categoryId)) {
2556
            return;
2557
        }
2558
2559
        $usersInCategory = self::getUsersInCategory($categoryId);
2560
2561
        if (!empty($usersInCategory)) {
2562
            foreach ($usersInCategory as $data) {
2563
                if ($data['user_id']) {
2564
                    self::sendNotification($ticketId, $subject, $message, $data['user_id']);
2565
                }
2566
            }
2567
2568
            return;
2569
        }
2570
2571
        if ('true' === api_get_setting('ticket_send_warning_to_all_admins')) {
2572
            $categoryInfo = self::getCategory($categoryId);
2573
2574
            $warningNoUsers = sprintf(
2575
                get_lang('WarningCategoryXDoesntHaveUsers'),
2576
                $categoryInfo['name']
2577
            );
2578
2579
            $message = Display::return_message($warningNoUsers, 'warning')
2580
                .$message;
2581
2582
            $adminsToNotify = UserManager::get_all_administrators();
2583
2584
            foreach ($adminsToNotify as $userId => $data) {
2585
                if ($data['active']) {
2586
                    self::sendNotification($ticketId, $subject, $message, $userId);
2587
                }
2588
            }
2589
        }
2590
    }
2591
}
2592