Passed
Pull Request — master (#20)
by Goffy
03:16
created

Utility::getAlphaArray()   A

Complexity

Conditions 3
Paths 8

Size

Total Lines 60
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 30
nc 8
nop 0
dl 0
loc 60
rs 9.44
c 1
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A unichr() 0 3 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 XoopsForm
0 ignored issues
show
Bug introduced by
The type XoopsModules\Lexikon\XoopsForm was not found. Did you mean XoopsForm? If so, make sure to prefix the type with \.
Loading history...
417
     */
418
    public static function getFormSearch($type = '3', $categoryID = '0', $term = '')
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
        $action = $_SERVER['REQUEST_URI'];
0 ignored issues
show
Unused Code introduced by
The assignment to $action is dead and can be removed.
Loading history...
427
428
        // Get Theme Form
429
        \xoops_load('XoopsFormLoader');
430
        $form = new \XoopsThemeForm(_MD_LEXIKON_LOOKON, 'form', 'search.php', 'post', true);
431
        $form->setExtra('enctype="multipart/form-data"');
432
        // Form select search type
433
        $searchTypeSelect = new \XoopsFormSelect(\_MD_LEXIKON_LOOKON, 'type', $type);
434
        $searchTypeSelect->addOption('1', _MD_LEXIKON_TERMS);
435
        $searchTypeSelect->addOption('2', _MD_LEXIKON_DEFINS);
436
        $searchTypeSelect->addOption('3', _MD_LEXIKON_TERMSDEFS);
437
        $form->addElement($searchTypeSelect);
438
        // form select cats
439
        if (1 == $helper->getConfig('multicats')) {
440
            $resultcat  = $xoopsDB->query('SELECT categoryID, name FROM ' . $xoopsDB->prefix('lxcategories') . ' ORDER BY categoryID');
441
            $searchCatSelect = new \XoopsFormSelect(\_MD_LEXIKON_LOOKON, 'categoryID', $categoryID);
442
            $searchCatSelect->addOption(0, _MD_LEXIKON_ALLOFTHEM);
443
            while (list($categoryID, $name) = $xoopsDB->fetchRow($resultcat)) {
444
                if ($grouppermHandler->checkRight('lexikon_view', (int)$categoryID, $groups, $xoopsModule->getVar('mid'))) {
445
                    $searchCatSelect->addOption($categoryID, $categoryID . ' : ' . $name);
446
                }
447
            }
448
            $form->addElement($searchCatSelect);
449
        }
450
        // Form Text term
451
        $form->addElement(new \XoopsFormText(\_MD_LEXIKON_TERM, 'term', 30, 255, $term), true);
452
         // To Save
453
        $form->addElement(new \XoopsFormHidden('op', 'save'));
454
        $form->addElement(new \XoopsFormButton('', 'submit', \_MD_LEXIKON_SEARCH, 'submit'));
455
456
        return $form;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $form returns the type XoopsThemeForm which is incompatible with the documented return type XoopsModules\Lexikon\XoopsForm.
Loading history...
457
    }
458
    
459
    /**
460
     * @param $needle
461
     * @param $haystack
462
     * @param $hlS
463
     * @param $hlE
464
     * @return string
465
     */
466
    public static function getHTMLHighlight($needle, $haystack, $hlS, $hlE)
467
    {
468
        $parts = \explode('>', $haystack);
469
        foreach ($parts as $key => $part) {
470
            $pL = '';
471
            $pR = '';
472
473
            if (false === ($pos = mb_strpos($part, '<'))) {
474
                $pL = $part;
475
            } elseif ($pos > 0) {
476
                $pL = mb_substr($part, 0, $pos);
477
                $pR = mb_substr($part, $pos, mb_strlen($part));
478
            }
479
            if ('' != $pL) {
480
                $parts[$key] = \preg_replace('|(' . \quotemeta($needle) . ')|iU', $hlS . '\\1' . $hlE, $pL) . $pR;
481
            }
482
        }
483
484
        return \implode('>', $parts);
485
    }
486
487
    /* *******************************************************************************
488
     * Most of the following functions are modified functions from Herve's News Module
489
     * other functions are from  AMS by Novasmart/Mithrandir
490
     * others from Red Mexico Soft Rmdp
491
     * others from Xhelp 0.78 thanks to ackbarr and eric_juden
492
     * *******************************************************************************
493
     */
494
495
    // Create the meta keywords based on content
496
497
    /**
498
     * @param $content
499
     */
500
    public static function extractKeywords($content)
