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
    /**
778
     * Get tickets by userId.
779
     *
780
     * @param int $from
781
     * @param int $number_of_items
782
     * @param $column
783
     * @param $direction
784
     *
785
     * @return array
786
     */
787
    public static function getTicketsByCurrentUser(
788
        $from,
789
        $number_of_items,
790
        $column,
791
        $direction
792
    ) {
793
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
794
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
795
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
796
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
797
        $direction = !empty($direction) ? $direction : 'DESC';
798
        $userId = api_get_user_id();
799
        $userInfo = api_get_user_info($userId);
800
801
        if (empty($userInfo)) {
802
            return [];
803
        }
804
        $isAdmin = UserManager::is_admin($userId);
805
806
        if (!isset($_GET['project_id'])) {
807
            return [];
808
        }
809
810
        switch ($column) {
811
            case 0:
812
                $column = 'ticket_id';
813
                break;
814
            case 1:
815
                $column = 'status_name';
816
                break;
817
            case 2:
818
                $column = 'start_date';
819
                break;
820
            case 3:
821
                $column = 'sys_lastedit_datetime';
822
                break;
823
            case 4:
824
                $column = 'category_name';
825
                break;
826
            case 5:
827
                $column = 'sys_insert_user_id';
828
                break;
829
            case 6:
830
                $column = 'assigned_last_user';
831
                break;
832
            case 7:
833
                $column = 'total_messages';
834
                break;
835
            case 8:
836
                $column = 'subject';
837
                break;
838
            default:
839
                $column = 'ticket_id';
840
        }
841
842
        $sql = "SELECT DISTINCT
843
                ticket.*,
844
                ticket.id ticket_id,
845
                status.name AS status_name,
846
                ticket.start_date,
847
                ticket.sys_lastedit_datetime,
848
                cat.name AS category_name,
849
                priority.name AS priority_name,
850
                ticket.total_messages AS total_messages,
851
                ticket.message AS message,
852
                ticket.subject AS subject,
853
                ticket.assigned_last_user
854
            FROM $table_support_tickets ticket
855
            INNER JOIN $table_support_category cat
856
            ON (cat.id = ticket.category_id)
857
            INNER JOIN $table_support_priority priority
858
            ON (ticket.priority_id = priority.id)
859
            INNER JOIN $table_support_status status
860
            ON (ticket.status_id = status.id)
861
            WHERE 1=1
862
        ";
863
864
        $projectId = (int) $_GET['project_id'];
865
        $userIsAllowInProject = self::userIsAllowInProject($userInfo, $projectId);
866
867
        // Check if a role was set to the project
868
        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...
869
            $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
870
        }
871
872
        // Search simple
873
        if (isset($_GET['submit_simple']) && $_GET['keyword'] != '') {
874
            $keyword = Database::escape_string(trim($_GET['keyword']));
875
            $sql .= " AND (
876
                      ticket.id LIKE '%$keyword%' OR
877
                      ticket.code LIKE '%$keyword%' OR
878
                      ticket.subject LIKE '%$keyword%' OR
879
                      ticket.message LIKE '%$keyword%' OR
880
                      ticket.keyword LIKE '%$keyword%' OR
881
                      ticket.source LIKE '%$keyword%' OR
882
                      cat.name LIKE '%$keyword%' OR
883
                      status.name LIKE '%$keyword%' OR
884
                      priority.name LIKE '%$keyword%' OR
885
                      ticket.personal_email LIKE '%$keyword%'
886
            )";
887
        }
888
889
        $keywords = [
890
            'project_id' => 'ticket.project_id',
891
            'keyword_category' => 'ticket.category_id',
892
            'keyword_assigned_to' => 'ticket.assigned_last_user',
893
            'keyword_source' => 'ticket.source ',
894
            'keyword_status' => 'ticket.status_id',
895
            'keyword_priority' => 'ticket.priority_id',
896
        ];
897
898
        foreach ($keywords as $keyword => $label) {
899
            if (isset($_GET[$keyword])) {
900
                $data = Database::escape_string(trim($_GET[$keyword]));
901
                if (!empty($data)) {
902
                    $sql .= " AND $label = '$data' ";
903
                }
904
            }
905
        }
906
907
        // Search advanced
908
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
909
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
910
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
911
        $keyword_range = !empty($keyword_start_date_start) && !empty($keyword_start_date_end);
912
913
        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...
914
            $sql .= " AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start' ";
915
        }
916
        if ($keyword_range && $keyword_start_date_start != '' && $keyword_start_date_end != '') {
917
            $sql .= " AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
918
                      AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
919
        }
920
921
        if ($keyword_course != '') {
922
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
923
            $sql .= " AND ticket.course_id IN (
924
                     SELECT id FROM $course_table
925
                     WHERE (
926
                        title LIKE '%$keyword_course%' OR
927
                        code LIKE '%$keyword_course%' OR
928
                        visual_code LIKE '%$keyword_course%'
929
                     )
930
            )";
931
        }
932
        $sql .= " ORDER BY `$column` $direction";
933
        $sql .= " LIMIT $from, $number_of_items";
934
935
        $result = Database::query($sql);
936
        $tickets = [];
937
        $webPath = api_get_path(WEB_PATH);
