Completed
Push — master ( b610c1...53db9c )
by Michael
03:25 queued 01:39
created

NewsStory::prepare2show()   F

Complexity

Conditions 21
Paths > 20000

Size

Total Lines 133
Code Lines 99

Duplication

Lines 12
Ratio 9.02 %

Importance

Changes 0
Metric Value
cc 21
eloc 99
nc 20736
nop 1
dl 12
loc 133
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 29 and the first side effect is on line 22.

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
 * You may not change or alter any portion of this comment or credits
4
 * of supporting developers from this source code or any supporting source code
5
 * which is considered copyrighted (c) material of the original comment or credit authors.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
 */
11
12
/**
13
 * @copyright      {@link https://xoops.org/ XOOPS Project}
14
 * @license        {@link http://www.gnu.org/licenses/gpl-2.0.html GNU GPL 2 or later}
15
 * @package
16
 * @since
17
 * @author         XOOPS Development Team
18
 */
19
20
// defined('XOOPS_ROOT_PATH') || exit('Restricted access.');
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...
21
22
require_once XOOPS_ROOT_PATH . '/modules/news/class/xoopsstory.php';
23
require_once XOOPS_ROOT_PATH . '/include/comment_constants.php';
24
require_once XOOPS_ROOT_PATH . '/modules/news/class/utility.php';
25
26
/**
27
 * Class NewsStory
28
 */
29
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...
30
{
31
    public $newstopic; // XoopsTopic object
32
    public $rating; // News rating
33
    public $votes; // Number of votes
34
    public $description; // META, desciption
35
    public $keywords; // META, keywords
36
    public $picture;
37
    public $topic_imgurl;
38
    public $topic_title;
39
    public $subtitle;
40
    public $pictureinfo;
41
42
    /**
43
     * Constructor
44
     * @param int $storyid
45
     */
46
    public function __construct($storyid = -1)
47
    {
48
        $this->db          = XoopsDatabaseFactory::getDatabaseConnection();
49
        $this->table       = $this->db->prefix('news_stories');
50
        $this->topicstable = $this->db->prefix('news_topics');
51 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...
52
            $this->makeStory($storyid);
53
        } elseif ($storyid != -1) {
54
            $this->getStory((int)$storyid);
55
        }
56
    }
57
58
    /**
59
     * Returns the number of stories published before a date
60
     * @param         $timestamp
61
     * @param         $expired
62
     * @param  string $topicslist
63
     * @return mixed
64
     */
65
    public function getCountStoriesPublishedBefore($timestamp, $expired, $topicslist = '')
66
    {
67
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
68
        $sql = 'SELECT count(*) AS cpt FROM ' . $db->prefix('news_stories') . ' WHERE published <=' . $timestamp;
69
        if ($expired) {
70
            $sql .= ' AND (expired>0 AND expired<=' . time() . ')';
71
        }
72
        if (strlen(trim($topicslist)) > 0) {
73
            $sql .= ' AND topicid IN (' . $topicslist . ')';
74
        }
75
        $result = $db->query($sql);
76
        list($count) = $db->fetchRow($result);
77
78
        return $count;
79
    }
80
81
    /**
82
     * Load the specified story from the database
83
     * @param $storyid
84
     */
85
    public function getStory($storyid)
86
    {
87
        $sql   = 'SELECT s.*, t.* FROM ' . $this->table . ' s, ' . $this->db->prefix('news_topics') . ' t WHERE (storyid=' . (int)$storyid . ') AND (s.topicid=t.topic_id)';
88
        $array = $this->db->fetchArray($this->db->query($sql));
89
        $this->makeStory($array);
90
    }
91
92
    /**
93
     * Delete stories that were published before a given date
94
     * @param         $timestamp
95
     * @param         $expired
96
     * @param  string $topicslist
97
     * @return bool
98
     */
99
    public function deleteBeforeDate($timestamp, $expired, $topicslist = '')
100
    {
101
        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...
102
        $mid          = $xoopsModule->getVar('mid');
103
        $db           = XoopsDatabaseFactory::getDatabaseConnection();
104
        $prefix       = $db->prefix('news_stories');
105
        $vote_prefix  = $db->prefix('news_stories_votedata');
106
        $files_prefix = $db->prefix('news_stories_files');
107
        $sql          = 'SELECT storyid FROM  ' . $prefix . ' WHERE published <=' . $timestamp;
108
        if ($expired) {
109
            $sql .= ' (AND expired>0 AND expired<=' . time() . ')';
110
        }
111
        if (strlen(trim($topicslist)) > 0) {
112
            $sql .= ' AND topicid IN (' . $topicslist . ')';
113
        }
114
        $result = $db->query($sql);
115
        while ($myrow = $db->fetchArray($result)) {
116
            xoops_comment_delete($mid, $myrow['storyid']); // Delete comments
117
            xoops_notification_deletebyitem($mid, 'story', $myrow['storyid']); // Delete notifications
118
            $db->queryF('DELETE FROM ' . $vote_prefix . ' WHERE storyid=' . $myrow['storyid']); // Delete votes
119
            // Remove files and records related to the files
120
            $result2 = $db->query('SELECT * FROM ' . $files_prefix . ' WHERE storyid=' . $myrow['storyid']);
121
            while ($myrow2 = $db->fetchArray($result2)) {
122
                $name = XOOPS_ROOT_PATH . '/uploads/' . $myrow2['downloadname'];
123
                if (file_exists($name)) {
124
                    unlink($name);
125
                }
126
                $db->query('DELETE FROM ' . $files_prefix . ' WHERE fileid=' . $myrow2['fileid']);
127
            }
128
            $db->queryF('DELETE FROM ' . $prefix . ' WHERE storyid=' . $myrow['storyid']); // Delete the story
129
        }
130
131
        return true;
132
    }
133
134
    /**
135
     * @param      $storyid
136
     * @param bool $next
137
     * @param bool $checkRight
138
     *
139
     * @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...
140
     */
141
    public function _searchPreviousOrNextArticle($storyid, $next = true, $checkRight = false)
142
    {
143
        $db      = XoopsDatabaseFactory::getDatabaseConnection();
144
        $ret     = [];
145
        $storyid = (int)$storyid;
146
        if ($next) {
147
            $sql     = 'SELECT storyid, title FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . time() . ') AND (expired = 0 OR expired > ' . time() . ') AND storyid > ' . $storyid;
148
            $orderBy = ' ORDER BY storyid ASC';
149
        } else {
150
            $sql     = 'SELECT storyid, title FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . time() . ') AND (expired = 0 OR expired > ' . time() . ') AND storyid < ' . $storyid;
151
            $orderBy = ' ORDER BY storyid DESC';
152
        }
153
        if ($checkRight) {
154
            $topics = NewsUtility::getMyItemIds('news_view');
155
            if (count($topics) > 0) {
156
                $sql .= ' AND topicid IN (' . implode(',', $topics) . ')';
157
            } else {
158
                return null;
159
            }
160
        }
161
        $sql    .= $orderBy;
162
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
163
        $result = $db->query($sql, 1);
164
        if ($result) {
165
            $myts = MyTextSanitizer::getInstance();
166
            while ($row = $db->fetchArray($result)) {
167
                $ret = ['storyid' => $row['storyid'], 'title' => $myts->htmlSpecialChars($row['title'])];
168
            }
169
        }
170
171
        return $ret;
172
    }
173
174
    /**
175
     * @param int  $storyid
176
     * @param bool $checkRight
177
     *
178
     * @return null|array
179
     */
180
    public function getNextArticle($storyid, $checkRight = false)
181
    {
182
        return $this->_searchPreviousOrNextArticle($storyid, true, $checkRight);
183
    }
