Passed
Pull Request — 1.11.x (#4095)
by Angel Fernando Quiroz
08:19
created

TicketManager::add()   F

Complexity

Conditions 36
Paths > 20000

Size

Total Lines 290
Code Lines 173

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 36
eloc 173
nc 231391
nop 15
dl 0
loc 290
rs 0
c 1
b 0
f 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
372
        if (!empty($exerciseId)) {
373
            $params['exercise_id'] = $exerciseId;
374
        }
375
376
        if (!empty($lpId)) {
377
            $params['lp_id'] = $lpId;
378
        }
379
380
        if (!empty($course_id)) {
381
            $params['course_id'] = $course_id;
382
        }
383
384
        if (!empty($sessionId)) {
385
            $params['session_id'] = $sessionId;
386
        }
387
388
        $ticketId = Database::insert($table_support_tickets, $params);
389
390
        if ($ticketId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ticketId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

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

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
683
            // update_total_message
684
            $sql = "UPDATE $table_support_tickets
685
                    SET
686
                        sys_lastedit_user_id = $userId,
687
                        sys_lastedit_datetime = '$now',
688
                        total_messages = (
689
                            SELECT COUNT(*) as total_messages
690
                            FROM $table_support_messages
691
                            WHERE ticket_id = $ticketId
692
                        )
693
                    WHERE id = $ticketId ";
694
            Database::query($sql);
695
696
            if (is_array($fileAttachments)) {
697
                foreach ($fileAttachments as $file_attach) {
698
                    if ($file_attach['error'] == 0) {
699
                        self::saveMessageAttachmentFile(
700
                            $file_attach,
701
                            $ticketId,
702
                            $messageId
703
                        );
704
                    } else {
705
                        if ($file_attach['error'] != UPLOAD_ERR_NO_FILE) {
706
                            return false;
707
                        }
708
                    }
709
                }
710
            }
711
        }
712
713
        return true;
714
    }
715
716
    /**
717
     * Attachment files when a message is sent.
718
     *
719
     * @param $file_attach
720
     * @param $ticketId
721
     * @param $message_id
722
     *
723
     * @return bool
724
     */
725
    public static function saveMessageAttachmentFile(
726
        $file_attach,
727
        $ticketId,
728
        $message_id
729
    ) {
730
        $now = api_get_utc_datetime();
731
        $userId = api_get_user_id();
732
        $ticketId = (int) $ticketId;
733
734
        $new_file_name = add_ext_on_mime(
735
            stripslashes($file_attach['name']),
736
            $file_attach['type']
737
        );
738
        $table_support_message_attachments = Database::get_main_table(TABLE_TICKET_MESSAGE_ATTACHMENTS);
739
        if (!filter_extension($new_file_name)) {
740
            echo Display::return_message(
741
                get_lang('UplUnableToSaveFileFilteredExtension'),
742
                'error'
743
            );
744
        } else {
745
            $result = api_upload_file('ticket_attachment', $file_attach, $ticketId);
746
            if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array<string,string> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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

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

Loading history...
introduced by
$result is a non-empty array, thus is always true.
Loading history...
747
                $safe_file_name = Database::escape_string($new_file_name);
748
                $safe_new_file_name = Database::escape_string($result['path_to_save']);
749
                $sql = "INSERT INTO $table_support_message_attachments (
750
                        filename,
751
                        path,
752
                        ticket_id,
753
                        message_id,
754
                        size,
755
                        sys_insert_user_id,
756
                        sys_insert_datetime,
757
                        sys_lastedit_user_id,
758
                        sys_lastedit_datetime
759
                    ) VALUES (
760
                        '$safe_file_name',
761
                        '$safe_new_file_name',
762
                        '$ticketId',
763
                        '$message_id',
764
                        '".$file_attach['size']."',
765
                        '$userId',
766
                        '$now',
767
                        '$userId',
768
                        '$now'
769
                    )";
770
                Database::query($sql);
771
772
                return true;
773
            }
774
        }
775
    }
776
777
    /**
778
     * Get tickets by userId.
779
     *
780
     * @param int $from
781
     * @param int $number_of_items
782
     * @param $column
783
     * @param $direction
784
     *
785
     * @return array
786
     */