938
        while ($row = Database::fetch_assoc($result)) {
939
            $userInfo = api_get_user_info($row['sys_insert_user_id']);
940
            $hrefUser = $webPath.'main/admin/user_information.php?user_id='.$userInfo['user_id'];
941
            $name = "<a href='$hrefUser'> {$userInfo['complete_name_with_username']} </a>";
942
            if ($row['assigned_last_user'] != 0) {
943
                $assignedUserInfo = api_get_user_info($row['assigned_last_user']);
944
                if (!empty($assignedUserInfo)) {
945
                    $hrefResp = $webPath.'main/admin/user_information.php?user_id='.$assignedUserInfo['user_id'];
946
                    $row['assigned_last_user'] = "<a href='$hrefResp'> {$assignedUserInfo['complete_name_with_username']} </a>";
947
                } else {
948
                    $row['assigned_last_user'] = get_lang('UnknownUser');
949
                }
950
            } else {
951
                if ($row['status_id'] !== self::STATUS_FORWARDED) {
952
                    $row['assigned_last_user'] = '<span style="color:#ff0000;">'.get_lang('ToBeAssigned').'</span>';
953
                } else {
954
                    $row['assigned_last_user'] = '<span style="color:#00ff00;">'.get_lang('MessageResent').'</span>';
955
                }
956
            }
957
958
            switch ($row['source']) {
959
                case self::SOURCE_PRESENTIAL:
960
                    $img_source = 'icons/32/user.png';
961
                    break;
962
                case self::SOURCE_EMAIL:
963
                    $img_source = 'icons/32/mail.png';
964
                    break;
965
                case self::SOURCE_PHONE:
966
                    $img_source = 'icons/32/event.png';
967
                    break;
968
                default:
969
                    $img_source = 'icons/32/ticket.png';
970
                    break;
971
            }
972
973
            $row['start_date'] = Display::dateToStringAgoAndLongDate($row['start_date']);
974
            $row['sys_lastedit_datetime'] = Display::dateToStringAgoAndLongDate($row['sys_lastedit_datetime']);
975
976
            $icon = Display::return_icon(
977
                $img_source,
978
                get_lang('Info'),
979
                ['style' => 'margin-right: 10px; float: left;']
980
            );
981
982
            $icon .= '<a href="ticket_details.php?ticket_id='.$row['id'].'">'.$row['code'].'</a>';
983
984
            if ($isAdmin) {
985
                $ticket = [
986
                    $icon.' '.Security::remove_XSS($row['subject']),
987
                    $row['status_name'],
988
                    $row['start_date'],
989
                    $row['sys_lastedit_datetime'],
990
                    $row['category_name'],
991
                    $name,
992
                    $row['assigned_last_user'],
993
                    $row['total_messages'],
994
                ];
995
            } else {
996
                $ticket = [
997
                    $icon.' '.Security::remove_XSS($row['subject']),
998
                    $row['status_name'],
999
                    $row['start_date'],
1000
                    $row['sys_lastedit_datetime'],
1001
                    $row['category_name'],
1002
                ];
1003
            }
1004
            if ($isAdmin) {
1005
                $ticket['0'] .= '&nbsp;&nbsp;<a href="javascript:void(0)" onclick="load_history_ticket(\'div_'.$row['ticket_id'].'\','.$row['ticket_id'].')">
1006
					<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').'"/>
1007
					<div class="blackboard_hide" id="div_'.$row['ticket_id'].'">&nbsp;&nbsp;</div>
1008
					</a>&nbsp;&nbsp;';
1009
            }
1010
            $tickets[] = $ticket;
1011
        }
1012
1013
        return $tickets;
1014
    }
1015
1016
    /**
1017
     * @return int
1018
     */
1019
    public static function getTotalTicketsCurrentUser()
1020
    {
1021
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1022
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1023
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1024
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1025
1026
        $userInfo = api_get_user_info();
1027
        if (empty($userInfo)) {
1028
            return 0;
1029
        }
1030
        $userId = $userInfo['id'];
1031
1032
        if (!isset($_GET['project_id'])) {
1033
            return 0;
1034
        }
1035
1036
        $sql = "SELECT COUNT(ticket.id) AS total
1037
                FROM $table_support_tickets ticket
1038
                INNER JOIN $table_support_category cat
1039
                ON (cat.id = ticket.category_id)
1040
                INNER JOIN $table_support_priority priority
1041
                ON (ticket.priority_id = priority.id)
1042
                INNER JOIN $table_support_status status
1043
                ON (ticket.status_id = status.id)
1044
	            WHERE 1 = 1";
1045
1046
        $projectId = (int) $_GET['project_id'];
1047
        $allowRoleList = self::getAllowedRolesFromProject($projectId);
1048
1049
        // Check if a role was set to the project
1050
        if (!empty($allowRoleList) && is_array($allowRoleList)) {
1051
            if (!in_array($userInfo['status'], $allowRoleList)) {
1052
                $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
1053
            }
1054
        } else {
1055
            if (!api_is_platform_admin()) {
1056
                $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
1057
            }
1058
        }
1059
1060
        // Search simple
1061
        if (isset($_GET['submit_simple'])) {
1062
            if ($_GET['keyword'] != '') {
1063
                $keyword = Database::escape_string(trim($_GET['keyword']));
1064
                $sql .= " AND (
1065
                          ticket.code LIKE '%$keyword%' OR
1066
                          ticket.subject LIKE '%$keyword%' OR
1067
                          ticket.message LIKE '%$keyword%' OR
1068
                          ticket.keyword LIKE '%$keyword%' OR
1069
                          ticket.personal_email LIKE '%$keyword%' OR
1070
                          ticket.source LIKE '%$keyword%'
1071
                )";
1072
            }
1073
        }
1074
1075
        $keywords = [
1076
            'project_id' => 'ticket.project_id',
1077
            'keyword_category' => 'ticket.category_id',
1078
            'keyword_assigned_to' => 'ticket.assigned_last_user',
1079
            'keyword_source' => 'ticket.source',
1080
            'keyword_status' => 'ticket.status_id',
1081
            'keyword_priority' => 'ticket.priority_id',
1082
        ];
1083
1084
        foreach ($keywords as $keyword => $sqlLabel) {
1085
            if (!empty($_GET[$keyword])) {
1086
                $data = Database::escape_string(trim($_GET[$keyword]));
1087
                $sql .= " AND $sqlLabel = '$data' ";
1088
            }
1089
        }
1090
1091
        // Search advanced
1092
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
1093
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
1094
        $keyword_range = isset($_GET['keyword_dates']) ? Database::escape_string(trim($_GET['keyword_dates'])) : '';
1095
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
1096
1097
        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...
1098
            $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1099
        }
1100
        if ($keyword_range && $keyword_start_date_start != '' && $keyword_start_date_end != '') {
1101
            $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1102
                      AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1103
        }
1104
        if ($keyword_course != '') {
1105
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1106
            $sql .= " AND ticket.course_id IN (
1107
                        SELECT id
1108
                        FROM $course_table
1109
                        WHERE (
1110
                            title LIKE '%$keyword_course%' OR
1111
                            code LIKE '%$keyword_course%' OR
1112
                            visual_code LIKE '%$keyword_course%'
1113
                        )
1114
                   ) ";
1115
        }
1116
1117
        $res = Database::query($sql);
1118
        $obj = Database::fetch_object($res);
1119
1120
        return (int) $obj->total;
1121
    }
1122
1123
    /**
1124
     * @param int $id
1125
     *
1126
     * @return false|MessageAttachment
1127
     */
