Passed
Push — master ( 6d0bec...700d12 )
by Michael
05:09 queued 02:42
created

NewsStory   F

Complexity

Total Complexity 233

Size/Duplication

Total Lines 1668
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 1
Metric Value
wmc 233
eloc 907
c 2
b 1
f 1
dl 0
loc 1668
rs 1.693

46 Methods

Rating   Name   Duplication   Size   Complexity  
A keywords() 0 17 5
A textlink() 0 5 1
F prepare2show() 0 127 21
A description() 0 17 5
C getRandomNews() 0 69 15
B deleteBeforeDate() 0 34 6
A __construct() 0 10 3
A getStory() 0 7 1
B getAllSubmitted() 0 31 6
B getAllPublishedByAuthor() 0 69 7
A subtitle() 0 3 1
B getBigStory() 0 49 9
C getAllPublished() 0 66 13
B getStoriesByIds() 0 43 8
B hometext() 0 30 7
B bodytext() 0 31 7
A getPreviousArticle() 0 3 1
A getAllAutoStory() 0 17 3
A imglink() 0 9 3
A rating() 0 3 1
A votes() 0 3 1
F store() 0 101 15
A getByTopic() 0 12 2
B auto_summary() 0 31 7
A pictureinfo() 0 3 1
A setPictureinfo() 0 3 1
A setDescription() 0 3 1
A getAllExpired() 0 24 5
F getStats() 0 119 12
A picture() 0 3 1
B exportNews() 0 41 7
A setPicture() 0 3 1
A setSubtitle() 0 3 1
B uname() 0 46 10
A getArchive() 0 33 5
B getAllStoriesCount() 0 32 7
A topic_title() 0 21 5
A adminlink() 0 33 1
A setKeywords() 0 3 1
A getOlderRecentNews() 0 10 2
A getWhosWho() 0 22 4
A getCountStoriesPublishedBefore() 0 15 3
A getNextArticle() 0 3 1
A topic_imgurl() 0 22 6
A countPublishedByTopic() 0 23 4
B _searchPreviousOrNextArticle() 0 32 6

How to fix   Complexity   

Complex Class

Complex classes like NewsStory often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use NewsStory, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace XoopsModules\News;
4
5
/*
6
 * You may not change or alter any portion of this comment or credits
7
 * of supporting developers from this source code or any supporting source code
8
 * which is considered copyrighted (c) material of the original comment or credit authors.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/**
16
 * @copyright      {@link https://xoops.org/ XOOPS Project}
17
 * @license        {@link https://www.gnu.org/licenses/gpl-2.0.html GNU GPL 2 or later}
18
 * @package
19
 * @since
20
 * @author         XOOPS Development Team
21
 */
22
23
use XoopsModules\News;
24
25
//require_once XOOPS_ROOT_PATH . '/modules/news/class/xoopsstory.php';
26
require_once XOOPS_ROOT_PATH . '/include/comment_constants.php';
27
28
require_once \dirname(__DIR__) . '/preloads/autoloader.php';
29
30
/** @var News\Helper $helper */
31
$helper = News\Helper::getInstance();
32
$helper->loadLanguage('main');
33
34
/**
35
 * Class NewsStory
36
 */
37
class NewsStory extends XoopsStory
38
{
39
    public $newstopic; // XoopsTopic object
40
    public $rating; // News rating
41
    public $votes; // Number of votes
42
    public $description; // META, desciption
43
    public $keywords; // META, keywords
44
    public $picture;
45
    public $topic_imgurl;
46
    public $topic_title;
47
    public $subtitle;
48
    public $pictureinfo;
49
50
    /**
51
     * Constructor
52
     * @param int $storyid
53
     */
54
    public function __construct($storyid = -1)
55
    {
56
        /** @var \XoopsMySQLDatabase $this ->db */
57
        $this->db          = \XoopsDatabaseFactory::getDatabaseConnection();
0 ignored issues
show
Bug introduced by
The property db does not seem to exist on XoopsMySQLDatabase.
Loading history...
58
        $this->table       = $this->db->prefix('news_stories');
0 ignored issues
show
Bug introduced by
The property table does not seem to exist on XoopsMySQLDatabase.
Loading history...
59
        $this->topicstable = $this->db->prefix('news_topics');
0 ignored issues
show
Bug introduced by
The property topicstable does not seem to exist on XoopsMySQLDatabase.
Loading history...
60
        if (\is_array($storyid)) {
61
            $this->makeStory($storyid);
0 ignored issues
show
Bug introduced by
The method makeStory() does not exist on XoopsMySQLDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

61
            $this->/** @scrutinizer ignore-call */ 
62
                   makeStory($storyid);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
62
        } elseif (-1 != $storyid) {
63
            $this->getStory((int)$storyid);
0 ignored issues
show
Bug introduced by
The method getStory() does not exist on XoopsMySQLDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

63
            $this->/** @scrutinizer ignore-call */ 
64
                   getStory((int)$storyid);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
64
        }
65
    }
66
67
    /**
68
     * Returns the number of stories published before a date
69
     * @param         $timestamp
70
     * @param         $expired
71
     * @param string  $topicslist
72
     * @return mixed
73
     */
74
    public function getCountStoriesPublishedBefore($timestamp, $expired, $topicslist = '')
75
    {
76
        /** @var \XoopsMySQLDatabase $db */
77
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
78
        $sql = 'SELECT count(*) AS cpt FROM ' . $db->prefix('news_stories') . ' WHERE published <=' . $timestamp;
79
        if ($expired) {
80
            $sql .= ' AND (expired>0 AND expired<=' . \time() . ')';
81
        }
82
        if ('' !== \trim($topicslist)) {
83
            $sql .= ' AND topicid IN (' . $topicslist . ')';
84
        }
85
        $result = $db->query($sql);
86
        [$count] = $db->fetchRow($result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
        [$count] = $db->fetchRow(/** @scrutinizer ignore-type */ $result);
Loading history...
87
88
        return $count;
89
    }
90
91
    /**
92
     * Load the specified story from the database
93
     * @param $storyid
94
     */
95
    public function getStory($storyid)
96
    {
97
        /** @var \XoopsMySQLDatabase $db */
98
        $db    = \XoopsDatabaseFactory::getDatabaseConnection();
99
        $sql   = 'SELECT s.*, t.* FROM ' . $this->table . ' s, ' . $db->prefix('news_topics') . ' t WHERE (storyid=' . (int)$storyid . ') AND (s.topicid=t.topic_id)';
100
        $array = $db->fetchArray($db->query($sql));
0 ignored issues
show
Bug introduced by
It seems like $db->query($sql) can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

100
        $array = $db->fetchArray(/** @scrutinizer ignore-type */ $db->query($sql));
Loading history...
101
        $this->makeStory($array);
102
    }
103
104
    /**
105
     * Delete stories that were published before a given date
106
     * @param         $timestamp
107
     * @param         $expired
108
     * @param string  $topicslist
109
     * @return bool
110
     */
111
    public function deleteBeforeDate($timestamp, $expired, $topicslist = '')
112
    {
113
        global $xoopsModule;
114
        /** @var \XoopsMySQLDatabase $db */
115
        $db           = \XoopsDatabaseFactory::getDatabaseConnection();
116
        $mid          = $xoopsModule->getVar('mid');
117
        $prefix       = $db->prefix('news_stories');
118
        $vote_prefix  = $db->prefix('news_stories_votedata');
119
        $files_prefix = $db->prefix('news_stories_files');
120
        $sql          = 'SELECT storyid FROM  ' . $prefix . ' WHERE published <=' . $timestamp;
121
        if ($expired) {
122
            $sql .= ' (AND expired>0 AND expired<=' . \time() . ')';
123
        }
124
        if ('' !== \trim($topicslist)) {
125
            $sql .= ' AND topicid IN (' . $topicslist . ')';
126
        }
127
        $result = $db->query($sql);
128
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

128
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
129
            \xoops_comment_delete($mid, $myrow['storyid']); // Delete comments
130
            \xoops_notification_deletebyitem($mid, 'story', $myrow['storyid']); // Delete notifications
131
            $db->queryF('DELETE FROM ' . $vote_prefix . ' WHERE storyid=' . $myrow['storyid']); // Delete votes
132
            // Remove files and records related to the files
133
            $result2 = $db->query('SELECT * FROM ' . $files_prefix . ' WHERE storyid=' . $myrow['storyid']);
134
            while (false !== ($myrow2 = $db->fetchArray($result2))) {
135
                $name = XOOPS_ROOT_PATH . '/uploads/' . $myrow2['downloadname'];
136
                if (\is_file($name)) {
137
                    \unlink($name);
138
                }
139
                $db->query('DELETE FROM ' . $files_prefix . ' WHERE fileid=' . $myrow2['fileid']);
140
            }
141
            $db->queryF('DELETE FROM ' . $prefix . ' WHERE storyid=' . $myrow['storyid']); // Delete the story
142
        }
143
144
        return true;
145
    }
146
147
    /**
148
     * @param      $storyid
149
     * @param bool $next
150
     * @param bool $checkRight
151
     *
152
     * @return array
153
     */
154
    public function _searchPreviousOrNextArticle($storyid, $next = true, $checkRight = false)
155
    {
156
        /** @var \XoopsMySQLDatabase $db */
157
        $db      = \XoopsDatabaseFactory::getDatabaseConnection();
158
        $ret     = [];
159
        $storyid = (int)$storyid;
160
        if ($next) {
161
            $sql     = 'SELECT storyid, title FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . \time() . ') AND (expired = 0 OR expired > ' . \time() . ') AND storyid > ' . $storyid;
162
            $orderBy = ' ORDER BY storyid ASC';
163
        } else {
164
            $sql     = 'SELECT storyid, title FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . \time() . ') AND (expired = 0 OR expired > ' . \time() . ') AND storyid < ' . $storyid;
165
            $orderBy = ' ORDER BY storyid DESC';
166
        }
