Passed
Push — master ( d3e687...4990f6 )
by Michael
02:43
created

TopicRenderer   F

Complexity

Total Complexity 204

Size/Duplication

Total Lines 1131
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1131
rs 0.6314
c 0
b 0
f 0
wmc 204

22 Methods

Rating   Name   Duplication   Size   Complexity  
B buildTypes() 0 21 5
D myParseStatus() 0 162 48
C parseVars() 0 29 8
D getSort() 0 99 9
A __construct() 0 3 1
C buildSelection() 0 31 8
F renderTopics() 0 263 46
A getHeader() 0 11 1
C buildPagenav() 0 26 7
A getTypes() 0 15 3
B getStatus() 0 34 2
A init() 0 4 1
C buildHeaders() 0 23 7
B getCount() 0 27 4
B buildCurrent() 0 17 5
C setVar() 0 41 13
A getInstance() 0 8 2
A buildSearch() 0 8 1
A setVars() 0 11 3
D parseVar() 0 86 22
A buildFilters() 0 19 4
A getFromKeys() 0 13 4

How to fix   Complexity   

Complex Class

Complex classes like TopicRenderer 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 TopicRenderer, and based on these observations, apply Extract Interface, too.

1
<?php namespace XoopsModules\Newbb;
2
3
/**
4
 * NewBB 5.0x,  the forum module for XOOPS project
5
 *
6
 * @copyright      XOOPS Project (https://xoops.org)
7
 * @license        GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
8
 * @author         Taiwen Jiang (phppp or D.J.) <[email protected]>
9
 * @since          4.00
10
 * @package        module::newbb
11
 */
12
13
use Xmf\Request;
0 ignored issues
show
Bug introduced by
The type Xmf\Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use XoopsModules\Newbb;
15
16
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
17
18
/**
19
 * Topic Renderer
20
 *
21
 * @author    D.J. (phppp)
22
 * @copyright copyright &copy; Xoops Project
23
 * @package   module::newbb
24
 *
25
 */
26
class TopicRenderer
27
{
28
    /**
29
     * reference to an object handler
30
     */
31
    public $handler;
32
33
    /**
34
     * reference to moduleConfig
35
     */
36
    public $config;
37
38
    /**
39
     * Requested page
40
     */
41
    public $page = 'list.topic.php';
42
43
    /**
44
     * query variables
45
     */
46
    public $args = ['forum', 'uid', 'lastposter', 'type', 'status', 'mode', 'sort', 'order', 'start', 'since'];
47
    public $vars = [];
48
49
    /**
50
     * For multiple forums
51
     */
52
    public $is_multiple = false;
53
54
    /**
55
     * force to parse vars (run against static vars) irmtfan
56
     */
57
    public $force = false;
58
59
    /**
60
     * Vistitor's level: 0 - anonymous; 1 - user; 2 - moderator or admin
61
     */
62
    public $userlevel = 0;
63
64
    /**
65
     * Current user has no access to current page
66
     */
67
    public $noperm = false;
68
69
    /**
70
     *
71
     */
72
    public $query = [];
73
74
    /**
75
     * Constructor
76
     */
77
    //    public function TopicRenderer()
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
78
    public function __construct()
79
    {
80
        $this->handler = Newbb\Helper::getInstance()->getHandler('Topic');
81
    }
82
83
    /**
84
     * Access the only instance of this class
85
     * @return TopicRenderer
86
     */
87
    public static function getInstance()
88
    {
89
        static $instance;
90
        if (null === $instance) {
91
            $instance = new static();
92
        }
93
94
        return $instance;
95
    }
96
97
    public function init()
98
    {
99
        $this->noperm = false;
100
        $this->query  = [];
101
    }
102
103
    /**
104
     * @param $var
105
     * @param $val
106
     * @return array|int|string
107
     */
108
    public function setVar($var, $val)
109
    {
110
        switch ($var) {
111
            case 'forum':
112
                if (is_numeric($val)) {
113
                    $val = (int)$val;
114
                    // START irmtfan - if the forum is array
115
                } elseif (is_array($val)) {
116
                    $val = implode('|', $val);
117
                    //} elseif (!empty($val)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
77% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
118
                    //    $val = implode("|", array_map("intval", explode(", ", $val)));
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
119
                }
120
                // END irmtfan - if the forum is array
121
                break;
122
123
            case 'type':
124
            case 'mode':
125
            case 'order':
126
            case 'start':
127
            case 'since':
128
                $val = (int)$val;
129
                break;
130
131
            case 'uid': // irmtfan add multi topic poster
132
            case 'lastposter': // irmtfan add multi lastposter
133
                break;
134
135
            case 'status':
136
                // START irmtfan to accept multiple status
137
                $val = is_array($val) ? $val : [$val];
138
                $val = implode(',', $val);
139
                //$val = (in_array($val, array_keys($this->getStatus( $this->userlevel ))) ) ? $val : "all"; //irmtfan no need to check if status is empty or not
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
140
                //if ($val === "all" && !$this->is_multiple) $val = ""; irmtfan commented because it is done in sort
141
                // END irmtfan to accept multiple status
142
                break;
143
144
            default:
145
                break;
146
        }
147
148
        return $val;
149
    }
150
151
    /**
152
     * @param array $vars
153
     */
154
    public function setVars(array $vars = [])
155
    {
156
        $this->init();
157
158
        foreach ($vars as $var => $val) {
159
            if (!in_array($var, $this->args)) {
160
                continue;
161
            }
162
            $this->vars[$var] = $this->setVar($var, $val);
163
        }
164
        $this->parseVars();
165
    }
166
167
    /**
168
     * @param null $status
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $status is correct as it would always require null to be passed?
Loading history...
169
     */
170
    public function myParseStatus($status = null)
171
    {
172
        switch ($status) {
173
            case 'digest':
174
                $this->query['where'][] = 't.topic_digest = 1';
175
                break;
176
177
            case 'undigest':
178
                $this->query['where'][] = 't.topic_digest = 0';
179
                break;
180
181
            case 'sticky':
182
                $this->query['where'][] = 't.topic_sticky = 1';
183
                break;
184
185
            case 'unsticky':
186
                $this->query['where'][] = 't.topic_sticky = 0';
187
                break;
188
189
            case 'lock':
190
                $this->query['where'][] = 't.topic_status = 1';
191
                break;
192
193
            case 'unlock':
194
                $this->query['where'][] = 't.topic_status = 0';
195
                break;
196
197
            case 'poll':
198
                $this->query['where'][] = 't.topic_haspoll = 1';
199
                break;
200
201
            case 'unpoll':
202
                $this->query['where'][] = 't.topic_haspoll = 0';
203
                break;
204
205
            case 'voted':
206
                $this->query['where'][] = 't.votes > 0';
207
                break;
208
209
            case 'unvoted':
210
                $this->query['where'][] = 't.votes < 1';
211
                break;
212
213
            case 'replied':
214
                $this->query['where'][] = 't.topic_replies > 0';
215
                break;
216
217
            case 'unreplied':
218
                $this->query['where'][] = 't.topic_replies < 1';
219
                break;
220
221
            case 'viewed':
222
                $this->query['where'][] = 't.topic_views > 0';
223
                break;
224
225
            case 'unviewed':
226
                $this->query['where'][] = 't.topic_views < 1';
227
                break;
228
229
            case 'read':
230
                // Skip
231
                if (empty($this->config['read_mode'])) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
232
                    // Use database
233
                } elseif (2 == $this->config['read_mode']) {
234
                    // START irmtfan use read_uid to find the unread posts when the user is logged in
235
                    $read_uid = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0;
236
                    if (!empty($read_uid)) {
237
                        $this->query['join'][]  = 'LEFT JOIN ' . $this->handler->db->prefix('newbb_reads_topic') . ' AS r ON r.read_item = t.topic_id AND r.uid = ' . $read_uid . ' ';
0 ignored issues
show
Bug introduced by
The property db does not exist on boolean.
Loading history...
238
                        $this->query['where'][] = 'r.post_id = t.topic_last_post_id';
239
                    } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
240
                    }
241
                    // END irmtfan change criteria to get from uid p.uid = last post submit user id
242
                    // User cookie
243
                } elseif (1 == $this->config['read_mode']) {
244
                    // START irmtfan fix read_mode = 1 bugs - for all users (member and anon)
245
                    $startdate = !empty($this->vars['since']) ? (time() - newbbGetSinceTime($this->vars['since'])) : 0;
246
                    if ($lastvisit = max($GLOBALS['last_visit'], $startdate)) {
247
                        $readmode1query = '';
248
                        if ($lastvisit > $startdate) {
249
                            $readmode1query = 'p.post_time < ' . $lastvisit;
250
                        }
251
                        $topics         = [];
252
                        $topic_lastread = newbbGetCookie('LT', true);
253
                        if (count($topic_lastread) > 0) {
254
                            foreach ($topic_lastread as $id => $time) {
255
                                if ($time > $lastvisit) {
256
                                    $topics[] = $id;
257
                                }
258
                            }
259
                        }
260
                        if (count($topics) > 0) {
261
                            $topicquery = ' t.topic_id IN (' . implode(',', $topics) . ')';
262
                            // because it should be OR
263
                            $readmode1query = !empty($readmode1query) ? '(' . $readmode1query . ' OR ' . $topicquery . ')' : $topicquery;
264
                        }
265
                        $this->query['where'][] = $readmode1query;
266
                    }
267
                    // END irmtfan fix read_mode = 1 bugs - for all users (member and anon)
268
                }
269
                break;
270
271
            case 'unread':
272
                // Skip
273
                if (empty($this->config['read_mode'])) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
274
                    // Use database
275
                } elseif (2 == $this->config['read_mode']) {
276
                    // START irmtfan use read_uid to find the unread posts when the user is logged in
277
                    $read_uid = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0;
278
                    if (!empty($read_uid)) {
279
                        $this->query['join'][]  = 'LEFT JOIN ' . $this->handler->db->prefix('newbb_reads_topic') . ' AS r ON r.read_item = t.topic_id AND r.uid = ' . $read_uid . ' ';
280
                        $this->query['where'][] = '(r.read_id IS NULL OR r.post_id < t.topic_last_post_id)';
281
                    } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
282
                    }
