Passed
Push — dependabot/npm_and_yarn/nanoid... ( aaf2c9...c4aa90 )
by
unknown
14:37 queued 06:22
created

TicketManager   F

Complexity

Total Complexity 279

Size/Duplication

Total Lines 2589
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 1324
c 2
b 0
f 0
dl 0
loc 2589
rs 0.8
wmc 279

70 Methods

Rating   Name   Duplication   Size   Complexity  
A addCategory() 0 4 1
A userIsAssignedToCategory() 0 10 1
A getUsersInCategory() 0 8 1
A getCategories() 0 23 3
A deleteAllUserInCategory() 0 6 1
A addUsersToCategory() 0 18 5
A getCategory() 0 11 1
A updateCategory() 0 5 1
A deleteCategory() 0 16 2
A get_all_tickets_categories() 0 27 3
A getCategoriesCount() 0 11 1
A get_all_tickets_status() 0 11 2
A __construct() 0 2 1
A getProjects() 0 17 2
A getProjectForm() 0 8 1
A update_ticket_status() 0 31 2
B insertMessage() 0 75 8
A getFollowers() 0 14 2
A getTicketMessageAttachment() 0 10 2
A getAllowedRolesFromProject() 0 35 4
C sendNotification() 0 102 16
A get_assign_log() 0 27 3
A close_ticket() 0 19 1
A getSettingsMenuItems() 0 33 4
A getCategoryForm() 0 9 1
A unsubscribeUserFromTicket() 0 14 3
A getStatus() 0 3 1
C deleteUserFromTicketSystem() 0 67 9
A subscribeUserToTicket() 0 14 3
A getStatusAdminList() 0 17 2
A getPriority() 0 3 1
A getProjectsSimple() 0 18 2
F add() 0 291 36
F getTicketsByCurrentUser() 0 235 38
A getPriorityForm() 0 8 1
A assignTicketToUser() 0 32 3
A saveMessageAttachmentFile() 0 58 5
C get_ticket_detail_by_id() 0 134 10
A getDefaultStatusList() 0 8 1
A getDefaultPriorityList() 0 8 1
A getProject() 0 3 1
A isUserSubscribedToTicket() 0 12 3
A getStatusIdFromCode() 0 12 2
A getPriorityAdminList() 0 18 2
A generateUnsubscribeLink() 0 7 1
A getPriorityCount() 0 6 1
F export_tickets_by_user_id() 0 198 25
A update_message_status() 0 31 3
A deleteStatus() 0 6 2
A updatePriority() 0 8 1
A getStatusForm() 0 8 1
A getTicketsFromCriteria() 0 10 2
A addPriority() 0 14 1
A deletePriority() 0 6 2
A getTicketMessageAttachmentsByTicketId() 0 10 2
A updateTicket() 0 16 3
A getStatusCount() 0 6 1
A send_alert() 0 14 1
F getTotalTicketsCurrentUser() 0 103 21
A userIsAllowInProject() 0 25 5
A addStatus() 0 9 1
A getPriorityList() 0 10 2
A updateProject() 0 10 1
A addProject() 0 9 1
A getStatusList() 0 11 2
A getNumberOfMessages() 0 28 2
A deleteProject() 0 6 2
A getProjectsCount() 0 6 1
A close_old_tickets() 0 17 1
A updateStatus() 0 8 1

How to fix   Complexity   

Complex Class

Complex classes like TicketManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use TicketManager, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\Ticket;
6
use Chamilo\CoreBundle\Entity\TicketMessage;
7
use Chamilo\CoreBundle\Entity\TicketMessageAttachment;
8
use Chamilo\CoreBundle\Entity\TicketPriority;
9
use Chamilo\CoreBundle\Entity\TicketProject;
10
use Chamilo\CoreBundle\Entity\TicketRelUser;
11
use Chamilo\CoreBundle\Entity\TicketStatus;
12
use Chamilo\CoreBundle\Entity\User;
13
use Chamilo\CoreBundle\Entity\ValidationToken;
14
use Chamilo\CoreBundle\Framework\Container;
15
use Chamilo\CoreBundle\ServiceHelper\ValidationTokenHelper;
16
use Chamilo\CourseBundle\Entity\CLp;
17
use Symfony\Component\HttpFoundation\File\UploadedFile;
18
use Chamilo\CoreBundle\Component\Utils\ObjectIcon;
19
use Chamilo\CoreBundle\Component\Utils\StateIcon;
20
21
/**
22
 * Class TicketManager.
23
 */
