NewsStory::getStats()   F
last analyzed

Complexity

Conditions 12
Paths 2048

Size

Total Lines 119
Code Lines 83

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 83
c 0
b 0
f 0
dl 0
loc 119
rs 2.6109
cc 12
nc 2048
nop 1

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
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
 * @author         XOOPS Development Team
19
 */
20
21
use Xmf\Module\Admin;
22
23
//require_once XOOPS_ROOT_PATH . '/modules/news/class/xoopsstory.php';
24
require XOOPS_ROOT_PATH . '/include/comment_constants.php';
25
26
require_once \dirname(__DIR__) . '/preloads/autoloader.php';
27
28
/** @var Helper $helper */
29
$helper = Helper::getInstance();
30
$helper->loadLanguage('main');
31
32
/**
33
 * Class NewsStory
34
 */
35
class NewsStory extends XoopsStory
36
{
37
    public $newstopic; // XoopsTopic object
38
    public $rating; // News rating
39
    public $votes; // Number of votes
40
    public $description; // META, desciption
41
    public $keywords; // META, keywords
42
    public $picture;
43
    public $topic_imgurl;
44
    public $topic_title;
45
    public $topic_description;
46
    public $subtitle;
47
    public $pictureinfo;
48
49
    /**
50
     * Constructor
51
     * @param int $storyid
52
     */
53
    public function __construct($storyid = -1)
54
    {
55
        /** @var \XoopsMySQLDatabase $this ->db */
56
        $this->db          = \XoopsDatabaseFactory::getDatabaseConnection();
0 ignored issues
show
Bug introduced by
The property db does not seem to exist on XoopsMySQLDatabase.
Loading history...
57
        $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...
58
        $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...
59
        if (\is_array($storyid)) {
60
            $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

60
            $this->/** @scrutinizer ignore-call */ 
61
                   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...
61
        } elseif (-1 != $storyid) {
62
            $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

62
            $this->/** @scrutinizer ignore-call */ 
63
                   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...
63
        }
64
    }
65
66
    /**
67
     * Returns the number of stories published before a date
68
     * @param         $timestamp
69
     * @param         $expired
70
     * @param string  $topicslist
71
     * @return mixed
72
     */
73
    public function getCountStoriesPublishedBefore($timestamp, $expired, $topicslist = '')
74
    {
75
        /** @var \XoopsMySQLDatabase $db */
76
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
77
        $sql = 'SELECT count(*) AS cpt FROM ' . $db->prefix('news_stories') . ' WHERE published <=' . $timestamp;
78
        if ($expired) {
79
            $sql .= ' AND (expired>0 AND expired<=' . \time() . ')';
80
        }
81
        if ('' !== \trim($topicslist)) {
82
            $sql .= ' AND topicid IN (' . $topicslist . ')';
83
        }
84
        $result = $db->query($sql);
85
        [$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

85
        [$count] = $db->fetchRow(/** @scrutinizer ignore-type */ $result);
Loading history...
86
87
        return $count;
88
    }
89
90
    /**
91
     * Load the specified story from the database
92
     * @param $storyid
93
     */
94
    public function getStory($storyid): void
95
    {
96
        /** @var \XoopsMySQLDatabase $db */
97
        $db    = \XoopsDatabaseFactory::getDatabaseConnection();
98
        $sql   = 'SELECT s.*, t.* FROM ' . $this->table . ' s, ' . $db->prefix('news_topics') . ' t WHERE (storyid=' . (int)$storyid . ') AND (s.topicid=t.topic_id)';
99
        $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

99
        $array = $db->fetchArray(/** @scrutinizer ignore-type */ $db->query($sql));
Loading history...
100
        $this->makeStory($array);
101
    }
102
103
    /**
104
     * Delete stories that were published before a given date
105
     * @param         $timestamp
106
     * @param         $expired
107
     * @param string  $topicslist
108
     * @return bool
109
     */
110
    public function deleteBeforeDate($timestamp, $expired, $topicslist = '')
111
    {
112
        global $xoopsModule;
113
        /** @var \XoopsMySQLDatabase $db */
114
        $db           = \XoopsDatabaseFactory::getDatabaseConnection();
115
        $mid          = $xoopsModule->getVar('mid');
116
        $prefix       = $db->prefix('news_stories');
117
        $vote_prefix  = $db->prefix('news_stories_votedata');
118
        $files_prefix = $db->prefix('news_stories_files');
119
        $sql          = 'SELECT storyid FROM  ' . $prefix . ' WHERE published <=' . $timestamp;
120
        if ($expired) {
121
            $sql .= ' (AND expired>0 AND expired<=' . \time() . ')';
122
        }
123
        if ('' !== \trim($topicslist)) {
124
            $sql .= ' AND topicid IN (' . $topicslist . ')';
125
        }
126
        $result = $db->query($sql);
127
        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

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

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

284
            while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
285
                if ($asobject) {
286
                    $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

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

328
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
329
            if ($asobject) {
330
                $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

330
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
331
            } else {
332
                $ret[$myrow['storyid']] = \htmlspecialchars($myrow['title'], \ENT_QUOTES | \ENT_HTML5);
333
            }
334
        }
335
336
        return $ret;
337
    }
338
339
    /**
340
     * Get the today's most readed article
341
     *
342
     * @param int    $limit      records limit
343
     * @param int    $start      starting record
344
     * @param bool   $checkRight Do we need to check permissions (by topics) ?
345
     * @param int    $topic      limit the job to one topic
346
     * @param int    $ihome      Limit to articles published in home page only ?
347
     * @param bool   $asobject   Do we have to return an array of objects or a simple array ?
348
     * @param string $order      Fields to sort on
349
     *
350
     * @return array
351
     */
352
    public function getBigStory(
353
        $limit = 0,
354
        $start = 0,
355
        $checkRight = false,
356
        $topic = 0,
357
        $ihome = 0,
358
        $asobject = true,
359
        $order = 'counter'
360
    ) {
361
        /** @var \XoopsMySQLDatabase $db */
362
        $db    = \XoopsDatabaseFactory::getDatabaseConnection();
363
        $myts  = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
364
        $ret   = [];
365
        $tdate = \mktime(0, 0, 0, (int)\date('n'), (int)\date('j'), (int)\date('Y'));
366
        $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) ';
367
368
        if (0 != (int)$topic) {
369
            if (!\is_array($topic)) {
0 ignored issues
show
introduced by
The condition is_array($topic) is always false.
Loading history...
370
                $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
371
            } elseif (\count($topic) > 0) {
372
                $sql .= ' AND topicid IN (' . \implode(',', $topic) . ')';
373
            } else {
374
                return null;
375
            }
376
        } else {
377
            if ($checkRight) {
378
                $topics = Utility::getMyItemIds('news_view');
379
                if (\count($topics) > 0) {
380
                    $topics = \implode(',', $topics);
381
                    $sql    .= ' AND topicid IN (' . $topics . ')';
382
                } else {
383
                    return null;
384
                }
385
            }
386
            if (0 == (int)$ihome) {
387
                $sql .= ' AND ihome=0';
388
            }
389
        }
390
        $sql    .= " ORDER BY $order DESC";
391
        $result = $db->query($sql, (int)$limit, (int)$start);
392
        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

392
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
393
            if ($asobject) {
394
                $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

394
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
395
            } else {
396
                $ret[$myrow['storyid']] = \htmlspecialchars($myrow['title'], \ENT_QUOTES | \ENT_HTML5);
397
            }
398
        }
399
400
        return $ret;
401
    }
