Passed
Push — preprodparkur ( a600ab...f4828c )
by Angel Fernando Quiroz
20:49 queued 10:44
created

TicketManager::add()   F

Complexity

Conditions 36
Paths > 20000

Size

Total Lines 288
Code Lines 173

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 36
eloc 173
c 1
b 0
f 0
nc 231391
nop 15
dl 0
loc 288
rs 0

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
    const PRIORITY_NORMAL = 'NRM';
18
    const PRIORITY_HIGH = 'HGH';
19
    const PRIORITY_LOW = 'LOW';
20
21
    const SOURCE_EMAIL = 'MAI';
22
    const SOURCE_PHONE = 'TEL';
23
    const SOURCE_PLATFORM = 'PLA';
24
    const SOURCE_PRESENTIAL = 'PRE';
25
26
    const STATUS_NEW = 'NAT';
27
    const STATUS_PENDING = 'PND';
28
    const STATUS_UNCONFIRMED = 'XCF';
29
    const STATUS_CLOSE = 'CLS';
30
    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
        if (!empty($exerciseId)) {
372
            $params['exercise_id'] = $exerciseId;
373
        }
374
375
        if (!empty($lpId)) {
376
            $params['lp_id'] = $lpId;
377
        }
378
379
        if (!empty($course_id)) {
380
            $params['course_id'] = $course_id;
381
        }
382
383
        if (!empty($sessionId)) {
384
            $params['session_id'] = $sessionId;
385
        }
386
        $ticketId = Database::insert($table_support_tickets, $params);
387
388
        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...
389
            $ticket_code = 'A'.str_pad($ticketId, 11, '0', STR_PAD_LEFT);
390
            $titleCreated = sprintf(
391
                get_lang('TicketXCreated'),
392
                $ticket_code
393
            );
394
395
            Display::addFlash(Display::return_message(
396
                $titleCreated,
397
                'normal',
398
                false
399
            ));
400
401
            if ($assignedUserId != 0) {
402
                self::assignTicketToUser(
403
                    $ticketId,
404
                    $assignedUserId
405
                );
406
407
                Display::addFlash(Display::return_message(
408
                    sprintf(
409
                        get_lang('TicketXAssignedToUserX'),
410
                        $ticket_code,
411
                        $assignedUserInfo['complete_name']
412
                    ),
413
                    'normal',
414
                    false
415
                ));
416
            }
417
418
            if (!empty($fileAttachments)) {
419
                $attachmentCount = 0;
420
                foreach ($fileAttachments as $attach) {
421
                    if (!empty($attach['tmp_name'])) {
422
                        $attachmentCount++;
423
                    }
424
                }
425
                if ($attachmentCount > 0) {
426
                    self::insertMessage(
427
                        $ticketId,
428
                        '',
429
                        '',
430
                        $fileAttachments,
431
                        $currentUserId
432
                    );
433
                }
434
            }
435
436
            // Update code
437
            $sql = "UPDATE $table_support_tickets
438
                    SET code = '$ticket_code'
439
                    WHERE id = '$ticketId'";
440
            Database::query($sql);
441
442
            // Update total
443
            $sql = "UPDATE $table_support_category
444
                    SET total_tickets = total_tickets + 1
445
                    WHERE id = $category_id";
446
            Database::query($sql);
447
448
            $helpDeskMessage =
449
                '<table>
450
                        <tr>
451
                            <td width="100px"><b>'.get_lang('User').'</b></td>
452
                            <td width="400px">'.$currentUserInfo['complete_name'].'</td>
453
                        </tr>
454
                        <tr>
455
                            <td width="100px"><b>'.get_lang('Username').'</b></td>
456
                            <td width="400px">'.$currentUserInfo['username'].'</td>
457
                        </tr>
458
                        <tr>
459
                            <td width="100px"><b>'.get_lang('Email').'</b></td>
460
                            <td width="400px">'.$currentUserInfo['email'].'</td>
461
                        </tr>
462
                        <tr>
463
                            <td width="100px"><b>'.get_lang('Phone').'</b></td>
464
                            <td width="400px">'.$currentUserInfo['phone'].'</td>
465
                        </tr>
466
                        <tr>
467
                            <td width="100px"><b>'.get_lang('Date').'</b></td>
468
                            <td width="400px">'.api_convert_and_format_date($now, DATE_TIME_FORMAT_LONG).'</td>
469
                        </tr>
470
                        <tr>
471
                            <td width="100px"><b>'.get_lang('Title').'</b></td>
472
                            <td width="400px">'.Security::remove_XSS($subject).'</td>
473
                        </tr>
474
                        <tr>
475
                            <td width="100px"><b>'.get_lang('Description').'</b></td>
476
                            <td width="400px">'.Security::remove_XSS($content).'</td>
477
                        </tr>
478
                    </table>';
479
480
            if ($assignedUserId != 0) {
481
                $href = api_get_path(WEB_CODE_PATH).'/ticket/ticket_details.php?ticket_id='.$ticketId;
482
                $helpDeskMessage .= sprintf(
483
                    get_lang('TicketAssignedToXCheckZAtLinkY'),
484
                    $assignedUserInfo['complete_name'],
485
                    $href,
486
                    $ticketId
487
                );
488
            }
489
490
            if (empty($category_id)) {
491
                if (api_get_setting('ticket_send_warning_to_all_admins') === 'true') {
492
                    $warningSubject = sprintf(
493
                        get_lang('TicketXCreatedWithNoCategory'),
494
                        $ticket_code
495
                    );
496
                    Display::addFlash(Display::return_message($warningSubject));
497
498
                    $admins = UserManager::get_all_administrators();
499
                    foreach ($admins as $userId => $data) {
500
                        if ($data['active']) {
501
                            MessageManager::send_message_simple(
502
                                $userId,
503
                                $warningSubject,
504
                                $helpDeskMessage
505
                            );
506
                        }
507
                    }
508
                }
509
            } else {
510
                $categoryInfo = self::getCategory($category_id);
511
                $usersInCategory = self::getUsersInCategory($category_id);
512
513
                $message = '<h2>'.get_lang('TicketInformation').'</h2><br />'.$helpDeskMessage;
514
515
                if (api_get_setting('ticket_warn_admin_no_user_in_category') === 'true') {
516
                    if (empty($usersInCategory)) {
517
                        $subject = sprintf(
518
                            get_lang('WarningCategoryXDoesntHaveUsers'),
519
                            $categoryInfo['name']
520
                        );
521
522
                        if (api_get_setting('ticket_send_warning_to_all_admins') === 'true') {
523
                            Display::addFlash(Display::return_message(
524
                                sprintf(
525
                                    get_lang('CategoryWithNoUserNotificationSentToAdmins'),
526
                                    $categoryInfo['name']
527
                                ),
528
                                null,
529
                                false
530
                            ));
531
532
                            $admins = UserManager::get_all_administrators();
533
                            foreach ($admins as $userId => $data) {
534
                                if ($data['active']) {
535
                                    self::sendNotification(
536
                                        $ticketId,
537
                                        $subject,
538
                                        $message,
539
                                        $userId
540
                                    );
541
                                }
542
                            }
543
                        } else {
544
                            Display::addFlash(Display::return_message($subject));
545
                        }
546
                    }
547
                }
548
549
                // Send notification to all users
550
                if (!empty($usersInCategory)) {
551
                    foreach ($usersInCategory as $data) {
552
                        if ($data['user_id']) {
553
                            self::sendNotification(
554
                                $ticketId,
555
                                $subject,
556
                                $message,
557
                                $data['user_id']
558
                            );
559
                        }
560
                    }
561
                }
562
            }
563
564
            if (!empty($personalEmail)) {
565
                api_mail_html(
566
                    get_lang('VirtualSupport'),
567
                    $personalEmail,
568
                    get_lang('IncidentResentToVirtualSupport'),
569
                    $helpDeskMessage
570
                );
571
            }