24
class TicketManager
25
{
26
    public const PRIORITY_NORMAL = 'NRM';
27
    public const PRIORITY_HIGH = 'HGH';
28
    public const PRIORITY_LOW = 'LOW';
29
30
    public const SOURCE_EMAIL = 'MAI';
31
    public const SOURCE_PHONE = 'TEL';
32
    public const SOURCE_PLATFORM = 'PLA';
33
    public const SOURCE_PRESENTIAL = 'PRE';
34
35
    public const STATUS_NEW = 'NAT';
36
    public const STATUS_PENDING = 'PND';
37
    public const STATUS_UNCONFIRMED = 'XCF';
38
    public const STATUS_CLOSE = 'CLS';
39
    public const STATUS_FORWARDED = 'REE';
40
41
    public function __construct()
42
    {
43
    }
44
45
    /**
46
     * Get categories of tickets.
47
     *
48
     * @param int    $projectId
49
     * @param string $order
50
     *
51
     * @return array
52
     */
53
    public static function get_all_tickets_categories($projectId, $order = '')
54
    {
55
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
56
        $table_support_project = Database::get_main_table(TABLE_TICKET_PROJECT);
57
58
        $order = empty($order) ? 'category.total_tickets DESC' : $order;
59
        $order = Database::escape_string($order);
60
        $projectId = (int) $projectId;
61
62
        $sql = "SELECT
63
                    category.*,
64
                    category.id category_id,
65
                    project.other_area,
66
                    project.email
67
                FROM
68
                $table_support_category category
69
                INNER JOIN $table_support_project project
70
                ON project.id = category.project_id
71
                WHERE project.id  = $projectId
72
                ORDER BY $order";
73
        $result = Database::query($sql);
74
        $types = [];
75
        while ($row = Database::fetch_assoc($result)) {
76
            $types[] = $row;
77
        }
78
79
        return $types;
80
    }
81
82
    /**
83
     * @param $from
84
     * @param $numberItems
85
     * @param $column
86
     * @param $direction
87
     *
88
     * @return array
89
     */
90
    public static function getCategories($from, $numberItems, $column, $direction)
91
    {
92
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
93
        $sql = "SELECT id, title, description, total_tickets
94
                FROM $table";
95
96
        if (!in_array($direction, ['ASC', 'DESC'])) {
97
            $direction = 'ASC';
98
        }
99
        $column = (int) $column;
100
        $from = (int) $from;
101
        $numberItems = (int) $numberItems;
102
103
        //$sql .= " ORDER BY col$column $direction ";
104
        $sql .= " LIMIT $from,$numberItems";
105
106
        $result = Database::query($sql);
107
        $types = [];
108
        while ($row = Database::fetch_array($result)) {
109
            $types[] = $row;
110
        }
111
112
        return $types;
113
    }
114
115
    /**
116
     * @param int $id
117
     *
118
     * @return array|mixed
119
     */
120
    public static function getCategory($id)
121
    {
122
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
123
        $id = (int) $id;
124
        $sql = "SELECT id, title, description, total_tickets
125
                FROM $table WHERE id = $id";
126
127
        $result = Database::query($sql);
128
        $category = Database::fetch_array($result);
129
130
        return $category;
131
    }
132
133
    /**
134
     * @return int
135
     */
136
    public static function getCategoriesCount()
137
    {
138
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
139
140
        $sql = "SELECT count(id) count
141
                FROM $table ";
142
143
        $result = Database::query($sql);
144
        $category = Database::fetch_array($result);
145
146
        return $category['count'];
147
    }
148
149
    /**
150
     * @param int   $id
151
     * @param array $params
152
     */
153
    public static function updateCategory($id, $params)
154
    {
155
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
156
        $id = (int) $id;
157
        Database::update($table, $params, ['id = ?' => $id]);
158
    }
159
160
    /**
161
     * @param array $params
162
     */
163
    public static function addCategory($params)
164
    {
165
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
166
        Database::insert($table, $params);
167
    }
168
169
    /**
170
     * @param int $id
171
     *
172
     * @return bool
173
     */
174
    public static function deleteCategory($id)
175
    {
176
        $id = (int) $id;
177
        if (empty($id)) {
178
            return false;
179
        }
180
181
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
182
        $sql = "UPDATE $table SET category_id = NULL WHERE category_id = $id";
183
        Database::query($sql);
184
185
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
186
        $sql = "DELETE FROM $table WHERE id = $id";
187
        Database::query($sql);
188
189
        return true;
190
    }
191
192
    /**
193
     * @param int   $categoryId
194
     * @param array $users
195
     *
196
     * @return bool
197
     */
198
    public static function addUsersToCategory($categoryId, $users)
199
    {
200
        if (empty($users) || empty($categoryId)) {
201
            return false;
202
        }
203
204
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
205
        foreach ($users as $userId) {
206
            if (false === self::userIsAssignedToCategory($userId, $categoryId)) {
207
                $params = [
208
                    'category_id' => $categoryId,
209
                    'user_id' => $userId,
210
                ];
211
                Database::insert($table, $params);
212
            }
213
        }
214
215
        return true;
216
    }
217
218
    /**
219
     * @param int $userId
220
     * @param int $categoryId
221
     *
222
     * @return bool
223
     */
224
    public static function userIsAssignedToCategory($userId, $categoryId)
225
    {
226
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
227
        $userId = (int) $userId;
228
        $categoryId = (int) $categoryId;
229
        $sql = "SELECT * FROM $table
230
                WHERE category_id = $categoryId AND user_id = $userId";
231
        $result = Database::query($sql);
232
233
        return Database::num_rows($result) > 0;
234
    }
235
236
    /**
237
     * @param int $categoryId
238
     *
239
     * @return array
240
     */
241
    public static function getUsersInCategory($categoryId)
242
    {
243
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
244
        $categoryId = (int) $categoryId;
245
        $sql = "SELECT * FROM $table WHERE category_id = $categoryId";
246
        $result = Database::query($sql);
247
248
        return Database::store_result($result);
249
    }
250
251
    /**
252
     * @param int $categoryId
253
     */
254
    public static function deleteAllUserInCategory($categoryId)
255
    {
256
        $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
257
        $categoryId = (int) $categoryId;
258
        $sql = "DELETE FROM $table WHERE category_id = $categoryId";
259
        Database::query($sql);
260
    }
261
262
    /**
263
     * Get all possible tickets statuses.
264
     *
265
     * @return array
266
     */
267
    public static function get_all_tickets_status()
268
    {
269
        $table = Database::get_main_table(TABLE_TICKET_STATUS);
270
        $sql = "SELECT * FROM $table";
271
        $result = Database::query($sql);
272
        $types = [];
273
        while ($row = Database::fetch_assoc($result)) {
274
            $types[] = $row;
275
        }
276
277
        return $types;
278
    }
279
280
    /**
281
     * Inserts a new ticket in the corresponding tables.
282
     *
283
     * @param int      $category_id
284
     * @param int      $course_id
285
     * @param int      $sessionId
286
     * @param int      $project_id
287
     * @param string   $other_area
288
     * @param string   $subject
289
     * @param string   $content
290
     * @param string   $personalEmail
291
     * @param array    $fileAttachments
292
     * @param string   $source
293
     * @param string   $priority
294
     * @param string   $status
295
     * @param int|null $assignedUserId
296
     * @param int      $exerciseId
297
     * @param int      $lpId
298
     *
299
     * @return bool
300
     */
301
    public static function add(
302
        $category_id,
303
        $course_id,
304
        $sessionId,
305
        $project_id,
306
        $other_area,
307
        $subject,
308
        $content,
309
        $personalEmail = '',
310
        $fileAttachments = [],
311
        $source = '',
312
        $priority = '',
313
        $status = '',
314
        $assignedUserId = null,
315
        $exerciseId = null,
316
        $lpId = null
317
    ) {
318
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
319
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
320
321
        if (empty($category_id)) {
322
            return false;
323
        }
324
325
        $currentUserId = api_get_user_id();
326
        $currentUserInfo = api_get_user_info();
327
        $now = api_get_utc_datetime();
328
        $course_id = (int) $course_id;
329
        $category_id = (int) $category_id;
330
        $project_id = (int) $project_id;
331
        $priority = empty($priority) ? self::PRIORITY_NORMAL : (int) $priority;
332
333
        if ('' === $status) {
334
            $status = self::STATUS_NEW;
335
            if ($other_area > 0) {
336
                $status = self::STATUS_FORWARDED;
337
            }
338
        }
339
340
        if (empty($assignedUserId)) {
341
            $usersInCategory = self::getUsersInCategory($category_id);
342
            if (!empty($usersInCategory) && count($usersInCategory) > 0) {
343
                $userCategoryInfo = $usersInCategory[0];
344
                if (isset($userCategoryInfo['user_id'])) {
345
                    $assignedUserId = $userCategoryInfo['user_id'];
346
                }
347
            }
348
        }
349
350
        $assignedUserInfo = [];
351
        if (!empty($assignedUserId)) {
352
            $assignedUserInfo = api_get_user_info($assignedUserId);
353
            if (empty($assignedUserInfo)) {
354
                return false;
355
            }
356
        }
357
358
        // insert_ticket
359
        $params = [
360
            'project_id' => $project_id,
361
            'category_id' => $category_id,
362
            'priority_id' => $priority,
363
            'personal_email' => $personalEmail,
364
            'status_id' => $status,
365
            'start_date' => $now,
366
            'sys_insert_user_id' => $currentUserId,
367
            'sys_insert_datetime' => $now,
368
            'sys_lastedit_user_id' => $currentUserId,
369
            'sys_lastedit_datetime' => $now,
370
            'source' => $source,
371
            'assigned_last_user' => $assignedUserId,
372
            'subject' => $subject,
373
            'message' => $content,
374
            'code' => '',
375
            'total_messages' => 0,
376
        ];
377
378
        if (!empty($exerciseId)) {
379
            $params['exercise_id'] = $exerciseId;
380
        }
381
382
        if (!empty($lpId)) {
383
            $params['lp_id'] = $lpId;
384
        }
385
        if (!empty($course_id)) {
386
            $params['course_id'] = $course_id;
387
        }
388
389
        if (!empty($sessionId)) {
390
            $params['session_id'] = $sessionId;
391
        }
392
        $ticketId = Database::insert($table_support_tickets, $params);
393
394
        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...
395
            self::subscribeUserToTicket($ticketId, $currentUserId);
396
            $ticket_code = 'A'.str_pad($ticketId, 11, '0', STR_PAD_LEFT);
397
            $titleCreated = sprintf(
398
                get_lang('Ticket %s created'),
399
                $ticket_code
400
            );
401
402
            Display::addFlash(Display::return_message(
403
                $titleCreated,
404
                'normal',
405
                false
406
            ));
407
408
            if (0 != $assignedUserId) {
409
                self::assignTicketToUser(
410
                    $ticketId,
411
                    $assignedUserId
412
                );
413
414
                Display::addFlash(Display::return_message(
415
                    sprintf(
416
                        get_lang('Ticket <b>#%s</b> assigned to user <b>%s</b>'),
417
                        $ticket_code,
418
                        $assignedUserInfo['complete_name']
419
                    ),
420
                    'normal',
421
                    false
422
                ));
423
            }
424
425
            if (!empty($fileAttachments)) {
426
                $attachmentCount = 0;
427
                foreach ($fileAttachments as $attach) {
428
                    if (!empty($attach['tmp_name'])) {
429
                        $attachmentCount++;
430
                    }
431
                }
432
                if ($attachmentCount > 0) {
433
                    self::insertMessage(
434
                        $ticketId,
435
                        '',
436
                        '',
437
                        $fileAttachments,
438
                        $currentUserId
439
                    );
440
                }
441
            }
442
443
            // Update code
444
            $sql = "UPDATE $table_support_tickets
445
                    SET code = '$ticket_code'
446
                    WHERE id = '$ticketId'";
447
            Database::query($sql);
448
449
            // Update total
450
            $sql = "UPDATE $table_support_category
451
                    SET total_tickets = total_tickets + 1
452
                    WHERE id = $category_id";
453
            Database::query($sql);
454
455
            $helpDeskMessage =
456
                '<table>
457
                        <tr>
458
                            <td width="100px"><b>'.get_lang('User').'</b></td>
459
                            <td width="400px">'.$currentUserInfo['complete_name'].'</td>
460
                        </tr>
461
                        <tr>
462
                            <td width="100px"><b>'.get_lang('Username').'</b></td>
463
                            <td width="400px">'.$currentUserInfo['username'].'</td>
464
                        </tr>
465
                        <tr>
466
                            <td width="100px"><b>'.get_lang('Email').'</b></td>
467
                            <td width="400px">'.$currentUserInfo['email'].'</td>
468
                        </tr>
469
                        <tr>
470
                            <td width="100px"><b>'.get_lang('Phone').'</b></td>
471
                            <td width="400px">'.$currentUserInfo['phone'].'</td>
472
                        </tr>
473
                        <tr>
474
                            <td width="100px"><b>'.get_lang('Date').'</b></td>
475
                            <td width="400px">'.api_convert_and_format_date($now, DATE_TIME_FORMAT_LONG).'</td>
476
                        </tr>
477
                        <tr>
478
                            <td width="100px"><b>'.get_lang('Title').'</b></td>
479
                            <td width="400px">'.Security::remove_XSS($subject).'</td>
0 ignored issues
show
Bug introduced by
Are you sure Security::remove_XSS($subject) of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

479
                            <td width="400px">'./** @scrutinizer ignore-type */ Security::remove_XSS($subject).'</td>
Loading history...
480
                        </tr>
481
                        <tr>
482
                            <td width="100px"><b>'.get_lang('Description').'</b></td>
483
                            <td width="400px">'.Security::remove_XSS($content).'</td>
0 ignored issues
show
Bug introduced by
Are you sure Security::remove_XSS($content) of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

483
                            <td width="400px">'./** @scrutinizer ignore-type */ Security::remove_XSS($content).'</td>
Loading history...
484
                        </tr>
485
                    </table>';
486
487
            if (0 != $assignedUserId) {
488
                $href = api_get_path(WEB_CODE_PATH).'ticket/ticket_details.php?ticket_id='.$ticketId;
489
                $helpDeskMessage .= sprintf(
490
                    get_lang("Ticket assigned to %s. Follow-up at <a href='%s'>#%s</a>."),
491
                    $assignedUserInfo['complete_name'],
492
                    $href,
493
                    $ticketId
494
                );
495
            }
496
497
            if (empty($category_id)) {
498
                if ('true' === api_get_setting('ticket_send_warning_to_all_admins')) {
499
                    $warningSubject = sprintf(
500
                        get_lang('Ticket %s was created without a category'),
501
                        $ticket_code
502
                    );
503
                    Display::addFlash(Display::return_message($warningSubject));
504
505
                    $admins = UserManager::get_all_administrators();
506
                    foreach ($admins as $userId => $data) {
507
                        if ($data['active']) {
508
                            MessageManager::send_message_simple(
509
                                $userId,
510
                                $warningSubject,
511
                                $helpDeskMessage
512
                            );
513
                        }
514
                    }
515
                }
516
            } else {
517
                $categoryInfo = self::getCategory($category_id);
518
                $usersInCategory = self::getUsersInCategory($category_id);
519
                $message = '<h2>'.get_lang('Ticket info').'</h2><br />'.$helpDeskMessage;
520
521
                if ('true' === api_get_setting('ticket_warn_admin_no_user_in_category')) {
522
                    $usersInCategory = self::getUsersInCategory($category_id);
523
                    if (empty($usersInCategory)) {
524
                        $subject = sprintf(
525
                            get_lang('Warning: No one has been assigned to category %s'),
526
                            $categoryInfo['title']
527
                        );
528
529
                        if ('true' === api_get_setting('ticket_send_warning_to_all_admins')) {
530
                            Display::addFlash(Display::return_message(
531
                                sprintf(
532
                                    get_lang(
533
                                        'A notification was sent to the administrators to report this category has no user assigned'
534
                                    ),
535
                                    $categoryInfo['title']
536
                                ),
537
                                null,
538
                                false
539
                            ));
540
541
                            $admins = UserManager::get_all_administrators();
542
                            foreach ($admins as $userId => $data) {
543
                                if ($data['active']) {
544
                                    self::sendNotification(
545
                                        $ticketId,
546
                                        $subject,
547
                                        $message,
548
                                        $userId
549
                                    );
550
                                }
551
                            }
552
                        } else {
553
                            Display::addFlash(Display::return_message($subject));
554
                        }
555
                    }
556
                }
557
558
                // Send notification to all users
559
                if (!empty($usersInCategory)) {
560
                    foreach ($usersInCategory as $data) {
561
                        if ($data['user_id'] && $data['user_id'] !== $currentUserId) {
562
                            self::sendNotification(
563
                                $ticketId,
564
                                $titleCreated,
565
                                $helpDeskMessage,
566
                                $data['user_id']
567
                            );
568
                        }
569
                    }
570
                }
571
            }
572
573
            if (!empty($personalEmail)) {
574
                api_mail_html(
575
                    get_lang('Virtual support'),
576
                    $personalEmail,
577
                    get_lang('The incident has been sent to the virtual support team again'),
578
                    $helpDeskMessage
579
                );
580
            }
581
582
            self::sendNotification(
583
                $ticketId,
584
                $titleCreated,
585
                $helpDeskMessage
586
            );
587
588
            return true;
589
        }
590
591
        return false;
592
    }
593
594
    /**
595
     * Assign ticket to admin.
596
     *
597
     * @param int $ticketId
598
     * @param int $userId
599
     *
600
     * @return bool
601
     */
602
    public static function assignTicketToUser(
603
        $ticketId,
604
        $userId
605
    ) {
606
        $ticketId = (int) $ticketId;
607
        $userId = (int) $userId;
608
609
        if (empty($ticketId)) {
610
            return false;
611
        }
612
613
        $ticket = self::get_ticket_detail_by_id($ticketId);
614
615
        if ($ticket) {
616
            $table = Database::get_main_table(TABLE_TICKET_TICKET);
617
            $sql = "UPDATE $table
618
                    SET assigned_last_user = $userId
619
                    WHERE id = $ticketId";
620
            Database::query($sql);
621
622
            $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
623
            $params = [
624
                'ticket_id' => $ticketId,
625
                'user_id' => $userId,
626
                'sys_insert_user_id' => api_get_user_id(),
627
                'assigned_date' => api_get_utc_datetime(),
628
            ];
629
            Database::insert($table, $params);
630
631
            return true;
632
        } else {
633
            return false;
634
        }
635
    }
636
637
    /**
638
     * Insert message between Users and Admins.
639
     *
640
     * @param int    $ticketId
641
     * @param string $subject
642
     * @param string $content
643
     * @param array  $fileAttachments
644
     * @param int    $userId
645
     * @param string $status
646
     * @param bool   $sendConfirmation
647
     *
648
     * @return bool
649
     */
