Issues (267)

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 (2 issues)

1
<?php
2
3
namespace XoopsModules\Xoopstube;
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
use WideImage\WideImage;
16
use Xmf\Request;
17
use XoopsModules\Xoopstube\{
18
    Common,
19
    Helper
20
};
21
22
/**
23
 * xoopstube
24
 *
25
 * @copyright   XOOPS Project (https://xoops.org)
26
 * @license     https://www.fsf.org/copyleft/gpl.html GNU public license
27
 * @author      Hervé Thouzard (http://www.herve-thouzard.com/)
28
 */
29
30
/**
31
 * A set of useful and common functions
32
 *
33
 * @package       xoopstube
34
 * @author        Hervé Thouzard - Instant Zero (http://xoops.instant-zero.com)
35
 * @copyright (c) Instant Zero
36
 *
37
 * Note: You should be able to use it without the need to instantiate it.
38
 */
39
40
//require_once  dirname(__DIR__) . '/include/common.php';
41
42
/**
43
 * Class Utility
44
 */
45
class Utility extends Common\SysUtility
46
{
47
    //--------------- Custom module methods -----------------------------
48
49
    public const MODULE_NAME = 'xoopstube';
50
51
    /**
52
     * Access the only instance of this class
53
     *
54
     * @return \XoopsModules\Xoopstube\Utility
55
     *
56
     * @static
57
     * @staticvar   object
58
     */
59
    public static function getInstance()
60
    {
61
        static $instance;
62
        if (null === $instance) {
63
            $instance = new static();
64
        }
65
66
        return $instance;
67
    }
68
69
    /**
70
     * Returns a module's option (with cache)
71
     *
72
     * @param string $option    module option's name
73
     * @param bool   $withCache Do we have to use some cache ?
74
     *
75
     * @return mixed option's value
76
     */
77
    public static function getModuleOption($option, $withCache = true)
78
    {
79
        global $xoopsModuleConfig, $xoopsModule;
80
        $repmodule = self::MODULE_NAME;
81
        static $options = [];
82
        if (\is_array($options) && \array_key_exists($option, $options) && $withCache) {
83
            return $options[$option];
84
        }
85
86
        $retval = false;
87
        if (isset($xoopsModuleConfig) && (\is_object($xoopsModule) && $xoopsModule->getVar('dirname') == $repmodule && $xoopsModule->getVar('isactive'))) {
88
            if (isset($xoopsModuleConfig[$option])) {
89
                $retval = $xoopsModuleConfig[$option];
90
            }
91
        } else {
92
            /** @var \XoopsModuleHandler $moduleHandler */
93
            $moduleHandler = \xoops_getHandler('module');
94
            $module        = $moduleHandler->getByDirname($repmodule);
95
            /** @var \XoopsConfigHandler $configHandler */
96
            $configHandler = \xoops_getHandler('config');
97
            if ($module) {
98
                $moduleConfig = $configHandler->getConfigsByCat(0, $module->getVar('mid'));
99
                if (isset($moduleConfig[$option])) {
100
                    $retval = $moduleConfig[$option];
101
                }
102
            }
103
        }
104
        $options[$option] = $retval;
105
106
        return $retval;
107
    }
108
109
    /**
110
     * Is Xoops 2.3.x ?
111
     *
112
     * @return bool
113
     */
114
    public static function isX23()
115
    {
116
        $x23 = false;
117
        $xv  = \str_replace('XOOPS ', '', \XOOPS_VERSION);
118
        if ((int)mb_substr($xv, 2, 1) >= 3) {
119
            $x23 = true;
120
        }
121
122
        return $x23;
123
    }
124
125
    /**
126
     * Is Xoops 2.0.x ?
127
     *
128
     * @return bool
129
     */
130
    public static function isX20()
131
    {
132
        $x20 = false;
133
        $xv  = \str_replace('XOOPS ', '', \XOOPS_VERSION);
134
        if ('0' == mb_substr($xv, 2, 1)) {
135
            $x20 = true;
136
        }
137
138
        return $x20;
139
    }
140
141
    /**
142
     * Create (in a link) a javascript confirmation's box
143
     *
144
     * @param string $message Message to display
145
     * @param bool   $form    Is this a confirmation for a form ?
146
     *
147
     * @return string the javascript code to insert in the link (or in the form)
148
     */
149
    public static function javascriptLinkConfirm($message, $form = false)
150
    {
151
        if (!$form) {
152
            return "onclick=\"javascript:return confirm('" . \str_replace("'", ' ', $message) . "')\"";
153
        }
154
155
        return "onSubmit=\"javascript:return confirm('" . \str_replace("'", ' ', $message) . "')\"";
156
    }
157
158
    /**
159
     * Get current user IP
160
     *
161
     * @return string IP address (format Ipv4)
162
     */
163
    public static function IP()
164
    {
165
        $proxy_ip = '';
166
        if (Request::hasVar('HTTP_X_FORWARDED_FOR', 'SERVER')) {
167
            $proxy_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
168
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED'])) {
169
            $proxy_ip = $_SERVER['HTTP_X_FORWARDED'];
170
        } elseif (!empty($_SERVER['HTTP_FORWARDED_FOR'])) {
171
            $proxy_ip = $_SERVER['HTTP_FORWARDED_FOR'];
172
        } elseif (!empty($_SERVER['HTTP_FORWARDED'])) {
173
            $proxy_ip = $_SERVER['HTTP_FORWARDED'];
174
        } elseif (!empty($_SERVER['HTTP_VIA'])) {
175
            $proxy_ip = $_SERVER['HTTP_VIA'];
176
        } elseif (!empty($_SERVER['HTTP_X_COMING_FROM'])) {
177
            $proxy_ip = $_SERVER['HTTP_X_COMING_FROM'];
178
        } elseif (!empty($_SERVER['HTTP_COMING_FROM'])) {
179
            $proxy_ip = $_SERVER['HTTP_COMING_FROM'];
180
        }
181
        $regs = [];
182
        //if (!empty($proxy_ip) && $is_ip = ereg('^(\d{1,3}\.){3,3}\d{1,3}', $proxy_ip, $regs) && count($regs) > 0) {
183
        if (!empty($proxy_ip) && \filter_var($proxy_ip, \FILTER_VALIDATE_IP) && \count($regs) > 0) {
184
            $the_IP = $regs[0];
185
        } else {
186
            $the_IP = $_SERVER['REMOTE_ADDR'];
187
        }
188
189
        return $the_IP;
190
    }
191
192
    /**
193
     * Set the page's title, meta description and meta keywords
194
     * Datas are supposed to be sanitized
195
     *
196
     * @param string $pageTitle       Page's Title
197
     * @param string $metaDescription Page's meta description
198
     * @param string $metaKeywords    Page's meta keywords
199
     */
200
    public static function setMetas($pageTitle = '', $metaDescription = '', $metaKeywords = '')
201
    {
202
        global $xoTheme, $xoTheme, $xoopsTpl;
203
        $xoopsTpl->assign('xoops_pagetitle', $pageTitle);
204
        if (isset($xoTheme) && \is_object($xoTheme)) {
205
            if (!empty($metaKeywords)) {
206
                $xoTheme->addMeta('meta', 'keywords', $metaKeywords);
207
            }
208
            if (!empty($metaDescription)) {
209
                $xoTheme->addMeta('meta', 'description', $metaDescription);
210
            }
211
        } elseif (isset($xoopsTpl) && \is_object($xoopsTpl)) { // Compatibility for old Xoops versions
212
            if (!empty($metaKeywords)) {
213
                $xoopsTpl->assign('xoops_meta_keywords', $metaKeywords);
214
            }
215
            if (!empty($metaDescription)) {
216
                $xoopsTpl->assign('xoops_meta_description', $metaDescription);
217
            }
218
        }
219
    }
220
221
    /**
222
     * Send an email from a template to a list of recipients
223
     *
224
     * @param        $tplName
225
     * @param array  $recipients List of recipients
226
     * @param string $subject    Email's subject
227
     * @param array  $variables  Varirables to give to the template
228
     *
229
     * @return bool Result of the send
230
     * @internal param string $tpl_name Template's name
231
     */
232
    public static function sendEmailFromTpl($tplName, $recipients, $subject, $variables)
233
    {
234
        global $xoopsConfig;
235
        require_once XOOPS_ROOT_PATH . '/class/xoopsmailer.php';
236
        if (!\is_array($recipients)) {
237
            if ('' === \trim($recipients)) {
238
                return false;
239
            }
240
        } elseif (0 == \count($recipients)) {
241
            return false;
242
        }
243
        if (\function_exists('xoops_getMailer')) {
244
            $xoopsMailer = \xoops_getMailer();
245
        } else {
246
            $xoopsMailer = \getMailer();
247
        }
248
249
        $xoopsMailer->useMail();
250
        $templateDir = XOOPS_ROOT_PATH . '/modules/' . self::MODULE_NAME . '/language/' . $xoopsConfig['language'] . '/mail_template';
251
        if (!\is_dir($templateDir)) {
252
            $templateDir = XOOPS_ROOT_PATH . '/modules/' . self::MODULE_NAME . '/language/english/mail_template';
253
        }
254
        $xoopsMailer->setTemplateDir($templateDir);
255
        $xoopsMailer->setTemplate($tplName);
256
        $xoopsMailer->setToEmails($recipients);
257
        // TODO: Change !
258
        // $xoopsMailer->setFromEmail('[email protected]');
259
        //$xoopsMailer->setFromName('MonSite');
260
        $xoopsMailer->setSubject($subject);
261
        foreach ($variables as $key => $value) {
262
            $xoopsMailer->assign($key, $value);
263
        }
264
        $res = $xoopsMailer->send();
265
        unset($xoopsMailer);
266
        $filename = XOOPS_UPLOAD_PATH . '/logmail_' . self::MODULE_NAME . '.php';
267
        if (!\is_file($filename)) {
268
            $fp = @\fopen($filename, 'ab');
269
            if ($fp) {
270
                \fwrite($fp, "<?php exit(); ?>\n");
271
                \fclose($fp);
272
            }
273
        }
274
        $fp = @\fopen($filename, 'ab');
275
276
        if ($fp) {
277
            \fwrite($fp, \str_repeat('-', 120) . "\n");
278
            \fwrite($fp, \date('d/m/Y H:i:s') . "\n");
279
            \fwrite($fp, 'Template name : ' . $tplName . "\n");
280
            \fwrite($fp, 'Email subject : ' . $subject . "\n");
281
            if (\is_array($recipients)) {
282
                \fwrite($fp, 'Recipient(s) : ' . \implode(',', $recipients) . "\n");
283
            } else {
284
                \fwrite($fp, 'Recipient(s) : ' . $recipients . "\n");
285
            }
286
            \fwrite($fp, 'Transmited variables : ' . \implode(',', $variables) . "\n");
287
            \fclose($fp);
288
        }
289
290
        return $res;
291
    }
292
293
    /**
294
     * Remove module's cache
295
     */
296
    public static function updateCache()
297
    {
298
        global $xoopsModule;
299
        $folder  = $xoopsModule->getVar('dirname');
300
        $tpllist = [];
301
        require_once XOOPS_ROOT_PATH . '/class/xoopsblock.php';
302
        require_once XOOPS_ROOT_PATH . '/class/template.php';
303
        $tplfileHandler = \xoops_getHandler('tplfile');
304
        $tpllist        = $tplfileHandler->find(null, null, null, $folder);
305
        \xoops_template_clear_module_cache($xoopsModule->getVar('mid')); // Clear module's blocks cache
306
307
        foreach ($tpllist as $onetemplate) { // Remove cache for each page.
308
            if ('module' === $onetemplate->getVar('tpl_type')) {
309
                //  Note, I've been testing all the other methods (like the one of Smarty) and none of them run, that's why I have used this code
310
                $files_del = [];
311
                $files_del = \glob(XOOPS_CACHE_PATH . '/*' . $onetemplate->getVar('tpl_file') . '*', \GLOB_NOSORT);
312
                if (\count($files_del) > 0 && \is_array($files_del)) {
313
                    foreach ($files_del as $one_file) {
314
                        if (\is_file($one_file)) {
315
                            \unlink($one_file);
316
                        }
317
                    }
318
                }
319
            }
320
        }
321
    }
322
323
    /**
324
     * Redirect user with a message
325
     *
326
     * @param string $message message to display
327
     * @param string $url     The place where to go
328
     * @param mixed  $time
329
     */
330
    public static function redirect($message = '', $url = 'index.php', $time = 2)
331
    {
332
        \redirect_header($url, $time, $message);
333
    }
334
335
    /**
336
     * Returns the module's name (as defined by the user in the module manager) with cache
337
     *
338
     * @return string Module's name
339
     */
340
    public static function getModuleName()
341
    {
342
        static $moduleName;
343
        if (!isset($moduleName)) {
344
            $mymodule   = self::_getModule();
345
            $moduleName = $mymodule->getVar('name');
346
        }
347
348
        return $moduleName;
349
    }
350
351
    /**
352
     * Create a title for the href tags inside html links
353
     *
354
     * @param string $title Text to use
355
     *
356
     * @return string Formated text
357
     */
358
    public static function makeHrefTitle($title)
359
    {
360
        $s = "\"'";
361
        $r = '  ';
362
363
        return strtr($title, $s, $r);
364
    }
365
366
    /**
367
     * Retourne la liste des utilisateurs appartenants à un groupe
368
     *
369
     * @param int $groupId Searched group
370
     *
371
     * @return array Array of XoopsUsers
372
     */
373
    public static function getUsersFromGroup($groupId)
374
    {
375
        $users         = [];
376
        $memberHandler = \xoops_getHandler('member');
377
        $users         = $memberHandler->getUsersByGroup($groupId, true);
378
379
        return $users;
380
    }
381
382
    /**
383
     * Retourne la liste des emails des utilisateurs membres d'un groupe
384
     *
385
     * @param $groupId
386
     *
387
     * @return array Emails list
388
     * @internal param int $group_id Group's number
389
     */
390
    public static function getEmailsFromGroup($groupId)
391
    {
392
        $ret   = [];
393
        $users = self::getUsersFromGroup($groupId);
394
        foreach ($users as $user) {
395
            $ret[] = $user->getVar('email');
396
        }
397
398
        return $ret;
399
    }
400
401
    /**
402
     * Vérifie que l'utilisateur courant fait partie du groupe des administrateurs
403
     *
404
     * @return bool Admin or not
405
     */
406
    public static function isAdmin()
407
    {
408
        global $xoopsUser, $xoopsModule;
409
        if (\is_object($xoopsUser)) {
410
            if (\in_array(XOOPS_GROUP_ADMIN, $xoopsUser->getGroups())) {
411
                return true;
412
            }
413
414
            if (isset($xoopsModule) && $xoopsUser->isAdmin($xoopsModule->getVar('mid'))) {
415
                return true;
416
            }
417
        }
418
419
        return false;
420
    }
421
422
    /**
423
     * Returns the current date in the Mysql format
424
     *
425
     * @return string Date in the Mysql format
426
     */
427
    public static function getCurrentSQLDate()
428
    {
429
        return \date('Y-m-d'); // 2007-05-02
430
    }
431
432
    /**
433
     * @return bool|string
434
     */
435
    public static function getCurrentSQLDateTime()
436
    {
437
        return \date('Y-m-d H:i:s'); // 2007-05-02
438
    }
439
440
    /**
441
     * Convert a Mysql date to the human's format
442
     *
443
     * @param string $date The date to convert
444
     * @param string $format
445
     *
446
     * @return string The date in a human form
447
     */
448
    public static function SQLDateToHuman($date, $format = 'l')
449
    {
450
        if ('0000-00-00' != $date && '' != \xoops_trim($date)) {
451
            return \formatTimestamp(\strtotime($date), $format);
452
        }
453
454
        return '';
455
    }
456
457
    /**
458
     * Convert a timestamp to a Mysql date
459
     *
460
     * @param int $timestamp The timestamp to use
461
     *
462
     * @return string The date in the Mysql format
463
     */
464
    public static function timestampToMysqlDate($timestamp)
465
    {
466
        return \date('Y-m-d', (int)$timestamp);
467
    }
468
469
    /**
470
     * Conversion d'un dateTime Mysql en date lisible en français
471
     *
472
     * @param $dateTime
473
     *
474
     * @return bool|string
475
     */
476
    public static function sqlDateTimeToFrench($dateTime)
477
    {
478
        return \date('d/m/Y H:i:s', \strtotime($dateTime));
479
    }
480
481
    /**
482
     * Convert a timestamp to a Mysql datetime form
483
     *
484
     * @param int $timestamp The timestamp to use
485
     *
486
     * @return string The date and time in the Mysql format
487
     */
488
    public static function timestampToMysqlDateTime($timestamp)
489
    {
490
        return \date('Y-m-d H:i:s', $timestamp);
491
    }
492
493
    /**
494
     * This function indicates if the current Xoops version needs to add asterisks to required fields in forms
495
     *
496
     * @return bool Yes = we need to add them, false = no
497
     */
498
    public static function needsAsterisk()
499
    {
500
        if (self::isX23()) {
501
            return false;
502
        }
503
        if (false !== mb_stripos(\XOOPS_VERSION, 'impresscms')) {
504
            return false;
505
        }
506
        if (false === mb_stripos(\XOOPS_VERSION, 'legacy')) {
507
            $xv = \xoops_trim(\str_replace('XOOPS ', '', \XOOPS_VERSION));
508
            if ((int)mb_substr($xv, 4, 2) >= 17) {
509
                return false;
510
            }
511
        }
512
513
        return true;
514
    }
515
516
    /**
517
     * Mark the mandatory fields of a form with a star
518
     *
519
     * @param \XoopsForm $sform The form to modify
520
     *
521
     * @return \XoopsForm The modified form
522
     * @internal param string $caracter The character to use to mark fields
523
     */
524
    public static function &formMarkRequiredFields(\XoopsForm $sform)
525
    {
526
        if (self::needsAsterisk()) {
527
            $required = [];
528
            $elements = [];
529
            foreach ($sform->getRequired() as $item) {
530
                $required[] = $item->_name;
531
            }
532
            $elements = $sform->getElements();
533
            foreach ($elements as $iValue) {
534
                if (\is_object($iValue) && \in_array($iValue->_name, $required)) {
535
                    $iValue->_caption .= ' *';
536
                }
537
            }
538
        }
539
540
        return $sform;
541
    }
542
543
    /**
544
     * Create a html heading (from h1 to h6)
545
     *
546
     * @param string $title The text to use
547
     * @param int    $level Level to return
548
     *
549
     * @return void The heading
550
     */
551
    public static function htitle($title = '', $level = 1)
552
    {
553
        \printf('<h%01d>%s</h%01d>', $level, $title, $level);
554
    }
555
556
    /**
557
     * Create a unique upload filename
558
     *
559
     * @param string $folder   The folder where the file will be saved
560
     * @param string $fileName Original filename (coming from the user)
561
     * @param bool   $trimName Do we need to create a "short" unique name ?
562
     *
563
     * @return string The unique filename to use (with its extension)
564
     */
565
    public static function createUploadName($folder, $fileName, $trimName = false)
566
    {
567
        $workingfolder = $folder;
568
        if ('/' !== \xoops_substr($workingfolder, mb_strlen($workingfolder) - 1, 1)) {
569
            $workingfolder .= '/';
570
        }
571
        $ext  = \basename($fileName);
572
        $ext  = \explode('.', $ext);
573
        $ext  = '.' . $ext[\count($ext) - 1];
574
        $true = true;
575
        while ($true) {
576
            $ipbits = \explode('.', $_SERVER['REMOTE_ADDR']);
577
            [$usec, $sec] = \explode(' ', \microtime());
578
            $usec *= 65536;
579
            $sec  = ((int)$sec) & 0xFFFF;
580
581
            if ($trimName) {
582
                $uid = \sprintf('%06x%04x%04x', ($ipbits[0] << 24) | ($ipbits[1] << 16) | ($ipbits[2] << 8) | $ipbits[3], $sec, $usec);
583
            } else {
584
                $uid = \sprintf('%08x-%04x-%04x', ($ipbits[0] << 24) | ($ipbits[1] << 16) | ($ipbits[2] << 8) | $ipbits[3], $sec, $usec);
585
            }
586
            if (!\file_exists($workingfolder . $uid . $ext)) {
587
                $true = false;
588
            }
589
        }
590
591
        return $uid . $ext;
592
    }
593
594
    /**
595
     * Replace html entities with their ASCII equivalent
596
     *
597
     * @param string $chaine The string undecode
598
     *
599
     * @return string The undecoded string
600
     */
601
    public static function unhtml($chaine)
602
    {
603
        $search = $replace = [];
604
        $chaine = \html_entity_decode($chaine);
605
606
        for ($i = 0; $i <= 255; ++$i) {
607
            $search[]  = '&#' . $i . ';';
608
            $replace[] = \chr($i);
609
        }
610
        $replace[] = '...';
611
        $search[]  = '…';
612
        $replace[] = "'";
613
        $search[]  = '‘';
614
        $replace[] = "'";
615
        $search[]  = '’';
616
        $replace[] = '-';
617
        $search[]  = '&bull;'; // $replace[] = '•';
618
        $replace[] = '—';
619
        $search[]  = '&mdash;';
620
        $replace[] = '-';
621
        $search[]  = '&ndash;';
622
        $replace[] = '-';
623
        $search[]  = '&shy;';
624
        $replace[] = '"';
625
        $search[]  = '&quot;';
626
        $replace[] = '&';
627
        $search[]  = '&amp;';
628
        $replace[] = 'ˆ';
629
        $search[]  = '&circ;';
630
        $replace[] = '¡';
631
        $search[]  = '&iexcl;';
632
        $replace[] = '¦';
633
        $search[]  = '&brvbar;';
634
        $replace[] = '¨';
635
        $search[]  = '&uml;';
636
        $replace[] = '¯';
637
        $search[]  = '&macr;';
638
        $replace[] = '´';
639
        $search[]  = '&acute;';
640
        $replace[] = '¸';
641
        $search[]  = '&cedil;';
642
        $replace[] = '¿';
643
        $search[]  = '&iquest;';
644
        $replace[] = '˜';
645
        $search[]  = '&tilde;';
646
        $replace[] = "'";
647
        $search[]  = '&lsquo;'; // $replace[]='‘';
648
        $replace[] = "'";
649
        $search[]  = '&rsquo;'; // $replace[]='’';
650
        $replace[] = '‚';
651
        $search[]  = '&sbquo;';
652
        $replace[] = "'";
653
        $search[]  = '&ldquo;'; // $replace[]='“';
654
        $replace[] = "'";
655
        $search[]  = '&rdquo;'; // $replace[]='”';
656
        $replace[] = '„';
657
        $search[]  = '&bdquo;';
658
        $replace[] = '‹';
659
        $search[]  = '&lsaquo;';
660
        $replace[] = '›';
661
        $search[]  = '&rsaquo;';
662
        $replace[] = '<';
663
        $search[]  = '&lt;';
664
        $replace[] = '>';
665
        $search[]  = '&gt;';
666
        $replace[] = '±';
667
        $search[]  = '&plusmn;';
668
        $replace[] = '«';
669
        $search[]  = '&laquo;';
670
        $replace[] = '»';
671
        $search[]  = '&raquo;';
672
        $replace[] = '×';
673
        $search[]  = '&times;';
674
        $replace[] = '÷';
675
        $search[]  = '&divide;';
676
        $replace[] = '¢';
677
        $search[]  = '&cent;';
678
        $replace[] = '£';
679
        $search[]  = '&pound;';
680
        $replace[] = '¤';
681
        $search[]  = '&curren;';
682
        $replace[] = '¥';
683
        $search[]  = '&yen;';
684
        $replace[] = '§';
685
        $search[]  = '&sect;';
686
        $replace[] = '©';
687
        $search[]  = '&copy;';
688
        $replace[] = '¬';
689
        $search[]  = '&not;';
690
        $replace[] = '®';
691
        $search[]  = '&reg;';
692
        $replace[] = '°';
693
        $search[]  = '&deg;';
694
        $replace[] = 'µ';
695
        $search[]  = '&micro;';
696
        $replace[] = '¶';
697
        $search[]  = '&para;';
698
        $replace[] = '·';
699
        $search[]  = '&middot;';
700
        $replace[] = '†';
701
        $search[]  = '&dagger;';
702
        $replace[] = '‡';
703
        $search[]  = '&Dagger;';
704
        $replace[] = '‰';
705
        $search[]  = '&permil;';
706
        $replace[] = 'Euro';
707
        $search[]  = '&euro;'; // $replace[]='€'
708
        $replace[] = '¼';
709
        $search[]  = '&frac14;';
710
        $replace[] = '½';
711
        $search[]  = '&frac12;';
712
        $replace[] = '¾';
713
        $search[]  = '&frac34;';
714
        $replace[] = '¹';
715
        $search[]  = '&sup1;';
716
        $replace[] = '²';
717
        $search[]  = '&sup2;';
718
        $replace[] = '³';
719
        $search[]  = '&sup3;';
720
        $replace[] = 'á';
721
        $search[]  = '&aacute;';
722
        $replace[] = 'Á';
723
        $search[]  = '&Aacute;';
724
        $replace[] = 'â';
725
        $search[]  = '&acirc;';
726
        $replace[] = 'Â';
727
        $search[]  = '&Acirc;';
728
        $replace[] = 'à';
729
        $search[]  = '&agrave;';
730
        $replace[] = 'À';
731
        $search[]  = '&Agrave;';
732
        $replace[] = 'å';
733
        $search[]  = '&aring;';
734
        $replace[] = 'Å';
735
        $search[]  = '&Aring;';
736
        $replace[] = 'ã';
737
        $search[]  = '&atilde;';
738
        $replace[] = 'Ã';
739
        $search[]  = '&Atilde;';
740
        $replace[] = 'ä';
741
        $search[]  = '&auml;';
742
        $replace[] = 'Ä';
743
        $search[]  = '&Auml;';
744
        $replace[] = 'ª';
745
        $search[]  = '&ordf;';
746
        $replace[] = 'æ';
747
        $search[]  = '&aelig;';
748
        $replace[] = 'Æ';
749
        $search[]  = '&AElig;';
750
        $replace[] = 'ç';
751
        $search[]  = '&ccedil;';
752
        $replace[] = 'Ç';
753
        $search[]  = '&Ccedil;';
754
        $replace[] = 'ð';
755
        $search[]  = '&eth;';
756
        $replace[] = 'Ð';
757
        $search[]  = '&ETH;';
758
        $replace[] = 'é';
759
        $search[]  = '&eacute;';
760
        $replace[] = 'É';
761
        $search[]  = '&Eacute;';
762
        $replace[] = 'ê';
763
        $search[]  = '&ecirc;';
764
        $replace[] = 'Ê';
765
        $search[]  = '&Ecirc;';
766
        $replace[] = 'è';
767
        $search[]  = '&egrave;';
768
        $replace[] = 'È';
769
        $search[]  = '&Egrave;';
770
        $replace[] = 'ë';
771
        $search[]  = '&euml;';
772
        $replace[] = 'Ë';
773
        $search[]  = '&Euml;';
774
        $replace[] = 'ƒ';
775
        $search[]  = '&fnof;';
776
        $replace[] = 'í';
777
        $search[]  = '&iacute;';
778
        $replace[] = 'Í';
779
        $search[]  = '&Iacute;';
780
        $replace[] = 'î';
781
        $search[]  = '&icirc;';
782
        $replace[] = 'Î';
783
        $search[]  = '&Icirc;';
784
        $replace[] = 'ì';
785
        $search[]  = '&igrave;';
786
        $replace[] = 'Ì';
787
        $search[]  = '&Igrave;';
788
        $replace[] = 'ï';
789
        $search[]  = '&iuml;';
790
        $replace[] = 'Ï';
791
        $search[]  = '&Iuml;';
792
        $replace[] = 'ñ';
793
        $search[]  = '&ntilde;';
794
        $replace[] = 'Ñ';
795
        $search[]  = '&Ntilde;';
796
        $replace[] = 'ó';
797
        $search[]  = '&oacute;';
798
        $replace[] = 'Ó';
799
        $search[]  = '&Oacute;';
800
        $replace[] = 'ô';
801
        $search[]  = '&ocirc;';
802
        $replace[] = 'Ô';
803
        $search[]  = '&Ocirc;';
804
        $replace[] = 'ò';
805
        $search[]  = '&ograve;';
806
        $replace[] = 'Ò';
807
        $search[]  = '&Ograve;';
808
        $replace[] = 'º';
809
        $search[]  = '&ordm;';
810
        $replace[] = 'ø';
811
        $search[]  = '&oslash;';
812
        $replace[] = 'Ø';
813
        $search[]  = '&Oslash;';
814
        $replace[] = 'õ';
815
        $search[]  = '&otilde;';
816
        $replace[] = 'Õ';
817
        $search[]  = '&Otilde;';
818
        $replace[] = 'ö';
819
        $search[]  = '&ouml;';
820
        $replace[] = 'Ö';
821
        $search[]  = '&Ouml;';
822
        $replace[] = 'œ';
823
        $search[]  = '&oelig;';
824
        $replace[] = 'Œ';
825
        $search[]  = '&OElig;';
826
        $replace[] = 'š';
827
        $search[]  = '&scaron;';
828
        $replace[] = 'Š';
829
        $search[]  = '&Scaron;';
830
        $replace[] = 'ß';
831
        $search[]  = '&szlig;';
832
        $replace[] = 'þ';
833
        $search[]  = '&thorn;';
834
        $replace[] = 'Þ';
835
        $search[]  = '&THORN;';
836
        $replace[] = 'ú';
837
        $search[]  = '&uacute;';
838
        $replace[] = 'Ú';
839
        $search[]  = '&Uacute;';
840
        $replace[] = 'û';
841
        $search[]  = '&ucirc;';
842
        $replace[] = 'Û';
843
        $search[]  = '&Ucirc;';
844
        $replace[] = 'ù';
845
        $search[]  = '&ugrave;';
846
        $replace[] = 'Ù';
847
        $search[]  = '&Ugrave;';
848
        $replace[] = 'ü';
849
        $search[]  = '&uuml;';
850
        $replace[] = 'Ü';
851
        $search[]  = '&Uuml;';
852
        $replace[] = 'ý';
853
        $search[]  = '&yacute;';
854
        $replace[] = 'Ý';
855
        $search[]  = '&Yacute;';
856
        $replace[] = 'ÿ';
857
        $search[]  = '&yuml;';
858
        $replace[] = 'Ÿ';
859
        $search[]  = '&Yuml;';
860
        $chaine    = \str_replace($search, $replace, $chaine);
861
862
        return $chaine;
863
    }
864
865
    /**
866
     * Create a title to be used by the url rewriting
867
     *
868
     * @param string $content The text to use to create the url
869
     * @param int    $urw     The lower limit to create words
870
     *
871
     * @return string The text to use for the url
872
     *                Note, some parts are from Solo's code
873
     */
874
    public static function makeSeoUrl($content, $urw = 1)
875
    {
876
        $s       = "ÀÁÂÃÄÅÒÓÔÕÖØÈÉÊËÇÌÍÎÏÙÚÛܟÑàáâãäåòóôõöøèéêëçìíîïùúûüÿñ '()";
877
        $r       = 'AAAAAAOOOOOOEEEECIIIIUUUUYNaaaaaaooooooeeeeciiiiuuuuyn----';
878
        $content = self::unhtml($content); // First, remove html entities
879
        $content = strtr($content, $s, $r);
880
        $content = \strip_tags($content);
881
        $content = mb_strtolower($content);
882
        $content = \htmlentities($content, \ENT_QUOTES | \ENT_HTML5); // TODO: Vérifier
883
        $content = \preg_replace('/&([a-zA-Z])(uml|acute|grave|circ|tilde);/', '$1', $content);
884
        $content = \html_entity_decode($content);
885
        $content = \str_ireplace('quot', ' ', $content);
886
        $content = \preg_replace("/'/i", ' ', $content);
887
        $content = \str_ireplace('-', ' ', $content);
888
        $content = \preg_replace('/[[:punct:]]/i', '', $content);
889
890
        // Selon option mais attention au fichier .htaccess !
891
        // $content = eregi_replace('[[:digit:]]','', $content);
892
        $content = \preg_replace('/[^a-z|A-Z|0-9]/', '-', $content);
893
894
        $words    = \explode(' ', $content);
895
        $keywords = '';
896
        foreach ($words as $word) {
897
            if (mb_strlen($word) >= $urw) {
898
                $keywords .= '-' . \trim($word);
899
            }
900
        }
901
        if (!$keywords) {
902
            $keywords = '-';
903
        }
904
        // Supprime les tirets en double
905
        $keywords = \str_replace('---', '-', $keywords);
906
        $keywords = \str_replace('--', '-', $keywords);
907
        // Supprime un éventuel tiret à la fin de la chaine
908
        if ('-' === mb_substr($keywords, mb_strlen($keywords) - 1, 1)) {
909
            $keywords = mb_substr($keywords, 0, -1);
910
        }
911
912
        return $keywords;
913
    }
914
915
    /**
916
     * Create the meta keywords based on the content
917
     *
918
     * @param string $content Content from which we have to create metakeywords
919
     *
920
     * @return string The list of meta keywords
921
     */
922
    public static function createMetaKeywords($content)
923
    {
924
        $keywordscount = self::getModuleOption('metagen_maxwords');
925
        $keywordsorder = self::getModuleOption('metagen_order');
926
927
        $tmp = [];
928
        // Search for the "Minimum keyword length"
929
        if (Request::hasVar('xoopstube_keywords_limit', 'SESSION')) {
930
            $limit = $_SESSION['xoopstube_keywords_limit'];
931
        } else {
932
            /** @var \XoopsConfigHandler $configHandler */
933
            $configHandler                        = \xoops_getHandler('config');
934
            $xoopsConfigSearch                    = $configHandler->getConfigsByCat(\XOOPS_CONF_SEARCH);
935
            $limit                                = $xoopsConfigSearch['keyword_min'];
936
            $_SESSION['xoopstube_keywords_limit'] = $limit;
937
        }
938
        $myts            = \MyTextSanitizer::getInstance();
939
        $content         = \str_replace('<br>', ' ', $content);
940
        $content         = $myts->undoHtmlSpecialChars($content);
941
        $content         = \strip_tags($content);
942
        $content         = mb_strtolower($content);
943
        $search_pattern  = ['&nbsp;', "\t", "\r\n", "\r", "\n", ',', '.', "'", ';', ':', ')', '(', '"', '?', '!', '{', '}', '[', ']', '<', '>', '/', '+', '-', '_', '\\', '*'];
944
        $replace_pattern = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''];
945
        $content         = \str_replace($search_pattern, $replace_pattern, $content);
946
        $keywords        = \explode(' ', $content);
947
        switch ($keywordsorder) {
948
            case 0: // Ordre d'apparition dans le texte
949
                $keywords = \array_unique($keywords);
950
                break;
951
            case 1: // Ordre de fréquence des mots
952
                $keywords = \array_count_values($keywords);
953
                \asort($keywords);
954
                $keywords = \array_keys($keywords);
955
                break;
956
            case 2: // Ordre inverse de la fréquence des mots
957
                $keywords = \array_count_values($keywords);
958
                \arsort($keywords);
959
                $keywords = \array_keys($keywords);
960
                break;
961
        }
962
        // Remove black listed words
963
        if ('' !== \xoops_trim(self::getModuleOption('metagen_blacklist'))) {
964
            $metagen_blacklist = \str_replace("\r", '', self::getModuleOption('metagen_blacklist'));
965
            $metablack         = \explode("\n", $metagen_blacklist);
966
            \array_walk($metablack, '\trim');
967
            $keywords = \array_diff($keywords, $metablack);
968
        }
969
970
        foreach ($keywords as $keyword) {
971
            if (mb_strlen($keyword) >= $limit && !\is_numeric($keyword)) {
972
                $tmp[] = $keyword;
973
            }
974
        }
975
        $tmp = \array_slice($tmp, 0, $keywordscount);
976
        if (\count($tmp) > 0) {
977
            return \implode(',', $tmp);
978
        }
979
        if (!isset($configHandler) || !\is_object($configHandler)) {
980
            /** @var \XoopsConfigHandler $configHandler */
981
            $configHandler = \xoops_getHandler('config');
982
        }
983
        $xoopsConfigMetaFooter = $configHandler->getConfigsByCat(\XOOPS_CONF_METAFOOTER);
984
        return $xoopsConfigMetaFooter['meta_keywords'] ?? '';
985
    }
