Completed
Push — master ( 70d8b1...741c06 )
by Michael
02:57
created

functions.php ➔ news_createmeta_keywords()   F

Complexity

Conditions 14
Paths 241

Size

Total Lines 134
Code Lines 115

Duplication

Lines 6
Ratio 4.48 %

Importance

Changes 0
Metric Value
cc 14
eloc 115
nc 241
nop 1
dl 6
loc 134
rs 3.9099
c 0
b 0
f 0

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
2
//
3
//  ------------------------------------------------------------------------ //
4
//                XOOPS - PHP Content Management System                      //
5
//                  Copyright (c) 2000-2016 XOOPS.org                        //
6
//                       <http://xoops.org/>                             //
7
//  ------------------------------------------------------------------------ //
8
//  This program is free software; you can redistribute it and/or modify     //
9
//  it under the terms of the GNU General Public License as published by     //
10
//  the Free Software Foundation; either version 2 of the License, or        //
11
//  (at your option) any later version.                                      //
12
//                                                                           //
13
//  You may not change or alter any portion of this comment or credits       //
14
//  of supporting developers from this source code or any supporting         //
15
//  source code which is considered copyrighted (c) material of the          //
16
//  original comment or credit authors.                                      //
17
//                                                                           //
18
//  This program is distributed in the hope that it will be useful,          //
19
//  but WITHOUT ANY WARRANTY; without even the implied warranty of           //
20
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
21
//  GNU General Public License for more details.                             //
22
//                                                                           //
23
//  You should have received a copy of the GNU General Public License        //
24
//  along with this program; if not, write to the Free Software              //
25
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA //
26
//  ------------------------------------------------------------------------ //
27
// defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
28
29
/**
30
 * Returns a module's option
31
 *
32
 * Return's a module's option (for the news module)
33
 *
34
 * @package       News
35
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
36
 * @copyright (c) Hervé Thouzard
37
 *
38
 * @param string $option module option's name
39
 *
40
 * @param string $repmodule
41
 *
42
 * @return bool
43
 */
44
use WideImage\WideImage;
45
46
/**
47
 * @param             $option
48
 * @param  string     $repmodule
49
 * @return bool|mixed
50
 */
51
function news_getmoduleoption($option, $repmodule = 'news')
52
{
53
    global $xoopsModuleConfig, $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
54
    static $tbloptions = array();
55
    if (is_array($tbloptions) && array_key_exists($option, $tbloptions)) {
56
        return $tbloptions[$option];
57
    }
58
59
    $retval = false;
60
    if (isset($xoopsModuleConfig)
61
        && (is_object($xoopsModule) && $xoopsModule->getVar('dirname') == $repmodule
62
            && $xoopsModule->getVar('isactive'))
63
    ) {
64
        if (isset($xoopsModuleConfig[$option])) {
65
            $retval = $xoopsModuleConfig[$option];
66
        }
67
    } else {
68
        /** @var XoopsModuleHandler $moduleHandler */
69
        $moduleHandler  = xoops_getHandler('module');
70
        $module         = $moduleHandler->getByDirname($repmodule);
71
        $config_handler = xoops_getHandler('config');
72
        if ($module) {
73
            $moduleConfig = $config_handler->getConfigsByCat(0, $module->getVar('mid'));
74
            if (isset($moduleConfig[$option])) {
75
                $retval = $moduleConfig[$option];
76
            }
77
        }
78
    }
79
    $tbloptions[$option] = $retval;
80
81
    return $retval;
82
}
83
84
/**
85
 * Updates rating data in item table for a given item
86
 *
87
 * @package       News
88
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
89
 * @copyright (c) Hervé Thouzard
90
 * @param $storyid
91
 */
