Issues (1844)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class/Utility.php (19 issues)

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       Brian Wahoff <[email protected]>
19
 * @author       Eric Juden <[email protected]>
20
 * @author       XOOPS Development Team
21
 */
22
23
use const _XHELP_MAILBOXTYPE_POP3;
24
use const XHELP_ROLE_PERM_1;
25
use const XHELP_ROLE_PERM_2;
26
use const XHELP_ROLE_PERM_3;
27
use Xmf\Request;
28
29
/**
30
 * Class Utility
31
 */
32
class Utility extends Common\SysUtility
33
{
34
    //--------------- Custom module methods -----------------------------
35
    /**
36
     * Format a time as 'x' years, 'x' weeks, 'x' days, 'x' hours, 'x' minutes, 'x' seconds
37
     *
38
     * @param int $time UNIX timestamp
39
     * @return string formatted time
40
     */
41
    public static function formatTime(int $time): string
42
    {
43
        $values = self::getElapsedTime($time);
44
45
        foreach ($values as $key => $value) {
46
            $$key = $value;
47
        }
48
49
        $ret = [];
50
        if ($years) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $years seems to be never defined.
Loading history...
51
            $ret[] = $years . ' ' . (1 == $years ? \_XHELP_TIME_YEAR : \_XHELP_TIME_YEARS);
52
        }
53
54
        if ($weeks) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $weeks seems to be never defined.
Loading history...
55
            $ret[] = $weeks . ' ' . (1 == $weeks ? \_XHELP_TIME_WEEK : \_XHELP_TIME_WEEKS);
56
        }
57
58
        if ($days) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $days seems to be never defined.
Loading history...
59
            $ret[] = $days . ' ' . (1 == $days ? \_XHELP_TIME_DAY : \_XHELP_TIME_DAYS);
60
        }
61
62
        if ($hours) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $hours seems to be never defined.
Loading history...
63
            $ret[] = $hours . ' ' . (1 == $hours ? \_XHELP_TIME_HOUR : \_XHELP_TIME_HOURS);
64
        }
65
66
        if ($minutes) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $minutes seems to be never defined.
Loading history...
67
            $ret[] = $minutes . ' ' . (1 == $minutes ? \_XHELP_TIME_MIN : \_XHELP_TIME_MINS);
68
        }
69
70
        $ret[] = $seconds . ' ' . (1 == $seconds ? \_XHELP_TIME_SEC : \_XHELP_TIME_SECS);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $seconds seems to be never defined.
Loading history...
71
72
        return \implode(', ', $ret);
73
    }
74
75
    /**
76
     * Changes UNIX timestamp into array of time units of measure
77
     *
78
     * @param int $time UNIX timestamp
79
     * @return array
80
     */
81
    public static function getElapsedTime(int $time): array
82
    {
83
        //Define the units of measure
84
        $units = [
85
            'years'   => 365 * 60 * 60 * 24 /*Value of Unit expressed in seconds*/,
86
            'weeks'   => 7 * 60 * 60 * 24,
87
            'days'    => 60 * 60 * 24,
88
            'hours'   => 60 * 60,
89
            'minutes' => 60,
90
            'seconds' => 1,
91
        ];
92
93
        $local_time   = $time;
94
        $elapsed_time = [];
95
96
        //Calculate the total for each unit measure
97
        foreach ($units as $key => $single_unit) {
98
            $elapsed_time[$key] = \floor($local_time / $single_unit);
99
            $local_time         -= ($elapsed_time[$key] * $single_unit);
100
        }
101
102
        return $elapsed_time;
103
    }
104
105
    /**
106
     * Generate xhelp URL
107
     *
108
     * @param string $page
109
     * @param array  $vars
110
     * @param bool   $encodeAmp
111
     * @return string
112
     */
113
    public static function createURI(string $page, array $vars = [], bool $encodeAmp = true): string
114
    {
115
        $joinStr = '';
116
117
        $amp = ($encodeAmp ? '&amp;' : '&');
118
119
        if (!\count($vars)) {
120
            return $page;
121
        }
122
        $qs = '';
123
        foreach ($vars as $key => $value) {
124
            $qs      .= $joinStr . $key . '=' . $value;
125
            $joinStr = $amp;
126
        }
127
128
        return $page . '?' . $qs;
129
    }
130
131
    /**
132
     * Changes a ticket priority (int) into its string equivalent
133
     *
134
     * @param int $priority
135
     * @return string
136
     */
137
    public static function getPriority(int $priority)
138
    {
139
        $priorities = [
140
            1 => \_XHELP_TEXT_PRIORITY1,
141
            2 => \_XHELP_TEXT_PRIORITY2,
142
            3 => \_XHELP_TEXT_PRIORITY3,
143
            4 => \_XHELP_TEXT_PRIORITY4,
144
            5 => \_XHELP_TEXT_PRIORITY5,
145
        ];
146
147
        $priority = $priority;
148
149
        return ($priorities[$priority] ?? $priority);
150
    }
151
152
    /**
153
     * Gets a tickets state (unresolved/resolved)
154
     *
155
     * @param int $state
156
     * @return string
157
     */
158
    public static function getState(int $state)
159
    {
160
        $state       = $state;
161
        $stateValues = [
162
            1 => \_XHELP_STATE1,
163
            2 => \_XHELP_STATE2,
164
        ];
165
166
        return ($stateValues[$state] ?? $state);
167
    }
168
169
    /**
170
     * Changes a ticket status (int) into its string equivalent
171
     * Do not use this function in loops
172
     *
173
     * @param string|int $status
174
     * @return string Status Description
175
     */
176
    public static function getStatus($status)
177
    {
178
        static $statuses;
179
180
        $status = (int)$status;
181
        /** @var \XoopsModules\Xhelp\StatusHandler $statusHandler */
182
        $statusHandler = Helper::getInstance()
183
            ->getHandler('Status');
184
185
        //Get Statuses from database if first request
186
        if (!$statuses) {
187
            $statuses = $statusHandler->getObjects(null, true);
188
        }
189
190
        return (isset($statuses[$status]) ? $statuses[$status]->getVar('description') : $status);
191
    }
192
193
    /**
194
     * Changes a response rating (int) into its string equivalent
195
     *
196
     * @param int $rating
197
     * @return string
198
     */
199
    public static function getRating(int $rating)
200
    {
201
        $ratings = [
202
            0 => \_XHELP_RATING0,
203
            1 => \_XHELP_RATING1,
204
            2 => \_XHELP_RATING2,
205
            3 => \_XHELP_RATING3,
206
            4 => \_XHELP_RATING4,
207
            5 => \_XHELP_RATING5,
208
        ];
209
        $rating  = $rating;
210
211
        return ($ratings[$rating] ?? $rating);
212
    }