167
        if ($checkRight) {
168
            $topics = News\Utility::getMyItemIds('news_view');
169
            if (\count($topics) > 0) {
170
                $sql .= ' AND topicid IN (' . \implode(',', $topics) . ')';
171
            } else {
172
                return null;
173
            }
174
        }
175
        $sql .= $orderBy;
176
177
        $result = $db->query($sql, 1);
178
        if ($result) {
179
            $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
180
            while (false !== ($row = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type true; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

180
            while (false !== ($row = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
181
                $ret = ['storyid' => $row['storyid'], 'title' => htmlspecialchars($row['title'], ENT_QUOTES | ENT_HTML5)];
182
            }
183
        }
184
185
        return $ret;
186
    }
187
188
    /**
189
     * @param int  $storyid
190
     * @param bool $checkRight
191
     *
192
     * @return null|array
193
     */
194
    public function getNextArticle($storyid, $checkRight = false)
195
    {
196
        return $this->_searchPreviousOrNextArticle($storyid, true, $checkRight);
197
    }
198
199
    /**
200
     * @param      $storyid
201
     * @param bool $checkRight
202
     *
203
     * @return array
204
     */
205
    public function getPreviousArticle($storyid, $checkRight = false)
206
    {
207
        return $this->_searchPreviousOrNextArticle($storyid, false, $checkRight);
208
    }
209
210
    /**
211
     * Returns published stories according to some options
212
     * @param int    $limit
213
     * @param int    $start
214
     * @param bool   $checkRight
215
     * @param int    $topic
216
     * @param int    $ihome
217
     * @param bool   $asobject
218
     * @param string $order
219
     * @param bool   $topic_frontpage
220
     * @return array
221
     */
222
    public static function getAllPublished(
223
        $limit = 0,
224
        $start = 0,
225
        $checkRight = false,
226
        $topic = 0,
227
        $ihome = 0,
228
        $asobject = true,
229
        $order = 'published',
230
        $topic_frontpage = false
231
    ) {
232
        /** @var \XoopsMySQLDatabase $db */
233
        $db   = \XoopsDatabaseFactory::getDatabaseConnection();
234
        $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
235
        $ret  = [];
236
        $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) ';
237
        if (0 != $topic) {
238
            if (!\is_array($topic)) {
0 ignored issues
show
introduced by
The condition is_array($topic) is always false.
Loading history...
239
                if ($checkRight) {
240
                    $topics = News\Utility::getMyItemIds('news_view');
241
                    if (!\in_array($topic, $topics)) {
242
                        return null;
243
                    }
244
                    $sql .= ' AND s.topicid=' . (int)$topic . ' AND (s.ihome=1 OR s.ihome=0)';
245
                } else {
246
                    $sql .= ' AND s.topicid=' . (int)$topic . ' AND (s.ihome=1 OR s.ihome=0)';
247
                }
248
            } else {
249
                if ($checkRight) {
250
                    $topics = News\Utility::getMyItemIds('news_view');
251
                    $topic  = \array_intersect($topic, $topics);
252
                }
253
                if (\count($topic) > 0) {
254
                    $sql .= ' AND s.topicid IN (' . \implode(',', $topic) . ')';
255
                } else {
256
                    return null;
257
                }
258
            }
259
        } else {
260
            if ($checkRight) {
261
                $topics = News\Utility::getMyItemIds('news_view');
262
                if (\count($topics) > 0) {
263
                    $topics = \implode(',', $topics);
264
                    $sql    .= ' AND s.topicid IN (' . $topics . ')';
265
                } else {
266
                    return null;
267
                }
268
            }
269
            if (0 == (int)$ihome) {
270
                $sql .= ' AND s.ihome=0';
271
            }
272
        }
273
        if ($topic_frontpage) {
274
            $sql .= ' AND t.topic_frontpage=1';
275
        }
276
        $sql    .= " ORDER BY s.$order DESC";
277
        $result = $db->query($sql, (int)$limit, (int)$start);
278
279
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

279
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
280
            if ($asobject) {
281
                $ret[] = new self($myrow);
0 ignored issues
show
Bug introduced by
$myrow of type array is incompatible with the type integer expected by parameter $storyid of XoopsModules\News\NewsStory::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

281
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
282
            } else {
283
                $ret[$myrow['storyid']] = htmlspecialchars($myrow['title'], ENT_QUOTES | ENT_HTML5);
284
            }
285
        }
286
287
        return $ret;
288
    }
289
290
    /**
291
     * Retourne la liste des articles aux archives (pour une p�riode donn�e)
292
     * @param             $publish_start
293
     * @param             $publish_end
294
     * @param bool        $checkRight
295
     * @param bool        $asobject
296
     * @param string      $order
297
     * @return array|null
298
     */
299
    public function getArchive(
300
        $publish_start,
301
        $publish_end,
302
        $checkRight = false,
303
        $asobject = true,
304
        $order = 'published'
305
    ) {
306
        /** @var \XoopsMySQLDatabase $db */
307
        $db   = \XoopsDatabaseFactory::getDatabaseConnection();
308
        $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
309
        $ret  = [];
310
        $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() . ') ';
311
312
        if ($checkRight) {
313
            $topics = News\Utility::getMyItemIds('news_view');
314
            if (\count($topics) > 0) {
315
                $topics = \implode(',', $topics);
316
                $sql    .= ' AND topicid IN (' . $topics . ')';
317
            } else {
318
                return null;
319
            }
320
        }
321
        $sql    .= " ORDER BY $order DESC";
322
        $result = $db->query($sql);
323
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

323
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
324
            if ($asobject) {
325
                $ret[] = new self($myrow);
0 ignored issues
show
Bug introduced by
$myrow of type array is incompatible with the type integer expected by parameter $storyid of XoopsModules\News\NewsStory::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

325
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
326
            } else {
327
                $ret[$myrow['storyid']] = htmlspecialchars($myrow['title'], ENT_QUOTES | ENT_HTML5);
328
            }
329
        }
330
331
        return $ret;
332
    }
333
334
    /**
335
     * Get the today's most readed article
336
     *
337
     * @param int    $limit      records limit
338
     * @param int    $start      starting record
339
     * @param bool   $checkRight Do we need to check permissions (by topics) ?
340
     * @param int    $topic      limit the job to one topic
341
     * @param int    $ihome      Limit to articles published in home page only ?
342
     * @param bool   $asobject   Do we have to return an array of objects or a simple array ?
343
     * @param string $order      Fields to sort on
344
     *
345
     * @return array
346
     */
347
    public function getBigStory(
348
        $limit = 0,
349
        $start = 0,
350
        $checkRight = false,
351
        $topic = 0,
352
        $ihome = 0,
353
        $asobject = true,
354
        $order = 'counter'
355
    ) {
356
        /** @var \XoopsMySQLDatabase $db */
357
        $db    = \XoopsDatabaseFactory::getDatabaseConnection();
358
        $myts  = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
359
        $ret   = [];
360
        $tdate = \mktime(0, 0, 0, \date('n'), \date('j'), \date('Y'));
0 ignored issues
show
Bug introduced by
date('Y') of type string is incompatible with the type integer expected by parameter $year of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

360
        $tdate = \mktime(0, 0, 0, \date('n'), \date('j'), /** @scrutinizer ignore-type */ \date('Y'));
Loading history...
Bug introduced by
date('n') of type string is incompatible with the type integer expected by parameter $month of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

360
        $tdate = \mktime(0, 0, 0, /** @scrutinizer ignore-type */ \date('n'), \date('j'), \date('Y'));
Loading history...
Bug introduced by
date('j') of type string is incompatible with the type integer expected by parameter $day of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

360
        $tdate = \mktime(0, 0, 0, \date('n'), /** @scrutinizer ignore-type */ \date('j'), \date('Y'));
Loading history...
361
        $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) ';