184
185
    /**
186
     * @param      $storyid
187
     * @param bool $checkRight
188
     *
189
     * @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...
190
     */
191
    public function getPreviousArticle($storyid, $checkRight = false)
192
    {
193
        return $this->_searchPreviousOrNextArticle($storyid, false, $checkRight);
194
    }
195
196
    /**
197
     * Returns published stories according to some options
198
     * @param  int    $limit
199
     * @param  int    $start
200
     * @param  bool   $checkRight
201
     * @param  int    $topic
202
     * @param  int    $ihome
203
     * @param  bool   $asobject
204
     * @param  string $order
205
     * @param  bool   $topic_frontpage
206
     * @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...
207
     */
208
    public static function getAllPublished(
209
        $limit = 0,
210
        $start = 0,
211
        $checkRight = false,
212
        $topic = 0,
213
        $ihome = 0,
214
        $asobject = true,
215
        $order = 'published',
216
        $topic_frontpage = false
217
    ) {
218
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
219
        $myts = MyTextSanitizer::getInstance();
220
        $ret  = [];
221
        $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) ';
222
        if (0 != $topic) {
223
            if (!is_array($topic)) {
224 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...
225
                    $topics = NewsUtility::getMyItemIds('news_view');
226
                    if (!in_array($topic, $topics)) {
227
                        return null;
228
                    } else {
229
                        $sql .= ' AND s.topicid=' . (int)$topic . ' AND (s.ihome=1 OR s.ihome=0)';
230
                    }
231
                } else {
232
                    $sql .= ' AND s.topicid=' . (int)$topic . ' AND (s.ihome=1 OR s.ihome=0)';
233
                }
234
            } else {
235
                if ($checkRight) {
236
                    $topics = NewsUtility::getMyItemIds('news_view');
237
                    $topic  = array_intersect($topic, $topics);
238
                }
239
                if (count($topic) > 0) {
240
                    $sql .= ' AND s.topicid IN (' . implode(',', $topic) . ')';
241
                } else {
242
                    return null;
243
                }
244
            }
245 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...
246
            if ($checkRight) {
247
                $topics = NewsUtility::getMyItemIds('news_view');
248
                if (count($topics) > 0) {
249
                    $topics = implode(',', $topics);
250
                    $sql    .= ' AND s.topicid IN (' . $topics . ')';
251
                } else {
252
                    return null;
253
                }
254
            }
255
            if (0 == (int)$ihome) {
256
                $sql .= ' AND s.ihome=0';
257
            }
258
        }
259
        if ($topic_frontpage) {
260
            $sql .= ' AND t.topic_frontpage=1';
261
        }
262
        $sql    .= " ORDER BY s.$order DESC";
263
        $result = $db->query($sql, (int)$limit, (int)$start);
264
265 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...
266
            if ($asobject) {
267
                $ret[] = new NewsStory($myrow);
268
            } else {
269
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
270
            }
271
        }
272
273
        return $ret;
274
    }
275
276
    /**
277
     * Retourne la liste des articles aux archives (pour une p�riode donn�e)
278
     * @param             $publish_start
279
     * @param             $publish_end
280
     * @param  bool       $checkRight
281
     * @param  bool       $asobject
282
     * @param  string     $order
283
     * @return array|null
284
     */
285
    public function getArchive(
286
        $publish_start,
287
        $publish_end,
288
        $checkRight = false,
289
        $asobject = true,
290
        $order = 'published'
291
    ) {
292
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
293
        $myts = MyTextSanitizer::getInstance();
294
        $ret  = [];
295
        $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() . ') ';
296
297
        if ($checkRight) {
298
            $topics = NewsUtility::getMyItemIds('news_view');
299
            if (count($topics) > 0) {
300
                $topics = implode(',', $topics);
301
                $sql    .= ' AND topicid IN (' . $topics . ')';
302
            } else {
303
                return null;
304
            }
305
        }
306
        $sql    .= " ORDER BY $order DESC";
307
        $result = $db->query($sql);
308 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...
309
            if ($asobject) {
310
                $ret[] = new NewsStory($myrow);
311
            } else {
312
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
313
            }
314
        }
315
316
        return $ret;
317
    }
318
319
    /**
320
     * Get the today's most readed article
321
     *
322
     * @param int     $limit      records limit
323
     * @param int     $start      starting record
324
     * @param boolean $checkRight Do we need to check permissions (by topics) ?
325
     * @param int     $topic      limit the job to one topic
326
     * @param int     $ihome      Limit to articles published in home page only ?
327
     * @param boolean $asobject   Do we have to return an array of objects or a simple array ?
328
     * @param string  $order      Fields to sort on
329
     *
330
     * @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...
331
     */
332
    public function getBigStory(
333
        $limit = 0,
334
        $start = 0,
335
        $checkRight = false,
336
        $topic = 0,
337
        $ihome = 0,
338
        $asobject = true,
339
        $order = 'counter'
340
    ) {
341
        $db    = XoopsDatabaseFactory::getDatabaseConnection();
342
        $myts  = MyTextSanitizer::getInstance();
343
        $ret   = [];
344
        $tdate = mktime(0, 0, 0, date('n'), date('j'), date('Y'));
345
        $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) ';
346
347
        if (0 != (int)$topic) {
348 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...
349
                $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
350
            } else {
351
                if (count($topic) > 0) {
352
                    $sql .= ' AND topicid IN (' . implode(',', $topic) . ')';
353
                } else {
354
                    return null;
355
                }
356
            }
357 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...
358
            if ($checkRight) {
359
                $topics = NewsUtility::getMyItemIds('news_view');
360
                if (count($topics) > 0) {
361
                    $topics = implode(',', $topics);
362
                    $sql    .= ' AND topicid IN (' . $topics . ')';
363
                } else {
364
                    return null;
365
                }
366
            }
367
            if (0 == (int)$ihome) {
368
                $sql .= ' AND ihome=0';
369
            }
370
        }
371
        $sql    .= " ORDER BY $order DESC";
372
        $result = $db->query($sql, (int)$limit, (int)$start);
373 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...
374
            if ($asobject) {
375
                $ret[] = new NewsStory($myrow);
376
            } else {
377
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
378
            }
379
        }
380
381
        return $ret;
382
    }
383
384
    /**
385
     * Get all articles published by an author
386
     *
387
     * @param int     $uid        author's id
388
     * @param boolean $checkRight whether to check the user's rights to topics
389
     *
390
     * @param bool    $asobject
391
     *
392
     * @return array
393
     */
394
    public function getAllPublishedByAuthor($uid, $checkRight = false, $asobject = true)