986
987
    /**
988
     * Fonction chargée de gérer l'upload
989
     *
990
     * @param int    $indice L'indice du fichier à télécharger
991
     * @param string $dstpath
992
     * @param null   $mimeTypes
993
     * @param null   $uploadMaxSize
994
     * @param null   $maxWidth
995
     * @param null   $maxHeight
996
     *
997
     * @return bool|string True si l'upload s'est bien déroulé sinon le message d'erreur correspondant
998
     */
999
    public static function uploadFile(
1000
        $indice,
1001
        $dstpath = XOOPS_UPLOAD_PATH,
1002
        $mimeTypes = null,
1003
        $uploadMaxSize = null,
1004
        $maxWidth = null,
1005
        $maxHeight = null
1006
    ) {
1007
        require_once XOOPS_ROOT_PATH . '/class/uploader.php';
1008
        global $destname;
1009
        if (Request::hasVar('xoops_upload_file', 'POST')) {
1010
            require_once XOOPS_ROOT_PATH . '/class/uploader.php';
1011
            $fldname = '';
1012
            $fldname = $_FILES[$_POST['xoops_upload_file'][$indice]];
1013
            $fldname = $fldname['name'];
1014
            if (\xoops_trim('' !== $fldname)) {
1015
                $destname = self::createUploadName($dstpath, $fldname, true);
1016
                if (null === $mimeTypes) {
1017
                    $permittedtypes = \explode("\n", \str_replace("\r", '', self::getModuleOption('mimetypes')));
1018
                    \array_walk($permittedtypes, '\trim');
1019
                } else {
1020
                    $permittedtypes = $mimeTypes;
1021
                }
1022
                $uploadSize = $uploadMaxSize ?? self::getModuleOption('maxuploadsize');
1023
                $uploader   = new MediaUploader($dstpath, $permittedtypes, $uploadSize, $maxWidth, $maxHeight);
1024
                //$uploader->allowUnknownTypes = true;
1025
                $uploader->setTargetFileName($destname);
1026
                if ($uploader->fetchMedia($_POST['xoops_upload_file'][$indice])) {
1027
                    if ($uploader->upload()) {
1028
                        return true;
1029
                    }
1030
1031
                    return _ERRORS . ' ' . \htmlentities($uploader->getErrors(), \ENT_QUOTES | \ENT_HTML5);
1032
                }
1033
1034
                return \htmlentities($uploader->getErrors(), \ENT_QUOTES | \ENT_HTML5);
1035
            }
1036
1037
            return false;
1038
        }
1039
1040
        return false;
1041
    }
