Completed
Branch master (caa4fc)
by Michael
06:53 queued 04:04
created

NewsStory::getBigStory()   B

Complexity

Conditions 9
Paths 20

Size

Total Lines 54
Code Lines 42

Duplication

Lines 30
Ratio 55.56 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 9
eloc 42
c 5
b 0
f 0
nc 20
nop 7
dl 30
loc 54
rs 7.255

How to fix   Long Method   

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 ' . $this->table . ' s, ' . $this->db->prefix('news_topics') . ' t WHERE (storyid=' . (int)$storyid . ') AND (s.topicid=t.topic_id)';
95
        $array = $this->db->fetchArray($this->db->query($sql));
96
        $this->makeStory($array);
97
    }
98
99
    /**
100
     * Delete stories that were published before a given date
101
     * @param         $timestamp
102
     * @param         $expired
103
     * @param  string $topicslist
104
     * @return bool
105
     */
106
    public function DeleteBeforeDate($timestamp, $expired, $topicslist = '')
107
    {
108
        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...
109
        $mid          = $xoopsModule->getVar('mid');
110
        $db           = XoopsDatabaseFactory::getDatabaseConnection();
111
        $prefix       = $db->prefix('news_stories');
112
        $vote_prefix  = $db->prefix('news_stories_votedata');
113
        $files_prefix = $db->prefix('news_stories_files');
114
        $sql          = 'SELECT storyid FROM  ' . $prefix . ' WHERE published <=' . $timestamp;
115
        if ($expired) {
116
            $sql .= ' (AND expired>0 AND expired<=' . time() . ')';
117
        }
118
        if (strlen(trim($topicslist)) > 0) {
119
            $sql .= ' AND topicid IN (' . $topicslist . ')';
120
        }
121
        $result = $db->query($sql);
122
        while ($myrow = $db->fetchArray($result)) {
123
            xoops_comment_delete($mid, $myrow['storyid']); // Delete comments
124
            xoops_notification_deletebyitem($mid, 'story', $myrow['storyid']); // Delete notifications
125
            $db->queryF('DELETE FROM ' . $vote_prefix . ' WHERE storyid=' . $myrow['storyid']); // Delete votes
126
            // Remove files and records related to the files
127
            $result2 = $db->query('SELECT * FROM ' . $files_prefix . ' WHERE storyid=' . $myrow['storyid']);
128
            while ($myrow2 = $db->fetchArray($result2)) {
129
                $name = XOOPS_ROOT_PATH . '/uploads/' . $myrow2['downloadname'];
130
                if (file_exists($name)) {
131
                    unlink($name);
132
                }
133
                $db->query('DELETE FROM ' . $files_prefix . ' WHERE fileid=' . $myrow2['fileid']);
134
            }
135
            $db->queryF('DELETE FROM ' . $prefix . ' WHERE storyid=' . $myrow['storyid']); // Delete the story
136
        }
137
138
        return true;
139
    }
140
141
    /**
142
     * @param      $storyid
143
     * @param bool $next
144
     * @param bool $checkRight
145
     *
146
     * @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...
147
     */
148
    public function _searchPreviousOrNextArticle($storyid, $next = true, $checkRight = false)
149
    {
150
        $db      = XoopsDatabaseFactory::getDatabaseConnection();
151
        $ret     = array();
152
        $storyid = (int)$storyid;
153
        if ($next) {
154
            $sql     = 'SELECT storyid, title FROM '
155
                       . $db->prefix('news_stories')
156
                       . ' WHERE (published > 0 AND published <= '
157
                       . time()
158
                       . ') AND (expired = 0 OR expired > '
159
                       . time()
160
                       . ') AND storyid > '
161
                       . $storyid;
162
            $orderBy = ' ORDER BY storyid ASC';
163
        } else {
164
            $sql     = 'SELECT storyid, title FROM '
165
                       . $db->prefix('news_stories')
166
                       . ' WHERE (published > 0 AND published <= '
167
                       . time()
168
                       . ') AND (expired = 0 OR expired > '
169
                       . time()
170
                       . ') AND storyid < '
171
                       . $storyid;
172
            $orderBy = ' ORDER BY storyid DESC';
173
        }
174
        if ($checkRight) {
175
            $topics = news_MygetItemIds('news_view');
176
            if (count($topics) > 0) {
177
                $sql .= ' AND topicid IN (' . implode(',', $topics) . ')';
178
            } else {
179
                return null;
180
            }
181
        }
182
        $sql .= $orderBy;
183
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
184
        $result = $db->query($sql, 1);
185
        if ($result) {
186
            $myts = MyTextSanitizer::getInstance();
187
            while ($row = $db->fetchArray($result)) {
188
                $ret = array('storyid' => $row['storyid'], 'title' => $myts->htmlSpecialChars($row['title']));
189
            }
190
        }
191
192
        return $ret;
193
    }
194
195
    /**
196
     * @param      $storyid
197
     * @param bool $checkRight
198
     *
199
     * @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...
200
     */
201
    public function getNextArticle($storyid, $checkRight = false)
202
    {
203
        return $this->_searchPreviousOrNextArticle($storyid, true, $checkRight);
204
    }
205
206
    /**
207
     * @param      $storyid
208
     * @param bool $checkRight
209
     *
210
     * @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...
211
     */
212
    public function getPreviousArticle($storyid, $checkRight = false)
213
    {
214
        return $this->_searchPreviousOrNextArticle($storyid, false, $checkRight);
215
    }
216
217
    /**
218
     * Returns published stories according to some options
219
     * @param  int    $limit
220
     * @param  int    $start
221
     * @param  bool   $checkRight
222
     * @param  int    $topic
223
     * @param  int    $ihome
224
     * @param  bool   $asobject
225
     * @param  string $order
226
     * @param  bool   $topic_frontpage
227
     * @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...
228
     */
229
    public static function getAllPublished($limit = 0, $start = 0, $checkRight = false, $topic = 0, $ihome = 0, $asobject = true, $order = 'published', $topic_frontpage = false)
230
    {
231
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
232
        $myts = MyTextSanitizer::getInstance();
233
        $ret  = array();
234
        $sql  = 'SELECT s.*, t.* FROM '
235
                . $db->prefix('news_stories')
236
                . ' s, '
237
                . $db->prefix('news_topics')
238
                . ' t WHERE (s.published > 0 AND s.published <= '
239
                . time()
240
                . ') AND (s.expired = 0 OR s.expired > '
241
                . time()
242
                . ') AND (s.topicid=t.topic_id) ';
243
        if ($topic != 0) {
244
            if (!is_array($topic)) {
245 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...
246
                    $topics = news_MygetItemIds('news_view');
247
                    if (!in_array($topic, $topics)) {
248
                        return null;
249
                    } else {
250
                        $sql .= ' AND s.topicid=' . (int)$topic . ' AND (s.ihome=1 OR s.ihome=0)';
251
                    }
252
                } else {
253
                    $sql .= ' AND s.topicid=' . (int)$topic . ' AND (s.ihome=1 OR s.ihome=0)';
254
                }
255
            } else {
256
                if ($checkRight) {
257
                    $topics = news_MygetItemIds('news_view');
258
                    $topic  = array_intersect($topic, $topics);
259
                }
260
                if (count($topic) > 0) {
261
                    $sql .= ' AND s.topicid IN (' . implode(',', $topic) . ')';
262
                } else {
263
                    return null;
264
                }
265
            }
266 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...
267
            if ($checkRight) {
268
                $topics = news_MygetItemIds('news_view');
269
                if (count($topics) > 0) {
270
                    $topics = implode(',', $topics);
271
                    $sql .= ' AND s.topicid IN (' . $topics . ')';
272
                } else {
273
                    return null;
274
                }
275
            }
276
            if ((int)$ihome == 0) {
277
                $sql .= ' AND s.ihome=0';
278
            }
279
        }