1128
    public static function getTicketMessageAttachment($id)
1129
    {
1130
        $id = (int) $id;
1131
        $em = Database::getManager();
1132
        $item = $em->getRepository('ChamiloTicketBundle:MessageAttachment')->find($id);
1133
        if ($item) {
1134
            return $item;
1135
        }
1136
1137
        return false;
1138
    }
1139
1140
    /**
1141
     * @param int $id
1142
     *
1143
     * @return array
1144
     */
1145
    public static function getTicketMessageAttachmentsByTicketId($id)
1146
    {
1147
        $id = (int) $id;
1148
        $em = Database::getManager();
1149
        $items = $em->getRepository('ChamiloTicketBundle:MessageAttachment')->findBy(['ticket' => $id]);
1150
        if ($items) {
1151
            return $items;
1152
        }
1153
1154
        return false;
1155
    }
1156
1157
    /**
1158
     * @param int $ticketId
1159
     *
1160
     * @return array
1161
     */
1162
    public static function get_ticket_detail_by_id($ticketId)
1163
    {
1164
        $ticketId = (int) $ticketId;
1165
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1166
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1167
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1168
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1169
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1170
        $table_support_message_attachments = Database::get_main_table(TABLE_TICKET_MESSAGE_ATTACHMENTS);
1171
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1172
1173
        $sql = "SELECT
1174
                    ticket.*,
1175
                    cat.name,
1176
                    status.name as status,
1177
                    priority.name priority
1178
                FROM $table_support_tickets ticket
1179
                INNER JOIN $table_support_category cat
1180
                ON (cat.id = ticket.category_id)
1181
                INNER JOIN $table_support_priority priority
1182
                ON (priority.id = ticket.priority_id)
1183
                INNER JOIN $table_support_status status
1184
                ON (status.id = ticket.status_id)
1185
		        WHERE
1186
                    ticket.id = $ticketId ";
1187
        $result = Database::query($sql);
1188
        $ticket = [];
1189
        if (Database::num_rows($result) > 0) {
1190
            while ($row = Database::fetch_assoc($result)) {
1191
                $row['course'] = null;
1192
                $row['start_date_from_db'] = $row['start_date'];
1193
                $row['start_date'] = api_convert_and_format_date(
1194
                    api_get_local_time($row['start_date']),
1195
                    DATE_TIME_FORMAT_LONG,
1196
                    api_get_timezone()
1197
                );
1198
                $row['end_date_from_db'] = $row['end_date'];
1199
                $row['end_date'] = api_convert_and_format_date(
1200
                    api_get_local_time($row['end_date']),
1201
                    DATE_TIME_FORMAT_LONG,
1202
                    api_get_timezone()
1203
                );
1204
                $row['sys_lastedit_datetime_from_db'] = $row['sys_lastedit_datetime'];
1205
                $row['sys_lastedit_datetime'] = api_convert_and_format_date(
1206
                    api_get_local_time($row['sys_lastedit_datetime']),
1207
                    DATE_TIME_FORMAT_LONG,
1208
                    api_get_timezone()
1209
                );
1210
                $row['course_url'] = null;
1211
                if ($row['course_id'] != 0) {
1212
                    $course = api_get_course_info_by_id($row['course_id']);
1213
                    $sessionId = 0;
1214
                    if ($row['session_id']) {
1215
                        $sessionId = $row['session_id'];
1216
                    }
1217
                    if ($course) {
1218
                        $row['course_url'] = '<a href="'.$course['course_public_url'].'?id_session='.$sessionId.'">'.$course['name'].'</a>';
1219
                    }
1220
1221
                    $row['exercise_url'] = null;
1222
1223
                    if (!empty($row['exercise_id'])) {
1224
                        $exerciseTitle = ExerciseLib::getExerciseTitleById($row['exercise_id']);
1225
                        $dataExercise = [
1226
                            'cidReq' => $course['code'],
1227
                            'id_session' => $sessionId,
1228
                            'exerciseId' => $row['exercise_id'],
1229
                        ];
1230
                        $urlParamsExercise = http_build_query($dataExercise);
1231
1232
                        $row['exercise_url'] = '<a href="'.api_get_path(WEB_CODE_PATH).'exercise/overview.php?'.$urlParamsExercise.'">'.$exerciseTitle.'</a>';
1233
                    }
1234
1235
                    $row['lp_url'] = null;
1236
1237
                    if (!empty($row['lp_id'])) {
1238
                        $lpName = learnpath::getLpNameById($row['lp_id']);
1239
                        $dataLp = [
1240
                            'cidReq' => $course['code'],
1241
                            'id_session' => $sessionId,
1242
                            'lp_id' => $row['lp_id'],
1243
                            'action' => 'view',
1244
                        ];
1245
                        $urlParamsLp = http_build_query($dataLp);
1246
1247
                        $row['lp_url'] = '<a href="'.api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.$urlParamsLp.'">'.$lpName.'</a>';
1248
                    }
1249
                }
1250
1251
                $userInfo = api_get_user_info($row['sys_insert_user_id']);
1252
                $row['user_url'] = '<a href="'.api_get_path(WEB_PATH).'main/admin/user_information.php?user_id='.$userInfo['user_id'].'">
1253
                '.$userInfo['complete_name'].'</a>';
1254
                $ticket['usuario'] = $userInfo;
1255
                $ticket['ticket'] = $row;
1256
            }
1257
1258
            $sql = "SELECT *, message.id as message_id
1259
                    FROM $table_support_messages message
1260
                    INNER JOIN $table_main_user user
1261
                    ON (message.sys_insert_user_id = user.user_id)
1262
                    WHERE
1263
                        message.ticket_id = '$ticketId' ";
1264
            $result = Database::query($sql);
1265
            $ticket['messages'] = [];
1266
            $attach_icon = Display::return_icon('attachment.gif', '');
1267
            $webPath = api_get_path(WEB_CODE_PATH);
1268
            while ($row = Database::fetch_assoc($result)) {
1269
                $message = $row;
1270
                $message['admin'] = UserManager::is_admin($message['user_id']);
1271
                $message['user_info'] = api_get_user_info($message['user_id']);
1272
                $sql = "SELECT *
1273
                        FROM $table_support_message_attachments
1274
                        WHERE
1275
                            message_id = ".$row['message_id']." AND
1276
                            ticket_id = $ticketId";
1277
1278
                $result_attach = Database::query($sql);
1279
                while ($row2 = Database::fetch_assoc($result_attach)) {
1280
                    $row2['filename'] = Security::remove_XSS($row2['filename']);
1281
                    $archiveURL = $webPath.'ticket/download.php?ticket_id='.$ticketId.'&id='.$row2['id'];
1282
                    $row2['attachment_link'] = $attach_icon.
1283
                        '&nbsp;<a href="'.$archiveURL.'">'.$row2['filename'].'</a>&nbsp;('.$row2['size'].')';
1284
                    $message['attachments'][] = $row2;
1285
                }
1286
                $ticket['messages'][] = $message;
1287
            }
1288
        }
1289
1290
        return $ticket;
1291
    }