1042
1043
    /**
1044
     * Resize a Picture to some given dimensions (using the wideImage library)
1045
     *
1046
     * @param string $src_path      Picture's source
1047
     * @param string $dst_path      Picture's destination
1048
     * @param int    $param_width   Maximum picture's width
1049
     * @param int    $param_height  Maximum picture's height
1050
     * @param bool   $keep_original Do we have to keep the original picture ?
1051
     * @param string $fit           Resize mode (see the wideImage library for more information)
1052
     *
1053
     * @return bool
1054
     */
1055
    public static function resizePicture(
1056
        $src_path,
1057
        $dst_path,
1058
        $param_width,
1059
        $param_height,
1060
        $keep_original = false,
1061
        $fit = 'inside'
1062
    ) {
1063
        $resize = true;
1064
        if (XOOPSTUBE_DONT_RESIZE_IF_SMALLER) {
1065
            $pictureDimensions = \getimagesize($src_path);
1066
            if (\is_array($pictureDimensions)) {
1067
                $width  = $pictureDimensions[0];
1068
                $height = $pictureDimensions[1];
1069
                if ($width < $param_width && $height < $param_height) {
1070
                    $resize = false;
1071
                }
1072
            }
1073
        }
1074
1075
        $img = WideImage::load($src_path);
1076
        if ($resize) {
1077
            $result = $img->resize($param_width, $param_height, $fit);
1078
            $result->saveToFile($dst_path);
1079
        } else {
1080
            @\copy($src_path, $dst_path);
1081
        }
1082
1083
        if (!$keep_original) {
1084
            @\unlink($src_path);
1085
        }
1086
1087
        return true;
1088
    }
1089
1090
    /**
1091
     * Add days to a date and return the new date in Mysql Date format
1092
     *
1093
     * @param int $duration
1094
     * @param int $startingDate Starting date (timestamp)
1095
     *
1096
     * @return bool|string
1097
     * @internal param int $ Duration in days
1098
     */
1099
    public static function addDaysToDate($duration = 1, $startingDate = 0)
1100
    {
1101
        if (0 == $startingDate) {
1102
            $startingDate = \time();
1103
        }
1104
        $endingDate = $startingDate + ($duration * 86400);
1105
1106
        return \date('Y-m-d', $endingDate);
1107
    }
1108
1109
    /**
1110
     * Returns a breadcrumb according to the parameters passed and starting (automatically) from the root of the module
1111
     *
1112
     * @param array  $path  The full path (except the root) of the breadcrumb in the form of key = url value = title
1113
     * @param string $raquo The default separator to use
1114
     *
1115
     * @return string le breadcrumb
1116
     */
1117
    public static function breadcrumb($path, $raquo = ' &raquo; ')
1118
    {
1119
        $breadcrumb        = '';
1120
        $workingBreadcrumb = [];
1121
        if (\is_array($path)) {
1122
            $moduleName          = self::getModuleName();
1123
            $workingBreadcrumb[] = "<a href='" . XOOPSTUBE_URL . "' title='" . self::makeHrefTitle($moduleName) . "'>" . $moduleName . '</a>';
1124
            foreach ($path as $url => $title) {
1125
                $workingBreadcrumb[] = "<a href='" . $url . "'>" . $title . '</a>';
1126
            }
1127
            $cnt = \count($workingBreadcrumb);
1128
            foreach ($workingBreadcrumb as $i => $iValue) {
1129
                if ($i == $cnt - 1) {
1130
                    $workingBreadcrumb[$i] = \strip_tags($iValue);
1131
                }
1132
            }
1133
            $breadcrumb = \implode($raquo, $workingBreadcrumb);
1134
        }
1135
1136
        return $breadcrumb;
1137
    }
1138
1139
    /**
1140
     * @param $string
1141
     *
1142
     * @return string
1143
     */
1144
    public static function close_tags($string)
1145
    {
1146
        // match opened tags
1147
        if (\preg_match_all('/<([a-z\:\-]+)[^\/]>/', $string, $start_tags)) {
1148
            $start_tags = $start_tags[1];
1149
1150
            // match closed tags
1151
            if (\preg_match_all('/<\/([a-z]+)>/', $string, $end_tags)) {
1152
                $complete_tags = [];
1153
                $end_tags      = $end_tags[1];
1154
1155
                foreach ($start_tags as $key => $val) {
1156
                    $posb = \array_search($val, $end_tags, true);
1157
                    if (\is_int($posb)) {
1158
                        unset($end_tags[$posb]);
1159
                    } else {
1160
                        $complete_tags[] = $val;
1161
                    }
1162
                }
1163
            } else {
1164
                $complete_tags = $start_tags;
1165
            }
1166
1167
            $complete_tags = \array_reverse($complete_tags);
1168
            foreach ($complete_tags as $iValue) {
1169
                $string .= '</' . $iValue . '>';
1170
            }
1171
        }
1172
1173
        return $string;
1174
    }
1175
1176
    /**
1177
     * @param        $string
1178
     * @param int    $length
1179
     * @param string $etc
1180
     * @param bool   $break_words
1181
     *
1182
     * @return string
1183
     */
1184
    public static function truncate_tagsafe($string, $length = 80, $etc = '...', $break_words = false)
1185
    {
1186
        if (0 == $length) {
1187
            return '';
1188
        }
1189
1190
        if (mb_strlen($string) > $length) {
1191
            $length -= mb_strlen($etc);
1192
            if (!$break_words) {
1193
                $string = \preg_replace('/\s+?(\S+)?$/', '', mb_substr($string, 0, $length + 1));
1194
                $string = \preg_replace('/<[^>]*$/', '', $string);
1195
                $string = self::close_tags($string);
1196
            }
1197
1198
            return $string . $etc;
1199
        }
1200
1201
        return $string;
1202
    }
1203
1204
    /**
1205
     * Create an infotip
1206
     * @param $text
1207
     * @return string
1208
     */
1209
    public static function makeInfotips($text)
1210
    {
1211
        $ret      = '';
1212
        $infotips = self::getModuleOption('infotips');
1213
        if ($infotips > 0) {
1214
            $myts = \MyTextSanitizer::getInstance();
1215
            $ret  = \htmlspecialchars(\xoops_substr(\strip_tags($text), 0, $infotips), \ENT_QUOTES | \ENT_HTML5);
1216
        }
1217
1218
        return $ret;
1219
    }
1220
1221
    /**
1222
     * @param $datastream
1223
     * @param $url
1224
     *
1225
     * @return string
1226
     */
1227
    public static function postIt($datastream, $url)
1228
    {
1229
        $url     = \preg_replace('@^http://@i', '', $url);
1230
        $host    = mb_substr($url, 0, mb_strpos($url, '/'));
1231
        $uri     = mb_strstr($url, '/');
1232
        $reqbody = '';
1233
        foreach ($datastream as $key => $val) {
1234
            if (!empty($reqbody)) {
1235
                $reqbody .= '&';
1236
            }
1237
            $reqbody .= $key . '=' . \urlencode($val);
1238
        }
1239
        $contentlength = mb_strlen($reqbody);
1240
        $reqheader     = "POST $uri HTTP/1.1\r\n" . "Host: $host\n" . "Content-Type: application/x-www-form-urlencoded\r\n" . "Content-Length: $contentlength\r\n\r\n" . "$reqbody\r\n";
1241
1242
        return $reqheader;
1243
    }
1244
1245
    /**
1246
     * Returns the mime type of a file using first finfo then mime_content
1247
     *
1248
     * @param $filename
1249
     * @return string
1250
     */
1251
    public static function getMimeType($filename)
1252
    {
1253
        if (\function_exists('finfo_open')) {
1254
            $finfo    = \finfo_open();
1255
            $mimetype = \finfo_file($finfo, $filename, \FILEINFO_MIME_TYPE);
1256
            \finfo_close($finfo);
1257
1258
            return $mimetype;
1259
        }
1260
        if (\function_exists('mime_content_type')) {
1261
            return \mime_content_type($filename);
1262
        }
1263
1264
        return '';
1265
    }
1266
1267
    /**
1268
     * Retourne un criteria compo qui permet de filtrer les produits sur le mois courant
1269
     *
1270
     * @return \CriteriaCompo
1271
     */
1272
    public static function getThisMonthCriteria()
1273
    {
1274
        $start             = \mktime(0, 1, 0, \date('n'), \date('j'), \date('Y'));
1275
        $end               = \mktime(0, 0, 0, \date('n'), \date('t'), \date('Y'));
1276
        $criteriaThisMonth = new \CriteriaCompo();
1277
        $criteriaThisMonth->add(new \Criteria('product_submitted', $start, '>='));
1278
        $criteriaThisMonth->add(new \Criteria('product_submitted', $end, '<='));
1279
1280
        return $criteriaThisMonth;
1281
    }
1282
1283
    /**
1284
     * Retourne une liste d'objets XoopsUsers à partir d'une liste d'identifiants
1285
     *
1286
     * @param array $xoopsUsersIDs La liste des ID
1287
     *
1288
     * @return array Les objets XoopsUsers
1289
     */
1290
    public static function getUsersFromIds($xoopsUsersIDs)
1291
    {
1292
        $users = [];
1293
        if ($xoopsUsersIDs && \is_array($xoopsUsersIDs)) {
1294
            $xoopsUsersIDs = \array_unique($xoopsUsersIDs);
1295
            \sort($xoopsUsersIDs);
1296
            if (\count($xoopsUsersIDs) > 0) {
1297
                /** @var \XoopsUserHandler $memberHandler */
1298
                $memberHandler = \xoops_getHandler('user');
1299
                $criteria      = new \Criteria('uid', '(' . \implode(',', $xoopsUsersIDs) . ')', 'IN');
1300
                $criteria->setSort('uid');
1301
                $users = $memberHandler->getObjects($criteria, true);
1302
            }
1303
        }
1304
1305
        return $users;
1306
    }
1307
1308
    /**
1309
     * Retourne l'ID de l'utilisateur courant (s'il est connecté)
1310
     *
1311
     * @return int L'uid ou 0
1312
     */
1313
    public static function getCurrentUserID()
1314
    {
1315
        global $xoopsUser;
1316
        $uid = \is_object($xoopsUser) ? $xoopsUser->getVar('uid') : 0;
1317
1318
        return $uid;
1319
    }
1320
1321
    /**
1322
     * Retourne la liste des groupes de l'utilisateur courant (avec cache)
1323
     *
1324
     * @param int $uid
1325
     *
1326
     * @return array Les ID des groupes auquel l'utilisateur courant appartient
1327
     */
1328
    public static function getMemberGroups($uid = 0)
1329
    {
1330
        static $buffer = [];
1331
        if (0 == $uid) {
1332
            $uid = self::getCurrentUserID();
1333
        }
1334
1335
        if (\is_array($buffer) && \count($buffer) > 0 && isset($buffer[$uid])) {
1336
            return $buffer[$uid];
1337
        }
1338
        if ($uid > 0) {
1339
            $memberHandler = \xoops_getHandler('member');
1340
            $buffer[$uid]  = $memberHandler->getGroupsByUser($uid, false); // Renvoie un tableau d'ID (de groupes)
1341
        } else {
1342
            $buffer[$uid] = [XOOPS_GROUP_ANONYMOUS];
1343
        }
1344
1345
        return $buffer[$uid];
1346
    }
1347
1348
    /**
1349
     * Indique si l'utilisateur courant fait partie d'une groupe donné (avec gestion de cache)
1350
     *
1351
     * @param int $group Groupe recherché
1352
     * @param int $uid
1353
     *
1354
     * @return bool vrai si l'utilisateur fait partie du groupe, faux sinon
1355
     */
1356
    public static function isMemberOfGroup($group = 0, $uid = 0)
1357
    {
1358
        static $buffer = [];
1359
        $retval = false;
1360
        if (0 == $uid) {
1361
            $uid = self::getCurrentUserID();
1362
        }
1363
        if (\is_array($buffer) && \array_key_exists($group, $buffer)) {
1364
            $retval = $buffer[$group];
1365
        } else {
1366
            $memberHandler  = \xoops_getHandler('member');
1367
            $groups         = $memberHandler->getGroupsByUser($uid, false); // Renvoie un tableau d'ID (de groupes)
1368
            $retval         = \in_array($group, $groups);
1369
            $buffer[$group] = $retval;
1370
        }
1371
1372
        return $retval;
1373
    }
1374
1375
    /**
1376
     * Function responsible for verifying that a directory exists, we can write in and create an index.html file
1377
     *
1378
     * @param $folder
1379
     */
1380
    public static function prepareFolder($folder)
1381
    {
1382
        if (!\is_dir($folder)) {
1383
            if (!\mkdir($folder) && !\is_dir($folder)) {
1384
                throw new \RuntimeException(\sprintf('Directory "%s" was not created', $folder));
1385
            }
1386
            file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
1387
        }
1388
        //        chmod($folder, 0777);
1389
    }
1390
1391
    /**
1392
     * Duplicate a file in local
1393
     *
1394
     * @param string $path     The file's path
1395
     * @param string $filename The filename
1396
     *
1397
     * @return false|string If the copy succeed, the new filename else false
1398
     * @since 2.1
1399
     */
1400
    public static function duplicateFile($path, $filename)
1401
    {
1402
        $newName = self::createUploadName($path, $filename);
1403
        if (\copy($path . \DIRECTORY_SEPARATOR . $filename, $path . \DIRECTORY_SEPARATOR . $newName)) {
1404
            return $newName;
1405
        }
1406
1407
        return false;
1408
    }
1409
1410
    //=================================================================================================================================
1411
1412
    /**
1413
     * @param       $name
1414
     * @param bool  $optional
1415
     * @return bool
1416
     */
1417
    public static function getHandler($name, $optional = false)
1418
    {
1419
        global $handlers, $xoopsModule;
1420
1421
        $name = mb_strtolower(\trim($name));
1422
        if (!isset($handlers[$name])) {
1423
            if (\is_file($hnd_file = XOOPS_ROOT_PATH . '/modules/' . $xoopsModule->getVar('dirname') . '/class/class_' . $name . '.php')) {
1424
                require_once $hnd_file;
1425
            }
1426
            $class = 'xtube' . \ucfirst($name) . 'Handler';
1427
            if (\class_exists($class)) {
1428
                $handlers[$name] = new $class($GLOBALS['xoopsDB']);
1429
            }
1430
        }
1431
        if (!isset($handlers[$name]) && !$optional) {
1432
            \trigger_error('<div>Class <span style="font-weight: bold;">' . $class . '</span> does not exist.</div><div>Handler Name: ' . $name, \E_USER_ERROR) . '</div>';
1433
        }
1434
1435
        return $handlers[$name] ?? false;
1436
    }
1437
1438
    /**
1439
     * @param int    $cid
1440
     * @param string $permType
1441
     * @param bool   $redirect
1442
     *
1443
     * @return bool
1444
     */
1445
    public static function checkGroups($cid = 0, $permType = 'XTubeCatPerm', $redirect = false)