650
    public static function insertMessage(
651
        $ticketId,
652
        $subject,
653
        $content,
654
        $fileAttachments,
655
        $userId,
656
        $status = 'NOL',
657
        $sendConfirmation = false
658
    ) {
659
        $ticketId = (int) $ticketId;
660
        $userId = (int) $userId;
661
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
662
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
663
        if ($sendConfirmation) {
664
            $form =
665
                '<form action="ticket_details.php?ticket_id='.$ticketId.'" id="confirmticket" method="POST" >
666
                     <p>'.get_lang('Was this answer satisfactory?').'</p>
667
                     <button class="btn btn--primary responseyes" name="response" id="responseyes" value="1">'.
668
                get_lang('Yes').'</button>
669
                     <button class="btn btn--danger responseno" name="response" id="responseno" value="0">'.
670
                get_lang('No').'</button>
671
                 </form>';
672
            $content .= $form;
673
        }
674
675
        $now = api_get_utc_datetime();
676
677
        $params = [
678
            'ticket_id' => $ticketId,
679
            'subject' => $subject,
680
            'message' => $content,
681
            'ip_address' => api_get_real_ip(),
682
            'sys_insert_user_id' => $userId,
683
            'sys_insert_datetime' => $now,
684
            'sys_lastedit_user_id' => $userId,
685
            'sys_lastedit_datetime' => $now,
686
            'status' => $status,
687
        ];
688
        $messageId = Database::insert($table_support_messages, $params);
689
        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...
690
            // update_total_message
691
            $sql = "UPDATE $table_support_tickets
692
                    SET
693
                        sys_lastedit_user_id = $userId,
694
                        sys_lastedit_datetime = '$now',
695
                        total_messages = (
696
                            SELECT COUNT(*) as total_messages
697
                            FROM $table_support_messages
698
                            WHERE ticket_id = $ticketId
699
                        )
700
                    WHERE id = $ticketId ";
701
            Database::query($sql);
702
703
            if (is_array($fileAttachments)) {
704
                foreach ($fileAttachments as $file_attach) {
705
                    if (0 == $file_attach['error']) {
706
                        self::saveMessageAttachmentFile(
707
                            $file_attach,
708
                            $ticketId,
709
                            $messageId
710
                        );
711
                    } else {
712
                        if (UPLOAD_ERR_NO_FILE != $file_attach['error']) {
713
                            return false;
714
                        }
715
                    }
716
                }
717
            }
718
719
            if (!self::isUserSubscribedToTicket($ticketId, $userId)) {
720
                self::subscribeUserToTicket($ticketId, $userId);
721
            }
722
        }
723
724
        return true;
725
    }
726
727
    /**
728
     * Attachment files when a message is sent.
729
     *
730
     * @throws \Doctrine\ORM\ORMException
731
     * @throws \Doctrine\ORM\OptimisticLockException
732
     * @throws \Doctrine\ORM\TransactionRequiredException
733
     */
734
    public static function saveMessageAttachmentFile(
735
        $fileAttach,
736
        $ticketId,
737
        $messageId
738
    ): bool {
739
        if (!is_array($fileAttach) || UPLOAD_ERR_OK != $fileAttach['error']) {
740
            return false;
741
        }
742
743
        $em = Database::getManager();
744
745
        $ticket = $em->find(Ticket::class, $ticketId);
746
        $message = $em->find(TicketMessage::class, $messageId);
747
748
        $newFileName = add_ext_on_mime(
749
            stripslashes($fileAttach['name']),
750
            $fileAttach['type']
751
        );
752
753
        $fileName = $fileAttach['name'];
754
755
        if (!filter_extension($newFileName)) {
756
            Display::addFlash(
757
                Display::return_message(
758
                    get_lang('File upload failed: this file extension or file type is prohibited'),
759
                    'error'
760
                )
761
            );
762
763
            return false;
764
        }
765
766
        $currentUser = api_get_user_entity();
767
768
        $repo = Container::getTicketMessageAttachmentRepository();
769
        $attachment = (new TicketMessageAttachment())
770
            ->setFilename($fileName)
771
            ->setPath(uniqid('ticket_message', true))
772
            ->setMessage($message)
773
            ->setSize((int) $fileAttach['size'])
774
            ->setTicket($ticket)
775
            ->setInsertUserId($currentUser->getId())
776
            ->setInsertDateTime(api_get_utc_datetime(null, false, true))
777
            ->setParent($currentUser)
778
        ;
779
780
        if (null !== $ticket->getAssignedLastUser()) {
781
            $attachment->addUserLink($ticket->getAssignedLastUser());
782
        }
783
784
        $em->persist($attachment);
785
        $em->flush();
786
787
        $file = new UploadedFile($fileAttach['tmp_name'], $fileAttach['name'], $fileAttach['type'], $fileAttach['error']);
788
789
        $repo->addFile($attachment, $file);
790
791
        return true;
792
    }
793
794
    /**
795
     * Get tickets by userId.
796
     *
797
     * @param int $from
798
     * @param int $number_of_items
799
     * @param $column
800
     * @param $direction
801
     *
802
     * @return array
803
     */
804
    public static function getTicketsByCurrentUser($from, $number_of_items, $column, $direction)
805
    {
806
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
807
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
808
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
809
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
810
        $direction = !empty($direction) ? $direction : 'DESC';
811
        $userId = api_get_user_id();
812
        $userInfo = api_get_user_info($userId);
813
814
        if (empty($userInfo)) {
815
            return [];
816
        }
817
        $isAdmin = UserManager::is_admin($userId);
818
819
        if (!isset($_GET['project_id'])) {
820
            return [];
821
        }
822
823
        switch ($column) {
824
            case 0:
825
                $column = 'ticket_id';
826
                break;
827
            case 1:
828
                $column = 'status_title';
829
                break;
830
            case 2:
831
                $column = 'start_date';
832
                break;
833
            case 3:
834
                $column = 'sys_lastedit_datetime';
835
                break;
836
            case 4:
837
                $column = 'category_title';
838
                break;
839
            case 5:
840
                $column = 'sys_insert_user_id';
841
                break;
842
            case 6:
843
                $column = 'assigned_last_user';
844
                break;
845
            case 7:
846
                $column = 'total_messages';
847
                break;
848
            case 8:
849
                $column = 'subject';
850
                break;
851
            default:
852
                $column = 'ticket_id';
853
        }
854
855
        $sql = "SELECT DISTINCT
856
                ticket.*,
857
                ticket.id ticket_id,
858
                status.title AS status_title,
859
                ticket.start_date,
860
                ticket.sys_lastedit_datetime,
861
                cat.title AS category_title,
862
                priority.title AS priority_title,
863
                ticket.total_messages AS total_messages,
864
                ticket.message AS message,
865
                ticket.subject AS subject,
866
                ticket.assigned_last_user
867
            FROM $table_support_tickets ticket
868
            INNER JOIN $table_support_category cat
869
            ON (cat.id = ticket.category_id)
870
            INNER JOIN $table_support_priority priority
871
            ON (ticket.priority_id = priority.id)
872
            INNER JOIN $table_support_status status
873
            ON (ticket.status_id = status.id)
874
            WHERE 1=1
875
        ";
876
877
        $projectId = (int) $_GET['project_id'];
878
        $userIsAllowInProject = self::userIsAllowInProject($projectId);
0 ignored issues
show
Deprecated Code introduced by
The function TicketManager::userIsAllowInProject() has been deprecated: Use TicketProjectHelper::userIsAllowInProject instead ( Ignorable by Annotation )

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

878
        $userIsAllowInProject = /** @scrutinizer ignore-deprecated */ self::userIsAllowInProject($projectId);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
879
880
        // Check if a role was set to the project
881
        if (false == $userIsAllowInProject) {
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...
882
            $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
883
        }
884
885
        // Search simple
886
        if (isset($_GET['submit_simple']) && '' != $_GET['keyword']) {
887
            $keyword = Database::escape_string(trim($_GET['keyword']));
888
            $sql .= " AND (
889
                      ticket.id LIKE '%$keyword%' OR
890
                      ticket.code LIKE '%$keyword%' OR
891
                      ticket.subject LIKE '%$keyword%' OR
892
                      ticket.message LIKE '%$keyword%' OR
893
                      ticket.keyword LIKE '%$keyword%' OR
894
                      ticket.source LIKE '%$keyword%' OR
895
                      cat.title LIKE '%$keyword%' OR
896
                      status.title LIKE '%$keyword%' OR
897
                      priority.title LIKE '%$keyword%' OR
898
                      ticket.personal_email LIKE '%$keyword%'
899
            )";
900
        }
901
902
        $keywords = [
903
            'project_id' => 'ticket.project_id',
904
            'keyword_category' => 'ticket.category_id',
905
            'keyword_assigned_to' => 'ticket.assigned_last_user',
906
            'keyword_source' => 'ticket.source ',
907
            'keyword_status' => 'ticket.status_id',
908
            'keyword_priority' => 'ticket.priority_id',
909
        ];
910
911
        foreach ($keywords as $keyword => $label) {
912
            if (isset($_GET[$keyword])) {
913
                $data = Database::escape_string(trim($_GET[$keyword]));
914
                if (!empty($data)) {
915
                    $sql .= " AND $label = '$data' ";
916
                }
917
            }
918
        }
919
920
        // Search advanced
921
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
922
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
923
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
924
        $keyword_range = !empty($keyword_start_date_start) && !empty($keyword_start_date_end);
925
926
        if (false == $keyword_range && '' != $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...
927
            $sql .= " AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start' ";
928
        }
929
        if ($keyword_range && '' != $keyword_start_date_start && '' != $keyword_start_date_end) {
930
            $sql .= " AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
931
                      AND DATE_FORMAT(ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
932
        }
933
934
        if ('' != $keyword_course) {
935
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
936
            $sql .= " AND ticket.course_id IN (
937
                     SELECT id FROM $course_table
938
                     WHERE (
939
                        title LIKE '%$keyword_course%' OR
940
                        code LIKE '%$keyword_course%' OR
941
                        visual_code LIKE '%$keyword_course%'
942
                     )
943
            )";
944
        }
945
        $sql .= " ORDER BY `$column` $direction";
946
        $sql .= " LIMIT $from, $number_of_items";
947
948
        $result = Database::query($sql);
949
        $tickets = [];
950
        $webPath = api_get_path(WEB_PATH);
951
        while ($row = Database::fetch_assoc($result)) {
952
            $userInfo = api_get_user_info($row['sys_insert_user_id']);
953
            $hrefUser = $webPath.'main/admin/user_information.php?user_id='.$userInfo['user_id'];
954
            $name = "<a href='$hrefUser'> {$userInfo['complete_name_with_username']} </a>";
955
            if (0 != $row['assigned_last_user']) {
956
                $assignedUserInfo = api_get_user_info($row['assigned_last_user']);
957
                if (!empty($assignedUserInfo)) {
958
                    $hrefResp = $webPath.'main/admin/user_information.php?user_id='.$assignedUserInfo['user_id'];
959
                    $row['assigned_last_user'] = "<a href='$hrefResp'> {$assignedUserInfo['complete_name_with_username']} </a>";
960
                } else {
961
                    $row['assigned_last_user'] = get_lang('Unknown user');
962
                }
963
            } else {
964
                if (self::STATUS_FORWARDED !== $row['status_id']) {
965
                    $row['assigned_last_user'] = '<span style="color:#ff0000;">'.get_lang('To be assigned').'</span>';
966
                } else {
967
                    $row['assigned_last_user'] = '<span style="color:#00ff00;">'.get_lang('Message resent').'</span>';
968
                }
969
            }
970
971
            switch ($row['source']) {
972
                case self::SOURCE_PRESENTIAL:
973
                    $img_source = ObjectIcon::USER;
974
                    break;
975
                case self::SOURCE_EMAIL:
976
                    $img_source = ObjectIcon::EMAIL;
977
                    break;
978
                case self::SOURCE_PHONE:
979
                    $img_source = ObjectIcon::PHONE;
980
                    break;
981
                default:
982
                    $img_source = ObjectIcon::TICKET;
983
                    break;
984
            }
985
986
            $row['start_date'] = Display::dateToStringAgoAndLongDate($row['start_date']);
987
            $row['sys_lastedit_datetime'] = Display::dateToStringAgoAndLongDate($row['sys_lastedit_datetime']);
988
989
            $icon = Display::getMdiIcon(
990
                $img_source,
991
                'ch-tool-icon',
992
                'margin-right: 10px; float: left;',
993
                ICON_SIZE_SMALL,
994
                get_lang('Information'),
995
            );
996
997
            $icon .= '<a href="ticket_details.php?ticket_id='.$row['id'].'">'.$row['code'].'</a>';
998
999
            if ($isAdmin) {
1000
                $ticket = [
1001
                    $icon.' '.Security::remove_XSS($row['subject']),
0 ignored issues
show
Bug introduced by
Are you sure Security::remove_XSS($row['subject']) of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

1001
                    $icon.' './** @scrutinizer ignore-type */ Security::remove_XSS($row['subject']),
Loading history...
1002
                    $row['status_title'],
1003
                    $row['start_date'],
1004
                    $row['sys_lastedit_datetime'],
1005
                    $row['category_title'],
1006
                    $name,
1007
                    $row['assigned_last_user'],
1008
                    $row['total_messages'],
1009
                ];
1010
            } else {
1011
                $ticket = [
1012
                    $icon.' '.Security::remove_XSS($row['subject']),
1013
                    $row['status_title'],
1014
                    $row['start_date'],
1015
                    $row['sys_lastedit_datetime'],
1016
                    $row['category_title'],
1017
                ];
1018
            }
1019
            if ($isAdmin) {
1020
                $ticket['0'] .= '&nbsp;&nbsp;<a
1021
                href="javascript:void(0)"
1022
                onclick="load_history_ticket(\'div_'.$row['ticket_id'].'\','.$row['ticket_id'].')">
1023
                    <a
1024
                        onclick="load_course_list(\'div_'.$row['ticket_id'].'\','.$row['ticket_id'].')"
1025
					    onmouseover="clear_course_list (\'div_'.$row['ticket_id'].'\')"
1026
					    title="'.get_lang('History').'"
1027
					    alt="'.get_lang('History').'"
1028
                    >
1029
                    '.Display::getMdiIcon('history').'
1030
                    </a>
1031
1032
					<div class="blackboard_hide" id="div_'.$row['ticket_id'].'">&nbsp;&nbsp;</div>
1033
					</a>&nbsp;&nbsp;';
1034
            }
1035
            $tickets[] = $ticket;
1036
        }