1292
1293
    /**
1294
     * @param int $ticketId
1295
     * @param int $userId
1296
     *
1297
     * @return bool
1298
     */
1299
    public static function update_message_status($ticketId, $userId)
1300
    {
1301
        $ticketId = (int) $ticketId;
1302
        $userId = (int) $userId;
1303
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1304
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1305
        $now = api_get_utc_datetime();
1306
        $sql = "UPDATE $table_support_messages
1307
                SET
1308
                    status = 'LEI',
1309
                    sys_lastedit_user_id ='".api_get_user_id()."',
1310
                    sys_lastedit_datetime ='".$now."'
1311
                WHERE ticket_id ='$ticketId' ";
1312
1313
        if (api_is_platform_admin()) {
1314
            $sql .= " AND sys_insert_user_id = '$userId'";
1315
        } else {
1316
            $sql .= " AND sys_insert_user_id != '$userId'";
1317
        }
1318
        $result = Database::query($sql);
1319
        if (Database::affected_rows($result) > 0) {
1320
            Database::query(
1321
                "UPDATE $table_support_tickets SET
1322
                    status_id = '".self::STATUS_PENDING."'
1323
                 WHERE id ='$ticketId' AND status_id = '".self::STATUS_NEW."'"
1324
            );
1325
1326
            return true;
1327
        }
1328
1329
        return false;
1330
    }
1331
1332
    /**
1333
     * Send notification to a user through the internal messaging system.
1334
     *
1335
     * @param int    $ticketId
1336
     * @param string $title
1337
     * @param string $message
1338
     * @param int    $onlyToUserId
1339
     *
1340
     * @return bool
1341
     */
1342
    public static function sendNotification($ticketId, $title, $message, $onlyToUserId = 0)
1343
    {
1344
        $ticketInfo = self::get_ticket_detail_by_id($ticketId);
1345
1346
        if (empty($ticketInfo)) {
1347
            return false;
1348
        }
1349
1350
        $assignedUserInfo = api_get_user_info($ticketInfo['ticket']['assigned_last_user']);
1351
        $requestUserInfo = $ticketInfo['usuario'];
1352
        $ticketCode = $ticketInfo['ticket']['code'];
1353
        $status = $ticketInfo['ticket']['status'];
1354
        $priority = $ticketInfo['ticket']['priority'];
1355
1356
        // Subject
1357
        $titleEmail = "[$ticketCode] $title";
1358
1359
        // Content
1360
        $href = api_get_path(WEB_CODE_PATH).'ticket/ticket_details.php?ticket_id='.$ticketId;
1361
        $ticketUrl = Display::url($ticketCode, $href);
1362
        $messageEmail = get_lang('TicketNum').": $ticketUrl <br />";
1363
        $messageEmail .= get_lang('Status').": $status <br />";
1364
        $messageEmail .= get_lang('Priority').": $priority <br />";
1365
        $messageEmail .= '<hr /><br />';
1366
        $messageEmail .= $message;
1367
        $currentUserId = api_get_user_id();
1368
        $attachmentList = [];
1369
        $attachments = self::getTicketMessageAttachmentsByTicketId($ticketId);
1370
        if (!empty($attachments)) {
1371
            /** @var MessageAttachment $attachment */
1372
            foreach ($attachments as $attachment) {
1373
                $file = api_get_uploaded_file(
1374
                    'ticket_attachment',
1375
                    $ticketId,
1376
                    $attachment->getPath()
1377
                );
1378
                if (!empty($file)) {
1379
                    $attachmentList[] = [
1380
                        'tmp_name' => api_get_uploaded_file(
1381
                            'ticket_attachment',
1382
                            $ticketId,
1383
                            $attachment->getPath()
1384
                        ),
1385
                        'size' => $attachment->getSize(),
1386
                        'name' => $attachment->getFilename(),
1387
                        'error' => 0,
1388
                    ];
1389
                }
1390
            }
1391
        }
1392
1393
        if (!empty($onlyToUserId)) {
1394
            // Send only to specific user
1395
            if ($currentUserId != $onlyToUserId) {
1396
                MessageManager::send_message_simple(
1397
                    $onlyToUserId,
1398
                    $titleEmail,
1399
                    $messageEmail,
1400
                    0,
1401
                    false,
1402
                    false,
1403
                    [],
1404
                    false,
1405
                    $attachmentList
1406
                );
1407
            }
1408
        } else {
1409
            // Send to assigned user and to author
1410
            if ($requestUserInfo && $currentUserId != $requestUserInfo['id']) {
1411
                MessageManager::send_message_simple(
1412
                    $requestUserInfo['id'],
1413
                    $titleEmail,
1414
                    $messageEmail,
1415
                    0,
1416
                    false,
1417
                    false,
1418
                    [],
1419
                    false,
1420
                    $attachmentList
1421
                );
1422
            }
1423
1424
            if ($assignedUserInfo &&
1425
                $requestUserInfo['id'] != $assignedUserInfo['id'] &&
1426
                $currentUserId != $assignedUserInfo['id']
1427
            ) {
1428
                MessageManager::send_message_simple(
1429
                    $assignedUserInfo['id'],
1430
                    $titleEmail,
1431
                    $messageEmail,
1432
                    0,
1433
                    false,
1434
                    false,
1435
                    [],
1436
                    false,
1437
                    $attachmentList
1438
                );
1439
            }
1440
        }
1441
    }
1442
1443
    /**
1444
     * @param array $params
1445
     * @param int   $ticketId
1446
     * @param int   $userId
1447
     *
1448
     * @return bool
1449
     */