395
    {
396
        $db        = XoopsDatabaseFactory::getDatabaseConnection();
397
        $myts      = MyTextSanitizer::getInstance();
398
        $ret       = [];
399
        $tblstory  = $db->prefix('news_stories');
400
        $tbltopics = $db->prefix('news_topics');
401
402
        $sql = 'SELECT '
403
               . $tblstory
404
               . '.*, '
405
               . $tbltopics
406
               . '.topic_title, '
407
               . $tbltopics
408
               . '.topic_color FROM '
409
               . $tblstory
410
               . ','
411
               . $tbltopics
412
               . ' WHERE ('
413
               . $tblstory
414
               . '.topicid='
415
               . $tbltopics
416
               . '.topic_id) AND (published > 0 AND published <= '
417
               . time()
418
               . ') AND (expired = 0 OR expired > '
419
               . time()
420
               . ')';
421
        $sql .= ' AND uid=' . (int)$uid;
422
        if ($checkRight) {
423
            $topics = NewsUtility::getMyItemIds('news_view');
424
            $topics = implode(',', $topics);
425
            if ('' !== xoops_trim($topics)) {
426
                $sql .= ' AND topicid IN (' . $topics . ')';
427
            }
428
        }
429
        $sql    .= ' ORDER BY ' . $tbltopics . '.topic_title ASC, ' . $tblstory . '.published DESC';
430
        $result = $db->query($sql);
431
        while ($myrow = $db->fetchArray($result)) {
432
            if ($asobject) {
433
                $ret[] = new NewsStory($myrow);
434
            } else {
435
                if ($myrow['nohtml']) {
436
                    $html = 0;
437
                } else {
438
                    $html = 1;
439
                }
440
                if ($myrow['nosmiley']) {
441
                    $smiley = 0;
442
                } else {
443
                    $smiley = 1;
444
                }
445
                $ret[$myrow['storyid']] = [
446
                    'title'       => $myts->displayTarea($myrow['title'], $html, $smiley, 1),
447
                    'topicid'     => (int)$myrow['topicid'],
448
                    'storyid'     => (int)$myrow['storyid'],
449
                    'hometext'    => $myts->displayTarea($myrow['hometext'], $html, $smiley, 1),
450
                    'counter'     => (int)$myrow['counter'],
451
                    'created'     => (int)$myrow['created'],
452
                    'topic_title' => $myts->displayTarea($myrow['topic_title'], $html, $smiley, 1),
453
                    'topic_color' => $myts->displayTarea($myrow['topic_color']),
454
                    'published'   => (int)$myrow['published'],
455
                    'rating'      => (float)$myrow['rating'],
456
                    'votes'       => (int)$myrow['votes']
457
                ];
458
            }
459
        }
460
461
        return $ret;
462
    }
463
464
    /**
465
     * Get all expired stories
466
     * @param  int  $limit
467
     * @param  int  $start
468
     * @param  int  $topic
469
     * @param  int  $ihome
470
     * @param  bool $asobject
471
     * @return array
472
     */
473
    public static function getAllExpired($limit = 0, $start = 0, $topic = 0, $ihome = 0, $asobject = true)
474
    {
475
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
476
        $myts = MyTextSanitizer::getInstance();
477
        $ret  = [];
478
        $sql  = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE expired <= ' . time() . ' AND expired > 0';
479
        if (!empty($topic)) {
480
            $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
481
        } else {
482
            if (0 == (int)$ihome) {
483
                $sql .= ' AND ihome=0';
484
            }
485
        }
486
487
        $sql    .= ' ORDER BY expired DESC';
488
        $result = $db->query($sql, (int)$limit, (int)$start);
489 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...
490
            if ($asobject) {
491
                $ret[] = new NewsStory($myrow);
492
            } else {
493
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
494
            }
495
        }
496
497
        return $ret;
498
    }
499
500
    /**
501
     * Returns an array of object containing all the news to be automatically published.
502
     * @param  int  $limit
503
     * @param  bool $asobject
504
     * @param  int  $start
505
     * @return array
506
     */
507
    public static function getAllAutoStory($limit = 0, $asobject = true, $start = 0)
508
    {
509
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
510
        $myts   = MyTextSanitizer::getInstance();
511
        $ret    = [];
512
        $sql    = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE published > ' . time() . ' ORDER BY published ASC';
513
        $result = $db->query($sql, (int)$limit, (int)$start);
514 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...
515
            if ($asobject) {
516
                $ret[] = new NewsStory($myrow);
517
            } else {
518
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
519
            }
520
        }
521
522
        return $ret;
523
    }
524
525
    /**
526
     * Get all submitted stories awaiting approval
527
     *
528
     * @param int     $limit      Denotes where to start the query
529
     * @param boolean $asobject   true will returns the stories as an array of objects, false will return storyid => title
530
     * @param boolean $checkRight whether to check the user's rights to topics
531
     *
532
     * @param int     $start
533
     *
534
     * @return array
535
     */
536
    public static function getAllSubmitted($limit = 0, $asobject = true, $checkRight = false, $start = 0)
537
    {
538
        $db       = XoopsDatabaseFactory::getDatabaseConnection();
539
        $myts     = MyTextSanitizer::getInstance();
540
        $ret      = [];
541
        $criteria = new CriteriaCompo(new Criteria('published', 0));
542
        if ($checkRight) {
543
            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...
544
            if (!is_object($xoopsUser)) {
545
                return $ret;
546
            }
547
            $allowedtopics = NewsUtility::getMyItemIds('news_approve');
548
            $criteria2     = new CriteriaCompo();
549
            foreach ($allowedtopics as $key => $topicid) {
550
                $criteria2->add(new Criteria('topicid', $topicid), 'OR');
551
            }
552
            $criteria->add($criteria2);
553
        }
554
        $sql    = 'SELECT s.*, t.* FROM ' . $db->prefix('news_stories') . ' s, ' . $db->prefix('news_topics') . ' t ';
555
        $sql    .= ' ' . $criteria->renderWhere() . ' AND (s.topicid=t.topic_id) ORDER BY created DESC';
556
        $result = $db->query($sql, (int)$limit, (int)$start);
557 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...
558
            if ($asobject) {
559
                $ret[] = new NewsStory($myrow);
560
            } else {
561
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
562
            }
563
        }
564
565
        return $ret;
566
    }
567
568
    /**
569
     * Used in the module's admin to know the number of expired, automated or pubilshed news
570
     *
571
     * @param int  $storytype  1=Expired, 2=Automated, 3=New submissions, 4=Last published stories
572
     * @param bool $checkRight verify permissions or not ?
573
     *
574
     * @return int
575
     */
576
    public static function getAllStoriesCount($storytype = 1, $checkRight = false)
577
    {
578
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
579
        $sql = 'SELECT count(*) AS cpt FROM ' . $db->prefix('news_stories') . ' WHERE ';
580
        switch ($storytype) {
581
            case 1: // Expired
582
                $sql .= '(expired <= ' . time() . ' AND expired >0)';
583
                break;
584
            case 2: // Automated
585
                $sql .= '(published > ' . time() . ')';
586
                break;
587
            case 3: // New submissions
588
                $sql .= '(published = 0)';
589
                break;
590
            case 4: // Last published stories
591
                $sql .= '(published > 0 AND published <= ' . time() . ') AND (expired = 0 OR expired > ' . time() . ')';
592
                break;
593
        }
594
        if ($checkRight) {
595
            $topics = NewsUtility::getMyItemIds('news_view');
596
            if (count($topics) > 0) {
597
                $topics = implode(',', $topics);
598
                $sql    .= ' AND topicid IN (' . $topics . ')';
599
            } else {
600
                return 0;
601
            }
602
        }
603
        $result = $db->query($sql);
604
        $myrow  = $db->fetchArray($result);
605
606
        return $myrow['cpt'];
607
    }
608
609
    /**
610
     * Get a list of stories (as objects) related to a specific topic
611
     * @param        $topicid
612
     * @param  int   $limit
613
     * @return array
614
     */
615
    public static function getByTopic($topicid, $limit = 0)
616
    {
617
        $ret    = [];
618
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
619
        $sql    = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE topicid=' . (int)$topicid . ' ORDER BY published DESC';
620
        $result = $db->query($sql, (int)$limit, 0);
621
        while ($myrow = $db->fetchArray($result)) {
622
            $ret[] = new NewsStory($myrow);
623
        }
624
625
        return $ret;
626
    }
627
628
    /**
629
     * Count the number of news published for a specific topic
630
     * @param  int  $topicid
631
     * @param  bool $checkRight
632
     * @return null
633
     */
634
    public static function countPublishedByTopic($topicid = 0, $checkRight = false)