1037
1038
        return $tickets;
1039
    }
1040
1041
    /**
1042
     * @return int
1043
     */
1044
    public static function getTotalTicketsCurrentUser()
1045
    {
1046
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1047
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1048
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1049
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1050
1051
        $userInfo = api_get_user_info();
1052
        if (empty($userInfo)) {
1053
            return 0;
1054
        }
1055
        $userId = $userInfo['id'];
1056
1057
        if (!isset($_GET['project_id'])) {
1058
            return 0;
1059
        }
1060
1061
        $sql = "SELECT COUNT(ticket.id) AS total
1062
                FROM $table_support_tickets ticket
1063
                INNER JOIN $table_support_category cat
1064
                ON (cat.id = ticket.category_id)
1065
                INNER JOIN $table_support_priority priority
1066
                ON (ticket.priority_id = priority.id)
1067
                INNER JOIN $table_support_status status
1068
                ON (ticket.status_id = status.id)
1069
	            WHERE 1 = 1";
1070
1071
        $projectId = (int) $_GET['project_id'];
1072
        $allowRoleList = self::getAllowedRolesFromProject($projectId);
0 ignored issues
show
Deprecated Code introduced by
The function TicketManager::getAllowedRolesFromProject() has been deprecated: Use TicketProjectHelper::getAllowedRolesFromProject instead ( Ignorable by Annotation )

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

1072
        $allowRoleList = /** @scrutinizer ignore-deprecated */ self::getAllowedRolesFromProject($projectId);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1073
1074
        // Check if a role was set to the project
1075
        if (!empty($allowRoleList) && is_array($allowRoleList)) {
1076
            $allowed = self::userIsAllowInProject($projectId);
0 ignored issues
show
Deprecated Code introduced by
The function TicketManager::userIsAllowInProject() has been deprecated: Use TicketProjectHelper::userIsAllowInProject instead ( Ignorable by Annotation )

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

1076
            $allowed = /** @scrutinizer ignore-deprecated */ self::userIsAllowInProject($projectId);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1077
            if (!$allowed) {
1078
                $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
1079
            }
1080
        } else {
1081
            if (!api_is_platform_admin()) {
1082
                $sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId )";
1083
            }
1084
        }
1085
1086
        // Search simple
1087
        if (isset($_GET['submit_simple'])) {
1088
            if ('' != $_GET['keyword']) {
1089
                $keyword = Database::escape_string(trim($_GET['keyword']));
1090
                $sql .= " AND (
1091
                          ticket.code LIKE '%$keyword%' OR
1092
                          ticket.subject LIKE '%$keyword%' OR
1093
                          ticket.message LIKE '%$keyword%' OR
1094
                          ticket.keyword LIKE '%$keyword%' OR
1095
                          ticket.personal_email LIKE '%$keyword%' OR
1096
                          ticket.source LIKE '%$keyword%'
1097
                )";
1098
            }
1099
        }
1100
1101
        $keywords = [
1102
            'project_id' => 'ticket.project_id',
1103
            'keyword_category' => 'ticket.category_id',
1104
            'keyword_assigned_to' => 'ticket.assigned_last_user',
1105
            'keyword_source' => 'ticket.source',
1106
            'keyword_status' => 'ticket.status_id',
1107
            'keyword_priority' => 'ticket.priority_id',
1108
        ];
1109
1110
        foreach ($keywords as $keyword => $sqlLabel) {
1111
            if (isset($_GET[$keyword])) {
1112
                $data = Database::escape_string(trim($_GET[$keyword]));
1113
                $sql .= " AND $sqlLabel = '$data' ";
1114
            }
1115
        }
1116
1117
        // Search advanced
1118
        $keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
1119
        $keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
1120
        $keyword_range = isset($_GET['keyword_dates']) ? Database::escape_string(trim($_GET['keyword_dates'])) : '';
1121
        $keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
1122
1123
        if (false == $keyword_range && '' != $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...
1124
            $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1125
        }
1126
        if ($keyword_range && '' != $keyword_start_date_start && '' != $keyword_start_date_end) {
1127
            $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1128
                      AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1129
        }
1130
        if ('' != $keyword_course) {
1131
            $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1132
            $sql .= " AND ticket.course_id IN (
1133
                        SELECT id
1134
                        FROM $course_table
1135
                        WHERE (
1136
                            title LIKE '%$keyword_course%' OR
1137
                            code LIKE '%$keyword_course%' OR
1138
                            visual_code LIKE '%$keyword_course%'
1139
                        )
1140
                   ) ";
1141
        }
1142
1143
        $res = Database::query($sql);
1144
        $obj = Database::fetch_object($res);
1145
1146
        return (int) $obj->total;
1147
    }
1148
1149
    /**
1150
     * @param int $id
1151
     *
1152
     * @return false|TicketMessageAttachment
1153
     */
1154
    public static function getTicketMessageAttachment($id)
1155
    {
1156
        $id = (int) $id;
1157
        $em = Database::getManager();
1158
        $item = $em->getRepository(TicketMessageAttachment::class)->find($id);
1159
        if ($item) {
1160
            return $item;
1161
        }
1162
1163
        return false;
1164
    }
1165
1166
    /**
1167
     * @param int $id
1168
     *
1169
     * @return array
1170
     */
1171
    public static function getTicketMessageAttachmentsByTicketId($id)
1172
    {
1173
        $id = (int) $id;
1174
        $em = Database::getManager();
1175
        $items = $em->getRepository(TicketMessageAttachment::class)->findBy(['ticket' => $id]);
1176
        if ($items) {
1177
            return $items;
1178
        }
1179
1180
        return false;
1181
    }
1182
1183
    /**
1184
     * @param int $ticketId
1185
     *
1186
     * @return array
1187
     */
1188
    public static function get_ticket_detail_by_id($ticketId)
1189
    {
1190
        $attachmentRepo = Container::getTicketMessageAttachmentRepository();
1191
1192
        $ticketId = (int) $ticketId;
1193
        $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY);
1194
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1195
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1196
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1197
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1198
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1199
1200
        $sql = "SELECT
1201
                    ticket.*,
1202
                    cat.title,
1203
                    status.title as status,
1204
                    priority.title priority
1205
                FROM $table_support_tickets ticket
1206
                INNER JOIN $table_support_category cat
1207
                ON (cat.id = ticket.category_id)
1208
                INNER JOIN $table_support_priority priority
1209
                ON (priority.id = ticket.priority_id)
1210
                INNER JOIN $table_support_status status
1211
                ON (status.id = ticket.status_id)
1212
		        WHERE
1213
                    ticket.id = $ticketId ";
1214
        $result = Database::query($sql);
1215
        $ticket = [];
1216
1217
        $repo = Container::getLpRepository();
1218
        if (Database::num_rows($result) > 0) {
1219
            while ($row = Database::fetch_assoc($result)) {
1220
                $row['course'] = null;
1221
                $row['start_date_from_db'] = $row['start_date'];
1222
                $row['start_date'] = api_convert_and_format_date(
1223
                    api_get_local_time($row['start_date']),
1224
                    DATE_TIME_FORMAT_LONG,
1225
                    api_get_timezone()
1226
                );
1227
                $row['end_date_from_db'] = $row['end_date'];
1228
                $row['end_date'] = api_convert_and_format_date(
1229
                    api_get_local_time($row['end_date']),
1230
                    DATE_TIME_FORMAT_LONG,
1231
                    api_get_timezone()
1232
                );
1233
                $row['sys_lastedit_datetime_from_db'] = $row['sys_lastedit_datetime'];
1234
                $row['sys_lastedit_datetime'] = api_convert_and_format_date(
1235
                    api_get_local_time($row['sys_lastedit_datetime']),
1236
                    DATE_TIME_FORMAT_LONG,
1237
                    api_get_timezone()
1238
                );
1239
                $row['course_url'] = null;
1240
                if (0 != $row['course_id']) {
1241
                    $course = api_get_course_info_by_id($row['course_id']);
1242
                    $sessionId = 0;
1243
                    if ($row['session_id']) {
1244
                        $sessionId = $row['session_id'];
1245
                    }
1246
                    if ($course) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $course of type array 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...
1247
                        $row['course_url'] = '<a href="'.$course['course_public_url'].'?id_session='.$sessionId.'">'.$course['name'].'</a>';
1248
                    }
1249
                    $row['exercise_url'] = null;
1250
1251
                    if (!empty($row['exercise_id'])) {
1252
                        $exerciseTitle = ExerciseLib::getExerciseTitleById($row['exercise_id']);
1253
                        $dataExercise = [
1254
                            'cidReq' => $course['code'],
1255
                            'id_session' => $sessionId,
1256
                            'exerciseId' => $row['exercise_id'],
1257
                        ];
1258
                        $urlParamsExercise = http_build_query($dataExercise);
1259
1260
                        $row['exercise_url'] = '<a href="'.api_get_path(WEB_CODE_PATH).'exercise/overview.php?'.$urlParamsExercise.'">'.$exerciseTitle.'</a>';
1261
                    }
1262
1263
                    $row['lp_url'] = null;
1264
1265
                    if (!empty($row['lp_id'])) {
1266
                        /** @var CLp $lp */
1267
                        $lp = $repo->find($row['lp_id']);
1268
                        $dataLp = [
1269
                            'cidReq' => $course['code'],
1270
                            'id_session' => $sessionId,
1271
                            'lp_id' => $row['lp_id'],
1272
                            'action' => 'view',
1273
                        ];
1274
                        $urlParamsLp = http_build_query($dataLp);
1275
1276
                        $row['lp_url'] = '<a
1277
                            href="'.api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.$urlParamsLp.'">'.
1278
                            $lp->getTitle().
1279
                        '</a>';
1280
                    }
1281
                }
1282
1283
                $userInfo = api_get_user_info($row['sys_insert_user_id']);
1284
                $row['user_url'] = '<a href="'.api_get_path(WEB_PATH).'main/admin/user_information.php?user_id='.$userInfo['user_id'].'">
1285
                '.$userInfo['complete_name'].'</a>';
1286
                $ticket['user'] = $userInfo;
1287
                $ticket['ticket'] = $row;
1288
            }