787
    public static function getTicketsByCurrentUser(
788
        $from,
789
        $number_of_items,
790
        $column,
791
        $direction
792
    ) {
793
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
794
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
795
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
796
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
797
        $direction = !empty($direction) ? $direction : 'DESC';
798
        $userId = api_get_user_id();
799
        $userInfo = api_get_user_info($userId);
800
801
        if (empty($userInfo)) {
802
            return [];
803
        }
804
        $isAdmin = UserManager::is_admin($userId);
805
806
        if (!isset($_GET['project_id'])) {
807
            return [];
808
        }
809
810
        switch ($column) {
811
            case 0:
812
                $column = 'ticket_id';
813
                break;
814
            case 1:
815
                $column = 'status_name';
816
                break;
817
            case 2:
818
                $column = 'start_date';
819
                break;
820
            case 3:
821
                $column = 'sys_lastedit_datetime';
822
                break;
823
            case 4:
824
                $column = 'category_name';
825
                break;
826
            case 5:
827
                $column = 'sys_insert_user_id';
828
                break;
829
            case 6:
830
                $column = 'assigned_last_user';
831
                break;
832
            case 7:
833
                $column = 'total_messages';
834
                break;
835
            case 8:
836
                $column = 'subject';
837
                break;
838
            default:
839
                $column = 'ticket_id';
840
        }
841
842
        $sql = "SELECT DISTINCT
843
                ticket.*,
844
                ticket.id ticket_id,
845
                status.name AS status_name,
846
                ticket.start_date,
847
                ticket.sys_lastedit_datetime,
848
                cat.name AS category_name,
849
                priority.name AS priority_name,
850
                ticket.total_messages AS total_messages,
851
                ticket.message AS message,
852
                ticket.subject AS subject,
853
                ticket.assigned_last_user
854
            FROM $table_support_tickets ticket
855
            INNER JOIN $table_support_category cat
856
            ON (cat.id = ticket.category_id)
857
            INNER JOIN $table_support_priority priority
858
            ON (ticket.priority_id = priority.id)
859
            INNER JOIN $table_support_status status
860
            ON (ticket.status_id = status.id)
861
            WHERE 1=1
862
        ";
863
864
        $projectId = (int) $_GET['project_id'];
865
        $userIsAllowInProject = self::userIsAllowInProject($userInfo, $projectId);
866
867
        // Check if a role was set to the project
868
        if ($userIsAllowInProject == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

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

Loading history...
869
            $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
870
        }
871
872
        // Search simple
873
        if (isset($_GET['submit_simple']) && $_GET['keyword'] != '') {
874
            $keyword = Database::escape_string(trim($_GET['keyword']));
875
            $sql .= " AND (
876
                      ticket.id LIKE '%$keyword%' OR
877
                      ticket.code LIKE '%$keyword%' OR
878
                      ticket.subject LIKE '%$keyword%' OR
879
                      ticket.message LIKE '%$keyword%' OR
880
                      ticket.keyword LIKE '%$keyword%' OR
881
                      ticket.source LIKE '%$keyword%' OR
882
                      cat.name LIKE '%$keyword%' OR
883
                      status.name LIKE '%$keyword%' OR
884
                      priority.name LIKE '%$keyword%' OR
885
                      ticket.personal_email LIKE '%$keyword%'
886
            )";
887
        }
888
889
        $keywords = [
890
            'project_id' => 'ticket.project_id',
891
            'keyword_category' => 'ticket.category_id',
892
            'keyword_assigned_to' => 'ticket.assigned_last_user',
893
            'keyword_source' => 'ticket.source ',
894
            'keyword_status' => 'ticket.status_id',
895
            'keyword_priority' => 'ticket.priority_id',
896
        ];
897
898
        foreach ($keywords as $keyword => $label) {
899
            if (isset($_GET[$keyword])) {
900
                $data = Database::escape_string(trim($_GET[$keyword]));
901
                if (!empty($data)) {
902
                    $sql .= " AND $label = '$data' ";
903
                }
904
            }
905
        }
906
907
        // Search advanced
908
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
909
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
910
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
911
        $keyword_range = !empty($keyword_start_date_start) && !empty($keyword_start_date_end);
912
913
        if ($keyword_range == false && $keyword_start_date_start != '') {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

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

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

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

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