213
214
    /**
215
     * @param int $class
216
     * @return int|mixed
217
     */
218
    public static function getEventClass(int $class)
219
    {
220
        $classes = [
221
            0 => \_XHELP_MAIL_CLASS0,
222
            1 => \_XHELP_MAIL_CLASS1,
223
            2 => \_XHELP_MAIL_CLASS2,
224
            3 => \_XHELP_MAIL_CLASS3,
225
        ];
226
        $class   = $class;
227
228
        return ($classes[$class] ?? $class);
229
    }
230
231
    /**
232
     * Move specified tickets into department
233
     *
234
     * @param array $tickets array of ticket ids (int)
235
     * @param int   $dept    department ID
236
     * @return bool  True on success, False on error
237
     */
238
    public static function setDept(array $tickets, int $dept): bool
239
    {
240
        /** @var \XoopsModules\Xhelp\TicketHandler $ticketHandler */
241
        $ticketHandler = Helper::getInstance()
242
            ->getHandler('Ticket');
243
        $criteria      = new \Criteria('id', '(' . \implode(',', $tickets) . ')', 'IN');
244
245
        return $ticketHandler->updateAll('department', $dept, $criteria);
246
    }
247
248
    /**
249
     * Set specified tickets to a priority
250
     *
251
     * @param array $tickets  array of ticket ids (int)
252
     * @param int   $priority priority value
253
     * @return bool  True on success, False on error
254
     */
255
    public static function setPriority(array $tickets, int $priority): bool
256
    {
257
        /** @var \XoopsModules\Xhelp\TicketHandler $ticketHandler */
258
        $ticketHandler = Helper::getInstance()
259
            ->getHandler('Ticket');
260
        $criteria      = new \Criteria('id', '(' . \implode(',', $tickets) . ')', 'IN');
261
262
        return $ticketHandler->updateAll('priority', $priority, $criteria);
263
    }
264
265
    /**
266
     * Set specified tickets to a status
267
     *
268
     * @param array $tickets array of ticket ids (int)
269
     * @param int   $status  status value
270
     * @return bool  True on success, False on error
271
     */
272
    public static function setStatus(array $tickets, int $status): bool
273
    {
274
        /** @var \XoopsModules\Xhelp\TicketHandler $ticketHandler */
275
        $ticketHandler = Helper::getInstance()
276
            ->getHandler('Ticket');
277
        $criteria      = new \Criteria('id', '(' . \implode(',', $tickets) . ')', 'IN');
278
279
        return $ticketHandler->updateAll('status', $status, $criteria);
280
    }
281
282
    /**
283
     * Assign specified tickets to a staff member
284
     *
285
     * Assumes that owner is a member of all departments in specified tickets
286
     *
287
     * @param array $tickets array of ticket ids (int)
288
     * @param int   $owner   uid of new owner
289
     * @return bool  True on success, False on error
290
     */
291
    public static function setOwner(array $tickets, int $owner): bool
292
    {
293
        /** @var \XoopsModules\Xhelp\TicketHandler $ticketHandler */
294
        $ticketHandler = Helper::getInstance()
295
            ->getHandler('Ticket');
296
        $criteria      = new \Criteria('id', '(' . \implode(',', $tickets) . ')', 'IN');
297
298
        return $ticketHandler->updateAll('ownership', $owner, $criteria);
299
    }
300
301
    /**
302
     * Add the response to each ticket
303
     *
304
     *
305
     * @param array  $tickets   array of ticket ids (int)
306
     * @param string $sresponse
307
     * @param int    $timespent Number of minutes spent on ticket
308
     * @param bool   $private   Should this be a private message?
309
     * @return false|\XoopsModules\Xhelp\Response
310
     *
311
     * @internal param string $response response text to add
312
     */
313
    public static function addResponse(array $tickets, string $sresponse, int $timespent = 0, bool $private = false)
314
    {
315
        global $xoopsUser;
316
        /** @var \XoopsModules\Xhelp\ResponseHandler $responseHandler */
317
        $responseHandler = Helper::getInstance()
318
            ->getHandler('Response');
319
        /** @var \XoopsModules\Xhelp\TicketHandler $ticketHandler */
320
        $ticketHandler = Helper::getInstance()
321
            ->getHandler('Ticket');
322
        $updateTime    = \time();
323
        $uid           = $xoopsUser->getVar('uid');
324
        $ret           = true;
325
        $userIP        = \getenv('REMOTE_ADDR');
326
        $ticket_count  = \count($tickets);
327
        $i             = 1;
328
        foreach ($tickets as $ticketid) {
329
            /** @var \XoopsModules\Xhelp\Response $response */
330
            $response = $responseHandler->create();
331
            $response->setVar('uid', $uid);
332
            $response->setVar('ticketid', $ticketid);
333
            $response->setVar('message', $sresponse);
334
            $response->setVar('timeSpent', $timespent);
335
            $response->setVar('updateTime', $updateTime);
336
            $response->setVar('userIP', $userIP);
337
            $response->setVar('private', $private);
338
            $ret = $ret && $responseHandler->insert($response);
339
            if ($ticket_count != $i) {
340
                unset($response);
341
            }
342
            ++$i;
343
        }
344
        if ($ret) {
345
            $criteria = new \Criteria('id', '(' . \implode(',', $tickets) . ')', 'IN');
346
            $ret      = $ticketHandler->incrementAll('totalTimeSpent', $timespent, $criteria);
0 ignored issues
show
The assignment to $ret is dead and can be removed.
Loading history...
347
            $ret      = $ticketHandler->updateAll('lastUpdated', $updateTime, $criteria);
348
            $response->setVar('ticketid', 0);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $response seems to be defined by a foreach iteration on line 328. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
349
            $response->setVar('id', 0);
350
351
            return $response;
352
        }
353
354
        return false;
355
    }
356
357
    /**
358
     * Remove the specified tickets
359
     *
360
     * @param array $tickets array of ticket ids (int)
361
     * @return bool  True on success, False on error
362
     */
363
    public static function deleteTickets(array $tickets): bool
364
    {
365
        /** @var \XoopsModules\Xhelp\TicketHandler $ticketHandler */
366
        $ticketHandler = Helper::getInstance()
367
            ->getHandler('Ticket');
368
        $criteria      = new \Criteria('id', '(' . \implode(',', $tickets) . ')', 'IN');
369
370
        return $ticketHandler->deleteAll($criteria);
371
    }
372
373
    /**
374
     * Retrieves an array of tickets in one query
375
     *
376
     * @param array $tickets array of ticket ids (int)
377
     * @return array Array of ticket objects
378
     */
379
    public static function getTickets(array $tickets): array