1289
1290
            $sql = "SELECT *, message.id as message_id, user.id AS user_id
1291
                    FROM $table_support_messages message
1292
                    INNER JOIN $table_main_user user
1293
                    ON (message.sys_insert_user_id = user.id)
1294
                    WHERE user.active <> ".USER_SOFT_DELETED." AND
1295
                        message.ticket_id = '$ticketId' ";
1296
            $result = Database::query($sql);
1297
            $ticket['messages'] = [];
1298
            $attach_icon = Display::getMdiIcon(ObjectIcon::ATTACHMENT, 'ch-tool-icon', null, ICON_SIZE_SMALL);
1299
1300
            while ($row = Database::fetch_assoc($result)) {
1301
                $message = $row;
1302
                $message['admin'] = UserManager::is_admin($message['user_id']);
1303
                $message['user_info'] = api_get_user_info($message['user_id']);
1304
1305
                $messageAttachments = $attachmentRepo->findBy(['ticket' => $ticketId, 'message' => $row['message_id']]);
1306
1307
                /** @var TicketMessageAttachment $messageAttachment */
1308
                foreach ($messageAttachments as $messageAttachment) {
1309
                    $archiveURL = $attachmentRepo->getResourceFileDownloadUrl($messageAttachment);
1310
                    $link = Display::url(
1311
                        sprintf("%s (%d)", $messageAttachment->getFilename(), $messageAttachment->getSize()),
1312
                        $archiveURL
1313
                    );
1314
1315
                    $message['attachments'][] = $attach_icon.PHP_EOL.$link;
1316
                }
1317
                $ticket['messages'][] = $message;
1318
            }
1319
        }
1320
1321
        return $ticket;
1322
    }
1323
1324
    /**
1325
     * @param int $ticketId
1326
     * @param int $userId
1327
     *
1328
     * @return bool
1329
     */
1330
    public static function update_message_status($ticketId, $userId)
1331
    {
1332
        $ticketId = (int) $ticketId;
1333
        $userId = (int) $userId;
1334
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1335
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1336
        $now = api_get_utc_datetime();
1337
        $sql = "UPDATE $table_support_messages
1338
                SET
1339
                    status = 'LEI',
1340
                    sys_lastedit_user_id ='".api_get_user_id()."',
1341
                    sys_lastedit_datetime ='".$now."'
1342
                WHERE ticket_id ='$ticketId' ";
1343
1344
        if (api_is_platform_admin()) {
1345
            $sql .= " AND sys_insert_user_id = '$userId'";
1346
        } else {
1347
            $sql .= " AND sys_insert_user_id != '$userId'";
1348
        }
1349
        $result = Database::query($sql);
1350
        if (Database::affected_rows($result) > 0) {
1351
            Database::query(
1352
                "UPDATE $table_support_tickets SET
1353
                    status_id = '".self::STATUS_PENDING."'
1354
                 WHERE id ='$ticketId' AND status_id = '".self::STATUS_NEW."'"
1355
            );
1356
1357
            return true;
1358
        }
1359
1360
        return false;
1361
    }
1362
1363
    /**
1364
     * Send notification to a user through the internal messaging system.
1365
     */
1366
    public static function sendNotification($ticketId, $title, $message, $onlyToUserId = 0, $debug = false)
1367
    {
1368
        $ticketInfo = self::get_ticket_detail_by_id($ticketId);
1369
1370
        if (empty($ticketInfo)) {
1371
            return false;
1372
        }
1373
1374
        $assignedUserInfo = api_get_user_info($ticketInfo['ticket']['assigned_last_user']);
1375
        $requestUserInfo = $ticketInfo['user'];
1376
        $ticketCode = $ticketInfo['ticket']['code'];
1377
        $status = $ticketInfo['ticket']['status'];
1378
        $priority = $ticketInfo['ticket']['priority'];
1379
        $creatorId = $ticketInfo['ticket']['sys_insert_user_id'];
1380
1381
        // Subject
1382
        $titleEmail = "[$ticketCode] $title";
1383
1384
        // Content
1385
        $href = api_get_path(WEB_CODE_PATH) . 'ticket/ticket_details.php?ticket_id=' . $ticketId;
1386
        $ticketUrl = Display::url($ticketCode, $href);
1387
        $messageEmailBase = get_lang('Ticket number') . ": $ticketUrl <br />";
1388
        $messageEmailBase .= get_lang('Status') . ": $status <br />";
1389
        $messageEmailBase .= get_lang('Priority') . ": $priority <br />";
1390
        $messageEmailBase .= '<hr /><br />';
1391
        $messageEmailBase .= $message;
1392
1393
        $currentUserId = api_get_user_id();
1394
        $recipients = [];
1395
1396
        if (!empty($onlyToUserId) && $currentUserId != $onlyToUserId) {
1397
            $recipients[$onlyToUserId] = $onlyToUserId;
1398
        } else {
1399
            if (
1400
                $requestUserInfo &&
1401
                $currentUserId != $requestUserInfo['id'] &&
1402
                self::isUserSubscribedToTicket($ticketId, $requestUserInfo['id'])
1403
            ) {
1404
                $recipients[$requestUserInfo['id']] = $requestUserInfo['complete_name_with_username'];
1405
            }
1406
1407
            if ($assignedUserInfo && $currentUserId != $assignedUserInfo['id']) {
1408
                $recipients[$assignedUserInfo['id']] = $assignedUserInfo['complete_name_with_username'];
1409
            }
1410
1411
            $followers = self::getFollowers($ticketId);
1412
            /* @var User $follower */
1413
            foreach ($followers as $follower) {
1414
                if (
1415
                    $follower->getId() !== $currentUserId &&
1416
                    (
1417
                        $follower->getId() !== $creatorId ||
1418
                        self::isUserSubscribedToTicket($ticketId, $follower->getId())
1419
                    )
1420
                ) {
1421
                    $recipients[$follower->getId()] = $follower->getFullname();
1422
                }
1423
            }
1424
        }
1425
1426
        if ($debug) {
1427
            echo "<pre>";
1428
            echo "Title: $titleEmail\n";
1429
            echo "Message Preview:\n\n";
1430
1431
            foreach ($recipients as $recipientId => $recipientName) {
1432
                $unsubscribeLink = self::generateUnsubscribeLink($ticketId, $recipientId);
1433
                $finalMessageEmail = $messageEmailBase;
1434
                $finalMessageEmail .= '<br /><hr /><br />';
1435
                $finalMessageEmail .= '<small>' . get_lang('To unsubscribe from notifications, click here') . ': ';
1436
                $finalMessageEmail .= '<a href="' . $unsubscribeLink . '">' . $unsubscribeLink . '</a></small>';
1437
1438
                echo "------------------------------------\n";
1439
                echo "Recipient: $recipientName (User ID: $recipientId)\n";
1440
                echo "Message:\n$finalMessageEmail\n";
1441
                echo "------------------------------------\n\n";
1442
            }
1443
1444
            echo "</pre>";
1445
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1446
        }
1447
1448
        foreach ($recipients as $recipientId => $recipientName) {
1449
            $unsubscribeLink = self::generateUnsubscribeLink($ticketId, $recipientId);
1450
1451
            $finalMessageEmail = $messageEmailBase;
1452
            $finalMessageEmail .= '<br /><hr /><br />';
1453
            $finalMessageEmail .= '<small>' . get_lang('To unsubscribe from notifications, click here') . ': ';
1454
            $finalMessageEmail .= '<a href="' . $unsubscribeLink . '">' . $unsubscribeLink . '</a></small>';
1455
1456
            MessageManager::send_message_simple(
1457
                $recipientId,
1458
                $titleEmail,
1459
                $finalMessageEmail,
1460
                0,
1461
                false,
1462
                false,
1463
                false
1464
            );
1465
        }
1466
1467
        return true;
1468
    }
1469
1470
    /**
1471
     * @param array $params
1472
     * @param int   $ticketId
1473
     * @param int   $userId
1474
     *
1475
     * @return bool
1476
     */
1477
    public static function updateTicket(
1478
        $params,
1479
        $ticketId,
1480
        $userId
1481
    ) {
1482
        $now = api_get_utc_datetime();
1483
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1484
        $newParams = [
1485
            'priority_id' => isset($params['priority_id']) ? (int) $params['priority_id'] : '',
1486
            'status_id' => isset($params['status_id']) ? (int) $params['status_id'] : '',
1487
            'sys_lastedit_user_id' => (int) $userId,
1488
            'sys_lastedit_datetime' => $now,
1489
        ];
1490
        Database::update($table, $newParams, ['id = ? ' => $ticketId]);
1491
1492
        return true;
1493
    }
1494
1495
    /**
1496
     * @param int $status_id
1497
     * @param int $ticketId
1498
     * @param int $userId
1499
     *
1500
     * @return bool
1501
     */
1502
    public static function update_ticket_status(
1503
        $status_id,
1504
        $ticketId,
1505
        $userId
1506
    ) {
1507
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1508
1509
        $ticketId = (int) $ticketId;
1510
        $status_id = (int) $status_id;
1511
        $userId = (int) $userId;
1512
        $now = api_get_utc_datetime();
1513
1514
        $sql = "UPDATE $table_support_tickets
1515
                SET
1516
                    status_id = '$status_id',
1517
                    sys_lastedit_user_id ='$userId',
1518
                    sys_lastedit_datetime ='".$now."'
1519
                WHERE id ='$ticketId'";
1520
        $result = Database::query($sql);
1521
1522
        if (Database::affected_rows($result) > 0) {
1523
            self::sendNotification(
1524
                $ticketId,
1525
                get_lang('Ticket updated'),
1526
                get_lang('Ticket updated')
1527
            );
1528
1529
            return true;
1530
        }
1531
1532
        return false;
1533
    }
1534
1535
    /**
1536
     * @return mixed
1537
     */
1538
    public static function getNumberOfMessages()
1539
    {
1540
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1541
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1542
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1543
        $table_main_admin = Database::get_main_table(TABLE_MAIN_ADMIN);
1544
        $user_info = api_get_user_info();
1545
        $userId = $user_info['user_id'];
1546
        $sql = "SELECT COUNT(DISTINCT ticket.id) AS unread
1547
                FROM $table_support_tickets ticket,
1548
                $table_support_messages message ,
1549
                $table_main_user user
1550
                WHERE
1551
                    ticket.id = message.ticket_id AND
1552
                    message.status = 'NOL' AND
1553
                    user.user_id = message.sys_insert_user_id ";
1554
        if (!api_is_platform_admin()) {
1555
            $sql .= " AND ticket.request_user = '$userId'
1556
                      AND user_id IN (SELECT user_id FROM $table_main_admin)  ";
1557
        } else {
1558
            $sql .= " AND user_id NOT IN (SELECT user_id FROM $table_main_admin)
1559
                      AND ticket.status_id != '".self::STATUS_FORWARDED."'";
1560
        }
1561
        $sql .= "  AND ticket.project_id != '' ";
1562
        $res = Database::query($sql);
1563
        $obj = Database::fetch_object($res);
1564
1565
        return $obj->unread;
1566
    }
1567
1568
    /**
1569
     * @param int $ticketId
1570
     * @param int $userId
1571
     */
1572
    public static function send_alert($ticketId, $userId)
1573
    {
1574
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1575
        $now = api_get_utc_datetime();
1576
1577
        $ticketId = (int) $ticketId;
1578
        $userId = (int) $userId;
1579
1580
        $sql = "UPDATE $table_support_tickets SET
1581
                  priority_id = '".self::PRIORITY_HIGH."',
1582
                  sys_lastedit_user_id = $userId,
1583
                  sys_lastedit_datetime = '$now'
1584
                WHERE id = $ticketId";
1585
        Database::query($sql);
1586
    }
1587
1588
    /**
1589
     * @param int $ticketId
1590
     * @param int $userId
1591
     */
1592
    public static function close_ticket($ticketId, $userId)