402
403
    /**
404
     * Get all articles published by an author
405
     *
406
     * @param int  $uid        author's id
407
     * @param bool $checkRight whether to check the user's rights to topics
408
     *
409
     * @param bool $asobject
410
     *
411
     * @return array
412
     */
413
    public function getAllPublishedByAuthor($uid, $checkRight = false, $asobject = true)
414
    {
415
        /** @var \XoopsMySQLDatabase $db */
416
        $db        = \XoopsDatabaseFactory::getDatabaseConnection();
417
        $myts      = \MyTextSanitizer::getInstance();
418
        $ret       = [];
419
        $tblstory  = $db->prefix('news_stories');
420
        $tbltopics = $db->prefix('news_topics');
421
422
        $sql = 'SELECT '
423
               . $tblstory
424
               . '.*, '
425
               . $tbltopics
426
               . '.topic_title, '
427
               . $tbltopics
428
               . '.topic_color FROM '
429
               . $tblstory
430
               . ','
431
               . $tbltopics
432
               . ' WHERE ('
433
               . $tblstory
434
               . '.topicid='
435
               . $tbltopics
436
               . '.topic_id) AND (published > 0 AND published <= '
437
               . \time()
438
               . ') AND (expired = 0 OR expired > '
439
               . \time()
440
               . ')';
441
        $sql .= ' AND uid=' . (int)$uid;
442
        if ($checkRight) {
443
            $topics = Utility::getMyItemIds('news_view');
444
            $topics = \implode(',', $topics);
445
            if ('' !== \xoops_trim($topics)) {
446
                $sql .= ' AND topicid IN (' . $topics . ')';
447
            }
448
        }
449
        $sql    .= ' ORDER BY ' . $tbltopics . '.topic_title ASC, ' . $tblstory . '.published DESC';
450
        $result = $db->query($sql);
451
        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

451
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
452
            if ($asobject) {
453
                $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

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

508
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
509
            if ($asobject) {
510
                $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

510
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
511
            } else {
512
                $ret[$myrow['storyid']] = \htmlspecialchars($myrow['title'], \ENT_QUOTES | \ENT_HTML5);
513
            }
514
        }
515
516
        return $ret;
517
    }