635
    {
636
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
637
        $sql = 'SELECT COUNT(*) FROM ' . $db->prefix('news_stories') . ' WHERE published > 0 AND published <= ' . time() . ' AND (expired = 0 OR expired > ' . time() . ')';
638 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...
639
            $sql .= ' AND topicid=' . (int)$topicid;
640
        } else {
641
            $sql .= ' AND ihome=0';
642
            if ($checkRight) {
643
                $topics = NewsUtility::getMyItemIds('news_view');
644
                if (count($topics) > 0) {
645
                    $topics = implode(',', $topics);
646
                    $sql    .= ' AND topicid IN (' . $topics . ')';
647
                } else {
648
                    return null;
649
                }
650
            }
651
        }
652
        $result = $db->query($sql);
653
        list($count) = $db->fetchRow($result);
654
655
        return $count;
656
    }
657
658
    /**
659
     * Internal function
660
     */
661
    public function adminlink()
662
    {
663
        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...
664
        $dirname = basename(dirname(__DIR__));
665
        /** @var XoopsModuleHandler $moduleHandler */
666
        $moduleHandler = xoops_getHandler('module');
667
        $module        = $moduleHandler->getByDirname($dirname);
0 ignored issues
show
Unused Code introduced by
$module 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...
668
        $pathIcon16    = \Xmf\Module\Admin::iconUrl('', 16);
669
670
        $ret = '&nbsp; <a href='
671
               . XOOPS_URL
672
               . '/modules/news/submit.php?op=edit&amp;storyid='
673
               . $this->storyid()
674
               . '><img src='
675
               . $pathIcon16
676
               . '/edit.png'
677
               . ' '
678
               . 'title='
679
               . _NW_EDIT
680
               . '></a>'
681
               . '<a href='
682
               . XOOPS_URL
683
               . '/modules/news/admin/index.php?op=delete&amp;storyid='
684
               . $this->storyid()
685
               . '><img src='
686
               . $pathIcon16
687
               . '/delete.png'
688
               . ' '
689
               . 'title='
690
               . _NW_DELETE
691
               . '></a> &nbsp;';
692
693
        return $ret;
694
    }
695
696
    /**
697
     * Get the topic image url
698
     * @param string $format
699
     * @return
700
     */
701 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...
702
    {
703
        if ('' === trim($this->topic_imgurl)) {
704
            $this->topic_imgurl = 'blank.png';
705
        }
706
        $myts = MyTextSanitizer::getInstance();
707
        switch ($format) {
708
            case 'S':
709
                $imgurl = $myts->htmlSpecialChars($this->topic_imgurl);
710
                break;
711
            case 'E':
712
                $imgurl = $myts->htmlSpecialChars($this->topic_imgurl);
713
                break;
714
            case 'P':
715
                $imgurl = $myts->stripSlashesGPC($this->topic_imgurl);
716
                $imgurl = $myts->htmlSpecialChars($imgurl);
717
                break;
718
            case 'F':
719
                $imgurl = $myts->stripSlashesGPC($this->topic_imgurl);
720
                $imgurl = $myts->htmlSpecialChars($imgurl);
721
                break;
722
        }
723
724
        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...
725
    }
726
727
    /**
728
     * @param string $format
729
     *
730
     * @return mixed
731
     */
732
    public function topic_title($format = 'S')
733
    {
734
        $myts = MyTextSanitizer::getInstance();
735
        switch ($format) {
736
            case 'S':
737
                $title = $myts->htmlSpecialChars($this->topic_title);
738
                break;
739
            case 'E':
740
                $title = $myts->htmlSpecialChars($this->topic_title);
741
                break;
742
            case 'P':
743
                $title = $myts->stripSlashesGPC($this->topic_title);
744
                $title = $myts->htmlSpecialChars($title);
745
                break;
746
            case 'F':
747
                $title = $myts->stripSlashesGPC($this->topic_title);
748
                $title = $myts->htmlSpecialChars($title);
749
                break;
750
        }
751
752
        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...
753
    }
754
755
    /**
756
     * @return string
757
     */
758
    public function imglink()
759
    {
760
        $ret = '';
761
        if ('' !== $this->topic_imgurl()
762
            && file_exists(XOOPS_ROOT_PATH . '/uploads/news/image/' . $this->topic_imgurl())) {
763
            $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>";
764
        }
765
766
        return $ret;
767
    }
768
769
    /**
770
     * @return string
771
     */
772
    public function textlink()
773
    {
774
        $ret = '<a title=' . $this->topic_title() . " href='" . XOOPS_URL . '/modules/news/index.php?storytopic=' . $this->topicid() . "'>" . $this->topic_title() . '</a>';
775
776
        return $ret;
777
    }
778
779
    /**
780
     * Function used to prepare an article to be showned
781
     * @param $filescount
782
     * @return array
783
     */
784
    public function prepare2show($filescount)
785
    {
786
        require_once XOOPS_ROOT_PATH . '/modules/news/class/utility.php';
787
        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...
788
789
        $dirname = basename(dirname(__DIR__));
790
        /** @var XoopsModuleHandler $moduleHandler */
791
        $moduleHandler = xoops_getHandler('module');
792
        $module        = $moduleHandler->getByDirname($dirname);
0 ignored issues
show
Unused Code introduced by
$module 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...
793
        $pathIcon16    = \Xmf\Module\Admin::iconUrl('', 16);
794
795
        $myts                 = MyTextSanitizer::getInstance();
796
        $infotips             = NewsUtility::getModuleOption('infotips');
797
        $story                = [];
798
        $story['id']          = $this->storyid();
799
        $story['poster']      = $this->uname();
800
        $story['author_name'] = $this->uname();
801
        $story['author_uid']  = $this->uid();
802
        if (false !== $story['poster']) {
803
            $story['poster'] = "<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $this->uid() . "'>" . $story['poster'] . '</a>';
804
        } else {
805
            if (3 != $xoopsModuleConfig['displayname']) {
806
                $story['poster'] = $xoopsConfig['anonymous'];
807
            }
808
        }
809
        if ($xoopsModuleConfig['ratenews']) {
810
            $story['rating'] = number_format($this->rating(), 2);
811
            if (1 == $this->votes) {
812
                $story['votes'] = _NW_ONEVOTE;
813
            } else {
814
                $story['votes'] = sprintf(_NW_NUMVOTES, $this->votes);
815
            }
816
        }
817
        $story['posttimestamp']     = $this->published();
818
        $story['posttime']          = formatTimestamp($story['posttimestamp'], NewsUtility::getModuleOption('dateformat'));
819
        $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...
820
821
        $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...
822
        $tmp          = '';
823
        $auto_summary = $this->auto_summary($this->bodytext(), $tmp);
824
825
        $story['text'] = $this->hometext();
826
        $story['text'] = str_replace('[summary]', $auto_summary, $story['text']);
827
828
        //$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...
829
        if ('' !== $this->picture()) {
830
            $story['picture'] = XOOPS_URL . '/uploads/news/image/' . $this->picture();
831
        } else {
832
            $story['picture'] = '';
833
        }
834
        $story['pictureinfo'] = $this->pictureinfo();
835
836
        $introcount = strlen($story['text']);
837
        $fullcount  = strlen($this->bodytext());
838
        $totalcount = $introcount + $fullcount;
839
840
        $morelink = '';
841
        if ($fullcount > 1) {
842
            $morelink .= '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
843
            $morelink .= '">' . _NW_READMORE . '</a>';
844
            $morelink .= ' | ' . sprintf(_NW_BYTESMORE, $totalcount);
845
            if (XOOPS_COMMENT_APPROVENONE != $xoopsModuleConfig['com_rule']) {
846
                $morelink .= ' | ';
847
            }
848
        }
849
        if (XOOPS_COMMENT_APPROVENONE != $xoopsModuleConfig['com_rule']) {
850
            $ccount    = $this->comments();
851
            $morelink  .= '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
852
            $morelink2 = '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
853
            if (0 == $ccount) {
854
                $morelink .= '">' . _NW_COMMENTS . '</a>';
855
            } else {
856
                if ($fullcount < 1) {
857
                    if (1 == $ccount) {
858
                        $morelink .= '">' . _NW_READMORE . '</a> | ' . $morelink2 . '">' . _NW_ONECOMMENT . '</a>';
859 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...
860
                        $morelink .= '">' . _NW_READMORE . '</a> | ' . $morelink2 . '">';
861
                        $morelink .= sprintf(_NW_NUMCOMMENTS, $ccount);
862
                        $morelink .= '</a>';
863
                    }
864
                } else {
865 View Code Duplication
                    if (1 == $ccount) {
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...
866
                        $morelink .= '">' . _NW_ONECOMMENT . '</a>';
867
                    } else {
868
                        $morelink .= '">';
869
                        $morelink .= sprintf(_NW_NUMCOMMENTS, $ccount);
870
                        $morelink .= '</a>';
871
                    }
872
                }
873
            }
874
        }
875
        $story['morelink']  = $morelink;
876
        $story['adminlink'] = '';
877
878
        $approveprivilege = 0;
879
        if (NewsUtility::isAdminGroup()) {
880
            $approveprivilege = 1;
881
        }
882
883
        if (1 == $xoopsModuleConfig['authoredit']
884
            && (is_object($xoopsUser)
885
                && $xoopsUser->getVar('uid') == $this->uid())) {
886
            $approveprivilege = 1;
887
        }
888
        if ($approveprivilege) {
889
            $story['adminlink'] = $this->adminlink();
890
        }
891
        $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();
892
        $story['imglink']   = '';
893
        $story['align']     = '';
894
        if ($this->topicdisplay()) {
895
            $story['imglink'] = $this->imglink();
896
            $story['align']   = $this->topicalign();
897
        }
898
        if ($infotips > 0) {
899
            $story['infotips'] = ' title="' . NewsUtility::makeInfotips($this->hometext()) . '"';
900
        } else {
901
            $story['infotips'] = 'title="' . $this->title() . '"';
902
        }
903
        $story['title'] = "<a href='" . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . "'" . $story['infotips'] . '>' . $this->title() . '</a>';
904
        //$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...
905
906
        $story['hits'] = $this->counter();
907
        if ($filescount > 0) {
908
            $story['files_attached'] = true;
909
            $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>';
910
        } else {
911
            $story['files_attached'] = false;
912
            $story['attached_link']  = '';
913
        }
914
915
        return $story;
916
    }