280
        if ($topic_frontpage) {
281
            $sql .= ' AND t.topic_frontpage=1';
282
        }
283
        $sql .= " ORDER BY s.$order DESC";
284
        $result = $db->query($sql, (int)$limit, (int)$start);
285
286 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...
287
            if ($asobject) {
288
                $ret[] = new NewsStory($myrow);
289
            } else {
290
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
291
            }
292
        }
293
294
        return $ret;
295
    }
296
297
    /**
298
     * Retourne la liste des articles aux archives (pour une p�riode donn�e)
299
     * @param             $publish_start
300
     * @param             $publish_end
301
     * @param  bool       $checkRight
302
     * @param  bool       $asobject
303
     * @param  string     $order
304
     * @return array|null
305
     */
306
    public function getArchive($publish_start, $publish_end, $checkRight = false, $asobject = true, $order = 'published')
307
    {
308
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
309
        $myts = MyTextSanitizer::getInstance();
310
        $ret  = array();
311
        $sql  = 'SELECT s.*, t.* FROM '
312
                . $db->prefix('news_stories')
313
                . ' s, '
314
                . $db->prefix('news_topics')
315
                . ' t WHERE (s.topicid=t.topic_id) AND (s.published > '
316
                . $publish_start
317
                . ' AND s.published <= '
318
                . $publish_end
319
                . ') AND (expired = 0 OR expired > '
320
                . time()
321
                . ') ';
322
323
        if ($checkRight) {
324
            $topics = news_MygetItemIds('news_view');
325
            if (count($topics) > 0) {
326
                $topics = implode(',', $topics);
327
                $sql .= ' AND topicid IN (' . $topics . ')';
328
            } else {
329
                return null;
330
            }
331
        }
332
        $sql .= " ORDER BY $order DESC";
333
        $result = $db->query($sql);
334 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...
335
            if ($asobject) {
336
                $ret[] = new NewsStory($myrow);
337
            } else {
338
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
339
            }
340
        }
341
342
        return $ret;
343
    }
344
345
    /**
346
     * Get the today's most readed article
347
     *
348
     * @param int     $limit      records limit
349
     * @param int     $start      starting record
350
     * @param boolean $checkRight Do we need to check permissions (by topics) ?
351
     * @param int     $topic      limit the job to one topic
352
     * @param int     $ihome      Limit to articles published in home page only ?
353
     * @param boolean $asobject   Do we have to return an array of objects or a simple array ?
354
     * @param string  $order      Fields to sort on
355
     *
356
     * @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...
357
     */
358
    public function getBigStory($limit = 0, $start = 0, $checkRight = false, $topic = 0, $ihome = 0, $asobject = true, $order = 'counter')
359
    {
360
        $db    = XoopsDatabaseFactory::getDatabaseConnection();
361
        $myts  = MyTextSanitizer::getInstance();
362
        $ret   = array();
363
        $tdate = mktime(0, 0, 0, date('n'), date('j'), date('Y'));
364
        $sql   = 'SELECT s.*, t.* FROM '
365
                 . $db->prefix('news_stories')
366
                 . ' s, '
367
                 . $db->prefix('news_topics')
368
                 . ' t WHERE (s.topicid=t.topic_id) AND (published > '
369
                 . $tdate
370
                 . ' AND published < '
371
                 . time()
372
                 . ') AND (expired > '
373
                 . time()
374
                 . ' OR expired = 0) ';
375
376
        if ((int)$topic != 0) {
377 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...
378
                $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
379
            } else {
380
                if (count($topic) > 0) {
381
                    $sql .= ' AND topicid IN (' . implode(',', $topic) . ')';
382
                } else {
383
                    return null;
384
                }
385
            }
386 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...
387
            if ($checkRight) {
388
                $topics = news_MygetItemIds('news_view');
389
                if (count($topics) > 0) {
390
                    $topics = implode(',', $topics);
391
                    $sql .= ' AND topicid IN (' . $topics . ')';
392
                } else {
393
                    return null;
394
                }
395
            }
396
            if ((int)$ihome == 0) {
397
                $sql .= ' AND ihome=0';
398
            }
399
        }
400
        $sql .= " ORDER BY $order DESC";
401
        $result = $db->query($sql, (int)$limit, (int)$start);
402 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...
403
            if ($asobject) {
404
                $ret[] = new NewsStory($myrow);
405
            } else {
406
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
407
            }
408
        }
409
410
        return $ret;
411
    }
412
413
    /**
414
     * Get all articles published by an author
415
     *
416
     * @param int     $uid        author's id
417
     * @param boolean $checkRight whether to check the user's rights to topics
418
     *
419
     * @param bool    $asobject
420
     *
421
     * @return array
422
     */
423
    public function getAllPublishedByAuthor($uid, $checkRight = false, $asobject = true)
424
    {
425
        $db        = XoopsDatabaseFactory::getDatabaseConnection();
426
        $myts      = MyTextSanitizer::getInstance();
427
        $ret       = array();
428
        $tblstory  = $db->prefix('news_stories');
429
        $tbltopics = $db->prefix('news_topics');
430
431
        $sql = 'SELECT '
432
               . $tblstory
433
               . '.*, '
434
               . $tbltopics
435
               . '.topic_title, '
436
               . $tbltopics
437
               . '.topic_color FROM '
438
               . $tblstory
439
               . ','
440
               . $tbltopics
441
               . ' WHERE ('
442
               . $tblstory
443
               . '.topicid='
444
               . $tbltopics
445
               . '.topic_id) AND (published > 0 AND published <= '
446
               . time()
447
               . ') AND (expired = 0 OR expired > '
448
               . time()
449
               . ')';
450
        $sql .= ' AND uid=' . (int)$uid;
451
        if ($checkRight) {
452
            $topics = news_MygetItemIds('news_view');
453
            $topics = implode(',', $topics);
454
            if (xoops_trim($topics) !== '') {
455
                $sql .= ' AND topicid IN (' . $topics . ')';
456
            }
457
        }
458
        $sql .= ' ORDER BY ' . $tbltopics . '.topic_title ASC, ' . $tblstory . '.published DESC';
459
        $result = $db->query($sql);
460
        while ($myrow = $db->fetchArray($result)) {
461
            if ($asobject) {
462
                $ret[] = new NewsStory($myrow);
463
            } else {
464
                if ($myrow['nohtml']) {
465
                    $html = 0;
466
                } else {
467
                    $html = 1;
468
                }
469
                if ($myrow['nosmiley']) {
470
                    $smiley = 0;
471
                } else {
472
                    $smiley = 1;
473
                }
474
                $ret[$myrow['storyid']] = array(
475
                    'title'       => $myts->displayTarea($myrow['title'], $html, $smiley, 1),
476
                    'topicid'     => (int)$myrow['topicid'],
477
                    'storyid'     => (int)$myrow['storyid'],
478
                    'hometext'    => $myts->displayTarea($myrow['hometext'], $html, $smiley, 1),
479
                    'counter'     => (int)$myrow['counter'],
480
                    'created'     => (int)$myrow['created'],
481
                    'topic_title' => $myts->displayTarea($myrow['topic_title'], $html, $smiley, 1),
482
                    'topic_color' => $myts->displayTarea($myrow['topic_color']),
483
                    'published'   => (int)$myrow['published'],
484
                    'rating'      => (float)$myrow['rating'],
485
                    'votes'       => (int)$myrow['votes']
486
                );
487
            }
488
        }
489
490
        return $ret;
491
    }