572
573
            self::sendNotification(
574
                $ticketId,
575
                $titleCreated,
576
                $helpDeskMessage
577
            );
578
579
            return true;
580
        }
581
582
        return false;
583
    }
584
585
    /**
586
     * Assign ticket to admin.
587
     *
588
     * @param int $ticketId
589
     * @param int $userId
590
     *
591
     * @return bool
592
     */
593
    public static function assignTicketToUser(
594
        $ticketId,
595
        $userId
596
    ) {
597
        $ticketId = (int) $ticketId;
598
        $userId = (int) $userId;
599
600
        if (empty($ticketId)) {
601
            return false;
602
        }
603
604
        $ticket = self::get_ticket_detail_by_id($ticketId);
605
606
        if ($ticket) {
607
            $table = Database::get_main_table(TABLE_TICKET_TICKET);
608
            $sql = "UPDATE $table
609
                    SET assigned_last_user = $userId
610
                    WHERE id = $ticketId";
611
            Database::query($sql);
612
613
            $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
614
            $params = [
615
                'ticket_id' => $ticketId,
616
                'user_id' => $userId,
617
                'sys_insert_user_id' => api_get_user_id(),
618
                'assigned_date' => api_get_utc_datetime(),
619
            ];
620
            Database::insert($table, $params);
621
622
            return true;
623
        } else {
624
            return false;
625
        }
626
    }
627
628
    /**
629
     * Insert message between Users and Admins.
630
     *
631
     * @param int    $ticketId
632
     * @param string $subject
633
     * @param string $content
634
     * @param array  $fileAttachments
635
     * @param int    $userId
636
     * @param string $status
637
     * @param bool   $sendConfirmation
638
     *
639
     * @return bool
640
     */
641
    public static function insertMessage(
642
        $ticketId,
643
        $subject,
644
        $content,
645
        $fileAttachments,
646
        $userId,
647
        $status = 'NOL',
648
        $sendConfirmation = false
649
    ) {
650
        $ticketId = (int) $ticketId;
651
        $userId = (int) $userId;
652
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
653
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
654
        if ($sendConfirmation) {
655
            $form =
656
                '<form action="ticket_details.php?ticket_id='.$ticketId.'" id="confirmticket" method="POST" >
657
                     <p>'.get_lang('TicketWasThisAnswerSatisfying').'</p>
658
                     <button class="btn btn-primary responseyes" name="response" id="responseyes" value="1">'.
659
                get_lang('Yes').'</button>
660
                     <button class="btn btn-danger responseno" name="response" id="responseno" value="0">'.
661
                get_lang('No').'</button>
662
                 </form>';
663
            $content .= $form;
664
        }
665
666
        $now = api_get_utc_datetime();
667
668
        $params = [
669
            'ticket_id' => $ticketId,
670
            'subject' => $subject,
671
            'message' => $content,
672
            'ip_address' => api_get_real_ip(),
673
            'sys_insert_user_id' => $userId,
674
            'sys_insert_datetime' => $now,
675
            'sys_lastedit_user_id' => $userId,
676
            'sys_lastedit_datetime' => $now,
677
            'status' => $status,
678
        ];
679
        $messageId = Database::insert($table_support_messages, $params);
680
        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...
681
            // update_total_message
682
            $sql = "UPDATE $table_support_tickets
683
                    SET 
684
                        sys_lastedit_user_id = $userId,
685
                        sys_lastedit_datetime = '$now',
686
                        total_messages = (
687
                            SELECT COUNT(*) as total_messages
688
                            FROM $table_support_messages
689
                            WHERE ticket_id = $ticketId
690
                        )
691
                    WHERE id = $ticketId ";
692
            Database::query($sql);
693
694
            if (is_array($fileAttachments)) {
695
                foreach ($fileAttachments as $file_attach) {
696
                    if ($file_attach['error'] == 0) {
697
                        self::saveMessageAttachmentFile(
698
                            $file_attach,
699
                            $ticketId,
700
                            $messageId
701
                        );
702
                    } else {
703
                        if ($file_attach['error'] != UPLOAD_ERR_NO_FILE) {
704
                            return false;
705
                        }
706
                    }
707
                }
708
            }
709
        }
710
711
        return true;
712
    }
713
714
    /**
715
     * Attachment files when a message is sent.
716
     *
717
     * @param $file_attach
718
     * @param $ticketId
719
     * @param $message_id
720
     *
721
     * @return bool
722
     */
723
    public static function saveMessageAttachmentFile(
724
        $file_attach,
725
        $ticketId,
726
        $message_id
727
    ) {
728
        $now = api_get_utc_datetime();
729
        $userId = api_get_user_id();
730
        $ticketId = (int) $ticketId;
731
732
        $new_file_name = add_ext_on_mime(
733
            stripslashes($file_attach['name']),
734
            $file_attach['type']
735
        );
736
        $table_support_message_attachments = Database::get_main_table(TABLE_TICKET_MESSAGE_ATTACHMENTS);
737
        if (!filter_extension($new_file_name)) {
738
            echo Display::return_message(
739
                get_lang('UplUnableToSaveFileFilteredExtension'),
740
                'error'
741
            );
742
        } else {
743
            $result = api_upload_file('ticket_attachment', $file_attach, $ticketId);
744
            if ($result) {
0 ignored issues
show
introduced by
$result is a non-empty array, thus is always true.
Loading history...
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...
745
                $safe_file_name = Database::escape_string($new_file_name);
746
                $safe_new_file_name = Database::escape_string($result['path_to_save']);
747
                $sql = "INSERT INTO $table_support_message_attachments (
748
                        filename,
749
                        path,
750
                        ticket_id,
751
                        message_id,
752
                        size,
753
                        sys_insert_user_id,
754
                        sys_insert_datetime,
755
                        sys_lastedit_user_id,
756
                        sys_lastedit_datetime
757
                    ) VALUES (
758
                        '$safe_file_name',
759
                        '$safe_new_file_name',
760
                        '$ticketId',
761
                        '$message_id',
762
                        '".$file_attach['size']."',
763
                        '$userId',
764
                        '$now',
765
                        '$userId',
766
                        '$now'
767
                    )";
768
                Database::query($sql);
769
770
                return true;
771
            }
772
        }
773
    }
774
775
    /**
776
     * Get tickets by userId.
777
     *
778
     * @param int $from
779
     * @param int $number_of_items
780
     * @param $column
781
     * @param $direction
782
     *
783
     * @return array
784
     */
785
    public static function getTicketsByCurrentUser(
786
        $from,
787
        $number_of_items,
788
        $column,
789
        $direction
790
    ) {
791
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
792
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
793
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
794
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
795
        $direction = !empty($direction) ? $direction : 'DESC';
796
        $userId = api_get_user_id();
797
        $userInfo = api_get_user_info($userId);
798
799
        if (empty($userInfo)) {
800
            return [];
801
        }
802
        $isAdmin = UserManager::is_admin($userId);
803
804
        if (!isset($_GET['project_id'])) {
805
            return [];
806
        }
807
808
        switch ($column) {
809
            case 0:
810
                $column = 'ticket_id';
811
                break;
812
            case 1:
813
                $column = 'status_name';
814
                break;
815
            case 2:
816
                $column = 'start_date';
817
                break;
818
            case 3:
819
                $column = 'sys_lastedit_datetime';
820
                break;
821
            case 4:
822
                $column = 'category_name';
823
                break;
824
            case 5:
825
                $column = 'sys_insert_user_id';
826
                break;
827
            case 6:
828
                $column = 'assigned_last_user';
829
                break;
830
            case 7:
831
                $column = 'total_messages';
832
                break;
833
            case 8:
834
                $column = 'subject';
835
                break;
836
            default:
837
                $column = 'ticket_id';
838
        }
839
840
        $sql = "SELECT DISTINCT 
841
                ticket.*,
842
                ticket.id ticket_id,
843
                status.name AS status_name,
844
                ticket.start_date,
845
                ticket.sys_lastedit_datetime,
846
                cat.name AS category_name,
847
                priority.name AS priority_name,                           
848
                ticket.total_messages AS total_messages,
849
                ticket.message AS message,
850
                ticket.subject AS subject,
851
                ticket.assigned_last_user
852
            FROM $table_support_tickets ticket 
853
            INNER JOIN $table_support_category cat
854
            ON (cat.id = ticket.category_id)
855
            INNER JOIN $table_support_priority priority
856
            ON (ticket.priority_id = priority.id)
857
            INNER JOIN $table_support_status status
858
            ON (ticket.status_id = status.id)
859
            WHERE 1=1                                
860
        ";
861
862
        $projectId = (int) $_GET['project_id'];
863
        $userIsAllowInProject = self::userIsAllowInProject($userInfo, $projectId);
864
865
        // Check if a role was set to the project
866
        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...
867
            $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
868
        }