380
    {
381
        /** @var \XoopsModules\Xhelp\TicketHandler $ticketHandler */
382
        $ticketHandler = Helper::getInstance()
383
            ->getHandler('Ticket');
384
        $criteria      = new \Criteria('t.id', '(' . \implode(',', $tickets) . ')', 'IN');
385
386
        return $ticketHandler->getObjects($criteria);
387
    }
388
389
    /**
390
     * Check if all supplied rules pass, and return any errors
391
     *
392
     * @param array|Validation\Validator $rules  array of {@link Validator} classes
393
     * @param array|null                 $errors array of errors found (if any)
394
     * @return bool  True if all rules pass, false if any fail
395
     */
396
    public static function checkRules($rules, ?array &$errors): bool
397
    {
398
        $ret = true;
399
        if (\is_array($rules)) {
400
            foreach ($rules as $rule) {
401
                $ret    = $ret && self::checkRules($rule, $error);
402
                $errors = \array_merge($errors, $error);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $error does not seem to be defined for all execution paths leading up to this point.
Loading history...
403
            }
404
        } else {
405
            if ($rules->isValid()) {
406
                $ret    = true;
407
                $errors = [];
408
            } else {
409
                $ret    = false;
410
                $errors = $rules->getErrors();
411
            }
412
        }
413
414
        return $ret;
415
    }
416
417
    /**
418
     * Output the specified variable (for debugging)
419
     *
420
     * @param mixed $var Variable to output
421
     */
422
    public static function debug($var): void
423
    {
424
        echo '<pre>';
425
        \print_r($var);
426
        echo '</pre>';
427
    }
428
429
    /**
430
     * Detemines if a table exists in the current db
431
     *
432
     * @param string $table the table name (without XOOPS prefix)
433
     * @return bool   True if table exists, false if not
434
     */
435
    public static function tableExists(string $table): bool
436
    {
437
        $bRetVal = false;
438
        //Verifies that a MySQL table exists
439
        $xoopsDB  = \XoopsDatabaseFactory::getDatabaseConnection();
440
        $realname = $xoopsDB->prefix($table);
441
        $dbname   = XOOPS_DB_NAME;
442
        $sql      = "SHOW TABLES FROM $dbname";
443
        $ret      = $xoopsDB->queryF($sql);
444
        while ([$m_table] = $xoopsDB->fetchRow($ret)) {
445
            if ($m_table == $realname) {
446
                $bRetVal = true;
447
                break;
448
            }
449
        }
450
        $xoopsDB->freeRecordSet($ret);
451
452
        return $bRetVal;
453
    }
454
455
    /**
456
     * Gets a value from a key in the xhelp_meta table
457
     *
458
     * @param string $key
459
     * @return string|bool|null
460
     */
461
    public static function getMeta(string $key)
462
    {
463
        $xoopsDB = \XoopsDatabaseFactory::getDatabaseConnection();
464
        $sql     = \sprintf('SELECT metavalue FROM `%s` WHERE metakey=%s', $xoopsDB->prefix('xhelp_meta'), $xoopsDB->quoteString($key));
465
        $result  = $xoopsDB->query($sql);
466
        if (!$result || $xoopsDB->getRowsNum($result) < 1) {
467
            $value = false;
468
        } else {
469
            [$value] = $xoopsDB->fetchRow($result);
470
        }
471
472
        return $value;
473
    }
474
475
    /**
476
     * Sets a value for a key in the xhelp_meta table
477
     *
478
     * @param string $key
479
     * @param string $value
480
     * @return bool   TRUE if success, FALSE if failure
481
     */
482
    public static function setMeta(string $key, string $value): bool
483
    {
484
        $xoopsDB = \XoopsDatabaseFactory::getDatabaseConnection();
485
        $ret     = self::getMeta($key);
486
        if (false !== $ret) {
487
            $sql = \sprintf('UPDATE `%s` SET metavalue = %s WHERE metakey = %s', $xoopsDB->prefix('xhelp_meta'), $xoopsDB->quoteString($value), $xoopsDB->quoteString($key));
488
        } else {
489
            $sql = \sprintf('INSERT INTO `%s` (metakey, metavalue) VALUES (%s, %s)', $xoopsDB->prefix('xhelp_meta'), $xoopsDB->quoteString($key), $xoopsDB->quoteString($value));
490
        }
491
        $ret = $xoopsDB->queryF($sql);
492
        if (!$ret) {
493
            return false;
494
        }
495
496
        return true;
497
    }
498
499
    /**
500
     * Deletes a record from the xhelp_meta table
501
     *
502
     * @param string $key
503
     * @return bool   TRUE if success, FALSE if failure
504
     */
505
    public static function deleteMeta(string $key): bool
506
    {
507
        $xoopsDB = \XoopsDatabaseFactory::getDatabaseConnection();
508
        $sql     = \sprintf('DELETE FROM `%s` WHERE metakey=%s', $xoopsDB->prefix('xhelp_meta'), $xoopsDB->quoteString($key));
509
        $ret     = $xoopsDB->query($sql);
510
        if (!$ret) {
511
            return false;
512
        }
513
514
        return $ret;
515
    }
516
517
    /**
518
     * Does the supplied email belong to an existing xoops user
519
     *
520
     * @param string $email
521
     * @return \XoopsUser|bool \xoopsUser object if success, FALSE if failure
522
     * object if success, FALSE if failure
523
     */
524
    public static function emailIsXoopsUser(string $email)
525
    {
526
        /** @var \XoopsMemberHandler $memberHandler */
527
        $memberHandler = \xoops_getHandler('member');
528
        $criteria      = new \Criteria('email', $email);
529
        $criteria->setLimit(1);
530
531
        $users = $memberHandler->getUsers($criteria);
532
        if (\count($users) > 0) {
533
            return $users[0];
534
        }
535
536
        return false;
537
    }
538
539
    /**
540
     * Detemines if a field exists in the current db
541
     *
542
     * @param string $table the table name (without XOOPS prefix)
543
     * @param string $field the field name
544
     * @return mixed  false if field does not exist, array containing field info if does
545
     */
546
    //    public static function fieldExists($table, $field)
547
    //    {
548
    //        $xoopsDB = \XoopsDatabaseFactory::getDatabaseConnection();
549
    //        $tblname = $xoopsDB->prefix($table);
550
    //        $ret = $xoopsDB->query("DESCRIBE $tblname");
551
    //
552
    //        if (!$ret) {
553
    //            return false;
554
    //        }
555
    //
556
    //        while (false !== ($row = $xoopsDB->fetchRow($ret))) {
557
    //            if (0 == \strcasecmp($row['Field'], $field)) {
558
    //                return $row;
559
    //            }
560
    //        }
561
    //
562
    //        return false;
563
    //    }