1450
    public static function updateTicket(
1451
        $params,
1452
        $ticketId,
1453
        $userId
1454
    ) {
1455
        $now = api_get_utc_datetime();
1456
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1457
        $newParams = [
1458
            'priority_id' => isset($params['priority_id']) ? (int) $params['priority_id'] : '',
1459
            'status_id' => isset($params['status_id']) ? (int) $params['status_id'] : '',
1460
            'sys_lastedit_user_id' => (int) $userId,
1461
            'sys_lastedit_datetime' => $now,
1462
        ];
1463
        Database::update($table, $newParams, ['id = ? ' => $ticketId]);
1464
1465
        return true;
1466
    }
1467
1468
    /**
1469
     * @param int $status_id
1470
     * @param int $ticketId
1471
     * @param int $userId
1472
     *
1473
     * @return bool
1474
     */
1475
    public static function update_ticket_status(
1476
        $status_id,
1477
        $ticketId,
1478
        $userId
1479
    ) {
1480
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1481
1482
        $ticketId = (int) $ticketId;
1483
        $status_id = (int) $status_id;
1484
        $userId = (int) $userId;
1485
        $now = api_get_utc_datetime();
1486
1487
        $sql = "UPDATE $table_support_tickets
1488
                SET
1489
                    status_id = '$status_id',
1490
                    sys_lastedit_user_id ='$userId',
1491
                    sys_lastedit_datetime ='".$now."'
1492
                WHERE id ='$ticketId'";
1493
        $result = Database::query($sql);
1494
1495
        if (Database::affected_rows($result) > 0) {
1496
            self::sendNotification(
1497
                $ticketId,
1498
                get_lang('TicketUpdated'),
1499
                get_lang('TicketUpdated')
1500
            );
1501
1502
            return true;
1503
        }
1504
1505
        return false;
1506
    }
1507
1508
    /**
1509
     * @return mixed
1510
     */
1511
    public static function getNumberOfMessages()
1512
    {
1513
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1514
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1515
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1516
        $table_main_admin = Database::get_main_table(TABLE_MAIN_ADMIN);
1517
        $user_info = api_get_user_info();
1518
        $userId = $user_info['user_id'];
1519
        $sql = "SELECT COUNT(DISTINCT ticket.id) AS unread
1520
                FROM $table_support_tickets ticket,
1521
                $table_support_messages message ,
1522
                $table_main_user user
1523
                WHERE
1524
                    ticket.id = message.ticket_id AND
1525
                    message.status = 'NOL' AND
1526
                    user.user_id = message.sys_insert_user_id ";
1527
        if (!api_is_platform_admin()) {
1528
            $sql .= " AND ticket.request_user = '$userId'
1529
                      AND user_id IN (SELECT user_id FROM $table_main_admin)  ";
1530
        } else {
1531
            $sql .= " AND user_id NOT IN (SELECT user_id FROM $table_main_admin)
1532
                      AND ticket.status_id != '".self::STATUS_FORWARDED."'";
1533
        }
1534
        $sql .= "  AND ticket.project_id != '' ";
1535
        $res = Database::query($sql);
1536
        $obj = Database::fetch_object($res);
1537
1538
        return $obj->unread;
1539
    }
1540
1541
    /**
1542
     * @param int $ticketId
1543
     * @param int $userId
1544
     */
1545
    public static function send_alert($ticketId, $userId)
1546
    {
1547
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1548
        $now = api_get_utc_datetime();
1549
1550
        $ticketId = (int) $ticketId;
1551
        $userId = (int) $userId;
1552
1553
        $sql = "UPDATE $table_support_tickets SET
1554
                  priority_id = '".self::PRIORITY_HIGH."',
1555
                  sys_lastedit_user_id = $userId,
1556
                  sys_lastedit_datetime = '$now'
1557
                WHERE id = $ticketId";
1558
        Database::query($sql);
1559
    }
1560
1561
    /**
1562
     * @param int $ticketId
1563
     * @param int $userId
1564
     */
1565
    public static function close_ticket($ticketId, $userId)
1566
    {
1567
        $ticketId = (int) $ticketId;
1568
        $userId = (int) $userId;
1569
1570
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1571
        $now = api_get_utc_datetime();
1572
        $sql = "UPDATE $table_support_tickets SET
1573
                    status_id = '".self::STATUS_CLOSE."',
1574
                    sys_lastedit_user_id ='$userId',
1575
                    sys_lastedit_datetime ='".$now."',
1576
                    end_date ='$now'
1577
                WHERE id ='$ticketId'";
1578
        Database::query($sql);
1579
1580
        self::sendNotification(
1581
            $ticketId,
1582
            get_lang('TicketClosed'),
1583
            get_lang('TicketClosed')
1584
        );
1585
    }
1586
1587
    /**
1588
     * Close old tickets.
1589
     */
1590
    public static function close_old_tickets()
1591
    {
1592
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1593
        $now = api_get_utc_datetime();
1594
        $userId = api_get_user_id();
1595
        $sql = "UPDATE $table
1596
                SET
1597
                    status_id = '".self::STATUS_CLOSE."',
1598
                    sys_lastedit_user_id ='$userId',
1599
                    sys_lastedit_datetime ='$now',
1600
                    end_date = '$now'
1601
                WHERE
1602
                    DATEDIFF('$now', sys_lastedit_datetime) > 7 AND
1603
                    status_id != '".self::STATUS_CLOSE."' AND
1604
                    status_id != '".self::STATUS_NEW."' AND
1605
                    status_id != '".self::STATUS_FORWARDED."'";
1606
        Database::query($sql);
1607
    }
1608
1609
    /**
1610
     * @param int $ticketId
1611
     *
1612
     * @return array
1613
     */
1614
    public static function get_assign_log($ticketId)
