Passed
Push — master ( 6d0bec...700d12 )
by Michael
05:09 queued 02:42
created

Utility   F

Complexity

Total Complexity 105

Size/Duplication

Total Lines 831
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 105
eloc 409
c 0
b 0
f 0
dl 0
loc 831
rs 2

20 Methods

Rating   Name   Duplication   Size   Complexity  
A getEditor() 0 32 5
A closeTags() 0 29 6
A addField() 0 6 1
A getMyItemIds() 0 17 4
A updateCache() 0 21 5
A getDublinQuotes() 0 3 1
A existTable() 0 6 1
F createMetaDatas() 0 86 18
A updateRating() 0 14 2
F createMetaKeywords() 0 133 14
A isX23() 0 9 2
A isAdminGroup() 0 15 4
A makeInfotips() 0 10 2
B getModuleOption() 0 30 10
A isBot() 0 22 4
A existField() 0 6 1
A truncateTagSafe() 0 17 4
A html2text() 0 51 1
C getWysiwygForm() 0 64 14
A resizePicture() 0 31 6

How to fix   Complexity   

Complex Class

Complex classes like Utility often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Utility, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace XoopsModules\News;
4
5
use WideImage\WideImage;
6
use XoopsModules\News;
7
use XoopsModules\News\Common;
8
use XoopsModules\News\Constants;
0 ignored issues
show
Bug introduced by
The type XoopsModules\News\Constants 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...
9
10
/**
11
 * Class Utility
12
 */