869
870
        // Search simple
871
        if (isset($_GET['submit_simple']) && $_GET['keyword'] != '') {
872
            $keyword = Database::escape_string(trim($_GET['keyword']));
873
            $sql .= " AND (
874
                      ticket.id LIKE '%$keyword%' OR
875
                      ticket.code LIKE '%$keyword%' OR
876
                      ticket.subject LIKE '%$keyword%' OR
877
                      ticket.message LIKE '%$keyword%' OR
878
                      ticket.keyword LIKE '%$keyword%' OR
879
                      ticket.source LIKE '%$keyword%' OR
880
                      cat.name LIKE '%$keyword%' OR
881
                      status.name LIKE '%$keyword%' OR
882
                      priority.name LIKE '%$keyword%' OR
883
                      ticket.personal_email LIKE '%$keyword%'                          
884
            )";
885
        }
886
887
        $keywords = [
888
            'project_id' => 'ticket.project_id',
889
            'keyword_category' => 'ticket.category_id',
890
            'keyword_assigned_to' => 'ticket.assigned_last_user',
891
            'keyword_source' => 'ticket.source ',
892
            'keyword_status' => 'ticket.status_id',
893
            'keyword_priority' => 'ticket.priority_id',
894
        ];
895
896
        foreach ($keywords as $keyword => $label) {
897
            if (isset($_GET[$keyword])) {
898
                $data = Database::escape_string(trim($_GET[$keyword]));
899
                if (!empty($data)) {
900
                    $sql .= " AND $label = '$data' ";
901
                }
902
            }
903
        }
904
905
        // Search advanced
906
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
907
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
908
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
909
        $keyword_range = !empty($keyword_start_date_start) && !empty($keyword_start_date_end);
910
911
        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...
912
            $sql .= " AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start' ";
913
        }
914
        if ($keyword_range && $keyword_start_date_start != '' && $keyword_start_date_end != '') {
915
            $sql .= " AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
916
                      AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
917
        }
918
919
        if ($keyword_course != '') {
920
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
921
            $sql .= " AND ticket.course_id IN ( 
922
                     SELECT id FROM $course_table
923
                     WHERE (
924
                        title LIKE '%$keyword_course%' OR 
925
                        code LIKE '%$keyword_course%' OR 
926
                        visual_code LIKE '%$keyword_course%'
927
                     )
928
            )";
929
        }
930
        $sql .= " ORDER BY `$column` $direction";
931
        $sql .= " LIMIT $from, $number_of_items";
932
933
        $result = Database::query($sql);
934
        $tickets = [];
935
        $webPath = api_get_path(WEB_PATH);
936
        while ($row = Database::fetch_assoc($result)) {
937
            $userInfo = api_get_user_info($row['sys_insert_user_id']);
938
            $hrefUser = $webPath.'main/admin/user_information.php?user_id='.$userInfo['user_id'];
939
            $name = "<a href='$hrefUser'> {$userInfo['complete_name_with_username']} </a>";
940
            if ($row['assigned_last_user'] != 0) {
941
                $assignedUserInfo = api_get_user_info($row['assigned_last_user']);
942
                if (!empty($assignedUserInfo)) {
943
                    $hrefResp = $webPath.'main/admin/user_information.php?user_id='.$assignedUserInfo['user_id'];
944
                    $row['assigned_last_user'] = "<a href='$hrefResp'> {$assignedUserInfo['complete_name_with_username']} </a>";
945
                } else {
946
                    $row['assigned_last_user'] = get_lang('UnknownUser');
947
                }
948
            } else {
949
                if ($row['status_id'] !== self::STATUS_FORWARDED) {
950
                    $row['assigned_last_user'] = '<span style="color:#ff0000;">'.get_lang('ToBeAssigned').'</span>';
951
                } else {
952
                    $row['assigned_last_user'] = '<span style="color:#00ff00;">'.get_lang('MessageResent').'</span>';
953
                }
954
            }
955
956
            switch ($row['source']) {
957
                case self::SOURCE_PRESENTIAL:
958
                    $img_source = 'icons/32/user.png';
959
                    break;
960
                case self::SOURCE_EMAIL:
961
                    $img_source = 'icons/32/mail.png';
962
                    break;
963
                case self::SOURCE_PHONE:
964
                    $img_source = 'icons/32/event.png';
965
                    break;
966
                default:
967
                    $img_source = 'icons/32/ticket.png';
968
                    break;
969
            }
970
971
            $row['start_date'] = Display::dateToStringAgoAndLongDate($row['start_date']);
972
            $row['sys_lastedit_datetime'] = Display::dateToStringAgoAndLongDate($row['sys_lastedit_datetime']);
973
974
            $icon = Display::return_icon(
975
                $img_source,
976
                get_lang('Info'),
977
                ['style' => 'margin-right: 10px; float: left;']
978
            );
979
980
            $icon .= '<a href="ticket_details.php?ticket_id='.$row['id'].'">'.$row['code'].'</a>';
981
982
            if ($isAdmin) {
983
                $ticket = [
984
                    $icon.' '.Security::remove_XSS($row['subject']),
985
                    $row['status_name'],
986
                    $row['start_date'],
987
                    $row['sys_lastedit_datetime'],
988
                    $row['category_name'],
989
                    $name,
990
                    $row['assigned_last_user'],
991
                    $row['total_messages'],
992
                ];
993
            } else {
994
                $ticket = [
995
                    $icon.' '.Security::remove_XSS($row['subject']),
996
                    $row['status_name'],
997
                    $row['start_date'],
998
                    $row['sys_lastedit_datetime'],
999
                    $row['category_name'],
1000
                ];
1001
            }
1002
            if ($isAdmin) {
1003
                $ticket['0'] .= '&nbsp;&nbsp;<a href="javascript:void(0)" onclick="load_history_ticket(\'div_'.$row['ticket_id'].'\','.$row['ticket_id'].')">
1004
					<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').'"/>
1005
					<div class="blackboard_hide" id="div_'.$row['ticket_id'].'">&nbsp;&nbsp;</div>
1006
					</a>&nbsp;&nbsp;';
1007
            }
1008
            $tickets[] = $ticket;
1009
        }
1010
1011
        return $tickets;
1012
    }
1013
1014
    /**
1015
     * @return int
1016
     */
1017
    public static function getTotalTicketsCurrentUser()
