Passed
Push — master ( 0708c5...e4b65d )
by Michael
13:42 queued 13s
created

Utility::createMetaKeywords()   D

Complexity

Conditions 13
Paths 145

Size

Total Lines 129
Code Lines 109

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 109
c 0
b 0
f 0
nc 145
nop 1
dl 0
loc 129
rs 4.9932

How to fix   Long Method    Complexity   

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 declare(strict_types=1);
2
3
namespace XoopsModules\News;
4
5
use MyTextSanitizer;
6
use WideImage\WideImage;
7
use Xmf\Request;
8
use XoopsFormDhtmlTextArea;
9
use XoopsFormEditor;
10
use XoopsFormFckeditor;
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...
11
use XoopsFormHtmlarea;
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...
12
use XoopsFormTextArea;
13
use 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...
14
use XoopsFormWysiwygTextArea;
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...
15
use XoopsModules\News;
16
use XoopsObjectTree;
17
use XoopsTpl;
18
19
/**
20
 * Class Utility
21
 */
22
class Utility extends Common\SysUtility
23
{
24
    //--------------- Custom module methods -----------------------------
25
    /**
26
     * @param             $option
27
     * @param string      $repmodule
28
     * @return bool|mixed
29
     */
30
    public static function getModuleOption($option, $repmodule = 'news')
31
    {
32
        global $xoopsModuleConfig, $xoopsModule;
33
        static $tbloptions = [];
34
        if (\is_array($tbloptions) && \array_key_exists($option, $tbloptions)) {
35
            return $tbloptions[$option];
36
        }
37
38
        $retval = false;
39
        if (isset($xoopsModuleConfig)
40
            && (\is_object($xoopsModule) && $xoopsModule->getVar('dirname') == $repmodule
41
                && $xoopsModule->getVar('isactive'))) {
42
            if (isset($xoopsModuleConfig[$option])) {
43
                $retval = $xoopsModuleConfig[$option];
44
            }
45
        } else {
46
            /** @var \XoopsModuleHandler $moduleHandler */
47
            $moduleHandler = \xoops_getHandler('module');
48
            $module        = $moduleHandler->getByDirname($repmodule);
49
            $configHandler = \xoops_getHandler('config');
50
            if ($module) {
51
                $moduleConfig = $configHandler->getConfigsByCat(0, $module->getVar('mid'));
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

51
                /** @scrutinizer ignore-call */ 
52
                $moduleConfig = $configHandler->getConfigsByCat(0, $module->getVar('mid'));
Loading history...
52
                if (isset($moduleConfig[$option])) {
53
                    $retval = $moduleConfig[$option];
54
                }
55
            }
56
        }
57
        $tbloptions[$option] = $retval;
58
59
        return $retval;
60
    }
61
62
    /**
63
     * Updates rating data in item table for a given item
64
     *
65
     * @param $storyid
66
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
67
     * @copyright (c) Hervé Thouzard
68
     */
69
    public static function updateRating($storyid): void
70
    {
71
        global $xoopsDB;
72
        $query       = 'SELECT rating FROM ' . $xoopsDB->prefix('news_stories_votedata') . ' WHERE storyid = ' . $storyid;
73
        $voteresult  = $xoopsDB->query($query);
74
        $votesDB     = $xoopsDB->getRowsNum($voteresult);
75
        $totalrating = 0;
76
        while ([$rating] = $xoopsDB->fetchRow($voteresult)) {
77
            $totalrating += $rating;
78
        }
79
        $finalrating = $totalrating / $votesDB;
80
        $finalrating = \number_format($finalrating, 4);
81
        $sql         = \sprintf('UPDATE `%s` SET rating = %u, votes = %u WHERE storyid = %u', $xoopsDB->prefix('news_stories'), $finalrating, $votesDB, $storyid);
82
        $xoopsDB->queryF($sql);
83
    }
84
85
    /**
86
     * Internal function for permissions
87
     *
88
     * Returns a list of all the permitted topics Ids for the current user
89
     *
90
     * @param string $permtype
91
     *
92
     * @return array    Permitted topics Ids
93
     *
94
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
95
     * @copyright (c) Hervé Thouzard
96
     */
97
    public static function getMyItemIds($permtype = 'news_view')
98
    {
99
        global $xoopsUser;
100
        static $tblperms = [];
101
        if (\is_array($tblperms) && \array_key_exists($permtype, $tblperms)) {
102
            return $tblperms[$permtype];
103
        }
104
105
        /** @var \XoopsModuleHandler $moduleHandler */
106
        $moduleHandler       = \xoops_getHandler('module');
107
        $newsModule          = $moduleHandler->getByDirname('news');
108
        $groups              = \is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
109
        $grouppermHandler    = \xoops_getHandler('groupperm');
110
        $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

110
        /** @scrutinizer ignore-call */ 
111
        $topics              = $grouppermHandler->getItemIds($permtype, $groups, $newsModule->getVar('mid'));
Loading history...
111
        $tblperms[$permtype] = $topics;
112
113
        return $topics;
114
    }
115
116
    /**
117
     * @param $document
118
     *
119
     * @return mixed
120
     */
121
    public static function html2text($document)
122
    {
123
        // PHP Manual:: function preg_replace
124
        // $document should contain an HTML document.
125
        // This will remove HTML tags, javascript sections
126
        // and white space. It will also convert some
127
        // common HTML entities to their text equivalent.
128
129
        $search = [
130
            "'<script[^>]*?>.*?</script>'si", // Strip out javascript
131
            "'<img.*?>'si", // Strip out img tags
132
            "'<[\/\!]*?[^<>]*?>'si", // Strip out HTML tags
133
            "'([\r\n])[\s]+'", // Strip out white space
134
            "'&(quot|#34);'i", // Replace HTML entities
135
            "'&(amp|#38);'i",
136
            "'&(lt|#60);'i",
137
            "'&(gt|#62);'i",
138
            "'&(nbsp|#160);'i",
139
            "'&(iexcl|#161);'i",
140
            "'&(cent|#162);'i",
141
            "'&(pound|#163);'i",
142
            "'&(copy|#169);'i",
143
        ]; // evaluate as php
144
145
        $replace = [
146
            '',
147
            '',
148
            '',
149
            '\\1',
150
            '"',
151
            '&',
152
            '<',
153
            '>',
154
            ' ',
155
            \chr(161),
156
            \chr(162),
157
            \chr(163),
158
            \chr(169),
159
        ];
160
161
        $text = \preg_replace($search, $replace, $document);
162
163
        \preg_replace_callback(
164
            '/&#(\d+);/',
165
            static function ($matches) {
166
                return \chr($matches[1]);
167
            },
168
            $document
169
        );
170
171
        return $text;
172
    }
173
174
    /**
175
     * Is Xoops 2.3.x ?
176
     *
177
     * @return bool need to say it ?
178
     */
179
    public static function isX23()
180
    {
181
        $x23 = false;
182
        $xv  = \str_replace('XOOPS ', '', \XOOPS_VERSION);
183
        if (mb_substr($xv, 2, 1) >= '3') {
184
            $x23 = true;
185
        }
186
187
        return $x23;
188
    }
189
190
    /**
191
     * Retrieve an editor according to the module's option "form_options"
192
     *
193
     * @param                                                                                                                                 $caption
194
     * @param                                                                                                                                 $name
195
     * @param string                                                                                                                          $value
196
     * @param string                                                                                                                          $width
197
     * @param string                                                                                                                          $height
198
     * @param string                                                                                                                          $supplemental
199
     * @return bool|\XoopsFormDhtmlTextArea|\XoopsFormEditor|\XoopsFormFckeditor|\XoopsFormHtmlarea|\XoopsFormTextArea|\XoopsFormTinyeditorTextArea
200
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
201
     * @copyright (c) Hervé Thouzard
202
     */
203
    public static function getWysiwygForm($caption, $name, $value = '', $width = '100%', $height = '400px', $supplemental = '')
204
    {
205
        $editor_option            = \mb_strtolower(static::getModuleOption('form_options'));
0 ignored issues
show
Bug introduced by
It seems like static::getModuleOption('form_options') can also be of type boolean; however, parameter $string of mb_strtolower() 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

205
        $editor_option            = \mb_strtolower(/** @scrutinizer ignore-type */ static::getModuleOption('form_options'));
Loading history...
206
        $editor                   = false;
207
        $editor_configs           = [];
208
        $editor_configs['name']   = $name;
209
        $editor_configs['value']  = $value;
210
        $editor_configs['rows']   = 35;
211
        $editor_configs['cols']   = 60;
212
        $editor_configs['width']  = '100%';
213
        $editor_configs['height'] = '350px';
214
        $editor_configs['editor'] = $editor_option;
215
216
        if (static::isX23()) {
217
            $editor = new XoopsFormEditor($caption, $name, $editor_configs);
218
219
            return $editor;
220
        }
221
222
        // Only for Xoops 2.0.x
223
        switch ($editor_option) {
224
            case 'fckeditor':
225
                if (\is_readable(XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php')) {
226
                    require_once XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php';
227
                    $editor = new XoopsFormFckeditor($caption, $name, $value);
228
                }
229
                break;
230
            case 'htmlarea':
231
                if (\is_readable(XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php')) {
232
                    require_once XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php';
233
                    $editor = new XoopsFormHtmlarea($caption, $name, $value);
234
                }
235
                break;
236
            case 'dhtmltextarea':
237
            case 'dhtml':
238
                $editor = new XoopsFormDhtmlTextArea($caption, $name, $value, 10, 50, $supplemental);
239
                break;
240
            case 'textarea':
241
                $editor = new XoopsFormTextArea($caption, $name, $value);
242
                break;
243
            case 'tinyeditor':
244
            case 'tinymce':
245
                if (\is_readable(XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php')) {
246
                    require_once XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php';
247
                    $editor = new XoopsFormTinyeditorTextArea(
248
                        [
249
                            'caption' => $caption,
250
                            'name'    => $name,
251
                            'value'   => $value,
252
                            'width'   => '100%',
253
                            'height'  => '400px',
254
                        ]
255
                    );
256
                }
257
                break;
258
            case 'koivi':
259
                if (\is_readable(XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php')) {
260
                    require_once XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php';
261
                    $editor = new XoopsFormWysiwygTextArea($caption, $name, $value, $width, $height, '');
262
                }
263
                break;
264
        }
265
266
        return $editor;
267
    }
268
269
    /**
270
     * @param \Xmf\Module\Helper $helper
271
     * @param array|null         $options
272
     * @return \XoopsFormDhtmlTextArea|\XoopsFormEditor
273
     */
274
    public static function getEditor($helper = null, $options = null)
275
    {
276
        /** @var News\Helper $helper */
277
        if (null === $options) {
278
            $options           = [];
279
            $options['name']   = 'Editor';
280
            $options['value']  = 'Editor';
281
            $options['rows']   = 10;
282
            $options['cols']   = '100%';
283
            $options['width']  = '100%';
284
            $options['height'] = '400px';
285
        }
286
287
        if (null === $helper) {
288
            $helper = Helper::getInstance();
289
        }
290
291
        $isAdmin = $helper->isUserAdmin();
292
293
        if (\class_exists('XoopsFormEditor')) {
294
            if ($isAdmin) {
295
                $descEditor = new XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorAdmin'), $options, $nohtml = false, $onfailure = 'textarea');
296
            } else {
297
                $descEditor = new XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorUser'), $options, $nohtml = false, $onfailure = 'textarea');
298
            }
299
        } else {
300
            $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

300
            $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

300
            $descEditor = new XoopsFormDhtmlTextArea(\ucfirst($options['name']), $options['name'], $options['value'], /** @scrutinizer ignore-type */ '100%', '100%');
Loading history...
301
        }
302
303
        //        $form->addElement($descEditor);
304
305
        return $descEditor;
306
    }
307
308
    /**
309
     * Internal function
310
     *
311
     * @param $text
312
     * @return mixed
313
     * @copyright (c) Hervé Thouzard
314
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
315
     */
316
    public static function getDublinQuotes($text)
317
    {
318
        return \str_replace('"', ' ', $text);
319
    }
320
321
    /**
322
     * Creates all the meta datas :
323
     * - For Mozilla/Netscape and Opera the site navigation's bar
324
     * - The Dublin's Core Metadata
325
     * - The link for Firefox 2 micro summaries
326
     * - The meta keywords
327
     * - The meta description
328
     *
329
     * @param null $story
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $story is correct as it would always require null to be passed?
Loading history...
330
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
331
     * @copyright (c) Hervé Thouzard
332
     */
333
    public static function createMetaDatas($story = null): void
334
    {
335
        global $xoopsConfig, $xoTheme, $xoopsTpl;
336
        $content = '';
337
        $myts    = MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
338
        //        require_once XOOPS_ROOT_PATH . '/modules/news/class/class.newstopic.php';
339
340
        /**
341
         * Firefox and Opera Navigation's Bar
342
         */
343
        if (static::getModuleOption('sitenavbar')) {
344
            $content .= \sprintf("<link rel=\"Home\" title=\"%s\" href=\"%s/\">\n", $xoopsConfig['sitename'], XOOPS_URL);
345
            $content .= \sprintf("<link rel=\"Contents\" href=\"%s\">\n", XOOPS_URL . '/modules/news/index.php');
346
            $content .= \sprintf("<link rel=\"Search\" href=\"%s\">\n", XOOPS_URL . '/search.php');
347
            $content .= \sprintf("<link rel=\"Glossary\" href=\"%s\">\n", XOOPS_URL . '/modules/news/archive.php');
348
            $content .= \sprintf("<link rel=\"%s\" href=\"%s\">\n", \htmlspecialchars(_NW_SUBMITNEWS, \ENT_QUOTES | \ENT_HTML5), XOOPS_URL . '/modules/news/submit.php');
349
            $content .= \sprintf("<link rel=\"alternate\" type=\"application/rss+xml\" title=\"%s\" href=\"%s/\">\n", $xoopsConfig['sitename'], XOOPS_URL . '/backend.php');
350
351
            // Create chapters
352
            require_once XOOPS_ROOT_PATH . '/class/tree.php';
353
            //            require_once XOOPS_ROOT_PATH . '/modules/news/class/class.newstopic.php';
354
            $xt         = new \XoopsModules\News\NewsTopic();
355
            $allTopics  = $xt->getAllTopics(static::getModuleOption('restrictindex'));
356
            $topic_tree = new XoopsObjectTree($allTopics, 'topic_id', 'topic_pid');
357
            $topics_arr = $topic_tree->getAllChild(0);
358
            foreach ($topics_arr as $onetopic) {
359
                $content .= \sprintf("<link rel=\"Chapter\" title=\"%s\" href=\"%s\">\n", $onetopic->topic_title(), XOOPS_URL . '/modules/news/index.php?storytopic=' . $onetopic->topic_id());
360
            }
361
        }
362
363
        /**
364
         * Meta Keywords and Description
365
         * 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
366
         */
367
        $meta_keywords = '';
368
        if (isset($story) && \is_object($story)) {
369
            if ('' !== \xoops_trim($story->keywords())) {
370
                $meta_keywords = $story->keywords();
371
            } else {
372
                $meta_keywords = static::createMetaKeywords($story->hometext() . ' ' . $story->bodytext());
373
            }
374
            if ('' !== \xoops_trim($story->description())) {
375
                $meta_description = \strip_tags($story->description);
376
            } else {
377
                $meta_description = \strip_tags($story->title);
378
            }
379
            if (isset($xoTheme) && \is_object($xoTheme)) {
380
                $xoTheme->addMeta('meta', 'keywords', $meta_keywords);
381
                $xoTheme->addMeta('meta', 'description', $meta_description);
382
            } elseif (isset($xoopsTpl) && \is_object($xoopsTpl)) { // Compatibility for old Xoops versions
383
                $xoopsTpl->assign('xoops_meta_keywords', $meta_keywords);
384
                $xoopsTpl->assign('xoops_meta_description', $meta_description);
385
            }
386
        }
387
388
        /**
389
         * Dublin Core's meta datas
390
         */
391
        if (static::getModuleOption('dublincore') && isset($story) && \is_object($story)) {
392
            $configHandler         = \xoops_getHandler('config');
393
            $xoopsConfigMetaFooter = $configHandler->getConfigsByCat(\XOOPS_CONF_METAFOOTER);
394
            $content               .= '<meta name="DC.Title" content="' . static::getDublinQuotes($story->title()) . "\">\n";
395
            $content               .= '<meta name="DC.Creator" content="' . static::getDublinQuotes($story->uname()) . "\">\n";
396
            $content               .= '<meta name="DC.Subject" content="' . static::getDublinQuotes($meta_keywords) . "\">\n";
397
            $content               .= '<meta name="DC.Description" content="' . static::getDublinQuotes($story->title()) . "\">\n";
398
            $content               .= '<meta name="DC.Publisher" content="' . static::getDublinQuotes($xoopsConfig['sitename']) . "\">\n";
399
            $content               .= '<meta name="DC.Date.created" scheme="W3CDTF" content="' . \date('Y-m-d', $story->created) . "\">\n";
400
            $content               .= '<meta name="DC.Date.issued" scheme="W3CDTF" content="' . \date('Y-m-d', $story->published) . "\">\n";
401
            $content               .= '<meta name="DC.Identifier" content="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $story->storyid() . "\">\n";
402
            $content               .= '<meta name="DC.Source" content="' . XOOPS_URL . "\">\n";
403
            $content               .= '<meta name="DC.Language" content="' . _LANGCODE . "\">\n";
404
            $content               .= '<meta name="DC.Relation.isReferencedBy" content="' . XOOPS_URL . '/modules/news/index.php?storytopic=' . $story->topicid() . "\">\n";
405
            if (isset($xoopsConfigMetaFooter['meta_copyright'])) {
406
                $content .= '<meta name="DC.Rights" content="' . static::getDublinQuotes($xoopsConfigMetaFooter['meta_copyright']) . "\">\n";
407
            }
408
        }
409
410
        /**
411
         * Firefox 2 micro summaries
412
         */
413
        if (static::getModuleOption('firefox_microsummaries')) {
414
            $content .= \sprintf("<link rel=\"microsummary\" href=\"%s\">\n", XOOPS_URL . '/modules/news/micro_summary.php');
415
        }
416
417
        if (isset($xoopsTpl) && \is_object($xoopsTpl)) {
418
            $xoopsTpl->assign('xoops_module_header', $content);
419
        }
420
    }
421
422
    /**
423
     * Create the meta keywords based on the content
424
     *
425
     * @param $content
426
     * @return string
427
     * @copyright (c) Hervé Thouzard
428
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
429
     */
430
    public static function createMetaKeywords($content)
431
    {
432
        global $cfg;
433
        require_once XOOPS_ROOT_PATH . '/modules/news/config.php';
434
        // require_once XOOPS_ROOT_PATH . '/modules/news/class/blacklist.php';
435
        // require_once XOOPS_ROOT_PATH . '/modules/news/class/registryfile.php';
436
437
        if (!$cfg['meta_keywords_auto_generate']) {
438
            return '';
439
        }
440
        $registry = new Registryfile('news_metagen_options.txt');
441
        //    $tcontent = '';
442
        $tcontent = $registry->getfile();
443
        if ('' !== \xoops_trim($tcontent)) {
444
            [$keywordscount, $keywordsorder] = \explode(',', $tcontent);
445
        } else {
446
            $keywordscount = $cfg['meta_keywords_count'];
447
            $keywordsorder = $cfg['meta_keywords_order'];
448
        }
449
450
        $tmp = [];
451
        // Search for the "Minimum keyword length"
452
        if (Request::hasVar('news_keywords_limit', 'SESSION')) {
453
            $limit = $_SESSION['news_keywords_limit'];
454
        } else {
455
            $configHandler                   = \xoops_getHandler('config');
456
            $xoopsConfigSearch               = $configHandler->getConfigsByCat(\XOOPS_CONF_SEARCH);
457
            $limit                           = $xoopsConfigSearch['keyword_min'];
458
            $_SESSION['news_keywords_limit'] = $limit;
459
        }
460
        $myts            = MyTextSanitizer::getInstance();
461
        $content         = \str_replace('<br>', ' ', $content);
462
        $content         = $myts->undoHtmlSpecialChars($content);
463
        $content         = \strip_tags($content);
464
        $content         = \mb_strtolower($content);
465
        $search_pattern  = [
466
            '&nbsp;',
467
            "\t",
468
            "\r\n",
469
            "\r",
470
            "\n",
471
            ',',
472
            '.',
473
            "'",
474
            ';',
475
            ':',
476
            ')',
477
            '(',
478
            '"',
479
            '?',
480
            '!',
481
            '{',
482
            '}',
483
            '[',
484
            ']',
485
            '<',
486
            '>',
487
            '/',
488
            '+',
489
            '-',
490
            '_',
491
            '\\',
492
            '*',
493
        ];
494
        $replace_pattern = [
495
            ' ',
496
            ' ',
497
            ' ',
498
            ' ',
499
            ' ',
500
            ' ',
501
            ' ',
502
            ' ',
503
            '',
504
            '',
505
            '',
506
            '',
507
            '',
508
            '',
509
            '',
510
            '',
511
            '',
512
            '',
513
            '',
514
            '',
515
            '',
516
            '',
517
            '',
518
            '',
519
            '',
520
            '',
521
            '',
522
        ];
523
        $content         = \str_replace($search_pattern, $replace_pattern, $content);
524
        $keywords        = \explode(' ', $content);
525
        switch ($keywordsorder) {
526
            case 0: // Ordre d'apparition dans le texte
527
                $keywords = \array_unique($keywords);
528
                break;
529
            case 1: // Ordre de fréquence des mots
530
                $keywords = \array_count_values($keywords);
531
                \asort($keywords);
532
                $keywords = \array_keys($keywords);
533
                break;
534
            case 2: // Ordre inverse de la fréquence des mots
535
                $keywords = \array_count_values($keywords);
536
                \arsort($keywords);
537
                $keywords = \array_keys($keywords);
538
                break;
539
        }
540
        // Remove black listed words
541
        $metablack = new Blacklist();
542
        $words     = $metablack->getAllKeywords();
0 ignored issues
show
Unused Code introduced by
The assignment to $words is dead and can be removed.
Loading history...
543
        $keywords  = $metablack->remove_blacklisted($keywords);
544
545
        foreach ($keywords as $keyword) {
546
            if (mb_strlen($keyword) >= $limit && !\is_numeric($keyword)) {
547
                $tmp[] = $keyword;
548
            }
549
        }
550
        $tmp = \array_slice($tmp, 0, $keywordscount);
551
        if (\count($tmp) > 0) {
552
            return \implode(',', $tmp);
553
        }
554
        if (!isset($configHandler) || !\is_object($configHandler)) {
555
            $configHandler = \xoops_getHandler('config');
556
        }
557
        $xoopsConfigMetaFooter = $configHandler->getConfigsByCat(\XOOPS_CONF_METAFOOTER);
558
        return $xoopsConfigMetaFooter['meta_keywords'] ?? '';
559
    }
560
561
    /**
562
     * Remove module's cache
563
     *
564
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
565
     * @copyright (c) Hervé Thouzard
566
     */
567
    public static function updateCache(): void
568
    {
569
        global $xoopsModule;
570
        $folder  = $xoopsModule->getVar('dirname');
571
        $tpllist = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $tpllist is dead and can be removed.
Loading history...
572
        require_once XOOPS_ROOT_PATH . '/class/xoopsblock.php';
573
        require_once XOOPS_ROOT_PATH . '/class/template.php';
574
        $tplfileHandler = \xoops_getHandler('tplfile');
575
        $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

575
        /** @scrutinizer ignore-call */ 
576
        $tpllist        = $tplfileHandler->find(null, null, null, $folder);
Loading history...
576
        $xoopsTpl       = new XoopsTpl();
0 ignored issues
show
Unused Code introduced by
The assignment to $xoopsTpl is dead and can be removed.
Loading history...
577
        \xoops_template_clear_module_cache($xoopsModule->getVar('mid')); // Clear module's blocks cache
578
579
        // Remove cache for each page.
580
        foreach ($tpllist as $onetemplate) {
581
            if ('module' === $onetemplate->getVar('tpl_type')) {
582
                // 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
583
                $files_del = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $files_del is dead and can be removed.
Loading history...
584
                $files_del = \glob(XOOPS_CACHE_PATH . '/*' . $onetemplate->getVar('tpl_file') . '*', \GLOB_NOSORT);
585
                if (\count($files_del) > 0) {
586
                    foreach ($files_del as $one_file) {
587
                        \unlink($one_file);
588
                    }
589
                }
590
            }
591
        }
592
    }
593
594
    /**
595
     * Verify that a mysql table exists
596
     *
597
     * @param $tablename
598
     * @return bool
599
     * @copyright (c) Hervé Thouzard
600
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
601
     */
602
    public static function existTable($tablename)
603
    {
604
        global $xoopsDB;
605
        $result = $xoopsDB->queryF("SHOW TABLES LIKE '$tablename'");
606
607
        return ($xoopsDB->getRowsNum($result) > 0);
608
    }
609
610
    /**
611
     * Verify that a field exists inside a mysql table
612
     *
613
     * @param $fieldname
614
     * @param $table
615
     * @return bool
616
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
617
     * @copyright (c) Hervé Thouzard
618
     */
619
    public static function existField($fieldname, $table)
620
    {
621
        global $xoopsDB;
622
        $result = $xoopsDB->queryF("SHOW COLUMNS FROM   $table LIKE '$fieldname'");
623
624
        return ($xoopsDB->getRowsNum($result) > 0);
625
    }
626
627
    /**
628
     * Add a field to a mysql table
629
     *
630
     * @param $field
631
     * @param $table
632
     * @return bool|\mysqli_result
633
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
634
     * @copyright (c) Hervé Thouzard
635
     */
636
    public static function addField($field, $table)
637
    {
638
        global $xoopsDB;
639
        $result = $xoopsDB->queryF('ALTER TABLE ' . $table . " ADD $field;");
640
641
        return $result;
642
    }
643
644
    /**
645
     * Verify that the current user is a member of the Admin group
646
     */
647
    public static function isAdminGroup()
648
    {
649
        global $xoopsUser, $xoopsModule;
650
        if (\is_object($xoopsUser)) {
651
            if (\in_array('1', $xoopsUser->getGroups(), true)) {
652
                return true;
653
            }
654
            if ($xoopsUser->isAdmin($xoopsModule->mid())) {
655
                return true;
656
            }
657
658
            return false;
659
        }
660
661
        return false;
662
    }
663
664
    /**
665
     * Verify if the current "user" is a bot or not
666
     *
667
     * If you have a problem with this function, insert the folowing code just before the line if (\Xmf\Request::hasVar('news_cache_bot', 'SESSION'))) { :
668
     * return false;
669
     *
670
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
671
     * @copyright (c) Hervé Thouzard
672
     */
673
    public static function isBot()
674
    {
675
        if (Request::hasVar('news_cache_bot', 'SESSION')) {
676
            return $_SESSION['news_cache_bot'];
677
        }
678
        // Add here every bot you know separated by a pipe | (not matter with the upper or lower cases)
679
        // If you want to see the result for yourself, add your navigator's user agent at the end (mozilla for example)
680
        $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';
681
        $botlist      = \mb_strtoupper($botlist);
682
        $currentagent = \mb_strtoupper(\xoops_getenv('HTTP_USER_AGENT'));
683
        $retval       = false;
684
        $botarray     = \explode('|', $botlist);
685
        foreach ($botarray as $onebot) {
686
            if (false !== mb_strpos($currentagent, $onebot)) {
687
                $retval = true;
688
                break;
689
            }
690
        }
691
692
        $_SESSION['news_cache_bot'] = $retval;
693
694
        return $retval;
695
    }
696
697
    /**
698
     * Create an infotip
699
     *
700
     * @param $text
701
     * @return string|null
702
     * @copyright (c) Hervé Thouzard
703
     * @author        Hervé Thouzard (https://www.herve-thouzard.com)
704
     */
705
    public static function makeInfotips($text)
706
    {
707
        $infotips = static::getModuleOption('infotips');
708
        if ($infotips > 0) {
709
            $myts = MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
710
711
            return \htmlspecialchars(\xoops_substr(\strip_tags($text), 0, $infotips), \ENT_QUOTES | \ENT_HTML5);
0 ignored issues
show
Bug introduced by
It seems like $infotips can also be of type boolean; however, parameter $length of xoops_substr() does only seem to accept integer, 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

711
            return \htmlspecialchars(\xoops_substr(\strip_tags($text), 0, /** @scrutinizer ignore-type */ $infotips), \ENT_QUOTES | \ENT_HTML5);
Loading history...
712
        }
713
714
        return null;
715
    }
716
717
    /**
718
     * @param $string
719
     * @return string
720
     * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
721
     *           <amos dot robinson at gmail dot com>
722
     */
723
    public static function closeTags($string)
724
    {
725
        // match opened tags
726
        if (\preg_match_all('/<([a-z\:\-]+)[^\/]>/', $string, $start_tags)) {
727
            $start_tags = $start_tags[1];
728
            // match closed tags
729
            if (\preg_match_all('/<\/([a-z]+)>/', $string, $end_tags)) {
730
                $complete_tags = [];
731
                $end_tags      = $end_tags[1];
732
733
                foreach ($start_tags as $key => $val) {
734
                    $posb = \array_search($val, $end_tags, true);
735
                    if (\is_int($posb)) {
736
                        unset($end_tags[$posb]);
737
                    } else {
738
                        $complete_tags[] = $val;
739
                    }
740
                }
741
            } else {
742
                $complete_tags = $start_tags;
743
            }
744
745
            $complete_tags = \array_reverse($complete_tags);
746
            foreach ($complete_tags as $iValue) {
747
                $string .= '</' . $iValue . '>';
748
            }
749
        }
750
751
        return $string;
752
    }
753
754
    /**
755
     * Smarty truncate_tagsafe modifier plugin
756
     *
757
     * Type:     modifier<br>
758
     * Name:     truncate_tagsafe<br>
759
     * Purpose:  Truncate a string to a certain length if necessary,
760
     *           optionally splitting in the middle of a word, and
761
     *           appending the $etc string or inserting $etc into the middle.
762
     *           Makes sure no tags are left half-open or half-closed
763
     *           (e.g. "Banana in a <a...")
764
     *
765
     * @param mixed $string
766
     * @param mixed $length
767
     * @param mixed $etc
768
     * @param mixed $break_words
769
     *
770
     * @return string
771
     * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
772
     *           <amos dot robinson at gmail dot com>
773
     */
774
    public static function truncateTagSafe($string, $length = 80, $etc = '...', $break_words = false)
775
    {
776
        if (0 == $length) {
777
            return '';
778
        }
779
        if (mb_strlen($string) > $length) {
780
            $length -= mb_strlen($etc);
781
            if (!$break_words) {
782
                $string = \preg_replace('/\s+?(\S+)?$/', '', mb_substr($string, 0, $length + 1));
783
                $string = \preg_replace('/<[^>]*$/', '', $string);
784
                $string = static::closeTags($string);
785
            }
786
787
            return $string . $etc;
788
        }
789
790
        return $string;
791
    }
792
793
    /**
794
     * Resize a Picture to some given dimensions (using the wideImage library)
795
     *
796
     * @param string $src_path      Picture's source
797
     * @param string $dst_path      Picture's destination
798
     * @param int    $param_width   Maximum picture's width
799
     * @param int    $param_height  Maximum picture's height
800
     * @param bool   $keep_original Do we have to keep the original picture ?
801
     * @param string $fit           Resize mode (see the wideImage library for more information)
802
     *
803
     * @return bool
804
     */
805
    public static function resizePicture(
806
        $src_path,
807
        $dst_path,
808
        $param_width,
809
        $param_height,
810
        $keep_original = false,
811
        $fit = 'inside'
812
    ) {
813
        //    require_once XOOPS_PATH . '/vendor/wideimage/WideImage.php';
814
        $resize            = true;
815
        $pictureDimensions = \getimagesize($src_path);
816
        if (\is_array($pictureDimensions)) {
0 ignored issues
show
introduced by
The condition is_array($pictureDimensions) is always true.
Loading history...
817
            $pictureWidth  = $pictureDimensions[0];
818
            $pictureHeight = $pictureDimensions[1];
819
            if ($pictureWidth < $param_width && $pictureHeight < $param_height) {
820
                $resize = false;
821
            }
822
        }
823
824
        $img = WideImage::load($src_path);
825
        if ($resize) {
826
            $result = $img->resize($param_width, $param_height, $fit);
827
            $result->saveToFile($dst_path);
828
        } else {
829
            @\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

829
            /** @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...
830
        }
831
        if (!$keep_original) {
832
            @\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

832
            /** @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...
833
        }
834
835
        return true;
836
    }
837
}
838