Ticket   F
last analyzed

Complexity

Total Complexity 86

Size/Duplication

Total Lines 638
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 300
c 0
b 0
f 0
dl 0
loc 638
rs 2
wmc 86

22 Methods

Rating   Name   Duplication   Size   Complexity  
A getFiles() 0 14 2
A getReviews() 0 19 2
A elapsed() 0 5 1
A getResponseCount() 0 6 1
A __construct() 0 30 3
A getResponses() 0 17 2
A lastUpdated() 0 3 1
A addResponse() 0 27 3
A getEmails() 0 16 3
A lastUpdate() 0 5 1
A createEmailHash() 0 10 2
C prettyElapsed() 0 34 16
C storeUpload() 0 53 12
A checkUpload() 0 28 4
A posted() 0 3 1
A isOverdue() 0 18 5
A getDepartment() 0 5 1
A addSubmitter() 0 19 3
C getCustFieldValues() 0 56 12
A merge() 0 55 4
A getLogs() 0 18 2
A canAddResponse() 0 27 5

How to fix   Complexity   

Complex Class

Complex classes like Ticket 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 Ticket, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Xhelp;
4
5
/*
6
 * You may not change or alter any portion of this comment or credits
7
 * of supporting developers from this source code or any supporting source code
8
 * which is considered copyrighted (c) material of the original comment or credit authors.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/**
16
 * @copyright    {@link https://xoops.org/ XOOPS Project}
17
 * @license      {@link https://www.gnu.org/licenses/gpl-2.0.html GNU GPL 2 or later}
18
 * @author       Eric Juden <[email protected]>
19
 * @author       XOOPS Development Team
20
 */
21
22
use function md5;
23
24
if (!\defined('XHELP_CLASS_PATH')) {
25
    exit();
26
}
27
// require_once XHELP_CLASS_PATH . '/BaseObjectHandler.php';
28
$path = \dirname(__DIR__, 3);
29
require_once $path . '/mainfile.php';
30
//require_once $path . '/include/cp_functions.php';
31
//require_once $path . '/include/cp_header.php';
32
33
global $xoopsUser;
34
35
/**
36
 * Ticket class
37
 *
38
 * Information about an individual ticket
39
 *
40
 * <code>
41
 * $ticketHandler = $this->helper->getHandler('Ticket');
42
 * $ticket = $ticketHandler->get(1);
43
 * $ticket_id = $ticket->getVar('id');
44
 * $responses = $ticket->getResponses();
45
 * echo $ticket->lastUpdated();
46
 * </code>
47
 *
48
 * @author  Eric Juden <[email protected]>
49
 */