1615
    {
1616
        $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
1617
        $ticketId = (int) $ticketId;
1618
1619
        $sql = "SELECT * FROM $table
1620
                WHERE ticket_id = $ticketId
1621
                ORDER BY assigned_date DESC";
1622
        $result = Database::query($sql);
1623
        $history = [];
1624
        $webpath = api_get_path(WEB_PATH);
1625
        while ($row = Database::fetch_assoc($result)) {
1626
            if ($row['user_id'] != 0) {
1627
                $assignuser = api_get_user_info($row['user_id']);
1628
                $row['assignuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['user_id'].'"  target="_blank">'.
1629
                $assignuser['username'].'</a>';
1630
            } else {
1631
                $row['assignuser'] = get_lang('Unassign');
1632
            }
1633
            $row['assigned_date'] = Display::dateToStringAgoAndLongDate($row['assigned_date']);
1634
            $insertuser = api_get_user_info($row['sys_insert_user_id']);
1635
            $row['insertuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['sys_insert_user_id'].'"  target="_blank">'.
1636
                $insertuser['username'].'</a>';
1637
            $history[] = $row;
1638
        }
1639
1640
        return $history;
1641
    }
1642
1643
    /**
1644
     * @param $from
1645
     * @param $number_of_items
1646
     * @param $column
1647
     * @param $direction
1648
     * @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...
1649
     *
1650
     * @return array
1651
     */
1652
    public static function export_tickets_by_user_id(
1653
        $from,
1654
        $number_of_items,
1655
        $column,
1656
        $direction,
1657
        $userId = null
1658
    ) {
1659
        $from = (int) $from;
1660
        $number_of_items = (int) $number_of_items;
1661
        $table_support_category = Database::get_main_table(
1662
            TABLE_TICKET_CATEGORY
1663
        );
1664
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1665
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1666
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1667
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1668
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1669
1670
        if (is_null($direction)) {
1671
            $direction = 'DESC';
1672
        }
1673
        if (is_null($userId) || $userId == 0) {
1674
            $userId = api_get_user_id();
1675
        }
1676
1677
        $sql = "SELECT
1678
                    ticket.code,
1679
                    ticket.sys_insert_datetime,
1680
                    ticket.sys_lastedit_datetime,
1681
                    cat.name as category,
1682
                    CONCAT(user.lastname,' ', user.firstname) AS fullname,
1683
                    status.name as status,
1684
                    ticket.total_messages as messages,
1685
                    ticket.assigned_last_user as responsable
1686
                FROM $table_support_tickets ticket,
1687
                $table_support_category cat ,
1688
                $table_support_priority priority,
1689
                $table_support_status status ,
1690
                $table_main_user user
1691
                WHERE
1692
                    cat.id = ticket.category_id
1693
                    AND ticket.priority_id = priority.id
1694
                    AND ticket.status_id = status.id
1695
                    AND user.user_id = ticket.request_user ";
1696
        // Search simple
1697
        if (isset($_GET['submit_simple'])) {
1698
            if ($_GET['keyword'] !== '') {
1699
                $keyword = Database::escape_string(trim($_GET['keyword']));
1700
                $sql .= " AND (ticket.code = '$keyword'
1701
                          OR user.firstname LIKE '%$keyword%'
1702
                          OR user.lastname LIKE '%$keyword%'
1703
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword%'
1704
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword%'
1705
                          OR user.username LIKE '%$keyword%')  ";
1706
            }
1707
        }
1708
        // Search advanced
1709
        if (isset($_GET['submit_advanced'])) {
1710
            $keyword_category = Database::escape_string(
1711
                trim($_GET['keyword_category'])
1712
            );
1713
            $keyword_request_user = Database::escape_string(
1714
                trim($_GET['keyword_request_user'])
1715
            );
1716
            $keywordAssignedTo = (int) $_GET['keyword_assigned_to'];
1717
            $keyword_start_date_start = Database::escape_string(
1718
                trim($_GET['keyword_start_date_start'])
1719
            );
1720
            $keyword_start_date_end = Database::escape_string(
1721
                trim($_GET['keyword_start_date_end'])
1722
            );
1723
            $keyword_status = Database::escape_string(
1724
                trim($_GET['keyword_status'])
1725
            );
1726
            $keyword_source = Database::escape_string(
1727
                trim($_GET['keyword_source'])
1728
            );
1729
            $keyword_priority = Database::escape_string(
1730
                trim($_GET['keyword_priority'])
1731
            );
1732
            $keyword_range = Database::escape_string(
1733
                trim($_GET['keyword_dates'])
1734
            );
1735
            $keyword_unread = Database::escape_string(
1736
                trim($_GET['keyword_unread'])
1737
            );
1738
            $keyword_course = Database::escape_string(
1739
                trim($_GET['keyword_course'])
1740
            );
1741
1742
            if ($keyword_category != '') {
1743
                $sql .= " AND ticket.category_id = '$keyword_category'  ";
1744
            }
1745
            if ($keyword_request_user != '') {
1746
                $sql .= " AND (ticket.request_user = '$keyword_request_user'
1747
                          OR user.firstname LIKE '%$keyword_request_user%'
1748
                          OR user.official_code LIKE '%$keyword_request_user%'
1749
                          OR user.lastname LIKE '%$keyword_request_user%'
1750
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword_request_user%'
1751
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword_request_user%'
1752
                          OR user.username LIKE '%$keyword_request_user%') ";
1753
            }
1754
            if (!empty($keywordAssignedTo)) {
1755
                $sql .= " AND ticket.assigned_last_user = $keywordAssignedTo ";
1756
            }
1757
            if ($keyword_status != '') {
1758
                $sql .= " AND ticket.status_id = '$keyword_status'  ";
1759
            }
1760
            if ($keyword_range == '' && $keyword_start_date_start != '') {
1761
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1762
            }
1763
            if ($keyword_range == '1' && $keyword_start_date_start != '' && $keyword_start_date_end != '') {
1764
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1765
                          AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1766
            }
1767
            if ($keyword_priority != '') {
1768
                $sql .= " AND ticket.priority_id = '$keyword_priority'  ";
1769
            }
1770
            if ($keyword_source != '') {
1771
                $sql .= " AND ticket.source = '$keyword_source' ";
1772
            }
1773
            if ($keyword_priority != '') {
1774
                $sql .= " AND ticket.priority_id = '$keyword_priority' ";
1775
            }
1776
            if ($keyword_course != '') {
1777
                $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1778
                $sql .= " AND ticket.course_id IN ( ";
1779
                $sql .= "SELECT id
1780
                         FROM $course_table
1781
                         WHERE (title LIKE '%$keyword_course%'
1782
                         OR code LIKE '%$keyword_course%'
1783
                         OR visual_code LIKE '%$keyword_course%' )) ";
1784
            }
1785
            if ($keyword_unread == 'yes') {
1786
                $sql .= " AND ticket.id IN (
1787
                          SELECT ticket.id
1788
                          FROM $table_support_tickets ticket,
1789
                          $table_support_messages message,
1790
                          $table_main_user user
1791
                          WHERE ticket.id = message.ticket_id
1792
                          AND message.status = 'NOL'
1793
                          AND message.sys_insert_user_id = user.user_id
1794
                          AND user.status != 1   AND ticket.status_id != '".self::STATUS_FORWARDED."'
1795
                          GROUP BY ticket.id)";
1796
            } else {
1797
                if ($keyword_unread == 'no') {
1798
                    $sql .= " AND ticket.id NOT IN (
1799
                              SELECT ticket.id
1800
                              FROM  $table_support_tickets ticket,
1801
                              $table_support_messages message,
1802
                              $table_main_user user
1803
                              WHERE ticket.id = message.ticket_id
1804
                              AND message.status = 'NOL'
1805
                              AND message.sys_insert_user_id = user.user_id
1806
                              AND user.status != 1
1807
                              AND ticket.status_id != '".self::STATUS_FORWARDED."'
1808
                             GROUP BY ticket.id)";
1809
                }