492
493
    /**
494
     * Get all expired stories
495
     * @param  int  $limit
496
     * @param  int  $start
497
     * @param  int  $topic
498
     * @param  int  $ihome
499
     * @param  bool $asobject
500
     * @return array
501
     */
502
    public static function getAllExpired($limit = 0, $start = 0, $topic = 0, $ihome = 0, $asobject = true)
503
    {
504
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
505
        $myts = MyTextSanitizer::getInstance();
506
        $ret  = array();
507
        $sql  = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE expired <= ' . time() . ' AND expired > 0';
508
        if (!empty($topic)) {
509
            $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
510
        } else {
511
            if ((int)$ihome == 0) {
512
                $sql .= ' AND ihome=0';
513
            }
514
        }
515
516
        $sql .= ' ORDER BY expired DESC';
517
        $result = $db->query($sql, (int)$limit, (int)$start);
518 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...
519
            if ($asobject) {
520
                $ret[] = new NewsStory($myrow);
521
            } else {
522
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
523
            }
524
        }
525
526
        return $ret;
527
    }
528
529
    /**
530
     * Returns an array of object containing all the news to be automatically published.
531
     * @param  int  $limit
532
     * @param  bool $asobject
533
     * @param  int  $start
534
     * @return array
535
     */
536
    public static function getAllAutoStory($limit = 0, $asobject = true, $start = 0)
537
    {
538
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
539
        $myts   = MyTextSanitizer::getInstance();
540
        $ret    = array();
541
        $sql    = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE published > ' . time() . ' ORDER BY published ASC';
542
        $result = $db->query($sql, (int)$limit, (int)$start);
543 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...
544
            if ($asobject) {
545
                $ret[] = new NewsStory($myrow);
546
            } else {
547
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
548
            }
549
        }
550
551
        return $ret;
552
    }
553
554
    /**
555
     * Get all submitted stories awaiting approval
556
     *
557
     * @param int     $limit      Denotes where to start the query
558
     * @param boolean $asobject   true will returns the stories as an array of objects, false will return storyid => title
559
     * @param boolean $checkRight whether to check the user's rights to topics
560
     *
561
     * @param int     $start
562
     *
563
     * @return array
564
     */
565
    public static function getAllSubmitted($limit = 0, $asobject = true, $checkRight = false, $start = 0)
566
    {
567
        $db       = XoopsDatabaseFactory::getDatabaseConnection();
568
        $myts     = MyTextSanitizer::getInstance();
569
        $ret      = array();
570
        $criteria = new CriteriaCompo(new Criteria('published', 0));
571
        if ($checkRight) {
572
            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...
573
            if (!is_object($xoopsUser)) {
574
                return $ret;
575
            }
576
            $allowedtopics = news_MygetItemIds('news_approve');
577
            $criteria2     = new CriteriaCompo();
578
            foreach ($allowedtopics as $key => $topicid) {
579
                $criteria2->add(new Criteria('topicid', $topicid), 'OR');
580
            }
581
            $criteria->add($criteria2);
582
        }
583
        $sql = 'SELECT s.*, t.* FROM ' . $db->prefix('news_stories') . ' s, ' . $db->prefix('news_topics') . ' t ';
584
        $sql .= ' ' . $criteria->renderWhere() . ' AND (s.topicid=t.topic_id) ORDER BY created DESC';
585
        $result = $db->query($sql, (int)$limit, (int)$start);
586 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...
587
            if ($asobject) {
588
                $ret[] = new NewsStory($myrow);
589
            } else {
590
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
591
            }
592
        }
593
594
        return $ret;
595
    }
596
597
    /**
598
     * Used in the module's admin to know the number of expired, automated or pubilshed news
599
     *
600
     * @param int  $storytype  1=Expired, 2=Automated, 3=New submissions, 4=Last published stories
601
     * @param bool $checkRight verify permissions or not ?
602
     *
603
     * @return int
604
     */
605
    public static function getAllStoriesCount($storytype = 1, $checkRight = false)
606
    {
607
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
608
        $sql = 'SELECT count(*) as cpt FROM ' . $db->prefix('news_stories') . ' WHERE ';
609
        switch ($storytype) {
610
            case 1: // Expired
611
                $sql .= '(expired <= ' . time() . ' AND expired >0)';
612
                break;
613
            case 2: // Automated
614
                $sql .= '(published > ' . time() . ')';
615
                break;
616
            case 3: // New submissions
617
                $sql .= '(published = 0)';
618
                break;
619
            case 4: // Last published stories
620
                $sql .= '(published > 0 AND published <= ' . time() . ') AND (expired = 0 OR expired > ' . time() . ')';
621
                break;
622
        }
623
        if ($checkRight) {
624
            $topics = news_MygetItemIds('news_view');
625
            if (count($topics) > 0) {
626
                $topics = implode(',', $topics);
627
                $sql .= ' AND topicid IN (' . $topics . ')';
628
            } else {
629
                return 0;
630
            }
631
        }
632
        $result = $db->query($sql);
633
        $myrow  = $db->fetchArray($result);
634
635
        return $myrow['cpt'];
636
    }
637
638
    /**
639
     * Get a list of stories (as objects) related to a specific topic
640
     * @param        $topicid
641
     * @param  int   $limit
642
     * @return array
643
     */
644
    public static function getByTopic($topicid, $limit = 0)
645
    {
646
        $ret    = array();
647
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
648
        $sql    = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE topicid=' . (int)$topicid . ' ORDER BY published DESC';
649
        $result = $db->query($sql, (int)$limit, 0);
650
        while ($myrow = $db->fetchArray($result)) {
651
            $ret[] = new NewsStory($myrow);
652
        }
653
654
        return $ret;
655
    }
656
657
    /**
658
     * Count the number of news published for a specific topic
659
     * @param  int  $topicid
660
     * @param  bool $checkRight
661
     * @return null
662
     */
663
    public static function countPublishedByTopic($topicid = 0, $checkRight = false)
664
    {
665
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
666
        $sql = 'SELECT COUNT(*) FROM ' . $db->prefix('news_stories') . ' WHERE published > 0 AND published <= ' . time() . ' AND (expired = 0 OR expired > ' . time() . ')';
667 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...
668
            $sql .= ' AND topicid=' . (int)$topicid;
669
        } else {
670
            $sql .= ' AND ihome=0';
671
            if ($checkRight) {
672
                $topics = news_MygetItemIds('news_view');
673
                if (count($topics) > 0) {
674
                    $topics = implode(',', $topics);
675
                    $sql .= ' AND topicid IN (' . $topics . ')';
676
                } else {
677
                    return null;
678
                }
679
            }
680
        }
681
        $result = $db->query($sql);
682
        list($count) = $db->fetchRow($result);
683
684
        return $count;
685
    }
686
687
    /**
688
     * Internal function
689
     */
690
    public function adminlink()