50
class Ticket extends \XoopsObject
51
{
52
    private $helper;
53
54
    /**
55
     * Ticket constructor.
56
     * @param int|array|null $id
57
     */
58
    public function __construct($id = null)
59
    {
60
        $this->initVar('id', \XOBJ_DTYPE_INT, null, false);
61
        $this->initVar('uid', \XOBJ_DTYPE_INT, null, false);                      // will store Xoops user id
62
        $this->initVar('subject', \XOBJ_DTYPE_TXTBOX, null, true, 100);
63
        $this->initVar('description', \XOBJ_DTYPE_TXTAREA, null, false, 1000000);
64
        $this->initVar('department', \XOBJ_DTYPE_INT, null, false);
65
        $this->initVar('priority', \XOBJ_DTYPE_INT, null, false);
66
        $this->initVar('status', \XOBJ_DTYPE_INT, null, false);
67
        $this->initVar('lastUpdated', \XOBJ_DTYPE_INT, null, false);
68
        $this->initVar('posted', \XOBJ_DTYPE_INT, null, false);
69
        $this->initVar('ownership', \XOBJ_DTYPE_INT, null, false);                // will store Xoops user id
70
        $this->initVar('closedBy', \XOBJ_DTYPE_INT, null, false);                 // will store Xoops user id
71
        $this->initVar('totalTimeSpent', \XOBJ_DTYPE_INT, null, false);
72
        $this->initVar('userIP', \XOBJ_DTYPE_TXTBOX, null, false, 25);
73
        $this->initVar('elapsed', \XOBJ_DTYPE_INT, null, false);
74
        $this->initVar('lastUpdate', \XOBJ_DTYPE_INT, null, false);
75
        $this->initVar('emailHash', \XOBJ_DTYPE_TXTBOX, '', true, 100);
76
        $this->initVar('email', \XOBJ_DTYPE_TXTBOX, '', true, 100);
77
        $this->initVar('serverid', \XOBJ_DTYPE_INT, null, false);                 //will store email server this was picked up from
78
        $this->initVar('overdueTime', \XOBJ_DTYPE_INT, null, false);
79
80
        $this->helper = Helper::getInstance();
81
82
        if (null !== $id) {
83
            if (\is_array($id)) {
84
                $this->assignVars($id);
85
            }
86
        } else {
87
            $this->setNew();
88
        }
89
    }
90
91
    /**
92
     * retrieve the department object associated with this ticket
93
     *
94
     * @return Department|bool {@link Department}
95
     */
96
    public function getDepartment()
97
    {
98
        $departmentHandler = $this->helper->getHandler('Department');
99
100
        return $departmentHandler->get($this->getVar('department'));
101
    }
102
103
    /**
104
     * create an md5 hash based on the ID and emailaddress. Use this as a lookup key when trying to find a ticket.
105
     *
106
     * @param string $email
107
     */
108
    public function createEmailHash(string $email): void
109
    {
110
        if ('' === $this->getVar('posted')) {
111
            $this->setVar('posted', \time());
112
        }
113
        $hash = $this->getVar('posted') . '-' . $email;
114
        $hash = md5($hash);
115
116
        $this->setVar('email', $email);
117
        $this->setVar('emailHash', $hash);
118
    }
119
120
    /**
121
     * retrieve all emails attached to this ticket object
122
     * @param bool $activeOnly
123
     * @return array of <a href='psi_element://TicketEmail'>TicketEmail</a> objects
124
     * objects
125
     */
126
    public function getEmails(bool $activeOnly = false): array
127
    {
128
        $arr = [];
129
        $id  = (int)$this->getVar('id');
130
        if (!$id) {
131
            return $arr;
132
        }
133
134
        $hEmails  = $this->helper->getHandler('TicketEmails');
135
        $criteria = new \CriteriaCompo(new \Criteria('ticketid', $id));
136
        if ($activeOnly) {
137
            $criteria->add(new \Criteria('suppress', 0));
138
        }
139
        $arr = $hEmails->getObjects($criteria);
140
141
        return $arr;
142
    }
143
144
    /**
145
     * retrieve all files attached to this ticket object
146
     *
147
     * @return array of {@link File} objects
148
     */
149
    public function getFiles(): array
150
    {
151
        $arr = [];
152
        $id  = (int)$this->getVar('id');
153
        if (!$id) {
154
            return $arr;
155
        }
156
157
        $fileHandler = $this->helper->getHandler('File');
158
        $criteria    = new \CriteriaCompo(new \Criteria('ticketid', $id));
159
        $criteria->setSort('responseid');
160
        $arr = $fileHandler->getObjects($criteria);
161
162
        return $arr;
163
    }
164
165
    /**
166
     * retrieve all responses attached to this ticket object
167
     *
168
     * @param int $limit
169
     * @param int $start
170
     * @return array of <a href='psi_element://Response'>Response</a> objects
171
     * objects
172
     */
173
    public function getResponses(int $limit = 0, int $start = 0): array
174
    {
175
        $arr = [];
176
        $id  = (int)$this->getVar('id');
177
        if (!$id) {
178
            return $arr;
179
        }
180
        $responseHandler = $this->helper->getHandler('Response');
181
        $criteria        = new \CriteriaCompo(new \Criteria('ticketid', $id));
182
        $criteria->setSort('updateTime');
183
        $criteria->setOrder('DESC');
184
        $criteria->setLimit($limit);
185
        $criteria->setStart($start);
186
187
        $arr = $responseHandler->getObjects($criteria);
188
189
        return $arr;
190
    }
191
192
    /**
193
     * Retrieve number of responses for this ticket object
194
     * @return int Number of Responses
195
     */
196
    public function getResponseCount(): int
197
    {
198
        $responseHandler = $this->helper->getHandler('Response');
199
        $criteria        = new \Criteria('ticketid', $this->getVar('id'));
0 ignored issues
show
Bug introduced by
It seems like $this->getVar('id') can also be of type array and array; however, parameter $value of Criteria::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

199
        $criteria        = new \Criteria('ticketid', /** @scrutinizer ignore-type */ $this->getVar('id'));
Loading history...
200
201
        return $responseHandler->getCount($criteria);
202
    }
203
204
    /**
205
     *  Get all reviews for the current ticket
206
     * @param int $limit
207
     * @param int $start
208
     * @return array of <a href='psi_element://StaffReview'>StaffReview</a>
209
     */
210
    public function getReviews(int $limit = 0, int $start = 0): array
211
    {
212
        $helper = Helper::getInstance();
213
        $arr    = [];
214
        $id     = (int)$this->getVar('id');
215
        if (!$id) {
216
            return $arr;
217
        }
218
        /** @var \XoopsModules\Xhelp\StaffReviewHandler $staffReviewHandler */
219
        $staffReviewHandler = $helper->getHandler('StaffReview');
220
        $criteria           = new \CriteriaCompo(new \Criteria('ticketid', $id));
221
        $criteria->setSort('responseid');
222
        $criteria->setOrder('DESC');
223
        $criteria->setLimit($limit);
224
        $criteria->setStart($start);
225
226
        $arr = $staffReviewHandler->getObjects($criteria);
227
228
        return $arr;
229
    }
230
231
    /**
232
     * retrieve all log messages attached to this ticket object
233
     *
234
     * @param int $limit
235
     * @param int $start
236
     * @return array of <a href='psi_element://LogMessages'>LogMessages</a> objects
237
     * objects
238
     */
239
    public function getLogs(int $limit = 0, int $start = 0): array
240
    {
241
        $arr = [];
242
        $id  = (int)$this->getVar('id');
243
        if (!$id) {
244
            return $arr;
245
        }
246
        /** @var \XoopsModules\Xhelp\LogMessageHandler $this- >logmessageHandler */
247
        $logMessageHandler = $this->helper->getHandler('LogMessage');
248
        $criteria          = new \CriteriaCompo(new \Criteria('ticketid', $id));
249
        $criteria->setSort('lastUpdated');
250
        $criteria->setOrder('DESC');
251
        $criteria->setLimit($limit);
252
        $criteria->setStart($start);
253
254
        $arr = $logMessageHandler->getObjects($criteria);
255
256
        return $arr;
257
    }
258
259
    /**
260
     * @param string                                   $post_field
261
     * @param \XoopsModules\Xhelp\Response|string|null $response
262
     * @param array|string|null                        $allowed_mimetypes
263
     * @return \XoopsModules\Xhelp\File|array|false|string|void
264
     */
265
    public function storeUpload(string $post_field, $response = null, $allowed_mimetypes = null)
266
    {
267
        global $xoopsUser, $xoopsDB, $xoopsModule;
268
        // require_once XHELP_CLASS_PATH . '/uploader.php';
269
270
        $config = Utility::getModuleConfig();
271
272
        $ticketid = $this->getVar('id');
273
274
        if (null === $allowed_mimetypes) {
275
            $mimetypeHandler   = $this->helper->getHandler('Mimetype');
276
            $allowed_mimetypes = $mimetypeHandler->checkMimeTypes($post_field);
277
            if (!$allowed_mimetypes) {
0 ignored issues
show
introduced by
The condition $allowed_mimetypes is always false.
Loading history...
278
                return false;
279
            }
280
        }
281
282
        $maxfilesize   = (int)$config['xhelp_uploadSize'];
283
        $maxfilewidth  = (int)$config['xhelp_uploadWidth'];
284
        $maxfileheight = (int)$config['xhelp_uploadHeight'];
285
        if (!\is_dir(XHELP_UPLOAD_PATH)) {
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Xhelp\XHELP_UPLOAD_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
286
            if (!\mkdir($concurrentDirectory = XHELP_UPLOAD_PATH, 0757) && !\is_dir($concurrentDirectory)) {
287
                throw new \RuntimeException(\sprintf('Directory "%s" was not created', $concurrentDirectory));
288
            }
289
        }
290
291
        $uploader = new MediaUploader(XHELP_UPLOAD_PATH . '/', $allowed_mimetypes, $maxfilesize, $maxfilewidth, $maxfileheight);
0 ignored issues
show
Bug introduced by
It seems like $allowed_mimetypes can also be of type string; however, parameter $allowedMimeTypes of XoopsModules\Xhelp\MediaUploader::__construct() does only seem to accept array|integer, maybe add an additional type check? ( Ignorable by Annotation )

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

291
        $uploader = new MediaUploader(XHELP_UPLOAD_PATH . '/', /** @scrutinizer ignore-type */ $allowed_mimetypes, $maxfilesize, $maxfilewidth, $maxfileheight);
Loading history...
292
        if ($uploader->fetchMedia($post_field)) {
293
            if (null === $response) {
294
                $uploader->setTargetFileName($ticketid . '_' . $uploader->getMediaName());
295
            } else {
296
                if ($response > 0) {
297
                    $uploader->setTargetFileName($ticketid . '_' . $response . '_' . $uploader->getMediaName());
0 ignored issues
show
Bug introduced by
Are you sure $response of type XoopsModules\Xhelp\Response|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

297
                    $uploader->setTargetFileName($ticketid . '_' . /** @scrutinizer ignore-type */ $response . '_' . $uploader->getMediaName());
Loading history...
298
                } else {
299
                    $uploader->setTargetFileName($ticketid . '_' . $uploader->getMediaName());
300
                }
301
            }
302
            if ($uploader->upload()) {
303
                $fileHandler = $this->helper->getHandler('File');
304
                $file        = $fileHandler->create();
305
                $file->setVar('filename', $uploader->getSavedFileName());
306
                $file->setVar('ticketid', $ticketid);
307
                $file->setVar('mimetype', $allowed_mimetypes);
308
                $file->setVar('responseid', (null !== $response ? (int)$response : 0));
309
310
                if ($fileHandler->insert($file)) {
311
                    return $file;
312
                }
313
314
                return $uploader->getErrors();
315
            }
316
317
            return $uploader->getErrors();
318
        }
319
    }
320
321
    /**
322
     * @param string     $post_field
323
     * @param array|null $allowed_mimetypes
324
     * @param array      $errors
325
     * @return bool
326
     */
327
    public function checkUpload(string $post_field, ?array &$allowed_mimetypes, array &$errors): bool
328
    {
329
        // require_once XHELP_CLASS_PATH . '/uploader.php';
330
        $config = Utility::getModuleConfig();
331
332
        $maxfilesize   = (int)$config['xhelp_uploadSize'];
333
        $maxfilewidth  = (int)$config['xhelp_uploadWidth'];
334
        $maxfileheight = (int)$config['xhelp_uploadHeight'];
335
        $errors        = [];
336
337
        if (null === $allowed_mimetypes) {
0 ignored issues
show
introduced by
The condition null === $allowed_mimetypes is always false.
Loading history...
338
            $mimetypeHandler   = $this->helper->getHandler('Mimetype');
339
            $allowed_mimetypes = $mimetypeHandler->checkMimeTypes($post_field);
340
            if (!$allowed_mimetypes) {
341
                $errors[] = \_XHELP_MESSAGE_WRONG_MIMETYPE;
342
343
                return false;
344
            }
345
        }
346
        $uploader = new MediaUploader(XHELP_UPLOAD_PATH . '/', $allowed_mimetypes, $maxfilesize, $maxfilewidth, $maxfileheight);
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Xhelp\XHELP_UPLOAD_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
347
348
        if ($uploader->fetchMedia($post_field)) {
349
            return true;
350
        }
351
352
        $errors = \array_merge($errors, $uploader->getErrors(false));
353
354
        return false;
355
    }
356
357
    /**
358
     * determine last time the ticket was updated relative to the current user
359
     *
360
     * @param string $format
361
     * @return int Timestamp of last update
362
     */
363
    public function lastUpdated(string $format = 'l'): int
364
    {
365
        return (int)\formatTimestamp($this->getVar('lastUpdated'), $format);
366
    }
367
368
    /**
369
     * @param string $format
370
     * @return string
371
     */
372
    public function posted(string $format = 'l'): string
373
    {
374
        return \formatTimestamp($this->getVar('posted'), $format);
375
    }
376
377
    /**
378
     * return a simplified measurement of elapsed ticket time
379
     *
380
     * @return string Elapsed time
381
     */
382
    public function elapsed(): string
383
    {
384
        $tmp = Utility::getElapsedTime($this->getVar('elapsed'));
385
386
        return $this->prettyElapsed($tmp);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->prettyElapsed($tmp) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
387
    }
388
389
    /**
390
     * @return string
391
     */
392
    public function lastUpdate(): string
393
    {
394
        $tmp = Utility::getElapsedTime($this->getVar('lastUpdate'));
395
396
        return $this->prettyElapsed($tmp);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->prettyElapsed($tmp) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
397
    }
398
399
    /**
400
     * @param array $time
401
     * @return string
402
     */
403
    private function prettyElapsed(array $time): ?string
404
    {
405
        $useSingle = false;
406
407
        foreach ($time as $unit => $value) {
408
            if ($value) {
409
                if (1 == $value) {
410
                    $useSingle = true;
411
                }
412
                switch ($unit) {
413
                    case 'years':
414
                        $unit_dsc = ($useSingle ? \_XHELP_TIME_YEAR : \_XHELP_TIME_YEARS);
415
                        break;
416
                    case 'weeks':
417
                        $unit_dsc = ($useSingle ? \_XHELP_TIME_WEEK : \_XHELP_TIME_WEEKS);
418
                        break;
419
                    case 'days':
420
                        $unit_dsc = ($useSingle ? \_XHELP_TIME_DAY : \_XHELP_TIME_DAYS);
421
                        break;
422
                    case 'hours':
423
                        $unit_dsc = ($useSingle ? \_XHELP_TIME_HOUR : \_XHELP_TIME_HOURS);
424
                        break;
425
                    case 'minutes':
426
                        $unit_dsc = ($useSingle ? \_XHELP_TIME_MIN : \_XHELP_TIME_MINS);
427
                        break;
428
                    case 'seconds':
429
                        $unit_dsc = ($useSingle ? \_XHELP_TIME_SEC : \_XHELP_TIME_SECS);
430
                        break;
431
                    default:
432
                        $unit_dsc = $unit;
433
                        break;
434
                }
435
436
                return "$value $unit_dsc";
437
            }
438
        }
439
    }
440
441
    /**
442
     * Determine if ticket is overdue
443
     *
444
     * @return bool
445
     */
446
    public function isOverdue(): bool
447
    {
448
        $config        = Utility::getModuleConfig();
449
        $statusHandler = $this->helper->getHandler('Status');
450
        if (isset($config['xhelp_overdueTime'])) {
451
            $overdueTime = $config['xhelp_overdueTime'];
452
453
            if ($overdueTime) {
454
                $status = $statusHandler->get($this->getVar('status'));
455
                if (1 == $status->getVar('state')) {
456
                    if (\time() > $this->getVar('overdueTime')) {
457
                        return true;
458
                    }
459
                }
460
            }
461
        }
462
463
        return false;
464
    }
465
466
    /**
467
     * @param string $email
468
     * @param int    $uid
469
     * @param int    $suppress
470
     * @return bool
471
     */
472
    public function addSubmitter(string $email, int $uid, int $suppress = 0): bool
473
    {
474
        $uid = $uid;
475
476
        if ('' != $email) {
477
            $ticketEmailsHandler = $this->helper->getHandler('TicketEmails');
478
            $tEmail              = $ticketEmailsHandler->create();
479
480
            $tEmail->setVar('ticketid', $this->getVar('id'));
481
            $tEmail->setVar('email', $email);
482
            $tEmail->setVar('uid', $uid);
483
            $tEmail->setVar('suppress', $suppress);
484
485
            if ($ticketEmailsHandler->insert($tEmail)) {
486
                return true;
487
            }
488
        }
489
490
        return false;
491
    }
492
493
    /**
494
     * @param int $ticket2_id
495
     * @return bool|mixed
496
     */
497
    public function merge(int $ticket2_id)
498
    {
499
        global $xoopsDB;
500
        $ticket2_id = $ticket2_id;
501
502
        // Retrieve $ticket2
503
        $ticketHandler = $this->helper->getHandler('Ticket');
504
        $mergeTicket   = $ticketHandler->get($ticket2_id);
505
506
        // Figure out which ticket is older
507
        if ($this->getVar('posted') < $mergeTicket->getVar('posted')) {   // If this ticket is older than the 2nd ticket
508
            $keepTicket = $this;
509
            $loseTicket = $mergeTicket;
510
        } else {
511
            $keepTicket = $mergeTicket;
512
            $loseTicket = $this;
513
        }
514
515
        $keep_id = $keepTicket->getVar('id');
516
        $lose_id = $loseTicket->getVar('id');
517
518
        // Copy ticket subject and description of 2nd ticket as response to $this ticket
519
        $responseid = $keepTicket->addResponse($loseTicket->getVar('uid'), $keep_id, $loseTicket->getVar('subject', 'e') . ' - ' . $loseTicket->getVar('description', 'e'), $loseTicket->getVar('posted'), $loseTicket->getVar('userIP'));
520
521
        // Copy 2nd ticket file attachments to $this ticket
522
        $fileHandler = $this->helper->getHandler('File');
523
        $criteria    = new \Criteria('ticketid', $lose_id);
0 ignored issues
show
Bug introduced by
It seems like $lose_id can also be of type array and array; however, parameter $value of Criteria::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

523
        $criteria    = new \Criteria('ticketid', /** @scrutinizer ignore-type */ $lose_id);
Loading history...
524
        $files       = $fileHandler->getObjects($criteria);
525
        foreach ($files as $file) {
526
            $file->rename($keep_id, $responseid);
527
        }
528
        $success = $fileHandler->updateAll('ticketid', $keep_id, $criteria);
0 ignored issues
show
Unused Code introduced by
The assignment to $success is dead and can be removed.
Loading history...
529
530
        // Copy 2nd ticket responses as responses to $this ticket
531
        $responseHandler = $this->helper->getHandler('Response');
532
        $criteria        = new \Criteria('ticketid', $lose_id);
533
        $success         = $responseHandler->updateAll('ticketid', $keep_id, $criteria);
534
535
        // Change file responseid to match the response added to merged ticket
536
        $criteria = new \CriteriaCompo(new \Criteria('ticketid', $lose_id));
537
        $criteria->add(new \Criteria('responseid', 0));
538
        $success = $fileHandler->updateAll('responseid', $responseid, $criteria);
539
540
        // Add 2nd ticket submitter to $this ticket via ticketEmails table
541
        $ticketEmailsHandler = $this->helper->getHandler('TicketEmails');
542
        $criteria            = new \Criteria('ticketid', $lose_id);
543
        $success             = $ticketEmailsHandler->updateAll('ticketid', $keep_id, $criteria);
544
545
        // Remove $loseTicket
546
        $criteria = new \Criteria('id', $lose_id);
547
        if (!$ticketHandler->deleteAll($criteria)) {
548
            return false;
549
        }
550
551
        return $keep_id;
552
    }
553
554
    /**
555
     * Check if the supplied user can add a response to the ticket
556
     * @param \XoopsUser $xoopsUser The user to check
557
     * @return bool
558
     */
559
    public function canAddResponse(\XoopsUser $xoopsUser): bool
560
    {
561
        //1. If the $xoopsUser a valid \XoopsUser Object
562
        if (!$xoopsUser instanceof \XoopsUser) {
0 ignored issues
show
introduced by
$xoopsUser is always a sub-type of XoopsUser.
Loading history...
563
            return false;
564
        }
565
566
        //2. Is the user one of the "ticket submitters"
567
        $ticketEmailsHandler = $this->helper->getHandler('TicketEmails');
568
        $criteria            = new \CriteriaCompo(new \Criteria('ticketid', $this->getVar('id')));
0 ignored issues
show
Bug introduced by
It seems like $this->getVar('id') can also be of type array and array; however, parameter $value of Criteria::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

568
        $criteria            = new \CriteriaCompo(new \Criteria('ticketid', /** @scrutinizer ignore-type */ $this->getVar('id')));
Loading history...
569
        $criteria->add(new \Criteria('uid', $xoopsUser->getVar('uid')));
570
        $count = $ticketEmailsHandler->getCount($criteria);
571
572
        if ($count > 0) {
573
            return true;
574
        }
575
576
        //3. Is the user a staff member?
577
        global $xhelp_isStaff, $staff;
578
        if ($xhelp_isStaff) {
579
            if ($staff->checkRoleRights(\XHELP_SEC_RESPONSE_ADD, $this->getVar('department'))) {
580
                return true;
581
            }
582
        }
583
584
        //4. If neither option is true, user cannot add response.
585
        return false;
586
    }
587
588
    /**
589
     * @param int    $uid
590
     * @param int    $ticketid
591
     * @param string $message
592
     * @param int    $updateTime
593
     * @param string $userIP
594
     * @param int    $private
595
     * @param int    $timeSpent
596
     * @param bool   $ret_obj
597
     * @return bool|mixed|\XoopsObject
598
     */
599
    public function addResponse(
600
        int $uid, int $ticketid, string $message, int $updateTime, string $userIP, int $private = 0, int $timeSpent = 0, bool $ret_obj = false
601
    ) {
602
        $uid        = $uid;
603
        $ticketid   = $ticketid;
604
        $updateTime = $updateTime;
605
        $private    = $private;
606
        $timeSpent  = $timeSpent;
607
608
        $responseHandler = $this->helper->getHandler('Response');
609
        $newResponse     = $responseHandler->create();
610
        $newResponse->setVar('uid', $uid);
611
        $newResponse->setVar('ticketid', $ticketid);
612
        $newResponse->setVar('message', $message);
613
        $newResponse->setVar('timeSpent', $timeSpent);
614
        $newResponse->setVar('updateTime', $updateTime);
615
        $newResponse->setVar('userIP', $userIP);
616
        $newResponse->setVar('private', $private);
617
        if ($responseHandler->insert($newResponse)) {
618
            if ($ret_obj) {
619
                return $newResponse;
620
            }
621
622
            return $newResponse->getVar('id');
623
        }
624
625
        return false;
626
    }
627
628
    /**
629
     * @param bool $includeEmptyValues
630
     * @return array
631
     */
632
    public function &getCustFieldValues(bool $includeEmptyValues = false): array
633
    {
634
        $ticketid = $this->getVar('id');
635
636
        /** @var \XoopsModules\Xhelp\TicketFieldHandler $ticketFieldHandler */
637
        $ticketFieldHandler = $this->helper->getHandler('TicketField');
638
        $fields             = $ticketFieldHandler->getObjects(null);                  // Retrieve custom fields
639
640
        $ticketValuesHandler = $this->helper->getHandler('TicketValues');
641
        $values              = $ticketValuesHandler->get($ticketid);               // Retrieve custom field values
642
        $aCustFields         = [];
643
        foreach ($fields as $field) {
644
            $fileid   = '';
645
            $filename = '';
646
            $value    = '';
647
            $key      = '';
648
            $hasValue = false;
649
            $_arr     = $field->toArray();
650
651
            if (false !== $values
652
                && '' != $values->getVar($field->getVar('fieldname'))) {             // If values for this field has something
653
                $fieldvalues = $field->getVar('fieldvalues');                        // Set fieldvalues
654
                $value       = $key = $values->getVar($field->getVar('fieldname'));  // Value of current field
655
656
                if (\XHELP_CONTROL_YESNO == $field->getVar('controltype')) {
657
                    $value = ((1 == $value) ? _YES : _NO);
658
                }
659
660
                if (\XHELP_CONTROL_FILE == $field->getVar('controltype')) {
661
                    $file     = \explode('_', $value);
662
                    $fileid   = $file[0];
663
                    $filename = $file[1];
664
                }
665
666
                if (\is_array($fieldvalues)) {
667
                    foreach ($fieldvalues as $fkey => $fvalue) {
668
                        if ($fkey == $value) {
669
                            $value = $fvalue;
670
                            break;
671
                        }
672
                    }
673
                }
674
675
                $hasValue = true;
676
            }
677
            $_arr['value']    = $value;
678
            $_arr['fileid']   = $fileid;
679
            $_arr['filename'] = $filename;
680
            $_arr['key']      = $key;
681
682
            if ($includeEmptyValues || $hasValue) {
683
                $aCustFields[$field->getVar('fieldname')] = $_arr;
684
            }
685
        }
686
687
        return $aCustFields;
688
    }
689
}   // end of class
690