1018
    {
1019
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1020
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1021
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1022
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1023
1024
        $userInfo = api_get_user_info();
1025
        if (empty($userInfo)) {
1026
            return 0;
1027
        }
1028
        $userId = $userInfo['id'];
1029
1030
        if (!isset($_GET['project_id'])) {
1031
            return 0;
1032
        }
1033
1034
        $sql = "SELECT COUNT(ticket.id) AS total
1035
                FROM $table_support_tickets ticket
1036
                INNER JOIN $table_support_category cat
1037
                ON (cat.id = ticket.category_id)
1038
                INNER JOIN $table_support_priority priority
1039
                ON (ticket.priority_id = priority.id)
1040
                INNER JOIN $table_support_status status
1041
                ON (ticket.status_id = status.id)
1042
	            WHERE 1 = 1";
1043
1044
        $projectId = (int) $_GET['project_id'];
1045
        $allowRoleList = self::getAllowedRolesFromProject($projectId);
1046
1047
        // Check if a role was set to the project
1048
        if (!empty($allowRoleList) && is_array($allowRoleList)) {
1049
            if (!in_array($userInfo['status'], $allowRoleList)) {
1050
                $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
1051
            }
1052
        } else {
1053
            if (!api_is_platform_admin()) {
1054
                $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
1055
            }
1056
        }
1057
1058
        // Search simple
1059
        if (isset($_GET['submit_simple'])) {
1060
            if ($_GET['keyword'] != '') {
1061
                $keyword = Database::escape_string(trim($_GET['keyword']));
1062
                $sql .= " AND (
1063
                          ticket.code LIKE '%$keyword%' OR
1064
                          ticket.subject LIKE '%$keyword%' OR
1065
                          ticket.message LIKE '%$keyword%' OR
1066
                          ticket.keyword LIKE '%$keyword%' OR
1067
                          ticket.personal_email LIKE '%$keyword%' OR
1068
                          ticket.source LIKE '%$keyword%'
1069
                )";
1070
            }
1071
        }
1072
1073
        $keywords = [
1074
            'project_id' => 'ticket.project_id',
1075
            'keyword_category' => 'ticket.category_id',
1076
            'keyword_assigned_to' => 'ticket.assigned_last_user',
1077
            'keyword_source' => 'ticket.source',
1078
            'keyword_status' => 'ticket.status_id',
1079
            'keyword_priority' => 'ticket.priority_id',
1080
        ];
1081
1082
        foreach ($keywords as $keyword => $sqlLabel) {
1083
            if (isset($_GET[$keyword])) {
1084
                $data = Database::escape_string(trim($_GET[$keyword]));
1085
                $sql .= " AND $sqlLabel = '$data' ";
1086
            }
1087
        }
1088
1089
        // Search advanced
1090
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
1091
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
1092
        $keyword_range = isset($_GET['keyword_dates']) ? Database::escape_string(trim($_GET['keyword_dates'])) : '';
1093
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
1094
1095
        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...
1096
            $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1097
        }
1098
        if ($keyword_range && $keyword_start_date_start != '' && $keyword_start_date_end != '') {
1099
            $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1100
                      AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1101
        }
1102
        if ($keyword_course != '') {
1103
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1104
            $sql .= " AND ticket.course_id IN (  
1105
                        SELECT id
1106
                        FROM $course_table
1107
                        WHERE (
1108
                            title LIKE '%$keyword_course%' OR 
1109
                            code LIKE '%$keyword_course%' OR 
1110
                            visual_code LIKE '%$keyword_course%'
1111
                        )
1112
                   ) ";
1113
        }
1114
1115
        $res = Database::query($sql);
1116
        $obj = Database::fetch_object($res);
1117
1118
        return (int) $obj->total;
1119
    }
1120
1121
    /**
1122
     * @param int $id
1123
     *
1124
     * @return false|MessageAttachment
1125
     */
1126
    public static function getTicketMessageAttachment($id)
1127
    {
1128
        $id = (int) $id;
1129
        $em = Database::getManager();
1130
        $item = $em->getRepository('ChamiloTicketBundle:MessageAttachment')->find($id);
1131
        if ($item) {
1132
            return $item;
1133
        }
1134
1135
        return false;
1136
    }
1137
1138
    /**
1139
     * @param int $id
1140
     *
1141
     * @return array
1142
     */
1143
    public static function getTicketMessageAttachmentsByTicketId($id)
1144
    {
1145
        $id = (int) $id;
1146
        $em = Database::getManager();
1147
        $items = $em->getRepository('ChamiloTicketBundle:MessageAttachment')->findBy(['ticket' => $id]);
1148
        if ($items) {
1149
            return $items;
1150
        }
1151
1152
        return false;
1153
    }
1154
1155
    /**
1156
     * @param int $ticketId
1157
     *
1158
     * @return array
1159
     */
1160
    public static function get_ticket_detail_by_id($ticketId)
1161
    {
1162
        $ticketId = (int) $ticketId;
1163
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1164
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1165
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1166
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1167
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1168
        $table_support_message_attachments = Database::get_main_table(TABLE_TICKET_MESSAGE_ATTACHMENTS);
1169
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1170
1171
        $sql = "SELECT
1172
                    ticket.*, 
1173
                    cat.name,
1174
                    status.name as status, 
1175
                    priority.name priority
1176
                FROM $table_support_tickets ticket
1177
                INNER JOIN $table_support_category cat
1178
                ON (cat.id = ticket.category_id)
1179
                INNER JOIN $table_support_priority priority
1180
                ON (priority.id = ticket.priority_id)
1181
                INNER JOIN $table_support_status status
1182
                ON (status.id = ticket.status_id)
1183
		        WHERE
1184
                    ticket.id = $ticketId ";
1185
        $result = Database::query($sql);
1186
        $ticket = [];
1187
        if (Database::num_rows($result) > 0) {
1188
            while ($row = Database::fetch_assoc($result)) {
1189
                $row['course'] = null;
1190
                $row['start_date_from_db'] = $row['start_date'];
1191
                $row['start_date'] = api_convert_and_format_date(
1192
                    api_get_local_time($row['start_date']),
1193
                    DATE_TIME_FORMAT_LONG,
1194
                    api_get_timezone()
1195
                );
1196
                $row['end_date_from_db'] = $row['end_date'];
1197
                $row['end_date'] = api_convert_and_format_date(
1198
                    api_get_local_time($row['end_date']),
1199
                    DATE_TIME_FORMAT_LONG,
1200
                    api_get_timezone()
1201
                );
1202
                $row['sys_lastedit_datetime_from_db'] = $row['sys_lastedit_datetime'];
1203
                $row['sys_lastedit_datetime'] = api_convert_and_format_date(
1204
                    api_get_local_time($row['sys_lastedit_datetime']),
1205
                    DATE_TIME_FORMAT_LONG,
1206
                    api_get_timezone()
1207
                );
1208
                $row['course_url'] = null;
1209
                if ($row['course_id'] != 0) {
1210
                    $course = api_get_course_info_by_id($row['course_id']);
1211
                    $sessionId = 0;
1212
                    if ($row['session_id']) {
1213
                        $sessionId = $row['session_id'];
1214
                    }
1215
                    if ($course) {
1216
                        $row['course_url'] = '<a href="'.$course['course_public_url'].'?id_session='.$sessionId.'">'.$course['name'].'</a>';
1217
                    }
1218
1219
                    $row['exercise_url'] = null;
1220
1221
                    if (!empty($row['exercise_id'])) {
1222
                        $exerciseTitle = ExerciseLib::getExerciseTitleById($row['exercise_id']);
0 ignored issues
show
Bug introduced by
The method getExerciseTitleById() does not exist on ExerciseLib. ( Ignorable by Annotation )

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

1222
                        /** @scrutinizer ignore-call */ 
1223
                        $exerciseTitle = ExerciseLib::getExerciseTitleById($row['exercise_id']);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1223
                        $dataExercise = [
1224
                            'cidReq' => $course['code'],
1225
                            'id_session' => $sessionId,
1226
                            'exerciseId' => $row['exercise_id'],
1227
                        ];
1228
                        $urlParamsExercise = http_build_query($dataExercise);
1229
1230
                        $row['exercise_url'] = '<a href="'.api_get_path(WEB_CODE_PATH).'exercise/overview.php?'.$urlParamsExercise.'">'.$exerciseTitle.'</a>';
1231
                    }
1232
1233
                    $row['lp_url'] = null;
1234
1235
                    if (!empty($row['lp_id'])) {
1236
                        $lpName = learnpath::getLpNameById($row['lp_id']);
0 ignored issues
show
Bug introduced by
The method getLpNameById() does not exist on learnpath. ( Ignorable by Annotation )

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

1236
                        /** @scrutinizer ignore-call */ 
1237
                        $lpName = learnpath::getLpNameById($row['lp_id']);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1237
                        $dataLp = [
1238
                            'cidReq' => $course['code'],
1239
                            'id_session' => $sessionId,
1240
                            'lp_id' => $row['lp_id'],
1241
                            'action' => 'view',
1242
                        ];
1243
                        $urlParamsLp = http_build_query($dataLp);
1244
1245
                        $row['lp_url'] = '<a href="'.api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.$urlParamsLp.'">'.$lpName.'</a>';
1246
                    }
1247
                }
1248
1249
                $userInfo = api_get_user_info($row['sys_insert_user_id']);
1250
                $row['user_url'] = '<a href="'.api_get_path(WEB_PATH).'main/admin/user_information.php?user_id='.$userInfo['user_id'].'">
1251
                '.$userInfo['complete_name'].'</a>';
1252
                $ticket['usuario'] = $userInfo;
1253
                $ticket['ticket'] = $row;
1254
            }
1255
1256
            $sql = "SELECT *, message.id as message_id 
1257
                    FROM $table_support_messages message 
1258
                    INNER JOIN $table_main_user user
1259
                    ON (message.sys_insert_user_id = user.user_id)
1260
                    WHERE
1261
                        message.ticket_id = '$ticketId' ";
1262
            $result = Database::query($sql);
1263
            $ticket['messages'] = [];
1264
            $attach_icon = Display::return_icon('attachment.gif', '');
1265
            $webPath = api_get_path(WEB_CODE_PATH);
1266
            while ($row = Database::fetch_assoc($result)) {
1267
                $message = $row;
1268
                $message['admin'] = UserManager::is_admin($message['user_id']);
1269
                $message['user_info'] = api_get_user_info($message['user_id']);
1270
                $sql = "SELECT *
1271
                        FROM $table_support_message_attachments
1272
                        WHERE
1273
                            message_id = ".$row['message_id']." AND
1274
                            ticket_id = $ticketId";
1275
1276
                $result_attach = Database::query($sql);
1277
                while ($row2 = Database::fetch_assoc($result_attach)) {
1278
                    $archiveURL = $webPath.'ticket/download.php?ticket_id='.$ticketId.'&id='.$row2['id'];
1279
                    $row2['attachment_link'] = $attach_icon.
1280
                        '&nbsp;<a href="'.$archiveURL.'">'.$row2['filename'].'</a>&nbsp;('.$row2['size'].')';
1281
                    $message['attachments'][] = $row2;
1282
                }
1283
                $ticket['messages'][] = $message;
1284
            }
1285
        }
1286
1287
        return $ticket;
1288
    }