92
function news_updaterating($storyid)
93
{
94
    global $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
95
    $query       = 'SELECT rating FROM ' . $xoopsDB->prefix('news_stories_votedata') . ' WHERE storyid = ' . $storyid;
96
    $voteresult  = $xoopsDB->query($query);
97
    $votesDB     = $xoopsDB->getRowsNum($voteresult);
98
    $totalrating = 0;
99
    while (list($rating) = $xoopsDB->fetchRow($voteresult)) {
100
        $totalrating += $rating;
101
    }
102
    $finalrating = $totalrating / $votesDB;
103
    $finalrating = number_format($finalrating, 4);
104
    $sql         = sprintf('UPDATE %s SET rating = %u, votes = %u WHERE storyid = %u', $xoopsDB->prefix('news_stories'), $finalrating, $votesDB,
105
                           $storyid);
106
    $xoopsDB->queryF($sql);
107
}
108
109
/**
110
 * Internal function for permissions
111
 *
112
 * Returns a list of all the permitted topics Ids for the current user
113
 *
114
 * @param string $permtype
115
 *
116
 * @return array $topics    Permitted topics Ids
117
 *
118
 * @package       News
119
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
120
 * @copyright (c) Hervé Thouzard
121
 */
122
function news_MygetItemIds($permtype = 'news_view')
123
{
124
    global $xoopsUser;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
125
    static $tblperms = array();
126
    if (is_array($tblperms) && array_key_exists($permtype, $tblperms)) {
127
        return $tblperms[$permtype];
128
    }
129
130
    /** @var XoopsModuleHandler $moduleHandler */
131
    $moduleHandler       = xoops_getHandler('module');
132
    $newsModule          = $moduleHandler->getByDirname('news');
133
    $groups              = is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
134
    $gperm_handler       = xoops_getHandler('groupperm');
135
    $topics              = $gperm_handler->getItemIds($permtype, $groups, $newsModule->getVar('mid'));
136
    $tblperms[$permtype] = $topics;
137
138
    return $topics;
139
}
140
141
/**
142
 * @param $document
143
 *
144
 * @return mixed
145
 */
146
function news_html2text($document)
147
{
148
    // PHP Manual:: function preg_replace
149
    // $document should contain an HTML document.
150
    // This will remove HTML tags, javascript sections
151
    // and white space. It will also convert some
152
    // common HTML entities to their text equivalent.
153
154
    $search = array(
155
        "'<script[^>]*?>.*?</script>'si", // Strip out javascript
156
        "'<img.*?/>'si", // Strip out img tags
157
        "'<[\/\!]*?[^<>]*?>'si", // Strip out HTML tags
158
        "'([\r\n])[\s]+'", // Strip out white space
159
        "'&(quot|#34);'i", // Replace HTML entities
160
        "'&(amp|#38);'i",
161
        "'&(lt|#60);'i",
162
        "'&(gt|#62);'i",
163
        "'&(nbsp|#160);'i",
164
        "'&(iexcl|#161);'i",
165
        "'&(cent|#162);'i",
166
        "'&(pound|#163);'i",
167
        "'&(copy|#169);'i"
168
    ); // evaluate as php
169
170
    $replace = array(
171
        '',
172
        '',
173
        '',
174
        "\\1",
175
        "\"",
176
        '&',
177
        '<',
178
        '>',
179
        ' ',
180
        chr(161),
181
        chr(162),
182
        chr(163),
183
        chr(169),
184
    );
185
186
    $text = preg_replace($search, $replace, $document);
187
188
    preg_replace_callback('/&#(\d+);/', function ($matches) {
189
        return chr($matches[1]);
190
    }, $document);
191
192
    return $text;
193
}
194
195
/**
196
 * Is Xoops 2.3.x ?
197
 *
198
 * @return boolean need to say it ?
199
 */
200
function news_isX23()
201
{
202
    $x23 = false;
203
    $xv  = str_replace('XOOPS ', '', XOOPS_VERSION);
204
    if (substr($xv, 2, 1) >= '3') {
205
        $x23 = true;
206
    }
207
208
    return $x23;
209
}
210
211
/**
212
 * Retreive an editor according to the module's option "form_options"
213
 *
214
 * @package       News
215
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
216
 * @copyright (c) Hervé Thouzard
217
 * @param                                                                                                                                 $caption
218
 * @param                                                                                                                                 $name
219
 * @param  string                                                                                                                         $value
220
 * @param  string                                                                                                                         $width
221
 * @param  string                                                                                                                         $height
222
 * @param  string                                                                                                                         $supplemental
223
 * @return bool|XoopsFormDhtmlTextArea|XoopsFormEditor|XoopsFormFckeditor|XoopsFormHtmlarea|XoopsFormTextArea|XoopsFormTinyeditorTextArea
0 ignored issues
show
Documentation introduced by
Should the return type not be XoopsFormEditor|XoopsFor...oopsFormWysiwygTextArea?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
224
 */