564
565
    /**
566
     * Creates a xoops account from an email address and password
567
     *
568
     * @param string $email
569
     * @param string $name
570
     * @param string $password
571
     * @param int    $level
572
     * @return \XoopsUser|bool \xoopsUser object if success, FALSE if failure
573
     */
574
    public static function getXoopsAccountFromEmail(string $email, string $name, string &$password, int $level)
575
    {
576
        /** @var \XoopsMemberHandler $memberHandler */
577
        $memberHandler = \xoops_getHandler('member');
578
579
        $unamecount = 10;
580
        if ('' === $password) {
581
            $password = mb_substr(\md5(\uniqid((string)\mt_rand(), true)), 0, 6);
582
        }
583
584
        $usernames = self::generateUserNames($email, $name, $unamecount);
585
        $newuser   = false;
586
        $i         = 0;
587
        while (!$newuser) {
588
            $criteria = new \Criteria('uname', $usernames[$i]);
589
            $count    = $memberHandler->getUserCount($criteria);
590
            if (0 == $count) {
591
                $newuser = true;
592
            } else {
593
                //Move to next username
594
                ++$i;
595
                if ($i == $unamecount) {
596
                    //Get next batch of usernames to try, reset counter
597
                    $usernames = self::generateUserNames($email->getEmail(), $email->getName(), $unamecount);
598
                    $i         = 0;
599
                }
600
            }
601
        }
602
603
        $xuser = $memberHandler->createUser();
604
        $xuser->setVar('uname', $usernames[$i]);
605
        $xuser->setVar('loginname', $usernames[$i]);
606
        $xuser->setVar('user_avatar', 'blank.gif');
607
        $xuser->setVar('user_regdate', \time());
608
        $xuser->setVar('timezone_offset', 0);
609
        $xuser->setVar('actkey', mb_substr(\md5(\uniqid((string)\mt_rand(), true)), 0, 8));
610
        $xuser->setVar('email', $email);
611
        $xuser->setVar('name', $name);
612
        $xuser->setVar('pass', \md5($password));
613
        $xuser->setVar('notify_method', 2);
614
        $xuser->setVar('level', $level);
615
616
        if ($memberHandler->insertUser($xuser)) {
617
            //Add the user to Registered Users group
618
            $memberHandler->addUserToGroup(XOOPS_GROUP_USERS, $xuser->getVar('uid'));
0 ignored issues
show
XoopsModules\Xhelp\XOOPS_GROUP_USERS of type string is incompatible with the type integer expected by parameter $group_id of XoopsMemberHandler::addUserToGroup(). ( Ignorable by Annotation )

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

618
            $memberHandler->addUserToGroup(/** @scrutinizer ignore-type */ XOOPS_GROUP_USERS, $xuser->getVar('uid'));
Loading history...
619
        } else {
620
            return false;
621
        }
622
623
        return $xuser;
624
    }
625
626
    /**
627
     * Generates an array of usernames
628
     *
629
     * @param string $email email of user
630
     * @param string $name  name of user
631
     * @param int    $count number of names to generate
632
     * @return array
633
     */
634
    public static function generateUserNames(string $email, string $name, int $count = 20): array
635
    {
636
        $names  = [];
637
        $userid = \explode('@', $email);
638
639
        $basename    = '';
640
        $hasbasename = false;
641
        $emailname   = $userid[0];
642
643
        $names[] = $emailname;
644
645
        if ('' !== $name) {
646
            $name = \explode(' ', \trim($name));
647
            if (\count($name) > 1) {
648
                $basename = \mb_strtolower(mb_substr($name[0], 0, 1) . $name[\count($name) - 1]);
649
            } else {
650
                $basename = \mb_strtolower($name[0]);
651
            }
652
            $basename = \xoops_substr($basename, 0, 60, '');
653
            //Prevent Duplication of Email Username and Name
654
            if (!\in_array($basename, $names)) {
655
                $names[]     = $basename;
656
                $hasbasename = true;
657
            }
658
        }
659
660
        $i          = \count($names);
661
        $onbasename = 1;
662
        while ($i < $count) {
663
            $num = self::generateRandNumber();
664
            if ($onbasename < 0 && $hasbasename) {
665
                $names[] = \xoops_substr($basename, 0, 58, '') . $num;
666
            } else {
667
                $names[] = \xoops_substr($emailname, 0, 58, '') . $num;
668
            }
669
            $i          = \count($names);
670
            $onbasename = ~$onbasename;
671
            $num        = '';
0 ignored issues
show
The assignment to $num is dead and can be removed.
Loading history...
672
        }
673
674
        return $names;
675
    }
676
677
    /**
678
     * Gives the random number generator a seed to start from
679
     *
680
     * @return void
681
     *
682
     * @access public
683
     */
684
    public static function initRand(): void
685
    {
686
        static $randCalled = false;
687
        if (!$randCalled) {
688
            // mt_srand((double)microtime() * 1000000);
689
            $randCalled = true;
690
        }
691
    }
692
693
    /**
694
     * Creates a random number with a specified number of $digits
695
     *
696
     * @param int $digits number of digits
697
     * @return string random number
698
     */
699
    public static function generateRandNumber(int $digits = 2): string
700
    {
701
        self::initRand();
702
        $tmp = [];
703
704
        for ($i = 0; $i < $digits; $i++) {
705
            $tmp[$i] = (\mt_rand() % 9);
706
        }
707
708
        return \implode('', $tmp);
709
    }
710
711
    /**
712
     * Converts int $type into its string equivalent
713
     *
714
     * @param int $type
715
     * @return string
716
     */
717
    public static function getMBoxType(int $type): string
718
    {
719
        $mboxTypes = [
720
            \_XHELP_MAILBOXTYPE_POP3 => 'POP3',
721
            \_XHELP_MAILBOXTYPE_IMAP => 'IMAP',
722
        ];
723
724
        return ($mboxTypes[$type] ?? 'NA');
725
    }
726
727
    /**
728
     * Retrieve list of all staff members
729
     *
730
     * @param int $displayName
731
     * @return array Staff objects
732
     * objects
733
     */
734
    public static function getStaff(int $displayName): array
735
    {
736
        $xoopsDB = \XoopsDatabaseFactory::getDatabaseConnection();
737
738
        $sql = \sprintf('SELECT u.uid, u.uname, u.name FROM `%s` u INNER JOIN %s s ON u.uid = s.uid ORDER BY u.uname', $xoopsDB->prefix('users'), $xoopsDB->prefix('xhelp_staff'));
739
        $ret = $xoopsDB->query($sql);
740
741
        $staff[-1] = \_XHELP_TEXT_SELECT_ALL;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$staff was never initialized. Although not strictly required by PHP, it is generally a good practice to add $staff = array(); before regardless.
Loading history...
742
        $staff[0]  = \_XHELP_NO_OWNER;
743
        while (false !== ($member = $xoopsDB->fetchArray($ret))) {
744
            $staff[$member['uid']] = self::getDisplayName($displayName, $member['name'], $member['uname']);
745
        }
746
747
        return $staff;
748
    }