1593
    {
1594
        $ticketId = (int) $ticketId;
1595
        $userId = (int) $userId;
1596
1597
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1598
        $now = api_get_utc_datetime();
1599
        $sql = "UPDATE $table_support_tickets SET
1600
                    status_id = '".self::STATUS_CLOSE."',
1601
                    sys_lastedit_user_id ='$userId',
1602
                    sys_lastedit_datetime ='".$now."',
1603
                    end_date ='$now'
1604
                WHERE id ='$ticketId'";
1605
        Database::query($sql);
1606
1607
        self::sendNotification(
1608
            $ticketId,
1609
            get_lang('Ticket closed'),
1610
            get_lang('Ticket closed')
1611
        );
1612
    }
1613
1614
    /**
1615
     * Close old tickets.
1616
     */
1617
    public static function close_old_tickets()
1618
    {
1619
        $table = Database::get_main_table(TABLE_TICKET_TICKET);
1620
        $now = api_get_utc_datetime();
1621
        $userId = api_get_user_id();
1622
        $sql = "UPDATE $table
1623
                SET
1624
                    status_id = '".self::STATUS_CLOSE."',
1625
                    sys_lastedit_user_id ='$userId',
1626
                    sys_lastedit_datetime ='$now',
1627
                    end_date = '$now'
1628
                WHERE
1629
                    DATEDIFF('$now', sys_lastedit_datetime) > 7 AND
1630
                    status_id != '".self::STATUS_CLOSE."' AND
1631
                    status_id != '".self::STATUS_NEW."' AND
1632
                    status_id != '".self::STATUS_FORWARDED."'";
1633
        Database::query($sql);
1634
    }
1635
1636
    /**
1637
     * @param int $ticketId
1638
     *
1639
     * @return array
1640
     */
1641
    public static function get_assign_log($ticketId)
1642
    {
1643
        $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
1644
        $ticketId = (int) $ticketId;
1645
1646
        $sql = "SELECT * FROM $table
1647
                WHERE ticket_id = $ticketId
1648
                ORDER BY assigned_date DESC";
1649
        $result = Database::query($sql);
1650
        $history = [];
1651
        $webpath = api_get_path(WEB_PATH);
1652
        while ($row = Database::fetch_assoc($result)) {
1653
            if (0 != $row['user_id']) {
1654
                $assignuser = api_get_user_info($row['user_id']);
1655
                $row['assignuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['user_id'].'"  target="_blank">'.
1656
                $assignuser['username'].'</a>';
1657
            } else {
1658
                $row['assignuser'] = get_lang('Unassign');
1659
            }
1660
            $row['assigned_date'] = Display::dateToStringAgoAndLongDate($row['assigned_date']);
1661
            $insertuser = api_get_user_info($row['sys_insert_user_id']);
1662
            $row['insertuser'] = '<a href="'.$webpath.'main/admin/user_information.php?user_id='.$row['sys_insert_user_id'].'"  target="_blank">'.
1663
                $insertuser['username'].'</a>';
1664
            $history[] = $row;
1665
        }
1666
1667
        return $history;
1668
    }
1669
1670
    /**
1671
     * @param $from
1672
     * @param $number_of_items
1673
     * @param $column
1674
     * @param $direction
1675
     * @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...
1676
     *
1677
     * @return array
1678
     */
1679
    public static function export_tickets_by_user_id(
1680
        $from,
1681
        $number_of_items,
1682
        $column,
1683
        $direction,
1684
        $userId = null
1685
    ) {
1686
        $from = (int) $from;
1687
        $number_of_items = (int) $number_of_items;
1688
        $table_support_category = Database::get_main_table(
1689
            TABLE_TICKET_CATEGORY
1690
        );
1691
        $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
1692
        $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY);
1693
        $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS);
1694
        $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
1695
        $table_main_user = Database::get_main_table(TABLE_MAIN_USER);
1696
1697
        if (is_null($direction)) {
1698
            $direction = 'DESC';
1699
        }
1700
        if (is_null($userId) || 0 == $userId) {
1701
            $userId = api_get_user_id();
1702
        }
1703
1704
        $sql = "SELECT
1705
                    ticket.code,
1706
                    ticket.sys_insert_datetime,
1707
                    ticket.sys_lastedit_datetime,
1708
                    cat.title as category,
1709
                    CONCAT(user.lastname,' ', user.firstname) AS fullname,
1710
                    status.title as status,
1711
                    ticket.total_messages as messages,
1712
                    ticket.assigned_last_user as responsable
1713
                FROM $table_support_tickets ticket,
1714
                $table_support_category cat ,
1715
                $table_support_priority priority,
1716
                $table_support_status status ,
1717
                $table_main_user user
1718
                WHERE
1719
                    cat.id = ticket.category_id
1720
                    AND ticket.priority_id = priority.id
1721
                    AND ticket.status_id = status.id
1722
                    AND user.user_id = ticket.request_user ";
1723
        // Search simple
1724
        if (isset($_GET['submit_simple'])) {
1725
            if ('' !== $_GET['keyword']) {
1726
                $keyword = Database::escape_string(trim($_GET['keyword']));
1727
                $sql .= " AND (ticket.code = '$keyword'
1728
                          OR user.firstname LIKE '%$keyword%'
1729
                          OR user.lastname LIKE '%$keyword%'
1730
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword%'
1731
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword%'
1732
                          OR user.username LIKE '%$keyword%')  ";
1733
            }
1734
        }
1735
        // Search advanced
1736
        if (isset($_GET['submit_advanced'])) {
1737
            $keyword_category = Database::escape_string(
1738
                trim($_GET['keyword_category'])
1739
            );
1740
            $keyword_request_user = Database::escape_string(
1741
                trim($_GET['keyword_request_user'])
1742
            );
1743
            $keywordAssignedTo = (int) $_GET['keyword_assigned_to'];
1744
            $keyword_start_date_start = Database::escape_string(
1745
                trim($_GET['keyword_start_date_start'])
1746
            );
1747
            $keyword_start_date_end = Database::escape_string(
1748
                trim($_GET['keyword_start_date_end'])
1749
            );
1750
            $keyword_status = Database::escape_string(
1751
                trim($_GET['keyword_status'])
1752
            );
1753
            $keyword_source = Database::escape_string(
1754
                trim($_GET['keyword_source'])
1755
            );
1756
            $keyword_priority = Database::escape_string(
1757
                trim($_GET['keyword_priority'])
1758
            );
1759
            $keyword_range = Database::escape_string(
1760
                trim($_GET['keyword_dates'])
1761
            );
1762
            $keyword_unread = Database::escape_string(
1763
                trim($_GET['keyword_unread'])
1764
            );
1765
            $keyword_course = Database::escape_string(
1766
                trim($_GET['keyword_course'])
1767
            );
1768
1769
            if ('' != $keyword_category) {
1770
                $sql .= " AND ticket.category_id = '$keyword_category'  ";
1771
            }
1772
            if ('' != $keyword_request_user) {
1773
                $sql .= " AND (ticket.request_user = '$keyword_request_user'
1774
                          OR user.firstname LIKE '%$keyword_request_user%'
1775
                          OR user.official_code LIKE '%$keyword_request_user%'
1776
                          OR user.lastname LIKE '%$keyword_request_user%'
1777
                          OR concat(user.firstname,' ',user.lastname) LIKE '%$keyword_request_user%'
1778
                          OR concat(user.lastname,' ',user.firstname) LIKE '%$keyword_request_user%'
1779
                          OR user.username LIKE '%$keyword_request_user%') ";
1780
            }
1781
            if (!empty($keywordAssignedTo)) {
1782
                $sql .= " AND ticket.assigned_last_user = $keywordAssignedTo ";
1783
            }
1784
            if ('' != $keyword_status) {
1785
                $sql .= " AND ticket.status_id = '$keyword_status'  ";
1786
            }
1787
            if ('' == $keyword_range && '' != $keyword_start_date_start) {
1788
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') = '$keyword_start_date_start' ";
1789
            }
1790
            if ('1' == $keyword_range && '' != $keyword_start_date_start && '' != $keyword_start_date_end) {
1791
                $sql .= " AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') >= '$keyword_start_date_start'
1792
                          AND DATE_FORMAT( ticket.start_date,'%d/%m/%Y') <= '$keyword_start_date_end'";
1793
            }
1794
            if ('' != $keyword_priority) {
1795
                $sql .= " AND ticket.priority_id = '$keyword_priority'  ";
1796
            }
1797
            if ('' != $keyword_source) {
1798
                $sql .= " AND ticket.source = '$keyword_source' ";
1799
            }
1800
            if ('' != $keyword_priority) {
1801
                $sql .= " AND ticket.priority_id = '$keyword_priority' ";
1802
            }
1803
            if ('' != $keyword_course) {
1804
                $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1805
                $sql .= " AND ticket.course_id IN ( ";
1806
                $sql .= "SELECT id
1807
                         FROM $course_table
1808
                         WHERE (title LIKE '%$keyword_course%'
1809
                         OR code LIKE '%$keyword_course%'
1810
                         OR visual_code LIKE '%$keyword_course%' )) ";
1811
            }
1812
            if ('yes' == $keyword_unread) {
1813
                $sql .= " AND ticket.id IN (
1814
                          SELECT ticket.id
1815
                          FROM $table_support_tickets ticket,
1816
                          $table_support_messages message,
1817
                          $table_main_user user
1818
                          WHERE ticket.id = message.ticket_id
1819
                          AND message.status = 'NOL'
1820
                          AND message.sys_insert_user_id = user.user_id
1821
                          AND user.status != 1   AND ticket.status_id != '".self::STATUS_FORWARDED."'
1822
                          GROUP BY ticket.id)";
1823
            } else {
1824
                if ('no' == $keyword_unread) {
1825
                    $sql .= " AND ticket.id NOT IN (
1826
                              SELECT ticket.id
1827
                              FROM  $table_support_tickets ticket,
1828
                              $table_support_messages message,
1829
                              $table_main_user user
1830
                              WHERE ticket.id = message.ticket_id
1831
                              AND message.status = 'NOL'
1832
                              AND message.sys_insert_user_id = user.user_id
1833
                              AND user.status != 1
1834
                              AND ticket.status_id != '".self::STATUS_FORWARDED."'
1835
                             GROUP BY ticket.id)";
1836
                }
1837
            }
1838
        }
1839
1840
        $sql .= !str_contains($sql, 'WHERE') ? ' WHERE user.active <> '.USER_SOFT_DELETED : ' AND user.active <> '.USER_SOFT_DELETED;
1841
        $sql .= " LIMIT $from,$number_of_items";
1842
1843
        $result = Database::query($sql);
1844
        $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...
1845
            utf8_decode('Ticket#'),
1846
            utf8_decode('Fecha'),
1847
            utf8_decode('Fecha Edicion'),
1848
            utf8_decode('Categoria'),
1849
            utf8_decode('Usuario'),
1850
            utf8_decode('Estado'),
1851
            utf8_decode('Mensajes'),
1852
            utf8_decode('Responsable'),
1853
            utf8_decode('Programa'),
1854
        ];
1855
1856
        while ($row = Database::fetch_assoc($result)) {
1857
            if (0 != $row['responsable']) {
1858
                $row['responsable'] = api_get_user_info($row['responsable']);
1859
                $row['responsable'] = $row['responsable']['firstname'].' '.$row['responsable']['lastname'];
1860
            }
1861
            $row['sys_insert_datetime'] = api_format_date(
1862
                $row['sys_insert_datetime'],
1863
                '%d/%m/%y - %I:%M:%S %p'
1864
            );
1865
            $row['sys_lastedit_datetime'] = api_format_date(
1866
                $row['sys_lastedit_datetime'],
1867
                '%d/%m/%y - %I:%M:%S %p'
1868
            );
1869
            $row['category'] = utf8_decode($row['category']);
1870
            $row['programa'] = utf8_decode($row['fullname']);
1871
            $row['fullname'] = utf8_decode($row['fullname']);
1872
            $row['responsable'] = utf8_decode($row['responsable']);
1873
            $tickets[] = $row;
1874
        }
