Completed
Push — master ( 6452b0...d576ea )
by Michael
05:58 queued 03:02
created

NewsStory::bodytext()   C

Complexity

Conditions 7
Paths 20

Size

Total Lines 33
Code Lines 27

Duplication

Lines 33
Ratio 100 %

Importance

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