917
918
    /**
919
     * Returns the user's name of the current story according to the module's option "displayname"
920
     * @param  int $uid
921
     * @return null|string
922
     */
923
    public function uname($uid = 0)
924
    {
925
        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...
926
        require_once XOOPS_ROOT_PATH . '/modules/news/class/utility.php';
927
        static $tblusers = [];
928
        $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...
929
        if (0 == $uid) {
930
            $uid = $this->uid();
931
        }
932
933
        if (is_array($tblusers) && array_key_exists($uid, $tblusers)) {
934
            return $tblusers[$uid];
935
        }
936
937
        $option = NewsUtility::getModuleOption('displayname');
938
        if (!$option) {
939
            $option = 1;
940
        }
941
942
        switch ($option) {
943
            case 1: // Username
944
                $tblusers[$uid] = XoopsUser::getUnameFromId($uid);
945
946
                return $tblusers[$uid];
947
948
            case 2: // Display full name (if it is not empty)
949
                $memberHandler = xoops_getHandler('member');
950
                $thisuser      = $memberHandler->getUser($uid);
951
                if (is_object($thisuser)) {
952
                    $return = $thisuser->getVar('name');
953
                    if ('' === $return) {
954
                        $return = $thisuser->getVar('uname');
955
                    }
956
                } else {
957
                    $return = $xoopsConfig['anonymous'];
958
                }
959
                $tblusers[$uid] = $return;
960
961
                return $return;
962
963
            case 3: // Nothing
964
                $tblusers[$uid] = '';
965
966
                return '';
967
        }
968
969
        return null;
970
    }
971
972
    /**
973
     * Function used to export news (in xml) and eventually the topics definitions
974
     * Warning, permissions are not exported !
975
     *
976
     * @param int      $fromdate     Starting date
977
     * @param int      $todate       Ending date
978
     * @param string   $topicslist
979
     * @param bool|int $usetopicsdef Should we also export topics definitions ?
980
     * @param          $tbltopics
981
     * @param boolean  $asobject     Return values as an object or not ?
982
     *
983
     * @param string   $order
984
     *
985
     * @internal param string $topiclist If not empty, a list of topics to limit to
986
     * @return array
987
     */
988
    public function exportNews(
989
        $fromdate,
990
        $todate,
991
        $topicslist = '',
992
        $usetopicsdef = 0,
993
        &$tbltopics,
994
        $asobject = true,
995
        $order = 'published'
996
    ) {
997
        $ret  = [];
998
        $myts = MyTextSanitizer::getInstance();
999
        if ($usetopicsdef) { // We firt begin by exporting topics definitions
1000
            // Before all we must know wich topics to export
1001
            $sql = 'SELECT DISTINCT topicid FROM ' . $this->db->prefix('news_stories') . ' WHERE (published >=' . $fromdate . ' AND published <= ' . $todate . ')';
1002
            if (strlen(trim($topicslist)) > 0) {
1003
                $sql .= ' AND topicid IN (' . $topicslist . ')';
1004
            }
1005
            $result = $this->db->query($sql);
1006
            while ($myrow = $this->db->fetchArray($result)) {
1007
                $tbltopics[] = $myrow['topicid'];
1008
            }
1009
        }
1010
1011
        // Now we can search for the stories
1012
        $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 . ')';
1013
        if (strlen(trim($topicslist)) > 0) {
1014
            $sql .= ' AND topicid IN (' . $topicslist . ')';
1015
        }
1016
        $sql    .= " ORDER BY $order DESC";
1017
        $result = $this->db->query($sql);
1018 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...
1019
            if ($asobject) {
1020
                $ret[] = new NewsStory($myrow);
1021
            } else {
1022
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
1023
            }
1024
        }
1025
1026
        return $ret;
1027
    }
1028
1029
    /**
1030
     * Create or update an article
1031
     * @param  bool $approved
1032
     * @return bool|int
1033
     */
1034
    public function store($approved = false)
