Passed
Push — master ( 3a2152...658ebb )
by Goffy
04:30 queued 12s
created

Utility::calculateTotals()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 9
nc 6
nop 0
dl 0
loc 12
rs 9.9666
c 1
b 0
f 0
1
<?php
2
3
namespace XoopsModules\Lexikon;
4
5
/*
6
 * You may not change or alter any portion of this comment or credits
7
 * of supporting developers from this source code or any supporting source code
8
 * which is considered copyrighted (c) material of the original comment or credit authors.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/**
16
 * @copyright    XOOPS Project (https://xoops.org)
17
 * @license      GNU GPL 2 or later (https://www.gnu.org/licenses/gpl-2.0.html)
18
 * @author      XOOPS Development Team, hsalazar
19
 */
20
21
use Xmf\Module\Admin;
22
use Xmf\Request;
23
24
/** @var Helper $helper */
25
use XoopsModules\Lexikon\Common;
26
27
/**
28
 * Class Utility
29
 */
30
class Utility extends Common\SysUtility
31
{
32
    //--------------- Custom module methods -----------------------------
33
    /**
34
     * static::getLinkedUnameFromId()
35
     *
36
     * @param int $userid Userid of author etc
37
     * @param int $name   :  0 Use Usenamer 1 Use realname
38
     * @return string
39
     */
40
    public static function getLinkedUnameFromId($userid = 0, $name = 0)
41
    {
42
        if (!\is_numeric($userid)) {
0 ignored issues
show
introduced by
The condition is_numeric($userid) is always true.
Loading history...
43
            return $userid;
44
        }
45
46
        $userid = (int)$userid;
47
        if ($userid > 0) {
48
            /** @var \XoopsMemberHandler $memberHandler */
49
            $memberHandler = \xoops_getHandler('member');
50
            $user          = $memberHandler->getUser($userid);
51
52
            if (\is_object($user)) {
53
                $ts        = \MyTextSanitizer::getInstance();
54
                $username  = $user->getVar('uname');
55
                $usernameu = $user->getVar('name');
56
57
                if ($name && !empty($usernameu)) {
58
                    $username = $user->getVar('name');
59
                }
60
                if (!empty($usernameu)) {
61
                    $linkeduser = "$usernameu [<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $userid . "'>" . $ts->htmlSpecialChars($username) . '</a>]';
0 ignored issues
show
Bug introduced by
It seems like $username can also be of type array and array; however, parameter $text of MyTextSanitizer::htmlSpecialChars() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

61
                    $linkeduser = "$usernameu [<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $userid . "'>" . $ts->htmlSpecialChars(/** @scrutinizer ignore-type */ $username) . '</a>]';
Loading history...
62
                } else {
63
                    $linkeduser = "<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $userid . "'>" . \ucfirst($ts->htmlSpecialChars($username)) . '</a>';
64
                }
65
66
                return $linkeduser;
67
            }
68
        }
69
70
        return $GLOBALS['xoopsConfig']['anonymous'];
71
    }
72
73
    /**
74
     * @param $user
75
     */
76
    public static function getUserForm($user)
77
    {
78
        global $xoopsDB, $xoopsConfig;
79
80
        echo "<select name='author'>";
81
        echo "<option value='-1'>------</option>";
82
        $result = $xoopsDB->query('SELECT uid, uname FROM ' . $xoopsDB->prefix('users') . ' ORDER BY uname');
83
84
        while (list($uid, $uname) = $xoopsDB->fetchRow($result)) {
85
            if ($uid == $user) {
86
                $opt_selected = 'selected';
87
            } else {
88
                $opt_selected = '';
89
            }
90
            echo "<option value='" . $uid . "' $opt_selected>" . $uname . '</option>';
91
        }
92
        echo '</select></div>';
93
    }
94
95
    /**
96
     *
97
     */
98
    public static function calculateTotals()