13
class Utility extends Common\SysUtility
14
{
15
    //--------------- Custom module methods -----------------------------
16
    /**
17
     * @param             $option
18
     * @param string      $repmodule
19
     * @return bool|mixed
20
     */
21
    public static function getModuleOption($option, $repmodule = 'news')
22
    {
23
        global $xoopsModuleConfig, $xoopsModule;
24
        static $tbloptions = [];
25
        if (\is_array($tbloptions) && \array_key_exists($option, $tbloptions)) {
26
            return $tbloptions[$option];
27
        }
28
29
        $retval = false;
30
        if (isset($xoopsModuleConfig)
31
            && (\is_object($xoopsModule) && $xoopsModule->getVar('dirname') == $repmodule
32
                && $xoopsModule->getVar('isactive'))) {
33
            if (isset($xoopsModuleConfig[$option])) {
34
                $retval = $xoopsModuleConfig[$option];
35
            }
36
        } else {
37
            /** @var \XoopsModuleHandler $moduleHandler */
38
            $moduleHandler = \xoops_getHandler('module');
39
            $module        = $moduleHandler->getByDirname($repmodule);
40
            $configHandler = \xoops_getHandler('config');
41
            if ($module) {
42
                $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

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

103
        /** @scrutinizer ignore-call */ 
104
        $topics              = $grouppermHandler->getItemIds($permtype, $groups, $newsModule->getVar('mid'));
Loading history...
104
        $tblperms[$permtype] = $topics;
105
106
        return $topics;
107
    }
108
109
    /**
110
     * @param $document
111
     *
112
     * @return mixed
113
     */
114
    public static function html2text($document)
115
    {
116
        // PHP Manual:: function preg_replace
117
        // $document should contain an HTML document.
118
        // This will remove HTML tags, javascript sections
119
        // and white space. It will also convert some
120
        // common HTML entities to their text equivalent.
121
122
        $search = [
123
            "'<script[^>]*?>.*?</script>'si", // Strip out javascript
124
            "'<img.*?>'si", // Strip out img tags
125
            "'<[\/\!]*?[^<>]*?>'si", // Strip out HTML tags
126
            "'([\r\n])[\s]+'", // Strip out white space
127
            "'&(quot|#34);'i", // Replace HTML entities
128
            "'&(amp|#38);'i",
129
            "'&(lt|#60);'i",
130
            "'&(gt|#62);'i",
131
            "'&(nbsp|#160);'i",
132
            "'&(iexcl|#161);'i",
133
            "'&(cent|#162);'i",
134
            "'&(pound|#163);'i",
135
            "'&(copy|#169);'i",
136
        ]; // evaluate as php
137
138
        $replace = [
139
            '',
140
            '',
141
            '',
142
            '\\1',
143
            '"',
144
            '&',
145
            '<',
146
            '>',
147
            ' ',
148
            \chr(161),
149
            \chr(162),
150
            \chr(163),
151
            \chr(169),
152
        ];
153
154
        $text = \preg_replace($search, $replace, $document);
155
156
        \preg_replace_callback(
157
            '/&#(\d+);/',
158
            static function ($matches) {
159
                return \chr($matches[1]);
160
            },
161
            $document
162
        );
163
164
        return $text;
165
    }
166
167
    /**
168
     * Is Xoops 2.3.x ?
169
     *
170
     * @return bool need to say it ?
171
     */
172
    public static function isX23()
173
    {
174
        $x23 = false;
175
        $xv  = \str_replace('XOOPS ', '', \XOOPS_VERSION);
176
        if (mb_substr($xv, 2, 1) >= '3') {
177
            $x23 = true;
178
        }
179
180
        return $x23;
181
    }
182
183
    /**
184
     * Retreive an editor according to the module's option "form_options"
185
     *
186
     * @param                                                                                                                                 $caption
187
     * @param                                                                                                                                 $name
188
     * @param string                                                                                                                          $value
189
     * @param string                                                                                                                          $width
190
     * @param string                                                                                                                          $height
191
     * @param string                                                                                                                          $supplemental
192
     * @return bool|\XoopsFormDhtmlTextArea|\XoopsFormEditor|\XoopsFormFckeditor|\XoopsFormHtmlarea|\XoopsFormTextArea|\XoopsFormTinyeditorTextArea
193
     * @package       News
194
     * @author        Hervé Thouzard (http://www.herve-thouzard.com)
195
     * @copyright (c) Hervé Thouzard
196
     */
197
    public static function getWysiwygForm($caption, $name, $value = '', $width = '100%', $height = '400px', $supplemental = '')
198
    {
199
        $editor_option            = mb_strtolower(static::getModuleOption('form_options'));
200
        $editor                   = false;
201
        $editor_configs           = [];
202
        $editor_configs['name']   = $name;
203
        $editor_configs['value']  = $value;
204
        $editor_configs['rows']   = 35;
205
        $editor_configs['cols']   = 60;
206
        $editor_configs['width']  = '100%';
207
        $editor_configs['height'] = '350px';
208
        $editor_configs['editor'] = $editor_option;
209
210
        if (static::isX23()) {
211
            $editor = new \XoopsFormEditor($caption, $name, $editor_configs);
212
213
            return $editor;
214
        }
215
216
        // Only for Xoops 2.0.x
217
        switch ($editor_option) {
218
            case 'fckeditor':
219
                if (\is_readable(XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php')) {
220
                    require_once XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php';
221
                    $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...
222
                }
223
                break;
224
            case 'htmlarea':
225
                if (\is_readable(XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php')) {
226
                    require_once XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php';
227
                    $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...
228
                }
229
                break;
230
            case 'dhtmltextarea':
231
            case 'dhtml':
232
                $editor = new \XoopsFormDhtmlTextArea($caption, $name, $value, 10, 50, $supplemental);
233
                break;
234
            case 'textarea':
235
                $editor = new \XoopsFormTextArea($caption, $name, $value);
236
                break;
237
            case 'tinyeditor':
238
            case 'tinymce':
239
                if (\is_readable(XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php')) {
240
                    require_once XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php';
241
                    $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...
242
                        [
243
                            'caption' => $caption,
244
                            'name'    => $name,
245
                            'value'   => $value,
246
                            'width'   => '100%',
247
                            'height'  => '400px',
248
                        ]
249
                    );
250
                }
251
                break;
252
            case 'koivi':
253
                if (\is_readable(XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php')) {
254
                    require_once XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php';
255
                    $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...
256
                }
257
                break;
258
        }
259
260
        return $editor;
261
    }
262
263
    /**
264
     * @param \Xmf\Module\Helper $helper
265
     * @param array|null         $options
266
     * @return \XoopsFormDhtmlTextArea|\XoopsFormEditor
267
     */
268
    public static function getEditor($helper = null, $options = null)
269
    {
270
        /** @var News\Helper $helper */
271
        if (null === $options) {
272
            $options           = [];
273
            $options['name']   = 'Editor';
274
            $options['value']  = 'Editor';
275
            $options['rows']   = 10;
276
            $options['cols']   = '100%';
277
            $options['width']  = '100%';
278
            $options['height'] = '400px';
279
        }
280
281
        if (null === $helper) {
282
            $helper = Helper::getInstance();
283
        }
284
285
        $isAdmin = $helper->isUserAdmin();
286
287
        if (\class_exists('XoopsFormEditor')) {
288
            if ($isAdmin) {
289
                $descEditor = new \XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorAdmin'), $options, $nohtml = false, $onfailure = 'textarea');
290
            } else {
291
                $descEditor = new \XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorUser'), $options, $nohtml = false, $onfailure = 'textarea');
292
            }
293
        } else {
294
            $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

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

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

577
        /** @scrutinizer ignore-call */ 
578
        $tpllist        = $tplfileHandler->find(null, null, null, $folder);
Loading history...
578
        $xoopsTpl       = new \XoopsTpl();
0 ignored issues
show
Unused Code introduced by
The assignment to $xoopsTpl is dead and can be removed.
Loading history...
579
        \xoops_template_clear_module_cache($xoopsModule->getVar('mid')); // Clear module's blocks cache
580
581
        // Remove cache for each page.
582
        foreach ($tpllist as $onetemplate) {
583
            if ('module' === $onetemplate->getVar('tpl_type')) {
584
                // 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
585
                $files_del = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $files_del is dead and can be removed.
Loading history...
586
                $files_del = \glob(XOOPS_CACHE_PATH . '/*' . $onetemplate->getVar('tpl_file') . '*', GLOB_NOSORT);
587
                if (\count($files_del) > 0) {
0 ignored issues
show
Bug introduced by
It seems like $files_del can also be of type false; however, parameter $var of count() does only seem to accept Countable|array, 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

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

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

837
            /** @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...
838
        }
839
        if (!$keep_original) {
840
            @\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

840
            /** @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...
841
        }
842
843
        return true;
844
    }
845
}
846