518
519
    /**
520
     * Returns an array of object containing all the news to be automatically published.
521
     * @param int  $limit
522
     * @param bool $asobject
523
     * @param int  $start
524
     * @return array
525
     */
526
    public static function getAllAutoStory($limit = 0, $asobject = true, $start = 0)
527
    {
528
        /** @var \XoopsMySQLDatabase $db */
529
        $db     = \XoopsDatabaseFactory::getDatabaseConnection();
530
        $myts   = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
531
        $ret    = [];
532
        $sql    = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE published > ' . \time() . ' ORDER BY published ASC';
533
        $result = $db->query($sql, (int)$limit, (int)$start);
534
        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

534
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
535
            if ($asobject) {
536
                $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

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

578
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
579
            if ($asobject) {
580
                $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

580
                $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
581
            } else {
582
                $ret[$myrow['storyid']] = \htmlspecialchars($myrow['title'], \ENT_QUOTES | \ENT_HTML5);
583
            }
584
        }
585
586
        return $ret;
587
    }
588
589
    /**
590
     * Used in the module's admin to know the number of expired, automated or pubilshed news
591
     *
592
     * @param int  $storytype  1=Expired, 2=Automated, 3=New submissions, 4=Last published stories
593
     * @param bool $checkRight verify permissions or not ?
594
     *
595
     * @return int
596
     */
597
    public static function getAllStoriesCount($storytype = 1, $checkRight = false)
598
    {
599
        /** @var \XoopsMySQLDatabase $db */
600
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
601
        $sql = 'SELECT count(*) AS cpt FROM ' . $db->prefix('news_stories') . ' WHERE ';
602
        switch ($storytype) {
603
            case 1: // Expired
604
                $sql .= '(expired <= ' . \time() . ' AND expired >0)';
605
                break;
606
            case 2: // Automated
607
                $sql .= '(published > ' . \time() . ')';
608
                break;
609
            case 3: // New submissions
610
                $sql .= '(published = 0)';
611
                break;
612
            case 4: // Last published stories
613
                $sql .= '(published > 0 AND published <= ' . \time() . ') AND (expired = 0 OR expired > ' . \time() . ')';
614
                break;
615
        }
616
        if ($checkRight) {
617
            $topics = Utility::getMyItemIds('news_view');
618
            if (\count($topics) > 0) {
619
                $topics = \implode(',', $topics);
620
                $sql    .= ' AND topicid IN (' . $topics . ')';
621
            } else {
622
                return 0;
623
            }
624
        }
625
        $result = $db->query($sql);
626
        $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

626
        $myrow  = $db->fetchArray(/** @scrutinizer ignore-type */ $result);
Loading history...
627
628
        return $myrow['cpt'];
629
    }