1875
1876
        return $tickets;
1877
    }
1878
1879
    /**
1880
     * @param string $url
1881
     * @param int    $projectId
1882
     *
1883
     * @return FormValidator
1884
     */
1885
    public static function getCategoryForm($url, $projectId)
1886
    {
1887
        $form = new FormValidator('category', 'post', $url);
1888
        $form->addText('name', get_lang('Name'));
1889
        $form->addHtmlEditor('description', get_lang('Description'));
1890
        $form->addHidden('project_id', $projectId);
1891
        $form->addButtonUpdate(get_lang('Save'));
1892
1893
        return $form;
1894
    }
1895
1896
    /**
1897
     * @return array
1898
     */
1899
    public static function getStatusList()
1900
    {
1901
        $items = Database::getManager()->getRepository(TicketStatus::class)->findAll();
1902
1903
        $list = [];
1904
        /** @var TicketStatus $row */
1905
        foreach ($items as $row) {
1906
            $list[$row->getId()] = $row->getTitle();
1907
        }
1908
1909
        return $list;
1910
    }
1911
1912
    /**
1913
     * @param array $criteria
1914
     *
1915
     * @return array
1916
     */
1917
    public static function getTicketsFromCriteria($criteria)
1918
    {
1919
        $items = Database::getManager()->getRepository(Ticket::class)->findBy($criteria);
1920
        $list = [];
1921
        /** @var Ticket $row */
1922
        foreach ($items as $row) {
1923
            $list[$row->getId()] = $row->getCode();
1924
        }
1925
1926
        return $list;
1927
    }
1928
1929
    /**
1930
     * @param string $code
1931
     *
1932
     * @return int
1933
     */
1934
    public static function getStatusIdFromCode($code)
1935
    {
1936
        $item = Database::getManager()
1937
            ->getRepository(TicketStatus::class)
1938
            ->findOneBy(['code' => $code])
1939
        ;
1940
1941
        if ($item) {
1942
            return $item->getId();
1943
        }
1944
1945
        return 0;
1946
    }
1947
1948
    /**
1949
     * @return array
1950
     */
1951
    public static function getPriorityList()
1952
    {
1953
        $projects = Database::getManager()->getRepository(TicketPriority::class)->findAll();
1954
        $list = [];
1955
        /** @var TicketPriority $row */
1956
        foreach ($projects as $row) {
1957
            $list[$row->getId()] = $row->getTitle();
1958
        }
1959
1960
        return $list;
1961
    }
1962
1963
    /**
1964
     * @return array
1965
     */
1966
    public static function getProjects()
1967
    {
1968
        $projects = Database::getManager()->getRepository(TicketProject::class)->findAll();
1969
1970
        $list = [];
1971
        /** @var TicketProject $row */
1972
        foreach ($projects as $row) {
1973
            $list[] = [
1974
                'id' => $row->getId(),
1975
                '0' => $row->getId(),
1976
                '1' => $row->getTitle(),
1977
                '2' => $row->getDescription(),
1978
                '3' => $row->getId(),
1979
            ];
1980
        }
1981
1982
        return $list;
1983
    }
1984
1985
    /**
1986
     * @return array
1987
     */
1988
    public static function getProjectsSimple()
1989
    {
1990
        $projects = Database::getManager()->getRepository(TicketProject::class)->findAll();
1991
        $list = [];
1992
        /** @var TicketProject $row */
1993
        foreach ($projects as $row) {
1994
            $list[] = [
1995
                'id' => $row->getId(),
1996
                '0' => $row->getId(),
1997
                '1' => Display::url(
1998
                    $row->getTitle(),
1999
                    api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id='.$row->getId()
2000
                ),
2001
                '2' => $row->getDescription(),
2002
            ];
2003
        }
2004
2005
        return $list;
2006
    }
2007
2008
    /**
2009
     * @return int
2010
     */
2011
    public static function getProjectsCount()
2012
    {
2013
        return Database::getManager()->getRepository(TicketProject::class)->createQueryBuilder('p')
2014
            ->select('COUNT(p.id)')
2015
            ->getQuery()
2016
            ->getSingleScalarResult();
2017
    }
2018
2019
    /**
2020
     * @param array $params
2021
     */
2022
    public static function addProject($params)
2023
    {
2024
        $project = new TicketProject();
2025
        $project->setTitle($params['title']);
2026
        $project->setDescription($params['description']);
2027
        $project->setInsertUserId(api_get_user_id());
2028
2029
        Database::getManager()->persist($project);
2030
        Database::getManager()->flush();
2031
    }
2032
2033
    /**
2034
     * @param int $id
2035
     *
2036
     * @return TicketProject
2037
     */
2038
    public static function getProject($id)
2039
    {
2040
        return Database::getManager()->getRepository(TicketProject::class)->find($id);
2041
    }
2042
2043
    /**
2044
     * @param int   $id
2045
     * @param array $params
2046
     */
2047
    public static function updateProject($id, $params)
2048
    {
2049
        $project = self::getProject($id);
2050
        $project->setTitle($params['title']);
2051
        $project->setDescription($params['description']);
2052
        $project->setLastEditDateTime(new DateTime($params['sys_lastedit_datetime']));
2053
        $project->setLastEditUserId($params['sys_lastedit_user_id']);
2054
2055
        Database::getManager()->persist($project);
2056
        Database::getManager()->flush();
2057
    }
2058
2059
    /**
2060
     * @param int $id
2061
     */
2062
    public static function deleteProject($id)
2063
    {
2064
        $project = self::getProject($id);
2065
        if ($project) {
0 ignored issues
show
introduced by
$project is of type Chamilo\CoreBundle\Entity\TicketProject, thus it always evaluated to true.
Loading history...
2066
            Database::getManager()->remove($project);
2067
            Database::getManager()->flush();
2068
        }
2069
    }
2070
2071
    /**
2072
     * @param string $url
2073
     *
2074
     * @return FormValidator
2075
     */
2076
    public static function getProjectForm($url)
2077
    {
2078
        $form = new FormValidator('project', 'post', $url);
2079
        $form->addText('name', get_lang('Name'));
2080
        $form->addHtmlEditor('description', get_lang('Description'));
2081
        $form->addButtonUpdate(get_lang('Save'));
2082
2083
        return $form;
2084
    }
2085
2086
    /**
2087
     * @return array
2088
     */
2089
    public static function getStatusAdminList()
2090
    {
2091
        $items = Database::getManager()->getRepository(TicketStatus::class)->findAll();
2092
        $list = [];
2093
        /** @var TicketStatus $row */
2094
        foreach ($items as $row) {
2095
            $list[] = [
2096
                'id' => $row->getId(),
2097
                'code' => $row->getCode(),
2098
                '0' => $row->getId(),
2099
                '1' => $row->getTitle(),
2100
                '2' => $row->getDescription(),
2101
                '3' => $row->getId(),
2102
            ];
2103
        }
2104
2105
        return $list;
2106
    }
2107
2108
    /**
2109
     * @return array
2110
     */
2111
    /*public static function getStatusSimple()
2112
    {
2113
        $projects = Database::getManager()->getRepository(TicketStatus::class)->findAll();
2114
        $list = [];
2115
        // @var TicketProject $row
2116
        foreach ($projects as $row) {
2117
            $list[] = [
2118
                'id' => $row->getId(),
2119
                '0' => $row->getId(),
2120
                '1' => Display::url($row->getName()),
2121
                '2' => $row->getDescription(),
2122
            ];
2123
        }
2124
2125
        return $list;
2126
    }*/
2127
2128
    /**
2129
     * @return int
2130
     */
2131
    public static function getStatusCount()
2132
    {
2133
        return Database::getManager()->getRepository(TicketStatus::class)->createQueryBuilder('p')
2134
            ->select('COUNT(p.id)')
2135
            ->getQuery()
2136
            ->getSingleScalarResult();
2137
    }
2138
2139
    /**
2140
     * @param array $params
2141
     */
2142
    public static function addStatus($params)
2143
    {
2144
        $item = new TicketStatus();
2145
        $item->setCode(URLify::filter($params['title']));
2146
        $item->setTitle($params['title']);
2147
        $item->setDescription($params['description']);
2148
2149
        Database::getManager()->persist($item);
2150
        Database::getManager()->flush();
2151
    }
2152
2153
    /**
2154
     * @param $id
2155
     *
2156
     * @return TicketProject
2157
     */
2158
    public static function getStatus($id)
2159
    {
2160
        return Database::getManager()->getRepository(TicketStatus::class)->find($id);
2161
    }
2162
2163
    /**
2164
     * @param int   $id
2165
     * @param array $params
2166
     */
2167
    public static function updateStatus($id, $params)
2168
    {
2169
        $item = self::getStatus($id);
2170
        $item->setTitle($params['title']);
2171
        $item->setDescription($params['description']);
2172
2173
        Database::getManager()->persist($item);
2174
        Database::getManager()->flush();
2175
    }
2176
2177
    /**
2178
     * @param int $id
2179
     */
2180
    public static function deleteStatus($id)
2181
    {
2182
        $item = self::getStatus($id);
2183
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\CoreBundle\Entity\TicketProject, thus it always evaluated to true.
Loading history...
2184
            Database::getManager()->remove($item);
2185
            Database::getManager()->flush();
2186
        }
2187
    }
2188
2189
    /**
2190
     * @param string $url
2191
     *
2192
     * @return FormValidator
2193
     */
2194
    public static function getStatusForm($url)
2195
    {
2196
        $form = new FormValidator('status', 'post', $url);
2197
        $form->addText('name', get_lang('Name'));
2198
        $form->addHtmlEditor('description', get_lang('Description'));
2199
        $form->addButtonUpdate(get_lang('Save'));
2200
2201
        return $form;
2202
    }
2203
2204
    /**
2205
     * @return array
2206
     */
2207
    public static function getPriorityAdminList()
2208
    {
2209
        $items = Database::getManager()->getRepository(TicketPriority::class)->findAll();
2210
2211
        $list = [];
2212
        /** @var TicketStatus $row */
2213
        foreach ($items as $row) {
2214
            $list[] = [
2215
                'id' => $row->getId(),
2216
                'code' => $row->getCode(),
2217
                '0' => $row->getId(),
2218
                '1' => $row->getTitle(),
2219
                '2' => $row->getDescription(),
2220
                '3' => $row->getId(),
2221
            ];
2222
        }
2223
2224
        return $list;
2225
    }
2226
2227
    /**
2228
     * @return int
2229
     */
2230
    public static function getPriorityCount()
2231
    {
2232
        return Database::getManager()->getRepository(TicketPriority::class)->createQueryBuilder('p')
2233
            ->select('COUNT(p.id)')
2234
            ->getQuery()
2235
            ->getSingleScalarResult();
2236
    }
2237
2238
    /**
2239
     * @param array $params
2240
     */
2241
    public static function addPriority($params)
2242
    {
2243
        $item = new TicketPriority();
2244
        $item
2245
            ->setCode(URLify::filter($params['title']))
2246
            ->setTitle($params['title'])
2247
            ->setDescription($params['description'])
2248
            ->setColor('')
2249
            ->setInsertUserId(api_get_user_id())
2250
            ->setUrgency('')
2251
        ;
2252
2253
        Database::getManager()->persist($item);
2254
        Database::getManager()->flush();
2255
    }
2256
2257
    /**
2258
     * @param $id
2259
     *
2260
     * @return TicketPriority
2261
     */
2262
    public static function getPriority($id)
2263
    {
2264
        return Database::getManager()->getRepository(TicketPriority::class)->find($id);
2265
    }
2266
2267
    /**
2268
     * @param int   $id
2269
     * @param array $params
2270
     */
2271
    public static function updatePriority($id, $params)
2272
    {
2273
        $item = self::getPriority($id);
2274
        $item->setTitle($params['title']);
2275
        $item->setDescription($params['description']);
2276
2277
        Database::getManager()->persist($item);
2278
        Database::getManager()->flush();
2279
    }