1446
    {
1447
        global $xoopsModule;
1448
1449
        $groups = \is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getGroups() : XOOPS_GROUP_ANONYMOUS;
1450
        /** @var \XoopsGroupPermHandler $grouppermHandler */
1451
        $grouppermHandler = \xoops_getHandler('groupperm');
1452
        if (!$grouppermHandler->checkRight($permType, $cid, $groups, $xoopsModule->getVar('mid'))) {
1453
            if (!$redirect) {
1454
                return false;
1455
            }
1456
            \redirect_header('index.php', 3, _NOPERM);
1457
        }
1458
1459
        return true;
1460
    }
1461
1462
    /**
1463
     * @param int $lid
1464
     *
1465
     * @return bool
1466
     */
1467
    public static function getVoteDetails($lid = 0)
1468
    {
1469
        $sql = 'SELECT
1470
        COUNT(rating) AS rate,
1471
        MIN(rating) AS min_rate,
1472
        MAX(rating) AS max_rate,
1473
        AVG(rating) AS avg_rate,
1474
        COUNT(ratinguser) AS rating_user,
1475
        MAX(ratinguser) AS max_user,
1476
        MAX(title) AS max_title,
1477
        MIN(title) AS min_title,
1478
        sum(ratinguser = 0) AS null_ratinguser
1479
            FROM ' . $GLOBALS['xoopsDB']->prefix('xoopstube_votedata');
1480
        if ($lid > 0) {
1481
            $sql .= ' WHERE lid=' . $lid;
1482
        }
1483
        if (!$result = $GLOBALS['xoopsDB']->query($sql)) {
1484
            return false;
1485
        }
1486
        $ret = $GLOBALS['xoopsDB']->fetchArray($result);
1487
1488
        return $ret;
1489
    }
1490
1491
    /**
1492
     * @param int $sel_id
1493
     *
1494
     * @return array|bool
1495
     */
1496
    public static function calculateVoteData($sel_id = 0)
1497
    {
1498
        $ret                  = [];
1499
        $ret['useravgrating'] = 0;
1500
1501
        $sql = 'SELECT rating FROM ' . $GLOBALS['xoopsDB']->prefix('xoopstube_votedata');
1502
        if (0 !== $sel_id) {
1503
            $sql .= ' WHERE lid=' . $sel_id;
1504
        }
1505
        if (!$result = $GLOBALS['xoopsDB']->query($sql)) {
1506
            return false;
1507
        }
1508
        $ret['uservotes'] = $GLOBALS['xoopsDB']->getRowsNum($result);
1509
        while (list($rating) = $GLOBALS['xoopsDB']->fetchRow($result)) {
1510
            $ret['useravgrating'] += (int)$rating;
1511
        }
1512
        if ($ret['useravgrating'] > 0) {
1513
            $ret['useravgrating'] = \number_format($ret['useravgrating'] / $ret['uservotes'], 2);
1514
        }
1515
1516
        return $ret;
1517
    }
1518
1519
    /**
1520
     * @param      $array
1521
     * @param null $name
1522
     * @param null $def
1523
     * @param bool $strict
1524
     * @param int  $lengthcheck
1525
     *
1526
     * @return array|int|null|string
1527
     */
1528
    public static function cleanRequestVars(
1529
        &$array,
1530
        $name = null,
1531
        $def = null,
1532
        $strict = false,
1533
        $lengthcheck = 15
1534
    ) {
1535
        // Sanitise $_request for further use.  This method gives more control and security.
1536
        // Method is more for functionality rather than beauty at the moment, will correct later.
1537
        unset($array['usercookie'], $array['PHPSESSID']);
1538
1539
        if (\is_array($array) && null === $name) {
1540
            $globals = [];
1541
            foreach (\array_keys($array) as $k) {
1542
                $value = \strip_tags(\trim($array[$k]));
1543
                if (mb_strlen($value >= $lengthcheck)) {
1544
                    return null;
1545
                }
1546
                if (ctype_digit($value)) {
1547
                    $value = (int)$value;
1548
                } else {
1549
                    if ($strict) {
1550
                        $value = \preg_replace('/\W/', '', \trim($value));
1551
                    }
1552
                    $value = mb_strtolower((string)$value);
1553
                }
1554
                $globals[$k] = $value;
1555
            }
1556
1557
            return $globals;
1558
        }
1559
        if (!isset($array[$name]) || !\array_key_exists($name, $array)) {
1560
            return $def;
1561
        }
1562
        $value = \strip_tags(\trim($array[$name]));
1563
1564
        if (ctype_digit($value)) {
1565
            $value = (int)$value;
1566
        } else {
1567
            if ($strict) {
1568
                $value = \preg_replace('/\W/', '', \trim($value));
1569
            }
1570
            $value = mb_strtolower((string)$value);
1571
        }
1572
1573
        return $value;
1574
    }
1575
1576
    /**
1577
     * @param int $cid
1578
     *
1579
     * @return string
1580
     */
1581
    public static function renderToolbar($cid = 0)
1582
    {
1583
        $toolbar = '[ ';
1584
        if (self::checkGroups($cid, 'XTubeSubPerm')) {
1585
            $toolbar .= '<a href="submit.php?cid=' . $cid . '">' . \_MD_XOOPSTUBE_SUBMITVIDEO . '</a> | ';
1586
        }
1587
        $toolbar .= '<a href="newlist.php?newvideoshowdays=7">' . \_MD_XOOPSTUBE_LATESTLIST . '</a> | <a href="topten.php?list=hit">' . \_MD_XOOPSTUBE_POPULARITY . '</a> | <a href="topten.php?list=rate">' . \_MD_XOOPSTUBE_TOPRATED . '</a> ]';
1588
1589
        return $toolbar;
1590
    }
1591
1592
    public static function getServerStatistics()
1593
    {
1594
        global $xoopsModule;
1595
        echo '<fieldset style="border: #E8E8E8 1px solid;">
1596
          <legend style="display: inline; font-weight: bold; color: #0A3760;">' . \_AM_XOOPSTUBE_VIDEO_IMAGEINFO . '</legend>
1597
          <div style="padding: 8px;">
1598
            <img src="' . XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . '/assets/images/icon/server.png" alt="" style="float: left; padding-right: 10px;">
1599
          <div>' . \_AM_XOOPSTUBE_VIDEO_SPHPINI . '</div>';
1600
1601
        //    $safemode        = ini_get('safe_mode') ? _AM_XOOPSTUBE_VIDEO_ON . _AM_XOOPSTUBE_VIDEO_SAFEMODEPROBLEMS : _AM_XOOPSTUBE_VIDEO_OFF;
1602
        //    $registerglobals = (ini_get('register_globals') === '') ? _AM_XOOPSTUBE_VIDEO_OFF : _AM_XOOPSTUBE_VIDEO_ON;
1603
        $videos = \ini_get('file_uploads') ? \_AM_XOOPSTUBE_VIDEO_ON : \_AM_XOOPSTUBE_VIDEO_OFF;
1604
1605
        $gdlib = \function_exists('gd_info') ? \_AM_XOOPSTUBE_VIDEO_GDON : \_AM_XOOPSTUBE_VIDEO_GDOFF;
1606
        echo '<li>' . \_AM_XOOPSTUBE_VIDEO_GDLIBSTATUS . $gdlib;
1607
        if (\function_exists('gd_info')) {
1608
            if (true === $gdlib = gd_info()) {
1609
                echo '<li>' . \_AM_XOOPSTUBE_VIDEO_GDLIBVERSION . '<b>' . $gdlib['GD Version'] . '</b>';
1610
            }
1611
        }
1612
        echo '<br><br>';
1613
        //    echo '<li>' . _AM_XOOPSTUBE_VIDEO_SAFEMODESTATUS . $safemode;
1614
        //    echo '<li>' . _AM_XOOPSTUBE_VIDEO_REGISTERGLOBALS . $registerglobals;
1615
        echo '<li>' . \_AM_XOOPSTUBE_VIDEO_SERVERUPLOADSTATUS . $videos;
1616
        echo '</div>';
1617
        echo '</fieldset>';
1618
    }
1619
1620
    // displayIcons()
1621
    //
1622
    // @param  $time
1623
    // @param integer $status
1624
    // @param integer $counter
1625
    // @return
1626
1627
    /**
1628
     * @param     $time
1629
     * @param int $status
1630
     * @param int $counter
1631
     *
1632
     * @return string
1633
     */
1634
    public static function displayIcons($time, $status = 0, $counter = 0)
1635
    {
1636
        global $xoopsModule;
1637
1638
        $new = '';
1639
        $pop = '';
1640
1641
        $newdate = (\time() - (86400 * (int)$GLOBALS['xoopsModuleConfig']['daysnew']));
1642
        $popdate = (\time() - (86400 * (int)$GLOBALS['xoopsModuleConfig']['daysupdated']));
1643
1644
        if (3 != $GLOBALS['xoopsModuleConfig']['displayicons']) {
1645
            if ($newdate < $time) {
1646
                if ((int)$status > 1) {
1647
                    if (1 == $GLOBALS['xoopsModuleConfig']['displayicons']) {
1648
                        $new = '&nbsp;<img src="' . XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . '/assets/images/icon/updated.gif" alt="" style="vertical-align: middle;">';
1649
                    }
1650
                    if (2 == $GLOBALS['xoopsModuleConfig']['displayicons']) {
1651
                        $new = '<em>' . \_MD_XOOPSTUBE_UPDATED . '</em>';
1652
                    }
1653
                } else {
1654
                    if (1 == $GLOBALS['xoopsModuleConfig']['displayicons']) {
1655
                        $new = '&nbsp;<img src="' . XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . '/assets/images/icon/new.gif" alt="" style="vertical-align: middle;">';
1656
                    }
1657
                    if (2 == $GLOBALS['xoopsModuleConfig']['displayicons']) {
1658
                        $new = '<em>' . \_MD_XOOPSTUBE_NEW . '</em>';
1659
                    }
1660
                }
1661
            }
1662
            if ($popdate > $time) {
1663
                if ($counter >= $GLOBALS['xoopsModuleConfig']['popular']) {
1664
                    if (1 == $GLOBALS['xoopsModuleConfig']['displayicons']) {
1665
                        $pop = '&nbsp;<img src="' . XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . '/assets/images/icon/popular.png" alt="" style="vertical-align: middle;">';
1666
                    }
1667
                    if (2 == $GLOBALS['xoopsModuleConfig']['displayicons']) {
1668
                        $pop = '<em>' . \_MD_XOOPSTUBE_POPULAR . '!</em>';
1669
                    }
1670
                }
1671
            }
1672
        }
1673
        $icons = $new . ' ' . $pop;
1674
1675
        return $icons;
1676
    }
1677
1678
    // Reusable Link Sorting Functions
1679
    // convertOrderByIn()
1680
    // @param  $orderby
1681
    // @return
1682
1683
    /**
1684
     * @param $orderby
1685
     *
1686
     * @return string
1687
     */
1688
    public static function convertOrderByIn($orderby)
1689
    {
1690
        switch (\trim($orderby)) {
1691
            case 'titleA':
1692
                $orderby = 'title ASC';
1693
                break;
1694
            case 'dateA':
1695
                $orderby = 'published ASC';
1696
                break;
1697
            case 'hitsA':
1698
                $orderby = 'hits ASC';
1699
                break;
1700
            case 'ratingA':
1701
                $orderby = 'rating ASC';
1702
                break;
1703
            case 'countryA':
1704
                $orderby = 'country ASC';
1705
                break;
1706
            case 'titleD':
1707
                $orderby = 'title DESC';
1708
                break;
1709
            case 'hitsD':
1710
                $orderby = 'hits DESC';
1711
                break;
1712
            case 'ratingD':
1713
                $orderby = 'rating DESC';
1714
                break;
1715
            case'dateD':
1716
                $orderby = 'published DESC';
1717
                break;
1718
            case 'countryD':
1719
                $orderby = 'country DESC';
1720
                break;
1721
        }
1722
1723
        return $orderby;
1724
    }
1725
1726
    /**
1727
     * @param $orderby
1728
     *
1729
     * @return string
1730
     */
1731
    public static function convertOrderByTrans($orderby)
1732
    {
1733
        switch ($orderby) {
1734
            case 'hits ASC':
1735
                $orderByTrans = \_MD_XOOPSTUBE_POPULARITYLTOM;
1736
                break;
1737
            case 'hits DESC':
1738
                $orderByTrans = \_MD_XOOPSTUBE_POPULARITYMTOL;
1739
                break;
1740
            case 'title ASC':
1741
                $orderByTrans = \_MD_XOOPSTUBE_TITLEATOZ;
1742
                break;
1743
            case 'title DESC':
1744
                $orderByTrans = \_MD_XOOPSTUBE_TITLEZTOA;
1745
                break;
1746
            case 'published ASC':
1747
                $orderByTrans = \_MD_XOOPSTUBE_DATEOLD;
1748
                break;
1749
            case 'published DESC':
1750
                $orderByTrans = \_MD_XOOPSTUBE_DATENEW;
1751
                break;
1752
            case 'rating ASC':
1753
                $orderByTrans = \_MD_XOOPSTUBE_RATINGLTOH;
1754
                break;
1755
            case 'rating DESC':
1756
                $orderByTrans = \_MD_XOOPSTUBE_RATINGHTOL;
1757
                break;
1758
            case'country ASC':
1759
                $orderByTrans = \_MD_XOOPSTUBE_COUNTRYLTOH;
1760
                break;
1761
            case 'country DESC':
1762
                $orderByTrans = \_MD_XOOPSTUBE_COUNTRYHTOL;
1763
                break;
1764
        }
1765
1766
        return $orderByTrans;
1767
    }
1768
1769
    /**
1770
     * @param $orderby
1771
     *
1772
     * @return string
1773
     */
1774
    public static function convertOrderByOut($orderby)
1775
    {
1776
        switch ($orderby) {
1777
            case 'title ASC':
1778
                $orderby = 'titleA';
1779
                break;
1780
            case 'published ASC':
1781
                $orderby = 'dateA';
1782
                break;
1783
            case 'hits ASC':
1784
                $orderby = 'hitsA';
1785
                break;
1786
            case 'rating ASC':
1787
                $orderby = 'ratingA';
1788
                break;
1789
            case 'country ASC':
1790
                $orderby = 'countryA';
1791
                break;
1792
            case 'title DESC':
1793
                $orderby = 'titleD';
1794
                break;
1795
            case 'published DESC':
1796
                $orderby = 'dateD';
1797
                break;
1798
            case 'hits DESC':
1799
                $orderby = 'hitsD';
1800
                break;
1801
            case 'rating DESC':
1802
                $orderby = 'ratingD';
1803
                break;
1804
            case 'country DESC':
1805
                $orderby = 'countryD';
1806
                break;
1807
        }
1808
1809
        return $orderby;
1810
    }
1811
1812
    // updaterating()
1813
    // @param  $sel_id
1814
    // @return updates rating data in itemtable for a given item
1815
1816
    /**
1817
     * @param $sel_id
1818
     */
1819
    public static function updateRating($sel_id)
1820
    {
1821
        $query       = 'SELECT rating FROM ' . $GLOBALS['xoopsDB']->prefix('xoopstube_votedata') . ' WHERE lid=' . $sel_id;
1822
        $voteresult  = $GLOBALS['xoopsDB']->query($query);
1823
        $votesDB     = $GLOBALS['xoopsDB']->getRowsNum($voteresult);
1824
        $totalrating = 0;
1825
        while (list($rating) = $GLOBALS['xoopsDB']->fetchRow($voteresult)) {
1826
            $totalrating += $rating;
1827
        }
1828
        $finalrating = $totalrating / $votesDB;
1829
        $finalrating = \number_format($finalrating, 4);
1830
        $sql         = \sprintf('UPDATE `%s` SET rating = %u, votes = %u WHERE lid = %u', $GLOBALS['xoopsDB']->prefix('xoopstube_videos'), $finalrating, $votesDB, $sel_id);
1831
        $GLOBALS['xoopsDB']->query($sql);
1832
    }
1833
1834
    // totalcategory()
1835
    // @param integer $pid
1836
    // @return
1837
1838
    /**
1839
     * @param int $pid
1840
     *
1841
     * @return int
1842
     */
1843
    public static function getTotalCategoryCount($pid = 0)
1844
    {
1845
        $sql = 'SELECT cid FROM ' . $GLOBALS['xoopsDB']->prefix('xoopstube_cat');
1846
        if ($pid > 0) {
1847
            $sql .= ' WHERE pid = 0';
1848
        }
1849
        $result     = $GLOBALS['xoopsDB']->query($sql);
1850
        $catlisting = 0;
1851
        while (list($cid) = $GLOBALS['xoopsDB']->fetchRow($result)) {
1852
            if (self::checkGroups($cid)) {
1853
                ++$catlisting;
1854
            }
1855
        }
1856
1857
        return $catlisting;
1858
    }
1859
1860
    // getTotalItems()
1861
    // @param integer $sel_id
1862
    // @param integer $get_child
1863
    // @param integer $return_sql
1864
    // @return
1865
1866
    /**
1867
     * @param int $sel_id
1868
     * @param int $get_child
1869
     * @param int $return_sql
1870
     *
1871
     * @return string
1872
     */
1873
    public static function getTotalItems($sel_id = 0, $get_child = 0, $return_sql = 0)