749
750
    /**
751
     * Create default staff roles for a new installation
752
     *
753
     * @return bool true if success, FALSE if failure
754
     */
755
    public static function createRoles(): bool
756
    {
757
        if (!\defined('_XHELP_ROLE_NAME1')) {
758
            self::includeLang('main', 'english');
759
        }
760
761
        $defaultRolePermissions = [
762
            1 => ['name' => \_XHELP_ROLE_NAME1, 'desc' => \_XHELP_ROLE_DSC1, 'value' => XHELP_ROLE_PERM_1],
763
            2 => ['name' => \_XHELP_ROLE_NAME2, 'desc' => \_XHELP_ROLE_DSC2, 'value' => XHELP_ROLE_PERM_2],
764
            3 => ['name' => \_XHELP_ROLE_NAME3, 'desc' => \_XHELP_ROLE_DSC3, 'value' => XHELP_ROLE_PERM_3],
765
        ];
766
767
        /** @var \XoopsModules\Xhelp\RoleHandler $roleHandler */
768
        $roleHandler = Helper::getInstance()
769
            ->getHandler('Role');
770
771
        foreach ($defaultRolePermissions as $key => $aRole) {
772
            /** @var \XoopsModules\Xhelp\Role $role */
773
            $role = $roleHandler->create();
774
            $role->setVar('id', $key);
775
            $role->setVar('name', $aRole['name']);
776
            $role->setVar('description', $aRole['desc']);
777
            $role->setVar('tasks', $aRole['value']);
778
            if (!$roleHandler->insert($role)) {
779
                return false;
780
            }
781
        }
782
783
        return true;
784
    }
785
786
    /**
787
     * Create ticket statuses for a new installation
788
     *
789
     * @return bool true if success, FALSE if failure
790
     */
791
    public static function createStatuses(): bool
792
    {
793
        if (!\defined('_XHELP_STATUS0')) {
794
            self::includeLang('main', 'english');
795
        }
796
797
        $statuses = [
798
            1 => ['description' => \_XHELP_STATUS0, 'state' => \XHELP_STATE_UNRESOLVED],
799
            2 => ['description' => \_XHELP_STATUS1, 'state' => \XHELP_STATE_UNRESOLVED],
800
            3 => ['description' => \_XHELP_STATUS2, 'state' => \XHELP_STATE_RESOLVED],
801
        ];
802
803
        /** @var \XoopsModules\Xhelp\StatusHandler $statusHandler */
804
        $statusHandler = Helper::getInstance()
805
            ->getHandler('Status');
806
        foreach ($statuses as $id => $status) {
807
            /** @var \XoopsModules\Xhelp\Status $newStatus */
808
            $newStatus = $statusHandler->create();
809
            $newStatus->setVar('id', $id);
810
            $newStatus->setVar('description', $status['description']);
811
            $newStatus->setVar('state', $status['state']);
812
813
            if (!$statusHandler->insert($newStatus)) {
814
                return false;
815
            }
816
        }
817
818
        return true;
819
    }
820
821
    /**
822
     * Convert Bytes to a human readable size (GB, MB, KB, etc)
823
     *
824
     * @param int $bytes
825
     * @return string Human readable size
826
     */
827
    public static function prettyBytes(int $bytes): string
828
    {
829
        $bytes = $bytes;
830
831
        if ($bytes >= 1099511627776) {
832
            $return = \number_format($bytes / 1024 / 1024 / 1024 / 1024, 2);
833
            $suffix = \_XHELP_SIZE_TB;
834
        } elseif ($bytes >= 1073741824) {
835
            $return = \number_format($bytes / 1024 / 1024 / 1024, 2);
836
            $suffix = \_XHELP_SIZE_GB;
837
        } elseif ($bytes >= 1048576) {
838
            $return = \number_format($bytes / 1024 / 1024, 2);
839
            $suffix = \_XHELP_SIZE_MB;
840
        } elseif ($bytes >= 1024) {
841
            $return = \number_format($bytes / 1024, 2);
842
            $suffix = \_XHELP_SIZE_KB;
843
        } else {
844
            $return = $bytes;
845
            $suffix = \_XHELP_SIZE_BYTES;
846
        }
847
848
        return $return . ' ' . $suffix;
849
    }
850
851
    /**
852
     * Add a new database field to an existing table
853
     * MySQL Only!
854
     *
855
     * @param string $table
856
     * @param string $fieldname
857
     * @param string $fieldtype
858
     * @param int    $size
859
     * @param null   $attr
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $attr is correct as it would always require null to be passed?
Loading history...
860
     * @return resource SQL query resource
861
     */
862
    public static function addDBField(string $table, string $fieldname, string $fieldtype = 'VARCHAR', int $size = 0, $attr = null)
863
    {
864
        $xoopsDB = \XoopsDatabaseFactory::getDatabaseConnection();
865
866
        $column_def = $fieldname;
867
        if ($size) {
868
            $column_def .= \sprintf(' %s(%s)', $fieldtype, $size);
869
        } else {
870
            $column_def .= " $fieldtype";
871
        }
872
        if (\is_array($attr)) {
0 ignored issues
show
The condition is_array($attr) is always false.
Loading history...
873
            if (isset($attr['nullable']) && true === $attr['nullable']) {
874
                $column_def .= ' NULL';
875
            } else {
876
                $column_def .= ' NOT NULL';
877
            }
878
879
            if (isset($attr['default'])) {
880
                $column_def .= ' DEFAULT ' . $xoopsDB->quoteString($attr['default']);
881
            }
882
883
            if (isset($attr['increment'])) {
884
                $column_def .= ' AUTO_INCREMENT';
885
            }
886
887
            if (isset($attr['key'])) {
888
                $column_def .= ' KEY';
889
            }
890
891
            if (isset($attr['comment'])) {
892
                $column_def .= 'COMMENT ' . $xoopsDB->quoteString($attr['comment']);
893
            }
894
        }
895
896
        $sql = \sprintf('ALTER TABLE %s ADD COLUMN %s', $xoopsDB->prefix($table), $column_def);
897
        $ret = $xoopsDB->query($sql);
898
899
        return $ret;
900
    }
901
902
    /**
903
     * Rename an existing database field
904
     * MySQL Only!
905
     *
906
     * @param string $table
907
     * @param string $oldcol
908
     * @param string $newcol
909
     * @param string $fieldtype
910
     * @param int    $size
911
     * @return resource SQL query resource
912
     */
913
    public static function renameDBField(string $table, string $oldcol, string $newcol, string $fieldtype = 'VARCHAR', int $size = 0)