2280
2281
    /**
2282
     * @param int $id
2283
     */
2284
    public static function deletePriority($id)
2285
    {
2286
        $item = self::getPriority($id);
2287
        if ($item) {
0 ignored issues
show
introduced by
$item is of type Chamilo\CoreBundle\Entity\TicketPriority, thus it always evaluated to true.
Loading history...
2288
            Database::getManager()->remove($item);
2289
            Database::getManager()->flush();
2290
        }
2291
    }
2292
2293
    /**
2294
     * @param string $url
2295
     *
2296
     * @return FormValidator
2297
     */
2298
    public static function getPriorityForm($url)
2299
    {
2300
        $form = new FormValidator('priority', 'post', $url);
2301
        $form->addText('name', get_lang('Name'));
2302
        $form->addHtmlEditor('description', get_lang('Description'));
2303
        $form->addButtonUpdate(get_lang('Save'));
2304
2305
        return $form;
2306
    }
2307
2308
    /**
2309
     * Returns a list of menu elements for the tickets system's configuration.
2310
     *
2311
     * @param string $exclude The element to exclude from the list
2312
     *
2313
     * @return array
2314
     */
2315
    public static function getSettingsMenuItems($exclude = null)
2316
    {
2317
        $project = [
2318
            'icon' => ObjectIcon::PROJECT,
2319
            'url' => 'projects.php',
2320
            'content' => get_lang('Projects'),
2321
        ];
2322
        $status = [
2323
            'icon' => StateIcon::COMPLETE,
2324
            'url' => 'status.php',
2325
            'content' => get_lang('Status'),
2326
        ];
2327
        $priority = [
2328
            'icon' => StateIcon::EXPIRED,
2329
            'url' => 'priorities.php',
2330
            'content' => get_lang('Priority'),
2331
        ];
2332
        switch ($exclude) {
2333
            case 'project':
2334
                $items = [$status, $priority];
2335
                break;
2336
            case 'status':
2337
                $items = [$project, $priority];
2338
                break;
2339
            case 'priority':
2340
                $items = [$project, $status];
2341
                break;
2342
            default:
2343
                $items = [$project, $status, $priority];
2344
                break;
2345
        }
2346
2347
        return $items;
2348
    }
2349
2350
    /**
2351
     * Returns a list of strings representing the default statuses.
2352
     *
2353
     * @return array
2354
     */
2355
    public static function getDefaultStatusList()
2356
    {
2357
        return [
2358
            self::STATUS_NEW,
2359
            self::STATUS_PENDING,
2360
            self::STATUS_UNCONFIRMED,
2361
            self::STATUS_CLOSE,
2362
            self::STATUS_FORWARDED,
2363
        ];
2364
    }
2365
2366
    /**
2367
     * @return array
2368
     */
2369
    public static function getDefaultPriorityList()
2370
    {
2371
        return [
2372
            self::PRIORITY_NORMAL,
2373
            self::PRIORITY_HIGH,
2374
            self::PRIORITY_LOW,
2375
            self::STATUS_CLOSE,
2376
            self::STATUS_FORWARDED,
2377
        ];
2378
    }
2379
2380
    /**
2381
     * Deletes the user from all the ticket system.
2382
     *
2383
     * @param int $userId
2384
     */
2385
    public static function deleteUserFromTicketSystem($userId)
2386
    {
2387
        $userId = (int) $userId;
2388
        $schema = Database::getManager()->getConnection()->createSchemaManager();
2389
2390
        if ($schema->tablesExist('ticket_assigned_log')) {
2391
            $sql = "UPDATE ticket_assigned_log SET user_id = NULL WHERE user_id = $userId";
2392
            Database::query($sql);
2393
2394
            $sql = "UPDATE ticket_assigned_log SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2395
            Database::query($sql);
2396
        }
2397
2398
        if ($schema->tablesExist('ticket_ticket')) {
2399
            $sql = "UPDATE ticket_ticket SET assigned_last_user = NULL WHERE assigned_last_user = $userId";
2400
            Database::query($sql);
2401
2402
            $sql = "UPDATE ticket_ticket SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2403
            Database::query($sql);
2404
2405
            $sql = "UPDATE ticket_ticket SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2406
            Database::query($sql);
2407
        }
2408
2409
        if ($schema->tablesExist('ticket_category')) {
2410
            $sql = "UPDATE ticket_category SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2411
            Database::query($sql);
2412
2413
            $sql = "UPDATE ticket_category SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2414
            Database::query($sql);
2415
        }
2416
2417
        if ($schema->tablesExist('ticket_category_rel_user')) {
2418
            $sql = "DELETE FROM ticket_category_rel_user WHERE user_id = $userId";
2419
            Database::query($sql);
2420
        }
2421
2422
        if ($schema->tablesExist('ticket_message')) {
2423
            $sql = "UPDATE ticket_message SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2424
            Database::query($sql);
2425
2426
            $sql = "UPDATE ticket_message SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2427
            Database::query($sql);
2428
        }
2429
2430
        if ($schema->tablesExist('ticket_message_attachments')) {
2431
            $sql = "UPDATE ticket_message_attachments SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2432
            Database::query($sql);
2433
2434
            $sql = "UPDATE ticket_message_attachments SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2435
            Database::query($sql);
2436
        }
2437
2438
        if ($schema->tablesExist('ticket_priority')) {
2439
            $sql = "UPDATE ticket_priority SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2440
            Database::query($sql);
2441
2442
            $sql = "UPDATE ticket_priority SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2443
            Database::query($sql);
2444
        }
2445
2446
        if ($schema->tablesExist('ticket_project')) {
2447
            $sql = "UPDATE ticket_project SET sys_insert_user_id = NULL WHERE sys_insert_user_id = $userId";
2448
            Database::query($sql);
2449
2450
            $sql = "UPDATE ticket_project SET sys_lastedit_user_id = NULL WHERE sys_lastedit_user_id = $userId";
2451
            Database::query($sql);
2452
        }
2453
    }
2454
2455
    /**
2456
     * @deprecated Use TicketProjectHelper::userIsAllowInProject instead
2457
     */
2458
    public static function userIsAllowInProject(int $projectId): bool
2459
    {
2460
        $authorizationChecked = Container::getAuthorizationChecker();
2461
2462
        if ($authorizationChecked->isGranted('ROLE_ADMIN')) {
2463
            return true;
2464
        }
2465
2466
        $allowRoleList = self::getAllowedRolesFromProject($projectId);
0 ignored issues
show
Deprecated Code introduced by
The function TicketManager::getAllowedRolesFromProject() has been deprecated: Use TicketProjectHelper::getAllowedRolesFromProject instead ( Ignorable by Annotation )

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

2466
        $allowRoleList = /** @scrutinizer ignore-deprecated */ self::getAllowedRolesFromProject($projectId);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
2467
2468
        // Check if a role was set to the project.
2469
        // Project 1 is considered the default and is accessible to all users
2470
        if (!empty($allowRoleList)) {
2471
            $result = false;
2472
            foreach ($allowRoleList as $role) {
2473
                if ($authorizationChecked->isGranted($role)) {
2474
                    $result = true;
2475
                    break;
2476
                }
2477
            }
2478
2479
            return $result;
2480
        }
2481
2482
        return false;
2483
    }
2484
2485
    /**
2486
     * @deprecated Use TicketProjectHelper::getAllowedRolesFromProject instead
2487
     */
2488
    public static function getAllowedRolesFromProject(int $projectId): array
2489
    {
2490
        // Define a mapping from role IDs to role names
2491
        $roleMap = [
2492
            1 => 'ROLE_TEACHER',
2493
            17 => 'ROLE_STUDENT_BOSS',
2494
            4 => 'ROLE_HR',
2495
            3 => 'ROLE_SESSION_MANAGER',
2496
            // ... other mappings can be added as needed
2497
        ];
2498
2499
        $jsonString = Container::getSettingsManager()->getSetting('ticket.ticket_project_user_roles');
2500
2501
        if (empty($jsonString)) {
2502
            return [];
2503
        }
2504
2505
        $data = json_decode($jsonString, true);
2506
2507
        if (JSON_ERROR_NONE !== json_last_error()) {
2508
            // Invalid JSON
2509
            return [];
2510
        }
2511
2512
        if (!isset($data['permissions'][$projectId])) {
2513
            // No permissions for the given projectId
2514
            return [];
2515
        }
2516
2517
        $roleIds = $data['permissions'][$projectId];
2518
2519
        // Transform role IDs into role names using the defined mapping
2520
        return array_map(function ($roleId) use ($roleMap) {
2521
            return $roleMap[$roleId] ?? "$roleId";
2522
        }, $roleIds);
2523
    }
2524
2525
    /**
2526
     * Subscribes a user to a ticket.
2527
     */
2528
    public static function subscribeUserToTicket(int $ticketId, int $userId): void
2529
    {
2530
        $em = Database::getManager();
2531
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2532
        $user = $em->getRepository(User::class)->find($userId);
2533
2534
        if ($ticket && $user) {
2535
            $repository = $em->getRepository(TicketRelUser::class);
2536
            $repository->subscribeUserToTicket($user, $ticket);
2537
2538
            Event::addEvent(
0 ignored issues
show
Bug introduced by
The method addEvent() does not exist on Event. ( Ignorable by Annotation )

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

2538
            Event::/** @scrutinizer ignore-call */ 
2539
                   addEvent(

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

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

Loading history...
2539
                'ticket_subscribe',
2540
                'ticket_event',
2541
                ['user_id' => $userId, 'ticket_id' => $ticketId, 'action' => 'subscribe']
2542
            );
2543
        }
2544
    }
2545
2546
    /**
2547
     * Unsubscribes a user from a ticket.
2548
     */
2549
    public static function unsubscribeUserFromTicket(int $ticketId, int $userId): void
2550
    {
2551
        $em = Database::getManager();
2552
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2553
        $user = $em->getRepository(User::class)->find($userId);
2554
2555
        if ($ticket && $user) {
2556
            $repository = $em->getRepository(TicketRelUser::class);
2557
            $repository->unsubscribeUserFromTicket($user, $ticket);
2558
2559
            Event::addEvent(
2560
                'ticket_unsubscribe',
2561
                'ticket_event',
2562
                ['user_id' => $userId, 'ticket_id' => $ticketId, 'action' => 'unsubscribe']
2563
            );
2564
        }
2565
    }
2566
2567
    /**
2568
     * Checks if a user is subscribed to a ticket.
2569
     */
2570
    public static function isUserSubscribedToTicket(int $ticketId, int $userId): bool
2571
    {
2572
        $em = Database::getManager();
2573
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2574
        $user = $em->getRepository(User::class)->find($userId);
2575
2576
        if ($ticket && $user) {
2577
            $repository = $em->getRepository(TicketRelUser::class);
2578
            return $repository->isUserSubscribedToTicket($user, $ticket);
2579
        }
2580
2581
        return false;
2582
    }
2583
2584
    /**
2585
     * Retrieves the followers of a ticket.
2586
     */
2587
    public static function getFollowers($ticketId): array
2588
    {
2589
        $em = Database::getManager();
2590
        $repository = $em->getRepository(TicketRelUser::class);
2591
        $ticket = $em->getRepository(Ticket::class)->find($ticketId);
2592
2593
        $followers = $repository->findBy(['ticket' => $ticket]);
2594
2595
        $users = [];
2596
        foreach ($followers as $follower) {
2597
            $users[] = $follower->getUser();
2598
        }
2599
2600
        return $users;
2601
    }
2602
2603
    /**
2604
     * Generates an unsubscribe link for a ticket.
2605
     */
2606
    public static function generateUnsubscribeLink($ticketId, $userId): string
2607
    {
2608
        $token = new ValidationToken(ValidationTokenHelper::TYPE_TICKET, $ticketId);
2609
        Database::getManager()->persist($token);
2610
        Database::getManager()->flush();
2611
2612
        return api_get_path(WEB_PATH).'validate/ticket/'.$token->getHash().'?user_id='.$userId;
2613
    }
2614
}
2615