362
363
        if (0 != (int)$topic) {
364
            if (!\is_array($topic)) {
0 ignored issues
show
introduced by
The condition is_array($topic) is always false.
Loading history...
365
                $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
366
            } elseif (\count($topic) > 0) {
367
                $sql .= ' AND topicid IN (' . \implode(',', $topic) . ')';
368
            } else {
369
                return null;
370
            }
371
        } else {
372
            if ($checkRight) {
373
                $topics = News\Utility::getMyItemIds('news_view');
374
                if (\count($topics) > 0) {
375
                    $topics = \implode(',', $topics);
376
                    $sql    .= ' AND topicid IN (' . $topics . ')';
377
                } else {
378
                    return null;
379
                }
380
            }
381
            if (0 == (int)$ihome) {
382
                $sql .= ' AND ihome=0';
383
            }
384
        }
385
        $sql    .= " ORDER BY $order DESC";
386
        $result = $db->query($sql, (int)$limit, (int)$start);
387
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

387
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
388
            if ($asobject) {
389
                $ret[] = new self($myrow);
0 ignored issues
show
Bug introduced by
$myrow of type array is incompatible with the type integer expected by parameter $storyid of XoopsModules\News\NewsStory::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

389
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
390
            } else {
391
                $ret[$myrow['storyid']] = htmlspecialchars($myrow['title'], ENT_QUOTES | ENT_HTML5);
392
            }
393
        }
394
395
        return $ret;
396
    }
397
398
    /**
399
     * Get all articles published by an author
400
     *
401
     * @param int  $uid        author's id
402
     * @param bool $checkRight whether to check the user's rights to topics
403
     *
404
     * @param bool $asobject
405
     *
406
     * @return array
407
     */
408
    public function getAllPublishedByAuthor($uid, $checkRight = false, $asobject = true)
409
    {
410
        /** @var \XoopsMySQLDatabase $db */
411
        $db        = \XoopsDatabaseFactory::getDatabaseConnection();
412
        $myts      = \MyTextSanitizer::getInstance();
413
        $ret       = [];
414
        $tblstory  = $db->prefix('news_stories');
415
        $tbltopics = $db->prefix('news_topics');
416
417
        $sql = 'SELECT '
418
               . $tblstory
419
               . '.*, '
420
               . $tbltopics
421
               . '.topic_title, '
422
               . $tbltopics
423
               . '.topic_color FROM '
424
               . $tblstory
425
               . ','
426
               . $tbltopics
427
               . ' WHERE ('
428
               . $tblstory
429
               . '.topicid='
430
               . $tbltopics
431
               . '.topic_id) AND (published > 0 AND published <= '
432
               . \time()
433
               . ') AND (expired = 0 OR expired > '
434
               . \time()
435
               . ')';
436
        $sql .= ' AND uid=' . (int)$uid;
437
        if ($checkRight) {
438
            $topics = News\Utility::getMyItemIds('news_view');
439
            $topics = \implode(',', $topics);
440
            if ('' !== \xoops_trim($topics)) {
441
                $sql .= ' AND topicid IN (' . $topics . ')';
442
            }
443
        }
444
        $sql    .= ' ORDER BY ' . $tbltopics . '.topic_title ASC, ' . $tblstory . '.published DESC';
445
        $result = $db->query($sql);
446
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

446
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
447
            if ($asobject) {
448
                $ret[] = new self($myrow);
0 ignored issues
show
Bug introduced by
$myrow of type array is incompatible with the type integer expected by parameter $storyid of XoopsModules\News\NewsStory::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

448
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
449
            } else {
450
                if ($myrow['nohtml']) {
451
                    $html = 0;
452
                } else {
453
                    $html = 1;
454
                }
455
                if ($myrow['nosmiley']) {
456
                    $smiley = 0;
457
                } else {
458
                    $smiley = 1;
459
                }
460
                $ret[$myrow['storyid']] = [
461
                    'title'       => $myts->displayTarea($myrow['title'], $html, $smiley, 1),
462
                    'topicid'     => (int)$myrow['topicid'],
463
                    'storyid'     => (int)$myrow['storyid'],
464
                    'hometext'    => $myts->displayTarea($myrow['hometext'], $html, $smiley, 1),
465
                    'counter'     => (int)$myrow['counter'],
466
                    'created'     => (int)$myrow['created'],
467
                    'topic_title' => $myts->displayTarea($myrow['topic_title'], $html, $smiley, 1),
468
                    'topic_color' => $myts->displayTarea($myrow['topic_color']),
469
                    'published'   => (int)$myrow['published'],
470
                    'rating'      => (float)$myrow['rating'],
471
                    'votes'       => (int)$myrow['votes'],
472
                ];
473
            }
474
        }
475
476
        return $ret;
477
    }
478
479
    /**
480
     * Get all expired stories
481
     * @param int  $limit
482
     * @param int  $start
483
     * @param int  $topic
484
     * @param int  $ihome
485
     * @param bool $asobject
486
     * @return array
487
     */
488
    public static function getAllExpired($limit = 0, $start = 0, $topic = 0, $ihome = 0, $asobject = true)
489
    {
490
        /** @var \XoopsMySQLDatabase $db */
491
        $db   = \XoopsDatabaseFactory::getDatabaseConnection();
492
        $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
493
        $ret  = [];
494
        $sql  = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE expired <= ' . \time() . ' AND expired > 0';
495
        if (!empty($topic)) {
496
            $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
497
        } elseif (0 == (int)$ihome) {
498
            $sql .= ' AND ihome=0';
499
        }
500
501
        $sql    .= ' ORDER BY expired DESC';
502
        $result = $db->query($sql, (int)$limit, (int)$start);
503
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

503
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
504
            if ($asobject) {
505
                $ret[] = new self($myrow);
0 ignored issues
show
Bug introduced by
$myrow of type array is incompatible with the type integer expected by parameter $storyid of XoopsModules\News\NewsStory::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

505
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
506
            } else {
507
                $ret[$myrow['storyid']] = htmlspecialchars($myrow['title'], ENT_QUOTES | ENT_HTML5);
508
            }
509
        }
510
511
        return $ret;
512
    }
513
514
    /**
515
     * Returns an array of object containing all the news to be automatically published.
516
     * @param int  $limit
517
     * @param bool $asobject
518
     * @param int  $start
519
     * @return array
520
     */
521
    public static function getAllAutoStory($limit = 0, $asobject = true, $start = 0)
522
    {
523
        /** @var \XoopsMySQLDatabase $db */
524
        $db     = \XoopsDatabaseFactory::getDatabaseConnection();
525
        $myts   = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
526
        $ret    = [];
527
        $sql    = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE published > ' . \time() . ' ORDER BY published ASC';
528
        $result = $db->query($sql, (int)$limit, (int)$start);
529
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

529
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
530
            if ($asobject) {
531
                $ret[] = new self($myrow);
0 ignored issues
show
Bug introduced by
$myrow of type array is incompatible with the type integer expected by parameter $storyid of XoopsModules\News\NewsStory::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

531
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
532
            } else {
533
                $ret[$myrow['storyid']] = htmlspecialchars($myrow['title'], ENT_QUOTES | ENT_HTML5);
534
            }
535
        }
536
537
        return $ret;
538
    }
539
540
    /**
541
     * Get all submitted stories awaiting approval
542
     *
543
     * @param int  $limit      Denotes where to start the query
544
     * @param bool $asobject   true will returns the stories as an array of objects, false will return storyid => title
545
     * @param bool $checkRight whether to check the user's rights to topics
546
     *
547
     * @param int  $start
548
     *
549
     * @return array
550
     */
551
    public static function getAllSubmitted($limit = 0, $asobject = true, $checkRight = false, $start = 0)
552
    {
553
        /** @var \XoopsMySQLDatabase $db */
554
        $db       = \XoopsDatabaseFactory::getDatabaseConnection();
555
        $myts     = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
556
        $ret      = [];
557
        $criteria = new \CriteriaCompo(new \Criteria('published', 0));
558
        if ($checkRight) {
559
            global $xoopsUser;
560
            if (!\is_object($xoopsUser)) {
561
                return $ret;
562
            }
563
            $allowedtopics = News\Utility::getMyItemIds('news_approve');
564
            $criteria2     = new \CriteriaCompo();
565
            foreach ($allowedtopics as $key => $topicid) {
566
                $criteria2->add(new \Criteria('topicid', $topicid), 'OR');
567
            }
568
            $criteria->add($criteria2);
569
        }
570
        $sql    = 'SELECT s.*, t.* FROM ' . $db->prefix('news_stories') . ' s, ' . $db->prefix('news_topics') . ' t ';
571
        $sql    .= ' ' . $criteria->renderWhere() . ' AND (s.topicid=t.topic_id) ORDER BY created DESC';
572
        $result = $db->query($sql, (int)$limit, (int)$start);
573
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

573
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
574
            if ($asobject) {
575
                $ret[] = new self($myrow);
0 ignored issues
show
Bug introduced by
$myrow of type array is incompatible with the type integer expected by parameter $storyid of XoopsModules\News\NewsStory::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

575
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
576
            } else {
577
                $ret[$myrow['storyid']] = htmlspecialchars($myrow['title'], ENT_QUOTES | ENT_HTML5);
578
            }
579
        }