691
    {
692
        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...
693
        $dirname       = basename(dirname(__DIR__));
694
        $moduleHandler = xoops_getHandler('module');
695
        $module        = $moduleHandler->getByDirname($dirname);
696
        $pathIcon16    = $module->getInfo('icons16');
697
698
        $ret = '&nbsp; <a href='
699
               . XOOPS_URL
700
               . '/modules/news/submit.php?op=edit&amp;storyid='
701
               . $this->storyid()
702
               . '><img src='
703
               . $pathIcon16
704
               . '/edit.png'
705
               . ' '
706
               . 'title='
707
               . _NW_EDIT
708
               . '></a>'
709
               . '<a href='
710
               . XOOPS_URL
711
               . '/modules/news/admin/index.php?op=delete&amp;storyid='
712
               . $this->storyid()
713
               . '><img src='
714
               . $pathIcon16
715
               . '/delete.png'
716
               . ' '
717
               . 'title='
718
               . _NW_DELETE
719
               . '></a> &nbsp;';
720
721
        return $ret;
722
    }
723
724
    /**
725
     * Get the topic image url
726
     * @param string $format
727
     * @return
728
     */
729 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...
730
    {
731
        if (trim($this->topic_imgurl) === '') {
732
            $this->topic_imgurl = 'blank.png';
733
        }
734
        $myts = MyTextSanitizer::getInstance();
735
        switch ($format) {
736
            case 'S':
737
                $imgurl = $myts->htmlSpecialChars($this->topic_imgurl);
738
                break;
739
            case 'E':
740
                $imgurl = $myts->htmlSpecialChars($this->topic_imgurl);
741
                break;
742
            case 'P':
743
                $imgurl = $myts->stripSlashesGPC($this->topic_imgurl);
744
                $imgurl = $myts->htmlSpecialChars($imgurl);
745
                break;
746
            case 'F':
747
                $imgurl = $myts->stripSlashesGPC($this->topic_imgurl);
748
                $imgurl = $myts->htmlSpecialChars($imgurl);
749
                break;
750
        }
751
752
        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...
753
    }
754
755
    /**
756
     * @param string $format
757
     *
758
     * @return mixed
759
     */
760
    public function topic_title($format = 'S')
761
    {
762
        $myts = MyTextSanitizer::getInstance();
763
        switch ($format) {
764
            case 'S':
765
                $title = $myts->htmlSpecialChars($this->topic_title);
766
                break;
767
            case 'E':
768
                $title = $myts->htmlSpecialChars($this->topic_title);
769
                break;
770
            case 'P':
771
                $title = $myts->stripSlashesGPC($this->topic_title);
772
                $title = $myts->htmlSpecialChars($title);
773
                break;
774
            case 'F':
775
                $title = $myts->stripSlashesGPC($this->topic_title);
776
                $title = $myts->htmlSpecialChars($title);
777
                break;
778
        }
779
780
        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...
781
    }
782
783
    /**
784
     * @return string
785
     */
786
    public function imglink()
787
    {
788
        $ret = '';
789
        if ($this->topic_imgurl() !== '' && file_exists(XOOPS_ROOT_PATH . '/uploads/news/image/' . $this->topic_imgurl())) {
790
            $ret = "<a href='"
791
                   . XOOPS_URL
792
                   . '/modules/news/index.php?storytopic='
793
                   . $this->topicid()
794
                   . "'><img src='"
795
                   . XOOPS_URL
796
                   . '/uploads/news/image/'
797
                   . $this->topic_imgurl()
798
                   . "' alt='"
799
                   . $this->topic_title()
800
                   . "' hspace='10' vspace='10' align='"
801
                   . $this->topicalign()
802
                   . "' /></a>";
803
        }
804
805
        return $ret;
806
    }
807
808
    /**
809
     * @return string
810
     */
811
    public function textlink()
812
    {
813
        $ret = '<a titls=' . $this->topic_title() . " href='" . XOOPS_URL . '/modules/news/index.php?storytopic=' . $this->topicid() . "'>" . $this->topic_title() . '</a>';
814
815
        return $ret;
816
    }
817
818
    /**
819
     * Function used to prepare an article to be showned
820
     * @param $filescount
821
     * @return array
822
     */
823
    public function prepare2show($filescount)
824
    {
825
        include_once XOOPS_ROOT_PATH . '/modules/news/include/functions.php';
826
        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...
827
828
        $dirname       = basename(dirname(__DIR__));
829
        $moduleHandler = xoops_getHandler('module');
830
        $module        = $moduleHandler->getByDirname($dirname);
831
        $pathIcon16    = $module->getInfo('icons16');
832
833
        $myts                 = MyTextSanitizer::getInstance();
834
        $infotips             = news_getmoduleoption('infotips');
835
        $story                = array();
836
        $story['id']          = $this->storyid();
837
        $story['poster']      = $this->uname();
838
        $story['author_name'] = $this->uname();
839
        $story['author_uid']  = $this->uid();
840
        if ($story['poster'] !== false) {
841
            $story['poster'] = "<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $this->uid() . "'>" . $story['poster'] . '</a>';
842
        } else {
843
            if ($xoopsModuleConfig['displayname'] != 3) {
844
                $story['poster'] = $xoopsConfig['anonymous'];
845
            }
846
        }
847
        if ($xoopsModuleConfig['ratenews']) {
848
            $story['rating'] = number_format($this->rating(), 2);
849
            if ($this->votes == 1) {
850
                $story['votes'] = _NW_ONEVOTE;
851
            } else {
852
                $story['votes'] = sprintf(_NW_NUMVOTES, $this->votes);
853
            }
854
        }
855
        $story['posttimestamp']     = $this->published();
856
        $story['posttime']          = formatTimestamp($story['posttimestamp'], news_getmoduleoption('dateformat'));
857
        $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...
858
859
        $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...
860
        $tmp          = '';
861
        $auto_summary = $this->auto_summary($this->bodytext(), $tmp);
862
863
        $story['text'] = $this->hometext();
864
        $story['text'] = str_replace('[summary]', $auto_summary, $story['text']);
865
866
        //$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...
867
        if ($this->picture() !== '') {
868
            $story['picture'] = XOOPS_URL . '/uploads/news/image/' . $this->picture();
869
        } else {
870
            $story['picture'] = '';
871
        }
872
        $story['pictureinfo'] = $this->pictureinfo();
873
874
        $introcount = strlen($story['text']);
875
        $fullcount  = strlen($this->bodytext());
876
        $totalcount = $introcount + $fullcount;
877
878
        $morelink = '';
879
        if ($fullcount > 1) {
880
            $morelink .= '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
881
            $morelink .= '">' . _NW_READMORE . '</a>';
882
            $morelink .= ' | ' . sprintf(_NW_BYTESMORE, $totalcount);
883
            if (XOOPS_COMMENT_APPROVENONE != $xoopsModuleConfig['com_rule']) {
884
                $morelink .= ' | ';
885
            }
886
        }
887
        if (XOOPS_COMMENT_APPROVENONE != $xoopsModuleConfig['com_rule']) {
888
            $ccount = $this->comments();
889
            $morelink .= '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
890
            $morelink2 = '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
891
            if ($ccount == 0) {
892
                $morelink .= '">' . _NW_COMMENTS . '</a>';
893
            } else {
894
                if ($fullcount < 1) {
895
                    if ($ccount == 1) {
896
                        $morelink .= '">' . _NW_READMORE . '</a> | ' . $morelink2 . '">' . _NW_ONECOMMENT . '</a>';
897 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...
898
                        $morelink .= '">' . _NW_READMORE . '</a> | ' . $morelink2 . '">';
899
                        $morelink .= sprintf(_NW_NUMCOMMENTS, $ccount);
900
                        $morelink .= '</a>';
901
                    }
902
                } else {
903 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...
904
                        $morelink .= '">' . _NW_ONECOMMENT . '</a>';
905
                    } else {
906
                        $morelink .= '">';
907
                        $morelink .= sprintf(_NW_NUMCOMMENTS, $ccount);
908
                        $morelink .= '</a>';
909
                    }
910
                }
911
            }
912
        }