99
    {
100
        global $xoopsUser, $xoopsDB, $xoopsModule;
101
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
102
        $grouppermHandler = \xoops_getHandler('groupperm');
103
104
        $result01 = $xoopsDB->query('SELECT categoryID, total FROM ' . $xoopsDB->prefix('lxcategories') . ' ');
105
        [$totalcategories] = $xoopsDB->getRowsNum($result01);
0 ignored issues
show
Comprehensibility Best Practice introduced by
This list assign is not used and could be removed.
Loading history...
106
        while (list($categoryID, $total) = $xoopsDB->fetchRow($result01)) {
107
            if ($grouppermHandler->checkRight('lexikon_view', $categoryID, $groups, $xoopsModule->getVar('mid'))) {
0 ignored issues
show
Bug introduced by
The method checkRight() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsGroupPermHandler or XoopsPersistableObjectHandler. ( Ignorable by Annotation )

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

107
            if ($grouppermHandler->/** @scrutinizer ignore-call */ checkRight('lexikon_view', $categoryID, $groups, $xoopsModule->getVar('mid'))) {
Loading history...
108
                $newcount = self::countByCategory($categoryID);
109
                $xoopsDB->queryF('UPDATE ' . $xoopsDB->prefix('lxcategories') . " SET total = '$newcount' WHERE categoryID = '$categoryID'");
110
            }
111
        }
112
    }
113
114
    /**
115
     * @param $c
116
     * @return int
117
     */
118
    public static function countByCategory($c)
119
    {
120
        global $xoopsUser, $xoopsDB, $xoopsModule;
121
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
0 ignored issues
show
Unused Code introduced by
The assignment to $groups is dead and can be removed.
Loading history...
122
        $grouppermHandler = \xoops_getHandler('groupperm');
0 ignored issues
show
Unused Code introduced by
The assignment to $grouppermHandler is dead and can be removed.
Loading history...
123
        $count            = 0;
124
        $sql              = $xoopsDB->query('SELECT entryID FROM ' . $xoopsDB->prefix('lxentries') . " WHERE offline = '0' AND categoryID = '$c'");
125
        while (false !== ($myrow = $xoopsDB->fetchArray($sql))) {
0 ignored issues
show
Unused Code introduced by
The assignment to $myrow is dead and can be removed.
Loading history...
126
            ++$count;
127
        }
128
129
        return $count;
130
    }
131
132
    /**
133
     * @return int
134
     */
135
    public static function countCats()
136
    {
137
        global $xoopsUser, $xoopsModule;
138
        $grouppermHandler = \xoops_getHandler('groupperm');
139
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
140
        $totalcats        = $grouppermHandler->getItemIds('lexikon_view', $groups, $xoopsModule->getVar('mid'));
0 ignored issues
show
Bug introduced by
The method getItemIds() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsGroupPermHandler or XoopsPersistableObjectHandler. ( Ignorable by Annotation )

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

140
        /** @scrutinizer ignore-call */ 
141
        $totalcats        = $grouppermHandler->getItemIds('lexikon_view', $groups, $xoopsModule->getVar('mid'));
Loading history...
141
142
        return \count($totalcats);
143
    }
144
145
    /**
146
     * @return mixed
147
     */
148
    public static function countWords()
149
    {
150
        global $xoopsUser, $xoopsDB;
151
        $grouppermHandler = \xoops_getHandler('groupperm');
152
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
153
        /** @var \XoopsModuleHandler $moduleHandler */
154
        $moduleHandler = \xoops_getHandler('module');
155
        $module        = $moduleHandler->getByDirname('lexikon');
156
        $module_id     = $module->getVar('mid');
157
        $allowed_cats  = $grouppermHandler->getItemIds('lexikon_view', $groups, $module_id);
158
        $catids        = \implode(',', $allowed_cats);
159
        $catperms      = " AND categoryID IN ($catids) ";
160
161
        $pubwords       = $xoopsDB->query('SELECT * FROM ' . $xoopsDB->prefix('lxentries') . " WHERE submit = '0' AND offline ='0' AND request = '0' " . $catperms . ' ');
162
        $publishedwords = $xoopsDB->getRowsNum($pubwords);
163
164
        return $publishedwords;
165
    }
166
167
    // To display the list of categories
168
169
    /**
170
     * @return array
171
     */
172
    public static function getCategoryArray()
173
    {
174
        global $xoopsDB, $xoopsUser, $xoopsModule;
175
176
        $helper           = Helper::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $helper is dead and can be removed.
Loading history...
177
        $myts             = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
178
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
179
        $grouppermHandler = \xoops_getHandler('groupperm');
180
        $block0           = [];
181
        $count            = 1;
182
        $resultcat        = $xoopsDB->query('SELECT categoryID, name, total, logourl FROM ' . $xoopsDB->prefix('lxcategories') . ' ORDER BY weight ASC');
183
        while (list($catID, $name, $total, $logourl) = $xoopsDB->fetchRow($resultcat)) {
184
            if ($grouppermHandler->checkRight('lexikon_view', $catID, $groups, $xoopsModule->getVar('mid'))) {
185
                $catlinks = [];
186
                ++$count;
187
                if ($logourl && 'http://' !== $logourl) {
188
                    $logourl = htmlspecialchars($logourl, ENT_QUOTES | ENT_HTML5);
189
                } else {
190
                    $logourl = '';
191
                }
192
                $xoopsModule          = \XoopsModule::getByDirname('lexikon');
193
                $catlinks['id']       = (int)$catID;
194
                $catlinks['total']    = (int)$total;
195
                $catlinks['linktext'] = htmlspecialchars($name, ENT_QUOTES | ENT_HTML5);
196
                $catlinks['image']    = $logourl;
197
                $catlinks['count']    = $count;
198
199
                $block0['categories'][] = $catlinks;
200
            }
201
        }
202
203
        return $block0;
204
    }
205
206
    /**
207
     * @return array
208
     */
209
    public static function getAlphaArray()
210
    {
211
        global $xoopsUser, $xoopsDB, $xoopsModule;
212
        $grouppermHandler = \xoops_getHandler('groupperm');
213
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
214
        /** @var \XoopsModuleHandler $moduleHandler */
215
        $moduleHandler = \xoops_getHandler('module');
216
        $module        = $moduleHandler->getByDirname('lexikon');
217
        $module_id     = $module->getVar('mid');
218
        $allowed_cats  = $grouppermHandler->getItemIds('lexikon_view', $groups, $module_id);
219
        $catids        = \implode(',', $allowed_cats);
220
        $catperms      = " AND categoryID IN ($catids) ";
221
        $alpha         = [];
222
        /**
223
         * @param $a
224
         * @return null|string|string[]
225
         */
226
        function unichr($a)
227
        {
228
            return mb_convert_encoding(\pack('N', $a), mb_internal_encoding(), 'UCS-4BE');
0 ignored issues
show
Bug introduced by
It seems like mb_internal_encoding() can also be of type true; however, parameter $to_encoding of mb_convert_encoding() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

228
            return mb_convert_encoding(\pack('N', $a), /** @scrutinizer ignore-type */ mb_internal_encoding(), 'UCS-4BE');
Loading history...
229
        }
230
231
        for ($a = 48; $a < (48 + 10); ++$a) {
232
            $letterlinks             = [];
233
            $initial                 = unichr($a);
234
            $sql                     = $xoopsDB->query('SELECT entryID FROM ' . $xoopsDB->prefix('lxentries') . " WHERE init = '$initial' AND submit = '0' AND offline ='0' AND request = '0' " . $catperms . '');
235
            $howmany                 = $xoopsDB->getRowsNum($sql);
236
            $letterlinks['total']    = $howmany;
237
            $letterlinks['id']       = unichr($a);
238
            $letterlinks['linktext'] = unichr($a);
239
240
            $alpha['initial'][] = $letterlinks;
241
        }
242
        for ($a = 65; $a < (65 + 26); ++$a) {
243
            $letterlinks             = [];
244
            $initial                 = unichr($a);
245
            $sql                     = $xoopsDB->query('SELECT entryID FROM ' . $xoopsDB->prefix('lxentries') . " WHERE init = '$initial' AND submit = '0' AND offline ='0' AND request = '0' " . $catperms . '');
246
            $howmany                 = $xoopsDB->getRowsNum($sql);
247
            $letterlinks['total']    = $howmany;
248
            $letterlinks['id']       = unichr($a);
249
            $letterlinks['linktext'] = unichr($a);
250
251
            $alpha['initial'][] = $letterlinks;
252
        }
253
        /*for ($a = 1040; $a < (1040 + 32); ++$a) {
254
            $letterlinks             = [];
255
            $initial                 = unichr($a);
256
            $sql                     = $xoopsDB->query('SELECT entryID FROM '
257
                                                           . $xoopsDB->prefix('lxentries')
258
                                                           . " WHERE init = '$initial' AND submit = '0' AND offline ='0' AND request = '0' "
259
                                                           . $catperms
260
                                                           . '');
261
            $howmany                 = $xoopsDB->getRowsNum($sql);
262
            $letterlinks['total']    = $howmany;
263
            $letterlinks['id']       = unichr($a);
264
            $letterlinks['linktext'] = unichr($a);
265
            $alpha['initial'][] = $letterlinks;
266
        }*/
267
268
        return $alpha;
269
    }
270
271
    /**
272
     * chr() with unicode support
273
     * I found this on this site http://en.php.net/chr
274
     * don't take credit for this.
275
     * @param $initials
276
     * @return string
277
     */
278
    public static function getUchr($initials)
279
    {
280
        if (\is_scalar($initials)) {
281
            $initials = \func_get_args();
282
        }
283
        $str = '';
284
        foreach ($initials as $init) {
285
            $str .= \html_entity_decode('&#' . $init . ';', \ENT_NOQUOTES, 'UTF-8');
286
        }
287
288
        return $str;
289
    }
290
291
    /* sample */
292
    /*
293
        echo static::getUchr(23383); echo '<br>';
294
        echo static::getUchr(23383,215,23383); echo '<br>';
295
        echo static::getUchr(array(23383,215,23383,215,23383)); echo '<br>';
296
    */
297
298
    // Functional links
299
300
    /**
301
     * @param $variable
302
     * @return string
303
     */
304
    public static function getServiceLinks($variable)
305
    {
306
        global $xoopsUser, $xoopsDB, $xoopsModule, $xoopsConfig, $entrytype;
307
308
        $helper = Helper::getInstance();
309
310
        /** @var \XoopsModuleHandler $moduleHandler */
311
        $moduleHandler = \xoops_getHandler('module');
312
        $moduleInfo    = $moduleHandler->get($xoopsModule->getVar('mid'));
0 ignored issues
show
Unused Code introduced by
The assignment to $moduleInfo is dead and can be removed.
Loading history...
313
        $pathIcon16    = Admin::iconUrl('', 16);
314
315
        $srvlinks = '';
316
        if ($xoopsUser) {
317
            if ($xoopsUser->isAdmin()) {
318
                $srvlinks .= '<a TITLE="'
319
                             . _EDIT
320
                             . '" href="admin/entry.php?op=mod&entryID='
321
                             . $variable['id']
322
                             . '" target="_blank"><img src="'
323
                             . $pathIcon16
324
                             . '/edit.png"   alt="'
325
                             . _MD_LEXIKON_EDITTERM
326
                             . '" style="width:16px; height:16px;"></a>&nbsp;<a TITLE="'
327
                             . _DELETE
328
                             . '" href="admin/entry.php?op=del&entryID='
329
                             . $variable['id']
330
                             . '" target="_self"><img src="'
331
                             . $pathIcon16
332
                             . '/delete.png" alt="'
333
                             . _MD_LEXIKON_DELTERM
334
                             . '" style="width:16px; height:16px;"></a>&nbsp;';
335
            }
336
        }
337
        if ('1' != $entrytype) {
338
            $srvlinks .= '<a TITLE="'
339
                         . _MD_LEXIKON_PRINTTERM
340
                         . '" href="print.php?entryID='
341
                         . $variable['id']
342
                         . '" target="_blank"><img src="'
343
                         . $pathIcon16
344
                         . '/printer.png"  alt="'
345
                         . _MD_LEXIKON_PRINTTERM
346
                         . '" style="width:16px; height:16px;"></a>&nbsp;<a TITLE="'
347
                         . _MD_LEXIKON_SENDTOFRIEND
348
                         . '" href="mailto:?subject='
349
                         . \sprintf(_MD_LEXIKON_INTENTRY, $xoopsConfig['sitename'])
350
                         . '&amp;body='
351
                         . \sprintf(_MD_LEXIKON_INTENTRYFOUND, $xoopsConfig['sitename'])
352
                         . ': '
353
                         . XOOPS_URL
354
                         . '/modules/'
355
                         . $xoopsModule->dirname()
356
                         . '/entry.php?entryID='
357
                         . $variable['id']
358
                         . ' " target="_blank"><img src="'
359
                         . $pathIcon16
360
                         . '/mail_replay.png" alt="'
361
                         . _MD_LEXIKON_SENDTOFRIEND
362
                         . '" style="width:16px; height:16px;"></a>&nbsp;';
363
            if ((0 != $helper->getConfig('com_rule'))
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $helper->getConfig('com_rule') of type mixed|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
364
                && (!empty($helper->getConfig('com_anonpost'))
365
                    || \is_object($xoopsUser))) {
366
                $srvlinks .= '<a TITLE="' . _COMMENTS . '?" href="comment_new.php?com_itemid=' . $variable['id'] . '" target="_parent"><img src="assets/images/comments.gif" alt="' . _COMMENTS . '?" style="width:16px; height:16px;"></a>&nbsp;';
367
            }
368
        }
369
370
        return $srvlinks;
371
    }
372
373
    // entry footer
374
375
    /**
376
     * @param $variable
377
     * @return string
378
     */
379
    public static function getServiceLinksNew($variable)
380
    {
381
        global $xoopsUser, $xoopsDB, $xoopsModule, $xoopsConfig, $myts;
382
383
        $helper    = Helper::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $helper is dead and can be removed.
Loading history...
384
        $srvlinks2 = '<a TITLE="'
385
                     . _MD_LEXIKON_PRINTTERM
386
                     . '" href="print.php?entryID='
387
                     . $variable['id']
388
                     . '" target="_blank"><img src="assets/images/print.gif" alt="'
389
                     . _MD_LEXIKON_PRINTTERM
390
                     . '" style="vertical-align: middle; width:16px; height:16px; margin: 2px 4px;"> '
391
                     . _MD_LEXIKON_PRINTTERM2
392
                     . '</a>&nbsp; <a TITLE="'
393
                     . _MD_LEXIKON_SENDTOFRIEND
394
                     . '" href="mailto:?subject='
395
                     . \sprintf(_MD_LEXIKON_INTENTRY, $xoopsConfig['sitename'])
396
                     . '&amp;body='
397
                     . \sprintf(_MD_LEXIKON_INTENTRYFOUND, $xoopsConfig['sitename'])
398
                     . ': '
399
                     . $variable['term']
400
                     . ' '
401
                     . XOOPS_URL
402
                     . '/modules/'
403
                     . $xoopsModule->dirname()
404
                     . '/entry.php?entryID='
405
                     . $variable['id']
406
                     . ' " target="_blank"><img src="assets/images/friend.gif" alt="'
407
                     . _MD_LEXIKON_SENDTOFRIEND
408
                     . '" style="vertical-align: middle; width:16px; height:16px; margin: 2px 4px;"> '
409
                     . _MD_LEXIKON_SENDTOFRIEND2
410
                     . '</a>&nbsp;';
411
412
        return $srvlinks2;
413
    }
414
415
    /**
416
     * @return string
417
     */
418
    public static function showSearchForm()
419
    {
420
        global $xoopsUser, $xoopsDB, $xoopsModule, $xoopsConfig;
421
422
        $helper = Helper::getInstance();
423
424
        $grouppermHandler = \xoops_getHandler('groupperm');
425
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
426
427
        $searchform = '<table style="width:100%;">';
428
        $searchform .= '<form name="op" id="op" action="search.php" method="post">';
429
        $searchform .= '<tr><td style="text-align: right; line-height: 200%; width:150px;">';
430
        $searchform .= _MD_LEXIKON_LOOKON . '</td><td style="width:10px;">&nbsp;</td><td style="text-align: left;">';
431
        $searchform .= '<select name="type"><option value="1">' . _MD_LEXIKON_TERMS . '</option><option value="2">' . _MD_LEXIKON_DEFINS . '</option>';
432
        $searchform .= '<option SELECTED value="3">' . _MD_LEXIKON_TERMSDEFS . '</option></select></td></tr>';
433
434
        if (1 == $helper->getConfig('multicats')) {
435
            $searchform .= '<tr><td style="text-align: right; line-height: 200%;">' . _MD_LEXIKON_CATEGORY . '</td>';
436
            $searchform .= '<td>&nbsp;</td><td style="text-align: left;">';
437
            $resultcat  = $xoopsDB->query('SELECT categoryID, name FROM ' . $xoopsDB->prefix('lxcategories') . ' ORDER BY categoryID');
438
            $searchform .= '<select name="categoryID">';
439
            $searchform .= '<option value="0">' . _MD_LEXIKON_ALLOFTHEM . '</option>';
440
441
            while (list($categoryID, $name) = $xoopsDB->fetchRow($resultcat)) {
442
                if ($grouppermHandler->checkRight('lexikon_view', (int)$categoryID, $groups, $xoopsModule->getVar('mid'))) {
443
                    $searchform .= "<option value=\"$categoryID\">$categoryID : $name</option>";
444
                }
445
            }
446
            $searchform .= '</select></td></tr>';
447
        }
448
449
        $searchform .= '<tr><td style="text-align: right; line-height: 200%;">';
450
        $searchform .= _MD_LEXIKON_TERM . '</td><td>&nbsp;</td><td style="text-align: left;">';
451
        $searchform .= '<input type="text" name="term" class="searchBox" ></td></tr><tr>';
452
        $searchform .= '<td>&nbsp;</td><td>&nbsp;</td><td><input type="submit" class="btnDefault" value="' . _MD_LEXIKON_SEARCH . '" >';
453
        $searchform .= '</td></tr></form></table>';
454
455
        return $searchform;
456
    }
457
458
    /**
459
     * @param $needle
460
     * @param $haystack
461
     * @param $hlS
462
     * @param $hlE
463
     * @return string
464
     */
465
    public static function getHTMLHighlight($needle, $haystack, $hlS, $hlE)
466
    {
467
        $parts = \explode('>', $haystack);
468
        foreach ($parts as $key => $part) {
469
            $pL = '';
470
            $pR = '';
471
472
            if (false === ($pos = mb_strpos($part, '<'))) {
473
                $pL = $part;
474
            } elseif ($pos > 0) {
475
                $pL = mb_substr($part, 0, $pos);
476
                $pR = mb_substr($part, $pos, mb_strlen($part));
477
            }
478
            if ('' != $pL) {
479
                $parts[$key] = \preg_replace('|(' . \quotemeta($needle) . ')|iU', $hlS . '\\1' . $hlE, $pL) . $pR;
480
            }
481
        }
482
483
        return \implode('>', $parts);
484
    }
485
486
    /* *******************************************************************************
487
     * Most of the following functions are modified functions from Herve's News Module
488
     * other functions are from  AMS by Novasmart/Mithrandir
489
     * others from Red Mexico Soft Rmdp
490
     * others from Xhelp 0.78 thanks to ackbarr and eric_juden
491
     * *******************************************************************************
492
     */
493
494
    // Create the meta keywords based on content
495
496
    /**
497
     * @param $content
498
     */
499
    public static function extractKeywords($content)
500
    {
501
        global $xoopsTpl, $xoTheme, $xoopsModule;
502
503
        $helper = Helper::getInstance();
504
        require_once XOOPS_ROOT_PATH . '/modules/lexikon/include/common.inc.php';
505
        $keywords_count = $helper->getConfig('metakeywordsnum');
506
        $tmp            = [];
507
        if (\Xmf\Request::hasVar('xoops_keywords_limit', 'SESSION')) {    // Search the "Minimum keyword length"
508
            $limit = $_SESSION['xoops_keywords_limit'];
509
        } else {
510
            /** @var \XoopsConfigHandler $configHandler */
511
            $configHandler                    = \xoops_getHandler('config');
512
            $xoopsConfigSearch                = $configHandler->getConfigsByCat(\XOOPS_CONF_SEARCH);
513
            $limit                            = $xoopsConfigSearch['keyword_min'];
514
            $_SESSION['xoops_keywords_limit'] = $limit;
515
        }
516
        $myts            = \MyTextSanitizer::getInstance();
517
        $content         = \str_replace('<br>', ' ', $content);
518
        $content         = $myts->undoHtmlSpecialChars($content);
519
        $content         = \strip_tags($content);
520
        $content         = mb_strtolower($content);
521
        $search_pattern  = [
522
            '&nbsp;',
523
            "\t",
524
            "\r\n",
525
            "\r",
526
            "\n",
527
            ',',
528
            '.',
529
            "'",
530
            ';',
531
            ':',
532
            ')',
533
            '(',
534
            '"',
535
            '?',
536
            '!',
537
            '{',
538
            '}',
539
            '[',
540
            ']',
541
            '<',
542
            '>',
543
            '/',
544
            '+',
545
            '-',
546
            '_',
547
            '\\',
548
            '*',
549
        ];
550
        $replace_pattern = [
551
            ' ',
552
            ' ',
553
            ' ',
554
            ' ',
555
            ' ',
556
            ' ',
557
            ' ',
558
            ' ',
559
            '',
560
            '',
561
            '',
562
            '',
563
            '',
564
            '',
565
            '',
566
            '',
567
            '',
568
            '',
569
            '',
570
            '',
571
            '',
572
            '',
573
            '',
574
            '',
575
            '',
576
            '',
577
            '',
578
        ];
579
        $content         = \str_replace($search_pattern, $replace_pattern, $content);
580
        $keywords        = \explode(' ', $content);
581
        switch (\META_KEYWORDS_ORDER) {
582
            case 1:    // Returns keywords in the same order that they were created in the text
583
                $keywords = \array_unique($keywords);
584
                break;
585
            case 2:    // the keywords order is made according to the reverse keywords frequency (so the less frequent words appear in first in the list)
586
                $keywords = \array_count_values($keywords);
587
                \asort($keywords);
588
                $keywords = \array_keys($keywords);
589
                break;
590
            case 3:    // Same as previous, the only difference is that the most frequent words will appear in first in the list
591
                $keywords = \array_count_values($keywords);
592
                \arsort($keywords);
593
                $keywords = \array_keys($keywords);
594
                break;
595
        }
596
        foreach ($keywords as $keyword) {
597
            if (mb_strlen($keyword) >= $limit && !\is_numeric($keyword)) {
598
                $tmp[] = $keyword;
599
            }
600
        }
601
        $tmp = \array_slice($tmp, 0, $keywords_count);
602
        if (\count($tmp) > 0) {
603
            if (isset($xoTheme) && \is_object($xoTheme)) {
604
                $xoTheme->addMeta('meta', 'keywords', \implode(',', $tmp));
605
            } else {    // Compatibility for old Xoops versions
606
                $xoopsTpl->assign('xoops_meta_keywords', \implode(',', $tmp));
607
            }
608
        } else {
609
            if (!isset($configHandler) || !\is_object($configHandler)) {
610
                $configHandler = \xoops_getHandler('config');
611
            }
612
            $xoopsConfigMetaFooter = $configHandler->getConfigsByCat(\XOOPS_CONF_METAFOOTER);
0 ignored issues
show
Bug introduced by
The method getConfigsByCat() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

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

612
            /** @scrutinizer ignore-call */ 
613
            $xoopsConfigMetaFooter = $configHandler->getConfigsByCat(\XOOPS_CONF_METAFOOTER);
Loading history...
613
            if (isset($xoTheme) && \is_object($xoTheme)) {
614
                $xoTheme->addMeta('meta', 'keywords', $xoopsConfigMetaFooter['meta_keywords']);
615
            } else {    // Compatibility for old Xoops versions
616
                $xoopsTpl->assign('xoops_meta_keywords', $xoopsConfigMetaFooter['meta_keywords']);
617
            }
618
        }
619
    }
620
621
    // Create meta description based on content
622
623
    /**
624
     * @param $content
625
     */
626
    public static function getMetaDescription($content)
627
    {
628
        global $xoopsTpl, $xoTheme;
629
        $myts    = \MyTextSanitizer::getInstance();
630
        $content = $myts->undoHtmlSpecialChars($myts->displayTarea($content));
631
        if (isset($xoTheme) && \is_object($xoTheme)) {
632
            $xoTheme->addMeta('meta', 'description', \strip_tags($content));
633
        } else {  // Compatibility for old Xoops versions
634
            $xoopsTpl->assign('xoops_meta_description', \strip_tags($content));
635
        }
636
    }
637
638
    // Create pagetitles
639
640
    /**
641
     * @param string $article
642
     * @param string $topic
643
     */
644
    public static function createPageTitle($article = '', $topic = '')
645
    {
646
        global $xoopsModule, $xoopsTpl;
647
        $myts    = \MyTextSanitizer::getInstance();
648
        $content = '';
649
        if (!empty($article)) {
650
            $content .= \strip_tags($myts->displayTarea($article));
651
        }
652
        if (!empty($topic)) {
653
            if ('' != \xoops_trim($content)) {
654
                $content .= ' - ' . \strip_tags($myts->displayTarea($topic));
655
            } else {
656
                $content .= \strip_tags($myts->displayTarea($topic));
657
            }
658
        }
659
        if (\is_object($xoopsModule) && '' != \xoops_trim($xoopsModule->name())) {
660
            if ('' != \xoops_trim($content)) {
661
                $content .= ' - ' . \strip_tags($myts->displayTarea($xoopsModule->name()));
662
            } else {
663
                $content .= \strip_tags($myts->displayTarea($xoopsModule->name()));
664
            }
665
        }
666
        if ('' != $content) {
667
            $xoopsTpl->assign('xoops_pagetitle', $content);
668
        }
669
    }
670
671
    // clear descriptions
672
673
    /**
674
     * @param $document
675
     * @return array|string|string[]|null
676
     */
677
    public static function convertHtml2text($document)
678
    {
679
        // PHP Manual:: function preg_replace $document should contain an HTML document.
680
        // This will remove HTML tags, javascript sections and white space. It will also
681
        // convert some common HTML entities to their text equivalent.
682
683
        $search = [
684
            "'<script[^>]*?>.*?</script>'si",  // Strip out javascript
685
            "'<[\/\!]*?[^<>]*?>'si",          // Strip out HTML tags
686
            "'([\r\n])[\s]+'",                // Strip out white space
687
            "'&(quot|#34);'i",                // Replace HTML entities
688
            "'&(amp|#38);'i",
689
            "'&(lt|#60);'i",
690
            "'&(gt|#62);'i",
691
            "'&(nbsp|#160);'i",
692
            "'&(iexcl|#161);'i",
693
            "'&(cent|#162);'i",
694
            "'&(pound|#163);'i",
695
            "'&(copy|#169);'i",
696
        ];
697
698
        $replace = [
699
            '',
700
            '',
701
            '\\1',
702
            '"',
703
            '&',
704
            '<',
705
            '>',
706
            ' ',
707
            \chr(161),
708
            \chr(162),
709
            \chr(163),
710
            \chr(169),
711
        ];
712
713
        $text = \preg_replace($search, $replace, $document);
714
715
        \preg_replace_callback(
716
            '/&#(\d+);/',
717
            static function ($matches) {
718
                return \chr($matches[1]);
719
            },
720
            $document
721
        );
722
723
        return $text;
724
    }
725
726
    //Retrieve moduleoptions equivalent to $Xoopsmoduleconfig
727
728
    /**
729
     * @param         $option
730
     * @param string  $repmodule
731
     * @return bool
732
     */
733
    public static function getModuleOption($option, $repmodule = 'lexikon')
734
    {
735
        global $xoopsModuleConfig, $xoopsModule;
736
        static $tbloptions = [];
737
        if (\is_array($tbloptions) && \array_key_exists($option, $tbloptions)) {
738
            return $tbloptions[$option];
739
        }
740
741
        $retval = false;
742
        if (isset($xoopsModuleConfig)
743
            && (\is_object($xoopsModule) && $xoopsModule->getVar('dirname') == $repmodule
744
                && $xoopsModule->getVar('isactive'))) {
745
            if (isset($xoopsModuleConfig[$option])) {
746
                $retval = $xoopsModuleConfig[$option];
747
            }
748
        } else {
749
            /** @var \XoopsModuleHandler $moduleHandler */
750
            $moduleHandler = \xoops_getHandler('module');
751
            $module        = $moduleHandler->getByDirname($repmodule);
752
            $configHandler = \xoops_getHandler('config');
753
            if ($module) {
754
                $moduleConfig = $configHandler->getConfigsByCat(0, $module->getVar('mid'));
755
                if (isset($moduleConfig[$option])) {
756
                    $retval = $moduleConfig[$option];
757
                }
758
            }
759
        }
760
        $tbloptions[$option] = $retval;
761
762
        return $retval;
763
    }
764
765
    /**
766
     * Is Xoops 2.3.x ?
767
     *
768
     * @return bool need to say it ?
769
     */
770
    public static function isX23()
771
    {
772
        $x23 = false;
773
        $xv  = \str_replace('XOOPS ', '', \XOOPS_VERSION);
774
        if (mb_substr($xv, 2, 1) >= '3') {
775
            $x23 = true;
776
        }
777
778
        return $x23;
779
    }
780
781
    /**
782
     * Retreive an editor according to the module's option "form_options"
783
     * following function is from News modified by trabis
784
     * @param                                                                                                                                 $caption
785
     * @param                                                                                                                                 $name
786
     * @param string                                                                                                                          $value
787
     * @param string                                                                                                                          $width
788
     * @param string                                                                                                                          $height
789
     * @param string                                                                                                                          $supplemental
790
     * @return bool|\XoopsFormEditor
791
     */
792
    public static function getWysiwygForm($caption, $name, $value = '', $width = '100%', $height = '400px', $supplemental = '')
793
    {
794
        $editor_option            = mb_strtolower(static::getModuleOption('form_options'));
0 ignored issues
show
Bug introduced by
static::getModuleOption('form_options') of type boolean is incompatible with the type string expected by parameter $string of mb_strtolower(). ( Ignorable by Annotation )

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

794
        $editor_option            = mb_strtolower(/** @scrutinizer ignore-type */ static::getModuleOption('form_options'));
Loading history...
795
        $editor                   = false;
796
        $editor_configs           = [];
797
        $editor_configs['name']   = $name;
798
        $editor_configs['value']  = $value;
799
        $editor_configs['rows']   = 35;
800
        $editor_configs['cols']   = 60;
801
        $editor_configs['width']  = '100%';
802
        $editor_configs['height'] = '350px';
803
        $editor_configs['editor'] = $editor_option;
804
805
        if (static::isX23()) {
806
            $editor = new \XoopsFormEditor($caption, $name, $editor_configs);
807
808
            return $editor;
809
        }
810
811
        // Only for Xoops 2.0.x
812
        switch ($editor_option) {
813
            case 'fckeditor':
814
                if (\is_readable(XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php')) {
815
                    require_once XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php';
816
                    $editor = new \XoopsFormFckeditor($caption, $name, $value);
0 ignored issues
show
Bug introduced by
The type XoopsFormFckeditor was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
817
                }
818
                break;
819
            case 'htmlarea':
820
                if (\is_readable(XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php')) {
821
                    require_once XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php';
822
                    $editor = new \XoopsFormHtmlarea($caption, $name, $value);
0 ignored issues
show
Bug introduced by
The type XoopsFormHtmlarea was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
823
                }
824
                break;
825
            case 'dhtmltextarea':
826
            case 'dhtml':
827
                $editor = new \XoopsFormDhtmlTextArea($caption, $name, $value, 10, 50, $supplemental);
828
                break;
829
            case 'textarea':
830
                $editor = new \XoopsFormTextArea($caption, $name, $value);
831
                break;
832
            case 'tinyeditor':
833
            case 'tinymce':
834
                if (\is_readable(XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php')) {
835
                    require_once XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php';
836
                    $editor = new \XoopsFormTinyeditorTextArea(
0 ignored issues
show
Bug introduced by
The type XoopsFormTinyeditorTextArea was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
837
                        [
838
                            'caption' => $caption,
839
                            'name'    => $name,
840
                            'value'   => $value,
841
                            'width'   => '100%',
842
                            'height'  => '400px',
843
                        ]
844
                    );
845
                }
846
                break;
847
            case 'koivi':
848
                if (\is_readable(XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php')) {
849
                    require_once XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php';
850
                    $editor = new \XoopsFormWysiwygTextArea($caption, $name, $value, $width, $height, '');
0 ignored issues
show
Bug introduced by
The type XoopsFormWysiwygTextArea was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
851
                }
852
                break;
853
        }
854
855
        return $editor;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $editor also could return the type XoopsFormDhtmlTextArea which is incompatible with the documented return type XoopsFormEditor|boolean.
Loading history...
856
    }
857
858
    /**
859
     * @param \Xmf\Module\Helper $helper
860
     * @param array|null         $options
861
     * @return \XoopsFormDhtmlTextArea|\XoopsFormEditor
862
     */
863
    public static function getEditor($helper = null, $options = null)
864
    {
865
866
        if (null === $options) {
867
            $options           = [];
868
            $options['name']   = 'Editor';
869
            $options['value']  = 'Editor';
870
            $options['rows']   = 10;
871
            $options['cols']   = '100%';
872
            $options['width']  = '100%';
873
            $options['height'] = '400px';
874
        }
875
876
        if (null === $helper) {
877
            $helper = Helper::getInstance();
878
        }
879
880
        $isAdmin = $helper->isUserAdmin();
881
882
        if (\class_exists('XoopsFormEditor')) {
883
            if ($isAdmin) {
884
                $descEditor = new \XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorAdmin'), $options, $nohtml = false, $onfailure = 'textarea');
885
            } else {
886
                $descEditor = new \XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorUser'), $options, $nohtml = false, $onfailure = 'textarea');
887
            }
888
        } else {
889
            $descEditor = new \XoopsFormDhtmlTextArea(\ucfirst($options['name']), $options['name'], $options['value'], '100%', '100%');
0 ignored issues
show
Bug introduced by
'100%' of type string is incompatible with the type integer expected by parameter $rows of XoopsFormDhtmlTextArea::__construct(). ( Ignorable by Annotation )

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

889
            $descEditor = new \XoopsFormDhtmlTextArea(\ucfirst($options['name']), $options['name'], $options['value'], /** @scrutinizer ignore-type */ '100%', '100%');
Loading history...
Bug introduced by
'100%' of type string is incompatible with the type integer expected by parameter $cols of XoopsFormDhtmlTextArea::__construct(). ( Ignorable by Annotation )

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

889
            $descEditor = new \XoopsFormDhtmlTextArea(\ucfirst($options['name']), $options['name'], $options['value'], '100%', /** @scrutinizer ignore-type */ '100%');
Loading history...
890
        }
891
892
        //        $form->addElement($descEditor);
893
894
        return $descEditor;
895
    }
896
897
    /**
898
     * linkterms: assign module header
899
     *
900
     * tooltips (c) dhtmlgoodies
901
     */
902
    public static function getModuleHeader()
903
    {
904
        global $xoopsTpl, $xoTheme, $xoopsModule, $lexikon_module_header;
905
906
        $helper = Helper::getInstance();
907
908
        if (isset($xoTheme) && \is_object($xoTheme)) {
909
            $xoTheme->addStylesheet('modules/lexikon/assets/css/style.css');
910
            if (3 == $helper->getConfig('linkterms')) {
911
                $xoTheme->addStylesheet('modules/lexikon/assets/css/linkterms.css');
912
                $xoTheme->addScript('/modules/lexikon/assets/js/tooltipscript2.js', ['type' => 'text/javascript']);
913
            }
914
            if (4 == $helper->getConfig('linkterms')) {
915
                $xoTheme->addScript('/modules/lexikon/assets/js/popup.js', ['type' => 'text/javascript']);
916
            }
917
            if (5 == $helper->getConfig('linkterms')) {
918
                $xoTheme->addStylesheet('modules/lexikon/assets/css/linkterms.css');
919
                $xoTheme->addScript('/modules/lexikon/assets/js/balloontooltip.js', ['type' => 'text/javascript']);
920
            }
921
            if (6 == $helper->getConfig('linkterms')) {
922
                $xoTheme->addStylesheet('modules/lexikon/assets/css/linkterms.css');
923
                $xoTheme->addScript('/modules/lexikon/assets/js/shadowtooltip.js', ['type' => 'text/javascript']);
924
            }
925
        } else {
926
            $lexikon_url = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname');
927
            if (3 == $helper->getConfig('linkterms')) {
928
                $lexikon_module_header = '<link rel="stylesheet" type="text/css" href="assets/css/style.css" >
929
            <link rel="stylesheet" type="text/css" href="assets/css/linkterms.css" >
930
            <script src="' . $lexikon_url . '/assets/js/tooltipscript2.js" type="text/javascript"></script>';
931
            }
932
            if (4 == $helper->getConfig('linkterms')) {
933
                $lexikon_module_header = '<link rel="stylesheet" type="text/css" href="assets/css/style.css" >
934
            <link rel="stylesheet" type="text/css" href="assets/css/linkterms.css" >
935
            <script src="' . $lexikon_url . '/assets/js/popup.js" type="text/javascript"></script>';
936
            }
937
            if (5 == $helper->getConfig('linkterms')) {
938
                $lexikon_module_header = '<link rel="stylesheet" type="text/css" href="assets/css/style.css" >
939
            <link rel="stylesheet" type="text/css" href="assets/css/linkterms.css" >
940
            <script src="' . $lexikon_url . '/assets/js/balloontooltip.js" type="text/javascript"></script>';
941
            }
942
            if (6 == $helper->getConfig('linkterms')) {
943
                $lexikon_module_header = '<link rel="stylesheet" type="text/css" href="assets/css/style.css" >
944
            <link rel="stylesheet" type="text/css" href="assets/css/linkterms.css" >
945
            <script src="' . $lexikon_url . '/assets/js/shadowtooltip.js" type="text/javascript"></script>';
946
            }
947
        }
948
    }
949
950
    /**
951
     * Validate userid
952
     * @param $uids
953
     * @return bool
954
     */
955
    public static function getUserData($uids)
956
    {
957
        global $xoopsDB, $xoopsUser, $xoopsUserIsAdmin;
958
959
        if ($uids <= 0) {
960
            return false;
961
        }
962
        if ($uids > 0) {
963
            $memberHandler = \xoops_getHandler('member');
964
            $user          = $memberHandler->getUser($uids);
0 ignored issues
show
Bug introduced by
The method getUser() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsAvatarHandler or XoopsPersistableObjectHandler. ( Ignorable by Annotation )

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

964
            /** @scrutinizer ignore-call */ 
965
            $user          = $memberHandler->getUser($uids);
Loading history...
965
            if (!\is_object($user)) {
966
                return false;
967
            }
968
        }
969
        $result = $xoopsDB->query('SELECT * FROM ' . $xoopsDB->prefix('users') . " WHERE uid='$uids'");
970
        if ($xoopsDB->getRowsNum($result) <= 0) {
971
            return false;
972
        }
973
        $row = $xoopsDB->fetchArray($result);
974
975
        return $row;
976
    }
977
978
    // Get all terms published by an author
979
980
    /**
981
     * @param $uid
982
     */
983
    public static function getAuthorProfile($uid)
984
    {
985
        require_once XOOPS_ROOT_PATH . '/class/pagenav.php';
986
        global $authortermstotal, $xoopsTpl, $xoopsDB, $xoopsUser;
987
988
        $helper = Helper::getInstance();
989
        $myts   = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
990
        //permissions
991
        $grouppermHandler = \xoops_getHandler('groupperm');
992
        $groups           = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
993
        /** @var \XoopsModuleHandler $moduleHandler */
994
        $moduleHandler = \xoops_getHandler('module');
995
        $module        = $moduleHandler->getByDirname('lexikon');
996
        $module_id     = $module->getVar('mid');
997
        $allowed_cats  = $grouppermHandler->getItemIds('lexikon_view', $groups, $module_id);
998
        $catids        = \implode(',', $allowed_cats);
999
        $catperms      = " AND categoryID IN ($catids) ";
1000
1001
        $start = \Xmf\Request::getInt('start', 0, 'GET');
1002
        $limit = $helper->getConfig('indexperpage');
1003
1004
        $sql = $xoopsDB->query(
1005
            'SELECT *
1006
                              FROM ' . $xoopsDB->prefix('lxentries') . "
1007
                              WHERE uid='" . (int)$uid . "' AND  offline = '0' AND submit = '0' AND request = '0' " . $catperms . "
1008
                              ORDER BY term
1009
                              LIMIT $start,$limit"
1010
        );
1011
1012
        while (false !== ($row = $xoopsDB->fetchArray($sql))) {
1013
            $xoopsTpl->append(
1014
                'entries',
1015
                [
1016
                    'id'      => $row['entryID'],
1017
                    'name'    => $row['term'],
1018
                    'date'    => \date($helper->getConfig('dateformat'), $row['datesub']),
0 ignored issues
show
Bug introduced by
It seems like $helper->getConfig('dateformat') can also be of type null; however, parameter $format of date() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

1018
                    'date'    => \date(/** @scrutinizer ignore-type */ $helper->getConfig('dateformat'), $row['datesub']),
Loading history...
1019
                    'counter' => $row['counter'],
1020
                ]
1021
            );
1022
        }
1023
1024
        $navstring                = '';
1025
        $navstring                .= 'uid=' . $uid . '&start';
1026
        $pagenav                  = new \XoopsPageNav($authortermstotal, $helper->getConfig('indexperpage'), $start, $navstring);
1027
        $authortermsarr['navbar'] = '<span style="text-align:right;">' . $pagenav->renderNav(6) . '</span>';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$authortermsarr was never initialized. Although not strictly required by PHP, it is generally a good practice to add $authortermsarr = array(); before regardless.
Loading history...
1028
        $xoopsTpl->assign('authortermsarr', $authortermsarr);
1029
    }
1030
1031
    // Returns the author's IDs for authorslist
1032
1033
    /**
1034
     * @param int $limit
1035
     * @param int $start
1036
     * @return array
1037
     */
1038
    public static function getAuthors($limit = 0, $start = 0)
0 ignored issues
show
Unused Code introduced by
The parameter $limit is not used and could be removed. ( Ignorable by Annotation )

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

1038
    public static function getAuthors(/** @scrutinizer ignore-unused */ $limit = 0, $start = 0)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $start is not used and could be removed. ( Ignorable by Annotation )

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

1038
    public static function getAuthors($limit = 0, /** @scrutinizer ignore-unused */ $start = 0)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1039
    {
1040
        global $xoopsDB;
1041
1042
        $ret    = [];
1043
        $sql    = 'SELECT DISTINCT(uid) AS uid FROM ' . $xoopsDB->prefix('lxentries') . ' WHERE offline = 0 ';
1044
        $sql    .= ' ORDER BY uid';
1045
        $result = $xoopsDB->query($sql);
1046
        while (false !== ($myrow = $xoopsDB->fetchArray($result))) {
1047
            $ret[] = $myrow['uid'];
1048
        }
1049
1050
        return $ret;
1051
    }
1052
1053
    // link to userprofile
1054
1055
    /**
1056
     * @param $userid
1057
     * @return string
1058
     */
1059
    public static function getLinkedProfileFromId($userid)
0 ignored issues
show
Unused Code introduced by
The parameter $userid is not used and could be removed. ( Ignorable by Annotation )

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

1059
    public static function getLinkedProfileFromId(/** @scrutinizer ignore-unused */ $userid)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1060
    {
1061
        global $uid, $xoopsModule;
1062
        $userid = (int)$uid;
1063
        if ($userid > 0) {
1064
            $memberHandler = \xoops_getHandler('member');
1065
            $user          = $memberHandler->getUser($userid);
1066
            if (\is_object($user)) {
1067
                $linkeduser = '<A TITLE="' . _MD_LEXIKON_AUTHORPROFILETEXT . '" HREF="' . XOOPS_URL . '/modules/' . $xoopsModule->dirname() . '/profile.php?uid=' . $uid . '">' . $user->getVar('uname') . '</a>';
1068
                //$linkeduser = \XoopsUserUtility::getUnameFromId ( $uid );
1069
                //$linkeduser .= '<div style=\'position:relative; right: 4px; top: 2px;\'><A TITLE="'._MD_LEXIKON_AUTHORPROFILETEXT.'" HREF="'.XOOPS_URL.'/modules/'.$xoopsModule->dirname().'/profile.php?uid='.$uid.'">'._MD_LEXIKON_AUTHORPROFILETEXT.'</a></div>';
1070
                return $linkeduser;
1071
            }
1072
        }
1073
1074
        return $GLOBALS['xoopsConfig']['anonymous'];
1075
    }
1076
1077
    // functionset to assign terms with accentuated or umlaut initials to the adequate initial
1078
1079
    /**
1080
     * @param $string
1081
     * @return array|string|string[]
1082
     */
1083
    public static function removeAccents($string)
1084
    {
1085
        $chars['in']  = \chr(128)
0 ignored issues
show
Comprehensibility Best Practice introduced by
$chars was never initialized. Although not strictly required by PHP, it is generally a good practice to add $chars = array(); before regardless.
Loading history...
1086
                        . \chr(131)
1087
                        . \chr(138)
1088
                        . \chr(142)
1089
                        . \chr(154)
1090
                        . \chr(158)
1091
                        . \chr(159)
1092
                        . \chr(162)
1093
                        . \chr(165)
1094
                        . \chr(181)
1095
                        . \chr(192)
1096
                        . \chr(193)
1097
                        . \chr(194)
1098
                        . \chr(195)
1099
                        . \chr(196)
1100
                        . \chr(197)
1101
                        . \chr(199)
1102
                        . \chr(200)
1103
                        . \chr(201)
1104
                        . \chr(202)
1105
                        . \chr(203)
1106
                        . \chr(204)
1107
                        . \chr(205)
1108
                        . \chr(206)
1109
                        . \chr(207)
1110
                        . \chr(209)
1111
                        . \chr(210)
1112
                        . \chr(211)
1113
                        . \chr(212)
1114
                        . \chr(213)
1115
                        . \chr(214)
1116
                        . \chr(216)
1117
                        . \chr(217)
1118
                        . \chr(218)
1119
                        . \chr(219)
1120
                        . \chr(220)
1121
                        . \chr(221)
1122
                        . \chr(224)
1123
                        . \chr(225)
1124
                        . \chr(226)
1125
                        . \chr(227)
1126
                        . \chr(228)
1127
                        . \chr(229)
1128
                        . \chr(231)
1129
                        . \chr(232)
1130
                        . \chr(233)
1131
                        . \chr(234)
1132
                        . \chr(235)
1133
                        . \chr(236)
1134
                        . \chr(237)
1135
                        . \chr(238)
1136
                        . \chr(239)
1137
                        . \chr(241)
1138
                        . \chr(242)
1139
                        . \chr(243)
1140
                        . \chr(244)
1141
                        . \chr(245)
1142
                        . \chr(246)
1143
                        . \chr(248)
1144
                        . \chr(249)
1145
                        . \chr(250)
1146
                        . \chr(251)
1147
                        . \chr(252)
1148
                        . \chr(253)
1149
                        . \chr(255);
1150
        $chars['out'] = 'EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy';
1151
        if (static::isUtf8($string)) {
1152
            $invalid_latin_chars = [
1153
                \chr(197) . \chr(146)             => 'OE',
1154
                \chr(197) . \chr(147)             => 'oe',
1155
                \chr(197) . \chr(160)             => 'S',
1156
                \chr(197) . \chr(189)             => 'Z',
1157
                \chr(197) . \chr(161)             => 's',
1158
                \chr(197) . \chr(190)             => 'z',
1159
                \chr(226) . \chr(130) . \chr(172) => 'E',
1160
            ];
1161
            $string              = utf8_decode(strtr($string, $invalid_latin_chars));
1162
        }
1163
        $string              = strtr($string, $chars['in'], $chars['out']);
1164
        $double_chars['in']  = [
0 ignored issues
show
Comprehensibility Best Practice introduced by
$double_chars was never initialized. Although not strictly required by PHP, it is generally a good practice to add $double_chars = array(); before regardless.
Loading history...
1165
            \chr(140),
1166
            \chr(156),
1167
            \chr(198),
1168
            \chr(208),
1169
            \chr(222),
1170
            \chr(223),
1171
            \chr(230),
1172
            \chr(240),
1173
            \chr(254),
1174
        ];
1175
        $double_chars['out'] = ['OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'];
1176
        $string              = \str_replace($double_chars['in'], $double_chars['out'], $string);
1177
1178
        return $string;
1179
    }
1180
1181
    /**
1182
     * @param $Str
1183
     * @return bool
1184
     */
1185
    public static function isUtf8($Str)
1186
    { # by bmorel at ssi dot fr
1187
        for ($i = 0, $iMax = mb_strlen($Str); $i < $iMax; ++$i) {
1188
            if (\ord($Str[$i]) < 0x80) {
1189
                continue;
1190
            }
1191
1192
            if (0xC0 == (\ord($Str[$i]) & 0xE0)) {
1193
                $n = 1;
1194
            } # 0bbbbbbb
1195
            # 110bbbbb
1196
            elseif (0xE0 == (\ord($Str[$i]) & 0xF0)) {
1197
                $n = 2;
1198
            } # 1110bbbb
1199
            elseif (0xF0 == (\ord($Str[$i]) & 0xF8)) {
1200
                $n = 3;
1201
            } # 11110bbb
1202
            elseif (0xF8 == (\ord($Str[$i]) & 0xFC)) {
1203
                $n = 4;
1204
            } # 111110bb
1205
            elseif (0xFC == (\ord($Str[$i]) & 0xFE)) {
1206
                $n = 5;
1207
            } # 1111110b
1208
            else {
1209
                return false;
1210
            } # Does not match any model
1211
            for ($j = 0; $j < $n; ++$j) { # n bytes matching 10bbbbbb follow ?
1212
                if ((++$i == mb_strlen($Str)) || (0x80 != (\ord($Str[$i]) & 0xC0))) {
1213
                    return false;
1214
                }
1215
            }
1216
        }
1217
1218
        return true;
1219
    }
1220
1221
    /**
1222
     * @param $field
1223
     * @return string
1224
     */
1225
    public static function sanitizeFieldName($field)
1226
    {
1227
        $field = static::removeAccents($field);
1228
        $field = mb_strtolower($field);
1229
        $field = \preg_replace('/&.+?;/', '', $field); // kill entities
1230
        $field = \preg_replace('/[^a-z0-9 _-]/', '', $field);
1231
        $field = \preg_replace('/\s+/', ' ', $field);
1232
        $field = \str_replace(' ', '-', $field);
1233
        $field = \preg_replace('|-+|', '-', $field);
1234
        $field = \trim($field, '-');
1235
1236
        return $field;
1237
    }
1238
1239
    // Verify that a term does not exist for submissions and requests (both user frontend and admin backend)
1240
1241
    /**
1242
     * @param $term
1243
     * @param $table
1244
     * @return mixed
1245
     */
1246
    public static function isTermPresent($term, $table)
1247
    {
1248
        global $xoopsDB;
1249
        $sql    = \sprintf('SELECT COUNT(*) FROM `%s` WHERE term = %s', $table, $xoopsDB->quoteString(\addslashes($term)));
1250
        $result = $xoopsDB->query($sql);
1251
        [$count] = $xoopsDB->fetchRow($result);
1252
1253
        return $count;
1254
    }
1255
1256
    // Static method to get author data block authors - from AMS
1257
1258
    /**
1259
     * @param int    $limit
1260
     * @param string $sort
1261
     * @param string $name
1262
     * @param string $compute_method
1263
     * @return array|bool
1264
     */
1265
    public static function getBlockAuthors($limit = 5, $sort = 'count', $name = 'uname', $compute_method = 'average')
1266
    {
1267
        $limit = (int)$limit;
1268
        if ('uname' !== $name) {
1269
            $name = 'name';
1270
        } //making sure that there is not invalid information in field value
1271
        $ret = [];
1272
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
1273
        if ('count' === $sort) {
1274
            $sql = 'SELECT u.' . $name . ' AS name, u.uid , count( n.entryID ) AS count
1275
              FROM ' . $db->prefix('users') . ' u, ' . $db->prefix('lxentries') . ' n
1276
              WHERE u.uid = n.uid
1277
              AND n.datesub > 0 AND n.datesub <= ' . \time() . ' AND n.offline = 0 AND n.submit = 0
1278
              GROUP BY u.uid ORDER BY count DESC';
1279
        } elseif ('read' === $sort) {
1280
            if ('average' === $compute_method) {
1281
                $compute = 'sum( n.counter ) / count( n.entryID )';
1282
            } else {
1283
                $compute = 'sum( n.counter )';
1284
            }
1285
            $sql = 'SELECT u.' . $name . " AS name, u.uid , $compute AS count
1286
              FROM " . $db->prefix('users') . ' u, ' . $db->prefix('lxentries') . ' n
1287
              WHERE u.uid = n.uid
1288
              AND n.datesub > 0 AND n.datesub <= ' . \time() . ' AND n.offline = 0 AND n.submit = 0
1289
              GROUP BY u.uid ORDER BY count DESC';
1290
        }
1291
        if (!$result = $db->query($sql, $limit)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sql does not seem to be defined for all execution paths leading up to this point.
Loading history...
1292
            return false;
1293
        }
1294
1295
        while (false !== ($row = $db->fetchArray($result))) {
1296
            if ('name' === $name && '' == $row['name']) {
1297
                $row['name'] = \XoopsUser::getUnameFromId($row['uid']);
1298
            }
1299
            $row['count'] = \round($row['count'], 0);
1300
            $ret[]        = $row;
1301
        }
1302
1303
        return $ret;
1304
    }
1305
1306
    /**
1307
     * close all unclosed xhtml tags *Test*
1308
     *
1309
     * @param string $html
1310
     * @return string
1311
     * @author Milian Wolff <mail -at- milianw.de>
1312
     */
1313
    public static function closeTags2($html)
1314
    {
1315
        // put all opened tags into an array
1316
        \preg_match_all('#<([a-z]+)( .*)?(?!/)>#iU', $html, $result);
1317
        $openedtags = $result[1];
1318
1319
        // put all closed tags into an array
1320
        \preg_match_all('#</([a-z]+)>#iU', $html, $result);
1321
        $closedtags = $result[1];
1322
        $len_opened = \count($openedtags);
1323
        // all tags are closed
1324
        if (\count($closedtags) == $len_opened) {
1325
            return $html;
1326
        }
1327
1328
        $openedtags = \array_reverse($openedtags);
1329
        // close tags
1330
        for ($i = 0; $i < $len_opened; ++$i) {
1331
            if (!\in_array($openedtags[$i], $closedtags)) {
1332
                $html .= '</' . $openedtags[$i] . '>';
1333
            } else {
1334
                unset($closedtags[\array_search($openedtags[$i], $closedtags, true)]);
1335
            }
1336
        }
1337
1338
        return $html;
1339
    }
1340
1341
    /**
1342
     * @param $string
1343
     * @return string
1344
     * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
1345
     *           <amos dot robinson at gmail dot com>
1346
     */
1347
    public static function closeTags($string)
1348
    {
1349
        // match opened tags
1350
        if (\preg_match_all('/<([a-z\:\-]+)[^\/]>/', $string, $start_tags)) {
1351
            $start_tags = $start_tags[1];
1352
            // match closed tags
1353
            if (\preg_match_all('/<\/([a-z]+)>/', $string, $end_tags)) {
1354
                $complete_tags = [];
1355
                $end_tags      = $end_tags[1];
1356
1357
                foreach ($start_tags as $key => $val) {
1358
                    $posb = \array_search($val, $end_tags, true);
1359
                    if (\is_int($posb)) {
1360
                        unset($end_tags[$posb]);
1361
                    } else {
1362
                        $complete_tags[] = $val;
1363
                    }
1364
                }
1365
            } else {
1366
                $complete_tags = $start_tags;
1367
            }
1368
1369
            $complete_tags = \array_reverse($complete_tags);
1370
            for ($i = 0, $iMax = \count($complete_tags); $i < $iMax; ++$i) {
1371
                $string .= '</' . $complete_tags[$i] . '>';
1372
            }
1373
        }
1374
1375
        return $string;
1376
    }
1377
1378
    /**
1379
     * Smarty plugin
1380
     * @param mixed $string
1381
     * @param mixed $length
1382
     * @param mixed $etc
1383
     * @param mixed $break_words
1384
     * @package    Smarty
1385
     * @subpackage plugins
1386
     */
1387
1388
    /**
1389
     * Smarty truncate_tagsafe modifier plugin
1390
     *
1391
     * Type:     modifier<br>
1392
     * Name:     truncate_tagsafe<br>
1393
     * Purpose:  Truncate a string to a certain length if necessary,
1394
     *           optionally splitting in the middle of a word, and
1395
     *           appending the $etc string or inserting $etc into the middle.
1396
     *           Makes sure no tags are left half-open or half-closed (e.g. "Banana in a <a...")
1397
     * @param               $string
1398
     * @param int           $length
1399
     * @param string        $etc
1400
     * @param bool          $break_words
1401
     * @return string
1402
     * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
1403
     *           <amos dot robinson at gmail dot com>
1404
     *           used in Block entries_scrolling.php
1405
     */
1406
    public static function truncateTagSafe($string, $length = 80, $etc = '...', $break_words = false)
1407
    {
1408
        if (0 == $length) {
1409
            return '';
1410
        }
1411
        if (mb_strlen($string) > $length) {
1412
            $length -= mb_strlen($etc);
1413
            if (!$break_words) {
1414
                $string = \preg_replace('/\s+?(\S+)?$/', '', mb_substr($string, 0, $length + 1));
1415
                $string = \preg_replace('/<[^>]*$/', '', $string);
1416
                $string = static::closeTags($string);
1417
            }
1418
1419
            return $string . $etc;
1420
        }
1421
1422
        return $string;
1423
    }
1424
1425
    /**
1426
     * @return array
1427
     */
1428
    public static function getSummary()
1429
    {
1430
        global $xoopsDB;
1431
1432
        $summary = [];
1433
1434
        $result01 = $xoopsDB->query(
1435
            'SELECT COUNT(*)
1436
                                   FROM ' . $xoopsDB->prefix('lxcategories') . ' '
1437
        );
1438
        [$totalcategories] = $xoopsDB->fetchRow($result01);
1439
1440
        $result02 = $xoopsDB->query(
1441
            'SELECT COUNT(*)
1442
                                   FROM ' . $xoopsDB->prefix('lxentries') . '
1443
                                   WHERE submit = 0'
1444
        );
1445
        [$totalpublished] = $xoopsDB->fetchRow($result02);
1446
1447
        $result03 = $xoopsDB->query(
1448
            'SELECT COUNT(*)
1449
                                   FROM ' . $xoopsDB->prefix('lxentries') . "
1450
                                   WHERE submit = '1' AND request = '0' "
1451
        );
1452
        [$totalsubmitted] = $xoopsDB->fetchRow($result03);
1453
1454
        $result04 = $xoopsDB->query(
1455
            'SELECT COUNT(*)
1456
                                   FROM ' . $xoopsDB->prefix('lxentries') . "
1457
                                   WHERE submit = '1' AND request = '1' "
1458
        );
1459
        [$totalrequested] = $xoopsDB->fetchRow($result04);
1460
1461
        // Recuperer les valeurs dans la base de donnees
1462
1463
        $summary['publishedEntries']    = $totalpublished ?: '0';
1464
        $summary['availableCategories'] = $totalcategories ?: '0';
1465
        $summary['submittedEntries']    = $totalsubmitted ?: '0';
1466
        $summary['requestedEntries']    = $totalrequested ?: '0';
1467
1468
        //print_r($summary);
1469
        return $summary;
1470
    }
1471
1472
    // end function
1473
1474
    /**
1475
     * @param $text
1476
     * @param $form_sort
1477
     * @return string
1478
     */
1479
    public static function selectSorting($text, $form_sort)
1480
    {
1481
        global $start, $order, $file_cat, $sort, $xoopsModule;
1482
1483
        $select_view   = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $select_view is dead and can be removed.
Loading history...
1484
        $moduleDirName = \basename(\dirname(__DIR__));
1485
1486
        $helper = Helper::getInstance();
1487
1488
        $pathModIcon16 = XOOPS_URL . '/modules/' . $moduleDirName . '/' . $helper->getModule()->getInfo('modicons16');
0 ignored issues
show
Bug introduced by
Are you sure $helper->getModule()->getInfo('modicons16') of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

1488
        $pathModIcon16 = XOOPS_URL . '/modules/' . $moduleDirName . '/' . /** @scrutinizer ignore-type */ $helper->getModule()->getInfo('modicons16');
Loading history...
1489
1490
        $select_view = '<form name="form_switch" id="form_switch" action="' . Request::getString('REQUEST_URI', '', 'SERVER') . '" method="post"><span style="font-weight: bold;">' . $text . '</span>';
1491
        //$sorts =  $sort ==  'asc' ? 'desc' : 'asc';
1492
        if ($form_sort == $sort) {
1493
            $sel1 = 'asc' === $order ? 'selasc.png' : 'asc.png';
1494
            $sel2 = 'desc' === $order ? 'seldesc.png' : 'desc.png';
1495
        } else {
1496
            $sel1 = 'asc.png';
1497
            $sel2 = 'desc.png';
1498
        }
1499
        $select_view .= '  <a href="' . Request::getString('SCRIPT_NAME', '', 'SERVER') . '?start=' . $start . '&sort=' . $form_sort . '&order=asc" ><img src="' . $pathModIcon16 . '/' . $sel1 . '" title="ASC" alt="ASC"></a>';
1500
        $select_view .= '<a href="' . Request::getString('SCRIPT_NAME', '', 'SERVER') . '?start=' . $start . '&sort=' . $form_sort . '&order=desc" ><img src="' . $pathModIcon16 . '/' . $sel2 . '" title="DESC" alt="DESC"></a>';
1501
        $select_view .= '</form>';
1502
1503
        return $select_view;
1504
    }
1505
1506
    /***************Blocks***************/
1507
1508
    /**
1509
     * @param array $cats
1510
     * @return string
1511
     */
1512
    public static function block_addCatSelect($cats)
1513
    {
1514
        $cat_sql = '';
1515
        if (\is_array($cats)) {
0 ignored issues
show
introduced by
The condition is_array($cats) is always true.
Loading history...
1516
            $cat_sql = '(' . \current($cats);
1517
            \array_shift($cats);
1518
            foreach ($cats as $cat) {
1519
                $cat_sql .= ',' . $cat;
1520
            }
1521
            $cat_sql .= ')';
1522
        }
1523
1524
        return $cat_sql;
1525
    }
1526
1527
    /**
1528
     * @param $content
1529
     */
1530
    public static function meta_keywords($content)
1531
    {
1532
        global $xoopsTpl, $xoTheme;
1533
        $myts    = \MyTextSanitizer::getInstance();
1534
        $content = $myts->undoHtmlSpecialChars($myts->displayTarea($content));
1535
        if (null !== $xoTheme && \is_object($xoTheme)) {
1536
            $xoTheme->addMeta('meta', 'keywords', \strip_tags($content));
1537
        } else {    // Compatibility for old Xoops versions
1538
            $xoopsTpl->assign('xoops_meta_keywords', \strip_tags($content));
1539
        }
1540
    }
1541
1542
    /**
1543
     * @param $content
1544
     */
1545
    public static function meta_description($content)
1546
    {
1547
        global $xoopsTpl, $xoTheme;
1548
        $myts    = \MyTextSanitizer::getInstance();
1549
        $content = $myts->undoHtmlSpecialChars($myts->displayTarea($content));
1550
        if (null !== $xoTheme && \is_object($xoTheme)) {
1551
            $xoTheme->addMeta('meta', 'description', \strip_tags($content));
1552
        } else {    // Compatibility for old Xoops versions
1553
            $xoopsTpl->assign('xoops_meta_description', \strip_tags($content));
1554
        }
1555
    }
1556
1557
    /**
1558
     * @param $tableName
1559
     * @param $columnName
1560
     *
1561
     * @return array
1562
     */
1563
    public static function enumerate($tableName, $columnName)
1564
    {
1565
        $table = $GLOBALS['xoopsDB']->prefix($tableName);
1566
1567
        //    $result = $GLOBALS['xoopsDB']->query("SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS
1568
        //        WHERE TABLE_NAME = '" . $table . "' AND COLUMN_NAME = '" . $columnName . "'")
1569
        //    || exit ($GLOBALS['xoopsDB']->error());
1570
1571
        $sql    = 'SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = "' . $table . '" AND COLUMN_NAME = "' . $columnName . '"';
1572
        $result = $GLOBALS['xoopsDB']->query($sql);
1573
        if (!$result) {
1574
            exit($GLOBALS['xoopsDB']->error());
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

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

Loading history...
1575
        }
1576
1577
        $row      = $GLOBALS['xoopsDB']->fetchBoth($result);
1578
        $enumList = \explode(',', \str_replace("'", '', mb_substr($row['COLUMN_TYPE'], 5, -6)));
1579
1580
        return $enumList;
1581
    }
1582
1583
    /**
1584
     * @param array|string $tableName
1585
     * @param string       $id_field
1586
     * @param int          $id
1587
     *
1588
     * @return false|void
1589
     */
1590
    public static function cloneRecord($tableName, $id_field, $id)
1591
    {
1592
        $new_id = false;
1593
        $table  = $GLOBALS['xoopsDB']->prefix($tableName);
1594
        // copy content of the record you wish to clone
1595
        $tempTable = $GLOBALS['xoopsDB']->fetchArray($GLOBALS['xoopsDB']->query("SELECT * FROM $table WHERE $id_field='$id' "), \MYSQLI_ASSOC) or exit('Could not select record');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

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

Loading history...
1596
        // set the auto-incremented id's value to blank.
1597
        unset($tempTable[$id_field]);
1598
        // insert cloned copy of the original  record
1599
        $result = $GLOBALS['xoopsDB']->queryF("INSERT INTO $table (" . \implode(', ', \array_keys($tempTable)) . ") VALUES ('" . \implode("', '", \array_values($tempTable)) . "')") or exit($GLOBALS['xoopsDB']->error());
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

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

Loading history...
1600
1601
        if ($result) {
1602
            // Return the new id
1603
            $new_id = $GLOBALS['xoopsDB']->getInsertId();
1604
        }
1605
1606
        return $new_id;
1607
    }
1608
1609
    /**
1610
     * truncateHtml can truncate a string up to a number of characters while preserving whole words and HTML tags
1611
     * www.gsdesign.ro/blog/cut-html-string-without-breaking-the-tags
1612
     * www.cakephp.org
1613
     *
1614
     * @param string $text         String to truncate.
1615
     * @param int    $length       Length of returned string, including ellipsis.
1616
     * @param string $ending       Ending to be appended to the trimmed string.
1617
     * @param bool   $exact        If false, $text will not be cut mid-word
1618
     * @param bool   $considerHtml If true, HTML tags would be handled correctly
1619
     *
1620
     * @return string Trimmed string.
1621
     */
1622
    public static function truncateHtml($text, $length = 100, $ending = '...', $exact = false, $considerHtml = true)
1623
    {
1624
        if ($considerHtml) {
1625
            // if the plain text is shorter than the maximum length, return the whole text
1626
            if (mb_strlen(\preg_replace('/<.*?' . '>/', '', $text)) <= $length) {
1627
                return $text;
1628
            }
1629
            // splits all html-tags to scanable lines
1630
            \preg_match_all('/(<.+?' . '>)?([^<>]*)/s', $text, $lines, \PREG_SET_ORDER);
1631
            $total_length = mb_strlen($ending);
1632
            $open_tags    = [];
1633
            $truncate     = '';
1634
            foreach ($lines as $line_matchings) {
1635
                // if there is any html-tag in this line, handle it and add it (uncounted) to the output
1636
                if (!empty($line_matchings[1])) {
1637
                    // if it's an "empty element" with or without xhtml-conform closing slash
1638
                    if (\preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
1639
                        // do nothing
1640
                        // if tag is a closing tag
1641
                    } elseif (\preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
1642
                        // delete tag from $open_tags list
1643
                        $pos = \array_search($tag_matchings[1], $open_tags, true);
1644
                        if (false !== $pos) {
1645
                            unset($open_tags[$pos]);
1646
                        }
1647
                        // if tag is an opening tag
1648
                    } elseif (\preg_match('/^<\s*([^\s>!]+).*?' . '>$/s', $line_matchings[1], $tag_matchings)) {
1649
                        // add tag to the beginning of $open_tags list
1650
                        \array_unshift($open_tags, mb_strtolower($tag_matchings[1]));
1651
                    }
1652
                    // add html-tag to $truncate'd text
1653
                    $truncate .= $line_matchings[1];
1654
                }
1655
                // calculate the length of the plain text part of the line; handle entities as one character
1656
                $content_length = mb_strlen(\preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
1657
                if ($total_length + $content_length > $length) {
1658
                    // the number of characters which are left
1659
                    $left            = $length - $total_length;
1660
                    $entities_length = 0;
1661
                    // search for html entities
1662
                    if (\preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $line_matchings[2], $entities, \PREG_OFFSET_CAPTURE)) {
1663
                        // calculate the real length of all entities in the legal range
1664
                        foreach ($entities[0] as $entity) {
1665
                            if ($left >= $entity[1] + 1 - $entities_length) {
1666
                                $left--;
1667
                                $entities_length += mb_strlen($entity[0]);
1668
                            } else {
1669
                                // no more characters left
1670
                                break;
1671
                            }
1672
                        }
1673
                    }
1674
                    $truncate .= mb_substr($line_matchings[2], 0, $left + $entities_length);
1675
                    // maximum lenght is reached, so get off the loop
1676
                    break;
1677
                }
1678
                $truncate     .= $line_matchings[2];
1679
                $total_length += $content_length;
1680
1681
                // if the maximum length is reached, get off the loop
1682
                if ($total_length >= $length) {
1683
                    break;
1684
                }
1685
            }
1686
        } else {
1687
            if (mb_strlen($text) <= $length) {
1688
                return $text;
1689
            }
1690
            $truncate = mb_substr($text, 0, $length - mb_strlen($ending));
1691
        }
1692
        // if the words shouldn't be cut in the middle...
1693
        if (!$exact) {
1694
            // ...search the last occurance of a space...
1695
            $spacepos = mb_strrpos($truncate, ' ');
1696
            if (isset($spacepos)) {
1697
                // ...and cut the text in this position
1698
                $truncate = mb_substr($truncate, 0, $spacepos);
1699
            }
1700
        }
1701
        // add the defined ending to the text
1702
        $truncate .= $ending;
1703
        if ($considerHtml) {
1704
            // close all unclosed html-tags
1705
            foreach ($open_tags as $tag) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $open_tags does not seem to be defined for all execution paths leading up to this point.
Loading history...
1706
                $truncate .= '</' . $tag . '>';
1707
            }
1708
        }
1709
1710
        return $truncate;
1711
    }
1712
}
1713