580
581
        return $ret;
582
    }
583
584
    /**
585
     * Used in the module's admin to know the number of expired, automated or pubilshed news
586
     *
587
     * @param int  $storytype  1=Expired, 2=Automated, 3=New submissions, 4=Last published stories
588
     * @param bool $checkRight verify permissions or not ?
589
     *
590
     * @return int
591
     */
592
    public static function getAllStoriesCount($storytype = 1, $checkRight = false)
593
    {
594
        /** @var \XoopsMySQLDatabase $db */
595
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
596
        $sql = 'SELECT count(*) AS cpt FROM ' . $db->prefix('news_stories') . ' WHERE ';
597
        switch ($storytype) {
598
            case 1: // Expired
599
                $sql .= '(expired <= ' . \time() . ' AND expired >0)';
600
                break;
601
            case 2: // Automated
602
                $sql .= '(published > ' . \time() . ')';
603
                break;
604
            case 3: // New submissions
605
                $sql .= '(published = 0)';
606
                break;
607
            case 4: // Last published stories
608
                $sql .= '(published > 0 AND published <= ' . \time() . ') AND (expired = 0 OR expired > ' . \time() . ')';
609
                break;
610
        }
611
        if ($checkRight) {
612
            $topics = News\Utility::getMyItemIds('news_view');
613
            if (\count($topics) > 0) {
614
                $topics = \implode(',', $topics);
615
                $sql    .= ' AND topicid IN (' . $topics . ')';
616
            } else {
617
                return 0;
618
            }
619
        }
620
        $result = $db->query($sql);
621
        $myrow  = $db->fetchArray($result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

621
        $myrow  = $db->fetchArray(/** @scrutinizer ignore-type */ $result);
Loading history...
622
623
        return $myrow['cpt'];
624
    }
625
626
    /**
627
     * Get a list of stories (as objects) related to a specific topic
628
     * @param        $topicid
629
     * @param int    $limit
630
     * @return array
631
     */
632
    public static function getByTopic($topicid, $limit = 0)
633
    {
634
        $ret = [];
635
        /** @var \XoopsMySQLDatabase $db */
636
        $db     = \XoopsDatabaseFactory::getDatabaseConnection();
637
        $sql    = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE topicid=' . (int)$topicid . ' ORDER BY published DESC';
638
        $result = $db->query($sql, (int)$limit, 0);
639
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

639
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
640
            $ret[] = new self($myrow);
0 ignored issues
show
Bug introduced by
$myrow of type array is incompatible with the type integer expected by parameter $storyid of XoopsModules\News\NewsStory::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

640
            $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
641
        }
642
643
        return $ret;
644
    }
645
646
    /**
647
     * Count the number of news published for a specific topic
648
     * @param int  $topicid
649
     * @param bool $checkRight
650
     * @return mixed|null
651
     */
652
    public static function countPublishedByTopic($topicid = 0, $checkRight = false)