913
        $story['morelink']  = $morelink;
914
        $story['adminlink'] = '';
915
916
        $approveprivilege = 0;
917
        if (news_is_admin_group()) {
918
            $approveprivilege = 1;
919
        }
920
921
        if ($xoopsModuleConfig['authoredit'] == 1 && (is_object($xoopsUser) && $xoopsUser->getVar('uid') == $this->uid())) {
922
            $approveprivilege = 1;
923
        }
924
        if ($approveprivilege) {
925
            $story['adminlink'] = $this->adminlink();
926
        }
927
        $story['mail_link'] = 'mailto:?subject='
928
                              . sprintf(_NW_INTARTICLE, $xoopsConfig['sitename'])
929
                              . '&amp;body='
930
                              . sprintf(_NW_INTARTFOUND, $xoopsConfig['sitename'])
931
                              . ':  '
932
                              . XOOPS_URL
933
                              . '/modules/news/article.php?storyid='
934
                              . $this->storyid();
935
        $story['imglink']   = '';
936
        $story['align']     = '';
937
        if ($this->topicdisplay()) {
938
            $story['imglink'] = $this->imglink();
939
            $story['align']   = $this->topicalign();
940
        }
941
        if ($infotips > 0) {
942
            $story['infotips'] = ' title="' . news_make_infotips($this->hometext()) . '"';
943
        } else {
944
            $story['infotips'] = 'title="' . $this->title() . '"';
945
        }
946
        $story['title'] = "<a href='" . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . "'" . $story['infotips'] . '>' . $this->title() . '</a>';
947
        //$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...
948
949
        $story['hits'] = $this->counter();
950
        if ($filescount > 0) {
951
            $story['files_attached'] = true;
952
            $story['attached_link']  = "<a href='"
953
                                       . XOOPS_URL
954
                                       . '/modules/news/article.php?storyid='
955
                                       . $this->storyid()
956
                                       . "' title='"
957
                                       . _NW_ATTACHEDLIB
958
                                       . "'><img src="
959
                                       . $pathIcon16
960
                                       . '/attach.png'
961
                                       . ' '
962
                                       . 'title='
963
                                       . _NW_ATTACHEDLIB
964
                                       . '></a>';
965
        } else {
966
            $story['files_attached'] = false;
967
            $story['attached_link']  = '';
968
        }
969
970
        return $story;
971
    }
972
973
    /**
974
     * Returns the user's name of the current story according to the module's option "displayname"
975
     * @param  int $uid
976
     * @return null|string
977
     */
978
    public function uname($uid = 0)
979
    {
980
        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...
981
        include_once XOOPS_ROOT_PATH . '/modules/news/include/functions.php';
982
        static $tblusers = array();
983
        $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...
984
        if ($uid == 0) {
985
            $uid = $this->uid();
986
        }
987
988
        if (is_array($tblusers) && array_key_exists($uid, $tblusers)) {
989
            return $tblusers[$uid];
990
        }
991
992
        $option = news_getmoduleoption('displayname');
993
        if (!$option) {
994
            $option = 1;
995
        }
996
997
        switch ($option) {
998
            case 1: // Username
999
                $tblusers[$uid] = XoopsUser::getUnameFromId($uid);
1000
1001
                return $tblusers[$uid];
1002
1003
            case 2: // Display full name (if it is not empty)
1004
                $member_handler = xoops_getHandler('member');
1005
                $thisuser       = $member_handler->getUser($uid);
1006
                if (is_object($thisuser)) {
1007
                    $return = $thisuser->getVar('name');
1008
                    if ($return === '') {
1009
                        $return = $thisuser->getVar('uname');
1010
                    }
1011
                } else {
1012
                    $return = $xoopsConfig['anonymous'];
1013
                }
1014
                $tblusers[$uid] = $return;
1015
1016
                return $return;
1017
1018
            case 3: // Nothing
1019
                $tblusers[$uid] = '';
1020
1021
                return '';
1022
        }
1023
1024
        return null;
1025
    }
1026
1027
    /**
1028
     * Function used to export news (in xml) and eventually the topics definitions
1029
     * Warning, permissions are not exported !
1030
     *
1031
     * @param int      $fromdate     Starting date
1032
     * @param int      $todate       Ending date
1033
     * @param string   $topicslist
1034
     * @param bool|int $usetopicsdef Should we also export topics definitions ?
1035
     * @param          $tbltopics
1036
     * @param boolean  $asobject     Return values as an object or not ?
1037
     *
1038
     * @param string   $order
1039
     *
1040
     * @internal param string $topiclist If not empty, a list of topics to limit to
1041
     * @return array
1042
     */
1043
    public function NewsExport($fromdate, $todate, $topicslist = '', $usetopicsdef = 0, &$tbltopics, $asobject = true, $order = 'published')
1044
    {
1045
        $ret  = array();
1046
        $myts = MyTextSanitizer::getInstance();
1047
        if ($usetopicsdef) { // We firt begin by exporting topics definitions
1048
            // Before all we must know wich topics to export
1049
            $sql = 'SELECT distinct topicid FROM ' . $this->db->prefix('news_stories') . ' WHERE (published >=' . $fromdate . ' AND published <= ' . $todate . ')';
1050
            if (strlen(trim($topicslist)) > 0) {
1051
                $sql .= ' AND topicid IN (' . $topicslist . ')';
1052
            }
1053
            $result = $this->db->query($sql);
1054
            while ($myrow = $this->db->fetchArray($result)) {
1055
                $tbltopics[] = $myrow['topicid'];
1056
            }
1057
        }
1058
1059
        // Now we can search for the stories
1060
        $sql = 'SELECT s.*, t.* FROM '
1061
               . $this->table
1062
               . ' s, '
1063
               . $this->db->prefix('news_topics')
1064
               . ' t WHERE (s.topicid=t.topic_id) AND (s.published >='
1065
               . $fromdate
1066
               . ' AND s.published <= '
1067
               . $todate
1068
               . ')';
1069
        if (strlen(trim($topicslist)) > 0) {
1070
            $sql .= ' AND topicid IN (' . $topicslist . ')';
1071
        }
1072
        $sql .= " ORDER BY $order DESC";
1073
        $result = $this->db->query($sql);
1074 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...
1075
            if ($asobject) {
1076
                $ret[] = new NewsStory($myrow);
1077
            } else {
1078
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
1079
            }
1080
        }
1081
1082
        return $ret;
1083
    }
1084
1085
    /**
1086
     * Create or update an article
1087
     * @param  bool $approved
1088
     * @return bool|int
1089
     */
1090
    public function store($approved = false)