1810
            }
1811
        }
1812
1813
        $sql .= " LIMIT $from,$number_of_items";
1814
1815
        $result = Database::query($sql);
1816
        $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...
1817
            utf8_decode('Ticket#'),
1818
            utf8_decode('Fecha'),
1819
            utf8_decode('Fecha Edicion'),
1820
            utf8_decode('Categoria'),
1821
            utf8_decode('Usuario'),
1822
            utf8_decode('Estado'),
1823
            utf8_decode('Mensajes'),
1824
            utf8_decode('Responsable'),
1825
            utf8_decode('Programa'),
1826
        ];
1827
1828
        while ($row = Database::fetch_assoc($result)) {
1829
            if ($row['responsable'] != 0) {
1830
                $row['responsable'] = api_get_user_info($row['responsable']);
1831
                $row['responsable'] = $row['responsable']['firstname'].' '.$row['responsable']['lastname'];
1832
            }
1833
            $row['sys_insert_datetime'] = api_format_date(
1834
                $row['sys_insert_datetime'],
1835
                '%d/%m/%y - %I:%M:%S %p'
1836
            );
1837
            $row['sys_lastedit_datetime'] = api_format_date(
1838
                $row['sys_lastedit_datetime'],
1839
                '%d/%m/%y - %I:%M:%S %p'
1840
            );
1841
            $row['category'] = utf8_decode($row['category']);
1842
            $row['programa'] = utf8_decode($row['fullname']);
1843
            $row['fullname'] = utf8_decode($row['fullname']);
1844
            $row['responsable'] = utf8_decode($row['responsable']);
1845
            $tickets[] = $row;
1846
        }
1847
1848
        return $tickets;
1849
    }
1850
1851
    /**
1852
     * @param string $url
1853
     * @param int    $projectId
1854
     *
1855
     * @return FormValidator
1856
     */
1857
    public static function getCategoryForm($url, $projectId)
1858
    {
1859
        $form = new FormValidator('category', 'post', $url);
1860
        $form->addText('name', get_lang('Name'));
1861
        $form->addHtmlEditor('description', get_lang('Description'));
1862
        $form->addHidden('project_id', $projectId);
1863
        $form->addButtonUpdate(get_lang('Save'));
1864
1865
        return $form;
1866
    }
1867
1868
    /**
1869
     * @return array
1870
     */
1871
    public static function getStatusList()
1872
    {
1873
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->findAll();
1874
1875
        $list = [];
1876
        /** @var Status $row */
1877
        foreach ($items as $row) {
1878
            $list[$row->getId()] = $row->getName();
1879
        }
1880
1881
        return $list;
1882
    }
1883
1884
    /**
1885
     * @param array $criteria
1886
     *
1887
     * @return array
1888
     */
1889
    public static function getTicketsFromCriteria($criteria)
1890
    {
1891
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Ticket')->findBy($criteria);
1892
1893
        $list = [];
1894
        /** @var Ticket $row */
1895
        foreach ($items as $row) {
1896
            $list[$row->getId()] = $row->getCode();
1897
        }
1898
1899
        return $list;
1900
    }
1901
1902
    /**
1903
     * @param string $code
1904
     *
1905
     * @return int
1906
     */
1907
    public static function getStatusIdFromCode($code)
1908
    {
1909
        $item = Database::getManager()
1910
            ->getRepository('ChamiloTicketBundle:Status')
1911
            ->findOneBy(['code' => $code])
1912
        ;
1913
1914
        if ($item) {
1915
            return $item->getId();
1916
        }
1917
1918
        return 0;
1919
    }
1920
1921
    /**
1922
     * @return array
1923
     */
1924
    public static function getPriorityList()
1925
    {
1926
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->findAll();
1927
1928
        $list = [];
1929
        /** @var Priority $row */
1930
        foreach ($projects as $row) {
1931
            $list[$row->getId()] = $row->getName();
1932
        }
1933
1934
        return $list;
1935
    }
1936
1937
    /**
1938
     * @return array
1939
     */
1940
    public static function getProjects()
1941
    {
1942
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Project')->findAll();
1943
1944
        $list = [];
1945
        /** @var Project $row */
1946
        foreach ($projects as $row) {
1947
            $list[] = [
1948
                'id' => $row->getId(),
1949
                '0' => $row->getId(),
1950
                '1' => $row->getName(),
1951
                '2' => $row->getDescription(),
1952
                '3' => $row->getId(),
1953
            ];
1954
        }
1955
1956
        return $list;
1957
    }
1958
1959
    /**
1960
     * @return array
1961
     */
1962
    public static function getProjectsSimple()
1963
    {
1964
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Project')->findAll();
1965
1966
        $list = [];
1967
        /** @var Project $row */
1968
        foreach ($projects as $row) {
1969
            $list[] = [
1970
                'id' => $row->getId(),
1971
                '0' => $row->getId(),
1972
                '1' => Display::url(
1973
                    $row->getName(),
1974
                    api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id='.$row->getId()
1975
                ),
1976
                '2' => $row->getDescription(),
1977
            ];
1978
        }
1979
1980
        return $list;
1981
    }
1982
1983
    /**
1984
     * @return int
1985
     */
1986
    public static function getProjectsCount()
1987
    {
1988
        $count = Database::getManager()->getRepository('ChamiloTicketBundle:Project')->createQueryBuilder('p')
1989
            ->select('COUNT(p.id)')
1990
            ->getQuery()
1991
            ->getSingleScalarResult();
1992
1993
        return $count;
1994
    }
1995
1996
    /**
1997
     * @param array $params
1998
     */
1999
    public static function addProject($params)