1874
    {
1875
        global $mytree, $_check_array;
1876
1877
        if ($sel_id > 0) {
1878
            $sql = 'SELECT a.lid, a.cid, a.published FROM '
1879
                   . $GLOBALS['xoopsDB']->prefix('xoopstube_videos')
1880
                   . ' a LEFT JOIN '
1881
                   . $GLOBALS['xoopsDB']->prefix('xoopstube_altcat')
1882
                   . ' b'
1883
                   . ' ON b.lid=a.lid'
1884
                   . ' WHERE a.published > 0 AND a.published <= '
1885
                   . \time()
1886
                   . ' AND (a.expired = 0 OR a.expired > '
1887
                   . \time()
1888
                   . ') AND offline = 0 '
1889
                   . ' AND (b.cid=a.cid OR (a.cid='
1890
                   . $sel_id
1891
                   . ' OR b.cid='
1892
                   . $sel_id
1893
                   . '))'
1894
                   . ' GROUP BY a.lid, a.cid, a.published';
1895
        } else {
1896
            $sql = 'SELECT lid, cid, published FROM ' . $GLOBALS['xoopsDB']->prefix('xoopstube_videos') . ' WHERE offline = 0 AND published > 0 AND published <= ' . \time() . ' AND (expired = 0 OR expired > ' . \time() . ')';
1897
        }
1898
        if (1 == $return_sql) {
1899
            return $sql;
1900
        }
1901
1902
        $count          = 0;
1903
        $published_date = 0;
1904
1905
        $arr    = [];
1906
        $result = $GLOBALS['xoopsDB']->query($sql);
1907
        while (list($lid, $cid, $published) = $GLOBALS['xoopsDB']->fetchRow($result)) {
1908
            if (self::checkGroups()) {
1909
                ++$count;
1910
                $published_date = ($published > $published_date) ? $published : $published_date;
1911
            }
1912
        }
1913
1914
        $child_count = 0;
1915
        if (1 == $get_child) {
1916
            $arr  = $mytree->getAllChildId($sel_id);
1917
            $size = \count($arr);
1918
            foreach ($arr as $iValue) {
1919
                $query2 = 'SELECT a.lid, a.published, a.cid FROM '
1920
                          . $GLOBALS['xoopsDB']->prefix('xoopstube_videos')
1921
                          . ' a LEFT JOIN '
1922
                          . $GLOBALS['xoopsDB']->prefix('xoopstube_altcat')
1923
                          . ' b'
1924
                          . ' ON b.lid = a.lid'
1925
                          . ' WHERE a.published > 0 AND a.published <= '
1926
                          . \time()
1927
                          . ' AND (a.expired = 0 OR a.expired > '
1928
                          . \time()
1929
                          . ') AND offline = 0'
1930
                          . ' AND (b.cid=a.cid OR (a.cid='
1931
                          . $iValue
1932
                          . ' OR b.cid='
1933
                          . $iValue
1934
                          . ')) GROUP BY a.lid, a.published, a.cid';
1935
1936
                $result2 = $GLOBALS['xoopsDB']->query($query2);
1937
                while (list($lid, $published) = $GLOBALS['xoopsDB']->fetchRow($result2)) {
1938
                    if (0 == $published) {
1939
                        continue;
1940
                    }
1941
                    $published_date = ($published > $published_date) ? $published : $published_date;
1942
                    ++$child_count;
1943
                }
1944
            }
1945
        }
1946
        $info['count']     = $count + $child_count;
1947
        $info['published'] = $published_date;
1948
1949
        return $info;
1950
    }
1951
1952
    /**
1953
     * @param string $indeximage
1954
     * @param string $indexheading
1955
     *
1956
     * @return string
1957
     */
1958
    public static function renderImageHeader($indeximage = '', $indexheading = '')
1959
    {
1960
        if ('' === $indeximage) {
1961
            $result = $GLOBALS['xoopsDB']->query('SELECT indeximage, indexheading FROM ' . $GLOBALS['xoopsDB']->prefix('xoopstube_indexpage'));
1962
            [$indeximage, $indexheading] = $GLOBALS['xoopsDB']->fetchrow($result);
1963
        }
1964
1965
        $image = '';
1966
        if (!empty($indeximage)) {
1967
            $image = self::displayImage($indeximage, 'index.php', $GLOBALS['xoopsModuleConfig']['mainimagedir'], $indexheading);
1968
        }
1969
1970
        return $image;
1971
    }
1972
1973
    /**
1974
     * @param string $image
1975
     * @param string $path
1976
     * @param string $imgsource
1977
     * @param string $alttext
1978
     *
1979
     * @return string
1980
     */
1981
    public static function displayImage($image = '', $path = '', $imgsource = '', $alttext = '')
1982
    {
1983
        global $xoopsModule;
1984
1985
        $showimage = '';
1986
        // Check to see if link is given
1987
        if ($path) {
1988
            $showimage = '<a href="' . $path . '">';
1989
        }
1990
        // checks to see if the file is valid else displays default blank image
1991
        if (\is_file(XOOPS_ROOT_PATH . "/{$imgsource}/{$image}")//            && is_dir(XOOPS_ROOT_PATH . "/{$imgsource}/{$image}")
1992
        ) {
1993
            $showimage .= "<img src='" . XOOPS_URL . "/{$imgsource}/{$image}' border='0' title='" . $alttext . "' alt='" . $alttext . "'></a>";
1994
        } elseif ($GLOBALS['xoopsUser'] && $GLOBALS['xoopsUser']->isAdmin($xoopsModule->getVar('mid'))) {
1995
            $showimage .= '<img src="' . XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . '/assets/images/brokenimg.png" alt="' . \_MD_XOOPSTUBE_ISADMINNOTICE . '"></a>';
1996
        } else {
1997
            $showimage .= '<img src="' . XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . '/assets/images/blank.png" alt="' . $alttext . '"></a>';
1998
        }
1999
        \clearstatcache();
2000
2001
        return $showimage;
2002
    }
2003
2004
    /**
2005
     * @param $published
2006
     *
2007
     * @return array
2008
     */
2009
    public static function isNewImage($published)
2010
    {
2011
        global $xoopsModule;
2012
2013
        $oneday    = (\time() - (86400 * 1));
2014
        $threedays = (\time() - (86400 * 3));
2015
        $week      = (\time() - (86400 * 7));
2016
2017
        $path = 'modules/' . $xoopsModule->getVar('dirname') . '/assets/images/icon';
2018
2019
        if ($published > 0 && $published < $week) {
2020
            $indicator['image']   = "$path/linkload4.png";
2021
            $indicator['alttext'] = \_MD_XOOPSTUBE_NEWLAST;
2022
        } elseif ($published >= $week && $published < $threedays) {
2023
            $indicator['image']   = "$path/linkload3.png";
2024
            $indicator['alttext'] = \_MD_XOOPSTUBE_NEWTHIS;
2025
        } elseif ($published >= $threedays && $published < $oneday) {
2026
            $indicator['image']   = "$path/linkload2.png";
2027
            $indicator['alttext'] = \_MD_XOOPSTUBE_THREE;
2028
        } elseif ($published >= $oneday) {
2029
            $indicator['image']   = "$path/linkload1.png";
2030
            $indicator['alttext'] = \_MD_XOOPSTUBE_TODAY;
2031
        } else {
2032
            $indicator['image']   = "$path/linkload.png";
2033
            $indicator['alttext'] = \_MD_XOOPSTUBE_NO_FILES;
2034
        }
2035
2036
        return $indicator;
2037
    }
2038
2039
    /**
2040
     * @param $haystack
2041
     * @param $needle
2042
     *
2043
     * @return string
2044
     */
2045
    public static function findStringChar($haystack, $needle)
2046
    {
2047
        return mb_substr($haystack, 0, mb_strpos($haystack, $needle) + 1);
2048
    }
2049
2050
    /**
2051
     * @param string $header
2052
     * @param string $menu
2053
     * @param string $extra
2054
     * @param int    $scount
2055
     *
2056
     * @return bool|null
2057
     */
2058
    public static function renderAdminMenu($header = '', $menu = '', $extra = '', $scount = 4)
2059
    {
2060
        global $xoopsModule;
2061
2062
        $_named_vidid = \xoops_getenv('SCRIPT_NAME');
2063
        if ($_named_vidid) {
2064
            $thispage = \basename($_named_vidid);
2065
        }
2066
2067
        //    $op = (isset($_GET['op'])) ? $op = '?op=' . $_GET['op'] : '';
2068
        $op = Request::getString('op', '', 'GET');
2069
        echo '<h4 style="color: #2F5376;">' . \_AM_XOOPSTUBE_MODULE_NAME . '</h4>';
2070
        echo '
2071
        <div style="font-size: 10px; text-align: left; color: #2F5376; padding: 2px 6px; line-height: 18px;">
2072
        <span style="margin: 1px; padding: 4px; border: #E8E8E8 1px solid;">
2073
            <a href="../admin/index.php">' . \_AM_XOOPSTUBE_BINDEX . '</a>
2074
        </span>
2075
        <span  style="margin: 1px; padding: 4px; border: #E8E8E8 1px solid;">
2076
            <a href="../index.php">' . \_AM_XOOPSTUBE_GOMODULE . '</a>
2077
        </span>
2078
        <span  style="margin: 1px; padding: 4px; border: #E8E8E8 1px solid;">
2079
            <a href="../../system/admin.php?fct=preferences&op=showmod&mod=' . $xoopsModule->getVar('mid') . '">' . \_AM_XOOPSTUBE_PREFS . '</a>
2080
        </span>
2081
        <span  style="margin: 1px; padding: 4px; border: #E8E8E8 1px solid;">
2082
            <a href="../admin/permissions.php">' . \_AM_XOOPSTUBE_BPERMISSIONS . '</a>
2083
        </span>
2084
        <span  style="margin: 1px; padding: 4px; border: #E8E8E8 1px solid;">
2085
            <a href="../admin/myblocksadmin.php">' . \_AM_XOOPSTUBE_BLOCKADMIN . '</a>
2086
        </span>
2087
        <span  style="margin: 1px; padding: 4px; border: #E8E8E8 1px solid;">
2088
            <a href="../../system/admin.php?fct=modulesadmin&op=update&module=' . $xoopsModule->getVar('dirname') . '">' . \_AM_XOOPSTUBE_BUPDATE . '</a>
2089
        </span>
2090
        <span  style="margin: 1px; padding: 4px; border: #E8E8E8 1px solid;">
2091
            <a href="../admin/about.php">' . \_AM_XOOPSTUBE_ABOUT . '</a>
2092
        </span>
2093
        </div><br>';
2094
2095
        if (empty($menu)) {
2096
            // You can change this part to suit your own module. Defining this here will save you form having to do this each time.
2097
            $menu = [
2098
                \_AM_XOOPSTUBE_MVIDEOS   => 'main.php?op=edit',
2099
                \_AM_XOOPSTUBE_MCATEGORY => 'category.php',
2100
                \_AM_XOOPSTUBE_INDEXPAGE => 'indexpage.php',
2101
                //            _AM_XOOPSTUBE_MXOOPSTUBE     => 'main.php?op=edit',
2102
                \_AM_XOOPSTUBE_MUPLOADS  => 'upload.php',
2103
                \_AM_XOOPSTUBE_VUPLOADS  => 'vupload.php',
2104
                \_AM_XOOPSTUBE_MVOTEDATA => 'votedata.php',
2105
                \_AM_XOOPSTUBE_MCOMMENTS => '../../system/admin.php?module=' . $xoopsModule->getVar('mid') . '&status=0&limit=100&fct=comments&selsubmit=Go',
2106
            ];
2107
        }
2108
2109
        if (!\is_array($menu)) {
2110
            echo '<table width="100%" cellpadding="2" cellspacing="1" class="outer">';
2111
            echo '<tr><td class="even" align="center"><b>' . \_AM_XOOPSTUBE_NOMENUITEMS . '</b></td></tr></table><br>';
2112
2113
            return false;
2114
        }
2115
2116
        $oddnum = [
2117
            1  => '1',
2118
            3  => '3',
2119
            5  => '5',
2120
            7  => '7',
2121
            9  => '9',
2122
            11 => '11',
2123
            13 => '13',
2124
        ];
2125
        // number of rows per menu
2126
        $menurows = \count($menu) / $scount;
2127
        // total amount of rows to complete menu
2128
        $menurow = \ceil($menurows) * $scount;
2129
        // actual number of menuitems per row
2130
        $rowcount = $menurow / \ceil($menurows);
2131
        $count    = 0;
2132
        for ($i = \count($menu); $i < $menurow; ++$i) {
2133
            $tempArray = [1 => null];
2134
            $menu      = \array_merge($menu, $tempArray);
2135
            ++$count;
2136
        }
2137
2138
        // Sets up the width of each menu cell
2139
        $width = 100 / $scount;
2140
        $width = \ceil($width);
2141
2142
        $menucount = 0;
2143
        $count     = 0;
2144
        // Menu table output
2145
        echo '<table width="100%" cellpadding="2" cellspacing="1" class="outer" border="1"><tr>';
2146
        // Check to see if $menu is and array
2147
        if (\is_array($menu)) {
2148
            $classcounts = 0;
2149
            $classcol[0] = 'even';
2150
2151
            for ($i = 1; $i < $menurow; ++$i) {
2152
                ++$classcounts;
2153
                if ($classcounts >= $scount) {
2154
                    if ('odd' === $classcol[$i - 1]) {
2155
                        $classcol[$i] = ('odd' === $classcol[$i - 1] && \in_array($classcounts, $oddnum)) ? 'even' : 'odd';
2156
                    } else {
2157
                        $classcol[$i] = ('even' === $classcol[$i - 1] && \in_array($classcounts, $oddnum)) ? 'odd' : 'even';
2158
                    }
2159
                    $classcounts = 0;
2160
                } else {
2161
                    $classcol[$i] = ('even' === $classcol[$i - 1]) ? 'odd' : 'even';
2162
                }
2163
            }
2164
            unset($classcounts);
2165
2166
            foreach ($menu as $menutitle => $menuvideo) {
2167
                if ($thispage . $op == $menuvideo) {
2168
                    $classcol[$count] = 'outer';
2169
                }
2170
                echo '<td class="' . $classcol[$count] . '" style="padding: 4px; text-align: center;" valign="middle" width="' . $width . '%">';
2171
                if (\is_string($menuvideo)) {
2172
                    echo '<a href="' . $menuvideo . '"><span style="font-size: small;">' . $menutitle . '</span></a></td>';
2173
                } else {
2174
                    echo '&nbsp;</td>';
2175
                }
2176
                ++$menucount;
2177
                ++$count;
2178
                // Break menu cells to start a new row if $count > $scount
2179
                if ($menucount >= $scount) {
2180
                    echo '</tr>';
2181
                    $menucount = 0;
2182
                }
2183
            }
2184
            echo '</table><br>';
2185
            unset($count, $menucount);
2186
        }
2187
        // ###### Output warn messages for security ######
2188
        if (\is_dir(XOOPS_ROOT_PATH . '/modules/' . $xoopsModule->getVar('dirname') . '/update/')) {
2189
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL1, XOOPS_ROOT_PATH . '/modules/' . $xoopsModule->getVar('dirname') . '/update/'));
2190
            echo '<br>';
2191
        }
2192
2193
        $_file = XOOPS_ROOT_PATH . '/modules/' . $xoopsModule->getVar('dirname') . '/update.php';
2194
        if (\file_exists($_file)) {
2195
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL2, XOOPS_ROOT_PATH . '/modules/' . $xoopsModule->getVar('dirname') . '/update.php'));
2196
            echo '<br>';
2197
        }
2198
2199
        $path1 = XOOPS_ROOT_PATH . '/' . $GLOBALS['xoopsModuleConfig']['mainimagedir'];
2200
        if (!\is_dir($path1)) {
2201
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL3, $path1));
2202
            echo '<br>';
2203
        }
2204
        if (!\is_writable($path1)) {
2205
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL4, $path1));
2206
            echo '<br>';
2207
        }
2208
2209
        $path1_t = XOOPS_ROOT_PATH . '/' . $GLOBALS['xoopsModuleConfig']['mainimagedir'] . '/thumbs';
2210
        if (!\is_dir($path1_t)) {
2211
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL3, $path1_t));
2212
            echo '<br>';
2213
        }
2214
        if (!\is_writable($path1_t)) {
2215
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL4, $path1_t));
2216
            echo '<br>';
2217
        }
2218
2219
        $path2 = XOOPS_ROOT_PATH . '/' . $GLOBALS['xoopsModuleConfig']['videoimgdir'];
2220
        if (!\is_dir($path2)) {
2221
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL3, $path2));
2222
            echo '<br>';
2223
        }
2224
        if (!\is_writable($path2)) {
2225
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL4, $path2));
2226
            echo '<br>';
2227
        }
2228
2229
        //    $path2_t = XOOPS_ROOT_PATH . '/' . $GLOBALS['xoopsModuleConfig']['videoimgdir'] . '/thumbs';
2230
        //    if ( !is_dir( $path2_t ) || !is_writable( $path2_t ) ) {
2231
        //        xoops_error( sprintf( _AM_XOOPSTUBE_WARNINSTALL3, $path2_t ) );
2232
        //        echo '<br>';
2233
        //    }
2234
2235
        $path3 = XOOPS_ROOT_PATH . '/' . $GLOBALS['xoopsModuleConfig']['catimage'];
2236
        if (!\is_dir($path3)) {
2237
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL3, $path3));
2238
            echo '<br>';
2239
        }
2240
        if (!\is_writable($path3)) {
2241
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL4, $path3));
2242
            echo '<br>';
2243
        }
2244
2245
        $path3_t = XOOPS_ROOT_PATH . '/' . $GLOBALS['xoopsModuleConfig']['catimage'] . '/thumbs';
2246
        if (!\is_dir($path3_t)) {
2247
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL3, $path3_t));
2248
            echo '<br>';
2249
        }
2250
        if (!\is_writable($path3_t)) {
2251
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL4, $path3_t));
2252
            echo '<br>';
2253
        }
2254
2255
        $path4 = XOOPS_ROOT_PATH . '/' . $GLOBALS['xoopsModuleConfig']['videodir'];
2256
        if (!\is_dir($path4)) {
2257
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL3, $path4));
2258
            echo '<br>';
2259
        }
2260
        if (!\is_writable($path4)) {
2261
            \xoops_error(\sprintf(\_AM_XOOPSTUBE_WARNINSTALL4, $path4));
2262
            echo '<br>';
2263
        }
2264
2265
        echo '<h4 style="color: #2F5376;">' . $header . '</h4>';
2266
        if ($extra) {
2267
            echo '<div>' . $extra . '</div>';
2268
        }
2269
2270
        return null;
2271
    }
2272
2273
    /**
2274
     * @param $selected
2275
     * @param $dirarray
2276
     * @param $namearray
2277
     */
2278
    public static function getDirSelectOption($selected, $dirarray, $namearray)
