Passed
Pull Request — master (#41)
by Michael
13:46
created

Utility::getWysiwygForm()   B

Complexity

Conditions 8
Paths 9

Size

Total Lines 46
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 33
c 0
b 0
f 0
nc 9
nop 6
dl 0
loc 46
rs 8.1475
1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\News;
4
5
use WideImage\WideImage;
6
use Xmf\Request;
7
8
/**
9
 * Class Utility
10
 */
11
class Utility extends Common\SysUtility
12
{
13
    //--------------- Custom module methods -----------------------------
14
    /**
15
     * @param string $option
16
     * @param string $repmodule
17
     * @return mixed
18
     */
19
    public static function getModuleOption(string $option, string $repmodule = 'news')
20
    {
21
        global $xoopsModuleConfig, $xoopsModule;
22
        static $tbloptions = [];
23
        if (\is_array($tbloptions) && \array_key_exists($option, $tbloptions)) {
24
            return $tbloptions[$option];
25
        }
26
27
        $retval = false;
28
        if (isset($xoopsModuleConfig)
29
            && (\is_object($xoopsModule) && $xoopsModule->getVar('dirname') == $repmodule
30
                && $xoopsModule->getVar('isactive'))) {
31
            if (isset($xoopsModuleConfig[$option])) {
32
                $retval = $xoopsModuleConfig[$option];
33
            }
34
        } else {
35
            /** @var \XoopsModuleHandler $moduleHandler */
36
            $moduleHandler = \xoops_getHandler('module');
37
            $module        = $moduleHandler->getByDirname($repmodule);
38
            /** @var XoopsConfigHandler $configHandler */
39
            $configHandler = \xoops_getHandler('config');
40
            if ($module) {
41
                $moduleConfig = $configHandler->getConfigsByCat(0, $module->getVar('mid'));
42
                if (isset($moduleConfig[$option])) {
43
                    $retval = $moduleConfig[$option];
44
                }
45
            }
46
        }
47
        $tbloptions[$option] = $retval;
48
49
        return $retval;
50
    }
51
52
    /**
53
     * Updates rating data in item table for a given item
54
     *
55
     * @param int $storyid
56
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
57
     * @copyright (c) Hervé Thouzard
58
     */
59
    public static function updateRating(int $storyid): void
60
    {
61
        global $xoopsDB;
62
        $sql         = 'SELECT rating FROM ' . $xoopsDB->prefix('news_stories_votedata') . ' WHERE storyid = ' . $storyid;
63
        $result      = self::queryAndCheck($xoopsDB, $sql);
64
        $votesDB     = $xoopsDB->getRowsNum($result);
65
        $totalrating = 0;
66
        while ([$rating] = $xoopsDB->fetchRow($result)) {
67
            $totalrating += $rating;
68
        }
69
        $finalrating = $totalrating / $votesDB;
70
        $finalrating = \number_format((float)$finalrating, 4);
71
        $sql         = \sprintf('UPDATE `%s` SET rating = %u, votes = %u WHERE storyid = %u', $xoopsDB->prefix('news_stories'), $finalrating, $votesDB, $storyid);
72
        $xoopsDB->queryF($sql);
73
    }
74
75
    /**
76
     * Internal function for permissions
77
     *
78
     * Returns a list of all the permitted topics Ids for the current user
79
     *
80
     * @param string $permtype
81
     *
82
     * @return array    Permitted topics Ids
83
     *
84
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
85
     * @copyright (c) Hervé Thouzard
86
     */
87
    public static function getMyItemIds(string $permtype = 'news_view'): array
88
    {
89
        global $xoopsUser;
90
        static $tblperms = [];
91
        if (\is_array($tblperms) && \array_key_exists($permtype, $tblperms)) {
92
            return $tblperms[$permtype];
93
        }
94
95
        /** @var \XoopsModuleHandler $moduleHandler */
96
        $moduleHandler       = \xoops_getHandler('module');
97
        $newsModule          = $moduleHandler->getByDirname('news');
98
        $groups              = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
99
        $grouppermHandler    = \xoops_getHandler('groupperm');
100
        $topics              = $grouppermHandler->getItemIds($permtype, $groups, $newsModule->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

100
        /** @scrutinizer ignore-call */ 
101
        $topics              = $grouppermHandler->getItemIds($permtype, $groups, $newsModule->getVar('mid'));
Loading history...
101
        $tblperms[$permtype] = $topics;
102
103
        return $topics;
104
    }
105
106
    /**
107
     * @param $document
108
     *
109
     * @return array|string|string[]|null
110
     */
111
    public static function html2text($document)
112
    {
113
        // PHP Manual:: function preg_replace
114
        // $document should contain an HTML document.
115
        // This will remove HTML tags, javascript sections
116
        // and white space. It will also convert some
117
        // common HTML entities to their text equivalent.
118
119
        $search = [
120
            "'<script[^>]*?>.*?</script>'si", // Strip out javascript
121
            "'<img.*?>'si", // Strip out img tags
122
            "'<[\/\!]*?[^<>]*?>'i", // Strip out HTML tags
123
            "'([\r\n])[\s]+'", // Strip out white space
124
            "'&(quot|#34);'i", // Replace HTML entities
125
            "'&(amp|#38);'i",
126
            "'&(lt|#60);'i",
127
            "'&(gt|#62);'i",
128
            "'&(nbsp|#160);'i",
129
            "'&(iexcl|#161);'i",
130
            "'&(cent|#162);'i",
131
            "'&(pound|#163);'i",
132
            "'&(copy|#169);'i",
133
        ]; // evaluate as php
134
135
        $replace = [
136
            '',
137
            '',
138
            '',
139
            '\\1',
140
            '"',
141
            '&',
142
            '<',
143
            '>',
144
            ' ',
145
            \chr(161),
146
            \chr(162),
147
            \chr(163),
148
            \chr(169),
149
        ];
150
151
        $text = \preg_replace($search, $replace, $document);
152
153
        \preg_replace_callback(
154
            '/&#(\d+);/',
155
            static function ($matches) {
156
                return \chr($matches[1]);
157
            },
158
            $document
159
        );
160
161
        return $text;
162
    }
163
164
    /**
165
     * Is Xoops 2.3.x ?
166
     *
167
     * @return bool need to say it ?
168
     */
169
    public static function isX23(): bool
170
    {
171
        $x23 = false;
172
        $xv  = \str_replace('XOOPS ', '', \XOOPS_VERSION);
173
        if (mb_substr($xv, 2, 1) >= '3') {
174
            $x23 = true;
175
        }
176
177
        return $x23;
178
    }
179
180
    /**
181
     * Retrieve an editor according to the module's option "form_options"
182
     *
183
     * @param string $caption
184
     * @param string $name
185
     * @param string $value
186
     * @param int $width
187
     * @param int $height
188
     * @param string $supplemental
189
     * @return bool|\XoopsFormEditor|\XoopsFormTextArea
190
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
191
     * @copyright (c) Hervé Thouzard
192
     */
193
    public static function getWysiwygForm(string $caption, string $name, string $value = '', int $width = 15, int $height = 60, string $supplemental = '')
194
    {
195
        $editor_option            = \mb_strtolower(static::getModuleOption('form_options'));
196
        $editor                   = false;
197
        $editor_configs           = [];
198
        $editor_configs['name']   = $name;
199
        $editor_configs['value']  = $value;
200
        $editor_configs['rows']   = 35;
201
        $editor_configs['cols']   = 60;
202
        $editor_configs['width']  = (string)$width;
203
        $editor_configs['height'] = (string)$height;
204
        $editor_configs['editor'] = $editor_option;
205
206
        if (static::isX23()) {
207
            $editor = new \XoopsFormEditor($caption, $name, $editor_configs);
208
209
            return $editor;
210
        }
211
212
        // Only for Xoops 2.0.x
213
        switch ($editor_option) {
214
            case 'dhtmltextarea':
215
            case 'dhtml':
216
                $editor = new \XoopsFormDhtmlTextArea($caption, $name, $value, 10, 50, $supplemental);
217
                break;
218
            case 'textarea':
219
                $editor = new \XoopsFormTextArea($caption, $name, $value);
220
                break;
221
            case 'tinyeditor':
222
            case 'tinymce':
223
                if (\is_readable(XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php')) {
224
                    require_once XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php';
225
                    $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...
226
                        [
227
                            'caption' => $caption,
228
                            'name'    => $name,
229
                            'value'   => $value,
230
                            'width'   => '100%',
231
                            'height'  => '400px',
232
                        ]
233
                    );
234
                }
235
                break;
236
        }
237
238
        return $editor;
239
    }
240
241
//    /**
242
//     * @param \Xmf\Module\Helper|null $helper
243
//     * @param array|null              $options
244
//     * @return \XoopsFormDhtmlTextArea|\XoopsFormEditor
245
//     */
246
//    public static function getEditor(?\Xmf\Module\Helper $helper = null, ?array $options = null)
247
//    {
248
//        /** @var Helper $helper */
249
//        if (null === $options) {
250
//            $options           = [];
251
//            $options['name']   = 'Editor';
252
//            $options['value']  = 'Editor';
253
//            $options['rows']   = 10;
254
//            $options['cols']   = '100%';
255
//            $options['width']  = '100%';
256
//            $options['height'] = '400px';
257
//        }
258
//
259
//        if (null === $helper) {
260
//            $helper = Helper::getInstance();
261
//        }
262
//
263
//        $isAdmin = $helper->isUserAdmin();
264
//
265
//        if (\class_exists('XoopsFormEditor')) {
266
//            if ($isAdmin) {
267
//                $descEditor = new \XoopsFormEditor(\ucfirst((string) $options['name']), $helper->getConfig('editorAdmin'), $options, $nohtml = false, $onfailure = 'textarea');
268
//            } else {
269
//                $descEditor = new \XoopsFormEditor(\ucfirst((string) $options['name']), $helper->getConfig('editorUser'), $options, $nohtml = false, $onfailure = 'textarea');
270
//            }
271
//        } else {
272
//            $descEditor = new \XoopsFormDhtmlTextArea(\ucfirst((string) $options['name']), $options['name'], $options['value']);
273
//        }
274
//
275
//        //        $form->addElement($descEditor);
276
//
277
//        return $descEditor;
278
//    }
279
280
    /**
281
     * Internal function
282
     *
283
     * @param string $text
284
     * @return array|string|string[]
285
     * @copyright (c) Hervé Thouzard
286
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
287
     */
288
    public static function getDublinQuotes(string $text)
289
    {
290
        return \str_replace('"', ' ', $text);
291
    }
292
293
    /**
294
     * Creates all the metadatas :
295
     * - For Mozilla/Netscape and Opera the site navigation's bar
296
     * - The Dublin's Core Metadata
297
     * - The link for Firefox 2 micro summaries
298
     * - The meta keywords
299
     * - The meta description
300
     *
301
     * @param object|null $story
302
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
303
     * @copyright (c) Hervé Thouzard
304
     */
305
    public static function createMetaDatas($story = null): void
306
    {
307
        global $xoopsConfig, $xoTheme, $xoopsTpl;
308
        $content = '';
309
        $myts    = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
310
        //        require_once XOOPS_ROOT_PATH . '/modules/news/class/class.newstopic.php';
311
312
        /**
313
         * Firefox and Opera Navigation's Bar
314
         */
315
        if (static::getModuleOption('sitenavbar')) {
316
            $content .= \sprintf("<link rel=\"Home\" title=\"%s\" href=\"%s/\">\n", $xoopsConfig['sitename'], XOOPS_URL);
317
            $content .= \sprintf("<link rel=\"Contents\" href=\"%s\">\n", XOOPS_URL . '/modules/news/index.php');
318
            $content .= \sprintf("<link rel=\"Search\" href=\"%s\">\n", XOOPS_URL . '/search.php');
319
            $content .= \sprintf("<link rel=\"Glossary\" href=\"%s\">\n", XOOPS_URL . '/modules/news/archive.php');
320
            $content .= \sprintf("<link rel=\"%s\" href=\"%s\">\n", \htmlspecialchars(_NW_SUBMITNEWS, \ENT_QUOTES | \ENT_HTML5), XOOPS_URL . '/modules/news/submit.php');
321
            $content .= \sprintf("<link rel=\"alternate\" type=\"application/rss+xml\" title=\"%s\" href=\"%s/\">\n", $xoopsConfig['sitename'], XOOPS_URL . '/backend.php');
322
323
            // Create chapters
324
            require_once XOOPS_ROOT_PATH . '/class/tree.php';
325
            //            require_once XOOPS_ROOT_PATH . '/modules/news/class/class.newstopic.php';
326
            $xt         = new NewsTopic();
327
            $allTopics  = $xt->getAllTopics(static::getModuleOption('restrictindex'));
328
            $topic_tree = new \XoopsObjectTree($allTopics, 'topic_id', 'topic_pid');
329
            $topics_arr = $topic_tree->getAllChild(0);
330
            foreach ($topics_arr as $onetopic) {
331
                $content .= \sprintf("<link rel=\"Chapter\" title=\"%s\" href=\"%s\">\n", $onetopic->topic_title(), XOOPS_URL . '/modules/news/index.php?storytopic=' . $onetopic->topic_id());
332
            }
333
        }
334
335
        /**
336
         * Meta Keywords and Description
337
         * If you have set this module's option to 'yes' and if the information was entered, then they are rendered in the page else they are computed
338
         */
339
        $meta_keywords = '';
340
        if (isset($story) && \is_object($story)) {
341
            if ('' !== \xoops_trim($story->keywords())) {
342
                $meta_keywords = $story->keywords();
343
            } else {
344
                $meta_keywords = static::createMetaKeywords($story->hometext() . ' ' . $story->bodytext());
345
            }
346
            if ('' !== \xoops_trim($story->description())) {
347
                $meta_description = \strip_tags($story->description);
348
            } else {
349
                $meta_description = \strip_tags($story->title);
350
            }
351
            if (isset($xoTheme) && \is_object($xoTheme)) {
352
                $xoTheme->addMeta('meta', 'keywords', $meta_keywords);
353
                $xoTheme->addMeta('meta', 'description', $meta_description);
354
            } elseif (isset($xoopsTpl) && \is_object($xoopsTpl)) { // Compatibility for old Xoops versions
355
                $xoopsTpl->assign('xoops_meta_keywords', $meta_keywords);
356
                $xoopsTpl->assign('xoops_meta_description', $meta_description);
357
            }
358
        }
359
360
        /**
361
         * Dublin Core's metadatas
362
         */
363
        if (static::getModuleOption('dublincore') && isset($story) && \is_object($story)) {
364
            /** @var XoopsConfigHandler $configHandler */
365
            $configHandler         = \xoops_getHandler('config');
366
            $xoopsConfigMetaFooter = $configHandler->getConfigsByCat(\XOOPS_CONF_METAFOOTER);
367
            $content               .= '<meta name="DC.Title" content="' . static::getDublinQuotes($story->title()) . "\">\n";
368
            $content               .= '<meta name="DC.Creator" content="' . static::getDublinQuotes($story->uname()) . "\">\n";
369
            $content               .= '<meta name="DC.Subject" content="' . static::getDublinQuotes($meta_keywords) . "\">\n";
370
            $content               .= '<meta name="DC.Description" content="' . static::getDublinQuotes($story->title()) . "\">\n";
371
            $content               .= '<meta name="DC.Publisher" content="' . static::getDublinQuotes($xoopsConfig['sitename']) . "\">\n";
372
            $content               .= '<meta name="DC.Date.created" scheme="W3CDTF" content="' . \date('Y-m-d', $story->created) . "\">\n";
373
            $content               .= '<meta name="DC.Date.issued" scheme="W3CDTF" content="' . \date('Y-m-d', $story->published) . "\">\n";
374
            $content               .= '<meta name="DC.Identifier" content="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $story->storyid() . "\">\n";
375
            $content               .= '<meta name="DC.Source" content="' . XOOPS_URL . "\">\n";
376
            $content               .= '<meta name="DC.Language" content="' . \_LANGCODE . "\">\n";
377
            $content               .= '<meta name="DC.Relation.isReferencedBy" content="' . XOOPS_URL . '/modules/news/index.php?storytopic=' . $story->topicid() . "\">\n";
378
            if (isset($xoopsConfigMetaFooter['meta_copyright'])) {
379
                $content .= '<meta name="DC.Rights" content="' . static::getDublinQuotes($xoopsConfigMetaFooter['meta_copyright']) . "\">\n";
380
            }
381
        }
382
383
        /**
384
         * Firefox 2 micro summaries
385
         */
386
        if (static::getModuleOption('firefox_microsummaries')) {
387
            $content .= \sprintf("<link rel=\"microsummary\" href=\"%s\">\n", XOOPS_URL . '/modules/news/micro_summary.php');
388
        }
389
390
        if (isset($xoopsTpl) && \is_object($xoopsTpl)) {
391
            $xoopsTpl->assign('xoops_module_header', $content);
392
        }
393
    }
394
395
    /**
396
     * Create the meta keywords based on the content
397
     *
398
     * @param string $content
399
     * @return string
400
     * @copyright (c) Hervé Thouzard
401
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
402
     */
403
    public static function createMetaKeywords(string $content): string
404
    {
405
        global $cfg;
406
        require_once XOOPS_ROOT_PATH . '/modules/news/config.php';
407
        // require_once XOOPS_ROOT_PATH . '/modules/news/class/blacklist.php';
408
        // require_once XOOPS_ROOT_PATH . '/modules/news/class/registryfile.php';
409
410
        if (!$cfg['meta_keywords_auto_generate']) {
411
            return '';
412
        }
413
        $registry = new Registryfile('news_metagen_options.txt');
414
        //    $tcontent = '';
415
        $tcontent = $registry->getfile();
416
        if ('' !== \xoops_trim($tcontent)) {
417
            [$keywordscount, $keywordsorder] = \explode(',', $tcontent);
418
        } else {
419
            $keywordscount = $cfg['meta_keywords_count'];
420
            $keywordsorder = $cfg['meta_keywords_order'];
421
        }
422
423
        $tmp = [];
424
        // Search for the "Minimum keyword length"
425
        if (Request::hasVar('news_keywords_limit', 'SESSION')) {
426
            $limit = $_SESSION['news_keywords_limit'];
427
        } else {
428
            /** @var XoopsConfigHandler $configHandler */
429
            $configHandler                   = \xoops_getHandler('config');
430
            $xoopsConfigSearch               = $configHandler->getConfigsByCat(\XOOPS_CONF_SEARCH);
431
            $limit                           = $xoopsConfigSearch['keyword_min'];
432
            $_SESSION['news_keywords_limit'] = $limit;
433
        }
434
        $myts            = \MyTextSanitizer::getInstance();
435
        $content         = \str_replace('<br>', ' ', $content);
436
        $content         = $myts->undoHtmlSpecialChars($content);
437
        $content         = \strip_tags($content);
438
        $content         = \mb_strtolower($content);
439
        $search_pattern  = [
440
            '&nbsp;',
441
            "\t",
442
            "\r\n",
443
            "\r",
444
            "\n",
445
            ',',
446
            '.',
447
            "'",
448
            ';',
449
            ':',
450
            ')',
451
            '(',
452
            '"',
453
            '?',
454
            '!',
455
            '{',
456
            '}',
457
            '[',
458
            ']',
459
            '<',
460
            '>',
461
            '/',
462
            '+',
463
            '-',
464
            '_',
465
            '\\',
466
            '*',
467
        ];
468
        $replace_pattern = [
469
            ' ',
470
            ' ',
471
            ' ',
472
            ' ',
473
            ' ',
474
            ' ',
475
            ' ',
476
            ' ',
477
            '',
478
            '',
479
            '',
480
            '',
481
            '',
482
            '',
483
            '',
484
            '',
485
            '',
486
            '',
487
            '',
488
            '',
489
            '',
490
            '',
491
            '',
492
            '',
493
            '',
494
            '',
495
            '',
496
        ];
497
        $content         = \str_replace($search_pattern, $replace_pattern, $content);
498
        $keywords        = \explode(' ', $content);
499
        switch ($keywordsorder) {
500
            case 0: // Ordre d'apparition dans le texte
501
                $keywords = \array_unique($keywords);
502
                break;
503
            case 1: // Ordre de fréquence des mots
504
                $keywords = \array_count_values($keywords);
505
                \asort($keywords);
506
                $keywords = \array_keys($keywords);
507
                break;
508
            case 2: // Ordre inverse de la fréquence des mots
509
                $keywords = \array_count_values($keywords);
510
                \arsort($keywords);
511
                $keywords = \array_keys($keywords);
512
                break;
513
        }
514
        // Remove black listed words
515
        $metablack = new Blacklist();
516
        $words     = $metablack->getAllKeywords();
0 ignored issues
show
Unused Code introduced by
The assignment to $words is dead and can be removed.
Loading history...
517
        $keywords  = $metablack->remove_blacklisted($keywords);
518
519
        foreach ($keywords as $keyword) {
520
            if (mb_strlen($keyword) >= $limit && !\is_numeric($keyword)) {
521
                $tmp[] = $keyword;
522
            }
523
        }
524
        $tmp = \array_slice($tmp, 0, $keywordscount);
525
        if (\count($tmp) > 0) {
526
            return \implode(',', $tmp);
527
        }
528
        if (!isset($configHandler) || !\is_object($configHandler)) {
529
            /** @var XoopsConfigHandler $configHandler */
530
            $configHandler = \xoops_getHandler('config');
531
        }
532
        $xoopsConfigMetaFooter = $configHandler->getConfigsByCat(\XOOPS_CONF_METAFOOTER);
533
        return $xoopsConfigMetaFooter['meta_keywords'] ?? '';
534
    }
535
536
    /**
537
     * Remove module's cache
538
     *
539
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
540
     * @copyright (c) Hervé Thouzard
541
     */
542
    public static function updateCache(): void
543
    {
544
        global $xoopsModule;
545
        $folder  = $xoopsModule->getVar('dirname');
546
        $tpllist = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $tpllist is dead and can be removed.
Loading history...
547
        require_once XOOPS_ROOT_PATH . '/class/xoopsblock.php';
548
        require_once XOOPS_ROOT_PATH . '/class/template.php';
549
        $tplfileHandler = \xoops_getHandler('tplfile');
550
        $tpllist        = $tplfileHandler->find(null, null, null, $folder);
0 ignored issues
show
Bug introduced by
The method find() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsTplfileHandler 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

550
        /** @scrutinizer ignore-call */ 
551
        $tpllist        = $tplfileHandler->find(null, null, null, $folder);
Loading history...
551
        $xoopsTpl       = new \XoopsTpl();
0 ignored issues
show
Unused Code introduced by
The assignment to $xoopsTpl is dead and can be removed.
Loading history...
552
        \xoops_template_clear_module_cache($xoopsModule->getVar('mid')); // Clear module's blocks cache
553
554
        // Remove cache for each page.
555
        foreach ($tpllist as $onetemplate) {
556
            if ('module' === $onetemplate->getVar('tpl_type')) {
557
                // Note, I've been testing all the other methods (like the one of Smarty) and none of them run, that's why I have used this code
558
                $files_del = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $files_del is dead and can be removed.
Loading history...
559
                $files_del = \glob(XOOPS_CACHE_PATH . '/*' . $onetemplate->getVar('tpl_file') . '*', \GLOB_NOSORT);
560
                if (\count($files_del) > 0) {
561
                    foreach ($files_del as $one_file) {
562
                        \unlink($one_file);
563
                    }
564
                }
565
            }
566
        }
567
    }
568
569
    /**
570
     * Verify that a mysql table exists
571
     *
572
     * @param string $tablename
573
     * @return bool
574
     * @copyright (c) Hervé Thouzard
575
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
576
     */
577
    public static function existTable(string $tablename): bool
578
    {
579
        global $xoopsDB;
580
        $sql = "SHOW TABLES LIKE '$tablename'";
581
        $result = Utility::queryFAndCheck($xoopsDB, $sql);
582
583
        return ($xoopsDB->getRowsNum($result) > 0);
584
    }
585
586
    /**
587
     * Verify that a field exists inside a mysql table
588
     *
589
     * @param string $fieldname
590
     * @param string $table
591
     * @return bool
592
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
593
     * @copyright (c) Hervé Thouzard
594
     */
595
    public static function existField(string $fieldname, string $table): bool
596
    {
597
        global $xoopsDB;
598
        $sql = "SHOW COLUMNS FROM   $table LIKE '$fieldname'";
599
        $result = Utility::queryFAndCheck($xoopsDB, $sql);
600
601
        return ($xoopsDB->getRowsNum($result) > 0);
602
    }
603
604
    /**
605
     * Add a field to a mysql table
606
     *
607
     * @param string $field
608
     * @param string $table
609
     * @return bool|\mysqli_result
610
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
611
     * @copyright (c) Hervé Thouzard
612
     */
613
    public static function addField(string $field, string $table)
614
    {
615
        global $xoopsDB;
616
        $result = $xoopsDB->queryF('ALTER TABLE ' . $table . " ADD $field;");
617
618
        return $result;
619
    }
620
621
    /**
622
     * Verify that the current user is a member of the Admin group
623
     */
624
    public static function isAdminGroup(): bool
625
    {
626
        global $xoopsUser, $xoopsModule;
627
        if (\is_object($xoopsUser)) {
628
            if (\in_array('1', $xoopsUser->getGroups(), true)) {
629
                return true;
630
            }
631
            if ($xoopsUser->isAdmin($xoopsModule->mid())) {
632
                return true;
633
            }
634
635
            return false;
636
        }
637
638
        return false;
639
    }
640
641
    /**
642
     * Verify if the current "user" is a bot or not
643
     *
644
     * If you have a problem with this function, insert the folowing code just before the line if (\Xmf\Request::hasVar('news_cache_bot', 'SESSION'))) { :
645
     * return false;
646
     *
647
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
648
     * @copyright (c) Hervé Thouzard
649
     */
650
    public static function isBot()
651
    {
652
        if (Request::hasVar('news_cache_bot', 'SESSION')) {
653
            return $_SESSION['news_cache_bot'];
654
        }
655
        // Add here every bot you know separated by a pipe | (not matter with the upper or lower cases)
656
        // If you want to see the result for yourself, add your navigator's user agent at the end (mozilla for example)
657
        $botlist      = 'AbachoBOT|Arachnoidea|ASPSeek|Atomz|cosmos|crawl25-public.alexa.com|CrawlerBoy Pinpoint.com|Crawler|DeepIndex|EchO!|exabot|Excalibur Internet Spider|FAST-WebCrawler|Fluffy the spider|GAIS Robot/1.0B2|GaisLab data gatherer|Google|Googlebot-Image|googlebot|Gulliver|ia_archiver|Infoseek|Links2Go|Lycos_Spider_(modspider)|Lycos_Spider_(T-Rex)|MantraAgent|Mata Hari|Mercator|MicrosoftPrototypeCrawler|[email protected]|MSNBOT|NEC Research Agent|NetMechanic|Nokia-WAPToolkit|nttdirectory_robot|Openfind|Oracle Ultra Search|PicoSearch|Pompos|Scooter|Slider_Search_v1-de|Slurp|Slurp.so|SlySearch|Spider|Spinne|SurferF3|Surfnomore Spider|suzuran|teomaagent1|TurnitinBot|Ultraseek|VoilaBot|vspider|W3C_Validator|Web Link Validator|WebTrends|WebZIP|whatUseek_winona|WISEbot|Xenu Link Sleuth|ZyBorg';
658
        $botlist      = \mb_strtoupper($botlist);
659
        $currentagent = \mb_strtoupper(\xoops_getenv('HTTP_USER_AGENT'));
660
        $retval       = false;
661
        $botarray     = \explode('|', $botlist);
662
        foreach ($botarray as $onebot) {
663
            if (false !== mb_strpos($currentagent, $onebot)) {
664
                $retval = true;
665
                break;
666
            }
667
        }
668
669
        $_SESSION['news_cache_bot'] = $retval;
670
671
        return $retval;
672
    }
673
674
    /**
675
     * Create an infotip
676
     *
677
     * @param string $text
678
     * @return string|null
679
     * @copyright (c) Hervé Thouzard
680
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
681
     */
682
    public static function makeInfotips(string $text): ?string
683
    {
684
        $infotips = static::getModuleOption('infotips');
685
        if ($infotips > 0) {
686
            $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
687
688
            return \htmlspecialchars(\xoops_substr(\strip_tags($text), 0, $infotips), \ENT_QUOTES | \ENT_HTML5);
689
        }
690
691
        return null;
692
    }
693
694
    /**
695
     * @param string $string
696
     * @return string
697
     * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
698
     *           <amos dot robinson at gmail dot com>
699
     */
700
    public static function closeTags(string $string): string
701
    {
702
        // match opened tags
703
        if (\preg_match_all('/<([a-z\:\-]+)[^\/]>/', $string, $start_tags)) {
704
            $start_tags = $start_tags[1];
705
            // match closed tags
706
            if (\preg_match_all('/<\/([a-z]+)>/', $string, $end_tags)) {
707
                $complete_tags = [];
708
                $end_tags      = $end_tags[1];
709
710
                foreach ($start_tags as $key => $val) {
711
                    $posb = \array_search($val, $end_tags, true);
712
                    if (\is_int($posb)) {
713
                        unset($end_tags[$posb]);
714
                    } else {
715
                        $complete_tags[] = $val;
716
                    }
717
                }
718
            } else {
719
                $complete_tags = $start_tags;
720
            }
721
722
            $complete_tags = \array_reverse($complete_tags);
723
            foreach ($complete_tags as $iValue) {
724
                $string .= '</' . $iValue . '>';
725
            }
726
        }
727
728
        return $string;
729
    }
730
731
    /**
732
     * Smarty truncate_tagsafe modifier plugin
733
     *
734
     * Type:     modifier<br>
735
     * Name:     truncate_tagsafe<br>
736
     * Purpose:  Truncate a string to a certain length if necessary,
737
     *           optionally splitting in the middle of a word, and
738
     *           appending the $etc string or inserting $etc into the middle.
739
     *           Makes sure no tags are left half-open or half-closed
740
     *           (e.g. "Banana in a <a...")
741
     *
742
     * @param string $string
743
     * @param int    $length
744
     * @param string $etc
745
     * @param bool   $break_words
746
     *
747
     * @return string
748
     * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
749
     *           <amos dot robinson at gmail dot com>
750
     */
751
    public static function truncateTagSafe(string $string, int $length = 80, string $etc = '...', bool $break_words = false): string
752
    {
753
        if (0 == $length) {
754
            return '';
755
        }
756
        if (mb_strlen($string) > $length) {
757
            $length -= \mb_strlen($etc);
758
            if (!$break_words) {
759
                $string = \preg_replace('/\s+?(\S+)?$/', '', mb_substr($string, 0, $length + 1));
760
                $string = \preg_replace('/<[^>]*$/', '', $string);
761
                $string = static::closeTags($string);
762
            }
763
764
            return $string . $etc;
765
        }
766
767
        return $string;
768
    }
769
770
    /**
771
     * Resize a Picture to some given dimensions (using the wideImage library)
772
     *
773
     * @param string $src_path      Picture's source
774
     * @param string $dst_path      Picture's destination
775
     * @param int    $param_width   Maximum picture's width
776
     * @param int    $param_height  Maximum picture's height
777
     * @param bool   $keep_original Do we have to keep the original picture ?
778
     * @param string $fit           Resize mode (see the wideImage library for more information)
779
     *
780
     * @return bool
781
     */
782
    public static function resizePicture(
783
        string $src_path,
784
        string $dst_path,
785
        int    $param_width,
786
        int    $param_height,
787
        bool   $keep_original = false,
788
        string $fit = 'inside'
789
    ): bool {
790
        //    require_once XOOPS_PATH . '/vendor/wideimage/WideImage.php';
791
        $resize            = true;
792
        $pictureDimensions = \getimagesize($src_path);
793
        if (\is_array($pictureDimensions)) {
0 ignored issues
show
introduced by
The condition is_array($pictureDimensions) is always true.
Loading history...
794
            $pictureWidth  = $pictureDimensions[0];
795
            $pictureHeight = $pictureDimensions[1];
796
            if ($pictureWidth < $param_width && $pictureHeight < $param_height) {
797
                $resize = false;
798
            }
799
        }
800
801
        $img = WideImage::load($src_path);
802
        if ($resize) {
803
            $result = $img->resize($param_width, $param_height, $fit);
804
            $result->saveToFile($dst_path);
805
        } else {
806
            @\copy($src_path, $dst_path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for copy(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

806
            /** @scrutinizer ignore-unhandled */ @\copy($src_path, $dst_path);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
807
        }
808
        if (!$keep_original) {
809
            @\unlink($src_path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

809
            /** @scrutinizer ignore-unhandled */ @\unlink($src_path);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
810
        }
811
812
        return true;
813
    }
814
}
815