914
    {
915
        $xoopsDB    = \XoopsDatabaseFactory::getDatabaseConnection();
916
        $column_def = $newcol;
917
        $column_def .= ($size ? \sprintf(' %s(%s)', $fieldtype, $size) : " $fieldtype");
918
        $sql        = \sprintf('ALTER TABLE %s CHANGE %s %s', $xoopsDB->prefix($table), $oldcol, $column_def);
919
        $ret        = $xoopsDB->query($sql);
920
921
        return $ret;
922
    }
923
924
    /**
925
     * Remove an existing database field
926
     * MySQL Only!
927
     *
928
     * @param string $table
929
     * @param string $column
930
     * @return resource SQL query resource
931
     */
932
    public static function removeDBField(string $table, string $column)
933
    {
934
        $xoopsDB = \XoopsDatabaseFactory::getDatabaseConnection();
935
        $sql     = \sprintf('ALTER TABLE %s DROP COLUMN `%s`', $xoopsDB->prefix($table), $column);
936
        $ret     = $xoopsDB->query($sql);
937
938
        return $ret;
939
    }
940
941
    /**
942
     * Mark all staff accounts as being updated
943
     *
944
     * @return bool True on success, False on Error
945
     */
946
    public static function resetStaffUpdatedTime(): bool
947
    {
948
        /** @var \XoopsModules\Xhelp\StaffHandler $staffHandler */
949
        $staffHandler = Helper::getInstance()
950
            ->getHandler('Staff');
951
952
        return $staffHandler->updateAll('permTimestamp', \time());
953
    }
954
955
    /**
956
     * Retrieve the XoopsModule object representing this application
957
     *
958
     * @return \XoopsModule object representing this application
959
     */
960
    public static function getModule(): \XoopsModule
961
    {
962
        global $xoopsModule;
963
        static $_module;
964
965
        if (null !== $_module) {
966
            return $_module;
967
        }
968
969
        if (null !== $xoopsModule && \is_object($xoopsModule) && \XHELP_DIR_NAME == $xoopsModule->getVar('dirname')) {
970
            $_module = &$xoopsModule;
971
        } else {
972
            /** @var \XoopsModuleHandler $moduleHandler */
973
            $moduleHandler = \xoops_getHandler('module');
974
            $_module       = $moduleHandler->getByDirname('xhelp');
975
        }
976
977
        return $_module;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $_module could return the type false which is incompatible with the type-hinted return XoopsModule. Consider adding an additional type-check to rule them out.
Loading history...
978
    }
979
980
    /**
981
     * Retrieve this modules configuration variables
982
     *
983
     * @return array Key = config variable name, Value = current value
984
     */
985
    public static function getModuleConfig(): array
986
    {
987
        static $_config;
988
989
        if (null === $_config) {
990
            /** @var \XoopsConfigHandler $configHandler */
991
            $configHandler = \xoops_getHandler('config');
992
            $_module       = self::getModule();
993
994
            $_config = &$configHandler->getConfigsByCat(0, $_module->getVar('mid'));
995
        }
996
997
        return $_config;
998
    }
999
1000
    //    /**
1001
    //     * Wrapper for the xoops_getModuleHandler function
1002
    //     *
1003
    //     * @param string $handler Name of the handler to return
1004
    //     * @return \XoopsObjectHandler The object handler requested
1005
    //     */
1006
    //    public static function getHandler($handler)
1007
    //    {
1008
    //        //        $handler = xoops_getModuleHandler($handler, XHELP_DIR_NAME);
1009
    //        require_once \dirname(__DIR__) . '/preloads/autoloader.php';
1010
    //        $class      = '\\XoopsModules\\Xhelp\\' . $handler . 'Handler';
1011
    //        $newHandler = new $class($GLOBALS['xoopsDB']);
1012
    //
1013
    //        return $newHandler;
1014
    //    }
1015
1016
    /**
1017
     * Retrieve all saved searches for the specified user(s)
1018
     *
1019
     * @param mixed $users Either an integer (UID) or an array of UIDs
1020
     * @return bool|array SavedSearch objects
1021
     */
1022
    public static function getSavedSearches($users)
1023
    {
1024
        /** @var \XoopsModules\Xhelp\SavedSearchHandler $savedSearchHandler */
1025
        $savedSearchHandler = Helper::getInstance()
1026
            ->getHandler('SavedSearch');
1027
1028
        if (\is_array($users)) {
1029
            $criteria = new \Criteria('uid', '(' . \implode(',', $users) . ')', 'IN');
1030
        } else {
1031
            $criteria = new \Criteria('uid', (int)$users);
1032
        }
1033
1034
        $savedSearches = $savedSearchHandler->getObjects($criteria);
1035
1036
        $ret = [];
1037
        foreach ($savedSearches as $obj) {
1038
            $ret[$obj->getVar('id')] = [
1039
                'id'            => $obj->getVar('id'),
1040
                'uid'           => $obj->getVar('uid'),
1041
                'name'          => $obj->getVar('name'),
1042
                'search'        => \unserialize($obj->getVar('search')),
1043
                'pagenav_vars'  => $obj->getVar('pagenav_vars'),
1044
                'hasCustFields' => $obj->getVar('hasCustFields'),
1045
            ];
1046
        }
1047
1048
        return (\count($ret) > 0 ? $ret : false);
1049
    }
1050
1051
    /**
1052
     * Set default notification settings for all xhelp events
1053
     *
1054
     * @return bool True on success, False on failure
1055
     */
1056
    public static function createNotifications(): bool