2279
    {
2280
        echo "<select size='1' name='workd' onchange='location.href=\"upload.php?rootpath=\"+this.options[this.selectedIndex].value'>";
2281
        echo "<option value=''>--------------------------------------</option>";
2282
        foreach ($namearray as $namearray => $workd) {
2283
            $opt_selected = '';
2284
            if ($workd == $selected) {
2285
                $opt_selected = 'selected';
2286
            }
2287
            echo '<option value="' . \htmlspecialchars($namearray, \ENT_QUOTES) . '" $opt_selected>' . $workd . '</option>';
2288
        }
2289
        echo '</select>';
2290
    }
2291
2292
    //    /**
2293
    //     * @param $selected
2294
    //     * @param $dirarray
2295
    //     * @param $namearray
2296
    //     */
2297
    //    public static function getDirSelectOption($selected, $dirarray, $namearray)
2298
    //    {
2299
    //        echo "<select size='1' name='workd' onchange='location.href=\"vupload.php?rootpath=\"+this.options[this.selectedIndex].value'>";
2300
    //        echo "<option value=''>--------------------------------------</option>";
2301
    //        foreach ($namearray as $namearray => $workd) {
2302
    //            $opt_selected = '';
2303
    //            if ($workd == $selected) {
2304
    //                $opt_selected = 'selected';
2305
    //            }
2306
    //            echo '<option value="' . htmlspecialchars($namearray, ENT_QUOTES) . '" $opt_selected>' . $workd . '</option>';
2307
    //        }
2308
    //        echo '</select>';
2309
    //    }
2310
2311
    /**
2312
     * @param        $FILES
2313
     * @param string $uploaddir
2314
     * @param string $allowed_mimetypes
2315
     * @param string $redirecturl
2316
     * @param int    $redirect
2317
     * @param int    $usertype
2318
     *
2319
     * @return array|null
2320
     */
2321
    public static function uploadFiles(
2322
        $FILES,
2323
        $uploaddir = 'uploads',
2324
        $allowed_mimetypes = '',
2325
        $redirecturl = 'index.php', //    $num = 0,
2326
        $redirect = 0,
2327
        $usertype = 1
2328
    ) {
2329
        global $FILES, $xoopsModule;
2330
2331
        $down = [];
2332
        //       require_once XOOPS_ROOT_PATH . '/modules/' . $xoopsModule->getVar('dirname') . '/class/uploader.php';
2333
        //        require_once __DIR__ . '/uploader.php';
2334
        //        require XOOPS_ROOT_PATH . '/class/uploader.php';
2335
2336
        if (empty($allowed_mimetypes)) {
2337
            $allowed_mimetypes = self::getMimeType($FILES['userfile']['name'], $usertype);
2338
        }
2339
        $upload_dir = XOOPS_ROOT_PATH . '/' . $uploaddir . '/';
2340
2341
        $maxfilesize = $GLOBALS['xoopsModuleConfig']['maxfilesize'];
2342
2343
        $maxfilewidth  = $GLOBALS['xoopsModuleConfig']['maximgwidth'];
2344
        $maxfileheight = $GLOBALS['xoopsModuleConfig']['maximgheight'];
2345
2346
        $uploader = new MediaUploader($upload_dir, $allowed_mimetypes, $maxfilesize, $maxfilewidth, $maxfileheight);
2347
        $uploader->noAdminSizeCheck(1);
2348
        //if ($uploader->fetchMedia(Request::getArray('xoops_upload_file[0]', array(), 'POST'))) {
2349
        if ($uploader->fetchMedia(Request::getArray('xoops_upload_file', '', 'POST')[0])) {
2350
            if (!$uploader->upload()) {
2351
                $errors = $uploader->getErrors();
2352
                \redirect_header($redirecturl, 2, $errors);
2353
            } elseif ($redirect) {
2354
                \redirect_header($redirecturl, 1, \_AM_XOOPSTUBE_UPLOADFILE);
2355
            } else {
2356
                if (\is_file($uploader->savedDestination)) {
2357
                    $down['url']  = XOOPS_URL . '/' . $uploaddir . '/' . mb_strtolower($uploader->savedFileName);
2358
                    $down['size'] = \filesize(XOOPS_ROOT_PATH . '/' . $uploaddir . '/' . mb_strtolower($uploader->savedFileName));
2359
                }
2360
2361
                return $down;
2362
            }
2363
        } else {
2364
            $errors = $uploader->getErrors();
2365
            \redirect_header($redirecturl, 1, $errors);
2366
        }
2367
2368
        return null;
2369
    }
2370
2371
    /**
2372
     * @param $heading
2373
     */
2374
    public static function renderCategoryListHeader($heading)
2375
    {
2376
        echo '
2377
        <h4 style="font-weight: bold; color: #0A3760;">' . $heading . '</h4>
2378
        <table width="100%" cellspacing="1" class="outer" summary>
2379
        <tr>
2380
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_ID . '</th>
2381
            <th style=" font-size: smaller;"><b>' . \_AM_XOOPSTUBE_FCATEGORY_TITLE . '</th>
2382
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_FCATEGORY_WEIGHT . '</th>
2383
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_FCATEGORY_CIMAGE . '</th>
2384
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_CATSPONSOR . '</th>
2385
<!--            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_PUBLISH . '</th>
2386
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_EXPIRE . '</th>
2387
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_ONLINE . '</th>
2388
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_ACTION . '</th> -->
2389
        </tr>
2390
        ';
2391
    }
2392
2393
    /**
2394
     * @param $published
2395
     */
2396
    public static function renderCategoryListBody($published)
2397
    {
2398
        global  $xtubeImageArray;
2399
2400
        $xtubemyts = new TextSanitizer();
2401
2402
        $lid = $published['lid'];
2403
        $cid = $published['cid'];
2404
2405
        $title        = '<a href="../singlevideo.php?cid=' . $published['cid'] . '&amp;lid=' . $published['lid'] . '">' . $xtubemyts->htmlSpecialCharsStrip(\trim($published['title'])) . '</a>';
2406
        $maintitle    = \urlencode(\htmlspecialchars(\trim($published['title']), \ENT_QUOTES | \ENT_HTML5));
2407
        $cattitle     = '<a href="../viewcat.php?cid=' . $published['cid'] . '">' . self::getCategoryTitle($published['cid']) . '</a>';
2408
        $submitter    = self::getLinkedUserNameFromId($published['submitter']);
2409
        $returnsource = \xtubeReturnSource($published['vidsource']);
2410
        $submitted    = self::getTimestamp(\formatTimestamp($published['date'], $GLOBALS['xoopsModuleConfig']['dateformatadmin']));
2411
        $publish      = ($published['published'] > 0) ? self::getTimestamp(\formatTimestamp($published['published'], $GLOBALS['xoopsModuleConfig']['dateformatadmin'])) : 'Not Published';
2412
        $expires      = $published['expired'] ? self::getTimestamp(\formatTimestamp($published['expired'], $GLOBALS['xoopsModuleConfig']['dateformatadmin'])) : \_AM_XOOPSTUBE_MINDEX_NOTSET;
2413
2414
        if ((($published['expired'] && $published['expired'] > \time()) || 0 == $published['expired'])
2415
            && ($published['published'] && $published['published'] < \time())
2416
            && 0 == $published['offline']) {
2417
            $published_status = $xtubeImageArray['online'];
2418
        } elseif (($published['expired'] && $published['expired'] < \time()) && 0 == $published['offline']) {
2419
            $published_status = $xtubeImageArray['expired'];
2420
        } else {
2421
            $published_status = (0 == $published['published']) ? '<a href="newvideos.php">' . $xtubeImageArray['offline'] . '</a>' : $xtubeImageArray['offline'];
2422
        }
2423
2424
        if (200 == $published['vidsource']) {
2425
            $icon = '<a href="main.php?op=edit&amp;lid=' . $lid . '" title="' . \_AM_XOOPSTUBE_ICO_EDIT . '">' . $xtubeImageArray['editimg'] . '</a>&nbsp;';
2426
        } else {
2427
            $icon = '<a href="main.php?op=edit&amp;lid=' . $lid . '" title="' . \_AM_XOOPSTUBE_ICO_EDIT . '">' . $xtubeImageArray['editimg'] . '</a>&nbsp;';
2428
        }
2429
        $icon .= '<a href="main.php?op=delete&amp;lid=' . $lid . '" title="' . \_AM_XOOPSTUBE_ICO_DELETE . '">' . $xtubeImageArray['deleteimg'] . '</a>&nbsp;';
2430
        $icon .= '<a href="altcat.php?op=main&amp;cid=' . $cid . '&amp;lid=' . $lid . '&amp;title=' . $published['title'] . '" title="' . \_AM_XOOPSTUBE_ALTCAT_CREATEF . '">' . $xtubeImageArray['altcat'] . '</a>';
2431
2432
        echo '
2433
        <tr style="text-align: center; font-size: smaller;">
2434
        <td class="head">' . $lid . '</span></td>
2435
        <td class="even" style="text-align: left;">' . $title . '</td>
2436
        <td class="even">' . $returnsource . '</td>
2437
        <td class="even">' . $cattitle . '</td>
2438
        <td class="even">' . $submitter . '</td>
2439
        <td class="even">' . $publish . '</td>
2440
        <td class="even">' . $expires . '</td>
2441
        <td class="even" style="width: 4%;">' . $published_status . '</td>
2442
        <td class="even" style="text-align: center; width: 6%; white-space: nowrap;">' . $icon . '</td>
2443
        </tr>';
2444
        //        unset($published);
2445
    }
2446
2447
    /**
2448
     * @param        $pubrowamount
2449
     * @param        $start
2450
     * @param string $art
2451
     * @param string $_this
2452
     * @param        $align
2453
     *
2454
     * @return bool|null
2455
     */
2456
    public static function setPageNavigationCategoryList(
2457
        $pubrowamount,
2458
        $start,
2459
        $art,
2460
        $_this,
2461
        $align
2462
    ) {
2463
        if ($pubrowamount < $GLOBALS['xoopsModuleConfig']['admin_perpage']) {
2464
            return false;
2465
        }
2466
        // Display Page Nav if published is > total display pages amount.
2467
        require_once XOOPS_ROOT_PATH . '/class/pagenav.php';
2468
        $pagenav = new \XoopsPageNav($pubrowamount, $GLOBALS['xoopsModuleConfig']['admin_perpage'], $start, 'st' . $art, $_this);
2469
        echo '<div style="text-align: ' . $align . '; padding: 8px;">' . $pagenav->renderNav() . '</div>';
2470
2471
        return null;
2472
    }
2473
2474
    public static function renderCategoryListFooter()
2475
    {
2476
        echo '<tr style="text-align: center;">
2477
            <td class="head" colspan="7">' . \_AM_XOOPSTUBE_MINDEX_NOVIDEOSFOUND . '</td>
2478
          </tr>';
2479
    }
2480
2481
    /**
2482
     * @param $heading
2483
     */
2484
    public static function renderVideoListHeader($heading)
2485
    {
2486
        echo '
2487
        <h4 style="font-weight: bold; color: #0A3760;">' . $heading . '</h4>
2488
        <table width="100%" cellspacing="1" class="outer" summary>
2489
        <tr>
2490
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_ID . '</th>
2491
            <th style=" font-size: smaller;"><b>' . \_AM_XOOPSTUBE_MINDEX_TITLE . '</th>
2492
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_VIDSOURCE2 . '</th>
2493
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_CATTITLE . '</th>
2494
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_POSTER . '</th>
2495
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_PUBLISH . '</th>
2496
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_EXPIRE . '</th>
2497
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_ONLINE . '</th>
2498
            <th style="text-align: center; font-size: smaller;">' . \_AM_XOOPSTUBE_MINDEX_ACTION . '</th>
2499
        </tr>
2500
        ';
2501
    }
2502
2503
    /**
2504
     * @param $published
2505
     */
2506
    public static function renderVideoListBody($published)
2507
    {
2508
        global $xtubeImageArray, $pathIcon16;
2509
2510
        $xtubemyts = new TextSanitizer();
2511
2512
        $lid = $published['lid'];
2513
        $cid = $published['cid'];
2514
2515
        $title        = '<a href="../singlevideo.php?cid=' . $published['cid'] . '&amp;lid=' . $published['lid'] . '">' . $xtubemyts->htmlSpecialChars(\trim($published['title']), \ENT_QUOTES | \ENT_HTML5) . '</a>';
2516
        $maintitle    = \urlencode(\htmlspecialchars(\trim($published['title']), \ENT_QUOTES | \ENT_HTML5));
2517
        $cattitle     = '<a href="../viewcat.php?cid=' . $published['cid'] . '">' . self::getCategoryTitle($published['cid']) . '</a>';
2518
        $submitter    = self::getLinkedUserNameFromId($published['submitter']);
2519
        $returnsource = \xtubeReturnSource($published['vidsource']);
2520
        $submitted    = self::getTimestamp(\formatTimestamp($published['date'], $GLOBALS['xoopsModuleConfig']['dateformatadmin']));
2521
        $publish      = ($published['published'] > 0) ? self::getTimestamp(\formatTimestamp($published['published'], $GLOBALS['xoopsModuleConfig']['dateformatadmin'])) : 'Not Published';
2522
        $expires      = $published['expired'] ? self::getTimestamp(\formatTimestamp($published['expired'], $GLOBALS['xoopsModuleConfig']['dateformatadmin'])) : \_AM_XOOPSTUBE_MINDEX_NOTSET;
2523
2524
        if ((($published['expired'] && (int)$published['expired'] > \time()) || 0 === (int)$published['expired'])
2525
            && ($published['published'] && (int)$published['published'] < \time())
2526
            && 0 === (int)$published['offline']) {
2527
            $published_status = '<a href="main.php?op=toggle&amp;lid=' . $lid . '&amp;offline=' . (int)$published['offline'] . '"><img src="' . $pathIcon16 . '/1.png' . '"></a>';
2528
        } elseif (($published['expired'] && (int)$published['expired'] < \time()) && 0 === (int)$published['offline']) {
2529
            $published_status = $xtubeImageArray['expired'];
2530
        } else {
2531
            $published_status = (0 === (int)$published['published']) ? '<a href="newvideos.php">' . $xtubeImageArray['offline'] . '</a>' : '<a href="main.php?op=toggle&amp;lid=' . $lid . '&amp;offline=' . $published['offline'] . '"><img src="' . $pathIcon16 . '/0.png' . '"></a>';
2532
        }
2533
2534
        if (200 == $published['vidsource']) {
2535
            $icon = '<a href="main.php?op=edit&amp;lid=' . $lid . '" title="' . \_AM_XOOPSTUBE_ICO_EDIT . '">' . $xtubeImageArray['editimg'] . '</a>&nbsp;';
2536
        } else {
2537
            $icon = '<a href="main.php?op=edit&amp;lid=' . $lid . '" title="' . \_AM_XOOPSTUBE_ICO_EDIT . '">' . $xtubeImageArray['editimg'] . '</a>&nbsp;';
2538
        }
2539
        $icon .= '<a href="main.php?op=delete&amp;lid=' . $lid . '" title="' . \_AM_XOOPSTUBE_ICO_DELETE . '">' . $xtubeImageArray['deleteimg'] . '</a>&nbsp;';
2540
        $icon .= '<a href="altcat.php?op=main&amp;cid=' . $cid . '&amp;lid=' . $lid . '&amp;title=' . $published['title'] . '" title="' . \_AM_XOOPSTUBE_ALTCAT_CREATEF . '">' . $xtubeImageArray['altcat'] . '</a>';
2541
2542
        echo '
2543
        <tr style="text-align: center; font-size: smaller;">
2544
        <td class="head">' . $lid . '</span></td>
2545
        <td class="even" style="text-align: left;">' . $title . '</td>
2546
        <td class="even">' . $returnsource . '</td>
2547
        <td class="even">' . $cattitle . '</td>
2548
        <td class="even">' . $submitter . '</td>
2549
        <td class="even">' . $publish . '</td>
2550
        <td class="even">' . $expires . '</td>
2551
        <td class="even" style="width: 4%;">' . $published_status . '</td>
2552
        <td class="even" style="text-align: center; width: 6%; white-space: nowrap;">' . $icon . '</td>
2553
        </tr>';
2554
        //        unset($published);
2555
    }
2556
2557
    /**
2558
     * @param $catt
2559
     *
2560
     * @return mixed
2561
     */
2562
    public static function getCategoryTitle($catt)
2563
    {
2564
        $sql    = 'SELECT title FROM ' . $GLOBALS['xoopsDB']->prefix('xoopstube_cat') . ' WHERE cid=' . $catt;
2565
        $result = $GLOBALS['xoopsDB']->query($sql);
2566
        $result = $GLOBALS['xoopsDB']->fetchArray($result);
2567
2568
        return $result['title'];
2569
    }
2570
2571
    public static function renderVideoListFooter()
2572
    {
2573
        echo '<tr style="text-align: center;">
2574
            <td class="head" colspan="7">' . \_AM_XOOPSTUBE_MINDEX_NOVIDEOSFOUND . '</td>
2575
          </tr>';
2576
    }
2577
2578
    /**
2579
     * @param        $pubrowamount
2580
     * @param        $start
2581
     * @param string $art
2582
     * @param string $_this
2583
     * @param        $align
2584
     *
2585
     * @return bool|null
2586
     */
2587
    public static function setPageNavigationVideoList($pubrowamount, $start, $art, $_this, $align)
2588
    {
2589
        if ($pubrowamount < $GLOBALS['xoopsModuleConfig']['admin_perpage']) {
2590
            return false;
2591
        }
2592
        // Display Page Nav if published is > total display pages amount.
2593
        require_once XOOPS_ROOT_PATH . '/class/pagenav.php';
2594
        $pagenav = new \XoopsPageNav($pubrowamount, $GLOBALS['xoopsModuleConfig']['admin_perpage'], $start, 'st' . $art, $_this);
2595
        echo '<div style="text-align: ' . $align . '; padding: 8px;">' . $pagenav->renderNav() . '</div>';
2596
2597
        return null;
2598
    }