2000
    {
2001
        $project = new Project();
2002
        $project->setName($params['name']);
2003
        $project->setDescription($params['description']);
2004
        $project->setInsertUserId(api_get_user_id());
2005
2006
        Database::getManager()->persist($project);
2007
        Database::getManager()->flush();
2008
    }
2009
2010
    /**
2011
     * @param int $id
2012
     *
2013
     * @return Project
2014
     */
2015
    public static function getProject($id)
2016
    {
2017
        return Database::getManager()->getRepository('ChamiloTicketBundle:Project')->find($id);
2018
    }
2019
2020
    /**
2021
     * @param int   $id
2022
     * @param array $params
2023
     */
2024
    public static function updateProject($id, $params)
2025
    {
2026
        $project = self::getProject($id);
2027
        $project->setName($params['name']);
2028
        $project->setDescription($params['description']);
2029
        $project->setLastEditDateTime(new DateTime($params['sys_lastedit_datetime']));
2030
        $project->setLastEditUserId($params['sys_lastedit_user_id']);
2031
2032
        Database::getManager()->merge($project);
2033
        Database::getManager()->flush();
2034
    }
2035
2036
    /**
2037
     * @param int $id
2038
     */
2039
    public static function deleteProject($id)
2040
    {
2041
        $project = self::getProject($id);
2042
        if ($project) {
0 ignored issues
show
introduced by
$project is of type Chamilo\TicketBundle\Entity\Project, thus it always evaluated to true.
Loading history...
2043
            Database::getManager()->remove($project);
2044
            Database::getManager()->flush();
2045
        }
2046
    }
2047
2048
    /**
2049
     * @param string $url
2050
     *
2051
     * @return FormValidator
2052
     */
2053
    public static function getProjectForm($url)
2054
    {
2055
        $form = new FormValidator('project', 'post', $url);
2056
        $form->addText('name', get_lang('Name'));
2057
        $form->addHtmlEditor('description', get_lang('Description'));
2058
        $form->addButtonUpdate(get_lang('Save'));
2059
2060
        return $form;
2061
    }
2062
2063
    /**
2064
     * @return array
2065
     */
2066
    public static function getStatusAdminList()
2067
    {
2068
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->findAll();
2069
2070
        $list = [];
2071
        /** @var Status $row */
2072
        foreach ($items as $row) {
2073
            $list[] = [
2074
                'id' => $row->getId(),
2075
                'code' => $row->getCode(),
2076
                '0' => $row->getId(),
2077
                '1' => $row->getName(),
2078
                '2' => $row->getDescription(),
2079
                '3' => $row->getId(),
2080
            ];
2081
        }
2082
2083
        return $list;
2084
    }
2085
2086
    /**
2087
     * @return array
2088
     */
2089
    public static function getStatusSimple()
2090
    {
2091
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->findAll();
2092
2093
        $list = [];
2094
        /** @var Project $row */
2095
        foreach ($projects as $row) {
2096
            $list[] = [
2097
                'id' => $row->getId(),
2098
                '0' => $row->getId(),
2099
                '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

2099
                '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...
2100
                '2' => $row->getDescription(),
2101
            ];
2102
        }
2103
2104
        return $list;
2105
    }
2106
2107
    /**
2108
     * @return int
2109
     */
2110
    public static function getStatusCount()
2111
    {
2112
        $count = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->createQueryBuilder('p')
2113
            ->select('COUNT(p.id)')
2114
            ->getQuery()
2115
            ->getSingleScalarResult();
2116
2117
        return $count;
2118
    }
2119
2120
    /**
2121
     * @param array $params
2122
     */
2123
    public static function addStatus($params)
2124
    {
2125
        $item = new Status();
2126
        $item->setCode(URLify::filter($params['name']));
2127
        $item->setName($params['name']);
2128
        $item->setDescription($params['description']);
2129
2130
        Database::getManager()->persist($item);
2131
        Database::getManager()->flush();
2132
    }
2133
2134
    /**
2135
     * @param $id
2136
     *
2137
     * @return Project
2138
     */
2139
    public static function getStatus($id)
2140
    {
2141
        return Database::getManager()->getRepository('ChamiloTicketBundle:Status')->find($id);
2142
    }
2143
2144
    /**
2145
     * @param int   $id
2146
     * @param array $params
2147
     */
2148
    public static function updateStatus($id, $params)
2149
    {
2150
        $item = self::getStatus($id);
2151
        $item->setName($params['name']);
2152
        $item->setDescription($params['description']);
2153
2154
        Database::getManager()->merge($item);
2155
        Database::getManager()->flush();
2156
    }
2157
2158
    /**
2159
     * @param int $id
2160
     */
2161
    public static function deleteStatus($id)
2162
    {
2163
        $item = self::getStatus($id);
2164
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\TicketBundle\Entity\Project, thus it always evaluated to true.
Loading history...
2165
            Database::getManager()->remove($item);
2166
            Database::getManager()->flush();
2167
        }
2168
    }
2169
2170
    /**
2171
     * @param string $url
2172
     *
2173
     * @return FormValidator
2174
     */
2175
    public static function getStatusForm($url)
2176
    {
2177
        $form = new FormValidator('status', 'post', $url);
2178
        $form->addText('name', get_lang('Name'));
2179
        $form->addHtmlEditor('description', get_lang('Description'));
2180
        $form->addButtonUpdate(get_lang('Save'));
2181
2182
        return $form;
2183
    }
2184
2185
    /**
2186
     * @return array
2187
     */
2188
    public static function getPriorityAdminList()
2189
    {
2190
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->findAll();
2191
2192
        $list = [];
2193
        /** @var Status $row */
2194
        foreach ($items as $row) {
2195
            $list[] = [
2196
                'id' => $row->getId(),
2197
                'code' => $row->getCode(),
2198
                '0' => $row->getId(),
2199
                '1' => $row->getName(),
2200
                '2' => $row->getDescription(),
2201
                '3' => $row->getId(),
2202
            ];
2203
        }
2204
2205
        return $list;
2206
    }
2207
2208
    /**
2209
     * @return array
2210
     */
2211
    public static function getPrioritySimple()
2212
    {
2213
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->findAll();
2214
2215
        $list = [];
2216
        /** @var Priority $row */
2217
        foreach ($projects as $row) {
2218
            $list[] = [
2219
                'id' => $row->getId(),
2220
                '0' => $row->getId(),
2221
                '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

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