1057
    {
1058
        /** @var \XoopsModules\Xhelp\RoleHandler $roleHandler */
1059
        $roleHandler = Helper::getInstance()
1060
            ->getHandler('Role');
1061
        /** @var \XoopsModules\Xhelp\NotificationHandler $notificationHandler */
1062
        $notificationHandler = Helper::getInstance()
1063
            ->getHandler('Notification');
1064
1065
        // Get list of all roles
1066
        $roles = $roleHandler->getObjects();
1067
1068
        $allRoles = [];
1069
        foreach ($roles as $role) {
1070
            $allRoles[$role->getVar('id')] = $role->getVar('id');
1071
        }
1072
1073
        $notifications = [
1074
            ['id' => 1, 'staff' => \XHELP_NOTIF_STAFF_DEPT, 'user' => \XHELP_NOTIF_USER_YES],
1075
            ['id' => 2, 'staff' => \XHELP_NOTIF_STAFF_DEPT, 'user' => \XHELP_NOTIF_USER_YES],
1076
            ['id' => 3, 'staff' => \XHELP_NOTIF_STAFF_DEPT, 'user' => \XHELP_NOTIF_USER_YES],
1077
            ['id' => 4, 'staff' => \XHELP_NOTIF_STAFF_OWNER, 'user' => \XHELP_NOTIF_USER_YES],
1078
            ['id' => 5, 'staff' => \XHELP_NOTIF_STAFF_OWNER, 'user' => \XHELP_NOTIF_USER_YES],
1079
            ['id' => 6, 'staff' => \XHELP_NOTIF_STAFF_DEPT, 'user' => \XHELP_NOTIF_USER_YES],
1080
            ['id' => 7, 'staff' => \XHELP_NOTIF_STAFF_DEPT, 'user' => \XHELP_NOTIF_USER_YES],
1081
            ['id' => 8, 'staff' => \XHELP_NOTIF_STAFF_OWNER, 'user' => \XHELP_NOTIF_USER_NO],
1082
            ['id' => 9, 'staff' => \XHELP_NOTIF_STAFF_DEPT, 'user' => \XHELP_NOTIF_USER_YES],
1083
            ['id' => 10, 'staff' => \XHELP_NOTIF_STAFF_DEPT, 'user' => \XHELP_NOTIF_USER_YES],
1084
        ];
1085
1086
        foreach ($notifications as $notif) {
1087
            /** @var \XoopsModules\Xhelp\Notification $template */
1088
            $template = $notificationHandler->create();
1089
            $template->setVar('notif_id', $notif['id']);
1090
            $template->setVar('staff_setting', $notif['staff']);
1091
            $template->setVar('user_setting', $notif['user']);
1092
            //Set the notification for all staff roles (if necessary)
1093
            if (\XHELP_NOTIF_STAFF_DEPT == $notif['staff']) {
1094
                $template->setVar('staff_options', $allRoles);
1095
            } else {
1096
                $template->setVar('staff_options', []);
1097
            }
1098
            $notificationHandler->insert($template, true);
1099
        }
1100
1101
        return true;
1102
    }
1103
1104
    /**
1105
     * Get the XOOPS username or realname for the specified users
1106
     *
1107
     * @param \CriteriaElement|\CriteriaCompo|null $criteria    Which users to retrieve
1108
     * @param int                                  $displayName XHELP_DISPLAYNAME_UNAME for username XHELP_DISPLAYNAME_REALNAME for realname
1109
     * @return array True on success, False on failure
1110
     */
1111
    public static function getUsers(\CriteriaElement $criteria = null, int $displayName = \XHELP_DISPLAYNAME_UNAME): array
1112
    {
1113
        /** @var \XoopsUserHandler $userHandler */
1114
        $userHandler = \xoops_getHandler('user');
1115
        $users       = $userHandler->getObjects($criteria, true);
1116
        $ret         = [];
1117
        foreach ($users as $i => $user) {
1118
            $ret[$i] = self::getDisplayName($displayName, $user->getVar('name'), $user->getVar('uname'));
1119
        }
1120
1121
        return $ret;
1122
    }
1123
1124
    /**
1125
     * Retrieve a user's name or username depending on value of xhelp_displayName preference
1126
     *
1127
     * @param mixed $xUser       {@link $xoopsUser object) or int {userid}
1128
     * @param int   $displayName {xhelp_displayName preference value}
1129
     *
1130
     * @return string username or real name
1131
     */
1132
    public static function getUsername($xUser, int $displayName = \XHELP_DISPLAYNAME_UNAME): string
1133
    {
1134
        global $xoopsUser, $xoopsConfig;
1135
        $user = false;
1136
        /** @var \XoopsMemberHandler $memberHandler */
1137
        $memberHandler = \xoops_getHandler('member');
1138
1139
        if (\is_numeric($xUser)) {
1140
            if ($xUser != (int)$xoopsUser->getVar('uid')) {
1141
                if (0 == $xUser) {
1142
                    return $xoopsConfig['anonymous'];
1143
                }
1144
                $user = $memberHandler->getUser($xUser);
1145
            } else {
1146
                $user = $xoopsUser;
1147
            }
1148
        } elseif (\is_object($xUser)) {
1149
            $user = $xUser;
1150
        } else {
1151
            return $xoopsConfig['anonymous'];
1152
        }
1153
1154
        $ret = self::getDisplayName($displayName, $user->getVar('name'), $user->getVar('uname'));
1155
1156
        return $ret;
1157
    }
1158
1159
    /**
1160
     * Retrieve the Displayname for the user
1161
     *
1162
     * @param int    $displayName {xhelp_displayName preference value}
1163
     * @param string $name        {user's real name}
1164
     * @param string $uname       {user's username}
1165
     * @return string {username or real name}
1166
     */
1167
    public static function getDisplayName(int $displayName, string $name = '', string $uname = ''): string
1168
    {
1169
        return ((\XHELP_DISPLAYNAME_REALNAME == $displayName && '' != $name) ? $name : $uname);
1170
    }
1171
1172
    /**
1173
     * Retrieve the site's active language
1174
     *
1175
     * @return string Name of language
1176
     */
1177
    public static function getSiteLanguage(): string
1178
    {
1179
        global $xoopsConfig;
1180
        if (null !== $xoopsConfig && isset($xoopsConfig['language'])) {
1181
            $language = $xoopsConfig['language'];
1182
        } else {
1183
            /** @var \XoopsConfigHandler $configHandler */
1184
            $configHandler = \xoops_getHandler('config');
1185
            $xoopsConfig   = $configHandler->getConfigsByCat(\XOOPS_CONF);
1186
            $language      = $xoopsConfig['language'];
1187
        }
1188
1189
        return $language;
1190
    }
1191
1192
    /**
1193
     * Include the specified language translation
1194
     *
1195
     * @param string $filename file to include
1196
     * @param null   $language translation to use
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $language is correct as it would always require null to be passed?
Loading history...
1197
     */
1198
    public static function includeLang(string $filename, $language = null): void
1199
    {
1200
        $langFiles = ['admin', 'blocks', 'main', 'modinfo', 'noise_words'];
1201
1202
        if (!\in_array($filename, $langFiles)) {
1203
            \trigger_error('Invalid language file inclusion attempt', \E_USER_ERROR);
1204
        }
1205
1206
        if (null === $language) {
0 ignored issues
show
The condition null === $language is always true.
Loading history...
1207
            $language = self::getSiteLanguage();
0 ignored issues
show
The assignment to $language is dead and can be removed.
Loading history...
1208
        }
1209
1210
        \xoops_loadLanguage($filename, 'xhelp');
1211
    }
1212
1213
    /**
1214
     * @param string $reportName
1215
     */
1216
    public static function includeReportLangFile(string $reportName): void
1217
    {
1218
        \xoops_loadLanguage($reportName, 'xhelp');
1219
    }