225
function news_getWysiwygForm($caption, $name, $value = '', $width = '100%', $height = '400px', $supplemental = '')
226
{
227
    $editor_option            = strtolower(news_getmoduleoption('form_options'));
228
    $editor                   = false;
229
    $editor_configs           = array();
230
    $editor_configs['name']   = $name;
231
    $editor_configs['value']  = $value;
232
    $editor_configs['rows']   = 35;
233
    $editor_configs['cols']   = 60;
234
    $editor_configs['width']  = '100%';
235
    $editor_configs['height'] = '350px';
236
    $editor_configs['editor'] = $editor_option;
237
238
    if (news_isX23()) {
239
        $editor = new XoopsFormEditor($caption, $name, $editor_configs);
240
241
        return $editor;
242
    }
243
244
    // Only for Xoops 2.0.x
245
    switch ($editor_option) {
246 View Code Duplication
        case 'fckeditor':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
247
            if (is_readable(XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php')) {
248
                require_once XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php';
249
                $editor = new XoopsFormFckeditor($caption, $name, $value);
250
            }
251
            break;
252
253 View Code Duplication
        case 'htmlarea':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
254
            if (is_readable(XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php')) {
255
                require_once XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php';
256
                $editor = new XoopsFormHtmlarea($caption, $name, $value);
257
            }
258
            break;
259
260
        case 'dhtmltextarea':
261
        case 'dhtml':
262
            $editor = new XoopsFormDhtmlTextArea($caption, $name, $value, 10, 50, $supplemental);
263
            break;
264
265
        case 'textarea':
266
            $editor = new XoopsFormTextArea($caption, $name, $value);
267
            break;
268
269
        case 'tinyeditor':
270
        case 'tinymce':
271
            if (is_readable(XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php')) {
272
                require_once XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php';
273
                $editor = new XoopsFormTinyeditorTextArea(array(
274
                                                              'caption' => $caption,
275
                                                              'name'    => $name,
276
                                                              'value'   => $value,
277
                                                              'width'   => '100%',
278
                                                              'height'  => '400px'
279
                                                          ));
280
            }
281
            break;
282
283 View Code Duplication
        case 'koivi':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
284
            if (is_readable(XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php')) {
285
                require_once XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php';
286
                $editor = new XoopsFormWysiwygTextArea($caption, $name, $value, $width, $height, '');
287
            }
288
            break;
289
    }
290
291
    return $editor;
292
}
293
294
/**
295
 * Internal function
296
 *
297
 * @package       News
298
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
299
 * @copyright (c) Hervé Thouzard
300
 * @param $text
301
 * @return mixed
302
 */
303
function DublinQuotes($text)
304
{
305
    return str_replace("\"", ' ', $text);
306
}
307
308
/**
309
 * Creates all the meta datas :
310
 * - For Mozilla/Netscape and Opera the site navigation's bar
311
 * - The Dublin's Core Metadata
312
 * - The link for Firefox 2 micro summaries
313
 * - The meta keywords
314
 * - The meta description
315
 *
316
 * @package       News
317
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
318
 * @copyright (c) Hervé Thouzard
319
 * @param null $story
320
 */
321
function news_CreateMetaDatas($story = null)
322
{
323
    global $xoopsConfig, $xoTheme, $xoopsTpl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
324
    $content = '';
325
    $myts    = MyTextSanitizer::getInstance();
326
    include_once XOOPS_ROOT_PATH . '/modules/news/class/class.newstopic.php';
327
328
    /**
329
     * Firefox and Opera Navigation's Bar
330
     */
331
    if (news_getmoduleoption('sitenavbar')) {
332
        $content .= sprintf("<link rel=\"Home\" title=\"%s\" href=\"%s/\" />\n", $xoopsConfig['sitename'], XOOPS_URL);
333
        $content .= sprintf("<link rel=\"Contents\" href=\"%s\" />\n", XOOPS_URL . '/modules/news/index.php');
334
        $content .= sprintf("<link rel=\"Search\" href=\"%s\" />\n", XOOPS_URL . '/search.php');
335
        $content .= sprintf("<link rel=\"Glossary\" href=\"%s\" />\n", XOOPS_URL . '/modules/news/archive.php');
336
        $content .= sprintf("<link rel=\"%s\" href=\"%s\" />\n", $myts->htmlSpecialChars(_NW_SUBMITNEWS), XOOPS_URL . '/modules/news/submit.php');
337
        $content .= sprintf("<link rel=\"alternate\" type=\"application/rss+xml\" title=\"%s\" href=\"%s/\" />\n", $xoopsConfig['sitename'],
338
                            XOOPS_URL . '/backend.php');
339
340
        // Create chapters
341
        include_once XOOPS_ROOT_PATH . '/class/tree.php';
342
        include_once XOOPS_ROOT_PATH . '/modules/news/class/class.newstopic.php';
343
        $xt         = new NewsTopic();
344
        $allTopics  = $xt->getAllTopics(news_getmoduleoption('restrictindex'));
345
        $topic_tree = new XoopsObjectTree($allTopics, 'topic_id', 'topic_pid');
346
        $topics_arr = $topic_tree->getAllChild(0);
347
        foreach ($topics_arr as $onetopic) {
348
            $content .= sprintf("<link rel=\"Chapter\" title=\"%s\" href=\"%s\" />\n", $onetopic->topic_title(),
349
                                XOOPS_URL . '/modules/news/index.php?storytopic=' . $onetopic->topic_id());
350
        }
351
    }
352
353
    /**
354
     * Meta Keywords and Description
355
     * 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
356
     */
357
    $meta_keywords = '';
358
    if (isset($story) && is_object($story)) {
359 View Code Duplication
        if (xoops_trim($story->keywords()) !== '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
360
            $meta_keywords = $story->keywords();
361
        } else {
362
            $meta_keywords = news_createmeta_keywords($story->hometext() . ' ' . $story->bodytext());
363
        }
364
        if (xoops_trim($story->description()) !== '') {
365
            $meta_description = strip_tags($story->description);
366
        } else {
367
            $meta_description = strip_tags($story->title);
368
        }
369
        if (isset($xoTheme) && is_object($xoTheme)) {
370
            $xoTheme->addMeta('meta', 'keywords', $meta_keywords);
371
            $xoTheme->addMeta('meta', 'description', $meta_description);
372
        } elseif (isset($xoopsTpl) && is_object($xoopsTpl)) { // Compatibility for old Xoops versions
373
            $xoopsTpl->assign('xoops_meta_keywords', $meta_keywords);
374
            $xoopsTpl->assign('xoops_meta_description', $meta_description);
375
        }
376
    }
377
378
    /**
379
     * Dublin Core's meta datas
380
     */
381
    if (news_getmoduleoption('dublincore') && isset($story) && is_object($story)) {
382
        $config_handler        = xoops_getHandler('config');
383
        $xoopsConfigMetaFooter = $config_handler->getConfigsByCat(XOOPS_CONF_METAFOOTER);
384
        $content .= '<meta name="DC.Title" content="' . DublinQuotes($story->title()) . "\" />\n";
385
        $content .= '<meta name="DC.Creator" content="' . DublinQuotes($story->uname()) . "\" />\n";
386
        $content .= '<meta name="DC.Subject" content="' . DublinQuotes($meta_keywords) . "\" />\n";
387
        $content .= '<meta name="DC.Description" content="' . DublinQuotes($story->title()) . "\" />\n";
388
        $content .= '<meta name="DC.Publisher" content="' . DublinQuotes($xoopsConfig['sitename']) . "\" />\n";
389
        $content .= '<meta name="DC.Date.created" scheme="W3CDTF" content="' . date('Y-m-d', $story->created) . "\" />\n";
390
        $content .= '<meta name="DC.Date.issued" scheme="W3CDTF" content="' . date('Y-m-d', $story->published) . "\" />\n";
391
        $content .= '<meta name="DC.Identifier" content="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $story->storyid() . "\" />\n";
392
        $content .= '<meta name="DC.Source" content="' . XOOPS_URL . "\" />\n";
393
        $content .= '<meta name="DC.Language" content="' . _LANGCODE . "\" />\n";
394
        $content .= '<meta name="DC.Relation.isReferencedBy" content="'
395
                    . XOOPS_URL
396
                    . '/modules/news/index.php?storytopic='
397
                    . $story->topicid()
398
                    . "\" />\n";
399
        if (isset($xoopsConfigMetaFooter['meta_copyright'])) {
400
            $content .= '<meta name="DC.Rights" content="' . DublinQuotes($xoopsConfigMetaFooter['meta_copyright']) . "\" />\n";
401
        }
402
    }
403
404
    /**
405
     * Firefox 2 micro summaries
406
     */
407
    if (news_getmoduleoption('firefox_microsummaries')) {
408
        $content .= sprintf("<link rel=\"microsummary\" href=\"%s\" />\n", XOOPS_URL . '/modules/news/micro_summary.php');
409
    }
410
411
    if (isset($xoopsTpl) && is_object($xoopsTpl)) {
412
        $xoopsTpl->assign('xoops_module_header', $content);
413
    }
414
}
415
416
/**
417
 * Create the meta keywords based on the content
418
 *
419
 * @package       News
420
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
421
 * @copyright (c) Hervé Thouzard
422
 * @param $content
423
 * @return string
424
 */
425
function news_createmeta_keywords($content)
0 ignored issues
show
Coding Style introduced by
news_createmeta_keywords uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
426
{
427
    include XOOPS_ROOT_PATH . '/modules/news/config.php';
428
    include_once XOOPS_ROOT_PATH . '/modules/news/class/blacklist.php';
429
    include_once XOOPS_ROOT_PATH . '/modules/news/class/registryfile.php';
430
431
    if (!$cfg['meta_keywords_auto_generate']) {
0 ignored issues
show
Bug introduced by
The variable $cfg does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
432
        return '';
433
    }
434
    $registry = new news_registryfile('news_metagen_options.txt');
435
    //    $tcontent = '';
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
436
    $tcontent = $registry->getfile();
437 View Code Duplication
    if (xoops_trim($tcontent) !== '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
438
        list($keywordscount, $keywordsorder) = explode(',', $tcontent);
439
    } else {
440
        $keywordscount = $cfg['meta_keywords_count'];
441
        $keywordsorder = $cfg['meta_keywords_order'];
442
    }
443
444
    $tmp = array();
445
    // Search for the "Minimum keyword length"
446
    if (isset($_SESSION['news_keywords_limit'])) {
447
        $limit = $_SESSION['news_keywords_limit'];
448
    } else {
449
        $config_handler                  = xoops_getHandler('config');
450
        $xoopsConfigSearch               = $config_handler->getConfigsByCat(XOOPS_CONF_SEARCH);
451
        $limit                           = $xoopsConfigSearch['keyword_min'];
452
        $_SESSION['news_keywords_limit'] = $limit;
453
    }
454
    $myts            = MyTextSanitizer::getInstance();
455
    $content         = str_replace('<br>', ' ', $content);
456
    $content         = $myts->undoHtmlSpecialChars($content);
457
    $content         = strip_tags($content);
458
    $content         = strtolower($content);
459
    $search_pattern  = array(
460
        '&nbsp;',
461
        "\t",
462
        "\r\n",
463
        "\r",
464
        "\n",
465
        ',',
466
        '.',
467
        "'",
468
        ';',
469
        ':',
470
        ')',
471
        '(',
472
        '"',
473
        '?',
474
        '!',
475
        '{',
476
        '}',
477
        '[',
478
        ']',
479
        '<',
480
        '>',
481
        '/',
482
        '+',
483
        '-',
484
        '_',
485
        '\\',
486
        '*'
487
    );
488
    $replace_pattern = array(
489
        ' ',
490
        ' ',
491
        ' ',
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
    $content         = str_replace($search_pattern, $replace_pattern, $content);
518
    $keywords        = explode(' ', $content);
519
    switch ($keywordsorder) {
520
        case 0: // Ordre d'apparition dans le texte
521
            $keywords = array_unique($keywords);
522
            break;
523
        case 1: // Ordre de fréquence des mots
524
            $keywords = array_count_values($keywords);
525
            asort($keywords);
526
            $keywords = array_keys($keywords);
527
            break;
528
        case 2: // Ordre inverse de la fréquence des mots
529
            $keywords = array_count_values($keywords);
530
            arsort($keywords);
531
            $keywords = array_keys($keywords);
532
            break;
533
    }
534
    // Remove black listed words
535
    $metablack = new news_blacklist();
536
    $words     = $metablack->getAllKeywords();
0 ignored issues
show
Unused Code introduced by
$words is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
537
    $keywords  = $metablack->remove_blacklisted($keywords);
538
539
    foreach ($keywords as $keyword) {
540
        if (strlen($keyword) >= $limit && !is_numeric($keyword)) {
541
            $tmp[] = $keyword;
542
        }
543
    }
544
    $tmp = array_slice($tmp, 0, $keywordscount);
545
    if (count($tmp) > 0) {
546
        return implode(',', $tmp);
547
    } else {
548
        if (!isset($config_handler) || !is_object($config_handler)) {
549
            $config_handler = xoops_getHandler('config');
550
        }
551
        $xoopsConfigMetaFooter = $config_handler->getConfigsByCat(XOOPS_CONF_METAFOOTER);
552
        if (isset($xoopsConfigMetaFooter['meta_keywords'])) {
553
            return $xoopsConfigMetaFooter['meta_keywords'];
554
        } else {
555
            return '';
556
        }
557
    }
558
}
559
560
/**
561
 * Remove module's cache
562
 *
563
 * @package       News
564
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
565
 * @copyright (c) Hervé Thouzard
566
 */
567
function news_updateCache()
568
{
569
    global $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
570
    $folder  = $xoopsModule->getVar('dirname');
571
    $tpllist = array();
0 ignored issues
show
Unused Code introduced by
$tpllist is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
572
    include_once XOOPS_ROOT_PATH . '/class/xoopsblock.php';
573
    include_once XOOPS_ROOT_PATH . '/class/template.php';
574
    $tplfile_handler = xoops_getHandler('tplfile');
575
    $tpllist         = $tplfile_handler->find(null, null, null, $folder);
576
    $xoopsTpl        = new XoopsTpl();
0 ignored issues
show
Unused Code introduced by
$xoopsTpl is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

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 ($onetemplate->getVar('tpl_type') === 'module') {
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 = array();
0 ignored issues
show
Unused Code introduced by
$files_del is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
584
            $files_del = glob(XOOPS_CACHE_PATH . '/*' . $onetemplate->getVar('tpl_file') . '*');
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
 * @package       News
598
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
599
 * @copyright (c) Hervé Thouzard
600
 * @param $tablename
601
 * @return bool
602
 */
603
function news_TableExists($tablename)
604
{
605
    global $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
606
    $result = $xoopsDB->queryF("SHOW TABLES LIKE '$tablename'");
607
608
    return ($xoopsDB->getRowsNum($result) > 0);
609
}
610
611
/**
612
 * Verify that a field exists inside a mysql table
613
 *
614
 * @package       News
615
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
616
 * @copyright (c) Hervé Thouzard
617
 * @param $fieldname
618
 * @param $table
619
 * @return bool
620
 */
621
function news_FieldExists($fieldname, $table)
622
{
623
    global $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
624
    $result = $xoopsDB->queryF("SHOW COLUMNS FROM   $table LIKE '$fieldname'");
625
626
    return ($xoopsDB->getRowsNum($result) > 0);
627
}
628
629
/**
630
 * Add a field to a mysql table
631
 *
632
 * @package       News
633
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
634
 * @copyright (c) Hervé Thouzard
635
 * @param $field
636
 * @param $table
637
 * @return
638
 */
639
function news_AddField($field, $table)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
640
{
641
    global $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
642
    $result = $xoopsDB->queryF('ALTER TABLE ' . $table . " ADD $field;");
643
644
    return $result;
645
}
646
647
/**
648
 * Verify that the current user is a member of the Admin group
649
 */
650
function news_is_admin_group()
651
{
652
    global $xoopsUser, $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
653
    if (is_object($xoopsUser)) {
654
        if (in_array('1', $xoopsUser->getGroups())) {
655
            return true;
656
        } else {
657
            if ($xoopsUser->isAdmin($xoopsModule->mid())) {
658
                return true;
659
            } else {
660
                return false;
661
            }
662
        }
663
    } else {
664
        return false;
665
    }
666
}
667
668
/**
669
 * Verify if the current "user" is a bot or not
670
 *
671
 * If you have a problem with this function, insert the folowing code just before the line if (isset($_SESSION['news_cache_bot'])) { :
672
 * return false;
673
 *
674
 * @package       News
675
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
676
 * @copyright (c) Hervé Thouzard
677
 */
678
function news_isbot()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
Coding Style introduced by
news_isbot uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
679
{
680
    if (isset($_SESSION['news_cache_bot'])) {
681
        return $_SESSION['news_cache_bot'];
682
    } else {
683
        // Add here every bot you know separated by a pipe | (not matter with the upper or lower cases)
684
        // If you want to see the result for yourself, add your navigator's user agent at the end (mozilla for example)
685
        $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';
686
        $botlist      = strtoupper($botlist);
687
        $currentagent = strtoupper(xoops_getenv('HTTP_USER_AGENT'));
688
        $retval       = false;
689
        $botarray     = explode('|', $botlist);
690
        foreach ($botarray as $onebot) {
691
            if (false !== strpos($currentagent, $onebot)) {
692
                $retval = true;
693
                break;
694
            }
695
        }
696
    }
697
    $_SESSION['news_cache_bot'] = $retval;
698
699
    return $retval;
700
}
701
702
/**
703
 * Create an infotip
704
 *
705
 * @package       News
706
 * @author        Hervé Thouzard (http://www.herve-thouzard.com)
707
 * @copyright (c) Hervé Thouzard
708
 * @param $text
709
 * @return null
710
 */
711
function news_make_infotips($text)
712
{
713
    $infotips = news_getmoduleoption('infotips');
714
    if ($infotips > 0) {
715
        $myts = MyTextSanitizer::getInstance();
716
717
        return $myts->htmlSpecialChars(xoops_substr(strip_tags($text), 0, $infotips));
718
    }
719
720
    return null;
721
}
722
723
/**
724
 * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
725
 *           <amos dot robinson at gmail dot com>
726
 * @param $string
727
 * @return string
728
 */
729
function news_close_tags($string)
730
{
731
    // match opened tags
732
    if (preg_match_all('/<([a-z\:\-]+)[^\/]>/', $string, $start_tags)) {
733
        $start_tags = $start_tags[1];
734
        // match closed tags
735
        if (preg_match_all('/<\/([a-z]+)>/', $string, $end_tags)) {
736
            $complete_tags = array();
737
            $end_tags      = $end_tags[1];
738
739
            foreach ($start_tags as $key => $val) {
740
                $posb = array_search($val, $end_tags);
741
                if (is_int($posb)) {
742
                    unset($end_tags[$posb]);
743
                } else {
744
                    $complete_tags[] = $val;
745
                }
746
            }
747
        } else {
748
            $complete_tags = $start_tags;
749
        }
750
751
        $complete_tags = array_reverse($complete_tags);
752
        for ($i = 0, $iMax = count($complete_tags); $i < $iMax; ++$i) {
753
            $string .= '</' . $complete_tags[$i] . '>';
754
        }
755
    }
756
757
    return $string;
758
}
759
760
/**
761
 * Smarty truncate_tagsafe modifier plugin
762
 *
763
 * Type:     modifier<br>
764
 * Name:     truncate_tagsafe<br>
765
 * Purpose:  Truncate a string to a certain length if necessary,
766
 *           optionally splitting in the middle of a word, and
767
 *           appending the $etc string or inserting $etc into the middle.
768
 *           Makes sure no tags are left half-open or half-closed
769
 *           (e.g. "Banana in a <a...")
770
 *
771
 * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
772
 *           <amos dot robinson at gmail dot com>
773
 *
774
 * @param string
775
 * @param integer
776
 * @param string
777
 * @param boolean
778
 * @param boolean
779
 *
780
 * @return string
781
 */
782
function news_truncate_tagsafe($string, $length = 80, $etc = '...', $break_words = false)
783
{
784
    if ($length == 0) {
785
        return '';
786
    }
787
    if (strlen($string) > $length) {
788
        $length -= strlen($etc);
789
        if (!$break_words) {
790
            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1));
791
            $string = preg_replace('/<[^>]*$/', '', $string);
792
            $string = news_close_tags($string);
793
        }
794
795
        return $string . $etc;
796
    } else {
797
        return $string;
798
    }
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 integer $param_width   Maximum picture's width
807
 * @param integer $param_height  Maximum picture's height
808
 * @param boolean $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
function news_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 here. This can introduce security issues, and is generally not recommended.

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 here. This can introduce security issues, and is generally not recommended.

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