283
                    // END irmtfan change criteria to get from uid p.uid = last post submit user id
284
                    // User cookie
285
                } elseif (1 == $this->config['read_mode']) {
286
                    // START irmtfan fix read_mode = 1 bugs - for all users (member and anon)
287
                    $startdate = !empty($this->vars['since']) ? (time() - newbbGetSinceTime($this->vars['since'])) : 0;
288
                    if ($lastvisit = max($GLOBALS['last_visit'], $startdate)) {
289
                        if ($lastvisit > $startdate) {
290
                            $this->query['where'][] = 'p.post_time > ' . $lastvisit;
291
                        }
292
                        $topics         = [];
293
                        $topic_lastread = newbbGetCookie('LT', true);
294
                        if (count($topic_lastread) > 0) {
295
                            foreach ($topic_lastread as $id => $time) {
296
                                if ($time > $lastvisit) {
297
                                    $topics[] = $id;
298
                                }
299
                            }
300
                        }
301
                        if (count($topics) > 0) {
302
                            $this->query['where'][] = ' t.topic_id NOT IN (' . implode(',', $topics) . ')';
303
                        }
304
                    }
305
                    // END irmtfan fix read_mode = 1 bugs - for all users (member and anon)
306
                }
307
                break;
308
309
            case 'pending':
310
                if ($this->userlevel < 2) {
311
                    $this->noperm = true;
312
                } else {
313
                    $this->query['where'][] = 't.approved = 0';
314
                }
315
                break;
316
317
            case 'deleted':
318
                if ($this->userlevel < 2) {
319
                    $this->noperm = true;
320
                } else {
321
                    $this->query['where'][] = 't.approved = -1';
322
                }
323
                break;
324
325
            case 'all': // For viewall.php; do not display sticky topics at first
326
            case 'active': // same as 'all'
327
                $this->query['where'][] = 't.approved = 1';
328
                break;
329
330
            default: // irmtfan do nothing
331
                break;
332
        }
333
    }
334
335
    /**
336
     * @param $var
337
     * @param $val
338
     */
339
    public function parseVar($var, $val)