653
    {
654
        /** @var \XoopsMySQLDatabase $db */
655
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
656
        $sql = 'SELECT COUNT(*) FROM ' . $db->prefix('news_stories') . ' WHERE published > 0 AND published <= ' . \time() . ' AND (expired = 0 OR expired > ' . \time() . ')';
657
        if (!empty($topicid)) {
658
            $sql .= ' AND topicid=' . (int)$topicid;
659
        } else {
660
            $sql .= ' AND ihome=0';
661
            if ($checkRight) {
662
                $topics = News\Utility::getMyItemIds('news_view');
663
                if (\count($topics) > 0) {
664
                    $topics = \implode(',', $topics);
665
                    $sql    .= ' AND topicid IN (' . $topics . ')';
666
                } else {
667
                    return null;
668
                }
669
            }
670
        }
671
        $result = $db->query($sql);
672
        [$count] = $db->fetchRow($result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

672
        [$count] = $db->fetchRow(/** @scrutinizer ignore-type */ $result);
Loading history...
673
674
        return $count;
675
    }
676
677
    /**
678
     * Internal function
679
     */
680
    public function adminlink()
681
    {
682
        global $xoopsModule;
683
        $dirname = \basename(\dirname(__DIR__));
684
        /** @var \XoopsModuleHandler $moduleHandler */
685
        $moduleHandler = \xoops_getHandler('module');
686
        $module        = $moduleHandler->getByDirname($dirname);
0 ignored issues
show
Unused Code introduced by
The assignment to $module is dead and can be removed.
Loading history...
687
        $pathIcon16    = \Xmf\Module\Admin::iconUrl('', 16);
688
689
        $ret = '&nbsp; <a href='
690
               . XOOPS_URL
691
               . '/modules/news/submit.php?op=edit&amp;storyid='
692
               . $this->storyid()
693
               . '><img src='
694
               . $pathIcon16
695
               . '/edit.png'
696
               . ' '
697
               . 'title='
698
               . \_NW_EDIT
699
               . '></a>'
700
               . '<a href='
701
               . XOOPS_URL
702
               . '/modules/news/admin/index.php?op=delete&amp;storyid='
703
               . $this->storyid()
704
               . '><img src='
705
               . $pathIcon16
706
               . '/delete.png'
707
               . ' '
708
               . 'title='
709
               . \_NW_DELETE
710
               . '></a> &nbsp;';
711
712
        return $ret;
713
    }
714
715
    /**
716
     * Get the topic image url
717
     * @param string $format
718
     * @return string
719
     */
720
    public function topic_imgurl($format = 'S')
721
    {
722
        if ('' === \trim($this->topic_imgurl)) {
723
            $this->topic_imgurl = 'blank.png';
724
        }
725
        $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
726
        switch ($format) {
727
            case 'S':
728
                $imgurl = htmlspecialchars($this->topic_imgurl, ENT_QUOTES | ENT_HTML5);
729
                break;
730
            case 'E':
731
                $imgurl = htmlspecialchars($this->topic_imgurl, ENT_QUOTES | ENT_HTML5);
732
                break;
733
            case 'P':
734
                $imgurl = htmlspecialchars($this->topic_imgurl, ENT_QUOTES | ENT_HTML5);
735
                break;
736
            case 'F':
737
                $imgurl = htmlspecialchars($this->topic_imgurl, ENT_QUOTES | ENT_HTML5);
738
                break;
739
        }
740
741
        return $imgurl;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $imgurl does not seem to be defined for all execution paths leading up to this point.
Loading history...
742
    }
743
744
    /**
745
     * @param string $format
746
     *
747
     * @return mixed
748
     */
749
    public function topic_title($format = 'S')
750
    {
751
        $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
752
        switch ($format) {
753
            case 'S':
754
                $title = htmlspecialchars($this->topic_title, ENT_QUOTES | ENT_HTML5);
755
                break;
756
            case 'E':
757
                $title = htmlspecialchars($this->topic_title, ENT_QUOTES | ENT_HTML5);
758
                break;
759
            case 'P':
760
                $title = $this->topic_title;
761
                $title = htmlspecialchars($title, ENT_QUOTES | ENT_HTML5);
762
                break;
763
            case 'F':
764
                $title = $this->topic_title;
765
                $title = htmlspecialchars($title, ENT_QUOTES | ENT_HTML5);
766
                break;
767
        }
768
769
        return $title;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $title does not seem to be defined for all execution paths leading up to this point.
Loading history...
770
    }
771
772
    /**
773
     * @return string
774
     */
775
    public function imglink()
776
    {
777
        $ret = '';
778
        if ('' !== $this->topic_imgurl()
779
            && \file_exists(XOOPS_ROOT_PATH . '/uploads/news/image/' . $this->topic_imgurl())) {
780
            $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>";
781
        }
782
783
        return $ret;
784
    }
785
786
    /**
787
     * @return string
788
     */
789
    public function textlink()
790
    {
791
        $ret = '<a title=' . $this->topic_title() . " href='" . XOOPS_URL . '/modules/news/index.php?storytopic=' . $this->topicid() . "'>" . $this->topic_title() . '</a>';
792
793
        return $ret;
794
    }
795
796
    /**
797
     * Function used to prepare an article to be showned
798
     * @param $filescount
799
     * @return array
800
     */
801
    public function prepare2show($filescount)
802
    {
803
        global $xoopsUser, $xoopsConfig, $xoopsModule;
804
        /** @var News\Helper $helper */
805
        $helper = News\Helper::getInstance();
806
807
        $dirname = \basename(\dirname(__DIR__));
808
        /** @var \XoopsModuleHandler $moduleHandler */
809
        $moduleHandler = \xoops_getHandler('module');
810
        $module        = $moduleHandler->getByDirname($dirname);
0 ignored issues
show
Unused Code introduced by
The assignment to $module is dead and can be removed.
Loading history...
811
        $pathIcon16    = \Xmf\Module\Admin::iconUrl('', 16);
812
813
        $myts                 = \MyTextSanitizer::getInstance();
814
        $infotips             = News\Utility::getModuleOption('infotips');
815
        $story                = [];
816
        $story['id']          = $this->storyid();
817
        $story['poster']      = $this->uname();
818
        $story['author_name'] = $this->uname();
819
        $story['author_uid']  = $this->uid();
820
        if (false !== $story['poster']) {
0 ignored issues
show
introduced by
The condition false !== $story['poster'] is always true.
Loading history...
821
            $story['poster'] = "<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $this->uid() . "'>" . $story['poster'] . '</a>';
822
        } elseif (3 != $helper->getConfig('displayname')) {
823
            $story['poster'] = $xoopsConfig['anonymous'];
824
        }
825
        if ($helper->getConfig('ratenews')) {
826
            $story['rating'] = \number_format($this->rating(), 2);
827
            if (1 == $this->votes) {
828
                $story['votes'] = \_NW_ONEVOTE;
829
            } else {
830
                $story['votes'] = \sprintf(\_NW_NUMVOTES, $this->votes);
831
            }
832
        }
833
        $story['posttimestamp']     = $this->published();
834
        $story['posttime']          = \formatTimestamp($story['posttimestamp'], News\Utility::getModuleOption('dateformat'));
835
        $story['topic_description'] = $myts->displayTarea($this->topic_description);
0 ignored issues
show
Bug introduced by
The property topic_description does not exist on XoopsModules\News\NewsStory. Did you mean description?
Loading history...
836
837
        $auto_summary = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $auto_summary is dead and can be removed.
Loading history...
838
        $tmp          = '';
839
        $auto_summary = $this->auto_summary($this->bodytext(), $tmp);
840
841
        $story['text'] = $this->hometext();
842
        $story['text'] = \str_replace('[summary]', $auto_summary, $story['text']);
843
844
        //$story['picture'] = XOOPS_URL.'/uploads/news/image/'.$this->picture();
845
        if ('' !== $this->picture()) {
846
            $story['picture'] = XOOPS_URL . '/uploads/news/image/' . $this->picture();
847
        } else {
848
            $story['picture'] = '';
849
        }
850
        $story['pictureinfo'] = $this->pictureinfo();
851
852
        $introcount = mb_strlen($story['text']);
853
        $fullcount  = mb_strlen($this->bodytext());
854
        $totalcount = $introcount + $fullcount;
855
856
        $morelink = '';
857
        if ($fullcount > 1) {
858
            $morelink .= '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
859
            $morelink .= '">' . _NW_READMORE . '</a>';
860
            $morelink .= ' | ' . \sprintf(_NW_BYTESMORE, $totalcount);
861
            if (\XOOPS_COMMENT_APPROVENONE != $helper->getConfig('com_rule')) {
862
                $morelink .= ' | ';
863
            }
864
        }
865
        if (\XOOPS_COMMENT_APPROVENONE != $helper->getConfig('com_rule')) {
866
            $ccount    = $this->comments();
867
            $morelink  .= '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
868
            $morelink2 = '<a href="' . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '';
869
            if (0 == $ccount) {
870
                $morelink .= '">' . _NW_COMMENTS . '</a>';
871
            } elseif ($fullcount < 1) {
872
                if (1 == $ccount) {
873
                    $morelink .= '">' . _NW_READMORE . '</a> | ' . $morelink2 . '">' . _NW_ONECOMMENT . '</a>';
874
                } else {
875
                    $morelink .= '">' . _NW_READMORE . '</a> | ' . $morelink2 . '">';
876
                    $morelink .= \sprintf(_NW_NUMCOMMENTS, $ccount);
877
                    $morelink .= '</a>';
878
                }
879
            } elseif (1 == $ccount) {
880
                $morelink .= '">' . _NW_ONECOMMENT . '</a>';
881
            } else {
882
                $morelink .= '">';
883
                $morelink .= \sprintf(_NW_NUMCOMMENTS, $ccount);
884
                $morelink .= '</a>';
885
            }
886
        }
887
        $story['morelink']  = $morelink;
888
        $story['adminlink'] = '';
889
890
        $approveprivilege = 0;
891
        if (News\Utility::isAdminGroup()) {
892
            $approveprivilege = 1;
893
        }
894
895
        if (1 == $helper->getConfig('authoredit')
896
            && (\is_object($xoopsUser)
897
                && $xoopsUser->getVar('uid') == $this->uid())) {
898
            $approveprivilege = 1;
899
        }
900
        if ($approveprivilege) {
901
            $story['adminlink'] = $this->adminlink();
902
        }
903
        $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();
904
        $story['imglink']   = '';
905
        $story['align']     = '';
906
        if ($this->topicdisplay()) {
907
            $story['imglink'] = $this->imglink();
908
            $story['align']   = $this->topicalign();
909
        }
910
        if ($infotips > 0) {
911
            $story['infotips'] = ' title="' . News\Utility::makeInfotips($this->hometext()) . '"';
912
        } else {
913
            $story['infotips'] = 'title="' . $this->title() . '"';
914
        }
915
        $story['title'] = "<a href='" . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . "'" . $story['infotips'] . '>' . $this->title() . '</a>';
916
        //$story['subtitle'] = $this->subtitle();
917
918
        $story['hits'] = $this->counter();
919
        if ($filescount > 0) {
920
            $story['files_attached'] = true;
921
            $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>';
922
        } else {
923
            $story['files_attached'] = false;
924
            $story['attached_link']  = '';
925
        }
926
927
        return $story;
928
    }
929
930
    /**
931
     * Returns the user's name of the current story according to the module's option "displayname"
932
     * @param int $uid
933
     * @return null|string
934
     */
935
    public function uname($uid = 0)
936
    {
937
        global $xoopsConfig;
938
        static $tblusers = [];
939
        $option = -1;
0 ignored issues
show
Unused Code introduced by
The assignment to $option is dead and can be removed.
Loading history...
940
        if (0 == $uid) {
941
            $uid = $this->uid();
942
        }
943
944
        if (\is_array($tblusers) && \array_key_exists($uid, $tblusers)) {
945
            return $tblusers[$uid];
946
        }
947
948
        /** @var News\Helper $helper */
949
        $helper = News\Helper::getInstance();
950
        $option = $helper->getConfig('displayname');
951
        //        $option = News\Utility::getModuleOption('displayname');
952
        if (!$option) {
953
            $option = 1;
954
        }
955
956
        switch ($option) {
957
            case 1: // Username
958
                $tblusers[$uid] = \XoopsUser::getUnameFromId($uid);
959
960
                return $tblusers[$uid];
961
            case 2: // Display full name (if it is not empty) /** @var \XoopsMemberHandler $memberHandler */ $memberHandler = xoops_getHandler('member');
962
                $thisuser = $memberHandler->getUser($uid);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $memberHandler seems to be never defined.
Loading history...
963
                if (\is_object($thisuser)) {
964
                    $return = $thisuser->getVar('name');
965
                    if ('' === $return) {
966
                        $return = $thisuser->getVar('uname');
967
                    }
968
                } else {
969
                    $return = $xoopsConfig['anonymous'];
970
                }
971
                $tblusers[$uid] = $return;
972
973
                return $return;
974
            case 3: // Nothing
975
                $tblusers[$uid] = '';
976
977
                return '';
978
        }
979
980
        return null;
981
    }
982
983
    /**
984
     * Function used to export news (in xml) and eventually the topics definitions
985
     * Warning, permissions are not exported !
986
     *
987
     * @param int      $fromdate     Starting date
988
     * @param int      $todate       Ending date
989
     * @param string   $topicslist
990
     * @param bool|int $usetopicsdef Should we also export topics definitions ?
991
     * @param          $tbltopics
992
     * @param bool     $asobject     Return values as an object or not ?
993
     *
994
     * @param string   $order
995
     *
996
     * @return array
997
     * @internal param string $topiclist If not empty, a list of topics to limit to
998
     */
999
    public function exportNews(
1000
        $fromdate,
1001
        $todate,
1002
        $topicslist,
1003
        $usetopicsdef,
1004
        &$tbltopics,
1005
        $asobject = true,
1006
        $order = 'published'
1007
    ) {
1008
        $ret = [];
1009
        /** @var \XoopsMySQLDatabase $db */
1010
        $db   = \XoopsDatabaseFactory::getDatabaseConnection();
1011
        $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
1012
        if ($usetopicsdef) { // We firt begin by exporting topics definitions
1013
            // Before all we must know wich topics to export
1014
            $sql = 'SELECT DISTINCT topicid FROM ' . $db->prefix('news_stories') . ' WHERE (published >=' . $fromdate . ' AND published <= ' . $todate . ')';
1015
            if ('' !== \trim($topicslist)) {
1016
                $sql .= ' AND topicid IN (' . $topicslist . ')';
1017
            }
1018
            $result = $db->query($sql);
1019
            while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1019
            while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
1020
                $tbltopics[] = $myrow['topicid'];
1021
            }
1022
        }
1023
1024
        // Now we can search for the stories
1025
        $sql = 'SELECT s.*, t.* FROM ' . $this->table . ' s, ' . $db->prefix('news_topics') . ' t WHERE (s.topicid=t.topic_id) AND (s.published >=' . $fromdate . ' AND s.published <= ' . $todate . ')';
1026
        if ('' !== \trim($topicslist)) {
1027
            $sql .= ' AND topicid IN (' . $topicslist . ')';
1028
        }
1029
        $sql    .= " ORDER BY $order DESC";
1030
        $result = $db->query($sql);
1031
        while (false !== ($myrow = $db->fetchArray($result))) {
1032
            if ($asobject) {
1033
                $ret[] = new self($myrow);
0 ignored issues
show
Bug introduced by
$myrow of type array is incompatible with the type integer expected by parameter $storyid of XoopsModules\News\NewsStory::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1033
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
1034
            } else {
1035
                $ret[$myrow['storyid']] = htmlspecialchars($myrow['title'], ENT_QUOTES | ENT_HTML5);
1036
            }
1037
        }
1038
1039
        return $ret;
1040
    }