2599
2600
    /**
2601
     * @param $document
2602
     *
2603
     * @return array|string|string[]|null
2604
     */
2605
    public static function convertHtml2text($document)
2606
    {
2607
        // PHP Manual:: function preg_replace
2608
        // $document should contain an HTML document.
2609
        // This will remove HTML tags, javascript sections
2610
        // and white space. It will also convert some
2611
        // common HTML entities to their text equivalent.
2612
        // Credits : newbb2
2613
        $search = [
2614
            "'<script[^>]*?>.*?</script>'si", // Strip out javascript
2615
            "'<img.*?>'si", // Strip out img tags
2616
            "'<[\/\!]*?[^<>]*?>'si", // Strip out HTML tags
2617
            "'([\r\n])[\s]+'", // Strip out white space
2618
            "'&(quot|#34);'i", // Replace HTML entities
2619
            "'&(amp|#38);'i",
2620
            "'&(lt|#60);'i",
2621
            "'&(gt|#62);'i",
2622
            "'&(nbsp|#160);'i",
2623
            "'&(iexcl|#161);'i",
2624
            "'&(cent|#162);'i",
2625
            "'&(pound|#163);'i",
2626
            "'&(copy|#169);'i",
2627
        ]; // evaluate as php
2628
2629
        $replace = [
2630
            '',
2631
            '',
2632
            '',
2633
            '\\1',
2634
            '"',
2635
            '&',
2636
            '<',
2637
            '>',
2638
            ' ',
2639
            \chr(161),
2640
            \chr(162),
2641
            \chr(163),
2642
            \chr(169),
2643
        ];
2644
2645
        $text = \preg_replace($search, $replace, $document);
2646
2647
        \preg_replace_callback(
2648
            '/&#(\d+);/',
2649
            static function ($matches) {
2650
                return \chr($matches[1]);
2651
            },
2652
            $document
2653
        );
2654
2655
        return $text;
2656
    }
2657
2658
    // Check if Tag module is installed
2659
2660
    /**
2661
     * @return bool
2662
     */
2663
    public static function isModuleTagInstalled()
2664
    {
2665
        static $isModuleTagInstalled;
2666
        if (!isset($isModuleTagInstalled)) {
2667
            /** @var \XoopsModuleHandler $moduleHandler */
2668
            $moduleHandler = \xoops_getHandler('module');
2669
            $tag_mod       = $moduleHandler->getByDirname('tag');
2670
            if (!$tag_mod) {
2671
                $tag_mod = false;
2672
            } else {
2673
                $isModuleTagInstalled = 1 == $tag_mod->getVar('isactive');
2674
            }
2675
        }
2676
2677
        return $isModuleTagInstalled;
2678
    }
2679
2680
    // Add item_tag to Tag-module
2681
2682
    /**
2683
     * @param $lid
2684
     * @param $item_tag
2685
     */
2686
    public static function updateTag($lid, $item_tag)
2687
    {
2688
        global $xoopsModule;
2689
        if (self::isModuleTagInstalled()) {
2690
            require_once XOOPS_ROOT_PATH . '/modules/tag/include/formtag.php';
2691
            $tagHandler = \XoopsModules\Tag\Helper::getInstance()->getHandler('Tag'); // xoops_getModuleHandler('tag', 'tag');
2692
            $tagHandler->updateByItem($item_tag, $lid, $xoopsModule->getVar('dirname'), 0);
2693
        }
2694
    }
2695
2696
    /**
2697
     * @param $lid
2698
     */
2699
    public static function updateCounter($lid)
2700
    {
2701
        $sql    = 'UPDATE ' . $GLOBALS['xoopsDB']->prefix('xoopstube_videos') . ' SET hits=hits+1 WHERE lid=' . (int)$lid;
2702
        $result = $GLOBALS['xoopsDB']->queryF($sql);
2703
    }
2704
2705
    /**
2706
     * @param $banner_id
2707
     *
2708
     * @return null|string
2709
     */
2710
    public static function getBannerFromBannerId($banner_id)
2711
    {
2712
        ###### Hack by www.stefanosilvestrini.com ######
2713
        $db      = \XoopsDatabaseFactory::getDatabaseConnection();
2714
        $bresult = $db->query('SELECT COUNT(*) FROM ' . $db->prefix('banner') . ' WHERE bid=' . $banner_id);
2715
        [$numrows] = $db->fetchRow($bresult);
2716
        if ($numrows > 1) {
2717
            --$numrows;
2718
            try {
2719
                $bannum = \random_int(0, $numrows);
2720
            } catch (\Exception $e) {
2721
            }            
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
2722
        } else {
2723
            $bannum = 0;
2724
        }
2725
        if ($numrows > 0) {
2726
            $bresult = $db->query('SELECT * FROM ' . $db->prefix('banner') . ' WHERE bid=' . $banner_id, 1, $bannum);
2727
            [$bid, $cid, $imptotal, $impmade, $clicks, $imageurl, $clickurl, $date, $htmlbanner, $htmlcode] = $db->fetchRow($bresult);
2728
            if ($GLOBALS['xoopsConfig']['my_ip'] == \xoops_getenv('REMOTE_ADDR')) {
2729
                // EMPTY
2730
            } else {
2731
                $db->queryF(\sprintf('UPDATE `%s` SET impmade = impmade+1 WHERE bid = %u', $db->prefix('banner'), $bid));
2732
            }
2733
            /* Check if this impression is the last one and print the banner */
2734
            if ($imptotal == $impmade) {
2735
                $newid = $db->genId($db->prefix('bannerfinish') . '_bid_seq');
2736
                $sql   = \sprintf('INSERT INTO `%s` (bid, cid, impressions, clicks, datestart, dateend) VALUES (%u, %u, %u, %u, %u, %u)', $db->prefix('bannerfinish'), $newid, $cid, $impmade, $clicks, $date, \time());
2737
                $db->queryF($sql);
2738
                $db->queryF(\sprintf('DELETE FROM `%s` WHERE bid = %u', $db->prefix('banner'), $bid));
2739
            }
2740
            if ($htmlbanner) {
2741
                $bannerobject = $htmlcode;
2742
            } else {
2743
                $bannerobject = '<div align="center"><a href="' . XOOPS_URL . '/banners.php?op=click&bid=' . $bid . '" target="_blank">';
2744
                if (false !== mb_stripos($imageurl, '.swf')) {
2745
                    $bannerobject .= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="468" height="60">'
2746
                                     . '<param name="movie" value="'
2747
                                     . $imageurl
2748
                                     . '"></param>'
2749
                                     . '<param name="quality" value="high"></param>'
2750
                                     . '<embed src="'
2751
                                     . $imageurl
2752
                                     . '" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="468" height="60">'
2753
                                     . '</embed>'
2754
                                     . '</object>';
2755
                } else {
2756
                    $bannerobject .= '<img src="' . $imageurl . '" alt="">';
2757
                }
2758
                $bannerobject .= '</a></div>';
2759
            }
2760
2761
            return $bannerobject;
2762
        }
2763
2764
        return null;
2765
    }
2766
2767
    /**
2768
     * @param $client_id
2769
     *
2770
     * @return null|string
2771
     */
2772
    public static function getBannerFromClientId($client_id)
2773
    {
2774
        ###### Hack by www.stefanosilvestrini.com ######
2775
        $db      = \XoopsDatabaseFactory::getDatabaseConnection();
2776
        $bresult = $db->query('SELECT COUNT(*) FROM ' . $db->prefix('banner') . ' WHERE cid=' . $client_id);
2777
        [$numrows] = $db->fetchRow($bresult);
2778
        if ($numrows > 1) {
2779
            --$numrows;
2780
            try {
2781
                $bannum = \random_int(0, $numrows);
2782
            } catch (\Exception $e) {
2783
            }
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
2784
        } else {
2785
            $bannum = 0;
2786
        }
2787
        if ($numrows > 0) {
2788
            $bresult = $db->query('SELECT * FROM ' . $db->prefix('banner') . ' WHERE cid=' . $client_id . ' ORDER BY rand()', 1, $bannum);
2789
            [$bid, $cid, $imptotal, $impmade, $clicks, $imageurl, $clickurl, $date, $htmlbanner, $htmlcode] = $db->fetchRow($bresult);
2790
            if ($GLOBALS['xoopsConfig']['my_ip'] == \xoops_getenv('REMOTE_ADDR')) {
2791
                // EMPTY
2792
            } else {
2793
                $db->queryF(\sprintf('UPDATE `%s` SET impmade = impmade+1 WHERE bid = %u', $db->prefix('banner'), $bid));
2794
            }
2795
            /* Check if this impression is the last one and print the banner */
2796
            if ($imptotal == $impmade) {
2797
                $newid = $db->genId($db->prefix('bannerfinish') . '_bid_seq');
2798
                $sql   = \sprintf('INSERT INTO `%s` (bid, cid, impressions, clicks, datestart, dateend) VALUES (%u, %u, %u, %u, %u, %u)', $db->prefix('bannerfinish'), $newid, $cid, $impmade, $clicks, $date, \time());
2799
                $db->queryF($sql);
2800
                $db->queryF(\sprintf('DELETE FROM `%s` WHERE bid = %u', $db->prefix('banner'), $bid));
2801
            }
2802
            if ($htmlbanner) {
2803
                $bannerobject = $htmlcode;
2804
            } else {
2805
                $bannerobject = '<div align="center"><a href="' . XOOPS_URL . '/banners.php?op=click&bid=' . $bid . '" target="_blank">';
2806
                if (false !== mb_stripos($imageurl, '.swf')) {
2807
                    $bannerobject .= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="468" height="60">'
2808
                                     . '<param name="movie" value="'
2809
                                     . $imageurl
2810
                                     . '"></param>'
2811
                                     . '<param name="quality" value="high"></param>'
2812
                                     . '<embed src="'
2813
                                     . $imageurl
2814
                                     . '" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="468" height="60">'
2815
                                     . '</embed>'
2816
                                     . '</object>';
2817
                } else {
2818
                    $bannerobject .= '<img src="' . $imageurl . '" alt="">';
2819
                }
2820
                $bannerobject .= '</a></div>';
2821
            }
2822
2823
            return $bannerobject;
2824
        }
2825
2826
        return null;
2827
    }
2828
2829
    public static function setNoIndexNoFollow()
2830
    {
2831
        global $xoopsTpl;
2832
        if (\is_object($GLOBALS['xoTheme'])) {
2833
            $GLOBALS['xoTheme']->addMeta('meta', 'robots', 'noindex,nofollow');
2834
        } else {
2835
            $xoopsTpl->assign('xoops_meta_robots', 'noindex,nofollow');
2836
        }
2837
    }
2838
2839
    /**
2840
     * @param $userid
2841
     *
2842
     * @return string
2843
     */
2844
    public static function getLinkedUserNameFromId($userid)
2845
    {
2846
        $userid = (int)$userid;
2847
        if ($userid > 0) {
2848
            /** @var \XoopsMemberHandler $memberHandler */
2849
            $memberHandler = \xoops_getHandler('member');
2850
            $user          = $memberHandler->getUser($userid);
2851
            if (\is_object($user)) {
2852
                $linkeduser = '<a href="' . XOOPS_URL . '/userinfo.php?uid=' . $userid . '">' . $user->getVar('uname') . '</a>';
2853
2854
                return $linkeduser;
2855
            }
2856
        }
2857
2858
        return $GLOBALS['xoopsConfig']['anonymous'];
2859
    }
2860
2861
    /**
2862
     * @param $time
2863
     *
2864
     * @return string
2865
     */
2866
    public static function getTimestamp($time)
2867
    {
2868
        $moduleDirName = \basename(\dirname(__DIR__));
2869
        \xoops_loadLanguage('local', $moduleDirName);
2870
2871
        $trans     = [
2872
            'Monday'    => \_XOOPSTUBE_MONDAY,
2873
            'Tuesday'   => \_XOOPSTUBE_TUESDAY,
2874
            'Wednesday' => \_XOOPSTUBE_WEDNESDAY,
2875
            'Thursday'  => \_XOOPSTUBE_THURSDAY,
2876
            'Friday'    => \_XOOPSTUBE_FRIDAY,
2877
            'Saturday'  => \_XOOPSTUBE_SATURDAY,
2878
            'Sunday'    => \_XOOPSTUBE_SUNDAY,
2879
            'Mon'       => \_XOOPSTUBE_MON,
2880
            'Tue'       => \_XOOPSTUBE_TUE,
2881
            'Wed'       => \_XOOPSTUBE_WED,
2882
            'Thu'       => \_XOOPSTUBE_THU,
2883
            'Fri'       => \_XOOPSTUBE_FRI,
2884
            'Sat'       => \_XOOPSTUBE_SAT,
2885
            'Sun'       => \_XOOPSTUBE_SUN,
2886
            'January'   => \_XOOPSTUBE_JANUARI,
2887
            'February'  => \_XOOPSTUBE_FEBRUARI,
2888
            'March'     => \_XOOPSTUBE_MARCH,
2889
            'April'     => \_XOOPSTUBE_APRIL,
2890
            'May'       => \_XOOPSTUBE_MAY,
2891
            'June'      => \_XOOPSTUBE_JUNE,
2892
            'July'      => \_XOOPSTUBE_JULY,
2893
            'August'    => \_XOOPSTUBE_AUGUST,
2894
            'September' => \_XOOPSTUBE_SEPTEMBER,
2895
            'October'   => \_XOOPSTUBE_OCTOBER,
2896
            'November'  => \_XOOPSTUBE_NOVEMBER,
2897
            'December'  => \_XOOPSTUBE_DECEMBER,
2898
            'Jan'       => \_XOOPSTUBE_JAN,
2899
            'Feb'       => \_XOOPSTUBE_FEB,
2900
            'Mar'       => \_XOOPSTUBE_MAR,
2901
            'Apr'       => \_XOOPSTUBE_APR,
2902
            //        'May'       => _XOOPSTUBE_MAY2,
2903
            'Jun'       => \_XOOPSTUBE_JUN,
2904
            'Jul'       => \_XOOPSTUBE_JUL,
2905
            'Aug'       => \_XOOPSTUBE_AUG,
2906
            'Sep'       => \_XOOPSTUBE_SEP,
2907
            'Oct'       => \_XOOPSTUBE_OCT,
2908
            'Nov'       => \_XOOPSTUBE_NOV,
2909
            'Dec'       => \_XOOPSTUBE_DEC,
2910
        ];
2911
        $timestamp = strtr($time, $trans);
2912
2913
        return $timestamp;
2914
    }
2915
2916
    /**
2917
     * Do some basic file checks and stuff.
2918
     * Author: Andrew Mills  Email:  [email protected]
2919
     * from amReviews module
2920
     */
2921
    public static function fileChecks()
2922
    {
2923
        echo '<fieldset>';
2924
        echo '<legend style="color: #990000; font-weight: bold;">' . \_AM_XOOPSTUBE_FILECHECKS . '</legend>';
2925
2926
        $dirPhotos      = XOOPS_ROOT_PATH . '/' . $GLOBALS['xoopsModuleConfig']['catimage'];
2927
        $dirVideos      = XOOPS_ROOT_PATH . '/' . $GLOBALS['xoopsModuleConfig']['videodir'];
2928
        $dirScreenshots = XOOPS_ROOT_PATH . '/' . $GLOBALS['xoopsModuleConfig']['videoimgdir'];
2929
2930
        if (\file_exists($dirPhotos)) {
2931
            if (!\is_writable($dirPhotos)) {
2932
                echo '<span style=" color: red; font-weight: bold;">Warning:</span> ' . \_AM_XOOPSTUBE_UNABLE_TO_WRITE . $dirPhotos . '<br>';
2933
            } else {
2934
                echo '<span style=" color: green; font-weight: bold;">OK:</span> ' . $dirPhotos . '<br>';
2935
            }
2936
        } else {
2937
            echo '<span style=" color: red; font-weight: bold;">' . \_AM_XOOPSTUBE_WARNING . '</span> ' . $dirPhotos . ' <span style=" color: red; ">' . \_AM_XOOPSTUBE_NOT_EXISTS . '</span> <br>';
2938
        }
2939
        // photothumbdir
2940
        if (\file_exists($dirVideos)) {
2941
            if (!\is_writable($dirVideos)) {
2942
                echo '<span style=" color: red; font-weight: bold;">' . \_AM_XOOPSTUBE_WARNING . '</span> ' . \_AM_XOOPSTUBE_UNABLE_TO_WRITE . $dirVideos . '<br>';
2943
            } else {
2944
                echo '<span style=" color: green; font-weight: bold;">OK:</span> ' . $dirVideos . '<br>';
2945
            }
2946
        } else {
2947
            echo '<span style=" color: red; font-weight: bold;">' . \_AM_XOOPSTUBE_WARNING . '</span> ' . $dirVideos . ' <span style=" color: red; ">' . \_AM_XOOPSTUBE_NOT_EXISTS . '</span> <br>';
2948
        }
2949
        // photohighdir
2950
        if (\file_exists($dirScreenshots)) {
2951
            if (!\is_writable($dirScreenshots)) {
2952
                echo '<span style=" color: red; font-weight: bold;">Warning:</span> ' . \_AM_XOOPSTUBE_UNABLE_TO_WRITE . $dirScreenshots . '<br>';
2953
            } else {
2954
                echo '<span style=" color: green; font-weight: bold;">OK:</span> ' . $dirScreenshots . '<br>';
2955
            }
2956
        } else {
2957
            echo '<span style=" color: red; font-weight: bold;">' . \_AM_XOOPSTUBE_WARNING . '</span> ' . $dirScreenshots . ' <span style=" color: red; ">' . \_AM_XOOPSTUBE_NOT_EXISTS . '</span> <br>';
2958
        }
2959
2960
        /**
2961
         * Some info.
2962
         */
2963
        $uploads = \ini_get('file_uploads') ? \_AM_XOOPSTUBE_UPLOAD_ON : \_AM_XOOPSTUBE_UPLOAD_OFF;
2964
        echo '<br>';
2965
        echo '<ul>';
2966
        echo '<li>' . \_AM_XOOPSTUBE_UPLOADMAX . '<b>' . \ini_get('upload_max_filesize') . '</b></li>';
2967
        echo '<li>' . \_AM_XOOPSTUBE_POSTMAX . '<b>' . \ini_get('post_max_size') . '</b></li>';
2968
        echo '<li>' . \_AM_XOOPSTUBE_UPLOADS . '<b>' . $uploads . '</b></li>';
2969
2970
        $gdinfo = gd_info();
2971
        if (\function_exists('gd_info')) {
2972
            echo '<li>' . \_AM_XOOPSTUBE_GDIMGSPPRT . '<b>' . \_AM_XOOPSTUBE_GDIMGON . '</b></li>';
2973
            echo '<li>' . \_AM_XOOPSTUBE_GDIMGVRSN . '<b>' . $gdinfo['GD Version'] . '</b></li>';
2974
        } else {
2975
            echo '<li>' . \_AM_XOOPSTUBE_GDIMGSPPRT . '<b>' . \_AM_XOOPSTUBE_GDIMGOFF . '</b></li>';
2976
        }
2977
        echo '</ul>';
2978
2979
        //$inithingy = ini_get_all();
2980
        //print_r($inithingy);
2981
2982
        echo '</fieldset>';
2983
    }