340
    {
341
        switch ($var) {
342
            case 'forum':
343
                /** @var Newbb\ForumHandler $forumHandler */
344
                $forumHandler = Newbb\Helper::getInstance()->getHandler('Forum');
345
                // START irmtfan - get forum Ids by values. parse positive values to forum IDs and negative values to category IDs. value=0 => all valid forums
346
                // Get accessible forums
347
                $accessForums = $forumHandler->getIdsByValues(array_map('intval', @explode('|', $val)));
0 ignored issues
show
Bug introduced by
array_map('intval', @explode('|', $val)) of type array is incompatible with the type XoopsModules\Newbb\text|integer expected by parameter $values of XoopsModules\Newbb\ForumHandler::getIdsByValues(). ( Ignorable by Annotation )

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

347
                $accessForums = $forumHandler->getIdsByValues(/** @scrutinizer ignore-type */ array_map('intval', @explode('|', $val)));
Loading history...
348
                // Filter specified forums if any
349
                //if (!empty($val) && $_forums = @explode('|', $val)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
350
                //$accessForums = array_intersect($accessForums, array_map('intval', $_forums));
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
351
                //}
352
                $this->vars['forum'] = $this->setVar('forum', $accessForums);
353
                // END irmtfan - get forum Ids by values. parse positive values to forum IDs and negative values to category IDs. value=0 => all valid forums
354
355
                if (empty($accessForums)) {
356
                    $this->noperm = true;
357
                    // irmtfan - it just return return the forum_id only when the forum_id is the first allowed forum - no need for this code implode is enough removed.
358
                    //} elseif (count($accessForums) === 1) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
359
                    //$this->query["where"][] = "t.forum_id = " . $accessForums[0];
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
360
                } else {
361
                    $this->query['where'][] = 't.forum_id IN ( ' . implode(', ', $accessForums) . ' )';
362
                }
363
                break;
364
365
            case 'uid': // irmtfan add multi topic poster
366
                if (-1 !== $val) {
367
                    $val                    = implode(',', array_map('intval', explode(',', $val)));
368
                    $this->query['where'][] = 't.topic_poster IN ( ' . $val . ' )';
369
                }
370
                break;
371
            case 'lastposter': // irmtfan add multi lastposter
372
                if (-1 !== $val) {
373
                    $val                    = implode(',', array_map('intval', explode(',', $val)));
374
                    $this->query['where'][] = 'p.uid IN ( ' . $val . ' )';
375
                }
376
                break;
377
378
            case 'since':
379
                if (!empty($val)) {
380
                    // START irmtfan if unread && read_mode = 1 and last_visit > startdate do not add where query | to accept multiple status
381
                    $startdate = time() - newbbGetSinceTime($val);
382
                    if (in_array('unread', explode(',', $this->vars['status'], true)) && 1 == $this->config['read_mode']
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type integer expected by parameter $limit of explode(). ( Ignorable by Annotation )

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

382
                    if (in_array('unread', explode(',', $this->vars['status'], /** @scrutinizer ignore-type */ true)) && 1 == $this->config['read_mode']
Loading history...
383
                        && $GLOBALS['last_visit'] > $startdate) {
384
                        break;
385
                    }
386
                    // irmtfan digest_time | to accept multiple status
387
                    if (in_array('digest', explode(',', $this->vars['status'], true))) {
388
                        $this->query['where'][] = 't.digest_time > ' . $startdate;
389
                    }
390
                    // irmtfan - should be >= instead of =
391
                    $this->query['where'][] = 'p.post_time >= ' . $startdate;
392
                    // END irmtfan if unread && read_mode = 1 and last_visit > startdate do not add where query
393
                }
394
                break;
395
396
            case 'type':
397
                if (!empty($val)) {
398
                    $this->query['where'][] = 't.type_id = ' . $val;
399
                }
400
                break;
401
402
            case 'status':
403
                // START irmtfan to accept multiple status
404
                $val = explode(',', $val);
405
                // irmtfan - add 'all' to always parse t.approved = 1
406
                if (0 === count(array_intersect($val, ['all', 'active', 'pending', 'deleted']))) {
407
                    $val[] = 'all';
408
                }
409
                foreach ($val as $key => $status) {
410
                    $this->myParseStatus($status);
411
                }
412
                // END irmtfan to accept multiple status
413
                break;
414
415
            case 'sort':
416
                if ($sort = $this->getSort($val, 'sort')) {
417
                    $this->query['sort'][] = $sort . (empty($this->vars['order']) ? ' DESC' : ' ASC');
0 ignored issues
show
Bug introduced by
Are you sure $sort of type array can be used in concatenation? ( Ignorable by Annotation )

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

417
                    $this->query['sort'][] = /** @scrutinizer ignore-type */ $sort . (empty($this->vars['order']) ? ' DESC' : ' ASC');
Loading history...
418
                } else { // irmtfan if sort is not in the list
419
                    $this->query['sort'][] = 't.topic_last_post_id' . (empty($this->vars['order']) ? ' DESC' : ' ASC');
420
                }
421
                break;
422
423
            default:
424
                break;
425
        }
426
    }
427
428
    /**
429
     * @return bool
430
     */
431
    public function parseVars()
432
    {
433
        static $parsed;
434
        // irmtfan - force to parse vars (run against static vars)
435
        if (isset($parsed) && !$this->force) {
436
            return true;
437
        }
438
439
        if (!isset($this->vars['forum'])) {
440
            $this->vars['forum'] = null;
441
        }
442
        //irmtfan parse status for rendering topic correctly - if empty($_GET(status)) it will show all topics include deleted and pendings. 'all' instead of all
443
        if (!isset($this->vars['status'])) {
444
            $this->vars['status'] = 'all';
445
        }
446
        // irmtfan if sort is not set or is empty get a default sort- if empty($_GET(sort)) | if sort=null eg: /list.topic.php?sort=
447
        if (empty($this->vars['sort'])) {
448
            $this->vars['sort'] = 'lastpost';
449
        } // use lastpost instead of sticky
450
451
        foreach ($this->vars as $var => $val) {
452
            $this->parseVar($var, $val);
453
            if (empty($val)) {
454
                unset($this->vars[$var]);
455
            }
456
        }
457
        $parsed = true;
458
459
        return true;
460
    }
461
462
    /**
463
     * @param  null $header
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $var is correct as it would always require null to be passed?
Loading history...
Documentation Bug introduced by
Are you sure the doc-type for parameter $header is correct as it would always require null to be passed?
Loading history...
464
     * @param  null $var
465
     * @return array|null
466
     */
467
    public function getSort($header = null, $var = null)
468
    {
469
        $headers = [
470
            'topic'           => [
471
                'title' => _MD_NEWBB_TOPICS,
472
                'sort'  => 't.topic_title'
473
            ],
474
            'forum'           => [
475
                'title' => _MD_NEWBB_FORUM,
476
                'sort'  => 't.forum_id'
477
            ],
478
            'poster'          => [
479
                'title' => _MD_NEWBB_TOPICPOSTER, /*irmtfan _MD_NEWBB_POSTER to _MD_NEWBB_TOPICPOSTER*/
480
                'sort'  => 't.topic_poster'
481
            ],
482
            'replies'         => [
483
                'title' => _MD_NEWBB_REPLIES,
484
                'sort'  => 't.topic_replies'
485
            ],
486
            'views'           => [
487
                'title' => _MD_NEWBB_VIEWS,
488
                'sort'  => 't.topic_views'
489
            ],
490
            'lastpost'        => [ // irmtfan show topic_page_jump_icon smarty
491
                                   'title' => _MD_NEWBB_LASTPOST,
492
                                   /*irmtfan _MD_NEWBB_DATE to _MD_NEWBB_LASTPOSTTIME again change to _MD_LASTPOST*/
493
                                   'sort'  => 't.topic_last_post_id'
494
            ],
495
            // START irmtfan add more sorts
496
            'lastposttime'    => [ // irmtfan same as lastpost
497
                                   'title' => _MD_NEWBB_LASTPOSTTIME,
498
                                   'sort'  => 't.topic_last_post_id'
499
            ],
500
            'lastposter'      => [ // irmtfan
501
                                   'title' => _MD_NEWBB_POSTER,
502
                                   'sort'  => 'p.uid',// poster uid
503
            ],
504
            'lastpostmsgicon' => [ // irmtfan
505
                                   'title' => _MD_NEWBB_MESSAGEICON,
506
                                   'sort'  => 'p.icon',// post message icon
507
            ],
508
            'ratings'         => [
509
                'title' => _MD_NEWBB_RATINGS,
510
                'sort'  => 't.rating', // irmtfan t.topic_rating to t.rating
511
            ],
512
            'votes'           => [
513
                'title' => _MD_NEWBB_VOTES,
514
                'sort'  => 't.votes'
515
            ],
516
            'publish'         => [
517
                'title' => _MD_NEWBB_TOPICTIME,
518
                'sort'  => 't.topic_id'
519
            ],
520
            'digest'          => [
521
                'title' => _MD_NEWBB_DIGEST,
522
                'sort'  => 't.digest_time'
523
            ],
524
            'sticky'          => [
525
                'title' => _MD_NEWBB_STICKY,
526
                'sort'  => 't.topic_sticky'
527
            ],
528
            'lock'            => [
529
                'title' => _MD_NEWBB_LOCK,
530
                'sort'  => 't.topic_status'
531
            ],
532
            'poll'            => [
533
                'title' => _MD_NEWBB_POLL_POLL,
534
                'sort'  => 't.poll_id'
535
            ]
536
        ];
537
        $types   = $this->getTypes();
538
        if (!empty($types)) {
539
            $headers['type'] = [
540
                'title' => _MD_NEWBB_TYPE,
541
                'sort'  => 't.type_id'
542
            ];
543
        }
544
        if (2 == $this->userlevel) {
545
            $headers['approve'] = [
546
                'title' => _MD_NEWBB_APPROVE,
547
                'sort'  => 't.approved'
548
            ];
549
        }
550
        // END irmtfan add more sorts
551
        if (empty($header) && empty($var)) {
552
            return $headers;
553
        }
554
        if (!empty($var) && !empty($header)) {
555
            return @$headers[$header][$var];
556
        }
557
        if (empty($var)) {
558
            return @$headers[$header];
559
        }
560
        $ret = null;
561
        foreach (array_keys($headers) as $key) {
562
            $ret[$key] = @$headers[$key][$var];
563
        }
564
565
        return $ret;
566
    }
567
568
    // START irmtfan add Display topic headers function
569
570
    /**
571
     * @param  null $header
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $header is correct as it would always require null to be passed?
Loading history...
572
     * @return array
573
     */
574
    public function getHeader($header = null)
575
    {
576
        $headersSort = $this->getSort('', 'title');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $headersSort is correct as $this->getSort('', 'title') targeting XoopsModules\Newbb\TopicRenderer::getSort() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
577
        // additional headers - important: those cannot be in sort anyway
578
        $headers = array_merge($headersSort, [
579
            'attachment' => _MD_NEWBB_TOPICSHASATT, // show attachment smarty
580
            'read'       => _MD_NEWBB_MARK_UNREAD . '|' . _MD_NEWBB_MARK_READ, // read/unread show topic_folder smarty
581
            'pagenav'    => _MD_NEWBB_PAGENAV_DISPLAY, // show topic_page_jump smarty - sort by topic_replies?
582
        ]);
583
584
        return $this->getFromKeys($headers, $header);
585
    }
586
587
    // END irmtfan add Display topic headers function
588
589
    /**
590
     * @param  null $type
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $status is correct as it would always require null to be passed?
Loading history...
Documentation Bug introduced by
Are you sure the doc-type for parameter $type is correct as it would always require null to be passed?
Loading history...
591
     * @param  null $status
592
     * @return array
593
     */
594
    public function getStatus($type = null, $status = null)
595
    {
596
        $links       = [
597
            //""            => "", /* irmtfan remove empty array */
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
598
            'all'       => _ALL,
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Newbb\_ALL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
599
            'digest'    => _MD_NEWBB_DIGEST,
600
            'undigest'  => _MD_NEWBB_UNDIGEST, // irmtfan add
601
            'sticky'    => _MD_NEWBB_STICKY, // irmtfan add
602
            'unsticky'  => _MD_NEWBB_UNSTICKY, // irmtfan add
603
            'lock'      => _MD_NEWBB_LOCK, // irmtfan add
604
            'unlock'    => _MD_NEWBB_UNLOCK, // irmtfan add
605
            'poll'      => _MD_NEWBB_TOPICHASPOLL, // irmtfan add
606
            'unpoll'    => _MD_NEWBB_TOPICHASNOTPOLL, // irmtfan add
607
            'voted'     => _MD_NEWBB_VOTED, // irmtfan add
608
            'unvoted'   => _MD_NEWBB_UNVOTED, // irmtfan add
609
            'viewed'    => _MD_NEWBB_VIEWED, // irmtfan add
610
            'unviewed'  => _MD_NEWBB_UNVIEWED, // irmtfan add
611
            'replied'   => _MD_NEWBB_REPLIED, // irmtfan add
612
            'unreplied' => _MD_NEWBB_UNREPLIED,
613
            'read'      => _MD_NEWBB_READ, // irmtfan add
614
            'unread'    => _MD_NEWBB_UNREAD
615
        ];
616
        $links_admin = [
617
            'active'  => _MD_NEWBB_TYPE_ADMIN,
618
            'pending' => _MD_NEWBB_TYPE_PENDING,
619
            'deleted' => _MD_NEWBB_TYPE_DELETED
620
        ];
621
622
        // all status, for admin
623
        if ($type > 1) {
624
            $links = array_merge($links, $links_admin);// irmtfan to accept multiple status
625
        }
626
627
        return $this->getFromKeys($links, $status); // irmtfan to accept multiple status
628
    }
629
630
    /**
631
     * @param \Smarty $xoopsTpl
632
     * @throws \RuntimeException
633
     */
634
    public function buildSelection(\Smarty $xoopsTpl)
0 ignored issues
show
Bug introduced by
The type Smarty was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
635
    {
636
        $selection         = ['action' => $this->page];
637
        $selection['vars'] = $this->vars;
638
        include_once __DIR__ . '/../include/functions.forum.php';
639
        $forum_selected     = empty($this->vars['forum']) ? null : explode('|', @$this->vars['forum']);
640
        $selection['forum'] = '<select name="forum[]" multiple="multiple">';
641
        $selection['forum'] .= '<option value="0">' . _MD_NEWBB_ALL . '</option>';
642
        $selection['forum'] .= newbbForumSelectBox($forum_selected);
643
        $selection['forum'] .= '</select>';
644
645
        $sort_selected     = $this->vars['sort'];
646
        $sorts             = $this->getSort('', 'title');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $sorts is correct as $this->getSort('', 'title') targeting XoopsModules\Newbb\TopicRenderer::getSort() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
647
        $selection['sort'] = "<select name='sort'>";
648
        if (!is_array($sorts)) {
0 ignored issues
show
introduced by
The condition is_array($sorts) is always false.
Loading history...
649
            throw new \RuntimeException('$sorts must be an array.');
650
        }
651
        foreach ($sorts as $sort => $title) {
652
            $selection['sort'] .= "<option value='" . $sort . "' " . (($sort == $sort_selected) ? " selected='selected'" : '') . '>' . $title . '</option>';
653
        }
654
        $selection['sort'] .= '</select>';
655
656
        $selection['order'] = "<select name='order'>";
657
        $selection['order'] .= "<option value='0' " . (empty($this->vars['order']) ? " selected='selected'" : '') . '>' . _DESCENDING . '</option>';
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Newbb\_DESCENDING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
658
        $selection['order'] .= "<option value='1' " . (!empty($this->vars['order']) ? " selected='selected'" : '') . '>' . _ASCENDING . '</option>';
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Newbb\_ASCENDING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
659
        $selection['order'] .= '</select>';
660
661
        $since              = isset($this->vars['since']) ? $this->vars['since'] : $this->config['since_default'];
662
        $selection['since'] = newbbSinceSelectBox($since);
663
664
        $xoopsTpl->assign_by_ref('selection', $selection);
665
    }
666
667
    /**
668
     * @param \Smarty $xoopsTpl
669
     */
670
    public function buildSearch(\Smarty $xoopsTpl)
671
    {
672
        $search             = [];
673
        $search['forum']    = @$this->vars['forum'];
674
        $search['since']    = @$this->vars['since'];
675
        $search['searchin'] = 'both';
676
677
        $xoopsTpl->assign_by_ref('search', $search);
678
    }
679
680
    /**
681
     * @param \Smarty $xoopsTpl
682
     * @throws \RuntimeException
683
     */
684
    public function buildHeaders(\Smarty $xoopsTpl)
685
    {
686
        $args = [];
687
        foreach ($this->vars as $var => $val) {
688
            if ('sort' === $var || 'order' === $var) {
689
                continue;
690
            }
691
            $args[] = "{$var}={$val}";
692
        }
693
694
        $headers = $this->getSort('', 'title');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $headers is correct as $this->getSort('', 'title') targeting XoopsModules\Newbb\TopicRenderer::getSort() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
695
        if (!is_array($headers)) {
0 ignored issues
show
introduced by
The condition is_array($headers) is always false.
Loading history...
696
            throw new \RuntimeException('$headers must be an array.');
697
        }
698
        foreach ($headers as $header => $title) {
699
            $_args = ["sort={$header}"];
700
            if (@$this->vars['sort'] == $header) {
701
                $_args[] = 'order=' . ((@$this->vars['order'] + 1) % 2);
702
            }
703
            $headers_data[$header]['title'] = $title;
704
            $headers_data[$header]['link']  = $this->page . '?' . implode('&amp;', array_merge($args, $_args));
705
        }
706
        $xoopsTpl->assign_by_ref('headers', $headers_data);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $headers_data seems to be defined by a foreach iteration on line 698. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
707
    }
708
709
    /**
710
     * @param \Smarty $xoopsTpl
711
     */
712
    public function buildFilters(\Smarty $xoopsTpl)
713
    {
714
        $args = [];
715
        foreach ($this->vars as $var => $val) {
716
            if ('status' === $var) {
717
                continue;
718
            }
719
            $args[] = "{$var}={$val}";
720
        }
721
722
        $links = $this->getStatus($this->userlevel);
723
724
        $status = [];
725
        foreach ($links as $link => $title) {
726
            $_args                  = ["status={$link}"];
727
            $status[$link]['title'] = $title;
728
            $status[$link]['link']  = $this->page . '?' . implode('&amp;', array_merge($args, $_args));
729
        }
730
        $xoopsTpl->assign_by_ref('filters', $status);
731
    }
732
733
    /**
734
     * @param  null $type_id
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $type_id is correct as it would always require null to be passed?
Loading history...
735
     * @return mixed
736
     */
737
    public function getTypes($type_id = null)
738
    {
739
        static $types;
740
        if (!isset($types)) {
741
            /** @var Newbb\TypeHandler $typeHandler */
742
            $typeHandler = Newbb\Helper::getInstance()->getHandler('Type');
743
744
            $types = $typeHandler->getByForum(explode('|', @$this->vars['forum']));
745
        }
746
747
        if (empty($type_id)) {
748
            return $types;
749
        }
750
751
        return @$types[$type_id];
752
    }
753
754
    /**
755
     * @param  \Smarty $xoopsTpl
756
     * @return bool
757
     */
758
    public function buildTypes(\Smarty $xoopsTpl)
759
    {
760
        $status = '';
761
        if (!$types = $this->getTypes()) {
762
            return true;
763
        }
764
765
        $args = [];
766
        foreach ($this->vars as $var => $val) {
767
            if ('type' === $var) {
768
                continue;
769
            }
770
            $args[] = "{$var}={$val}";
771
        }
772
773
        foreach ($types as $id => $type) {
774
            $_args                = ["type={$id}"];
775
            $status[$id]['title'] = $type['type_name'];
776
            $status[$id]['link']  = $this->page . '?' . implode('&amp;', array_merge($args, $_args));
777
        }
778
        $xoopsTpl->assign_by_ref('types', $status);
779
    }
780
781
    /**
782
     * @param  \Smarty $xoopsTpl
783
     * @return bool
784
     */
785
    public function buildCurrent(\Smarty $xoopsTpl)
786
    {
787
        if (empty($this->vars['status']) && !$this->is_multiple) {
788
            return true;
789
        }
790
791
        $args = [];
792
        foreach ($this->vars as $var => $val) {
793
            $args[] = "{$var}={$val}";
794
        }
795
796
        $status          = [];
797
        $status['title'] = implode(',', $this->getStatus($this->userlevel, $this->vars['status'])); // irmtfan to accept multiple status
798
        //$status['link'] = $this->page.(empty($this->vars['status']) ? '' : '?status='.$this->vars['status']);
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
799
        $status['link'] = $this->page . (empty($args) ? '' : '?' . implode('&amp;', $args));
800
801
        $xoopsTpl->assign_by_ref('current', $status);
802
    }
803
804
    /**
805
     * @param \Smarty $xoopsTpl
806
     */
807
    public function buildPagenav(\Smarty $xoopsTpl)
808
    {
809
        $count_topic = $this->getCount();
810
        if ($count_topic > $this->config['topics_per_page']) {
811
            $args = [];
812
            foreach ($this->vars as $var => $val) {
813
                if ('start' === $var) {
814
                    continue;
815
                }
816
                $args[] = "{$var}={$val}";
817
            }
818
            require_once $GLOBALS['xoops']->path('class/pagenav.php');
819
            $nav = new \XoopsPageNav($count_topic, $this->config['topics_per_page'], @$this->vars['start'], 'start', implode('&amp;', $args));
0 ignored issues
show
Bug introduced by
The type XoopsPageNav was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
820
            if (isset($GLOBALS['xoopsModuleConfig']['do_rewrite'])) {
821
                $nav->url = formatURL(Request::getString('SERVER_NAME', '', 'SERVER')) . ' /' . $nav->url;
0 ignored issues
show
Bug introduced by
The function formatURL was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

821
                $nav->url = /** @scrutinizer ignore-call */ formatURL(Request::getString('SERVER_NAME', '', 'SERVER')) . ' /' . $nav->url;
Loading history...
822
            }
823
            if ('select' === $this->config['pagenav_display']) {
824
                $navi = $nav->renderSelect();
825
            } elseif ('image' === $this->config['pagenav_display']) {
826
                $navi = $nav->renderImageNav(4);
827
            } else {
828
                $navi = $nav->renderNav(4);
829
            }
830
            $xoopsTpl->assign('pagenav', $navi);
831
        } else {
832
            $xoopsTpl->assign('pagenav', '');
833
        }
834
    }
835
836
    /**
837
     * @return int
838
     */
839
    public function getCount()
840
    {
841
        if ($this->noperm) {
842
            return 0;
843
        }
844
845
        $selects = [];
846
        $froms   = [];
847
        $joins   = [];
848
        $wheres  = [];
849
850
        // topic fields
851
        $selects[] = 'COUNT(*)';
852
853
        $froms[]  = $this->handler->db->prefix('newbb_topics') . ' AS t ';
0 ignored issues
show
Bug introduced by
The property db does not exist on boolean.
Loading history...
854
        $joins[]  = 'LEFT JOIN ' . $this->handler->db->prefix('newbb_posts') . ' AS p ON p.post_id = t.topic_last_post_id';
855
        $wheres[] = '1 = 1';
856
857
        $sql = '    SELECT ' . implode(', ', $selects) . '     FROM ' . implode(', ', $froms) . '        ' . implode(' ', $joins) . (!empty($this->query['join']) ? '        ' . implode(' ', $this->query['join']) : '') . // irmtfan bug fix: Undefined index: join when post_excerpt = 0
858
               '     WHERE ' . implode(' AND ', $wheres) . '        AND ' . @implode(' AND ', @$this->query['where']);
859
860
        if (!$result = $this->handler->db->query($sql)) {
861
            return 0;
862
        }
863
        list($count) = $this->handler->db->fetchRow($result);
864
865
        return $count;
866
    }
867
868
    /**
869
     * @param  \Smarty $xoopsTpl
870
     * @return array|void
871
     */
872
    public function renderTopics(\Smarty $xoopsTpl = null)
873
    {
874
        $myts = \MyTextSanitizer::getInstance(); // irmtfan Instanciate
0 ignored issues
show
Bug introduced by
The type MyTextSanitizer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
875
876
        $ret = [];
877
        //$this->parseVars();
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
878
879
        if ($this->noperm) {
880
            if (is_object($xoopsTpl)) {
881
                $xoopsTpl->assign_by_ref('topics', $ret);
882
883
                return;
884
            }
885
886
            return $ret;
887
        }
888
889
        $selects = [];
890
        $froms   = [];
891
        $joins   = [];
892
        $wheres  = [];
893
894
        // topic fields
895
        $selects[] = 't.*';
896
        // post fields
897
        $selects[] = 'p.post_time as last_post_time, p.poster_name as last_poster_name, p.icon, p.post_id, p.uid';
898
899
        $froms[]  = $this->handler->db->prefix('newbb_topics') . ' AS t ';
0 ignored issues
show
Bug introduced by
The property db does not exist on boolean.
Loading history...
900
        $joins[]  = 'LEFT JOIN ' . $this->handler->db->prefix('newbb_posts') . ' AS p ON p.post_id = t.topic_last_post_id';
901
        $wheres[] = '1 = 1';
902
903
        if (!empty($this->config['post_excerpt'])) {
904
            $selects[]             = 'p.post_karma, p.require_reply, pt.post_text';
905
            $this->query['join'][] = 'LEFT JOIN ' . $this->handler->db->prefix('newbb_posts_text') . ' AS pt ON pt.post_id = t.topic_last_post_id';
906
        }
907
        //if (empty($this->query["sort"])) $this->query["sort"][] = 't.topic_last_post_id DESC'; // irmtfan commented no need
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
908
909
        $sql = '    SELECT ' . implode(', ', $selects) . '     FROM ' . implode(', ', $froms) . '        ' . implode(' ', $joins) . (!empty($this->query['join']) ? '        ' . implode(' ', $this->query['join']) : '') . // irmtfan bug fix: Undefined index join when post_excerpt = 0
910
               '     WHERE ' . implode(' AND ', $wheres) . '        AND ' . @implode(' AND ', @$this->query['where']) . '     ORDER BY ' . implode(', ', $this->query['sort']);
911
912
        if (!$result = $this->handler->db->query($sql, $this->config['topics_per_page'], @$this->vars['start'])) {
913
            if (is_object($xoopsTpl)) {
914
                $xoopsTpl->assign_by_ref('topics', $ret);
915
916
                return;
917
            }
918
919
            return $ret;
920
        }
921
922
        include_once __DIR__ . '/../include/functions.render.php';
923
        include_once __DIR__ . '/../include/functions.session.php';
924
        include_once __DIR__ . '/../include/functions.time.php';
925
        include_once __DIR__ . '/../include/functions.read.php';
926
        include_once __DIR__ . '/../include/functions.topic.php';
927
928
        $sticky    = 0;
929
        $topics    = [];
930
        $posters   = [];
931
        $reads     = [];
932
        $types     = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $types is dead and can be removed.
Loading history...
933
        $forums    = [];
934
        $anonymous = $myts->htmlSpecialChars($GLOBALS['xoopsConfig']['anonymous']);
935
936
        while (false !== ($myrow = $this->handler->db->fetchArray($result))) {
937
            if ($myrow['topic_sticky']) {
938
                ++$sticky;
939
            }
940
941
            // ------------------------------------------------------
942
            // START irmtfan remove topic_icon hardcode smarty
943
            // topic_icon: just regular topic_icon
944
            if (!empty($myrow['icon'])) {
945
                $topic_icon = '<img align="middle" src="' . XOOPS_URL . '/images/subject/' . htmlspecialchars($myrow['icon']) . '" alt="" />';
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Newbb\XOOPS_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
946
            } else {
947
                $topic_icon = '<img align="middle" src="' . XOOPS_URL . '/images/icons/no_posticon.gif" alt="" />';
948
            }
949
            // END irmtfan remove topic_icon hardcode smarty
950
951
            // ------------------------------------------------------
952
            // rating_img
953
            $rating = number_format($myrow['rating'] / 2, 0);
954
            // irmtfan - add alt key for rating
955
            if ($rating < 1) {
956
                $rating_img = newbbDisplayImage('blank');
957
            } else {
958
                $rating_img = newbbDisplayImage('rate' . $rating, constant('_MD_NEWBB_RATE' . $rating));
959
            }
960
961
            // ------------------------------------------------------
962
            // topic_page_jump
963
            $topic_page_jump      = '';
964
            $topic_page_jump_icon = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $topic_page_jump_icon is dead and can be removed.
Loading history...
965
            $totalpages           = ceil(($myrow['topic_replies'] + 1) / $this->config['posts_per_page']);
966
            if ($totalpages > 1) {
967
                $topic_page_jump .= '&nbsp;&nbsp;';
968
                $append          = false;
969
                for ($i = 1; $i <= $totalpages; ++$i) {
970
                    if ($i > 3 && $i < $totalpages) {
971
                        if (!$append) {
972
                            $topic_page_jump .= '...';
973
                            $append          = true;
974
                        }
975
                    } else {
976
                        $topic_page_jump .= '[<a href="' . XOOPS_URL . '/modules/newbb/viewtopic.php?topic_id=' . $myrow['topic_id'] . '&amp;start=' . (($i - 1) * $this->config['posts_per_page']) . '">' . $i . '</a>]';
977
                        // irmtfan remove here and move
978
                        //$topic_page_jump_icon = "<a href='" . XOOPS_URL . "/modules/newbb/viewtopic.php?topic_id=" . $myrow['topic_id'] . "&amp;start=" . (($i - 1) * $this->config['posts_per_page']) . "" . "'>" . newbbDisplayImage('document',_MD_NEWBB_GOTOLASTPOST) . '</a>';
0 ignored issues
show
Unused Code Comprehensibility introduced by
41% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
979
                    }
980
                }
981
            }
982
            // irmtfan - move here for both topics with and without pages - change topic_id to post_id
983
            $topic_page_jump_icon = "<a href='" . XOOPS_URL . '/modules/newbb/viewtopic.php?post_id=' . $myrow['topic_last_post_id'] . '' . "'>" . newbbDisplayImage('lastposticon', _MD_NEWBB_GOTOLASTPOST) . '</a>';
984
985
            // ------------------------------------------------------
986
            // => topic array
987
988
            $topic_title = $myts->htmlSpecialChars($myrow['topic_title']);
989
            // irmtfan use topic_title_excerpt for block topic title length
990
            $topic_title_excerpt = $topic_title;
991
            if (!empty($this->config['topic_title_excerpt'])) {
992
                $topic_title_excerpt = xoops_substr($topic_title, 0, $this->config['topic_title_excerpt']);
0 ignored issues
show
Bug introduced by
The function xoops_substr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

992
                $topic_title_excerpt = /** @scrutinizer ignore-call */ xoops_substr($topic_title, 0, $this->config['topic_title_excerpt']);
Loading history...
993
            }
994
            // irmtfan hardcode class commented
995
            //if ($myrow['topic_digest']) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
996
            //   $topic_title = "<span class='digest'>" . $topic_title . "</span>";
997
            //}
998
999
            if (empty($this->config['post_excerpt'])) {
1000
                $topic_excerpt = '';
1001
            } elseif (($myrow['post_karma'] > 0 || $myrow['require_reply'] > 0) && !newbbIsAdmin($myrow['forum_id'])) {
1002
                $topic_excerpt = '';
1003
            } else {
1004
                $topic_excerpt = xoops_substr(newbbHtml2text($myts->displayTarea($myrow['post_text'])), 0, $this->config['post_excerpt']);
1005
                $topic_excerpt = str_replace('[', '&#91;', $myts->htmlSpecialChars($topic_excerpt));
1006
            }
1007
1008
            $topics[$myrow['topic_id']] = [
1009
                'topic_id'               => $myrow['topic_id'],
1010
                'topic_icon'             => $topic_icon,
1011
                'type_id'                => $myrow['type_id'],
1012
                'topic_title_excerpt'    => $topic_title_excerpt,
1013
                //irmtfan use topic_title_excerpt
1014
                //'topic_link'    => XOOPS_URL . '/modules/newbb/viewtopic.php?topic_id=' . $myrow['topic_id'], // . '&amp;forum=' . $myrow['forum_id'], // irmtfan comment
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1015
                'topic_link'             => 'viewtopic.php?topic_id=' . $myrow['topic_id'],
1016
                // irmtfan remove hardcode link
1017
                'rating_img'             => $rating_img,
1018
                'votes'                  => $myrow['votes'],
1019
                //irmtfan added
1020
                'topic_page_jump'        => $topic_page_jump,
1021
                'topic_page_jump_icon'   => $topic_page_jump_icon,
1022
                'topic_replies'          => $myrow['topic_replies'],
1023
                'topic_poster_uid'       => $myrow['topic_poster'],
1024
                'topic_poster_name'      => !empty($myrow['poster_name']) ? $myts->htmlSpecialChars($myrow['poster_name']) : $anonymous,
1025
                'topic_views'            => $myrow['topic_views'],
1026
                'topic_time'             => newbbFormatTimestamp($myrow['topic_time']),
1027
                'topic_last_post_id'     => $myrow['topic_last_post_id'],
1028
                //irmtfan added
1029
                'topic_last_posttime'    => newbbFormatTimestamp($myrow['last_post_time']),
1030
                'topic_last_poster_uid'  => $myrow['uid'],
1031
                'topic_last_poster_name' => !empty($myrow['last_poster_name']) ? $myts->htmlSpecialChars($myrow['last_poster_name']) : $anonymous,
1032
                'topic_forum'            => $myrow['forum_id'],
1033
                'topic_excerpt'          => $topic_excerpt,
1034
                'sticky'                 => $myrow['topic_sticky'] ? newbbDisplayImage('topic_sticky', _MD_NEWBB_TOPICSTICKY) : '',
1035
                // irmtfan bug fixed
1036
                'lock'                   => $myrow['topic_status'] ? newbbDisplayImage('topic_locked', _MD_NEWBB_TOPICLOCK) : '',
1037
                //irmtfan added
1038
                'digest'                 => $myrow['topic_digest'] ? newbbDisplayImage('topic_digest', _MD_NEWBB_TOPICDIGEST) : '',
1039
                //irmtfan added
1040
                'poll'                   => $myrow['topic_haspoll'] ? newbbDisplayImage('poll', _MD_NEWBB_TOPICHASPOLL) : '',
1041
                //irmtfan added
1042
                'approve'                => $myrow['approved'],
1043
                //irmtfan added
1044
            ];
1045
1046
            /* users */
1047
            $posters[$myrow['topic_poster']] = 1;
1048
            $posters[$myrow['uid']]          = 1;
1049
            // reads
1050
            if (!empty($this->config['read_mode'])) {
1051
                $reads[$myrow['topic_id']] = (1 == $this->config['read_mode']) ? $myrow['last_post_time'] : $myrow['topic_last_post_id'];
1052
            }
1053
            // types
1054
            if (!empty($myrow['type_id'])) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1055
                //$types[$myrow['type_id']] = 1;
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1056
            }
1057
            // forums
1058
            $forums[$myrow['forum_id']] = 1;
1059
        }
1060
        $posters_name = newbbGetUnameFromIds(array_keys($posters), $this->config['show_realname'], true);
1061
        $topic_isRead = newbbIsRead('topic', $reads);
1062
        /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1063
        $type_list = array();
1064
        if (count($types) > 0) {
1065
            $typeHandler =  Newbb\Helper::getInstance()->getHandler('Type');
1066
            $type_list = $typeHandler->getAll(new \Criteria("type_id", "(".implode(", ", array_keys($types)).")", "IN"), null, false);
1067
        }
1068
        */
1069
        $type_list = $this->getTypes();
1070
        /** @var Newbb\ForumHandler $forumHandler */
1071
        $forumHandler = Newbb\Helper::getInstance()->getHandler('Forum');
1072
1073
        if (count($forums) > 0) {
1074
            $forum_list = $forumHandler->getAll(new \Criteria('forum_id', '(' . implode(', ', array_keys($forums)) . ')', 'IN'), ['forum_name', 'hot_threshold'], false);
0 ignored issues
show
Bug introduced by
The type Criteria was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1075
        } else {
1076
            $forum_list = $forumHandler->getAll();
1077
        }
1078
1079
        foreach (array_keys($topics) as $id) {
1080
            $topics[$id]['topic_read']       = empty($topic_isRead[$id]) ? 0 : 1; // add topic-read/topic-new smarty variable
1081
            $topics[$id]['topic_forum_link'] = '<a href="' . XOOPS_URL . '/modules/newbb/viewforum.php?forum=' . $topics[$id]['topic_forum'] . '">' . $forum_list[$topics[$id]['topic_forum']]['forum_name'] . '</a>';
1082
1083
            //irmtfan use topic_title_excerpt -- add else
1084
            if (!empty($topics[$id]['type_id']) && isset($type_list[$topics[$id]['type_id']])) {
1085
                $topics[$id]['topic_title'] = getTopicTitle($topics[$id]['topic_title_excerpt'], $type_list[$topics[$id]['type_id']]['type_name'], $type_list[$topics[$id]['type_id']]['type_color']);
1086
            } else {
1087
                $topics[$id]['topic_title'] = $topics[$id]['topic_title_excerpt'];
1088
            }
1089
            $topics[$id]['topic_poster']      = !empty($posters_name[$topics[$id]['topic_poster_uid']]) ? $posters_name[$topics[$id]['topic_poster_uid']] : $topics[$id]['topic_poster_name'];
1090
            $topics[$id]['topic_last_poster'] = !empty($posters_name[$topics[$id]['topic_last_poster_uid']]) ? $posters_name[$topics[$id]['topic_last_poster_uid']] : $topics[$id]['topic_last_poster_name'];
1091
            // ------------------------------------------------------
1092
            // START irmtfan remove hardcodes from topic_folder smarty
1093
            // topic_folder: priority: newhot -> hot/new -> regular
1094
            //list($topic_status, $topic_digest, $topic_replies) = $topics[$id]["stats"]; irmtfan
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1095
            // START irmtfan - add topic_folder_text for alt
1096
            //if ($topics[$id]["lock"] === 1) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1097
            //    $topic_folder = 'topic_locked';
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1098
            //    $topic_folder_text = _MD_NEWBB_TOPICLOCKED;
1099
            //} else {
1100
            //if ($topic_digest) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1101
            //    $topic_folder = 'topic_digest';
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1102
            //    $topic_folder_text = _MD_NEWBB_TOPICDIGEST;
1103
            if ($topics[$id]['topic_replies'] >= $forum_list[$topics[$id]['topic_forum']]['hot_threshold']) {
1104
                $topic_folder      = empty($topic_isRead[$id]) ? 'topic_hot_new' : 'topic_hot';
1105
                $topic_folder_text = empty($topic_isRead[$id]) ? _MD_NEWBB_MORETHAN : _MD_NEWBB_MORETHAN2;
1106
            } else {
1107
                $topic_folder      = empty($topic_isRead[$id]) ? 'topic_new' : 'topic';
1108
                $topic_folder_text = empty($topic_isRead[$id]) ? _MD_NEWBB_NEWPOSTS : _MD_NEWBB_NONEWPOSTS;
1109
            }
1110
            //}
1111
            // END irmtfan remove hardcodes from topic_folder smarty
1112
            $topics[$id]['topic_folder'] = newbbDisplayImage($topic_folder, $topic_folder_text);
1113
            // END irmtfan - add topic_folder_text for alt
1114
1115
            unset($topics[$id]['topic_poster_name'], $topics[$id]['topic_last_poster_name']);// irmtfan remove $topics[$id]["stats"] because it is not exist now
1116
        }
1117
1118
        if (count($topics) > 0) {
1119
            $sql = ' SELECT DISTINCT topic_id FROM ' . $this->handler->db->prefix('newbb_posts') . " WHERE attachment != ''" . ' AND topic_id IN (' . implode(',', array_keys($topics)) . ')';
1120
            if ($result = $this->handler->db->query($sql)) {
1121
                while (list($topic_id) = $this->handler->db->fetchRow($result)) {
1122
                    $topics[$topic_id]['attachment'] = '&nbsp;' . newbbDisplayImage('attachment', _MD_NEWBB_TOPICSHASATT);
1123
                }
1124
            }
1125
        }
1126
1127
        if (is_object($xoopsTpl)) {
1128
            $xoopsTpl->assign_by_ref('sticky', $sticky);
1129
            $xoopsTpl->assign_by_ref('topics', $topics);
1130
1131
            return;
1132
        }
1133
1134
        return [$topics, $sticky];
1135
    }
1136
1137
    // START irmtfan to create an array from selected keys of an array
1138
1139
    /**
1140
     * @param        $array
1141
     * @param  null  $keys
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $keys is correct as it would always require null to be passed?
Loading history...
1142
     * @return array
1143
     */
1144
    public function getFromKeys($array, $keys = null)
1145
    {
1146
        if (empty($keys)) {
1147
            return $array;
1148
        } // all keys
1149
        $keyarr = is_string($keys) ? explode(',', $keys) : $keys;
1150
        $keyarr = array_intersect(array_keys($array), $keyarr); // keys should be in array
1151
        $ret    = [];
1152
        foreach ($keyarr as $key) {
1153
            $ret[$key] = $array[$key];
1154
        }
1155
1156
        return $ret;
1157
    }
1158
    // END irmtfan to create an array from selected keys of an array
1159
}
1160