1091
    {
1092
        $myts        = MyTextSanitizer::getInstance();
1093
        $counter     = isset($this->counter) ? $this->counter : 0;
1094
        $title       = $myts->addSlashes($myts->censorString($this->title));
1095
        $subtitle    = $myts->addSlashes($myts->censorString($this->subtitle));
1096
        $hostname    = $myts->addSlashes($this->hostname);
1097
        $type        = $myts->addSlashes($this->type);
1098
        $hometext    = $myts->addSlashes($myts->censorString($this->hometext));
1099
        $bodytext    = $myts->addSlashes($myts->censorString($this->bodytext));
1100
        $description = $myts->addSlashes($myts->censorString($this->description));
1101
        $keywords    = $myts->addSlashes($myts->censorString($this->keywords));
1102
        $picture     = $myts->addSlashes($this->picture);
1103
        $pictureinfo = $myts->addSlashes($myts->censorString($this->pictureinfo));
1104
        $votes       = (int)$this->votes;
1105
        $rating      = (float)$this->rating;
1106
        if (!isset($this->nohtml) || $this->nohtml != 1) {
1107
            $this->nohtml = 0;
1108
        }
1109
        if (!isset($this->nosmiley) || $this->nosmiley != 1) {
1110
            $this->nosmiley = 0;
1111
        }
1112
        if (!isset($this->notifypub) || $this->notifypub != 1) {
1113
            $this->notifypub = 0;
1114
        }
1115
        if (!isset($this->topicdisplay) || $this->topicdisplay != 0) {
1116
            $this->topicdisplay = 1;
1117
        }
1118
        $expired = !empty($this->expired) ? $this->expired : 0;
1119
        if (!isset($this->storyid)) {
1120
            //$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...
1121
            $newstoryid = $this->db->genId($this->table . '_storyid_seq');
1122
            $created    = time();
1123
            $published  = $this->approved ? (int)$this->published : 0;
1124
            $sql        =
1125
                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')",
1126
                        $this->table, $newstoryid, (int)$this->uid(), $title, $created, $published, $expired, $hostname, (int)$this->nohtml(), (int)$this->nosmiley(), $hometext, $bodytext, $counter,
1127
                        (int)$this->topicid(), (int)$this->ihome(), (int)$this->notifypub(), $type, (int)$this->topicdisplay(), $this->topicalign, (int)$this->comments(), $rating, $votes,
1128
                        $description, $keywords, $picture, $pictureinfo, $subtitle);
1129
        } else {
1130
            $sql        =
1131
                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",
1132
                        $this->table, $title, (int)$this->published(), $expired, (int)$this->nohtml(), (int)$this->nosmiley(), $hometext, $bodytext, (int)$this->topicid(), (int)$this->ihome(),
1133
                        (int)$this->topicdisplay(), $this->topicalign, (int)$this->comments(), $rating, $votes, (int)$this->uid(), $description, $keywords, $picture, $pictureinfo, $subtitle,
1134
                        (int)$this->storyid());
1135
            $newstoryid = (int)$this->storyid();
1136
        }
1137
        if (!$this->db->queryF($sql)) {
1138
            return false;
1139
        }
1140
        if (empty($newstoryid)) {
1141
            $newstoryid    = $this->db->getInsertId();
1142
            $this->storyid = $newstoryid;
1143
        }
1144
1145
        return $newstoryid;
1146
    }
1147
1148
    /**
1149
     * @return mixed
1150
     */
1151
    public function picture()
1152
    {
1153
        return $this->picture;
1154
    }
1155
1156
    /**
1157
     * @return mixed
1158
     */
1159
    public function pictureinfo()
1160
    {
1161
        return $this->pictureinfo;
1162
    }
1163
1164
    /**
1165
     * @return mixed
1166
     */
1167
    public function subtitle()
1168
    {
1169
        return $this->subtitle;
1170
    }
1171
1172
    /**
1173
     * @return mixed
1174
     */
1175
    public function rating()
1176
    {
1177
        return $this->rating;
1178
    }
1179
1180
    /**
1181
     * @return mixed
1182
     */
1183
    public function votes()
1184
    {
1185
        return $this->votes;
1186
    }
1187
1188
    /**
1189
     * @param $data
1190
     */
1191
    public function setPicture($data)
1192
    {
1193
        $this->picture = $data;
1194
    }
1195
1196
    /**
1197
     * @param $data
1198
     */
1199
    public function setPictureinfo($data)
1200
    {
1201
        $this->pictureinfo = $data;
1202
    }
1203
1204
    /**
1205
     * @param $data
1206
     */
1207
    public function setSubtitle($data)
1208
    {
1209
        $this->subtitle = $data;
1210
    }
1211
1212
    /**
1213
     * @param $data
1214
     */
1215
    public function setDescription($data)
1216
    {
1217
        $this->description = $data;
1218
    }
1219
1220
    /**
1221
     * @param $data
1222
     */
1223
    public function setKeywords($data)
1224
    {
1225
        $this->keywords = $data;
1226
    }
1227
1228
    /**
1229
     * @param string $format
1230
     *
1231
     * @return mixed
1232
     */
1233
    public function description($format = 'S')
1234
    {
1235
        $myts = MyTextSanitizer::getInstance();
1236
        switch (strtoupper($format)) {
1237
            case 'S':
1238
                $description = $myts->htmlSpecialChars($this->description);
1239
                break;
1240
            case 'P':
1241
            case 'F':
1242
                $description = $myts->htmlSpecialChars($myts->stripSlashesGPC($this->description));
1243
                break;
1244
            case 'E':
1245
                $description = $myts->htmlSpecialChars($this->description);
1246
                break;
1247
        }
1248
1249
        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...
1250
    }
1251
1252
    /**
1253
     * @param string $format
1254
     *
1255
     * @return mixed
1256
     */
1257
    public function keywords($format = 'S')
1258
    {
1259
        $myts = MyTextSanitizer::getInstance();
1260
        switch (strtoupper($format)) {
1261
            case 'S':
1262
                $keywords = $myts->htmlSpecialChars($this->keywords);
1263
                break;
1264
            case 'P':
1265
            case 'F':
1266
                $keywords = $myts->htmlSpecialChars($myts->stripSlashesGPC($this->keywords));
1267
                break;
1268
            case 'E':
1269
                $keywords = $myts->htmlSpecialChars($this->keywords);
1270
                break;
1271
        }
1272
1273
        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...
1274
    }
1275
1276
    /**
1277
     * Returns a random number of news
1278
     * @param  int    $limit
1279
     * @param  int    $start
1280
     * @param  bool   $checkRight
1281
     * @param  int    $topic
1282
     * @param  int    $ihome
1283
     * @param  string $order
1284
     * @param  bool   $topic_frontpage
1285
     * @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...
1286
     */
1287
    public function getRandomNews($limit = 0, $start = 0, $checkRight = false, $topic = 0, $ihome = 0, $order = 'published', $topic_frontpage = false)
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...
1288
    {
1289
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
1290
        $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...
1291
        $sql = 'SELECT storyid FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . time() . ') AND (expired = 0 OR expired > ' . time() . ')';
1292
        if ($topic != 0) {
1293
            if (!is_array($topic)) {
1294 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...
1295
                    $topics = news_MygetItemIds('news_view');
1296
                    if (!in_array($topic, $topics)) {
1297
                        return null;
1298
                    } else {
1299
                        $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
1300
                    }
1301
                } else {
1302
                    $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
1303
                }
1304
            } else {
1305
                if (count($topic) > 0) {
1306
                    $sql .= ' AND topicid IN (' . implode(',', $topic) . ')';
1307
                } else {
1308
                    return null;
1309
                }
1310
            }
1311 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...
1312
            if ($checkRight) {
1313
                $topics = news_MygetItemIds('news_view');
1314
                if (count($topics) > 0) {
1315
                    $topics = implode(',', $topics);
1316
                    $sql .= ' AND topicid IN (' . $topics . ')';
1317
                } else {
1318
                    return null;
1319
                }
1320
            }
1321
            if ((int)$ihome == 0) {
1322
                $sql .= ' AND ihome=0';
1323
            }