1035
    {
1036
        $myts        = MyTextSanitizer::getInstance();
1037
        $counter     = isset($this->counter) ? $this->counter : 0;
1038
        $title       = $myts->addSlashes($myts->censorString($this->title));
1039
        $subtitle    = $myts->addSlashes($myts->censorString($this->subtitle));
1040
        $hostname    = $myts->addSlashes($this->hostname);
1041
        $type        = $myts->addSlashes($this->type);
1042
        $hometext    = $myts->addSlashes($myts->censorString($this->hometext));
1043
        $bodytext    = $myts->addSlashes($myts->censorString($this->bodytext));
1044
        $description = $myts->addSlashes($myts->censorString($this->description));
1045
        $keywords    = $myts->addSlashes($myts->censorString($this->keywords));
1046
        $picture     = $myts->addSlashes($this->picture);
1047
        $pictureinfo = $myts->addSlashes($myts->censorString($this->pictureinfo));
1048
        $votes       = (int)$this->votes;
1049
        $rating      = (float)$this->rating;
1050
        if (!isset($this->nohtml) || 1 != $this->nohtml) {
1051
            $this->nohtml = 0;
1052
        }
1053
        if (!isset($this->nosmiley) || 1 != $this->nosmiley) {
1054
            $this->nosmiley = 0;
1055
        }
1056
        if (!isset($this->notifypub) || 1 != $this->notifypub) {
1057
            $this->notifypub = 0;
1058
        }
1059
        if (!isset($this->topicdisplay) || 0 != $this->topicdisplay) {
1060
            $this->topicdisplay = 1;
1061
        }
1062
        $expired = !empty($this->expired) ? $this->expired : 0;
1063
        if (!isset($this->storyid)) {
1064
            //$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...
1065
            $newstoryid = $this->db->genId($this->table . '_storyid_seq');
1066
            $created    = time();
1067
            $published  = $this->approved ? (int)$this->published : 0;
1068
            $sql        = sprintf(
1069
                "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')",
1070
                                  $this->table,
1071
                $newstoryid,
1072
                (int)$this->uid(),
1073
                $title,
1074
                $created,
1075
                $published,
1076
                $expired,
1077
                $hostname,
1078
                (int)$this->nohtml(),
1079
                (int)$this->nosmiley(),
1080
                $hometext,
1081
                $bodytext,
1082
                $counter,
1083
                (int)$this->topicid(),
1084
                (int)$this->ihome(),
1085
                (int)$this->notifypub(),
1086
                $type,
1087
                                  (int)$this->topicdisplay(),
1088
                $this->topicalign,
1089
                (int)$this->comments(),
1090
                $rating,
1091
                $votes,
1092
                $description,
1093
                $keywords,
1094
                $picture,
1095
                $pictureinfo,
1096
                $subtitle
1097
            );
1098
        } else {
1099
            $sql        = sprintf(
1100
                "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",
1101
                                  $this->table,
1102
                $title,
1103
                (int)$this->published(),
1104
                $expired,
1105
                (int)$this->nohtml(),
1106
                (int)$this->nosmiley(),
1107
                $hometext,
1108
                $bodytext,
1109
                (int)$this->topicid(),
1110
                (int)$this->ihome(),
1111
                (int)$this->topicdisplay(),
1112
                $this->topicalign,
1113
                (int)$this->comments(),
1114
                $rating,
1115
                $votes,
1116
                                  (int)$this->uid(),
1117
                $description,
1118
                $keywords,
1119
                $picture,
1120
                $pictureinfo,
1121
                $subtitle,
1122
                (int)$this->storyid()
1123
            );
1124
            $newstoryid = (int)$this->storyid();
1125
        }
1126
        if (!$this->db->queryF($sql)) {
1127
            return false;
1128
        }
1129
        if (empty($newstoryid)) {
1130
            $newstoryid    = $this->db->getInsertId();
1131
            $this->storyid = $newstoryid;
1132
        }
1133
1134
        return $newstoryid;
1135
    }
1136
1137
    /**
1138
     * @return mixed
1139
     */
1140
    public function picture()
1141
    {
1142
        return $this->picture;
1143
    }
1144
1145
    /**
1146
     * @return mixed
1147
     */
1148
    public function pictureinfo()
1149
    {
1150
        return $this->pictureinfo;
1151
    }
1152
1153
    /**
1154
     * @return mixed
1155
     */
1156
    public function subtitle()
1157
    {
1158
        return $this->subtitle;
1159
    }
1160
1161
    /**
1162
     * @return mixed
1163
     */
1164
    public function rating()
1165
    {
1166
        return $this->rating;
1167
    }
1168
1169
    /**
1170
     * @return mixed
1171
     */
1172
    public function votes()
1173
    {
1174
        return $this->votes;
1175
    }
1176
1177
    /**
1178
     * @param $data
1179
     */
1180
    public function setPicture($data)
1181
    {
1182
        $this->picture = $data;
1183
    }
1184
1185
    /**
1186
     * @param $data
1187
     */
1188
    public function setPictureinfo($data)
1189
    {
1190
        $this->pictureinfo = $data;
1191
    }
1192
1193
    /**
1194
     * @param $data
1195
     */
1196
    public function setSubtitle($data)
1197
    {
1198
        $this->subtitle = $data;
1199
    }
1200
1201
    /**
1202
     * @param $data
1203
     */
1204
    public function setDescription($data)
1205
    {
1206
        $this->description = $data;
1207
    }
1208
1209
    /**
1210
     * @param $data
1211
     */
1212
    public function setKeywords($data)
1213
    {
1214
        $this->keywords = $data;
1215
    }
1216
1217
    /**
1218
     * @param string $format
1219
     *
1220
     * @return mixed
1221
     */
1222
    public function description($format = 'S')
1223
    {
1224
        $myts = MyTextSanitizer::getInstance();
1225
        switch (strtoupper($format)) {
1226
            case 'S':
1227
                $description = $myts->htmlSpecialChars($this->description);
1228
                break;
1229
            case 'P':
1230
            case 'F':
1231
                $description = $myts->htmlSpecialChars($myts->stripSlashesGPC($this->description));
1232
                break;
1233
            case 'E':
1234
                $description = $myts->htmlSpecialChars($this->description);
1235
                break;
1236
        }
1237
1238
        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...
1239
    }
1240
1241
    /**
1242
     * @param string $format
1243
     *
1244
     * @return mixed
1245
     */
1246
    public function keywords($format = 'S')
1247
    {
1248
        $myts = MyTextSanitizer::getInstance();
1249
        switch (strtoupper($format)) {
1250
            case 'S':
1251
                $keywords = $myts->htmlSpecialChars($this->keywords);
1252
                break;
1253
            case 'P':
1254
            case 'F':
1255
                $keywords = $myts->htmlSpecialChars($myts->stripSlashesGPC($this->keywords));
1256
                break;
1257
            case 'E':
1258
                $keywords = $myts->htmlSpecialChars($this->keywords);
1259
                break;
1260
        }
1261
1262
        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...
1263
    }
1264
1265
    /**
1266
     * Returns a random number of news
1267
     * @param  int    $limit
1268
     * @param  int    $start
1269
     * @param  bool   $checkRight
1270
     * @param  int    $topic
1271
     * @param  int    $ihome
1272
     * @param  string $order
1273
     * @param  bool   $topic_frontpage
1274
     * @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...
1275
     */
1276
    public function getRandomNews(
1277
        $limit = 0,
1278
        $start = 0,
0 ignored issues
show
Unused Code introduced by
The parameter $start is not used and could be removed.

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

Loading history...
1279
        $checkRight = false,
1280
        $topic = 0,
1281
        $ihome = 0,
1282
        $order = 'published',
1283
        $topic_frontpage = false
1284
    ) {
1285
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
1286
        $ret = $rand_keys = $ret3 = [];
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...
1287
        $sql = 'SELECT storyid FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . time() . ') AND (expired = 0 OR expired > ' . time() . ')';
1288
        if (0 != $topic) {
1289
            if (!is_array($topic)) {
1290 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...
1291
                    $topics = NewsUtility::getMyItemIds('news_view');
1292
                    if (!in_array($topic, $topics)) {
1293
                        return null;
1294
                    } else {
1295
                        $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
1296
                    }
1297
                } else {
1298
                    $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
1299
                }
1300
            } else {
1301
                if (count($topic) > 0) {
1302
                    $sql .= ' AND topicid IN (' . implode(',', $topic) . ')';
1303
                } else {
1304
                    return null;
1305
                }
1306
            }
1307 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...
1308
            if ($checkRight) {
1309
                $topics = NewsUtility::getMyItemIds('news_view');
1310
                if (count($topics) > 0) {
1311
                    $topics = implode(',', $topics);
1312
                    $sql    .= ' AND topicid IN (' . $topics . ')';
1313
                } else {
1314
                    return null;
1315
                }
1316
            }
1317
            if (0 == (int)$ihome) {
1318
                $sql .= ' AND ihome=0';
1319
            }
1320
        }
1321
        if ($topic_frontpage) {
1322
            $sql .= ' AND t.topic_frontpage=1';
1323
        }