1041
1042
    /**
1043
     * Create or update an article
1044
     * @param bool $approved
1045
     * @return bool|int
1046
     */
1047
    public function store($approved = false)
1048
    {
1049
        $myts        = \MyTextSanitizer::getInstance();
1050
        $counter     = isset($this->counter) ? $this->counter : 0;
1051
        $title       = $myts->addSlashes($myts->censorString($this->title));
1052
        $subtitle    = $myts->addSlashes($myts->censorString($this->subtitle));
1053
        $hostname    = $myts->addSlashes($this->hostname);
1054
        $type        = $myts->addSlashes($this->type);
1055
        $hometext    = $myts->addSlashes($myts->censorString($this->hometext));
1056
        $bodytext    = $myts->addSlashes($myts->censorString($this->bodytext));
1057
        $description = $myts->addSlashes($myts->censorString($this->description));
1058
        $keywords    = $myts->addSlashes($myts->censorString($this->keywords));
1059
        $picture     = $myts->addSlashes($this->picture);
1060
        $pictureinfo = $myts->addSlashes($myts->censorString($this->pictureinfo));
1061
        $votes       = (int)$this->votes;
1062
        $rating      = (float)$this->rating;
1063
        if (!isset($this->nohtml) || 1 != $this->nohtml) {
1064
            $this->nohtml = 0;
1065
        }
1066
        if (!isset($this->nosmiley) || 1 != $this->nosmiley) {
1067
            $this->nosmiley = 0;
1068
        }
1069
        if (!isset($this->notifypub) || 1 != $this->notifypub) {
1070
            $this->notifypub = 0;
1071
        }
1072
        if (!isset($this->topicdisplay) || 0 != $this->topicdisplay) {
1073
            $this->topicdisplay = 1;
1074
        }
1075
        $expired = !empty($this->expired) ? $this->expired : 0;
1076
        if (!isset($this->storyid)) {
1077
            //$newpost = 1;
1078
            $newstoryid = $this->db->genId($this->table . '_storyid_seq');
1079
            $created    = \time();
1080
            $published  = $this->approved ? (int)$this->published : 0;
1081
            $sql        = \sprintf(
1082
                "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')",
1083
                $this->table,
1084
                $newstoryid,
1085
                (int)$this->uid(),
1086
                $title,
1087
                $created,
1088
                $published,
1089
                $expired,
1090
                $hostname,
1091
                (int)$this->nohtml(),
1092
                (int)$this->nosmiley(),
1093
                $hometext,
1094
                $bodytext,
1095
                $counter,
1096
                (int)$this->topicid(),
1097
                (int)$this->ihome(),
1098
                (int)$this->notifypub(),
1099
                $type,
1100
                (int)$this->topicdisplay(),
1101
                $this->topicalign,
1102
                (int)$this->comments(),
1103
                $rating,
1104
                $votes,
1105
                $description,
1106
                $keywords,
1107
                $picture,
1108
                $pictureinfo,
1109
                $subtitle
1110
            );
1111
        } else {
1112
            $sql        = \sprintf(
1113
                "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",
1114
                $this->table,
1115
                $title,
1116
                (int)$this->published(),
1117
                $expired,
1118
                (int)$this->nohtml(),
1119
                (int)$this->nosmiley(),
1120
                $hometext,
1121
                $bodytext,
1122
                (int)$this->topicid(),
1123
                (int)$this->ihome(),
1124
                (int)$this->topicdisplay(),
1125
                $this->topicalign,
1126
                (int)$this->comments(),
1127
                $rating,
1128
                $votes,
1129
                (int)$this->uid(),
1130
                $description,
1131
                $keywords,
1132
                $picture,
1133
                $pictureinfo,
1134
                $subtitle,
1135
                (int)$this->storyid()
1136
            );
1137
            $newstoryid = (int)$this->storyid();
1138
        }
1139
        if (!$this->db->queryF($sql)) {
1140
            return false;
1141
        }
1142
        if (empty($newstoryid)) {
1143
            $newstoryid    = $this->db->getInsertId();
1144
            $this->storyid = $newstoryid;
1145
        }
1146
1147
        return $newstoryid;
1148
    }
1149
1150
    /**
1151
     * @return mixed
1152
     */
1153
    public function picture()
1154
    {
1155
        return $this->picture;
1156
    }
1157
1158
    /**
1159
     * @return mixed
1160
     */
1161
    public function pictureinfo()
1162
    {
1163
        return $this->pictureinfo;
1164
    }
1165
1166
    /**
1167
     * @return mixed
1168
     */
1169
    public function subtitle()
1170
    {
1171
        return $this->subtitle;
1172
    }
1173
1174
    /**
1175
     * @return mixed
1176
     */
1177
    public function rating()
1178
    {
1179
        return $this->rating;
1180
    }
1181
1182
    /**
1183
     * @return mixed
1184
     */
1185
    public function votes()
1186
    {
1187
        return $this->votes;
1188
    }
1189
1190
    /**
1191
     * @param $data
1192
     */
1193
    public function setPicture($data)
1194
    {
1195
        $this->picture = $data;
1196
    }
1197
1198
    /**
1199
     * @param $data
1200
     */
1201
    public function setPictureinfo($data)
1202
    {
1203
        $this->pictureinfo = $data;
1204
    }
1205
1206
    /**
1207
     * @param $data
1208
     */
1209
    public function setSubtitle($data)
1210
    {
1211
        $this->subtitle = $data;
1212
    }
1213
1214
    /**
1215
     * @param $data
1216
     */
1217
    public function setDescription($data)
1218
    {
1219
        $this->description = $data;
1220
    }
1221
1222
    /**
1223
     * @param $data
1224
     */
1225
    public function setKeywords($data)
1226
    {
1227
        $this->keywords = $data;
1228
    }
1229
1230
    /**
1231
     * @param string $format
1232
     *
1233
     * @return mixed
1234
     */
1235
    public function description($format = 'S')
1236
    {
1237
        $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
1238
        switch (mb_strtoupper($format)) {
1239
            case 'S':
1240
                $description = htmlspecialchars($this->description, ENT_QUOTES | ENT_HTML5);
1241
                break;
1242
            case 'P':
1243
            case 'F':
1244
                $description = htmlspecialchars($this->description, ENT_QUOTES | ENT_HTML5);
1245
                break;
1246
            case 'E':
1247
                $description = htmlspecialchars($this->description, ENT_QUOTES | ENT_HTML5);
1248
                break;
1249
        }
1250
1251
        return $description;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $description does not seem to be defined for all execution paths leading up to this point.
Loading history...
1252
    }
1253
1254
    /**
1255
     * @param string $format
1256
     *
1257
     * @return mixed
1258
     */
1259
    public function keywords($format = 'S')
1260
    {
1261
        $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
1262
        switch (mb_strtoupper($format)) {
1263
            case 'S':
1264
                $keywords = htmlspecialchars($this->keywords, ENT_QUOTES | ENT_HTML5);
1265
                break;
1266
            case 'P':
1267
            case 'F':
1268
                $keywords = htmlspecialchars($this->keywords, ENT_QUOTES | ENT_HTML5);
1269
                break;
1270
            case 'E':
1271
                $keywords = htmlspecialchars($this->keywords, ENT_QUOTES | ENT_HTML5);
1272
                break;
1273
        }
1274
1275
        return $keywords;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $keywords does not seem to be defined for all execution paths leading up to this point.
Loading history...
1276
    }
1277
1278
    /**
1279
     * Returns a random number of news
1280
     * @param int    $limit
1281
     * @param int    $start
1282
     * @param bool   $checkRight
1283
     * @param int    $topic
1284
     * @param int    $ihome
1285
     * @param string $order
1286
     * @param bool   $topic_frontpage
1287
     * @return array
1288
     */