1289
1290
    /**
1291
     * @param int $ticketId
1292
     * @param int $userId
1293
     *
1294
     * @return bool
1295
     */
1296
    public static function update_message_status($ticketId, $userId)
1297
    {
1298
        $ticketId = (int) $ticketId;
1299
        $userId = (int) $userId;
1300
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1301
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1302
        $now = api_get_utc_datetime();
1303
        $sql = "UPDATE $table_support_messages
1304
                SET
1305
                    status = 'LEI',
1306
                    sys_lastedit_user_id ='".api_get_user_id()."',
1307
                    sys_lastedit_datetime ='".$now."'
1308
                WHERE ticket_id ='$ticketId' ";
1309
1310
        if (api_is_platform_admin()) {
1311
            $sql .= " AND sys_insert_user_id = '$userId'";
1312
        } else {
1313
            $sql .= " AND sys_insert_user_id != '$userId'";
1314
        }
1315
        $result = Database::query($sql);
1316
        if (Database::affected_rows($result) > 0) {
1317
            Database::query(
1318
                "UPDATE $table_support_tickets SET
1319
                    status_id = '".self::STATUS_PENDING."'
1320
                 WHERE id ='$ticketId' AND status_id = '".self::STATUS_NEW."'"
1321
            );
1322
1323
            return true;
1324
        }
1325
1326
        return false;
1327
    }
1328
1329
    /**
1330
     * Send notification to a user through the internal messaging system.
1331
     *
1332
     * @param int    $ticketId
1333
     * @param string $title
1334
     * @param string $message
1335
     * @param int    $onlyToUserId
1336
     *
1337
     * @return bool
1338
     */
1339
    public static function sendNotification($ticketId, $title, $message, $onlyToUserId = 0)
1340
    {
1341
        $ticketInfo = self::get_ticket_detail_by_id($ticketId);
1342
1343
        if (empty($ticketInfo)) {
1344
            return false;
1345
        }
1346
1347
        $assignedUserInfo = api_get_user_info($ticketInfo['ticket']['assigned_last_user']);
1348
        $requestUserInfo = $ticketInfo['usuario'];
1349
        $ticketCode = $ticketInfo['ticket']['code'];
1350
        $status = $ticketInfo['ticket']['status'];
1351
        $priority = $ticketInfo['ticket']['priority'];
1352
1353
        // Subject
1354
        $titleEmail = "[$ticketCode] $title";
1355
1356
        // Content
1357
        $href = api_get_path(WEB_CODE_PATH).'ticket/ticket_details.php?ticket_id='.$ticketId;
1358
        $ticketUrl = Display::url($ticketCode, $href);
1359
        $messageEmail = get_lang('TicketNum').": $ticketUrl <br />";
1360
        $messageEmail .= get_lang('Status').": $status <br />";
1361
        $messageEmail .= get_lang('Priority').": $priority <br />";
1362
        $messageEmail .= '<hr /><br />';
1363
        $messageEmail .= $message;
1364
        $currentUserId = api_get_user_id();
1365
        $attachmentList = [];
1366
        $attachments = self::getTicketMessageAttachmentsByTicketId($ticketId);
1367
        if (!empty($attachments)) {
1368
            /** @var MessageAttachment $attachment */
1369
            foreach ($attachments as $attachment) {
1370
                $file = api_get_uploaded_file(
1371
                    'ticket_attachment',
1372
                    $ticketId,
1373
                    $attachment->getPath()
1374
                );
1375
                if (!empty($file)) {
1376
                    $attachmentList[] = [
1377
                        'tmp_name' => api_get_uploaded_file(
1378
                            'ticket_attachment',
1379
                            $ticketId,
1380
                            $attachment->getPath()
1381
                        ),
1382
                        'size' => $attachment->getSize(),
1383
                        'name' => $attachment->getFilename(),
1384
                        'error' => 0,
1385
                    ];
1386
                }
1387
            }
1388
        }
1389
1390
        if (!empty($onlyToUserId)) {
1391
            // Send only to specific user
1392
            if ($currentUserId != $onlyToUserId) {
1393
                MessageManager::send_message_simple(
1394
                    $onlyToUserId,
1395
                    $titleEmail,
1396
                    $messageEmail,
1397
                    0,
1398
                    false,
1399
                    false,
1400
                    [],
1401
                    false,
1402
                    $attachmentList
1403
                );
1404
            }
1405
        } else {
1406
            // Send to assigned user and to author
1407
            if ($requestUserInfo && $currentUserId != $requestUserInfo['id']) {
1408
                MessageManager::send_message_simple(
1409
                    $requestUserInfo['id'],
1410
                    $titleEmail,
1411
                    $messageEmail,
1412
                    0,
1413
                    false,
1414
                    false,
1415
                    [],
1416
                    false,
1417
                    $attachmentList
1418
                );
1419
            }
1420
1421
            if ($assignedUserInfo &&
1422
                $requestUserInfo['id'] != $assignedUserInfo['id'] &&
1423
                $currentUserId != $assignedUserInfo['id']
1424
            ) {
1425
                MessageManager::send_message_simple(
1426
                    $assignedUserInfo['id'],
1427
                    $titleEmail,
1428
                    $messageEmail,
1429
                    0,
1430
                    false,
1431
                    false,
1432
                    [],
1433
                    false,
1434
                    $attachmentList
1435
                );
1436
            }
1437
        }
1438
    }