1324
        $sql    .= " ORDER BY $order DESC";
1325
        $result = $db->query($sql);
1326
1327
        while ($myrow = $db->fetchArray($result)) {
1328
            $ret[] = $myrow['storyid'];
1329
        }
1330
        $cnt = count($ret);
1331
        if ($cnt) {
1332
            mt_srand((double)microtime() * 10000000);
1333
            if ($limit > $cnt) {
1334
                $limit = $cnt;
1335
            }
1336
            $rand_keys = array_rand($ret, $limit);
1337
            if ($limit > 1) {
1338
                for ($i = 0; $i < $limit; ++$i) {
1339
                    $onestory = $ret[$rand_keys[$i]];
1340
                    $ret3[]   = new NewsStory($onestory);
1341
                }
1342
            } else {
1343
                $ret3[] = new NewsStory($ret[$rand_keys]);
1344
            }
1345
        }
1346
1347
        return $ret3;
1348
    }
1349
1350
    /**
1351
     * Returns statistics about the stories and topics
1352
     * @param $limit
1353
     * @return array
1354
     */
1355
    public function getStats($limit)
1356
    {
1357
        $ret  = [];
1358
        $db   = XoopsDatabaseFactory::getDatabaseConnection();
1359
        $tbls = $db->prefix('news_stories');
1360
        $tblt = $db->prefix('news_topics');
1361
        $tblf = $db->prefix('news_stories_files');
1362
1363
        $db = XoopsDatabaseFactory::getDatabaseConnection();
1364
        // Number of stories per topic, including expired and non published stories
1365
        $ret2   = [];
1366
        $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";
1367
        $result = $db->query($sql);
1368
        while ($myrow = $db->fetchArray($result)) {
1369
            $ret2[$myrow['topicid']] = $myrow;
1370
        }
1371
        $ret['storiespertopic'] = $ret2;
1372
        unset($ret2);
1373
1374
        // Total of reads per topic
1375
        $ret2   = [];
1376
        $sql    = "SELECT Sum(counter) as cpt, topicid FROM $tbls GROUP BY topicid ORDER BY topicid";
1377
        $result = $db->query($sql);
1378
        while ($myrow = $db->fetchArray($result)) {
1379
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1380
        }
1381
        $ret['readspertopic'] = $ret2;
1382
        unset($ret2);
1383
1384
        // Attached files per topic
1385
        $ret2   = [];
1386
        $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";
1387
        $result = $db->query($sql);
1388
        while ($myrow = $db->fetchArray($result)) {
1389
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1390
        }
1391
        $ret['filespertopic'] = $ret2;
1392
        unset($ret2);
1393
1394
        // Expired articles per topic
1395
        $ret2   = [];
1396
        $sql    = "SELECT Count(storyid) as cpt, topicid FROM $tbls WHERE expired>0 AND expired<=" . time() . ' GROUP BY topicid ORDER BY topicid';
1397
        $result = $db->query($sql);
1398
        while ($myrow = $db->fetchArray($result)) {
1399
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1400
        }
1401
        $ret['expiredpertopic'] = $ret2;
1402
        unset($ret2);
1403
1404
        // Number of unique authors per topic
1405
        $ret2   = [];
1406
        $sql    = "SELECT Count(Distinct(uid)) as cpt, topicid FROM $tbls GROUP BY topicid ORDER BY topicid";
1407
        $result = $db->query($sql);
1408
        while ($myrow = $db->fetchArray($result)) {
1409
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1410
        }
1411
        $ret['authorspertopic'] = $ret2;
1412
        unset($ret2);
1413
1414
        // Most readed articles
1415
        $ret2   = [];
1416
        $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";
1417
        $result = $db->query($sql, (int)$limit);
1418
        while ($myrow = $db->fetchArray($result)) {
1419
            $ret2[$myrow['storyid']] = $myrow;
1420
        }
1421
        $ret['mostreadednews'] = $ret2;
1422
        unset($ret2);
1423
1424
        // Less readed articles
1425
        $ret2   = [];
1426
        $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";
1427
        $result = $db->query($sql, (int)$limit);
1428
        while ($myrow = $db->fetchArray($result)) {
1429
            $ret2[$myrow['storyid']] = $myrow;
1430
        }
1431
        $ret['lessreadednews'] = $ret2;
1432
        unset($ret2);
1433
1434
        // Best rated articles
1435
        $ret2   = [];
1436
        $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";
1437
        $result = $db->query($sql, (int)$limit);
1438
        while ($myrow = $db->fetchArray($result)) {
1439
            $ret2[$myrow['storyid']] = $myrow;
1440
        }
1441
        $ret['besratednews'] = $ret2;
1442
        unset($ret2);
1443
1444
        // Most readed authors
1445
        $ret2   = [];
1446
        $sql    = "SELECT Sum(counter) as cpt, uid FROM $tbls GROUP BY uid ORDER BY cpt DESC";
1447
        $result = $db->query($sql, (int)$limit);
1448
        while ($myrow = $db->fetchArray($result)) {
1449
            $ret2[$myrow['uid']] = $myrow['cpt'];
1450
        }
1451
        $ret['mostreadedauthors'] = $ret2;
1452
        unset($ret2);
1453
1454
        // Best rated authors
1455
        $ret2   = [];
1456
        $sql    = "SELECT Avg(rating) as cpt, uid FROM $tbls WHERE votes > 0 GROUP BY uid ORDER BY cpt DESC";
1457
        $result = $db->query($sql, (int)$limit);
1458
        while ($myrow = $db->fetchArray($result)) {
1459
            $ret2[$myrow['uid']] = $myrow['cpt'];
1460
        }
1461
        $ret['bestratedauthors'] = $ret2;
1462
        unset($ret2);
1463
1464
        // Biggest contributors
1465
        $ret2   = [];
1466
        $sql    = "SELECT Count(*) as cpt, uid FROM $tbls GROUP BY uid ORDER BY cpt DESC";
1467
        $result = $db->query($sql, (int)$limit);
1468
        while ($myrow = $db->fetchArray($result)) {
1469
            $ret2[$myrow['uid']] = $myrow['cpt'];
1470
        }
1471
        $ret['biggestcontributors'] = $ret2;
1472
        unset($ret2);
1473
1474
        return $ret;
1475
    }
1476
1477
    /**
1478
     * Get the date of the older and most recent news
1479
     * @param $older
1480
     * @param $recent
1481
     */
1482
    public function getOlderRecentNews(&$older, &$recent)
1483
    {
1484
        $db     = XoopsDatabaseFactory::getDatabaseConnection();
1485
        $sql    = 'SELECT min(published) AS minpublish, max(published) AS maxpublish FROM ' . $db->prefix('news_stories');
1486
        $result = $db->query($sql);
1487
        if (!$result) {
1488
            $older = $recent = 0;
1489
        } else {
1490
            list($older, $recent) = $this->db->fetchRow($result);
1491
        }
1492
    }
1493
1494
    /*
1495
     * Returns the author's IDs for the Who's who page
1496
     */
1497
    /**
1498
     * @param bool $checkRight
1499
     * @param int  $limit
1500
     * @param int  $start
1501
     *
1502
     * @return array|null
1503
     */
1504
    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...
1505
    {
1506
        $db  = XoopsDatabaseFactory::getDatabaseConnection();
1507
        $ret = [];
1508
        $sql = 'SELECT DISTINCT(uid) AS uid FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . time() . ') AND (expired = 0 OR expired > ' . time() . ')';
1509
        if ($checkRight) {
1510
            $topics = NewsUtility::getMyItemIds('news_view');
1511
            if (count($topics) > 0) {
1512
                $topics = implode(',', $topics);
1513
                $sql    .= ' AND topicid IN (' . $topics . ')';
1514
            } else {
1515
                return null;
1516
            }
1517
        }
