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

NewsStory::getRandomNews()   D

Complexity

Conditions 15
Paths 143

Size

Total Lines 79
Code Lines 61

Duplication

Lines 24
Ratio 30.38 %

Importance

Changes 0
Metric Value
cc 15
eloc 61
nc 143
nop 7
dl 24
loc 79
rs 4.7516
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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 36 and the first side effect is on line 29.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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
include_once XOOPS_ROOT_PATH . '/modules/news/class/xoopsstory.php';
30
include_once XOOPS_ROOT_PATH . '/include/comment_constants.php';
31
include_once XOOPS_ROOT_PATH . '/modules/news/include/functions.php';
32
33
/**
34
 * Class NewsStory
35
 */
36
class NewsStory extends MyXoopsStory
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
37
{
38
    public $newstopic; // XoopsTopic object
39
    public $rating; // News rating
40
    public $votes; // Number of votes
41
    public $description; // META, desciption
42
    public $keywords; // META, keywords
43
    public $picture;
44
    public $topic_imgurl;
45
    public $topic_title;
46
    public $subtitle;
47
    public $pictureinfo;
48
49
    /**
50
     * Constructor
51
     * @param int $storyid
52
     */
53
    public function __construct($storyid = -1)
54
    {
55
        $this->db          = XoopsDatabaseFactory::getDatabaseConnection();
56
        $this->table       = $this->db->prefix('news_stories');
57
        $this->topicstable = $this->db->prefix('news_topics');
58 View Code Duplication
        if (is_array($storyid)) {
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...
59
            $this->makeStory($storyid);
60
        } elseif ($storyid != -1) {
61
            $this->getStory((int)$storyid);
62
        }
63
    }
64
65
    /**
66
     * Returns the number of stories published before a date
67
     * @param         $timestamp
68
     * @param         $expired
69
     * @param  string $topicslist
70
     * @return mixed
71
     */
72
    public function GetCountStoriesPublishedBefore($timestamp, $expired, $topicslist = '')
73
    {
74
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
75
        $sql = 'SELECT count(*) as cpt FROM ' . $db->prefix('news_stories') . ' WHERE published <=' . $timestamp;
76
        if ($expired) {
77
            $sql .= ' AND (expired>0 AND expired<=' . time() . ')';
78
        }
79
        if (strlen(trim($topicslist)) > 0) {
80
            $sql .= ' AND topicid IN (' . $topicslist . ')';
81
        }
82
        $result = $db->query($sql);
83
        list($count) = $db->fetchRow($result);
84
85
        return $count;
86
    }
87
88
    /**
89
     * Load the specified story from the database
90
     * @param $storyid
91
     */
92
    public function getStory($storyid)
93
    {
94
        $sql   = 'SELECT s.*, t.* FROM '
95
                 . $this->table
96
                 . ' s, '
97
                 . $this->db->prefix('news_topics')
98
                 . ' t WHERE (storyid='
99
                 . (int)$storyid
100
                 . ') AND (s.topicid=t.topic_id)';
101
        $array = $this->db->fetchArray($this->db->query($sql));
102
        $this->makeStory($array);
103
    }
104
105
    /**
106
     * Delete stories that were published before a given date
107
     * @param         $timestamp
108
     * @param         $expired
109
     * @param  string $topicslist
110
     * @return bool
111
     */
112
    public function DeleteBeforeDate($timestamp, $expired, $topicslist = '')
113
    {
114
        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...
115
        $mid          = $xoopsModule->getVar('mid');
116
        $db           = XoopsDatabaseFactory::getDatabaseConnection();
117
        $prefix       = $db->prefix('news_stories');
118
        $vote_prefix  = $db->prefix('news_stories_votedata');
119
        $files_prefix = $db->prefix('news_stories_files');
120
        $sql          = 'SELECT storyid FROM  ' . $prefix . ' WHERE published <=' . $timestamp;
121
        if ($expired) {
122
            $sql .= ' (AND expired>0 AND expired<=' . time() . ')';
123
        }
124
        if (strlen(trim($topicslist)) > 0) {
125
            $sql .= ' AND topicid IN (' . $topicslist . ')';
126
        }
127
        $result = $db->query($sql);
128
        while ($myrow = $db->fetchArray($result)) {
129
            xoops_comment_delete($mid, $myrow['storyid']); // Delete comments
130
            xoops_notification_deletebyitem($mid, 'story', $myrow['storyid']); // Delete notifications
131
            $db->queryF('DELETE FROM ' . $vote_prefix . ' WHERE storyid=' . $myrow['storyid']); // Delete votes
132
            // Remove files and records related to the files
133
            $result2 = $db->query('SELECT * FROM ' . $files_prefix . ' WHERE storyid=' . $myrow['storyid']);
134
            while ($myrow2 = $db->fetchArray($result2)) {
135
                $name = XOOPS_ROOT_PATH . '/uploads/' . $myrow2['downloadname'];
136
                if (file_exists($name)) {
137
                    unlink($name);
138
                }
139
                $db->query('DELETE FROM ' . $files_prefix . ' WHERE fileid=' . $myrow2['fileid']);
140
            }
141
            $db->queryF('DELETE FROM ' . $prefix . ' WHERE storyid=' . $myrow['storyid']); // Delete the story
142
        }
143
144
        return true;
145
    }
146
147
    /**
148
     * @param      $storyid
149
     * @param bool $next
150
     * @param bool $checkRight
151
     *
152
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

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...
153
     */
154
    public function _searchPreviousOrNextArticle($storyid, $next = true, $checkRight = false)
155
    {
156
        $db      = XoopsDatabaseFactory::getDatabaseConnection();
157
        $ret     = array();
158
        $storyid = (int)$storyid;
159
        if ($next) {
160
            $sql     = 'SELECT storyid, title FROM '
161
                       . $db->prefix('news_stories')
162
                       . ' WHERE (published > 0 AND published <= '
163
                       . time()
164
                       . ') AND (expired = 0 OR expired > '
165
                       . time()
166
                       . ') AND storyid > '
167
                       . $storyid;
168
            $orderBy = ' ORDER BY storyid ASC';
169
        } else {
170
            $sql     = 'SELECT storyid, title FROM '
171
                       . $db->prefix('news_stories')
172
                       . ' WHERE (published > 0 AND published <= '
173
                       . time()
174
                       . ') AND (expired = 0 OR expired > '
175
                       . time()
176
                       . ') AND storyid < '
177
                       . $storyid;
178
            $orderBy = ' ORDER BY storyid DESC';
179
        }
180
        if ($checkRight) {
181
            $topics = news_MygetItemIds('news_view');
182
            if (count($topics) > 0) {
183
                $sql .= ' AND topicid IN (' . implode(',', $topics) . ')';
184
            } else {
185
                return null;
186
            }
187
        }
188
        $sql .= $orderBy;
189
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
190
        $result = $db->query($sql, 1);
191
        if ($result) {
192
            $myts = MyTextSanitizer::getInstance();
193
            while ($row = $db->fetchArray($result)) {
194
                $ret = array('storyid' => $row['storyid'], 'title' => $myts->htmlSpecialChars($row['title']));
195
            }
196
        }
197
198
        return $ret;
199
    }
200
201
    /**
202
     * @param      $storyid
203
     * @param bool $checkRight
204
     *
205
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

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...
206
     */
207
    public function getNextArticle($storyid, $checkRight = false)
208
    {
209
        return $this->_searchPreviousOrNextArticle($storyid, true, $checkRight);
210
    }
211
212
    /**
213
     * @param      $storyid
214
     * @param bool $checkRight
215
     *
216
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

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...
217
     */
218
    public function getPreviousArticle($storyid, $checkRight = false)
219
    {
220
        return $this->_searchPreviousOrNextArticle($storyid, false, $checkRight);
221
    }
222
223
    /**
224
     * Returns published stories according to some options
225
     * @param  int    $limit
226
     * @param  int    $start
227
     * @param  bool   $checkRight
228
     * @param  int    $topic
229
     * @param  int    $ihome
230
     * @param  bool   $asobject
231
     * @param  string $order
232
     * @param  bool   $topic_frontpage
233
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

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...
234
     */
235
    public static function getAllPublished(
236
        $limit = 0,
237
        $start = 0,
238
        $checkRight = false,
239
        $topic = 0,
240
        $ihome = 0,
241
        $asobject = true,
242
        $order = 'published',
243
        $topic_frontpage = false
244
    ) {
245
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
246
        $myts = MyTextSanitizer::getInstance();
247
        $ret  = array();
248
        $sql  = 'SELECT s.*, t.* FROM '
249
                . $db->prefix('news_stories')
250
                . ' s, '
251
                . $db->prefix('news_topics')
252
                . ' t WHERE (s.published > 0 AND s.published <= '
253
                . time()
254
                . ') AND (s.expired = 0 OR s.expired > '
255
                . time()
256
                . ') AND (s.topicid=t.topic_id) ';
257
        if ($topic != 0) {
258
            if (!is_array($topic)) {
259 View Code Duplication
                if ($checkRight) {
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...
260
                    $topics = news_MygetItemIds('news_view');
261
                    if (!in_array($topic, $topics)) {
262
                        return null;
263
                    } else {
264
                        $sql .= ' AND s.topicid=' . (int)$topic . ' AND (s.ihome=1 OR s.ihome=0)';
265
                    }
266
                } else {
267
                    $sql .= ' AND s.topicid=' . (int)$topic . ' AND (s.ihome=1 OR s.ihome=0)';
268
                }
269
            } else {
270
                if ($checkRight) {
271
                    $topics = news_MygetItemIds('news_view');
272
                    $topic  = array_intersect($topic, $topics);
273
                }
274
                if (count($topic) > 0) {
275
                    $sql .= ' AND s.topicid IN (' . implode(',', $topic) . ')';
276
                } else {
277
                    return null;
278
                }
279
            }
280 View Code Duplication
        } else {
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...
281
            if ($checkRight) {
282
                $topics = news_MygetItemIds('news_view');
283
                if (count($topics) > 0) {
284
                    $topics = implode(',', $topics);
285
                    $sql .= ' AND s.topicid IN (' . $topics . ')';
286
                } else {
287
                    return null;
288
                }
289
            }
290
            if ((int)$ihome == 0) {
291
                $sql .= ' AND s.ihome=0';
292
            }
293
        }
294
        if ($topic_frontpage) {
295
            $sql .= ' AND t.topic_frontpage=1';
296
        }
297
        $sql .= " ORDER BY s.$order DESC";
298
        $result = $db->query($sql, (int)$limit, (int)$start);
299
300 View Code Duplication
        while ($myrow = $db->fetchArray($result)) {
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...
301
            if ($asobject) {
302
                $ret[] = new NewsStory($myrow);
303
            } else {
304
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
305
            }
306
        }
307
308
        return $ret;
309
    }
310
311
    /**
312
     * Retourne la liste des articles aux archives (pour une p�riode donn�e)
313
     * @param             $publish_start
314
     * @param             $publish_end
315
     * @param  bool       $checkRight
316
     * @param  bool       $asobject
317
     * @param  string     $order
318
     * @return array|null
319
     */
320
    public function getArchive(
321
        $publish_start,
322
        $publish_end,
323
        $checkRight = false,
324
        $asobject = true,
325
        $order = 'published'
326
    ) {
327
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
328
        $myts = MyTextSanitizer::getInstance();
329
        $ret  = array();
330
        $sql  = 'SELECT s.*, t.* FROM '
331
                . $db->prefix('news_stories')
332
                . ' s, '
333
                . $db->prefix('news_topics')
334
                . ' t WHERE (s.topicid=t.topic_id) AND (s.published > '
335
                . $publish_start
336
                . ' AND s.published <= '
337
                . $publish_end
338
                . ') AND (expired = 0 OR expired > '
339
                . time()
340
                . ') ';
341
342
        if ($checkRight) {
343
            $topics = news_MygetItemIds('news_view');
344
            if (count($topics) > 0) {
345
                $topics = implode(',', $topics);
346
                $sql .= ' AND topicid IN (' . $topics . ')';
347
            } else {
348
                return null;
349
            }
350
        }
351
        $sql .= " ORDER BY $order DESC";
352
        $result = $db->query($sql);
353 View Code Duplication
        while ($myrow = $db->fetchArray($result)) {
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...
354
            if ($asobject) {
355
                $ret[] = new NewsStory($myrow);
356
            } else {
357
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
358
            }
359
        }
360
361
        return $ret;
362
    }
363
364
    /**
365
     * Get the today's most readed article
366
     *
367
     * @param int     $limit      records limit
368
     * @param int     $start      starting record
369
     * @param boolean $checkRight Do we need to check permissions (by topics) ?
370
     * @param int     $topic      limit the job to one topic
371
     * @param int     $ihome      Limit to articles published in home page only ?
372
     * @param boolean $asobject   Do we have to return an array of objects or a simple array ?
373
     * @param string  $order      Fields to sort on
374
     *
375
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

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...
376
     */
377
    public function getBigStory(
378
        $limit = 0,
379
        $start = 0,
380
        $checkRight = false,
381
        $topic = 0,
382
        $ihome = 0,
383
        $asobject = true,
384
        $order = 'counter'
385
    ) {
386
        $db    = XoopsDatabaseFactory::getDatabaseConnection();
387
        $myts  = MyTextSanitizer::getInstance();
388
        $ret   = array();
389
        $tdate = mktime(0, 0, 0, date('n'), date('j'), date('Y'));
390
        $sql   = 'SELECT s.*, t.* FROM '
391
                 . $db->prefix('news_stories')
392
                 . ' s, '
393
                 . $db->prefix('news_topics')
394
                 . ' t WHERE (s.topicid=t.topic_id) AND (published > '
395
                 . $tdate
396
                 . ' AND published < '
397
                 . time()
398
                 . ') AND (expired > '
399
                 . time()
400
                 . ' OR expired = 0) ';
401
402
        if ((int)$topic != 0) {
403 View Code Duplication
            if (!is_array($topic)) {
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...
404
                $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
405
            } else {
406
                if (count($topic) > 0) {
407
                    $sql .= ' AND topicid IN (' . implode(',', $topic) . ')';
408
                } else {
409
                    return null;
410
                }
411
            }
412 View Code Duplication
        } else {
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...
413
            if ($checkRight) {
414
                $topics = news_MygetItemIds('news_view');
415
                if (count($topics) > 0) {
416
                    $topics = implode(',', $topics);
417
                    $sql .= ' AND topicid IN (' . $topics . ')';
418
                } else {
419
                    return null;
420
                }
421
            }
422
            if ((int)$ihome == 0) {
423
                $sql .= ' AND ihome=0';
424
            }
425
        }
426
        $sql .= " ORDER BY $order DESC";
427
        $result = $db->query($sql, (int)$limit, (int)$start);
428 View Code Duplication
        while ($myrow = $db->fetchArray($result)) {
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...
429
            if ($asobject) {
430
                $ret[] = new NewsStory($myrow);
431
            } else {
432
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
433
            }
434
        }
435
436
        return $ret;
437
    }
438
439
    /**
440
     * Get all articles published by an author
441
     *
442
     * @param int     $uid        author's id
443
     * @param boolean $checkRight whether to check the user's rights to topics
444
     *
445
     * @param bool    $asobject
446
     *
447
     * @return array
448
     */
449
    public function getAllPublishedByAuthor($uid, $checkRight = false, $asobject = true)
450
    {
451
        $db        = XoopsDatabaseFactory::getDatabaseConnection();
452
        $myts      = MyTextSanitizer::getInstance();
453
        $ret       = array();
454
        $tblstory  = $db->prefix('news_stories');
455
        $tbltopics = $db->prefix('news_topics');
456
457
        $sql = 'SELECT '
458
               . $tblstory
459
               . '.*, '
460
               . $tbltopics
461
               . '.topic_title, '
462
               . $tbltopics
463
               . '.topic_color FROM '
464
               . $tblstory
465
               . ','
466
               . $tbltopics
467
               . ' WHERE ('
468
               . $tblstory
469
               . '.topicid='
470
               . $tbltopics
471
               . '.topic_id) AND (published > 0 AND published <= '
472
               . time()
473
               . ') AND (expired = 0 OR expired > '
474
               . time()
475
               . ')';
476
        $sql .= ' AND uid=' . (int)$uid;
477
        if ($checkRight) {
478
            $topics = news_MygetItemIds('news_view');
479
            $topics = implode(',', $topics);
480
            if (xoops_trim($topics) !== '') {
481
                $sql .= ' AND topicid IN (' . $topics . ')';
482
            }
483
        }
484
        $sql .= ' ORDER BY ' . $tbltopics . '.topic_title ASC, ' . $tblstory . '.published DESC';
485
        $result = $db->query($sql);
486
        while ($myrow = $db->fetchArray($result)) {
487
            if ($asobject) {
488
                $ret[] = new NewsStory($myrow);
489
            } else {
490
                if ($myrow['nohtml']) {
491
                    $html = 0;
492
                } else {
493
                    $html = 1;
494
                }
495
                if ($myrow['nosmiley']) {
496
                    $smiley = 0;
497
                } else {
498
                    $smiley = 1;
499
                }
500
                $ret[$myrow['storyid']] = array(
501
                    'title'       => $myts->displayTarea($myrow['title'], $html, $smiley, 1),
502
                    'topicid'     => (int)$myrow['topicid'],
503
                    'storyid'     => (int)$myrow['storyid'],
504
                    'hometext'    => $myts->displayTarea($myrow['hometext'], $html, $smiley, 1),
505
                    'counter'     => (int)$myrow['counter'],
506
                    'created'     => (int)$myrow['created'],
507
                    'topic_title' => $myts->displayTarea($myrow['topic_title'], $html, $smiley, 1),
508
                    'topic_color' => $myts->displayTarea($myrow['topic_color']),
509
                    'published'   => (int)$myrow['published'],
510
                    'rating'      => (float)$myrow['rating'],
511
                    'votes'       => (int)$myrow['votes']
512
                );
513
            }
514
        }
515
516
        return $ret;
517
    }
518
519
    /**
520
     * Get all expired stories
521
     * @param  int  $limit
522
     * @param  int  $start
523
     * @param  int  $topic
524
     * @param  int  $ihome
525
     * @param  bool $asobject
526
     * @return array
527
     */
528
    public static function getAllExpired($limit = 0, $start = 0, $topic = 0, $ihome = 0, $asobject = true)
529
    {
530
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
531
        $myts = MyTextSanitizer::getInstance();
532
        $ret  = array();
533
        $sql  = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE expired <= ' . time() . ' AND expired > 0';
534
        if (!empty($topic)) {
535
            $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
536
        } else {
537
            if ((int)$ihome == 0) {
538
                $sql .= ' AND ihome=0';
539
            }
540
        }
541
542
        $sql .= ' ORDER BY expired DESC';
543
        $result = $db->query($sql, (int)$limit, (int)$start);
544 View Code Duplication
        while ($myrow = $db->fetchArray($result)) {
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...
545
            if ($asobject) {
546
                $ret[] = new NewsStory($myrow);
547
            } else {
548
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
549
            }
550
        }
551
552
        return $ret;
553
    }
554
555
    /**
556
     * Returns an array of object containing all the news to be automatically published.
557
     * @param  int  $limit
558
     * @param  bool $asobject
559
     * @param  int  $start
560
     * @return array
561
     */
562
    public static function getAllAutoStory($limit = 0, $asobject = true, $start = 0)
563
    {
564
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
565
        $myts   = MyTextSanitizer::getInstance();
566
        $ret    = array();
567
        $sql    = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE published > ' . time() . ' ORDER BY published ASC';
568
        $result = $db->query($sql, (int)$limit, (int)$start);
569 View Code Duplication
        while ($myrow = $db->fetchArray($result)) {
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...
570
            if ($asobject) {
571
                $ret[] = new NewsStory($myrow);
572
            } else {
573
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
574
            }
575
        }
576
577
        return $ret;
578
    }
579
580
    /**
581
     * Get all submitted stories awaiting approval
582
     *
583
     * @param int     $limit      Denotes where to start the query
584
     * @param boolean $asobject   true will returns the stories as an array of objects, false will return storyid => title
585
     * @param boolean $checkRight whether to check the user's rights to topics
586
     *
587
     * @param int     $start
588
     *
589
     * @return array
590
     */
591
    public static function getAllSubmitted($limit = 0, $asobject = true, $checkRight = false, $start = 0)
592
    {
593
        $db       = XoopsDatabaseFactory::getDatabaseConnection();
594
        $myts     = MyTextSanitizer::getInstance();
595
        $ret      = array();
596
        $criteria = new CriteriaCompo(new Criteria('published', 0));
597
        if ($checkRight) {
598
            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...
599
            if (!is_object($xoopsUser)) {
600
                return $ret;
601
            }
602
            $allowedtopics = news_MygetItemIds('news_approve');
603
            $criteria2     = new CriteriaCompo();
604
            foreach ($allowedtopics as $key => $topicid) {
605
                $criteria2->add(new Criteria('topicid', $topicid), 'OR');
606
            }
607
            $criteria->add($criteria2);
608
        }
609
        $sql = 'SELECT s.*, t.* FROM ' . $db->prefix('news_stories') . ' s, ' . $db->prefix('news_topics') . ' t ';
610
        $sql .= ' ' . $criteria->renderWhere() . ' AND (s.topicid=t.topic_id) ORDER BY created DESC';
611
        $result = $db->query($sql, (int)$limit, (int)$start);
612 View Code Duplication
        while ($myrow = $db->fetchArray($result)) {
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...
613
            if ($asobject) {
614
                $ret[] = new NewsStory($myrow);
615
            } else {
616
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
617
            }
618
        }
619
620
        return $ret;
621
    }
622
623
    /**
624
     * Used in the module's admin to know the number of expired, automated or pubilshed news
625
     *
626
     * @param int  $storytype  1=Expired, 2=Automated, 3=New submissions, 4=Last published stories
627
     * @param bool $checkRight verify permissions or not ?
628
     *
629
     * @return int
630
     */
631
    public static function getAllStoriesCount($storytype = 1, $checkRight = false)
632
    {
633
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
634
        $sql = 'SELECT count(*) as cpt FROM ' . $db->prefix('news_stories') . ' WHERE ';
635
        switch ($storytype) {
636
            case 1: // Expired
637
                $sql .= '(expired <= ' . time() . ' AND expired >0)';
638
                break;
639
            case 2: // Automated
640
                $sql .= '(published > ' . time() . ')';
641
                break;
642
            case 3: // New submissions
643
                $sql .= '(published = 0)';
644
                break;
645
            case 4: // Last published stories
646
                $sql .= '(published > 0 AND published <= ' . time() . ') AND (expired = 0 OR expired > ' . time() . ')';
647
                break;
648
        }
649
        if ($checkRight) {
650
            $topics = news_MygetItemIds('news_view');
651
            if (count($topics) > 0) {
652
                $topics = implode(',', $topics);
653
                $sql .= ' AND topicid IN (' . $topics . ')';
654
            } else {
655
                return 0;
656
            }
657
        }
658
        $result = $db->query($sql);
659
        $myrow  = $db->fetchArray($result);
660
661
        return $myrow['cpt'];
662
    }
663
664
    /**
665
     * Get a list of stories (as objects) related to a specific topic
666
     * @param        $topicid
667
     * @param  int   $limit
668
     * @return array
669
     */
670
    public static function getByTopic($topicid, $limit = 0)
671
    {
672
        $ret    = array();
673
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
674
        $sql    = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE topicid=' . (int)$topicid . ' ORDER BY published DESC';
675
        $result = $db->query($sql, (int)$limit, 0);
676
        while ($myrow = $db->fetchArray($result)) {
677
            $ret[] = new NewsStory($myrow);
678
        }
679
680
        return $ret;
681
    }
682
683
    /**
684
     * Count the number of news published for a specific topic
685
     * @param  int  $topicid
686
     * @param  bool $checkRight
687
     * @return null
688
     */
689
    public static function countPublishedByTopic($topicid = 0, $checkRight = false)
690
    {
691
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
692
        $sql = 'SELECT COUNT(*) FROM '
693
               . $db->prefix('news_stories')
694
               . ' WHERE published > 0 AND published <= '
695
               . time()
696
               . ' AND (expired = 0 OR expired > '
697
               . time()
698
               . ')';
699 View Code Duplication
        if (!empty($topicid)) {
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...
700
            $sql .= ' AND topicid=' . (int)$topicid;
701
        } else {
702
            $sql .= ' AND ihome=0';
703
            if ($checkRight) {
704
                $topics = news_MygetItemIds('news_view');
705
                if (count($topics) > 0) {
706
                    $topics = implode(',', $topics);
707
                    $sql .= ' AND topicid IN (' . $topics . ')';
708
                } else {
709
                    return null;
710
                }
711
            }
712
        }
713
        $result = $db->query($sql);
714
        list($count) = $db->fetchRow($result);
715
716
        return $count;
717
    }
718
719
    /**
720
     * Internal function
721
     */
722
    public function adminlink()
723
    {
724
        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...
725
        $dirname = basename(dirname(__DIR__));
726
        /** @var XoopsModuleHandler $moduleHandler */
727
        $moduleHandler = xoops_getHandler('module');
728
        $module        = $moduleHandler->getByDirname($dirname);
729
        $pathIcon16    = $module->getInfo('icons16');
730
731
        $ret = '&nbsp; <a href='
732
               . XOOPS_URL
733
               . '/modules/news/submit.php?op=edit&amp;storyid='
734
               . $this->storyid()
735
               . '><img src='
736
               . $pathIcon16
737
               . '/edit.png'
738
               . ' '
739
               . 'title='
740
               . _NW_EDIT
741
               . '></a>'
742
               . '<a href='
743
               . XOOPS_URL
744
               . '/modules/news/admin/index.php?op=delete&amp;storyid='
745
               . $this->storyid()
746
               . '><img src='
747
               . $pathIcon16
748
               . '/delete.png'
749
               . ' '
750
               . 'title='
751
               . _NW_DELETE
752
               . '></a> &nbsp;';
753
754
        return $ret;
755
    }
756
757
    /**
758
     * Get the topic image url
759
     * @param string $format
760
     * @return
761
     */
762 View Code Duplication
    public function topic_imgurl($format = 'S')
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...
Duplication introduced by
This method seems to be duplicated in 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...
763
    {
764
        if (trim($this->topic_imgurl) === '') {
765
            $this->topic_imgurl = 'blank.png';
766
        }
767
        $myts = MyTextSanitizer::getInstance();
768
        switch ($format) {
769
            case 'S':
770
                $imgurl = $myts->htmlSpecialChars($this->topic_imgurl);
771
                break;
772
            case 'E':
773
                $imgurl = $myts->htmlSpecialChars($this->topic_imgurl);
774
                break;
775
            case 'P':
776
                $imgurl = $myts->stripSlashesGPC($this->topic_imgurl);
777
                $imgurl = $myts->htmlSpecialChars($imgurl);
778
                break;
779
            case 'F':
780
                $imgurl = $myts->stripSlashesGPC($this->topic_imgurl);
781
                $imgurl = $myts->htmlSpecialChars($imgurl);
782
                break;
783
        }
784
785
        return $imgurl;
0 ignored issues
show
Bug introduced by
The variable $imgurl does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
786
    }
787
788
    /**
789
     * @param string $format
790
     *
791
     * @return mixed
792
     */
793
    public function topic_title($format = 'S')
794
    {
795
        $myts = MyTextSanitizer::getInstance();
796
        switch ($format) {
797
            case 'S':
798
                $title = $myts->htmlSpecialChars($this->topic_title);
799
                break;
800
            case 'E':
801
                $title = $myts->htmlSpecialChars($this->topic_title);
802
                break;
803
            case 'P':
804
                $title = $myts->stripSlashesGPC($this->topic_title);
805
                $title = $myts->htmlSpecialChars($title);
806
                break;
807
            case 'F':
808
                $title = $myts->stripSlashesGPC($this->topic_title);
809
                $title = $myts->htmlSpecialChars($title);
810
                break;
811
        }
812
813
        return $title;
0 ignored issues
show
Bug introduced by
The variable $title does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
814
    }
815
816
    /**
817
     * @return string
818
     */
819
    public function imglink()
820
    {
821
        $ret = '';
822
        if ($this->topic_imgurl() !== ''
823
            && file_exists(XOOPS_ROOT_PATH . '/uploads/news/image/' . $this->topic_imgurl())
824
        ) {
825
            $ret = "<a href='"
826
                   . XOOPS_URL
827
                   . '/modules/news/index.php?storytopic='
828
                   . $this->topicid()
829
                   . "'><img src='"
830
                   . XOOPS_URL
831
                   . '/uploads/news/image/'
832
                   . $this->topic_imgurl()
833
                   . "' alt='"
834
                   . $this->topic_title()
835
                   . "' hspace='10' vspace='10' align='"
836
                   . $this->topicalign()
837
                   . "' /></a>";
838
        }
839
840
        return $ret;
841
    }
842
843
    /**
844
     * @return string
845
     */
846
    public function textlink()
847
    {
848
        $ret = '<a titls='
849
               . $this->topic_title()
850
               . " href='"
851
               . XOOPS_URL
852
               . '/modules/news/index.php?storytopic='
853
               . $this->topicid()
854
               . "'>"
855
               . $this->topic_title()
856
               . '</a>';
857
858
        return $ret;
859
    }
860
861
    /**
862
     * Function used to prepare an article to be showned
863
     * @param $filescount
864
     * @return array
865
     */
866
    public function prepare2show($filescount)
867
    {
868
        include_once XOOPS_ROOT_PATH . '/modules/news/include/functions.php';
869
        global $xoopsUser, $xoopsConfig, $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...
870
871
        $dirname = basename(dirname(__DIR__));
872
        /** @var XoopsModuleHandler $moduleHandler */
873
        $moduleHandler = xoops_getHandler('module');
874
        $module        = $moduleHandler->getByDirname($dirname);
875
        $pathIcon16    = $module->getInfo('icons16');
876
877
        $myts                 = MyTextSanitizer::getInstance();
878
        $infotips             = news_getmoduleoption('infotips');
879
        $story                = array();
880
        $story['id']          = $this->storyid();
881
        $story['poster']      = $this->uname();
882
        $story['author_name'] = $this->uname();
883
        $story['author_uid']  = $this->uid();
884
        if ($story['poster'] !== false) {
885
            $story['poster'] = "<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $this->uid() . "'>" . $story['poster'] . '</a>';
886
        } else {
887
            if ($xoopsModuleConfig['displayname'] != 3) {
888
                $story['poster'] = $xoopsConfig['anonymous'];
889
            }
890
        }
891
        if ($xoopsModuleConfig['ratenews']) {
892
            $story['rating'] = number_format($this->rating(), 2);
893
            if ($this->votes == 1) {
894
                $story['votes'] = _NW_ONEVOTE;
895
            } else {
896
                $story['votes'] = sprintf(_NW_NUMVOTES, $this->votes);
897
            }
898
        }
899
        $story['posttimestamp']     = $this->published();
900
        $story['posttime']          = formatTimestamp($story['posttimestamp'], news_getmoduleoption('dateformat'));
901
        $story['topic_description'] = $myts->displayTarea($this->topic_description);
0 ignored issues
show
Bug introduced by
The property topic_description does not seem to exist. Did you mean description?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
902
903
        $auto_summary = '';
0 ignored issues
show
Unused Code introduced by
$auto_summary 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...
904
        $tmp          = '';
905
        $auto_summary = $this->auto_summary($this->bodytext(), $tmp);
906
907
        $story['text'] = $this->hometext();
908
        $story['text'] = str_replace('[summary]', $auto_summary, $story['text']);
909
910
        //$story['picture'] = XOOPS_URL.'/uploads/news/image/'.$this->picture();
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
911
        if ($this->picture() !== '') {
912
            $story['picture'] = XOOPS_URL . '/uploads/news/image/' . $this->picture();
913
        } else {
914
            $story['picture'] = '';
915
        }
916
        $story['pictureinfo'] = $this->pictureinfo();
917
918
        $introcount = strlen($story['text']);
919
        $fullcount  = strlen($this->bodytext());
920
        $totalcount = $introcount + $fullcount;
921
922
        $morelink = '';
923
        if ($fullcount > 1) {
924
            $morelink .= '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
925
            $morelink .= '">' . _NW_READMORE . '</a>';
926
            $morelink .= ' | ' . sprintf(_NW_BYTESMORE, $totalcount);
927
            if (XOOPS_COMMENT_APPROVENONE != $xoopsModuleConfig['com_rule']) {
928
                $morelink .= ' | ';
929
            }
930
        }
931
        if (XOOPS_COMMENT_APPROVENONE != $xoopsModuleConfig['com_rule']) {
932
            $ccount = $this->comments();
933
            $morelink .= '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
934
            $morelink2 = '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
935
            if ($ccount == 0) {
936
                $morelink .= '">' . _NW_COMMENTS . '</a>';
937
            } else {
938
                if ($fullcount < 1) {
939
                    if ($ccount == 1) {
940
                        $morelink .= '">' . _NW_READMORE . '</a> | ' . $morelink2 . '">' . _NW_ONECOMMENT . '</a>';
941 View Code Duplication
                    } else {
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...
942
                        $morelink .= '">' . _NW_READMORE . '</a> | ' . $morelink2 . '">';
943
                        $morelink .= sprintf(_NW_NUMCOMMENTS, $ccount);
944
                        $morelink .= '</a>';
945
                    }
946
                } else {
947 View Code Duplication
                    if ($ccount == 1) {
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...
948
                        $morelink .= '">' . _NW_ONECOMMENT . '</a>';
949
                    } else {
950
                        $morelink .= '">';
951
                        $morelink .= sprintf(_NW_NUMCOMMENTS, $ccount);
952
                        $morelink .= '</a>';
953
                    }
954
                }
955
            }
956
        }
957
        $story['morelink']  = $morelink;
958
        $story['adminlink'] = '';
959
960
        $approveprivilege = 0;
961
        if (news_is_admin_group()) {
962
            $approveprivilege = 1;
963
        }
964
965
        if ($xoopsModuleConfig['authoredit'] == 1
966
            && (is_object($xoopsUser)
967
                && $xoopsUser->getVar('uid') == $this->uid())
968
        ) {
969
            $approveprivilege = 1;
970
        }
971
        if ($approveprivilege) {
972
            $story['adminlink'] = $this->adminlink();
973
        }
974
        $story['mail_link'] = 'mailto:?subject='
975
                              . sprintf(_NW_INTARTICLE, $xoopsConfig['sitename'])
976
                              . '&amp;body='
977
                              . sprintf(_NW_INTARTFOUND, $xoopsConfig['sitename'])
978
                              . ':  '
979
                              . XOOPS_URL
980
                              . '/modules/news/article.php?storyid='
981
                              . $this->storyid();
982
        $story['imglink']   = '';
983
        $story['align']     = '';
984
        if ($this->topicdisplay()) {
985
            $story['imglink'] = $this->imglink();
986
            $story['align']   = $this->topicalign();
987
        }
988
        if ($infotips > 0) {
989
            $story['infotips'] = ' title="' . news_make_infotips($this->hometext()) . '"';
990
        } else {
991
            $story['infotips'] = 'title="' . $this->title() . '"';
992
        }
993
        $story['title'] = "<a href='"
994
                          . XOOPS_URL
995
                          . '/modules/news/article.php?storyid='
996
                          . $this->storyid()
997
                          . "'"
998
                          . $story['infotips']
999
                          . '>'
1000
                          . $this->title()
1001
                          . '</a>';
1002
        //$story['subtitle'] = $this->subtitle();
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
1003
1004
        $story['hits'] = $this->counter();
1005
        if ($filescount > 0) {
1006
            $story['files_attached'] = true;
1007
            $story['attached_link']  = "<a href='"
1008
                                       . XOOPS_URL
1009
                                       . '/modules/news/article.php?storyid='
1010
                                       . $this->storyid()
1011
                                       . "' title='"
1012
                                       . _NW_ATTACHEDLIB
1013
                                       . "'><img src="
1014
                                       . $pathIcon16
1015
                                       . '/attach.png'
1016
                                       . ' '
1017
                                       . 'title='
1018
                                       . _NW_ATTACHEDLIB
1019
                                       . '></a>';
1020
        } else {
1021
            $story['files_attached'] = false;
1022
            $story['attached_link']  = '';
1023
        }
1024
1025
        return $story;
1026
    }
1027
1028
    /**
1029
     * Returns the user's name of the current story according to the module's option "displayname"
1030
     * @param  int $uid
1031
     * @return null|string
1032
     */
1033
    public function uname($uid = 0)
1034
    {
1035
        global $xoopsConfig;
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...
1036
        include_once XOOPS_ROOT_PATH . '/modules/news/include/functions.php';
1037
        static $tblusers = array();
1038
        $option = -1;
0 ignored issues
show
Unused Code introduced by
$option 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...
1039
        if ($uid == 0) {
1040
            $uid = $this->uid();
1041
        }
1042
1043
        if (is_array($tblusers) && array_key_exists($uid, $tblusers)) {
1044
            return $tblusers[$uid];
1045
        }
1046
1047
        $option = news_getmoduleoption('displayname');
1048
        if (!$option) {
1049
            $option = 1;
1050
        }
1051
1052
        switch ($option) {
1053
            case 1: // Username
1054
                $tblusers[$uid] = XoopsUser::getUnameFromId($uid);
1055
1056
                return $tblusers[$uid];
1057
1058
            case 2: // Display full name (if it is not empty)
1059
                $member_handler = xoops_getHandler('member');
1060
                $thisuser       = $member_handler->getUser($uid);
1061
                if (is_object($thisuser)) {
1062
                    $return = $thisuser->getVar('name');
1063
                    if ($return === '') {
1064
                        $return = $thisuser->getVar('uname');
1065
                    }
1066
                } else {
1067
                    $return = $xoopsConfig['anonymous'];
1068
                }
1069
                $tblusers[$uid] = $return;
1070
1071
                return $return;
1072
1073
            case 3: // Nothing
1074
                $tblusers[$uid] = '';
1075
1076
                return '';
1077
        }
1078
1079
        return null;
1080
    }
1081
1082
    /**
1083
     * Function used to export news (in xml) and eventually the topics definitions
1084
     * Warning, permissions are not exported !
1085
     *
1086
     * @param int      $fromdate     Starting date
1087
     * @param int      $todate       Ending date
1088
     * @param string   $topicslist
1089
     * @param bool|int $usetopicsdef Should we also export topics definitions ?
1090
     * @param          $tbltopics
1091
     * @param boolean  $asobject     Return values as an object or not ?
1092
     *
1093
     * @param string   $order
1094
     *
1095
     * @internal param string $topiclist If not empty, a list of topics to limit to
1096
     * @return array
1097
     */
1098
    public function NewsExport(
1099
        $fromdate,
1100
        $todate,
1101
        $topicslist = '',
1102
        $usetopicsdef = 0,
1103
        &$tbltopics,
1104
        $asobject = true,
1105
        $order = 'published'
1106
    ) {
1107
        $ret  = array();
1108
        $myts = MyTextSanitizer::getInstance();
1109
        if ($usetopicsdef) { // We firt begin by exporting topics definitions
1110
            // Before all we must know wich topics to export
1111
            $sql = 'SELECT distinct topicid FROM '
1112
                   . $this->db->prefix('news_stories')
1113
                   . ' WHERE (published >='
1114
                   . $fromdate
1115
                   . ' AND published <= '
1116
                   . $todate
1117
                   . ')';
1118
            if (strlen(trim($topicslist)) > 0) {
1119
                $sql .= ' AND topicid IN (' . $topicslist . ')';
1120
            }
1121
            $result = $this->db->query($sql);
1122
            while ($myrow = $this->db->fetchArray($result)) {
1123
                $tbltopics[] = $myrow['topicid'];
1124
            }
1125
        }
1126
1127
        // Now we can search for the stories
1128
        $sql = 'SELECT s.*, t.* FROM '
1129
               . $this->table
1130
               . ' s, '
1131
               . $this->db->prefix('news_topics')
1132
               . ' t WHERE (s.topicid=t.topic_id) AND (s.published >='
1133
               . $fromdate
1134
               . ' AND s.published <= '
1135
               . $todate
1136
               . ')';
1137
        if (strlen(trim($topicslist)) > 0) {
1138
            $sql .= ' AND topicid IN (' . $topicslist . ')';
1139
        }
1140
        $sql .= " ORDER BY $order DESC";
1141
        $result = $this->db->query($sql);
1142 View Code Duplication
        while ($myrow = $this->db->fetchArray($result)) {
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...
1143
            if ($asobject) {
1144
                $ret[] = new NewsStory($myrow);
1145
            } else {
1146
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
1147
            }
1148
        }
1149
1150
        return $ret;
1151
    }
1152
1153
    /**
1154
     * Create or update an article
1155
     * @param  bool $approved
1156
     * @return bool|int
1157
     */
1158
    public function store($approved = false)
1159
    {
1160
        $myts        = MyTextSanitizer::getInstance();
1161
        $counter     = isset($this->counter) ? $this->counter : 0;
1162
        $title       = $myts->addSlashes($myts->censorString($this->title));
1163
        $subtitle    = $myts->addSlashes($myts->censorString($this->subtitle));
1164
        $hostname    = $myts->addSlashes($this->hostname);
1165
        $type        = $myts->addSlashes($this->type);
1166
        $hometext    = $myts->addSlashes($myts->censorString($this->hometext));
1167
        $bodytext    = $myts->addSlashes($myts->censorString($this->bodytext));
1168
        $description = $myts->addSlashes($myts->censorString($this->description));
1169
        $keywords    = $myts->addSlashes($myts->censorString($this->keywords));
1170
        $picture     = $myts->addSlashes($this->picture);
1171
        $pictureinfo = $myts->addSlashes($myts->censorString($this->pictureinfo));
1172
        $votes       = (int)$this->votes;
1173
        $rating      = (float)$this->rating;
1174
        if (!isset($this->nohtml) || $this->nohtml != 1) {
1175
            $this->nohtml = 0;
1176
        }
1177
        if (!isset($this->nosmiley) || $this->nosmiley != 1) {
1178
            $this->nosmiley = 0;
1179
        }
1180
        if (!isset($this->notifypub) || $this->notifypub != 1) {
1181
            $this->notifypub = 0;
1182
        }
1183
        if (!isset($this->topicdisplay) || $this->topicdisplay != 0) {
1184
            $this->topicdisplay = 1;
1185
        }
1186
        $expired = !empty($this->expired) ? $this->expired : 0;
1187
        if (!isset($this->storyid)) {
1188
            //$newpost = 1;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
1189
            $newstoryid = $this->db->genId($this->table . '_storyid_seq');
1190
            $created    = time();
1191
            $published  = $this->approved ? (int)$this->published : 0;
1192
            $sql        = sprintf("INSERT INTO %s (storyid, uid, title, created, published, expired, hostname, nohtml, nosmiley, hometext, bodytext, counter, topicid, ihome, notifypub, story_type, topicdisplay, topicalign, comments, rating, votes, description, keywords, picture, pictureinfo, subtitle) VALUES (%u, %u, '%s', %u, %u, %u, '%s', %u, %u, '%s', '%s', %u, %u, %u, %u, '%s', %u, '%s', %u, %u, %u, '%s', '%s', '%s', '%s', '%s')",
1193
                                  $this->table, $newstoryid, (int)$this->uid(), $title, $created, $published, $expired, $hostname,
1194
                                  (int)$this->nohtml(), (int)$this->nosmiley(), $hometext, $bodytext, $counter, (int)$this->topicid(),
1195
                                  (int)$this->ihome(), (int)$this->notifypub(), $type, (int)$this->topicdisplay(), $this->topicalign,
1196
                                  (int)$this->comments(), $rating, $votes, $description, $keywords, $picture, $pictureinfo, $subtitle);
1197
        } else {
1198
            $sql        = sprintf("UPDATE %s SET title='%s', published=%u, expired=%u, nohtml=%u, nosmiley=%u, hometext='%s', bodytext='%s', topicid=%u, ihome=%u, topicdisplay=%u, topicalign='%s', comments=%u, rating=%u, votes=%u, uid=%u, description='%s', keywords='%s', picture='%s' , pictureinfo='%s' , subtitle='%s' WHERE storyid = %u",
1199
                                  $this->table, $title, (int)$this->published(), $expired, (int)$this->nohtml(), (int)$this->nosmiley(), $hometext,
1200
                                  $bodytext, (int)$this->topicid(), (int)$this->ihome(), (int)$this->topicdisplay(), $this->topicalign,
1201
                                  (int)$this->comments(), $rating, $votes, (int)$this->uid(), $description, $keywords, $picture, $pictureinfo,
1202
                                  $subtitle, (int)$this->storyid());
1203
            $newstoryid = (int)$this->storyid();
1204
        }
1205
        if (!$this->db->queryF($sql)) {
1206
            return false;
1207
        }
1208
        if (empty($newstoryid)) {
1209
            $newstoryid    = $this->db->getInsertId();
1210
            $this->storyid = $newstoryid;
1211
        }
1212
1213
        return $newstoryid;
1214
    }
1215
1216
    /**
1217
     * @return mixed
1218
     */
1219
    public function picture()
1220
    {
1221
        return $this->picture;
1222
    }
1223
1224
    /**
1225
     * @return mixed
1226
     */
1227
    public function pictureinfo()
1228
    {
1229
        return $this->pictureinfo;
1230
    }
1231
1232
    /**
1233
     * @return mixed
1234
     */
1235
    public function subtitle()
1236
    {
1237
        return $this->subtitle;
1238
    }
1239
1240
    /**
1241
     * @return mixed
1242
     */
1243
    public function rating()
1244
    {
1245
        return $this->rating;
1246
    }
1247
1248
    /**
1249
     * @return mixed
1250
     */
1251
    public function votes()
1252
    {
1253
        return $this->votes;
1254
    }
1255
1256
    /**
1257
     * @param $data
1258
     */
1259
    public function setPicture($data)
1260
    {
1261
        $this->picture = $data;
1262
    }
1263
1264
    /**
1265
     * @param $data
1266
     */
1267
    public function setPictureinfo($data)
1268
    {
1269
        $this->pictureinfo = $data;
1270
    }
1271
1272
    /**
1273
     * @param $data
1274
     */
1275
    public function setSubtitle($data)
1276
    {
1277
        $this->subtitle = $data;
1278
    }
1279
1280
    /**
1281
     * @param $data
1282
     */
1283
    public function setDescription($data)
1284
    {
1285
        $this->description = $data;
1286
    }
1287
1288
    /**
1289
     * @param $data
1290
     */
1291
    public function setKeywords($data)
1292
    {
1293
        $this->keywords = $data;
1294
    }
1295
1296
    /**
1297
     * @param string $format
1298
     *
1299
     * @return mixed
1300
     */
1301
    public function description($format = 'S')
1302
    {
1303
        $myts = MyTextSanitizer::getInstance();
1304
        switch (strtoupper($format)) {
1305
            case 'S':
1306
                $description = $myts->htmlSpecialChars($this->description);
1307
                break;
1308
            case 'P':
1309
            case 'F':
1310
                $description = $myts->htmlSpecialChars($myts->stripSlashesGPC($this->description));
1311
                break;
1312
            case 'E':
1313
                $description = $myts->htmlSpecialChars($this->description);
1314
                break;
1315
        }
1316
1317
        return $description;
0 ignored issues
show
Bug introduced by
The variable $description does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1318
    }
1319
1320
    /**
1321
     * @param string $format
1322
     *
1323
     * @return mixed
1324
     */
1325
    public function keywords($format = 'S')
1326
    {
1327
        $myts = MyTextSanitizer::getInstance();
1328
        switch (strtoupper($format)) {
1329
            case 'S':
1330
                $keywords = $myts->htmlSpecialChars($this->keywords);
1331
                break;
1332
            case 'P':
1333
            case 'F':
1334
                $keywords = $myts->htmlSpecialChars($myts->stripSlashesGPC($this->keywords));
1335
                break;
1336
            case 'E':
1337
                $keywords = $myts->htmlSpecialChars($this->keywords);
1338
                break;
1339
        }
1340
1341
        return $keywords;
0 ignored issues
show
Bug introduced by
The variable $keywords does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1342
    }
1343
1344
    /**
1345
     * Returns a random number of news
1346
     * @param  int    $limit
1347
     * @param  int    $start
1348
     * @param  bool   $checkRight
1349
     * @param  int    $topic
1350
     * @param  int    $ihome
1351
     * @param  string $order
1352
     * @param  bool   $topic_frontpage
1353
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

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...
1354
     */
1355
    public function getRandomNews(
1356
        $limit = 0,
1357
        $start = 0,
0 ignored issues
show
Unused Code introduced by
The parameter $start is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1358
        $checkRight = false,
1359
        $topic = 0,
1360
        $ihome = 0,
1361
        $order = 'published',
1362
        $topic_frontpage = false
1363
    ) {
1364
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
1365
        $ret = $rand_keys = $ret3 = array();
0 ignored issues
show
Unused Code introduced by
$rand_keys 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...
1366
        $sql = 'SELECT storyid FROM '
1367
               . $db->prefix('news_stories')
1368
               . ' WHERE (published > 0 AND published <= '
1369
               . time()
1370
               . ') AND (expired = 0 OR expired > '
1371
               . time()
1372
               . ')';
1373
        if ($topic != 0) {
1374
            if (!is_array($topic)) {
1375 View Code Duplication
                if ($checkRight) {
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...
1376
                    $topics = news_MygetItemIds('news_view');
1377
                    if (!in_array($topic, $topics)) {
1378
                        return null;
1379
                    } else {
1380
                        $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
1381
                    }
1382
                } else {
1383
                    $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
1384
                }
1385
            } else {
1386
                if (count($topic) > 0) {
1387
                    $sql .= ' AND topicid IN (' . implode(',', $topic) . ')';
1388
                } else {
1389
                    return null;
1390
                }
1391
            }
1392 View Code Duplication
        } else {
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...
1393
            if ($checkRight) {
1394
                $topics = news_MygetItemIds('news_view');
1395
                if (count($topics) > 0) {
1396
                    $topics = implode(',', $topics);
1397
                    $sql .= ' AND topicid IN (' . $topics . ')';
1398
                } else {
1399
                    return null;
1400
                }
1401
            }
1402
            if ((int)$ihome == 0) {
1403
                $sql .= ' AND ihome=0';
1404
            }
1405
        }
1406
        if ($topic_frontpage) {
1407
            $sql .= ' AND t.topic_frontpage=1';
1408
        }
1409
        $sql .= " ORDER BY $order DESC";
1410
        $result = $db->query($sql);
1411
1412
        while ($myrow = $db->fetchArray($result)) {
1413
            $ret[] = $myrow['storyid'];
1414
        }
1415
        $cnt = count($ret);
1416
        if ($cnt) {
1417
            mt_srand((double)microtime() * 10000000);
1418
            if ($limit > $cnt) {
1419
                $limit = $cnt;
1420
            }
1421
            $rand_keys = array_rand($ret, $limit);
1422
            if ($limit > 1) {
1423
                for ($i = 0; $i < $limit; ++$i) {
1424
                    $onestory = $ret[$rand_keys[$i]];
1425
                    $ret3[]   = new NewsStory($onestory);
1426
                }
1427
            } else {
1428
                $ret3[] = new NewsStory($ret[$rand_keys]);
1429
            }
1430
        }
1431
1432
        return $ret3;
1433
    }
1434
1435
    /**
1436
     * Returns statistics about the stories and topics
1437
     * @param $limit
1438
     * @return array
1439
     */
1440
    public function GetStats($limit)
1441
    {
1442
        $ret  = array();
1443
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
1444
        $tbls = $db->prefix('news_stories');
1445
        $tblt = $db->prefix('news_topics');
1446
        $tblf = $db->prefix('news_stories_files');
1447
1448
        $db = XoopsDatabaseFactory::getDatabaseConnection();
1449
        // Number of stories per topic, including expired and non published stories
1450
        $ret2   = array();
1451
        $sql    = "SELECT count(s.storyid) as cpt, s.topicid, t.topic_title FROM $tbls s, $tblt t WHERE s.topicid=t.topic_id GROUP BY s.topicid ORDER BY t.topic_title";
1452
        $result = $db->query($sql);
1453
        while ($myrow = $db->fetchArray($result)) {
1454
            $ret2[$myrow['topicid']] = $myrow;
1455
        }
1456
        $ret['storiespertopic'] = $ret2;
1457
        unset($ret2);
1458
1459
        // Total of reads per topic
1460
        $ret2   = array();
1461
        $sql    = "SELECT Sum(counter) as cpt, topicid FROM $tbls GROUP BY topicid ORDER BY topicid";
1462
        $result = $db->query($sql);
1463
        while ($myrow = $db->fetchArray($result)) {
1464
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1465
        }
1466
        $ret['readspertopic'] = $ret2;
1467
        unset($ret2);
1468
1469
        // Attached files per topic
1470
        $ret2   = array();
1471
        $sql    = "SELECT Count(*) as cpt, s.topicid FROM $tblf f, $tbls s WHERE f.storyid=s.storyid GROUP BY s.topicid ORDER BY s.topicid";
1472
        $result = $db->query($sql);
1473
        while ($myrow = $db->fetchArray($result)) {
1474
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1475
        }
1476
        $ret['filespertopic'] = $ret2;
1477
        unset($ret2);
1478
1479
        // Expired articles per topic
1480
        $ret2   = array();
1481
        $sql    = "SELECT Count(storyid) as cpt, topicid FROM $tbls WHERE expired>0 AND expired<=" . time() . ' GROUP BY topicid ORDER BY topicid';
1482
        $result = $db->query($sql);
1483
        while ($myrow = $db->fetchArray($result)) {
1484
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1485
        }
1486
        $ret['expiredpertopic'] = $ret2;
1487
        unset($ret2);
1488
1489
        // Number of unique authors per topic
1490
        $ret2   = array();
1491
        $sql    = "SELECT Count(Distinct(uid)) as cpt, topicid FROM $tbls GROUP BY topicid ORDER BY topicid";
1492
        $result = $db->query($sql);
1493
        while ($myrow = $db->fetchArray($result)) {
1494
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1495
        }
1496
        $ret['authorspertopic'] = $ret2;
1497
        unset($ret2);
1498
1499
        // Most readed articles
1500
        $ret2   = array();
1501
        $sql    = "SELECT s.storyid, s.uid, s.title, s.counter, s.topicid, t.topic_title  FROM $tbls s, $tblt t WHERE s.topicid=t.topic_id ORDER BY s.counter DESC";
1502
        $result = $db->query($sql, (int)$limit);
1503
        while ($myrow = $db->fetchArray($result)) {
1504
            $ret2[$myrow['storyid']] = $myrow;
1505
        }
1506
        $ret['mostreadednews'] = $ret2;
1507
        unset($ret2);
1508
1509
        // Less readed articles
1510
        $ret2   = array();
1511
        $sql    = "SELECT s.storyid, s.uid, s.title, s.counter, s.topicid, t.topic_title  FROM $tbls s, $tblt t WHERE s.topicid=t.topic_id ORDER BY s.counter";
1512
        $result = $db->query($sql, (int)$limit);
1513
        while ($myrow = $db->fetchArray($result)) {
1514
            $ret2[$myrow['storyid']] = $myrow;
1515
        }
1516
        $ret['lessreadednews'] = $ret2;
1517
        unset($ret2);
1518
1519
        // Best rated articles
1520
        $ret2   = array();
1521
        $sql    = "SELECT s.storyid, s.uid, s.title, s.rating, s.topicid, t.topic_title  FROM $tbls s, $tblt t WHERE s.topicid=t.topic_id ORDER BY s.rating DESC";
1522
        $result = $db->query($sql, (int)$limit);
1523
        while ($myrow = $db->fetchArray($result)) {
1524
            $ret2[$myrow['storyid']] = $myrow;
1525
        }
1526
        $ret['besratednews'] = $ret2;
1527
        unset($ret2);
1528
1529
        // Most readed authors
1530
        $ret2   = array();
1531
        $sql    = "SELECT Sum(counter) as cpt, uid FROM $tbls GROUP BY uid ORDER BY cpt DESC";
1532
        $result = $db->query($sql, (int)$limit);
1533
        while ($myrow = $db->fetchArray($result)) {
1534
            $ret2[$myrow['uid']] = $myrow['cpt'];
1535
        }
1536
        $ret['mostreadedauthors'] = $ret2;
1537
        unset($ret2);
1538
1539
        // Best rated authors
1540
        $ret2   = array();
1541
        $sql    = "SELECT Avg(rating) as cpt, uid FROM $tbls WHERE votes > 0 GROUP BY uid ORDER BY cpt DESC";
1542
        $result = $db->query($sql, (int)$limit);
1543
        while ($myrow = $db->fetchArray($result)) {
1544
            $ret2[$myrow['uid']] = $myrow['cpt'];
1545
        }
1546
        $ret['bestratedauthors'] = $ret2;
1547
        unset($ret2);
1548
1549
        // Biggest contributors
1550
        $ret2   = array();
1551
        $sql    = "SELECT Count(*) as cpt, uid FROM $tbls GROUP BY uid ORDER BY cpt DESC";
1552
        $result = $db->query($sql, (int)$limit);
1553
        while ($myrow = $db->fetchArray($result)) {
1554
            $ret2[$myrow['uid']] = $myrow['cpt'];
1555
        }
1556
        $ret['biggestcontributors'] = $ret2;
1557
        unset($ret2);
1558
1559
        return $ret;
1560
    }
1561
1562
    /**
1563
     * Get the date of the older and most recent news
1564
     * @param $older
1565
     * @param $recent
1566
     */
1567
    public function GetOlderRecentNews(&$older, &$recent)
1568
    {
1569
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
1570
        $sql    = 'SELECT min(published) as minpublish, max(published) as maxpublish FROM ' . $db->prefix('news_stories');
1571
        $result = $db->query($sql);
1572
        if (!$result) {
1573
            $older = $recent = 0;
1574
        } else {
1575
            list($older, $recent) = $this->db->fetchRow($result);
1576
        }
1577
    }
1578
1579
    /*
1580
     * Returns the author's IDs for the Who's who page
1581
     */
1582
    /**
1583
     * @param bool $checkRight
1584
     * @param int  $limit
1585
     * @param int  $start
1586
     *
1587
     * @return array|null
1588
     */
1589
    public function getWhosWho($checkRight = false, $limit = 0, $start = 0)
0 ignored issues
show
Unused Code introduced by
The parameter $limit is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $start is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1590
    {
1591
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
1592
        $ret = array();
1593
        $sql = 'SELECT distinct(uid) as uid FROM '
1594
               . $db->prefix('news_stories')
1595
               . ' WHERE (published > 0 AND published <= '
1596
               . time()
1597
               . ') AND (expired = 0 OR expired > '
1598
               . time()
1599
               . ')';
1600
        if ($checkRight) {
1601
            $topics = news_MygetItemIds('news_view');
1602
            if (count($topics) > 0) {
1603
                $topics = implode(',', $topics);
1604
                $sql .= ' AND topicid IN (' . $topics . ')';
1605
            } else {
1606
                return null;
1607
            }
1608
        }
1609
        $sql .= ' ORDER BY uid';
1610
        $result = $db->query($sql);
1611
        while ($myrow = $db->fetchArray($result)) {
1612
            $ret[] = $myrow['uid'];
1613
        }
1614
1615
        return $ret;
1616
    }
1617
1618
    /**
1619
     * Returns the content of the summary and the titles requires for the list selector
1620
     * @param $text
1621
     * @param $titles
1622
     * @return string
1623
     */
1624
    public function auto_summary($text, &$titles)
1625
    {
1626
        $auto_summary = '';
1627
        if (news_getmoduleoption('enhanced_pagenav')) {
1628
            $expr_matches = array();
1629
            $posdeb       = preg_match_all('/(\[pagebreak:|\[pagebreak).*\]/iU', $text, $expr_matches);
0 ignored issues
show
Unused Code introduced by
$posdeb 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...
1630
            if (count($expr_matches) > 0) {
1631
                $delimiters  = $expr_matches[0];
1632
                $arr_search  = array('[pagebreak:', '[pagebreak', ']');
1633
                $arr_replace = array('', '', '');
1634
                $cpt         = 1;
1635
                if (isset($titles) && is_array($titles)) {
1636
                    $titles[] = strip_tags(sprintf(_NW_PAGE_AUTO_SUMMARY, 1, $this->title()));
1637
                }
1638
                $item = "<a href='"
1639
                        . XOOPS_URL
1640
                        . '/modules/news/article.php?storyid='
1641
                        . $this->storyid()
1642
                        . "&page=0'>"
1643
                        . sprintf(_NW_PAGE_AUTO_SUMMARY, 1, $this->title())
1644
                        . '</a><br>';
1645
                $auto_summary .= $item;
1646
1647
                foreach ($delimiters as $item) {
1648
                    ++$cpt;
1649
                    $item = str_replace($arr_search, $arr_replace, $item);
1650
                    if (xoops_trim($item) == '') {
1651
                        $item = $cpt;
1652
                    }
1653
                    $titles[] = strip_tags(sprintf(_NW_PAGE_AUTO_SUMMARY, $cpt, $item));
1654
                    $item     = "<a href='"
1655
                                . XOOPS_URL
1656
                                . '/modules/news/article.php?storyid='
1657
                                . $this->storyid()
1658
                                . '&page='
1659
                                . ($cpt - 1)
1660
                                . "'>"
1661
                                . sprintf(_NW_PAGE_AUTO_SUMMARY, $cpt, $item)
1662
                                . '</a><br>';
1663
                    $auto_summary .= $item;
1664
                }
1665
            }
1666
        }
1667
1668
        return $auto_summary;
1669
    }
1670
1671
    /**
1672
     * @param string $format
1673
     *
1674
     * @return mixed
1675
     */
1676 View Code Duplication
    public function hometext($format = 'Show')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1677
    {
1678
        $myts = MyTextSanitizer::getInstance();
1679
        $html = $smiley = $xcodes = 1;
1680
        if ($this->nohtml()) {
1681
            $html = 0;
1682
        }
1683
        if ($this->nosmiley()) {
1684
            $smiley = 0;
1685
        }
1686
        switch ($format) {
1687
            case 'Show':
1688
                $hometext     = $myts->displayTarea($this->hometext, $html, $smiley, $xcodes);
1689
                $tmp          = '';
1690
                $auto_summary = $this->auto_summary($this->bodytext('Show'), $tmp);
1691
                $hometext     = str_replace('[summary]', $auto_summary, $hometext);
1692
                break;
1693
            case 'Edit':
1694
                $hometext = $myts->htmlSpecialChars($this->hometext);
1695
                break;
1696
            case 'Preview':
1697
                $hometext = $myts->previewTarea($this->hometext, $html, $smiley, $xcodes);
1698
                break;
1699
            case 'InForm':
1700
                $hometext = $myts->stripSlashesGPC($this->hometext);
1701
                $hometext = $myts->htmlSpecialChars($hometext);
1702
                break;
1703
        }
1704
1705
        return $hometext;
0 ignored issues
show
Bug introduced by
The variable $hometext does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1706
    }
1707
1708
    /**
1709
     * @param string $format
1710
     *
1711
     * @return mixed
1712
     */
1713 View Code Duplication
    public function bodytext($format = 'Show')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1714
    {
1715
        $myts   = MyTextSanitizer::getInstance();
1716
        $html   = 1;
1717
        $smiley = 1;
1718
        $xcodes = 1;
1719
        if ($this->nohtml()) {
1720
            $html = 0;
1721
        }
1722
        if ($this->nosmiley()) {
1723
            $smiley = 0;
1724
        }
1725
        switch ($format) {
1726
            case 'Show':
1727
                $bodytext     = $myts->displayTarea($this->bodytext, $html, $smiley, $xcodes);
1728
                $tmp          = '';
1729
                $auto_summary = $this->auto_summary($bodytext, $tmp);
1730
                $bodytext     = str_replace('[summary]', $auto_summary, $bodytext);
1731
                break;
1732
            case 'Edit':
1733
                $bodytext = $myts->htmlSpecialChars($this->bodytext);
1734
                break;
1735
            case 'Preview':
1736
                $bodytext = $myts->previewTarea($this->bodytext, $html, $smiley, $xcodes);
1737
                break;
1738
            case 'InForm':
1739
                $bodytext = $myts->stripSlashesGPC($this->bodytext);
1740
                $bodytext = $myts->htmlSpecialChars($bodytext);
1741
                break;
1742
        }
1743
1744
        return $bodytext;
0 ignored issues
show
Bug introduced by
The variable $bodytext does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1745
    }
1746
1747
    /**
1748
     * Returns stories by Ids
1749
     * @param             $ids
1750
     * @param  bool       $checkRight
1751
     * @param  bool       $asobject
1752
     * @param  string     $order
1753
     * @param  bool       $onlyOnline
1754
     * @return array|null
1755
     */
1756
    public function getStoriesByIds(
1757
        $ids,
1758
        $checkRight = true,
1759
        $asobject = true,
1760
        $order = 'published',
1761
        $onlyOnline = true
1762
    ) {
1763
        $limit = $start = 0;
1764
        $db    = XoopsDatabaseFactory::getDatabaseConnection();
1765
        $myts  = MyTextSanitizer::getInstance();
1766
        $ret   = array();
1767
        $sql   = 'SELECT s.*, t.* FROM ' . $db->prefix('news_stories') . ' s, ' . $db->prefix('news_topics') . ' t WHERE ';
1768
        if (is_array($ids) && count($ids) > 0) {
1769
            array_walk($ids, 'intval');
1770
        }
1771
        $sql .= ' s.storyid IN (' . implode(',', $ids) . ') ';
1772
1773
        if ($onlyOnline) {
1774
            $sql .= ' AND (s.published > 0 AND s.published <= ' . time() . ') AND (s.expired = 0 OR s.expired > ' . time() . ') ';
1775
        }
1776
        $sql .= ' AND (s.topicid=t.topic_id) ';
1777
        if ($checkRight) {
1778
            $topics = news_MygetItemIds('news_view');
1779
            if (count($topics) > 0) {
1780
                $topics = implode(',', $topics);
1781
                $sql .= ' AND s.topicid IN (' . $topics . ')';
1782
            } else {
1783
                return null;
1784
            }
1785
        }
1786
        $sql .= " ORDER BY s.$order DESC";
1787
        $result = $db->query($sql, (int)$limit, (int)$start);
1788
1789 View Code Duplication
        while ($myrow = $db->fetchArray($result)) {
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...
1790
            if ($asobject) {
1791
                $ret[$myrow['storyid']] = new NewsStory($myrow);
1792
            } else {
1793
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
1794
            }
1795
        }
1796
1797
        return $ret;
1798
    }
1799
}
1800
1801
/**
1802
 * Class news_NewsStoryHandler
1803
 */
1804
class news_NewsStoryHandler extends XoopsPersistableObjectHandler
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
1805
{
1806
    /**
1807
     * @param null|XoopsDatabase $db
1808
     */
1809
    public function __construct(XoopsDatabase $db)
1810
    {
1811
        parent::__construct($db, 'news_stories', 'stories', 'storieid', 'title');
1812
    }
1813
}
1814