1439
1440
    /**
1441
     * @param array $params
1442
     * @param int   $ticketId
1443
     * @param int   $userId
1444
     *
1445
     * @return bool
1446
     */
1447
    public static function updateTicket(
1448
        $params,
1449
        $ticketId,
1450
        $userId
1451
    ) {
1452
        $now = api_get_utc_datetime();
1453
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1454
        $newParams = [
1455
            'priority_id' => isset($params['priority_id']) ? (int) $params['priority_id'] : '',
1456
            'status_id' => isset($params['status_id']) ? (int) $params['status_id'] : '',
1457
            'sys_lastedit_user_id' => (int) $userId,
1458
            'sys_lastedit_datetime' => $now,
1459
        ];
1460
        Database::update($table, $newParams, ['id = ? ' => $ticketId]);
1461
1462
        return true;
1463
    }
1464
1465
    /**
1466
     * @param int $status_id
1467
     * @param int $ticketId
1468
     * @param int $userId
1469
     *
1470
     * @return bool
1471
     */
1472
    public static function update_ticket_status(
1473
        $status_id,
1474
        $ticketId,
1475
        $userId
1476
    ) {
1477
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1478
1479
        $ticketId = (int) $ticketId;
1480
        $status_id = (int) $status_id;
1481
        $userId = (int) $userId;
1482
        $now = api_get_utc_datetime();
1483
1484
        $sql = "UPDATE $table_support_tickets
1485
                SET
1486
                    status_id = '$status_id',
1487
                    sys_lastedit_user_id ='$userId',
1488
                    sys_lastedit_datetime ='".$now."'
1489
                WHERE id ='$ticketId'";
1490
        $result = Database::query($sql);
1491
1492
        if (Database::affected_rows($result) > 0) {
1493
            self::sendNotification(
1494
                $ticketId,
1495
                get_lang('TicketUpdated'),
1496
                get_lang('TicketUpdated')
1497
            );
1498
1499
            return true;
1500
        }
1501
1502
        return false;
1503
    }
1504
1505
    /**
1506
     * @return mixed
1507
     */
1508
    public static function getNumberOfMessages()
1509
    {
1510
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1511
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1512
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1513
        $table_main_admin = Database::get_main_table(TABLE_MAIN_ADMIN);
1514
        $user_info = api_get_user_info();
1515
        $userId = $user_info['user_id'];
1516
        $sql = "SELECT COUNT(DISTINCT ticket.id) AS unread
1517
                FROM $table_support_tickets ticket,
1518
                $table_support_messages message ,
1519
                $table_main_user user
1520
                WHERE
1521
                    ticket.id = message.ticket_id AND
1522
                    message.status = 'NOL' AND
1523
                    user.user_id = message.sys_insert_user_id ";
1524
        if (!api_is_platform_admin()) {
1525
            $sql .= " AND ticket.request_user = '$userId'
1526
                      AND user_id IN (SELECT user_id FROM $table_main_admin)  ";
1527
        } else {
1528
            $sql .= " AND user_id NOT IN (SELECT user_id FROM $table_main_admin)
1529
                      AND ticket.status_id != '".self::STATUS_FORWARDED."'";
1530
        }
1531
        $sql .= "  AND ticket.project_id != '' ";
1532
        $res = Database::query($sql);
1533
        $obj = Database::fetch_object($res);
1534
1535
        return $obj->unread;
1536
    }
1537
1538
    /**
1539
     * @param int $ticketId
1540
     * @param int $userId
1541
     */
1542
    public static function send_alert($ticketId, $userId)
1543
    {
1544
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1545
        $now = api_get_utc_datetime();
1546
1547
        $ticketId = (int) $ticketId;
1548
        $userId = (int) $userId;
1549
1550
        $sql = "UPDATE $table_support_tickets SET
1551
                  priority_id = '".self::PRIORITY_HIGH."',
1552
                  sys_lastedit_user_id = $userId,
1553
                  sys_lastedit_datetime = '$now'
1554
                WHERE id = $ticketId";
1555
        Database::query($sql);
1556
    }
1557
1558
    /**
1559
     * @param int $ticketId
1560
     * @param int $userId
1561
     */
1562
    public static function close_ticket($ticketId, $userId)
1563
    {
1564
        $ticketId = (int) $ticketId;
1565
        $userId = (int) $userId;
1566
1567
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1568
        $now = api_get_utc_datetime();
1569
        $sql = "UPDATE $table_support_tickets SET
1570
                    status_id = '".self::STATUS_CLOSE."',
1571
                    sys_lastedit_user_id ='$userId',
1572
                    sys_lastedit_datetime ='".$now."',
1573
                    end_date ='$now'
1574
                WHERE id ='$ticketId'";
1575
        Database::query($sql);
1576
1577
        self::sendNotification(
1578
            $ticketId,
1579
            get_lang('TicketClosed'),
1580
            get_lang('TicketClosed')
1581
        );
1582
    }
1583
1584
    /**
1585
     * Close old tickets.
1586
     */
1587
    public static function close_old_tickets()
1588
    {
1589
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1590
        $now = api_get_utc_datetime();
1591
        $userId = api_get_user_id();
1592
        $sql = "UPDATE $table
1593
                SET
1594
                    status_id = '".self::STATUS_CLOSE."',
1595
                    sys_lastedit_user_id ='$userId',
1596
                    sys_lastedit_datetime ='$now',
1597
                    end_date = '$now'
1598
                WHERE
1599
                    DATEDIFF('$now', sys_lastedit_datetime) > 7 AND
1600
                    status_id != '".self::STATUS_CLOSE."' AND
1601
                    status_id != '".self::STATUS_NEW."' AND
1602
                    status_id != '".self::STATUS_FORWARDED."'";
1603
        Database::query($sql);
1604
    }
1605
1606
    /**
1607
     * @param int $ticketId
1608
     *
1609
     * @return array
1610
     */
1611
    public static function get_assign_log($ticketId)