1324
        }
1325
        if ($topic_frontpage) {
1326
            $sql .= ' AND t.topic_frontpage=1';
1327
        }
1328
        $sql .= " ORDER BY $order DESC";
1329
        $result = $db->query($sql);
1330
1331
        while ($myrow = $db->fetchArray($result)) {
1332
            $ret[] = $myrow['storyid'];
1333
        }
1334
        $cnt = count($ret);
1335
        if ($cnt) {
1336
            mt_srand((double)microtime() * 10000000);
1337
            if ($limit > $cnt) {
1338
                $limit = $cnt;
1339
            }
1340
            $rand_keys = array_rand($ret, $limit);
1341
            if ($limit > 1) {
1342
                for ($i = 0; $i < $limit; ++$i) {
1343
                    $onestory = $ret[$rand_keys[$i]];
1344
                    $ret3[]   = new NewsStory($onestory);
1345
                }
1346
            } else {
1347
                $ret3[] = new NewsStory($ret[$rand_keys]);
1348
            }
1349
        }
1350
1351
        return $ret3;
1352
    }
1353
1354
    /**
1355
     * Returns statistics about the stories and topics
1356
     * @param $limit
1357
     * @return array
1358
     */
1359
    public function GetStats($limit)
1360
    {
1361
        $ret  = array();
1362
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
1363
        $tbls = $db->prefix('news_stories');
1364
        $tblt = $db->prefix('news_topics');
1365
        $tblf = $db->prefix('news_stories_files');
1366
1367
        $db = XoopsDatabaseFactory::getDatabaseConnection();
1368
        // Number of stories per topic, including expired and non published stories
1369
        $ret2   = array();
1370
        $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";
1371
        $result = $db->query($sql);
1372
        while ($myrow = $db->fetchArray($result)) {
1373
            $ret2[$myrow['topicid']] = $myrow;
1374
        }
1375
        $ret['storiespertopic'] = $ret2;
1376
        unset($ret2);
1377
1378
        // Total of reads per topic
1379
        $ret2   = array();
1380
        $sql    = "SELECT Sum(counter) as cpt, topicid FROM $tbls GROUP BY topicid ORDER BY topicid";
1381
        $result = $db->query($sql);
1382
        while ($myrow = $db->fetchArray($result)) {
1383
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1384
        }
1385
        $ret['readspertopic'] = $ret2;
1386
        unset($ret2);
1387
1388
        // Attached files per topic
1389
        $ret2   = array();
1390
        $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";
1391
        $result = $db->query($sql);
1392
        while ($myrow = $db->fetchArray($result)) {
1393
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1394
        }
1395
        $ret['filespertopic'] = $ret2;
1396
        unset($ret2);
1397
1398
        // Expired articles per topic
1399
        $ret2   = array();
1400
        $sql    = "SELECT Count(storyid) as cpt, topicid FROM $tbls WHERE expired>0 AND expired<=" . time() . ' GROUP BY topicid ORDER BY topicid';
1401
        $result = $db->query($sql);
1402
        while ($myrow = $db->fetchArray($result)) {
1403
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1404
        }
1405
        $ret['expiredpertopic'] = $ret2;
1406
        unset($ret2);
1407
1408
        // Number of unique authors per topic
1409
        $ret2   = array();
1410
        $sql    = "SELECT Count(Distinct(uid)) as cpt, topicid FROM $tbls GROUP BY topicid ORDER BY topicid";
1411
        $result = $db->query($sql);
1412
        while ($myrow = $db->fetchArray($result)) {
1413
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1414
        }
1415
        $ret['authorspertopic'] = $ret2;
1416
        unset($ret2);
1417
1418
        // Most readed articles
1419
        $ret2   = array();
1420
        $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";
1421
        $result = $db->query($sql, (int)$limit);
1422
        while ($myrow = $db->fetchArray($result)) {
1423
            $ret2[$myrow['storyid']] = $myrow;
1424
        }
1425
        $ret['mostreadednews'] = $ret2;
1426
        unset($ret2);
1427
1428
        // Less readed articles
1429
        $ret2   = array();
1430
        $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";
1431
        $result = $db->query($sql, (int)$limit);
1432
        while ($myrow = $db->fetchArray($result)) {
1433
            $ret2[$myrow['storyid']] = $myrow;
1434
        }
1435
        $ret['lessreadednews'] = $ret2;
1436
        unset($ret2);
1437
1438
        // Best rated articles
1439
        $ret2   = array();
1440
        $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";
1441
        $result = $db->query($sql, (int)$limit);
1442
        while ($myrow = $db->fetchArray($result)) {
1443
            $ret2[$myrow['storyid']] = $myrow;
1444
        }
1445
        $ret['besratednews'] = $ret2;
1446
        unset($ret2);
1447
1448
        // Most readed authors
1449
        $ret2   = array();
1450
        $sql    = "SELECT Sum(counter) as cpt, uid FROM $tbls GROUP BY uid ORDER BY cpt DESC";
1451
        $result = $db->query($sql, (int)$limit);
1452
        while ($myrow = $db->fetchArray($result)) {
1453
            $ret2[$myrow['uid']] = $myrow['cpt'];
1454
        }
1455
        $ret['mostreadedauthors'] = $ret2;
1456
        unset($ret2);
1457
1458
        // Best rated authors
1459
        $ret2   = array();
1460
        $sql    = "SELECT Avg(rating) as cpt, uid FROM $tbls WHERE votes > 0 GROUP BY uid ORDER BY cpt DESC";
1461
        $result = $db->query($sql, (int)$limit);
1462
        while ($myrow = $db->fetchArray($result)) {
1463
            $ret2[$myrow['uid']] = $myrow['cpt'];
1464
        }
1465
        $ret['bestratedauthors'] = $ret2;
1466
        unset($ret2);
1467
1468
        // Biggest contributors
1469
        $ret2   = array();
1470
        $sql    = "SELECT Count(*) as cpt, uid FROM $tbls GROUP BY uid ORDER BY cpt DESC";
1471
        $result = $db->query($sql, (int)$limit);
1472
        while ($myrow = $db->fetchArray($result)) {
1473
            $ret2[$myrow['uid']] = $myrow['cpt'];
1474
        }
1475
        $ret['biggestcontributors'] = $ret2;
1476
        unset($ret2);
1477
1478
        return $ret;
1479
    }
1480
1481
    /**
1482
     * Get the date of the older and most recent news
1483
     * @param $older
1484
     * @param $recent
1485
     */
1486
    public function GetOlderRecentNews(&$older, &$recent)
1487
    {
1488
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
1489
        $sql    = 'SELECT min(published) as minpublish, max(published) as maxpublish FROM ' . $db->prefix('news_stories');
1490
        $result = $db->query($sql);
1491
        if (!$result) {
1492
            $older = $recent = 0;
1493
        } else {
1494
            list($older, $recent) = $this->db->fetchRow($result);
1495
        }
1496
    }
1497
1498
    /*
1499
     * Returns the author's IDs for the Who's who page
1500
     */
1501
    /**
1502
     * @param bool $checkRight
1503
     * @param int  $limit
1504
     * @param int  $start
1505
     *
1506
     * @return array|null
1507
     */
1508
    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...
1509
    {
1510
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
1511
        $ret = array();
1512
        $sql = 'SELECT distinct(uid) as uid FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . time() . ') AND (expired = 0 OR expired > ' . time() . ')';