630
631
    /**
632
     * Get a list of stories (as objects) related to a specific topic
633
     * @param        $topicid
634
     * @param int    $limit
635
     * @return array
636
     */
637
    public static function getByTopic($topicid, $limit = 0)
638
    {
639
        $ret = [];
640
        /** @var \XoopsMySQLDatabase $db */
641
        $db     = \XoopsDatabaseFactory::getDatabaseConnection();
642
        $sql    = 'SELECT * FROM ' . $db->prefix('news_stories') . ' WHERE topicid=' . (int)$topicid . ' ORDER BY published DESC';
643
        $result = $db->query($sql, (int)$limit, 0);
644
        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

644
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
645
            $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

645
            $ret[] = new self(/** @scrutinizer ignore-type */ $myrow);
Loading history...
646
        }
647
648
        return $ret;
649
    }
650
651
    /**
652
     * Count the number of news published for a specific topic
653
     * @param int  $topicid
654
     * @param bool $checkRight
655
     * @return mixed|null
656
     */
657
    public static function countPublishedByTopic($topicid = 0, $checkRight = false)
658
    {
659
        /** @var \XoopsMySQLDatabase $db */
660
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
661
        $sql = 'SELECT COUNT(*) FROM ' . $db->prefix('news_stories') . ' WHERE published > 0 AND published <= ' . \time() . ' AND (expired = 0 OR expired > ' . \time() . ')';
662
        if (!empty($topicid)) {
663
            $sql .= ' AND topicid=' . (int)$topicid;
664
        } else {
665
            $sql .= ' AND ihome=0';
666
            if ($checkRight) {
667
                $topics = Utility::getMyItemIds('news_view');
668
                if (\count($topics) > 0) {
669
                    $topics = \implode(',', $topics);
670
                    $sql    .= ' AND topicid IN (' . $topics . ')';
671
                } else {
672
                    return null;
673
                }
674
            }
675
        }
676
        $result = $db->query($sql);
677
        [$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

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

1023
            while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
1024
                $tbltopics[] = $myrow['topicid'];
1025
            }
1026
        }
1027
1028
        // Now we can search for the stories
1029
        $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 . ')';
1030
        if ('' !== \trim($topicslist)) {
1031
            $sql .= ' AND topicid IN (' . $topicslist . ')';
1032
        }
1033
        $sql    .= " ORDER BY $order DESC";
1034
        $result = $db->query($sql);