1612
    {
1613
        $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
1614
        $ticketId = (int) $ticketId;
1615
1616
        $sql = "SELECT * FROM $table
1617
                WHERE ticket_id = $ticketId
1618
                ORDER BY assigned_date DESC";
1619
        $result = Database::query($sql);
1620
        $history = [];
1621
        $webpath = api_get_path(WEB_PATH);
1622
        while ($row = Database::fetch_assoc($result)) {
1623
            if ($row['user_id'] != 0) {
1624
                $assignuser = api_get_user_info($row['user_id']);
1625
                $row['assignuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['user_id'].'"  target="_blank">'.
1626
                $assignuser['username'].'</a>';
1627
            } else {
1628
                $row['assignuser'] = get_lang('Unassign');
1629
            }
1630
            $row['assigned_date'] = Display::dateToStringAgoAndLongDate($row['assigned_date']);
1631
            $insertuser = api_get_user_info($row['sys_insert_user_id']);
1632
            $row['insertuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['sys_insert_user_id'].'"  target="_blank">'.
1633
                $insertuser['username'].'</a>';
1634
            $history[] = $row;
1635
        }
1636
1637
        return $history;
1638
    }
1639
1640
    /**
1641
     * @param $from
1642
     * @param $number_of_items
1643
     * @param $column
1644
     * @param $direction
1645
     * @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...
1646
     *
1647
     * @return array
1648
     */
1649
    public static function export_tickets_by_user_id(
1650
        $from,
1651
        $number_of_items,
1652
        $column,
1653
        $direction,
1654
        $userId = null
1655
    ) {
1656
        $from = (int) $from;
1657
        $number_of_items = (int) $number_of_items;
1658
        $table_support_category = Database::get_main_table(
1659
            TABLE_TICKET_CATEGORY
1660
        );
1661
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1662
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1663
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1664
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1665
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1666
1667
        if (is_null($direction)) {
1668
            $direction = 'DESC';
1669
        }
1670
        if (is_null($userId) || $userId == 0) {
1671
            $userId = api_get_user_id();
1672
        }
1673
1674
        $sql = "SELECT
1675
                    ticket.code,
1676
                    ticket.sys_insert_datetime,
1677
                    ticket.sys_lastedit_datetime,
1678
                    cat.name as category,
1679
                    CONCAT(user.lastname,' ', user.firstname) AS fullname,
1680
                    status.name as status,
1681
                    ticket.total_messages as messages,
1682
                    ticket.assigned_last_user as responsable
1683
                FROM $table_support_tickets ticket,
1684
                $table_support_category cat ,
1685
                $table_support_priority priority,
1686
                $table_support_status status ,
1687
                $table_main_user user
1688
                WHERE
1689
                    cat.id = ticket.category_id
1690
                    AND ticket.priority_id = priority.id
1691
                    AND ticket.status_id = status.id
1692
                    AND user.user_id = ticket.request_user ";
1693
        // Search simple
1694
        if (isset($_GET['submit_simple'])) {
1695
            if ($_GET['keyword'] !== '') {
1696
                $keyword = Database::escape_string(trim($_GET['keyword']));
1697
                $sql .= " AND (ticket.code = '$keyword'
1698
                          OR user.firstname LIKE '%$keyword%'
1699
                          OR user.lastname LIKE '%$keyword%'
1700
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword%'
1701
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword%'
1702
                          OR user.username LIKE '%$keyword%')  ";
1703
            }
1704
        }
1705
        // Search advanced
1706
        if (isset($_GET['submit_advanced'])) {
1707
            $keyword_category = Database::escape_string(
1708
                trim($_GET['keyword_category'])
1709
            );
1710
            $keyword_request_user = Database::escape_string(
1711
                trim($_GET['keyword_request_user'])
1712
            );
1713
            $keywordAssignedTo = (int) $_GET['keyword_assigned_to'];
1714
            $keyword_start_date_start = Database::escape_string(
1715
                trim($_GET['keyword_start_date_start'])
1716
            );
1717
            $keyword_start_date_end = Database::escape_string(
1718
                trim($_GET['keyword_start_date_end'])
1719
            );
1720
            $keyword_status = Database::escape_string(
1721
                trim($_GET['keyword_status'])
1722
            );
1723
            $keyword_source = Database::escape_string(
1724
                trim($_GET['keyword_source'])
1725
            );
1726
            $keyword_priority = Database::escape_string(
1727
                trim($_GET['keyword_priority'])
1728
            );
1729
            $keyword_range = Database::escape_string(
1730
                trim($_GET['keyword_dates'])
1731
            );
1732
            $keyword_unread = Database::escape_string(
1733
                trim($_GET['keyword_unread'])
1734
            );
1735
            $keyword_course = Database::escape_string(
1736
                trim($_GET['keyword_course'])
1737
            );
1738
1739
            if ($keyword_category != '') {
1740
                $sql .= " AND ticket.category_id = '$keyword_category'  ";
1741
            }
1742
            if ($keyword_request_user != '') {
1743
                $sql .= " AND (ticket.request_user = '$keyword_request_user'
1744
                          OR user.firstname LIKE '%$keyword_request_user%'
1745
                          OR user.official_code LIKE '%$keyword_request_user%'
1746
                          OR user.lastname LIKE '%$keyword_request_user%'
1747
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword_request_user%'
1748
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword_request_user%'
1749
                          OR user.username LIKE '%$keyword_request_user%') ";
1750
            }
1751
            if (!empty($keywordAssignedTo)) {
1752
                $sql .= " AND ticket.assigned_last_user = $keywordAssignedTo ";
1753
            }
1754
            if ($keyword_status != '') {
1755
                $sql .= " AND ticket.status_id = '$keyword_status'  ";
1756
            }
1757
            if ($keyword_range == '' && $keyword_start_date_start != '') {
1758
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1759
            }
1760
            if ($keyword_range == '1' && $keyword_start_date_start != '' && $keyword_start_date_end != '') {
1761
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1762
                          AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1763
            }
1764
            if ($keyword_priority != '') {
1765
                $sql .= " AND ticket.priority_id = '$keyword_priority'  ";
1766
            }
1767
            if ($keyword_source != '') {
1768
                $sql .= " AND ticket.source = '$keyword_source' ";
1769
            }
1770
            if ($keyword_priority != '') {
1771
                $sql .= " AND ticket.priority_id = '$keyword_priority' ";
1772
            }
1773
            if ($keyword_course != '') {
1774
                $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1775
                $sql .= " AND ticket.course_id IN ( ";
1776
                $sql .= "SELECT id
1777
                         FROM $course_table
1778
                         WHERE (title LIKE '%$keyword_course%'
1779
                         OR code LIKE '%$keyword_course%'
1780
                         OR visual_code LIKE '%$keyword_course%' )) ";
1781
            }
1782
            if ($keyword_unread == 'yes') {
1783
                $sql .= " AND ticket.id IN (
1784
                          SELECT ticket.id
1785
                          FROM $table_support_tickets ticket,
1786
                          $table_support_messages message,
1787
                          $table_main_user user
1788
                          WHERE ticket.id = message.ticket_id
1789
                          AND message.status = 'NOL'
1790
                          AND message.sys_insert_user_id = user.user_id
1791
                          AND user.status != 1   AND ticket.status_id != '".self::STATUS_FORWARDED."'
1792
                          GROUP BY ticket.id)";
1793
            } else {
1794
                if ($keyword_unread == 'no') {
1795
                    $sql .= " AND ticket.id NOT IN (
1796
                              SELECT ticket.id
1797
                              FROM  $table_support_tickets ticket,
1798
                              $table_support_messages message,
1799
                              $table_main_user user
1800
                              WHERE ticket.id = message.ticket_id
1801
                              AND message.status = 'NOL'
1802
                              AND message.sys_insert_user_id = user.user_id
1803
                              AND user.status != 1
1804
                              AND ticket.status_id != '".self::STATUS_FORWARDED."'
1805
                             GROUP BY ticket.id)";
1806
                }
1807
            }
1808
        }
1809
1810
        $sql .= " LIMIT $from,$number_of_items";
1811
1812
        $result = Database::query($sql);
1813
        $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...
1814
            utf8_decode('Ticket#'),
1815
            utf8_decode('Fecha'),
1816
            utf8_decode('Fecha Edicion'),
1817
            utf8_decode('Categoria'),
1818
            utf8_decode('Usuario'),
1819
            utf8_decode('Estado'),
1820
            utf8_decode('Mensajes'),
1821
            utf8_decode('Responsable'),
1822
            utf8_decode('Programa'),
1823
        ];