1289
    public function getRandomNews(
1290
        $limit = 0,
1291
        $start = 0,
0 ignored issues
show
Unused Code introduced by
The parameter $start is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1291
        /** @scrutinizer ignore-unused */ $start = 0,

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

Loading history...
1292
        $checkRight = false,
1293
        $topic = 0,
1294
        $ihome = 0,
1295
        $order = 'published',
1296
        $topic_frontpage = false
1297
    ) {
1298
        /** @var \XoopsMySQLDatabase $db */
1299
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
1300
        $ret = $rand_keys = $ret3 = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $rand_keys is dead and can be removed.
Loading history...
1301
        $sql = 'SELECT storyid FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . \time() . ') AND (expired = 0 OR expired > ' . \time() . ')';
1302
        if (0 != $topic) {
1303
            if (!\is_array($topic)) {
0 ignored issues
show
introduced by
The condition is_array($topic) is always false.
Loading history...
1304
                if ($checkRight) {
1305
                    $topics = News\Utility::getMyItemIds('news_view');
1306
                    if (!\in_array($topic, $topics)) {
1307
                        return null;
1308
                    }
1309
                    $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
1310
                } else {
1311
                    $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
1312
                }
1313
            } elseif (\count($topic) > 0) {
1314
                $sql .= ' AND topicid IN (' . \implode(',', $topic) . ')';
1315
            } else {
1316
                return null;
1317
            }
1318
        } else {
1319
            if ($checkRight) {
1320
                $topics = News\Utility::getMyItemIds('news_view');
1321
                if (\count($topics) > 0) {
1322
                    $topics = \implode(',', $topics);
1323
                    $sql    .= ' AND topicid IN (' . $topics . ')';
1324
                } else {
1325
                    return null;
1326
                }
1327
            }
1328
            if (0 == (int)$ihome) {
1329
                $sql .= ' AND ihome=0';
1330
            }
1331
        }
1332
        if ($topic_frontpage) {
1333
            $sql .= ' AND t.topic_frontpage=1';
1334
        }
1335
        $sql    .= " ORDER BY $order DESC";
1336
        $result = $db->query($sql);
1337
1338
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1338
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
1339
            $ret[] = $myrow['storyid'];
1340
        }
1341
        $cnt = \count($ret);
1342
        if ($cnt) {
1343
            if ($limit > $cnt) {
1344
                $limit = $cnt;
1345
            }
1346
            $rand_keys = \array_rand($ret, $limit);
1347
            if ($limit > 1) {
1348
                for ($i = 0; $i < $limit; ++$i) {
1349
                    $onestory = $ret[$rand_keys[$i]];
1350
                    $ret3[]   = new self($onestory);
1351
                }
1352
            } else {
1353
                $ret3[] = new self($ret[$rand_keys]);
1354
            }
1355
        }
1356
1357
        return $ret3;
1358
    }
1359
1360
    /**
1361
     * Returns statistics about the stories and topics
1362
     * @param $limit
1363
     * @return array
1364
     */
1365
    public function getStats($limit)
1366
    {
1367
        $ret = [];
1368
        /** @var \XoopsMySQLDatabase $db */
1369
        $db   = \XoopsDatabaseFactory::getDatabaseConnection();
1370
        $tbls = $db->prefix('news_stories');
1371
        $tblt = $db->prefix('news_topics');
1372
        $tblf = $db->prefix('news_stories_files');
1373
        // Number of stories per topic, including expired and non published stories
1374
        $ret2   = [];
1375
        $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";
1376
        $result = $db->query($sql);
1377
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1377
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
1378
            $ret2[$myrow['topicid']] = $myrow;
1379
        }
1380
        $ret['storiespertopic'] = $ret2;
1381
        unset($ret2);
1382
1383
        // Total of reads per topic
1384
        $ret2   = [];
1385
        $sql    = "SELECT Sum(counter) as cpt, topicid FROM $tbls GROUP BY topicid ORDER BY topicid";
1386
        $result = $db->query($sql);
1387
        while (false !== ($myrow = $db->fetchArray($result))) {
1388
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1389
        }
1390
        $ret['readspertopic'] = $ret2;
1391
        unset($ret2);
1392
1393
        // Attached files per topic
1394
        $ret2   = [];
1395
        $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";
1396
        $result = $db->query($sql);
1397
        while (false !== ($myrow = $db->fetchArray($result))) {
1398
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1399
        }
1400
        $ret['filespertopic'] = $ret2;
1401
        unset($ret2);
1402
1403
        // Expired articles per topic
1404
        $ret2   = [];
1405
        $sql    = "SELECT Count(storyid) as cpt, topicid FROM $tbls WHERE expired>0 AND expired<=" . \time() . ' GROUP BY topicid ORDER BY topicid';
1406
        $result = $db->query($sql);
1407
        while (false !== ($myrow = $db->fetchArray($result))) {
1408
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1409
        }
1410
        $ret['expiredpertopic'] = $ret2;
1411
        unset($ret2);
1412
1413
        // Number of unique authors per topic
1414
        $ret2   = [];
1415
        $sql    = "SELECT Count(Distinct(uid)) as cpt, topicid FROM $tbls GROUP BY topicid ORDER BY topicid";
1416
        $result = $db->query($sql);
1417
        while (false !== ($myrow = $db->fetchArray($result))) {
1418
            $ret2[$myrow['topicid']] = $myrow['cpt'];
1419
        }
1420
        $ret['authorspertopic'] = $ret2;
1421
        unset($ret2);
1422
1423
        // Most readed articles
1424
        $ret2   = [];
1425
        $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";
1426
        $result = $db->query($sql, (int)$limit);
1427
        while (false !== ($myrow = $db->fetchArray($result))) {
1428
            $ret2[$myrow['storyid']] = $myrow;
1429
        }
1430
        $ret['mostreadednews'] = $ret2;
1431
        unset($ret2);
1432
1433
        // Less readed articles
1434
        $ret2   = [];
1435
        $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";
1436
        $result = $db->query($sql, (int)$limit);
1437
        while (false !== ($myrow = $db->fetchArray($result))) {
1438
            $ret2[$myrow['storyid']] = $myrow;
1439
        }
1440
        $ret['lessreadednews'] = $ret2;
1441
        unset($ret2);
1442
1443
        // Best rated articles
1444
        $ret2   = [];
1445
        $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";
1446
        $result = $db->query($sql, (int)$limit);
1447
        while (false !== ($myrow = $db->fetchArray($result))) {
1448
            $ret2[$myrow['storyid']] = $myrow;
1449
        }
1450
        $ret['besratednews'] = $ret2;
1451
        unset($ret2);
1452
1453
        // Most readed authors
1454
        $ret2   = [];
1455
        $sql    = "SELECT Sum(counter) as cpt, uid FROM $tbls GROUP BY uid ORDER BY cpt DESC";
1456
        $result = $db->query($sql, (int)$limit);
1457
        while (false !== ($myrow = $db->fetchArray($result))) {
1458
            $ret2[$myrow['uid']] = $myrow['cpt'];
1459
        }
1460
        $ret['mostreadedauthors'] = $ret2;
1461
        unset($ret2);
1462
1463
        // Best rated authors
1464
        $ret2   = [];
1465
        $sql    = "SELECT Avg(rating) as cpt, uid FROM $tbls WHERE votes > 0 GROUP BY uid ORDER BY cpt DESC";
1466
        $result = $db->query($sql, (int)$limit);
1467
        while (false !== ($myrow = $db->fetchArray($result))) {
1468
            $ret2[$myrow['uid']] = $myrow['cpt'];
1469
        }
1470
        $ret['bestratedauthors'] = $ret2;
1471
        unset($ret2);
1472
1473
        // Biggest contributors
1474
        $ret2   = [];
1475
        $sql    = "SELECT Count(*) as cpt, uid FROM $tbls GROUP BY uid ORDER BY cpt DESC";
1476
        $result = $db->query($sql, (int)$limit);
1477
        while (false !== ($myrow = $db->fetchArray($result))) {
1478
            $ret2[$myrow['uid']] = $myrow['cpt'];
1479
        }
1480
        $ret['biggestcontributors'] = $ret2;
1481
        unset($ret2);
1482
1483
        return $ret;
1484
    }
1485
1486
    /**
1487
     * Get the date of the older and most recent news
1488
     * @param $older
1489
     * @param $recent
1490
     */
1491
    public function getOlderRecentNews(&$older, &$recent)