1035
        while (false !== ($myrow = $db->fetchArray($result))) {
1036
            if ($asobject) {
1037
                $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

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

1295
        /** @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...
1296
        $checkRight = false,
1297
        $topic = 0,
1298
        $ihome = 0,
1299
        $order = 'published',
1300
        $topic_frontpage = false
1301
    ) {
1302
        /** @var \XoopsMySQLDatabase $db */
1303
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
1304
        $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...
1305
        $sql = 'SELECT storyid FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . \time() . ') AND (expired = 0 OR expired > ' . \time() . ')';
1306
        if (0 != $topic) {
1307
            if (!\is_array($topic)) {
0 ignored issues
show
introduced by
The condition is_array($topic) is always false.
Loading history...
1308
                if ($checkRight) {
1309
                    $topics = Utility::getMyItemIds('news_view');
1310
                    if (!\in_array($topic, $topics, true)) {
1311
                        return null;
1312
                    }
1313
                    $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
1314
                } else {
1315
                    $sql .= ' AND topicid=' . (int)$topic . ' AND (ihome=1 OR ihome=0)';
1316
                }
1317
            } elseif (\count($topic) > 0) {
1318
                $sql .= ' AND topicid IN (' . \implode(',', $topic) . ')';
1319
            } else {
1320
                return null;
1321
            }
1322
        } else {
1323
            if ($checkRight) {
1324
                $topics = Utility::getMyItemIds('news_view');
1325
                if (\count($topics) > 0) {
1326
                    $topics = \implode(',', $topics);
1327
                    $sql    .= ' AND topicid IN (' . $topics . ')';
1328
                } else {
1329
                    return null;
1330
                }
1331
            }
1332
            if (0 == (int)$ihome) {
1333
                $sql .= ' AND ihome=0';
1334
            }
1335
        }
1336
        if ($topic_frontpage) {
1337
            $sql .= ' AND t.topic_frontpage=1';
1338
        }
1339
        $sql    .= " ORDER BY $order DESC";
1340
        $result = $db->query($sql);
1341
1342
        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

1342
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
1343
            $ret[] = $myrow['storyid'];
1344
        }
1345
        $cnt = \count($ret);
1346
        if ($cnt) {
1347
            if ($limit > $cnt) {
1348
                $limit = $cnt;
1349
            }
1350
            $rand_keys = \array_rand($ret, $limit);
1351
            if ($limit > 1) {
1352
                for ($i = 0; $i < $limit; ++$i) {
1353
                    $onestory = $ret[$rand_keys[$i]];
1354
                    $ret3[]   = new self($onestory);
1355
                }
1356
            } else {
1357
                $ret3[] = new self($ret[$rand_keys]);
1358
            }
1359
        }
1360
1361
        return $ret3;
1362
    }
1363
1364
    /**
1365
     * Returns statistics about the stories and topics
1366
     * @param $limit
1367
     * @return array
1368
     */
1369
    public function getStats($limit)
1370
    {
1371
        $ret = [];
1372
        /** @var \XoopsMySQLDatabase $db */
1373
        $db   = \XoopsDatabaseFactory::getDatabaseConnection();
1374
        $tbls = $db->prefix('news_stories');
1375
        $tblt = $db->prefix('news_topics');
1376
        $tblf = $db->prefix('news_stories_files');
1377
        // Number of stories per topic, including expired and non published stories
1378
        $ret2   = [];
1379
        $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";
1380
        $result = $db->query($sql);
1381
        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

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

1504
            [$older, $recent] = $db->fetchRow(/** @scrutinizer ignore-type */ $result);
Loading history...
1505
        }
1506
    }
1507
1508
    /*
1509
     * Returns the author's IDs for the Who's who page
1510
     */
1511
1512
    /**
1513
     * @param bool $checkRight
1514
     * @param int  $limit
1515
     * @param int  $start
1516
     *
1517
     * @return array|null
1518
     */
1519
    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

1519
    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

1519
    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...
1520
    {
1521
        /** @var \XoopsMySQLDatabase $db */
1522
        $db  = \XoopsDatabaseFactory::getDatabaseConnection();
1523
        $ret = [];
1524
        $sql = 'SELECT DISTINCT(uid) AS uid FROM ' . $db->prefix('news_stories') . ' WHERE (published > 0 AND published <= ' . \time() . ') AND (expired = 0 OR expired > ' . \time() . ')';
1525
        if ($checkRight) {
1526
            $topics = Utility::getMyItemIds('news_view');
1527
            if (\count($topics) > 0) {
1528
                $topics = \implode(',', $topics);
1529
                $sql    .= ' AND topicid IN (' . $topics . ')';
1530
            } else {
1531
                return null;
1532
            }
1533
        }
1534
        $sql    .= ' ORDER BY uid';
1535
        $result = $db->query($sql);
1536
        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

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

1700
        while (false !== ($myrow = $db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
1701
            if ($asobject) {
1702
                $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

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