1824
1825
        while ($row = Database::fetch_assoc($result)) {
1826
            if ($row['responsable'] != 0) {
1827
                $row['responsable'] = api_get_user_info($row['responsable']);
1828
                $row['responsable'] = $row['responsable']['firstname'].' '.$row['responsable']['lastname'];
1829
            }
1830
            $row['sys_insert_datetime'] = api_format_date(
1831
                $row['sys_insert_datetime'],
1832
                '%d/%m/%y - %I:%M:%S %p'
1833
            );
1834
            $row['sys_lastedit_datetime'] = api_format_date(
1835
                $row['sys_lastedit_datetime'],
1836
                '%d/%m/%y - %I:%M:%S %p'
1837
            );
1838
            $row['category'] = utf8_decode($row['category']);
1839
            $row['programa'] = utf8_decode($row['fullname']);
1840
            $row['fullname'] = utf8_decode($row['fullname']);
1841
            $row['responsable'] = utf8_decode($row['responsable']);
1842
            $tickets[] = $row;
1843
        }
1844
1845
        return $tickets;
1846
    }
1847
1848
    /**
1849
     * @param string $url
1850
     * @param int    $projectId
1851
     *
1852
     * @return FormValidator
1853
     */
1854
    public static function getCategoryForm($url, $projectId)
1855
    {
1856
        $form = new FormValidator('category', 'post', $url);
1857
        $form->addText('name', get_lang('Name'));
1858
        $form->addHtmlEditor('description', get_lang('Description'));
1859
        $form->addHidden('project_id', $projectId);
1860
        $form->addButtonUpdate(get_lang('Save'));
1861
1862
        return $form;
1863
    }
1864
1865
    /**
1866
     * @return array
1867
     */
1868
    public static function getStatusList()
1869
    {
1870
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->findAll();
1871
1872
        $list = [];
1873
        /** @var Status $row */
1874
        foreach ($items as $row) {
1875
            $list[$row->getId()] = $row->getName();
1876
        }
1877
1878
        return $list;
1879
    }
1880
1881
    /**
1882
     * @param array $criteria
1883
     *
1884
     * @return array
1885
     */
1886
    public static function getTicketsFromCriteria($criteria)
1887
    {
1888
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Ticket')->findBy($criteria);
1889
1890
        $list = [];
1891
        /** @var Ticket $row */
1892
        foreach ($items as $row) {
1893
            $list[$row->getId()] = $row->getCode();
1894
        }
1895
1896
        return $list;
1897
    }
1898
1899
    /**
1900
     * @param string $code
1901
     *
1902
     * @return int
1903
     */
1904
    public static function getStatusIdFromCode($code)
1905
    {
1906
        $item = Database::getManager()
1907
            ->getRepository('ChamiloTicketBundle:Status')
1908
            ->findOneBy(['code' => $code])
1909
        ;
1910
1911
        if ($item) {
1912
            return $item->getId();
1913
        }
1914
1915
        return 0;
1916
    }
1917
1918
    /**
1919
     * @return array
1920
     */
1921
    public static function getPriorityList()
1922
    {
1923
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Priority')->findAll();
1924
1925
        $list = [];
1926
        /** @var Priority $row */
1927
        foreach ($projects as $row) {
1928
            $list[$row->getId()] = $row->getName();
1929
        }
1930
1931
        return $list;
1932
    }
1933
1934
    /**
1935
     * @return array
1936
     */
1937
    public static function getProjects()
1938
    {
1939
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Project')->findAll();
1940
1941
        $list = [];
1942
        /** @var Project $row */
1943
        foreach ($projects as $row) {
1944
            $list[] = [
1945
                'id' => $row->getId(),
1946
                '0' => $row->getId(),
1947
                '1' => $row->getName(),
1948
                '2' => $row->getDescription(),
1949
                '3' => $row->getId(),
1950
            ];
1951
        }
1952
1953
        return $list;
1954
    }
1955
1956
    /**
1957
     * @return array
1958
     */
1959
    public static function getProjectsSimple()
1960
    {
1961
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Project')->findAll();
1962
1963
        $list = [];
1964
        /** @var Project $row */
1965
        foreach ($projects as $row) {
1966
            $list[] = [
1967
                'id' => $row->getId(),
1968
                '0' => $row->getId(),
1969
                '1' => Display::url(
1970
                    $row->getName(),
1971
                    api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id='.$row->getId()
1972
                ),
1973
                '2' => $row->getDescription(),
1974
            ];
1975
        }
1976
1977
        return $list;
1978
    }
1979
1980
    /**
1981
     * @return int
1982
     */
1983
    public static function getProjectsCount()
1984
    {
1985
        $count = Database::getManager()->getRepository('ChamiloTicketBundle:Project')->createQueryBuilder('p')
1986
            ->select('COUNT(p.id)')
1987
            ->getQuery()
1988
            ->getSingleScalarResult();
1989
1990
        return $count;
1991
    }
1992
1993
    /**
1994
     * @param array $params
1995
     */
1996
    public static function addProject($params)
1997
    {
1998
        $project = new Project();
1999
        $project->setName($params['name']);
2000
        $project->setDescription($params['description']);
2001
        $project->setInsertUserId(api_get_user_id());
2002
2003
        Database::getManager()->persist($project);
2004
        Database::getManager()->flush();
2005
    }
2006
2007
    /**
2008
     * @param int $id
2009
     *
2010
     * @return Project
2011
     */
2012
    public static function getProject($id)
2013
    {
2014
        return Database::getManager()->getRepository('ChamiloTicketBundle:Project')->find($id);
2015
    }
2016
2017
    /**
2018
     * @param int   $id
2019
     * @param array $params
2020
     */
2021
    public static function updateProject($id, $params)
2022
    {
2023
        $project = self::getProject($id);
2024
        $project->setName($params['name']);
2025
        $project->setDescription($params['description']);
2026
        $project->setLastEditDateTime(new DateTime($params['sys_lastedit_datetime']));
2027
        $project->setLastEditUserId($params['sys_lastedit_user_id']);
2028
2029
        Database::getManager()->merge($project);
2030
        Database::getManager()->flush();
2031
    }
2032
2033
    /**
2034
     * @param int $id
2035
     */
2036
    public static function deleteProject($id)
2037
    {
2038
        $project = self::getProject($id);
2039
        if ($project) {
0 ignored issues
show
introduced by
$project is of type Chamilo\TicketBundle\Entity\Project, thus it always evaluated to true.
Loading history...
2040
            Database::getManager()->remove($project);
2041
            Database::getManager()->flush();
2042
        }
2043
    }
2044
2045
    /**
2046
     * @param string $url
2047
     *
2048
     * @return FormValidator
2049
     */
2050
    public static function getProjectForm($url)
2051
    {
2052
        $form = new FormValidator('project', 'post', $url);
2053
        $form->addText('name', get_lang('Name'));
2054
        $form->addHtmlEditor('description', get_lang('Description'));
2055
        $form->addButtonUpdate(get_lang('Save'));
2056
2057
        return $form;
2058
    }
2059
2060
    /**
2061
     * @return array
2062
     */
2063
    public static function getStatusAdminList()
2064
    {
2065
        $items = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->findAll();
2066
2067
        $list = [];
2068
        /** @var Status $row */
2069
        foreach ($items as $row) {
2070
            $list[] = [
2071
                'id' => $row->getId(),
2072
                'code' => $row->getCode(),
2073
                '0' => $row->getId(),
2074
                '1' => $row->getName(),
2075
                '2' => $row->getDescription(),
2076
                '3' => $row->getId(),
2077
            ];
2078
        }
2079
2080
        return $list;
2081
    }
2082
2083
    /**
2084
     * @return array
2085
     */
2086
    public static function getStatusSimple()
2087
    {
2088
        $projects = Database::getManager()->getRepository('ChamiloTicketBundle:Status')->findAll();
2089
2090
        $list = [];
2091
        /** @var Project $row */
2092
        foreach ($projects as $row) {
2093
            $list[] = [
2094
                'id' => $row->getId(),
2095
                '0' => $row->getId(),
2096
                '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

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

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