1518
        $sql    .= ' ORDER BY uid';
1519
        $result = $db->query($sql);
1520
        while ($myrow = $db->fetchArray($result)) {
1521
            $ret[] = $myrow['uid'];
1522
        }
1523
1524
        return $ret;
1525
    }
1526
1527
    /**
1528
     * Returns the content of the summary and the titles requires for the list selector
1529
     * @param $text
1530
     * @param $titles
1531
     * @return string
1532
     */
1533
    public function auto_summary($text, &$titles)
1534
    {
1535
        $auto_summary = '';
1536
        if (NewsUtility::getModuleOption('enhanced_pagenav')) {
1537
            $expr_matches = [];
1538
            $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...
1539
            if (count($expr_matches) > 0) {
1540
                $delimiters  = $expr_matches[0];
1541
                $arr_search  = ['[pagebreak:', '[pagebreak', ']'];
1542
                $arr_replace = ['', '', ''];
1543
                $cpt         = 1;
1544
                if (isset($titles) && is_array($titles)) {
1545
                    $titles[] = strip_tags(sprintf(_NW_PAGE_AUTO_SUMMARY, 1, $this->title()));
1546
                }
1547
                $item         = "<a href='" . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . "&page=0'>" . sprintf(_NW_PAGE_AUTO_SUMMARY, 1, $this->title()) . '</a><br>';
1548
                $auto_summary .= $item;
1549
1550
                foreach ($delimiters as $item) {
1551
                    ++$cpt;
1552
                    $item = str_replace($arr_search, $arr_replace, $item);
1553
                    if ('' == xoops_trim($item)) {
1554
                        $item = $cpt;
1555
                    }
1556
                    $titles[]     = strip_tags(sprintf(_NW_PAGE_AUTO_SUMMARY, $cpt, $item));
1557
                    $item         = "<a href='" . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '&page=' . ($cpt - 1) . "'>" . sprintf(_NW_PAGE_AUTO_SUMMARY, $cpt, $item) . '</a><br>';
1558
                    $auto_summary .= $item;
1559
                }
1560
            }
1561
        }
1562
1563
        return $auto_summary;
1564
    }
1565
1566
    /**
1567
     * @param string $format
1568
     *
1569
     * @return mixed
1570
     */
1571 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...
1572
    {
1573
        $myts = MyTextSanitizer::getInstance();
1574
        $html = $smiley = $xcodes = 1;
1575
        if ($this->nohtml()) {
1576
            $html = 0;
1577
        }
1578
        if ($this->nosmiley()) {
1579
            $smiley = 0;
1580
        }
1581
        switch ($format) {
1582
            case 'Show':
1583
                $hometext     = $myts->displayTarea($this->hometext, $html, $smiley, $xcodes);
1584
                $tmp          = '';
1585
                $auto_summary = $this->auto_summary($this->bodytext('Show'), $tmp);
1586
                $hometext     = str_replace('[summary]', $auto_summary, $hometext);
1587
                break;
1588
            case 'Edit':
1589
                $hometext = $myts->htmlSpecialChars($this->hometext);
1590
                break;
1591
            case 'Preview':
1592
                $hometext = $myts->previewTarea($this->hometext, $html, $smiley, $xcodes);
1593
                break;
1594
            case 'InForm':
1595
                $hometext = $myts->stripSlashesGPC($this->hometext);
1596
                $hometext = $myts->htmlSpecialChars($hometext);
1597
                break;
1598
        }
1599
1600
        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...
1601
    }
1602
1603
    /**
1604
     * @param string $format
1605
     *
1606
     * @return mixed
1607
     */
1608 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...
1609
    {
1610
        $myts   = MyTextSanitizer::getInstance();
1611
        $html   = 1;
1612
        $smiley = 1;
1613
        $xcodes = 1;
1614
        if ($this->nohtml()) {
1615
            $html = 0;
1616
        }
1617
        if ($this->nosmiley()) {
1618
            $smiley = 0;
1619
        }
1620
        switch ($format) {
1621
            case 'Show':
1622
                $bodytext     = $myts->displayTarea($this->bodytext, $html, $smiley, $xcodes);
1623
                $tmp          = '';
1624
                $auto_summary = $this->auto_summary($bodytext, $tmp);
1625
                $bodytext     = str_replace('[summary]', $auto_summary, $bodytext);
1626
                break;
1627
            case 'Edit':
1628
                $bodytext = $myts->htmlSpecialChars($this->bodytext);
1629
                break;
1630
            case 'Preview':
1631
                $bodytext = $myts->previewTarea($this->bodytext, $html, $smiley, $xcodes);
1632
                break;
1633
            case 'InForm':
1634
                $bodytext = $myts->stripSlashesGPC($this->bodytext);
1635
                $bodytext = $myts->htmlSpecialChars($bodytext);
1636
                break;
1637
        }
1638
1639
        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...
1640
    }
1641
1642
    /**
1643
     * Returns stories by Ids
1644
     * @param             $ids
1645
     * @param  bool       $checkRight
1646
     * @param  bool       $asobject
1647
     * @param  string     $order
1648
     * @param  bool       $onlyOnline
1649
     * @return array|null
1650
     */
1651
    public function getStoriesByIds(
1652
        $ids,
1653
        $checkRight = true,
1654
        $asobject = true,
1655
        $order = 'published',
1656
        $onlyOnline = true
1657
    ) {
1658
        $limit = $start = 0;
1659
        $db    = XoopsDatabaseFactory::getDatabaseConnection();
1660
        $myts  = MyTextSanitizer::getInstance();
1661
        $ret   = [];
1662
        $sql   = 'SELECT s.*, t.* FROM ' . $db->prefix('news_stories') . ' s, ' . $db->prefix('news_topics') . ' t WHERE ';
1663
        if (is_array($ids) && count($ids) > 0) {
1664
            array_walk($ids, 'intval');
1665
        }
1666
        $sql .= ' s.storyid IN (' . implode(',', $ids) . ') ';
1667
1668
        if ($onlyOnline) {
1669
            $sql .= ' AND (s.published > 0 AND s.published <= ' . time() . ') AND (s.expired = 0 OR s.expired > ' . time() . ') ';
1670
        }
1671
        $sql .= ' AND (s.topicid=t.topic_id) ';
1672
        if ($checkRight) {
1673
            $topics = NewsUtility::getMyItemIds('news_view');
1674
            if (count($topics) > 0) {
1675
                $topics = implode(',', $topics);
1676
                $sql    .= ' AND s.topicid IN (' . $topics . ')';
1677
            } else {
1678
                return null;
1679
            }
1680
        }
1681
        $sql    .= " ORDER BY s.$order DESC";
1682
        $result = $db->query($sql, $limit, $start);
1683
1684 View Code Duplication
        while ($myrow = $db->fetchArray($result)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1685
            if ($asobject) {
1686
                $ret[$myrow['storyid']] = new NewsStory($myrow);
1687
            } else {
1688
                $ret[$myrow['storyid']] = $myts->htmlSpecialChars($myrow['title']);
1689
            }
1690
        }
1691
1692
        return $ret;
1693
    }
1694
}
1695
1696
/**
1697
 * Class news_NewsStoryHandler
1698
 */
1699
class news_NewsStoryHandler extends XoopsPersistableObjectHandler
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

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

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

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

namespace YourVendor;

class YourClass { }

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

Loading history...
1700
{
1701
    /**
1702
     * @param null|XoopsDatabase $db
1703
     */
1704
    public function __construct(XoopsDatabase $db)
1705
    {
1706
        parent::__construct($db, 'news_stories', 'stories', 'storieid', 'title');
1707
    }
1708
}
1709