1492
    {
1493
        /** @var \XoopsMySQLDatabase $db */
1494
        $db     = \XoopsDatabaseFactory::getDatabaseConnection();
1495
        $sql    = 'SELECT min(published) AS minpublish, max(published) AS maxpublish FROM ' . $db->prefix('news_stories');
1496
        $result = $db->query($sql);
1497
        if (!$result) {
1498
            $older = $recent = 0;
1499
        } else {
1500
            [$older, $recent] = $db->fetchRow($result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type true; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1500
            [$older, $recent] = $db->fetchRow(/** @scrutinizer ignore-type */ $result);
Loading history...
Comprehensibility Best Practice introduced by
This list assign is not used and could be removed.
Loading history...
1501
        }
1502
    }
1503
1504
    /*
1505
     * Returns the author's IDs for the Who's who page
1506
     */
1507
1508
    /**
1509
     * @param bool $checkRight
1510
     * @param int  $limit
1511
     * @param int  $start
1512
     *
1513
     * @return array|null
1514
     */
1515
    public function getWhosWho($checkRight = false, $limit = 0, $start = 0)
0 ignored issues
show
Unused Code introduced by
The parameter $start is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1515
    public function getWhosWho($checkRight = false, $limit = 0, /** @scrutinizer ignore-unused */ $start = 0)

This check looks for 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 $limit is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1515
    public function getWhosWho($checkRight = false, /** @scrutinizer ignore-unused */ $limit = 0, $start = 0)

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

Loading history...
1516
    {
1517
        /** @var \XoopsMySQLDatabase $db */
1518
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
1519
        $ret = [];
1520
        $sql = 'SELECT DISTINCT(uid) AS uid FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . \time() . ') AND (expired = 0 OR expired > ' . \time() . ')';
1521
        if ($checkRight) {
1522
            $topics = News\Utility::getMyItemIds('news_view');
1523
            if (\count($topics) > 0) {
1524
                $topics = \implode(',', $topics);
1525
                $sql    .= ' AND topicid IN (' . $topics . ')';
1526
            } else {
1527
                return null;
1528
            }
1529
        }
1530
        $sql    .= ' ORDER BY uid';
1531
        $result = $db->query($sql);
1532
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1532
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
1533
            $ret[] = $myrow['uid'];
1534
        }
1535
1536
        return $ret;
1537
    }
1538
1539
    /**
1540
     * Returns the content of the summary and the titles requires for the list selector
1541
     * @param $text
1542
     * @param $titles
1543
     * @return string
1544
     */
1545
    public function auto_summary($text, &$titles)
1546
    {
1547
        $auto_summary = '';
1548
        if (News\Utility::getModuleOption('enhanced_pagenav')) {
1549
            $expr_matches = [];
1550
            $posdeb       = \preg_match_all('/(\[pagebreak:|\[pagebreak).*\]/iU', $text, $expr_matches);
0 ignored issues
show
Unused Code introduced by
The assignment to $posdeb is dead and can be removed.
Loading history...
1551
            if (\count($expr_matches) > 0) {
1552
                $delimiters  = $expr_matches[0];
1553
                $arr_search  = ['[pagebreak:', '[pagebreak', ']'];
1554
                $arr_replace = ['', '', ''];
1555
                $cpt         = 1;
1556
                if (isset($titles) && \is_array($titles)) {
1557
                    $titles[] = \strip_tags(\sprintf(\_NW_PAGE_AUTO_SUMMARY, 1, $this->title()));
1558
                }
1559
                $item         = "<a href='" . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . "&page=0'>" . \sprintf(\_NW_PAGE_AUTO_SUMMARY, 1, $this->title()) . '</a><br>';
1560
                $auto_summary .= $item;
1561
1562
                foreach ($delimiters as $item) {
1563
                    ++$cpt;
1564
                    $item = \str_replace($arr_search, $arr_replace, $item);
1565
                    if ('' == \xoops_trim($item)) {
1566
                        $item = $cpt;
1567
                    }
1568
                    $titles[]     = \strip_tags(\sprintf(\_NW_PAGE_AUTO_SUMMARY, $cpt, $item));
1569
                    $item         = "<a href='" . XOOPS_URL . '/modules/news/article.php?storyid=' . $this->storyid() . '&page=' . ($cpt - 1) . "'>" . \sprintf(\_NW_PAGE_AUTO_SUMMARY, $cpt, $item) . '</a><br>';
1570
                    $auto_summary .= $item;
1571
                }
1572
            }
1573
        }
1574
1575
        return $auto_summary;
1576
    }
1577
1578
    /**
1579
     * @param string $format
1580
     *
1581
     * @return mixed
1582
     */
1583
    public function hometext($format = 'Show')
1584
    {
1585
        $hometext = '';
1586
        $myts     = \MyTextSanitizer::getInstance();
1587
        $html     = $smiley = $xcodes = 1;
1588
        if ($this->nohtml()) {
1589
            $html = 0;
1590
        }
1591
        if ($this->nosmiley()) {
1592
            $smiley = 0;
1593
        }
1594
        switch ($format) {
1595
            case 'Show':
1596
                $hometext     = $myts->displayTarea($this->hometext, $html, $smiley, $xcodes);
1597
                $tmp          = '';
1598
                $auto_summary = $this->auto_summary($this->bodytext('Show'), $tmp);
1599
                $hometext     = \str_replace('[summary]', $auto_summary, $hometext);
1600
                break;
1601
            case 'Edit':
1602
                $hometext = htmlspecialchars($this->hometext, ENT_QUOTES | ENT_HTML5);
1603
                break;
1604
            case 'Preview':
1605
                $hometext = $myts->previewTarea($this->hometext, $html, $smiley, $xcodes);
1606
                break;
1607
            case 'InForm':
1608
                $hometext = htmlspecialchars($this->hometext, ENT_QUOTES | ENT_HTML5);
1609
                break;
1610
        }
1611
1612
        return $hometext;
1613
    }
1614
1615
    /**
1616
     * @param string $format
1617
     *
1618
     * @return mixed
1619
     */
1620
    public function bodytext($format = 'Show')
1621
    {
1622
        $myts   = \MyTextSanitizer::getInstance();
1623
        $html   = 1;
1624
        $smiley = 1;
1625
        $xcodes = 1;
1626
        if ($this->nohtml()) {
1627
            $html = 0;
1628
        }
1629
        if ($this->nosmiley()) {
1630
            $smiley = 0;
1631
        }
1632
        switch ($format) {
1633
            case 'Show':
1634
                $bodytext     = $myts->displayTarea($this->bodytext, $html, $smiley, $xcodes);
1635
                $tmp          = '';
1636
                $auto_summary = $this->auto_summary($bodytext, $tmp);
1637
                $bodytext     = \str_replace('[summary]', $auto_summary, $bodytext);
1638
                break;
1639
            case 'Edit':
1640
                $bodytext = htmlspecialchars($this->bodytext, ENT_QUOTES | ENT_HTML5);
1641
                break;
1642
            case 'Preview':
1643
                $bodytext = $myts->previewTarea($this->bodytext, $html, $smiley, $xcodes);
1644
                break;
1645
            case 'InForm':
1646
                $bodytext = htmlspecialchars($this->bodytext, ENT_QUOTES | ENT_HTML5);
1647
                break;
1648
        }
1649
1650
        return $bodytext;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $bodytext does not seem to be defined for all execution paths leading up to this point.
Loading history...
1651
    }
1652
1653
    /**
1654
     * Returns stories by Ids
1655
     * @param             $ids
1656
     * @param bool        $checkRight
1657
     * @param bool        $asobject
1658
     * @param string      $order
1659
     * @param bool        $onlyOnline
1660
     * @return array|null
1661
     */
1662
    public function getStoriesByIds(
1663
        $ids,
1664
        $checkRight = true,
1665
        $asobject = true,
1666
        $order = 'published',
1667
        $onlyOnline = true
1668
    ) {
1669
        $limit = $start = 0;
1670
        /** @var \XoopsMySQLDatabase $db */
1671
        $db   = \XoopsDatabaseFactory::getDatabaseConnection();
1672
        $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
1673
        $ret  = [];
1674
        $sql  = 'SELECT s.*, t.* FROM ' . $db->prefix('news_stories') . ' s, ' . $db->prefix('news_topics') . ' t WHERE ';
1675
        if ($ids && \is_array($ids)) {
1676
            \array_walk($ids, '\intval');
1677
        }
1678
        $sql .= ' s.storyid IN (' . \implode(',', $ids) . ') ';
1679
1680
        if ($onlyOnline) {
1681
            $sql .= ' AND (s.published > 0 AND s.published <= ' . \time() . ') AND (s.expired = 0 OR s.expired > ' . \time() . ') ';
1682
        }
1683
        $sql .= ' AND (s.topicid=t.topic_id) ';
1684
        if ($checkRight) {
1685
            $topics = News\Utility::getMyItemIds('news_view');
1686
            if (\count($topics) > 0) {
1687
                $topics = \implode(',', $topics);
1688
                $sql    .= ' AND s.topicid IN (' . $topics . ')';
1689
            } else {
1690
                return null;
1691
            }
1692
        }
1693
        $sql    .= " ORDER BY s.$order DESC";
1694
        $result = $db->query($sql, $limit, $start);
1695
1696
        while (false !== ($myrow = $db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1696
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
1697
            if ($asobject) {
1698
                $ret[$myrow['storyid']] = new self($myrow);
0 ignored issues
show
Bug introduced by
$myrow of type array is incompatible with the type integer expected by parameter $storyid of XoopsModules\News\NewsStory::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1698
                $ret[$myrow['storyid']] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
1699
            } else {
1700
                $ret[$myrow['storyid']] = htmlspecialchars($myrow['title'], ENT_QUOTES | ENT_HTML5);
1701
            }
1702
        }
1703
1704
        return $ret;
1705
    }
1706
}
1707