1220
1221
    /**
1222
     * Retrieve the Displayname for the user
1223
     * @return bool {username or real name}
1224
     * @internal param int $displayName {xhelp_displayName preference value}
1225
     * @internal param string $name {user's real name}
1226
     * @internal param string $uname {user's username}
1227
     */
1228
    public static function createDefaultTicketLists(): bool
1229
    {
1230
        /** @var \XoopsModules\Xhelp\SavedSearchHandler $savedSearchHandler */
1231
        $savedSearchHandler = Helper::getInstance()
1232
            ->getHandler('SavedSearch');
1233
        /** @var \XoopsModules\Xhelp\TicketListHandler $ticketListHandler */
1234
        $ticketListHandler = Helper::getInstance()
1235
            ->getHandler('TicketList');
1236
        /** @var \XoopsModules\Xhelp\StaffHandler $staffHandler */
1237
        $staffHandler = Helper::getInstance()
1238
            ->getHandler('Staff');
1239
1240
        $ticketLists = [\XHELP_QRY_STAFF_HIGHPRIORITY, \XHELP_QRY_STAFF_NEW, \XHELP_QRY_STAFF_MINE, \XHELP_QRY_STAFF_ALL];
1241
        $i           = 1;
1242
        foreach ($ticketLists as $ticketList) {
1243
            /** @var \XoopsModules\Xhelp\SavedSearch $newSearch */
1244
            $newSearch = $savedSearchHandler->create();
1245
            $criteria  = new \CriteriaCompo();
1246
            switch ($ticketList) {
1247
                case \XHELP_QRY_STAFF_HIGHPRIORITY:
1248
                    $criteria->add(new \Criteria('uid', \XHELP_GLOBAL_UID, '=', 'j'));
1249
                    $criteria->add(new \Criteria('state', 1, '=', 's'));
1250
                    $criteria->add(new \Criteria('ownership', 0, '=', 't'));
1251
                    $criteria->setSort('t.priority, t.posted');
1252
                    $newSearch->setVar('name', \_XHELP_TEXT_HIGH_PRIORITY);
1253
                    $newSearch->setVar('pagenav_vars', 'limit=50&state=1');
1254
                    break;
1255
                case \XHELP_QRY_STAFF_NEW:
1256
                    $criteria->add(new \Criteria('uid', \XHELP_GLOBAL_UID, '=', 'j'));
1257
                    $criteria->add(new \Criteria('ownership', 0, '=', 't'));
1258
                    $criteria->add(new \Criteria('state', 1, '=', 's'));
1259
                    $criteria->setSort('t.posted');
1260
                    $criteria->setOrder('DESC');
1261
                    $newSearch->setVar('name', \_XHELP_TEXT_NEW_TICKETS);
1262
                    $newSearch->setVar('pagenav_vars', 'limit=50&state=1');
1263
                    break;
1264
                case \XHELP_QRY_STAFF_MINE:
1265
                    $criteria->add(new \Criteria('uid', \XHELP_GLOBAL_UID, '=', 'j'));
1266
                    $criteria->add(new \Criteria('ownership', \XHELP_GLOBAL_UID, '=', 't'));
1267
                    $criteria->add(new \Criteria('state', 1, '=', 's'));
1268
                    $criteria->setSort('t.posted');
1269
                    $newSearch->setVar('name', \_XHELP_TEXT_MY_TICKETS);
1270
                    $newSearch->setVar('pagenav_vars', 'limit=50&state=1&ownership=' . \XHELP_GLOBAL_UID);
1271
                    break;
1272
                case \XHELP_QRY_STAFF_ALL:
1273
                    $criteria->add(new \Criteria('uid', \XHELP_GLOBAL_UID, '=', 'j'));
1274
                    $criteria->add(new \Criteria('state', 1, '=', 's'));
1275
                    $criteria->add(new \Criteria('uid', \XHELP_GLOBAL_UID, '=', 't'));
1276
                    $newSearch->setVar('name', \_XHELP_TEXT_SUBMITTED_TICKETS);
1277
                    $newSearch->setVar('pagenav_vars', 'limit=50&state=1&submittedBy=' . \XHELP_GLOBAL_UID);
1278
                    break;
1279
                default:
1280
                    return false;
1281
            }
1282
1283
            $newSearch->setVar('uid', \XHELP_GLOBAL_UID);
1284
            $newSearch->setVar('search', \serialize($criteria));
1285
            $newSearch->setVar('hasCustFields', 0);
1286
            $ret = $savedSearchHandler->insert($newSearch, true);
0 ignored issues
show
The assignment to $ret is dead and can be removed.
Loading history...
1287
1288
            $staff = $staffHandler->getObjects(null, true);
1289
            foreach ($staff as $stf) {
1290
                /** @var \XoopsModules\Xhelp\TicketList $list */
1291
                $list = $ticketListHandler->create();
1292
                $list->setVar('uid', $stf->getVar('uid'));
1293
                $list->setVar('searchid', $newSearch->getVar('id'));
1294
                $list->setVar('weight', $i);
1295
                $ret = $ticketListHandler->insert($list, true);
1296
            }
1297
            ++$i;
1298
        }
1299
1300
        return true;
1301
    }
1302
1303
    /**
1304
     * Generate publisher URL
1305
     *
1306
     * @param string $page
1307
     * @param array  $vars
1308
     * @param bool   $encodeAmp
1309
     * @return string
1310
     *
1311
     * @credit : xHelp module, developped by 3Dev
1312
     */
1313
    public static function makeUri(string $page, array $vars = [], bool $encodeAmp = true): string
1314
    {
1315
        $joinStr = '';
1316
1317
        $amp = ($encodeAmp ? '&amp;' : '&');
1318
1319
        if (!\count($vars)) {
1320
            return $page;
1321
        }
1322
1323
        $qs = '';
1324
        foreach ($vars as $key => $value) {
1325
            $qs      .= $joinStr . $key . '=' . $value;
1326
            $joinStr = $amp;
1327
        }
1328
1329
        return $page . '?' . $qs;
1330
    }
1331
1332
    /**
1333
     * @return EventService
1334
     */
1335
    //    public static function createNewEventService(): EventService
1336
    //    {
1337
    //        static $instance;
1338
    //
1339
    //        if (null === $instance) {
1340
    //            $instance = new EventService();
1341
    //        }
1342
    //
1343
    //        return $instance;
1344
    //    }
1345
1346
    /**
1347
     * @param string $path
1348
     * @param string $image
1349
     * @param string $alt
1350
     * @return string
1351
     */
1352
    public static function iconSourceTag(string $path, string $image, string $alt): string
1353
    {
1354
        $imgSource = "<img src='" . $path . "$image'  alt='" . $alt . "' title='" . $alt . "' align='middle'>";
1355
1356
        return $imgSource;
1357
    }
1358
}
1359