1513
        if ($checkRight) {
1514
            $topics = news_MygetItemIds('news_view');
1515
            if (count($topics) > 0) {
1516
                $topics = implode(',', $topics);
1517
                $sql .= ' AND topicid IN (' . $topics . ')';
1518
            } else {
1519
                return null;
1520
            }
1521
        }
1522
        $sql .= ' ORDER BY uid';
1523
        $result = $db->query($sql);
1524
        while ($myrow = $db->fetchArray($result)) {
1525
            $ret[] = $myrow['uid'];
1526
        }
1527
1528
        return $ret;
1529
    }
1530
1531
    /**
1532
     * Returns the content of the summary and the titles requires for the list selector
1533
     * @param $text
1534
     * @param $titles
1535
     * @return string
1536
     */
1537
    public function auto_summary($text, &$titles)
1538
    {
1539
        $auto_summary = '';
1540
        if (news_getmoduleoption('enhanced_pagenav')) {
1541
            $expr_matches = array();
1542
            $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...
1543
            if (count($expr_matches) > 0) {
1544
                $delimiters  = $expr_matches[0];
1545
                $arr_search  = array('[pagebreak:', '[pagebreak', ']');
1546
                $arr_replace = array('', '', '');
1547
                $cpt         = 1;
1548
                if (isset($titles) && is_array($titles)) {
1549
                    $titles[] = strip_tags(sprintf(_NW_PAGE_AUTO_SUMMARY, 1, $this->title()));
1550
                }
1551
                $item = "<a href='" . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . "&page=0'>" . sprintf(_NW_PAGE_AUTO_SUMMARY, 1, $this->title()) . '</a><br>';
1552
                $auto_summary .= $item;
1553
1554
                foreach ($delimiters as $item) {
1555
                    ++$cpt;
1556
                    $item = str_replace($arr_search, $arr_replace, $item);
1557
                    if (xoops_trim($item) == '') {
1558
                        $item = $cpt;
1559
                    }
1560
                    $titles[] = strip_tags(sprintf(_NW_PAGE_AUTO_SUMMARY, $cpt, $item));
1561
                    $item     =
1562
                        "<a href='" . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '&page=' . ($cpt - 1) . "'>" . sprintf(_NW_PAGE_AUTO_SUMMARY, $cpt, $item) . '</a><br>';
1563
                    $auto_summary .= $item;
1564
                }
1565
            }
1566
        }
1567
1568
        return $auto_summary;
1569
    }
1570
1571
    /**
1572
     * @param string $format
1573
     *
1574
     * @return mixed
1575
     */
1576 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...
1577
    {
1578
        $myts = MyTextSanitizer::getInstance();
1579
        $html = $smiley = $xcodes = 1;
1580
        if ($this->nohtml()) {
1581
            $html = 0;
1582
        }
1583
        if ($this->nosmiley()) {
1584
            $smiley = 0;
1585
        }
1586
        switch ($format) {
1587
            case 'Show':
1588
                $hometext     = $myts->displayTarea($this->hometext, $html, $smiley, $xcodes);
1589
                $tmp          = '';
1590
                $auto_summary = $this->auto_summary($this->bodytext('Show'), $tmp);
1591
                $hometext     = str_replace('[summary]', $auto_summary, $hometext);
1592
                break;
1593
            case 'Edit':
1594
                $hometext = $myts->htmlSpecialChars($this->hometext);
1595
                break;
1596
            case 'Preview':
1597
                $hometext = $myts->previewTarea($this->hometext, $html, $smiley, $xcodes);
1598
                break;
1599
            case 'InForm':
1600
                $hometext = $myts->stripSlashesGPC($this->hometext);
1601
                $hometext = $myts->htmlSpecialChars($hometext);
1602
                break;
1603
        }
1604
1605
        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...
1606
    }
1607
1608
    /**
1609
     * @param string $format
1610
     *
1611
     * @return mixed
1612
     */
1613 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...
1614
    {
1615
        $myts   = MyTextSanitizer::getInstance();
1616
        $html   = 1;
1617
        $smiley = 1;
1618
        $xcodes = 1;
1619
        if ($this->nohtml()) {
1620
            $html = 0;
1621
        }
1622
        if ($this->nosmiley()) {
1623
            $smiley = 0;
1624
        }
1625
        switch ($format) {
1626
            case 'Show':
1627
                $bodytext     = $myts->displayTarea($this->bodytext, $html, $smiley, $xcodes);
1628
                $tmp          = '';
1629
                $auto_summary = $this->auto_summary($bodytext, $tmp);
1630
                $bodytext     = str_replace('[summary]', $auto_summary, $bodytext);
1631
                break;
1632
            case 'Edit':
1633
                $bodytext = $myts->htmlSpecialChars($this->bodytext);
1634
                break;
1635
            case 'Preview':
1636
                $bodytext = $myts->previewTarea($this->bodytext, $html, $smiley, $xcodes);
1637
                break;
1638
            case 'InForm':
1639
                $bodytext = $myts->stripSlashesGPC($this->bodytext);
1640
                $bodytext = $myts->htmlSpecialChars($bodytext);
1641
                break;
1642
        }
1643
1644
        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...
1645
    }
1646
1647
    /**
1648
     * Returns stories by Ids
1649
     * @param             $ids
1650
     * @param  bool       $checkRight
1651
     * @param  bool       $asobject
1652
     * @param  string     $order
1653
     * @param  bool       $onlyOnline
1654
     * @return array|null
1655
     */
1656
    public function getStoriesByIds($ids, $checkRight = true, $asobject = true, $order = 'published', $onlyOnline = true)
1657
    {
1658
        $limit = $start = 0;
1659
        $db    = XoopsDatabaseFactory::getDatabaseConnection();
1660
        $myts  = MyTextSanitizer::getInstance();
1661
        $ret   = array();
1662
        $sql   = 'SELECT s.*, t.* FROM ' . $db->prefix('news_stories') . ' s, ' . $db->prefix('news_topics') . ' t WHERE ';
1663
        if (is_array($ids) && count($ids) > 0) {
1664
            array_walk($ids, 'intval');
1665
        }
1666
        $sql .= ' s.storyid IN (' . implode(',', $ids) . ') ';
1667
1668
        if ($onlyOnline) {
1669
            $sql .= ' AND (s.published > 0 AND s.published <= ' . time() . ') AND (s.expired = 0 OR s.expired > ' . time() . ') ';
1670
        }
1671
        $sql .= ' AND (s.topicid=t.topic_id) ';
1672
        if ($checkRight) {
1673
            $topics = news_MygetItemIds('news_view');
1674
            if (count($topics) > 0) {
1675
                $topics = implode(',', $topics);
1676
                $sql .= ' AND s.topicid IN (' . $topics . ')';
1677
            } else {
1678
                return null;
1679
            }
1680
        }
1681
        $sql .= " ORDER BY s.$order DESC";
1682
        $result = $db->query($sql, (int)$limit, (int)$start);
1683
1684 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...
1685
            if ($asobject) {
1686
                $ret[$myrow['storyid']] = new NewsStory($myrow);
1687
            } else {
1688
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
1689
            }
1690
        }
1691
1692
        return $ret;
1693
    }
1694
}
1695
1696
/**
1697
 * Class news_NewsStoryHandler
1698
 */
1699
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...
1700
{
1701
    /**
1702
     * @param null|object|XoopsDatabase $db
1703
     */
1704
    public function __construct(XoopsDatabase $db)
1705
    {
1706
        parent::__construct($db, 'news_stories', 'stories', 'storieid', 'title');
1707
    }
1708
}
1709