501
    {
502
        global $xoopsTpl, $xoTheme, $xoopsModule;
503
504
        $helper = Helper::getInstance();
505
        require_once XOOPS_ROOT_PATH . '/modules/lexikon/include/common.inc.php';
506
        $keywords_count = $helper->getConfig('metakeywordsnum');
507
        $tmp            = [];
508
        if (\Xmf\Request::hasVar('xoops_keywords_limit', 'SESSION')) {    // Search the "Minimum keyword length"
509
            $limit = $_SESSION['xoops_keywords_limit'];
510
        } else {
511
            /** @var \XoopsConfigHandler $configHandler */
512
            $configHandler                    = \xoops_getHandler('config');
513
            $xoopsConfigSearch                = $configHandler->getConfigsByCat(\XOOPS_CONF_SEARCH);
514
            $limit                            = $xoopsConfigSearch['keyword_min'];
515
            $_SESSION['xoops_keywords_limit'] = $limit;
516
        }
517
        $myts            = \MyTextSanitizer::getInstance();
518
        $content         = \str_replace('<br>', ' ', $content);
519
        $content         = $myts->undoHtmlSpecialChars($content);
520
        $content         = \strip_tags($content);
521
        $content         = mb_strtolower($content);
522
        $search_pattern  = [
523
            '&nbsp;',
524
            "\t",
525
            "\r\n",
526
            "\r",
527
            "\n",
528
            ',',
529
            '.',
530
            "'",
531
            ';',
532
            ':',
533
            ')',
534
            '(',
535
            '"',
536
            '?',
537
            '!',
538
            '{',
539
            '}',
540
            '[',
541
            ']',
542
            '<',
543
            '>',
544
            '/',
545
            '+',
546
            '-',
547
            '_',
548
            '\\',
549
            '*',
550
        ];
551
        $replace_pattern = [
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
        ];
580
        $content         = \str_replace($search_pattern, $replace_pattern, $content);
581
        $keywords        = \explode(' ', $content);
582
        switch (\META_KEYWORDS_ORDER) {
583
            case 1:    // Returns keywords in the same order that they were created in the text
584
                $keywords = \array_unique($keywords);
585
                break;
586
            case 2:    // the keywords order is made according to the reverse keywords frequency (so the less frequent words appear in first in the list)
587
                $keywords = \array_count_values($keywords);
588
                \asort($keywords);
589
                $keywords = \array_keys($keywords);
590
                break;
591
            case 3:    // Same as previous, the only difference is that the most frequent words will appear in first in the list
592
                $keywords = \array_count_values($keywords);
593
                \arsort($keywords);
594
                $keywords = \array_keys($keywords);
595
                break;
596
        }
597
        foreach ($keywords as $keyword) {
598
            if (mb_strlen($keyword) >= $limit && !\is_numeric($keyword)) {
599
                $tmp[] = $keyword;
600
            }
601
        }
602
        $tmp = \array_slice($tmp, 0, $keywords_count);
603
        if (\count($tmp) > 0) {
604
            if (isset($xoTheme) && \is_object($xoTheme)) {
605
                $xoTheme->addMeta('meta', 'keywords', \implode(',', $tmp));
606
            } else {    // Compatibility for old Xoops versions
607
                $xoopsTpl->assign('xoops_meta_keywords', \implode(',', $tmp));
608
            }
609
        } else {
610
            if (!isset($configHandler) || !\is_object($configHandler)) {
611
                $configHandler = \xoops_getHandler('config');
612
            }
613
            $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

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

795
        $editor_option            = mb_strtolower(/** @scrutinizer ignore-type */ static::getModuleOption('form_options'));
Loading history...
796
        $editor                   = false;
797
        $editor_configs           = [];
798
        $editor_configs['name']   = $name;
799
        $editor_configs['value']  = $value;
800
        $editor_configs['rows']   = 35;
801
        $editor_configs['cols']   = 60;
802
        $editor_configs['width']  = '100%';
803
        $editor_configs['height'] = '350px';
804
        $editor_configs['editor'] = $editor_option;
805
806
        if (static::isX23()) {
807
            $editor = new \XoopsFormEditor($caption, $name, $editor_configs);
808
809
            return $editor;
810
        }
811
812
        // Only for Xoops 2.0.x
813
        switch ($editor_option) {
814
            case 'fckeditor':
815
                if (\is_readable(XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php')) {
816
                    require_once XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php';
817
                    $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...
818
                }
819
                break;
820
            case 'htmlarea':
821
                if (\is_readable(XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php')) {
822
                    require_once XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php';
823
                    $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...
824
                }
825
                break;
826
            case 'dhtmltextarea':
827
            case 'dhtml':
828
                $editor = new \XoopsFormDhtmlTextArea($caption, $name, $value, 10, 50, $supplemental);
829
                break;
830
            case 'textarea':
831
                $editor = new \XoopsFormTextArea($caption, $name, $value);
832
                break;
833
            case 'tinyeditor':
834
            case 'tinymce':
835
                if (\is_readable(XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php')) {
836
                    require_once XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php';
837
                    $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...
838
                        [
839
                            'caption' => $caption,
840
                            'name'    => $name,
841
                            'value'   => $value,
842
                            'width'   => '100%',
843
                            'height'  => '400px',
844
                        ]
845
                    );
846
                }
847
                break;
848
            case 'koivi':
849
                if (\is_readable(XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php')) {
850
                    require_once XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php';
851
                    $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...
852
                }
853
                break;
854
        }
855
856
        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...
857
    }
858
859
    /**
860
     * @param \Xmf\Module\Helper $helper
861
     * @param array|null         $options
862
     * @return \XoopsFormDhtmlTextArea|\XoopsFormEditor
863
     */
864
    public static function getEditor($helper = null, $options = null)
865
    {
866
867
        if (null === $options) {
868
            $options           = [];
869
            $options['name']   = 'Editor';
870
            $options['value']  = 'Editor';
871
            $options['rows']   = 10;
872
            $options['cols']   = '100%';
873
            $options['width']  = '100%';
874
            $options['height'] = '400px';
875
        }
876
877
        if (null === $helper) {
878
            $helper = Helper::getInstance();
879
        }
880
881
        $isAdmin = $helper->isUserAdmin();
882
883
        if (\class_exists('XoopsFormEditor')) {
884
            if ($isAdmin) {
885
                $descEditor = new \XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorAdmin'), $options, $nohtml = false, $onfailure = 'textarea');
886
            } else {
887
                $descEditor = new \XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorUser'), $options, $nohtml = false, $onfailure = 'textarea');
888
            }
889
        } else {
890
            $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 $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

890
            $descEditor = new \XoopsFormDhtmlTextArea(\ucfirst($options['name']), $options['name'], $options['value'], '100%', /** @scrutinizer ignore-type */ '100%');
Loading history...
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

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

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

1019
                    'date'    => \date(/** @scrutinizer ignore-type */ $helper->getConfig('dateformat'), $row['datesub']),
Loading history...
1020
                    'counter' => $row['counter'],
1021
                ]
1022
            );
1023
        }
1024
1025
        $navstring                = '';
1026
        $navstring                .= 'uid=' . $uid . '&start';
1027
        $pagenav                  = new \XoopsPageNav($authortermstotal, $helper->getConfig('indexperpage'), $start, $navstring);
1028
        $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...
1029
        $xoopsTpl->assign('authortermsarr', $authortermsarr);
1030
    }
1031
1032
    // Returns the author's IDs for authorslist
1033
1034
    /**
1035
     * @param int $limit
1036
     * @param int $start
1037
     * @return array
1038
     */
1039
    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

1039
    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

1039
    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...
1040
    {
1041
        global $xoopsDB;
1042
1043
        $ret    = [];
1044
        $sql    = 'SELECT DISTINCT(uid) AS uid FROM ' . $xoopsDB->prefix('lxentries') . ' WHERE offline = 0 ';
1045
        $sql    .= ' ORDER BY uid';
1046
        $result = $xoopsDB->query($sql);
1047
        while (false !== ($myrow = $xoopsDB->fetchArray($result))) {
1048
            $ret[] = $myrow['uid'];
1049
        }
1050
1051
        return $ret;
1052
    }
1053
1054
    // link to userprofile
1055
1056
    /**
1057
     * @param $userid
1058
     * @return string
1059
     */
1060
    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

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

1489
        $pathModIcon16 = XOOPS_URL . '/modules/' . $moduleDirName . '/' . /** @scrutinizer ignore-type */ $helper->getModule()->getInfo('modicons16');
Loading history...
1490
1491
        $select_view = '<form name="form_switch" id="form_switch" action="' . Request::getString('REQUEST_URI', '', 'SERVER') . '" method="post"><span style="font-weight: bold;">' . $text . '</span>';
1492
        //$sorts =  $sort ==  'asc' ? 'desc' : 'asc';
1493
        if ($form_sort == $sort) {
1494
            $sel1 = 'asc' === $order ? 'selasc.png' : 'asc.png';
1495
            $sel2 = 'desc' === $order ? 'seldesc.png' : 'desc.png';
1496
        } else {
1497
            $sel1 = 'asc.png';
1498
            $sel2 = 'desc.png';
1499
        }
1500
        $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>';
1501
        $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>';
1502
        $select_view .= '</form>';
1503
1504
        return $select_view;
1505
    }
1506
1507
    /***************Blocks***************/
1508
1509
    /**
1510
     * @param array $cats
1511
     * @return string
1512
     */
1513
    public static function block_addCatSelect($cats)
1514
    {
1515
        $cat_sql = '';
1516
        if (\is_array($cats)) {
0 ignored issues
show
introduced by
The condition is_array($cats) is always true.
Loading history...
1517
            $cat_sql = '(' . \current($cats);
1518
            \array_shift($cats);
1519
            foreach ($cats as $cat) {
1520
                $cat_sql .= ',' . $cat;
1521
            }
1522
            $cat_sql .= ')';
1523
        }
1524
1525
        return $cat_sql;
1526
    }
1527
1528
    /**
1529
     * @param $content
1530
     */
1531
    public static function meta_keywords($content)
1532
    {
1533
        global $xoopsTpl, $xoTheme;
1534
        $myts    = \MyTextSanitizer::getInstance();
1535
        $content = $myts->undoHtmlSpecialChars($myts->displayTarea($content));
1536
        if (null !== $xoTheme && \is_object($xoTheme)) {
1537
            $xoTheme->addMeta('meta', 'keywords', \strip_tags($content));
1538
        } else {    // Compatibility for old Xoops versions
1539
            $xoopsTpl->assign('xoops_meta_keywords', \strip_tags($content));
1540
        }
1541
    }
1542
1543
    /**
1544
     * @param $content
1545
     */
1546
    public static function meta_description($content)
1547
    {
1548
        global $xoopsTpl, $xoTheme;
1549
        $myts    = \MyTextSanitizer::getInstance();
1550
        $content = $myts->undoHtmlSpecialChars($myts->displayTarea($content));
1551
        if (null !== $xoTheme && \is_object($xoTheme)) {
1552
            $xoTheme->addMeta('meta', 'description', \strip_tags($content));
1553
        } else {    // Compatibility for old Xoops versions
1554
            $xoopsTpl->assign('xoops_meta_description', \strip_tags($content));
1555
        }
1556
    }
1557
1558
    /**
1559
     * @param $tableName
1560
     * @param $columnName
1561
     *
1562
     * @return array
1563
     */
1564
    public static function enumerate($tableName, $columnName)
1565
    {
1566
        $table = $GLOBALS['xoopsDB']->prefix($tableName);
1567
1568
        //    $result = $GLOBALS['xoopsDB']->query("SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS
1569
        //        WHERE TABLE_NAME = '" . $table . "' AND COLUMN_NAME = '" . $columnName . "'")
1570
        //    || exit ($GLOBALS['xoopsDB']->error());
1571
1572
        $sql    = 'SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = "' . $table . '" AND COLUMN_NAME = "' . $columnName . '"';
1573
        $result = $GLOBALS['xoopsDB']->query($sql);
1574
        if (!$result) {
1575
            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...
1576
        }
1577
1578
        $row      = $GLOBALS['xoopsDB']->fetchBoth($result);
1579
        $enumList = \explode(',', \str_replace("'", '', mb_substr($row['COLUMN_TYPE'], 5, -6)));
1580
1581
        return $enumList;
1582
    }
1583
1584
    /**
1585
     * @param array|string $tableName
1586
     * @param string       $id_field
1587
     * @param int          $id
1588
     *
1589
     * @return false|void
1590
     */
1591
    public static function cloneRecord($tableName, $id_field, $id)
1592
    {
1593
        $new_id = false;
1594
        $table  = $GLOBALS['xoopsDB']->prefix($tableName);
1595
        // copy content of the record you wish to clone
1596
        $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...
1597
        // set the auto-incremented id's value to blank.
1598
        unset($tempTable[$id_field]);
1599
        // insert cloned copy of the original  record
1600
        $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...
1601
1602
        if ($result) {
1603
            // Return the new id
1604
            $new_id = $GLOBALS['xoopsDB']->getInsertId();
1605
        }
1606
1607
        return $new_id;
1608
    }
1609
1610
    /**
1611
     * truncateHtml can truncate a string up to a number of characters while preserving whole words and HTML tags
1612
     * www.gsdesign.ro/blog/cut-html-string-without-breaking-the-tags
1613
     * www.cakephp.org
1614
     *
1615
     * @param string $text         String to truncate.
1616
     * @param int    $length       Length of returned string, including ellipsis.
1617
     * @param string $ending       Ending to be appended to the trimmed string.
1618
     * @param bool   $exact        If false, $text will not be cut mid-word
1619
     * @param bool   $considerHtml If true, HTML tags would be handled correctly
1620
     *
1621
     * @return string Trimmed string.
1622
     */
1623
    public static function truncateHtml($text, $length = 100, $ending = '...', $exact = false, $considerHtml = true)
1624
    {
1625
        if ($considerHtml) {
1626
            // if the plain text is shorter than the maximum length, return the whole text
1627
            if (mb_strlen(\preg_replace('/<.*?' . '>/', '', $text)) <= $length) {
1628
                return $text;
1629
            }
1630
            // splits all html-tags to scanable lines
1631
            \preg_match_all('/(<.+?' . '>)?([^<>]*)/s', $text, $lines, \PREG_SET_ORDER);
1632
            $total_length = mb_strlen($ending);
1633
            $open_tags    = [];
1634
            $truncate     = '';
1635
            foreach ($lines as $line_matchings) {
1636
                // if there is any html-tag in this line, handle it and add it (uncounted) to the output
1637
                if (!empty($line_matchings[1])) {
1638
                    // if it's an "empty element" with or without xhtml-conform closing slash
1639
                    if (\preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
1640
                        // do nothing
1641
                        // if tag is a closing tag
1642
                    } elseif (\preg_match('/^<\s*\/(\S+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
1643
                        // delete tag from $open_tags list
1644
                        $pos = \array_search($tag_matchings[1], $open_tags, true);
1645
                        if (false !== $pos) {
1646
                            unset($open_tags[$pos]);
1647
                        }
1648
                        // if tag is an opening tag
1649
                    } elseif (\preg_match('/^<\s*([^\s>!]+).*?' . '>$/s', $line_matchings[1], $tag_matchings)) {
1650
                        // add tag to the beginning of $open_tags list
1651
                        \array_unshift($open_tags, mb_strtolower($tag_matchings[1]));
1652
                    }
1653
                    // add html-tag to $truncate'd text
1654
                    $truncate .= $line_matchings[1];
1655
                }
1656
                // calculate the length of the plain text part of the line; handle entities as one character
1657
                $content_length = mb_strlen(\preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
1658
                if ($total_length + $content_length > $length) {
1659
                    // the number of characters which are left
1660
                    $left            = $length - $total_length;
1661
                    $entities_length = 0;
1662
                    // search for html entities
1663
                    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)) {
1664
                        // calculate the real length of all entities in the legal range
1665
                        foreach ($entities[0] as $entity) {
1666
                            if ($left >= $entity[1] + 1 - $entities_length) {
1667
                                $left--;
1668
                                $entities_length += mb_strlen($entity[0]);
1669
                            } else {
1670
                                // no more characters left
1671
                                break;
1672
                            }
1673
                        }
1674
                    }
1675
                    $truncate .= mb_substr($line_matchings[2], 0, $left + $entities_length);
1676
                    // maximum lenght is reached, so get off the loop
1677
                    break;
1678
                }
1679
                $truncate     .= $line_matchings[2];
1680
                $total_length += $content_length;
1681
1682
                // if the maximum length is reached, get off the loop
1683
                if ($total_length >= $length) {
1684
                    break;
1685
                }
1686
            }
1687
        } else {
1688
            if (mb_strlen($text) <= $length) {
1689
                return $text;
1690
            }
1691
            $truncate = mb_substr($text, 0, $length - mb_strlen($ending));
1692
        }
1693
        // if the words shouldn't be cut in the middle...
1694
        if (!$exact) {
1695
            // ...search the last occurance of a space...
1696
            $spacepos = mb_strrpos($truncate, ' ');
1697
            if (isset($spacepos)) {
1698
                // ...and cut the text in this position
1699
                $truncate = mb_substr($truncate, 0, $spacepos);
1700
            }
1701
        }
1702
        // add the defined ending to the text
1703
        $truncate .= $ending;
1704
        if ($considerHtml) {
1705
            // close all unclosed html-tags
1706
            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...
1707
                $truncate .= '</' . $tag . '>';
1708
            }
1709
        }
1710
1711
        return $truncate;
1712
    }
1713
}
1714