2984
2985
    /**
2986
     * @param      $path
2987
     * @param int  $mode
2988
     * @param      $fileSource
2989
     * @param null $fileTarget
2990
     */
2991
    public static function createDirectory($path, $mode, $fileSource, $fileTarget = null)
2992
    {
2993
        if (!\is_dir($path)) {
2994
            if (!\mkdir($path, $mode) && !\is_dir($path)) {
2995
                throw new \RuntimeException(\sprintf('Directory "%s" was not created', $path));
2996
            }
2997
            file_put_contents($path . '/index.html', '<script>history.go(-1);</script>');
2998
            if (!empty($fileSource) && !empty($fileTarget)) {
2999
                @\copy($fileSource, $fileTarget);
3000
            }
3001
        }
3002
        \chmod($path, $mode);
3003
    }
3004
3005
    /**
3006
     * @return string
3007
     */
3008
    public static function getLetters()
3009
    {
3010
        global $xoopsModule;
3011
3012
        $letterchoice          = '<div>' . \_MD_XOOPSTUBE_BROWSETOTOPIC . '</div>';
3013
        $alphabet              = \getXtubeAlphabet();
3014
        $num                   = \count($alphabet) - 1;
3015
        $counter               = 0;
3016
        $distinctDbLetters_arr = [];
3017
        $sql                   = 'SELECT DISTINCT (UPPER(LEFT(title, 1))) AS letter FROM ' . $GLOBALS['xoopsDB']->prefix('xoopstube_videos WHERE expired = 0 AND offline = 0');
3018
        $result                = $GLOBALS['xoopsDB']->query($sql);
3019
        if ($result) {
3020
            while (false !== ($row = $GLOBALS['xoopsDB']->fetchArray($result))) {
3021
                $distinctDbLetters_arr[] = $row['letter'];
3022
            }
3023
        }
3024
        unset($sql);
3025
3026
        //        while (list(, $ltr) = each($alphabet)) {
3027
        foreach ($alphabet as $key => $ltr) {
3028
            if (\in_array($ltr, $distinctDbLetters_arr)) {
3029
                $letterchoice .= '<a class="xoopstube_letters xoopstube_letters_green" href="';
3030
            } else {
3031
                $letterchoice .= '<a class="xoopstube_letters" href="';
3032
            }
3033
            $letterchoice .= XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . '/viewcat.php?letter=' . $ltr . '">' . $ltr . '</a>';
3034
            if ($counter == \round($num / 2)) {
3035
                $letterchoice .= '<br>';
3036
            } elseif ($counter !== $num) {
3037
                $letterchoice .= '&nbsp;';
3038
            }
3039
            ++$counter;
3040
        }
3041
3042
        return $letterchoice;
3043
    }
3044
3045
    /**
3046
     * @return mixed|string
3047
     */
3048
    public static function getLettersChoice()
3049
    {
3050
        global $xoopsModule;
3051
3052
        $moduleDirName = $xoopsModule->getVar('dirname');
3053
//        require_once XOOPS_ROOT_PATH . "/modules/$moduleDirName/class/$moduleDirName.php";
3054
        $helper = Helper::getInstance();
3055
3056
        $a             = $helper->getHandler('Videos');
3057
        $b             = $a->getActiveCriteria();
3058
        $moduleDirName = \basename(\dirname(__DIR__));
3059
3060
        $criteria = $helper->getHandler('Videos')->getActiveCriteria();
3061
        $criteria->setGroupby('UPPER(LEFT(title,1))');
3062
        $countsByLetters = $helper->getHandler($moduleDirName)->getCounts($criteria);
3063
        // Fill alphabet array
3064
        $alphabet       = \getXtubeAlphabet();
3065
        $alphabet_array = [];
3066
        foreach ($alphabet as $letter) {
3067
            $letter_array = [];
3068
            if (isset($countsByLetters[$letter])) {
3069
                $letter_array['letter'] = $letter;
3070
                $letter_array['count']  = $countsByLetters[$letter];
3071
                $letter_array['url']    = '' . XOOPS_URL . "/modules/$moduleDirName/viewcat.php?letter={$letter}";
3072
            } else {
3073
                $letter_array['letter'] = $letter;
3074
                $letter_array['count']  = 0;
3075
                $letter_array['url']    = '';
3076
            }
3077
            $alphabet_array[$letter] = $letter_array;
3078
            unset($letter_array);
3079
        }
3080
        // Render output
3081
        if (!isset($GLOBALS['xoTheme']) || !\is_object($GLOBALS['xoTheme'])) {
3082
            require_once $GLOBALS['xoops']->path('class/theme.php');
3083
            $GLOBALS['xoTheme'] = new \xos_opal_Theme();
3084
        }
3085
        require_once $GLOBALS['xoops']->path('class/template.php');
3086
        $letterschoiceTpl          = new \XoopsTpl();
3087
        $letterschoiceTpl->caching = 0; // Disable cache
3088
        $letterschoiceTpl->assign('alphabet', $alphabet_array);
3089
        $html = $letterschoiceTpl->fetch('db:' . $helper->getModule()->dirname() . '_common_letterschoice.tpl');
3090
        unset($letterschoiceTpl);
3091
3092
        return $html;
3093
    }
3094
3095
    /**
3096
     * Recursively sort categories by level and weight
3097
     *
3098
     * @param int $pid
3099
     * @param int $level
3100
     *
3101
     * @return array array of arrays: 'pid', 'cid', 'level', 'category' as array
3102
     *
3103
     * @access  public
3104
     * @author  luciorota
3105
     */
3106
    public static function sortCategories($pid = 0, $level = 0)
3107
    {
3108
        $helper = Helper::getInstance();
3109
3110
        $sorted   = [];
3111
        $criteria = new \CriteriaCompo();
3112
        $criteria->add(new \Criteria('pid', $pid));
3113
        $criteria->setSort('weight');
3114
        $criteria->setOrder('ASC');
3115
        $subCategoryObjs = $helper->getHandler('Category')->getObjects($criteria);
3116
        if (\count($subCategoryObjs) > 0) {
3117
            ++$level;
3118
            foreach ($subCategoryObjs as $subCategoryObj) {
3119
                $pid      = $subCategoryObj->getVar('pid');
3120
                $cid      = $subCategoryObj->getVar('cid');
3121
                $sorted[] = ['pid' => $pid, 'cid' => $cid, 'level' => $level, 'category' => $subCategoryObj->toArray()];
3122
                if (false !== ($subSorted = self::sortCategories($cid, $level))) {
3123
                    $sorted = \array_merge($sorted, $subSorted);
3124
                }
3125
            }
3126
        }
3127
3128
        return $sorted;
3129
    }
3130
3131
    /**
3132
     * Create download by letter choice bar/menu
3133
     * updated starting from this idea https://xoops.org/modules/news/article.php?storyid=6497
3134
     *
3135
     * @return string html
3136
     *
3137
     * @access  public
3138
     * @author  luciorota
3139
     */
3140
    //    public static function lettersChoice()
3141
    //    {
3142
    //        /** @var Helper $helper */
3143
    //        $helper = Helper::getInstance();
3144
    //
3145
    //        $criteria = $helper->getHandler('Videos')->getActiveCriteria();
3146
    //        $criteria->setGroupby('UPPER(LEFT(title,1))');
3147
    //        $countsByLetters = $helper->getHandler('Videos')->getCounts($criteria);
3148
    //        // Fill alphabet array
3149
    //        $alphabet       = getLocalAlphabet();
3150
    //        $alphabetArray = [];
3151
    //        foreach ($alphabet as $letter) {
3152
    //            $letter_array = [];
3153
    //            if (isset($countsByLetters[$letter])) {
3154
    //                $letter_array['letter'] = $letter;
3155
    //                $letter_array['count']  = $countsByLetters[$letter];
3156
    //                $letter_array['url']    = XOOPS_URL . "/modules/{$helper->getModule()->dirname()}/viewcat.php?list={$letter}";
3157
    //            } else {
3158
    //                $letter_array['letter'] = $letter;
3159
    //                $letter_array['count']  = 0;
3160
    //                $letter_array['url']    = '';
3161
    //            }
3162
    //            $alphabetArray[$letter] = $letter_array;
3163
    //            unset($letter_array);
3164
    //        }
3165
    //        // Render output
3166
    //        if (!isset($GLOBALS['xoTheme']) || !is_object($GLOBALS['xoTheme'])) {
3167
    //            require_once $GLOBALS['xoops']->path('/class/theme.php');
3168
    //            $GLOBALS['xoTheme'] = new \xos_opal_Theme();
3169
    //        }
3170
    //        require_once $GLOBALS['xoops']->path('class/template.php');
3171
    //        $letterschoiceTpl          = new \XoopsTpl();
3172
    //        $letterschoiceTpl->caching = false; // Disable cache
3173
    //        $letterschoiceTpl->assign('alphabet', $alphabetArray);
3174
    //        $html = $letterschoiceTpl->fetch("db:{$helper->getModule()->dirname()}_common_letterschoice.tpl");
3175
    //        unset($letterschoiceTpl);
3176
    //
3177
    //        return $html;
3178
    //    }
3179
3180
    //===============  from WF-Downloads   ======================================
3181
3182
    /**
3183
     * @return bool
3184
     */
3185
    public static function isUserAdmin()
3186
    {
3187
        $helper = Helper::getInstance();
3188
3189
        static $xtubeIsAdmin;
3190
3191
        if (isset($xtubeIsAdmin)) {
3192
            return $xtubeIsAdmin;
3193
        }
3194
3195
        if (!$GLOBALS['xoopsUser']) {
3196
            $xtubeIsAdmin = false;
3197
        } else {
3198
            $xtubeIsAdmin = $GLOBALS['xoopsUser']->isAdmin($helper->getModule()->getVar('mid'));
3199
        }
3200
3201
        return $xtubeIsAdmin;
3202
    }
3203
3204
    //from Lexikon
3205
3206
    /**
3207
     * @return int
3208
     */
3209
    public static function countCats()
3210
    {
3211
        global $xoopsUser, $xoopsModule;
3212
        $grouppermHandler = \xoops_getHandler('groupperm');
3213
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
3214
        $totalcats        = $grouppermHandler->getItemIds('lexikon_view', $groups, $xoopsModule->getVar('mid'));
3215
3216
        return \count($totalcats);
3217
    }
3218
3219
    /**
3220
     * @return mixed
3221
     */
3222
    public static function countWords()
3223
    {
3224
        global $xoopsUser, $xoopsDB;
3225
        $grouppermHandler = \xoops_getHandler('groupperm');
3226
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
3227
        /** @var \XoopsModuleHandler $moduleHandler */
3228
        $moduleHandler = \xoops_getHandler('module');
3229
        $module        = $moduleHandler->getByDirname('lexikon');
3230
        $module_id     = $module->getVar('mid');
3231
        $allowed_cats  = $grouppermHandler->getItemIds('lexikon_view', $groups, $module_id);
3232
        $catids        = \implode(',', $allowed_cats);
3233
        $catperms      = " AND categoryID IN ($catids) ";
3234
3235
        $pubwords       = $xoopsDB->query('SELECT * FROM ' . $xoopsDB->prefix('lxentries') . " WHERE submit = '0' AND offline ='0' AND request = '0' " . $catperms . ' ');
3236
        $publishedwords = $xoopsDB->getRowsNum($pubwords);
3237
3238
        return $publishedwords;
3239
    }
3240
3241
    /**
3242
     * @return array
3243
     */
3244
    public static function getCategoryArray()
3245
    {
3246
        global $xoopsDB, $xoopsUser, $xoopsModule;
3247
        $helper           = Helper::getInstance();
3248
        $myts             = \MyTextSanitizer::getInstance();
3249
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
3250
        $grouppermHandler = \xoops_getHandler('groupperm');
3251
        $block0           = [];
3252
        $count            = 1;
3253
        $resultcat        = $xoopsDB->query('SELECT categoryID, name, total, logourl FROM ' . $xoopsDB->prefix('lxcategories') . ' ORDER BY weight ASC');
3254
        while (list($catID, $name, $total, $logourl) = $xoopsDB->fetchRow($resultcat)) {
3255
            if ($grouppermHandler->checkRight('lexikon_view', $catID, $groups, $xoopsModule->getVar('mid'))) {
3256
                $catlinks = [];
3257
                ++$count;
3258
                if ($logourl && 'https://' !== $logourl) {
3259
                    $logourl = \htmlspecialchars($logourl, \ENT_QUOTES | \ENT_HTML5);
3260
                } else {
3261
                    $logourl = '';
3262
                }
3263
                $xoopsModule          = \XoopsModule::getByDirname('lexikon');
3264
                $catlinks['id']       = (int)$catID;
3265
                $catlinks['total']    = (int)$total;
3266
                $catlinks['linktext'] = \htmlspecialchars($name, \ENT_QUOTES | \ENT_HTML5);
3267
                $catlinks['image']    = $logourl;
3268
                $catlinks['count']    = $count;
3269
3270
                $block0['categories'][] = $catlinks;
3271
            }
3272
        }
3273
3274
        return $block0;
3275
    }
3276
3277
    /**
3278
     * @return array
3279
     */
3280
    public static function getAlphaArray()
3281
    {
3282
        global $xoopsUser, $xoopsDB, $xoopsModule;
3283
        $grouppermHandler = \xoops_getHandler('groupperm');
3284
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
3285
        /** @var \XoopsModuleHandler $moduleHandler */
3286
        $moduleHandler = \xoops_getHandler('module');
3287
        $module        = $moduleHandler->getByDirname('lexikon');
3288
        $module_id     = $module->getVar('mid');
3289
        $allowed_cats  = $grouppermHandler->getItemIds('lexikon_view', $groups, $module_id);
3290
        $catids        = \implode(',', $allowed_cats);
3291
        $catperms      = " AND categoryID IN ($catids) ";
3292
        $alpha         = [];
3293
        /**
3294
         * @param $a
3295
         * @return null|string|string[]
3296
         */
3297
        function unichr($a)
3298
        {
3299
            return mb_convert_encoding(\pack('N', $a), mb_internal_encoding(), 'UCS-4BE');
3300
        }
3301
3302
        for ($a = 48; $a < (48 + 10); ++$a) {
3303
            $letterlinks             = [];
3304
            $initial                 = unichr($a);
3305
            $sql                     = $xoopsDB->query('SELECT entryID FROM ' . $xoopsDB->prefix('lxentries') . " WHERE init = '$initial' AND submit = '0' AND offline ='0' AND request = '0' " . $catperms . ' ');
3306
            $howmany                 = $xoopsDB->getRowsNum($sql);
3307
            $letterlinks['total']    = $howmany;
3308
            $letterlinks['id']       = unichr($a);
3309
            $letterlinks['linktext'] = unichr($a);
3310
3311
            $alpha['initial'][] = $letterlinks;
3312
        }
3313
        for ($a = 65; $a < (65 + 26); ++$a) {
3314
            $letterlinks             = [];
3315
            $initial                 = unichr($a);
3316
            $sql                     = $xoopsDB->query('SELECT entryID FROM ' . $xoopsDB->prefix('lxentries') . " WHERE init = '$initial' AND submit = '0' AND offline ='0' AND request = '0' " . $catperms . ' ');
3317
            $howmany                 = $xoopsDB->getRowsNum($sql);
3318
            $letterlinks['total']    = $howmany;
3319
            $letterlinks['id']       = unichr($a);
3320
            $letterlinks['linktext'] = unichr($a);
3321
3322
            $alpha['initial'][] = $letterlinks;
3323
        }
3324
        /*for ($a = 1040; $a < (1040 + 32); ++$a) {
3325
            $letterlinks             = [];
3326
            $initial                 = unichr($a);
3327
            $sql                     = $xoopsDB->query('SELECT entryID FROM '
3328
                                                           . $xoopsDB->prefix('lxentries')
3329
                                                           . " WHERE init = '$initial' AND submit = '0' AND offline ='0' AND request = '0' "
3330
                                                           . $catperms
3331
                                                           . '');
3332
            $howmany                 = $xoopsDB->getRowsNum($sql);
3333
            $letterlinks['total']    = $howmany;
3334
            $letterlinks['id']       = unichr($a);
3335
            $letterlinks['linktext'] = unichr($a);
3336
            $alpha['initial'][] = $letterlinks;
3337
        }*/
3338
3339
        return $alpha;
3340
    }
3341
3342
    /**
3343
     * chr() with unicode support
3344
     * I found this on this site https://en.php.net/chr
3345
     * don't take credit for this.
3346
     * @param $initials
3347
     * @return string
3348
     */
3349
    public static function getUchr($initials)
3350
    {
3351
        if (\is_scalar($initials)) {
3352
            $initials = \func_get_args();
3353
        }
3354
        $str = '';
3355
        foreach ($initials as $init) {
3356
            $str .= \html_entity_decode('&#' . $init . ';', \ENT_NOQUOTES, 'UTF-8');
3357
        }
3358
3359
        return $str;
3360
    }
3361
}
3362