Completed
Branch master (4e8684)
by Michael
05:31 queued 02:57
created

NewbbTopicRenderer::buildHeaders()   C

Complexity

Conditions 7
Paths 12

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 16
nc 12
nop 1
dl 0
loc 24
rs 6.7272
c 0
b 0
f 0
1
<?php
2
/**
3
 * NewBB 5.0x,  the forum module for XOOPS project
4
 *
5
 * @copyright      XOOPS Project (http://xoops.org)
6
 * @license        GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
7
 * @author         Taiwen Jiang (phppp or D.J.) <[email protected]>
8
 * @since          4.00
9
 * @package        module::newbb
10
 */
11
12
// defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
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...
13
14
/**
15
 * Topic Renderer
16
 *
17
 * @author    D.J. (phppp)
18
 * @copyright copyright &copy; Xoops Project
19
 * @package   module::newbb
20
 *
21
 */
22
class NewbbTopicRenderer
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

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

namespace YourVendor;

class YourClass { }

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

Loading history...
23
{
24
    /**
25
     * reference to an object handler
26
     */
27
    public $handler;
28
29
    /**
30
     * reference to moduleConfig
31
     */
32
    public $config;
33
34
    /**
35
     * Requested page
36
     */
37
    public $page = 'list.topic.php';
38
39
    /**
40
     * query variables
41
     */
42
    public $args = ['forum', 'uid', 'lastposter', 'type', 'status', 'mode', 'sort', 'order', 'start', 'since'];
43
    public $vars = [];
44
45
    /**
46
     * For multiple forums
47
     */
48
    public $is_multiple = false;
49
50
    /**
51
     * force to parse vars (run against static vars) irmtfan
52
     */
53
    public $force = false;
54
55
    /**
56
     * Vistitor's level: 0 - anonymous; 1 - user; 2 - moderator or admin
57
     */
58
    public $userlevel = 0;
59
60
    /**
61
     * Current user has no access to current page
62
     */
63
    public $noperm = false;
64
65
    /**
66
     *
67
     */
68
    public $query = [];
69
70
    /**
71
     * Constructor
72
     */
73
    //    public function NewbbTopicRenderer()
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...
74
    public function __construct()
75
    {
76
        $this->handler = xoops_getModuleHandler('topic', 'newbb');
77
    }
78
79
    /**
80
     * Access the only instance of this class
81
     * @return NewbbTopicRenderer
82
     */
83
    public static function getInstance()
84
    {
85
        static $instance;
86
        if (null === $instance) {
87
            $instance = new static();
88
        }
89
90
        return $instance;
91
    }
92
93
    public function init()
94
    {
95
        $this->noperm = false;
96
        $this->query  = [];
97
    }
98
99
    /**
100
     * @param $var
101
     * @param $val
102
     * @return array|int|string
103
     */
104
    public function setVar($var, $val)
105
    {
106
        switch ($var) {
107
            case 'forum':
108
                if (is_numeric($val)) {
109
                    $val = (int)$val;
110
                    // START irmtfan - if the forum is array
111
                } elseif (is_array($val)) {
112
                    $val = implode('|', $val);
113
                    //} 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...
114
                    //    $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...
115
                }
116
                // END irmtfan - if the forum is array
117
                break;
118
119
            case 'type':
120
            case 'mode':
121
            case 'order':
122
            case 'start':
123
            case 'since':
124
                $val = (int)$val;
125
                break;
126
127
            case 'uid': // irmtfan add multi topic poster
128
            case 'lastposter': // irmtfan add multi lastposter
129
                break;
130
131
            case 'status':
132
                // START irmtfan to accept multiple status
133
                $val = is_array($val) ? $val : [$val];
134
                $val = implode(',', $val);
135
                //$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...
136
                //if ($val === "all" && !$this->is_multiple) $val = ""; irmtfan commented because it is done in sort
137
                // END irmtfan to accept multiple status
138
                break;
139
140
            default:
141
                break;
142
        }
143
144
        return $val;
145
    }
146
147
    /**
148
     * @param array $vars
149
     */
150
    public function setVars(array $vars = [])
151
    {
152
        $this->init();
153
154
        foreach ($vars as $var => $val) {
155
            if (!in_array($var, $this->args)) {
156
                continue;
157
            }
158
            $this->vars[$var] = $this->setVar($var, $val);
159
        }
160
        $this->parseVars();
161
    }
162
163
    /**
164
     * @param null $status
165
     */
166
    public function _parseStatus($status = null)
0 ignored issues
show
Coding Style introduced by
_parseStatus uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
167
    {
168
        switch ($status) {
169
            case 'digest':
170
                $this->query['where'][] = 't.topic_digest = 1';
171
                break;
172
173
            case 'undigest':
174
                $this->query['where'][] = 't.topic_digest = 0';
175
                break;
176
177
            case 'sticky':
178
                $this->query['where'][] = 't.topic_sticky = 1';
179
                break;
180
181
            case 'unsticky':
182
                $this->query['where'][] = 't.topic_sticky = 0';
183
                break;
184
185
            case 'lock':
186
                $this->query['where'][] = 't.topic_status = 1';
187
                break;
188
189
            case 'unlock':
190
                $this->query['where'][] = 't.topic_status = 0';
191
                break;
192
193
            case 'poll':
194
                $this->query['where'][] = 't.topic_haspoll = 1';
195
                break;
196
197
            case 'unpoll':
198
                $this->query['where'][] = 't.topic_haspoll = 0';
199
                break;
200
201
            case 'voted':
202
                $this->query['where'][] = 't.votes > 0';
203
                break;
204
205
            case 'unvoted':
206
                $this->query['where'][] = 't.votes < 1';
207
                break;
208
209
            case 'replied':
210
                $this->query['where'][] = 't.topic_replies > 0';
211
                break;
212
213
            case 'unreplied':
214
                $this->query['where'][] = 't.topic_replies < 1';
215
                break;
216
217
            case 'viewed':
218
                $this->query['where'][] = 't.topic_views > 0';
219
                break;
220
221
            case 'unviewed':
222
                $this->query['where'][] = 't.topic_views < 1';
223
                break;
224
225
            case 'read':
226
                // Skip
227
                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...
228
                    // Use database
229 View Code Duplication
                } elseif ($this->config['read_mode'] == 2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
230
                    // START irmtfan use read_uid to find the unread posts when the user is logged in
231
                    $read_uid = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0;
232
                    if (!empty($read_uid)) {
233
                        $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 . ' ';
234
                        $this->query['where'][] = 'r.post_id = t.topic_last_post_id';
235
                    } 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...
236
                    }
237
                    // END irmtfan change criteria to get from uid p.uid = last post submit user id
238
                    // User cookie
239
                } elseif ($this->config['read_mode'] == 1) {
240
                    // START irmtfan fix read_mode = 1 bugs - for all users (member and anon)
241
                    $startdate = !empty($this->vars['since']) ? (time() - newbb_getSinceTime($this->vars['since'])) : 0;
242
                    if ($lastvisit = max($GLOBALS['last_visit'], $startdate)) {
243
                        $readmode1query = '';
244
                        if ($lastvisit > $startdate) {
245
                            $readmode1query = 'p.post_time < ' . $lastvisit;
246
                        }
247
                        $topics         = [];
248
                        $topic_lastread = newbb_getcookie('LT', true);
249 View Code Duplication
                        if (count($topic_lastread) > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
250
                            foreach ($topic_lastread as $id => $time) {
0 ignored issues
show
Bug introduced by
The expression $topic_lastread of type array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
251
                                if ($time > $lastvisit) {
252
                                    $topics[] = $id;
253
                                }
254
                            }
255
                        }
256
                        if (count($topics) > 0) {
257
                            $topicquery = ' t.topic_id IN (' . implode(',', $topics) . ')';
258
                            // because it should be OR
259
                            $readmode1query = !empty($readmode1query) ? '(' . $readmode1query . ' OR ' . $topicquery . ')' : $topicquery;
260
                        }
261
                        $this->query['where'][] = $readmode1query;
262
                    }
263
                    // END irmtfan fix read_mode = 1 bugs - for all users (member and anon)
264
                }
265
                break;
266
267
            case 'unread':
268
                // Skip
269
                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...
270
                    // Use database
271 View Code Duplication
                } elseif ($this->config['read_mode'] == 2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
272
                    // START irmtfan use read_uid to find the unread posts when the user is logged in
273
                    $read_uid = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0;
274
                    if (!empty($read_uid)) {
275
                        $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 . ' ';
276
                        $this->query['where'][] = '(r.read_id IS NULL OR r.post_id < t.topic_last_post_id)';
277
                    } 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...
278
                    }
279
                    // END irmtfan change criteria to get from uid p.uid = last post submit user id
280
                    // User cookie
281
                } elseif ($this->config['read_mode'] == 1) {
282
                    // START irmtfan fix read_mode = 1 bugs - for all users (member and anon)
283
                    $startdate = !empty($this->vars['since']) ? (time() - newbb_getSinceTime($this->vars['since'])) : 0;
284
                    if ($lastvisit = max($GLOBALS['last_visit'], $startdate)) {
285
                        if ($lastvisit > $startdate) {
286
                            $this->query['where'][] = 'p.post_time > ' . $lastvisit;
287
                        }
288
                        $topics         = [];
289
                        $topic_lastread = newbb_getcookie('LT', true);
290 View Code Duplication
                        if (count($topic_lastread) > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
291
                            foreach ($topic_lastread as $id => $time) {
0 ignored issues
show
Bug introduced by
The expression $topic_lastread of type array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
292
                                if ($time > $lastvisit) {
293
                                    $topics[] = $id;
294
                                }
295
                            }
296
                        }
297
                        if (count($topics) > 0) {
298
                            $this->query['where'][] = ' t.topic_id NOT IN (' . implode(',', $topics) . ')';
299
                        }
300
                    }
301
                    // END irmtfan fix read_mode = 1 bugs - for all users (member and anon)
302
                }
303
                break;
304
305 View Code Duplication
            case 'pending':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
306
                if ($this->userlevel < 2) {
307
                    $this->noperm = true;
308
                } else {
309
                    $this->query['where'][] = 't.approved = 0';
310
                }
311
                break;
312
313 View Code Duplication
            case 'deleted':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
314
                if ($this->userlevel < 2) {
315
                    $this->noperm = true;
316
                } else {
317
                    $this->query['where'][] = 't.approved = -1';
318
                }
319
                break;
320
321
            case 'all': // For viewall.php; do not display sticky topics at first
322
            case 'active': // same as 'all'
323
                $this->query['where'][] = 't.approved = 1';
324
                break;
325
326
            default: // irmtfan do nothing
327
                break;
328
        }
329
    }
330
331
    /**
332
     * @param $var
333
     * @param $val
334
     */
335
    public function parseVar($var, $val)
0 ignored issues
show
Coding Style introduced by
parseVar uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
336
    {
337
        switch ($var) {
338
            case 'forum':
339
                /** @var \NewbbForumHandler $forumHandler */
340
                $forumHandler = xoops_getModuleHandler('forum', 'newbb');
341
                // START irmtfan - get forum Ids by values. parse positive values to forum IDs and negative values to category IDs. value=0 => all valid forums
342
                // Get accessible forums
343
                $accessForums = $forumHandler->getIdsByValues(array_map('intval', @explode('|', $val)));
344
                // Filter specified forums if any
345
                //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...
346
                //$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...
347
                //}
348
                $this->vars['forum'] = $this->setVar('forum', $accessForums);
349
                // END irmtfan - get forum Ids by values. parse positive values to forum IDs and negative values to category IDs. value=0 => all valid forums
350
351
                if (empty($accessForums)) {
352
                    $this->noperm = true;
353
                    // 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.
354
                    //} 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...
355
                    //$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...
356
                } else {
357
                    $this->query['where'][] = 't.forum_id IN ( ' . implode(', ', $accessForums) . ' )';
358
                }
359
                break;
360
361 View Code Duplication
            case 'uid': // irmtfan add multi topic poster
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
362
                if ($val !== -1) {
363
                    $val                    = implode(',', array_map('intval', explode(',', $val)));
364
                    $this->query['where'][] = 't.topic_poster IN ( ' . $val . ' )';
365
                }
366
                break;
367 View Code Duplication
            case 'lastposter': // irmtfan add multi lastposter
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
368
                if ($val !== -1) {
369
                    $val                    = implode(',', array_map('intval', explode(',', $val)));
370
                    $this->query['where'][] = 'p.uid IN ( ' . $val . ' )';
371
                }
372
                break;
373
374
            case 'since':
375
                if (!empty($val)) {
376
                    // START irmtfan if unread && read_mode = 1 and last_visit > startdate do not add where query | to accept multiple status
377
                    $startdate = time() - newbb_getSinceTime($val);
378
                    if (in_array('unread', explode(',', $this->vars['status'], true)) && $this->config['read_mode'] == 1
379
                        && $GLOBALS['last_visit'] > $startdate) {
380
                        break;
381
                    }
382
                    // irmtfan digest_time | to accept multiple status
383
                    if (in_array('digest', explode(',', $this->vars['status'], true))) {
384
                        $this->query['where'][] = 't.digest_time > ' . $startdate;
385
                    }
386
                    // irmtfan - should be >= instead of =
387
                    $this->query['where'][] = 'p.post_time >= ' . $startdate;
388
                    // END irmtfan if unread && read_mode = 1 and last_visit > startdate do not add where query
389
                }
390
                break;
391
392
            case 'type':
393
                if (!empty($val)) {
394
                    $this->query['where'][] = 't.type_id = ' . $val;
395
                }
396
                break;
397
398
            case 'status':
399
                // START irmtfan to accept multiple status
400
                $val = explode(',', $val);
401
                // irmtfan - add 'all' to always parse t.approved = 1
402
                if (count(array_intersect($val, ['all', 'active', 'pending', 'deleted'])) === 0) {
403
                    $val[] = 'all';
404
                }
405
                foreach ($val as $key => $status) {
406
                    $this->_parseStatus($status);
407
                }
408
                // END irmtfan to accept multiple status
409
                break;
410
411
            case 'sort':
412
                if ($sort = $this->getSort($val, 'sort')) {
413
                    $this->query['sort'][] = $sort . (empty($this->vars['order']) ? ' DESC' : ' ASC');
414
                } else { // irmtfan if sort is not in the list
415
                    $this->query['sort'][] = 't.topic_last_post_id' . (empty($this->vars['order']) ? ' DESC' : ' ASC');
416
                }
417
                break;
418
419
            default:
420
                break;
421
        }
422
    }
423
424
    /**
425
     * @return bool
426
     */
427
    public function parseVars()
428
    {
429
        static $parsed;
430
        // irmtfan - force to parse vars (run against static vars)
431
        if (isset($parsed) && !$this->force) {
432
            return true;
433
        }
434
435
        if (!isset($this->vars['forum'])) {
436
            $this->vars['forum'] = null;
437
        }
438
        //irmtfan parse status for rendering topic correctly - if empty($_GET(status)) it will show all topics include deleted and pendings. 'all' instead of all
439
        if (!isset($this->vars['status'])) {
440
            $this->vars['status'] = 'all';
441
        }
442
        // 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=
443
        if (empty($this->vars['sort'])) {
444
            $this->vars['sort'] = 'lastpost';
445
        } // use lastpost instead of sticky
446
447
        foreach ($this->vars as $var => $val) {
448
            $this->parseVar($var, $val);
449
            if (empty($val)) {
450
                unset($this->vars[$var]);
451
            }
452
        }
453
        $parsed = true;
454
455
        return true;
456
    }
457
458
    /**
459
     * @param  null $header
460
     * @param  null $var
461
     * @return array|null
462
     */
463
    public function getSort($header = null, $var = null)
464
    {
465
        $headers = [
466
            'topic'           => [
467
                'title' => _MD_NEWBB_TOPICS,
468
                'sort'  => 't.topic_title'
469
            ],
470
            'forum'           => [
471
                'title' => _MD_NEWBB_FORUM,
472
                'sort'  => 't.forum_id'
473
            ],
474
            'poster'          => [
475
                'title' => _MD_NEWBB_TOPICPOSTER, /*irmtfan _MD_NEWBB_POSTER to _MD_NEWBB_TOPICPOSTER*/
476
                'sort'  => 't.topic_poster'
477
            ],
478
            'replies'         => [
479
                'title' => _MD_NEWBB_REPLIES,
480
                'sort'  => 't.topic_replies'
481
            ],
482
            'views'           => [
483
                'title' => _MD_NEWBB_VIEWS,
484
                'sort'  => 't.topic_views'
485
            ],
486
            'lastpost'        => [ // irmtfan show topic_page_jump_icon smarty
487
                                   'title' => _MD_NEWBB_LASTPOST,
488
                                   /*irmtfan _MD_NEWBB_DATE to _MD_NEWBB_LASTPOSTTIME again change to _MD_LASTPOST*/
489
                                   'sort'  => 't.topic_last_post_id'
490
            ],
491
            // START irmtfan add more sorts
492
            'lastposttime'    => [ // irmtfan same as lastpost
493
                                   'title' => _MD_NEWBB_LASTPOSTTIME,
494
                                   'sort'  => 't.topic_last_post_id'
495
            ],
496
            'lastposter'      => [ // irmtfan
497
                                   'title' => _MD_NEWBB_POSTER,
498
                                   'sort'  => 'p.uid',// poster uid
499
            ],
500
            'lastpostmsgicon' => [ // irmtfan
501
                                   'title' => _MD_NEWBB_MESSAGEICON,
502
                                   'sort'  => 'p.icon',// post message icon
503
            ],
504
            'ratings'         => [
505
                'title' => _MD_NEWBB_RATINGS,
506
                'sort'  => 't.rating', // irmtfan t.topic_rating to t.rating
507
            ],
508
            'votes'           => [
509
                'title' => _MD_NEWBB_VOTES,
510
                'sort'  => 't.votes'
511
            ],
512
            'publish'         => [
513
                'title' => _MD_NEWBB_TOPICTIME,
514
                'sort'  => 't.topic_id'
515
            ],
516
            'digest'          => [
517
                'title' => _MD_NEWBB_DIGEST,
518
                'sort'  => 't.digest_time'
519
            ],
520
            'sticky'          => [
521
                'title' => _MD_NEWBB_STICKY,
522
                'sort'  => 't.topic_sticky'
523
            ],
524
            'lock'            => [
525
                'title' => _MD_NEWBB_LOCK,
526
                'sort'  => 't.topic_status'
527
            ],
528
            'poll'            => [
529
                'title' => _MD_NEWBB_POLL_POLL,
530
                'sort'  => 't.poll_id'
531
            ]
532
        ];
533
        $types   = $this->getTypes();
534
        if (!empty($types)) {
535
            $headers['type'] = [
536
                'title' => _MD_NEWBB_TYPE,
537
                'sort'  => 't.type_id'
538
            ];
539
        }
540
        if ($this->userlevel == 2) {
541
            $headers['approve'] = [
542
                'title' => _MD_NEWBB_APPROVE,
543
                'sort'  => 't.approved'
544
            ];
545
        }
546
        // END irmtfan add more sorts
547
        if (empty($header) && empty($var)) {
548
            return $headers;
549
        }
550
        if (!empty($var) && !empty($header)) {
551
            return @$headers[$header][$var];
552
        }
553
        if (empty($var)) {
554
            return @$headers[$header];
555
        }
556
        $ret = null;
557
        foreach (array_keys($headers) as $key) {
558
            $ret[$key] = @$headers[$key][$var];
559
        }
560
561
        return $ret;
562
    }
563
564
    // START irmtfan add Display topic headers function
565
566
    /**
567
     * @param  null $header
568
     * @return array
569
     */
570
    public function getHeader($header = null)
571
    {
572
        $headersSort = $this->getSort('', 'title');
573
        // additional headers - important: those cannot be in sort anyway
574
        $headers = array_merge($headersSort, [
575
            'attachment' => _MD_NEWBB_TOPICSHASATT, // show attachment smarty
576
            'read'       => _MD_NEWBB_MARK_UNREAD . '|' . _MD_NEWBB_MARK_READ, // read/unread show topic_folder smarty
577
            'pagenav'    => _MD_NEWBB_PAGENAV_DISPLAY, // show topic_page_jump smarty - sort by topic_replies?
578
        ]);
579
580
        return $this->getFromKeys($headers, $header);
581
    }
582
583
    // END irmtfan add Display topic headers function
584
585
    /**
586
     * @param  null $type
587
     * @param  null $status
588
     * @return array
589
     */
590
    public function getStatus($type = null, $status = null)
591
    {
592
        $links       = [
593
            //""            => "", /* 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...
594
            'all'       => _ALL,
595
            'digest'    => _MD_NEWBB_DIGEST,
596
            'undigest'  => _MD_NEWBB_UNDIGEST, // irmtfan add
597
            'sticky'    => _MD_NEWBB_STICKY, // irmtfan add
598
            'unsticky'  => _MD_NEWBB_UNSTICKY, // irmtfan add
599
            'lock'      => _MD_NEWBB_LOCK, // irmtfan add
600
            'unlock'    => _MD_NEWBB_UNLOCK, // irmtfan add
601
            'poll'      => _MD_NEWBB_TOPICHASPOLL, // irmtfan add
602
            'unpoll'    => _MD_NEWBB_TOPICHASNOTPOLL, // irmtfan add
603
            'voted'     => _MD_NEWBB_VOTED, // irmtfan add
604
            'unvoted'   => _MD_NEWBB_UNVOTED, // irmtfan add
605
            'viewed'    => _MD_NEWBB_VIEWED, // irmtfan add
606
            'unviewed'  => _MD_NEWBB_UNVIEWED, // irmtfan add
607
            'replied'   => _MD_NEWBB_REPLIED, // irmtfan add
608
            'unreplied' => _MD_NEWBB_UNREPLIED,
609
            'read'      => _MD_NEWBB_READ, // irmtfan add
610
            'unread'    => _MD_NEWBB_UNREAD
611
        ];
612
        $links_admin = [
613
            'active'  => _MD_NEWBB_TYPE_ADMIN,
614
            'pending' => _MD_NEWBB_TYPE_PENDING,
615
            'deleted' => _MD_NEWBB_TYPE_DELETED
616
        ];
617
618
        // all status, for admin
619
        if ($type > 1) {
620
            $links = array_merge($links, $links_admin);// irmtfan to accept multiple status
621
        }
622
623
        return $this->getFromKeys($links, $status); // irmtfan to accept multiple status
624
    }
625
626
    /**
627
     * @param Smarty $xoopsTpl
628
     */
629
    public function buildSelection(Smarty $xoopsTpl)
630
    {
631
        $selection         = ['action' => $this->page];
632
        $selection['vars'] = $this->vars;
633
        include_once __DIR__ . '/../include/functions.forum.php';
634
        $forum_selected     = empty($this->vars['forum']) ? null : explode('|', @$this->vars['forum']);
635
        $selection['forum'] = '<select name="forum[]" multiple="multiple">';
636
        $selection['forum'] .= '<option value="0">' . _MD_NEWBB_ALL . '</option>';
637
        $selection['forum'] .= newbb_forumSelectBox($forum_selected);
638
        $selection['forum'] .= '</select>';
639
640
        $sort_selected     = $this->vars['sort'];
641
        $sorts             = $this->getSort('', 'title');
642
        $selection['sort'] = "<select name='sort'>";
643
        if (! is_array($sorts)) {
644
            throw new \RuntimeException('$sorts must be an array.');
645
        }
646
        foreach ($sorts as $sort => $title) {
647
            $selection['sort'] .= "<option value='" . $sort . "' " . (($sort == $sort_selected) ? " selected='selected'" : '') . '>' . $title . '</option>';
648
        }
649
        $selection['sort'] .= '</select>';
650
651
        $selection['order'] = "<select name='order'>";
652
        $selection['order'] .= "<option value='0' " . (empty($this->vars['order']) ? " selected='selected'" : '') . '>' . _DESCENDING . '</option>';
653
        $selection['order'] .= "<option value='1' " . (!empty($this->vars['order']) ? " selected='selected'" : '') . '>' . _ASCENDING . '</option>';
654
        $selection['order'] .= '</select>';
655
656
        $since              = isset($this->vars['since']) ? $this->vars['since'] : $this->config['since_default'];
657
        $selection['since'] = newbb_sinceSelectBox($since);
658
659
        $xoopsTpl->assign_by_ref('selection', $selection);
660
    }
661
662
    /**
663
     * @param Smarty $xoopsTpl
664
     */
665
    public function buildSearch(Smarty $xoopsTpl)
666
    {
667
        $search             = [];
668
        $search['forum']    = @$this->vars['forum'];
669
        $search['since']    = @$this->vars['since'];
670
        $search['searchin'] = 'both';
671
672
        $xoopsTpl->assign_by_ref('search', $search);
673
    }
674
675
    /**
676
     * @param Smarty $xoopsTpl
677
     */
678
    public function buildHeaders(Smarty $xoopsTpl)
679
    {
680
        $args = [];
681
        foreach ($this->vars as $var => $val) {
682
            if ($var === 'sort' || $var === 'order') {
683
                continue;
684
            }
685
            $args[] = "{$var}={$val}";
686
        }
687
688
        $headers = $this->getSort('', 'title');
689
        if (! is_array($headers)) {
690
            throw new \RuntimeException('$headers must be an array.');
691
        }
692
        foreach ($headers as $header => $title) {
693
            $_args = ["sort={$header}"];
694
            if (@$this->vars['sort'] == $header) {
695
                $_args[] = 'order=' . ((@$this->vars['order'] + 1) % 2);
696
            }
697
            $headers_data[$header]['title'] = $title;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$headers_data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $headers_data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
698
            $headers_data[$header]['link']  = $this->page . '?' . implode('&amp;', array_merge($args, $_args));
699
        }
700
        $xoopsTpl->assign_by_ref('headers', $headers_data);
0 ignored issues
show
Bug introduced by
The variable $headers_data does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
701
    }
702
703
    /**
704
     * @param Smarty $xoopsTpl
705
     */
706
    public function buildFilters(Smarty $xoopsTpl)
707
    {
708
        $args = [];
709
        foreach ($this->vars as $var => $val) {
710
            if ($var === 'status') {
711
                continue;
712
            }
713
            $args[] = "{$var}={$val}";
714
        }
715
716
        $links = $this->getStatus($this->userlevel);
717
718
        $status = [];
719 View Code Duplication
        foreach ($links as $link => $title) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
720
            $_args                  = ["status={$link}"];
721
            $status[$link]['title'] = $title;
722
            $status[$link]['link']  = $this->page . '?' . implode('&amp;', array_merge($args, $_args));
723
        }
724
        $xoopsTpl->assign_by_ref('filters', $status);
725
    }
726
727
    /**
728
     * @param  null $type_id
729
     * @return mixed
730
     */
731
    public function getTypes($type_id = null)
732
    {
733
        static $types;
734
        if (!isset($types)) {
735
            $typeHandler = xoops_getModuleHandler('type', 'newbb');
736
            /** @var \NewbbTypeHandler $typeHandler */
737
            $types = $typeHandler->getByForum(explode('|', @$this->vars['forum']));
738
        }
739
740
        if (empty($type_id)) {
741
            return $types;
742
        }
743
744
        return @$types[$type_id];
745
    }
746
747
    /**
748
     * @param  Smarty $xoopsTpl
749
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
750
     */
751
    public function buildTypes(Smarty $xoopsTpl)
752
    {
753
        $status = '';
754
        if (!$types = $this->getTypes()) {
755
            return true;
756
        }
757
758
        $args = [];
759
        foreach ($this->vars as $var => $val) {
760
            if ($var === 'type') {
761
                continue;
762
            }
763
            $args[] = "{$var}={$val}";
764
        }
765
766 View Code Duplication
        foreach ($types as $id => $type) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
767
            $_args                = ["type={$id}"];
768
            $status[$id]['title'] = $type['type_name'];
769
            $status[$id]['link']  = $this->page . '?' . implode('&amp;', array_merge($args, $_args));
770
        }
771
        $xoopsTpl->assign_by_ref('types', $status);
772
    }
773
774
    /**
775
     * @param  Smarty $xoopsTpl
776
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
777
     */
778
    public function buildCurrent(Smarty $xoopsTpl)
779
    {
780
        if (empty($this->vars['status']) && !$this->is_multiple) {
781
            return true;
782
        }
783
784
        $args = [];
785
        foreach ($this->vars as $var => $val) {
786
            $args[] = "{$var}={$val}";
787
        }
788
789
        $status          = [];
790
        $status['title'] = implode(',', $this->getStatus($this->userlevel, $this->vars['status'])); // irmtfan to accept multiple status
791
        //$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...
792
        $status['link'] = $this->page . (empty($args) ? '' : '?' . implode('&amp;', $args));
793
794
        $xoopsTpl->assign_by_ref('current', $status);
795
    }
796
797
    /**
798
     * @param Smarty $xoopsTpl
799
     */
800
    public function buildPagenav(Smarty $xoopsTpl)
0 ignored issues
show
Coding Style introduced by
buildPagenav uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
801
    {
802
        $count_topic = $this->getCount();
803
        if ($count_topic > $this->config['topics_per_page']) {
804
            $args = [];
805
            foreach ($this->vars as $var => $val) {
806
                if ($var === 'start') {
807
                    continue;
808
                }
809
                $args[] = "{$var}={$val}";
810
            }
811
            require_once $GLOBALS['xoops']->path('class/pagenav.php');
812
            $nav = new XoopsPageNav($count_topic, $this->config['topics_per_page'], @$this->vars['start'], 'start', implode('&amp;', $args));
813
            if (isset($GLOBALS['xoopsModuleConfig']['do_rewrite'])) {
814
                $nav->url = formatURL(Request::getString('SERVER_NAME', '', 'SERVER')) . ' /' . $nav->url;
815
            }
816
            if ($this->config['pagenav_display'] === 'select') {
817
                $navi = $nav->renderSelect();
818
            } elseif ($this->config['pagenav_display'] == 'image') {
819
                $navi = $nav->renderImageNav(4);
820
            } else {
821
                $navi = $nav->renderNav(4);
822
            }
823
            $xoopsTpl->assign('pagenav', $navi);
824
        } else {
825
            $xoopsTpl->assign('pagenav', '');
826
        }
827
    }
828
829
    /**
830
     * @return int
831
     */
832
    public function getCount()
833
    {
834
        if ($this->noperm) {
835
            return 0;
836
        }
837
838
        $selects = [];
839
        $froms   = [];
840
        $joins   = [];
841
        $wheres  = [];
842
843
        // topic fields
844
        $selects[] = 'COUNT(*)';
845
846
        $froms[]  = $this->handler->db->prefix('newbb_topics') . ' AS t ';
847
        $joins[]  = 'LEFT JOIN ' . $this->handler->db->prefix('newbb_posts') . ' AS p ON p.post_id = t.topic_last_post_id';
848
        $wheres[] = '1 = 1';
849
850
        $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
851
               '     WHERE ' . implode(' AND ', $wheres) . '        AND ' . @implode(' AND ', @$this->query['where']);
852
853
        if (!$result = $this->handler->db->query($sql)) {
854
            return 0;
855
        }
856
        list($count) = $this->handler->db->fetchRow($result);
857
858
        return $count;
859
    }
860
861
    /**
862
     * @param  Smarty $xoopsTpl
0 ignored issues
show
Documentation introduced by
Should the type for parameter $xoopsTpl not be null|Smarty?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
863
     * @return array|void
864
     */
865
    public function renderTopics(Smarty $xoopsTpl = null)
0 ignored issues
show
Coding Style introduced by
renderTopics uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
866
    {
867
        $myts = MyTextSanitizer::getInstance(); // irmtfan Instanciate
868
869
        $ret = [];
870
        //$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...
871
872
        if ($this->noperm) {
873
            if (is_object($xoopsTpl)) {
874
                $xoopsTpl->assign_by_ref('topics', $ret);
875
876
                return;
877
            }
878
879
            return $ret;
880
        }
881
882
        $selects = [];
883
        $froms   = [];
884
        $joins   = [];
885
        $wheres  = [];
886
887
        // topic fields
888
        $selects[] = 't.*';
889
        // post fields
890
        $selects[] = 'p.post_time as last_post_time, p.poster_name as last_poster_name, p.icon, p.post_id, p.uid';
891
892
        $froms[]  = $this->handler->db->prefix('newbb_topics') . ' AS t ';
893
        $joins[]  = 'LEFT JOIN ' . $this->handler->db->prefix('newbb_posts') . ' AS p ON p.post_id = t.topic_last_post_id';
894
        $wheres[] = '1 = 1';
895
896
        if (!empty($this->config['post_excerpt'])) {
897
            $selects[]             = 'p.post_karma, p.require_reply, pt.post_text';
898
            $this->query['join'][] = 'LEFT JOIN ' . $this->handler->db->prefix('newbb_posts_text') . ' AS pt ON pt.post_id = t.topic_last_post_id';
899
        }
900
        //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...
901
902
        $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
903
               '     WHERE ' . implode(' AND ', $wheres) . '        AND ' . @implode(' AND ', @$this->query['where']) . '     ORDER BY ' . implode(', ', $this->query['sort']);
904
905
        if (!$result = $this->handler->db->query($sql, $this->config['topics_per_page'], @$this->vars['start'])) {
906
            if (is_object($xoopsTpl)) {
907
                $xoopsTpl->assign_by_ref('topics', $ret);
908
909
                return;
910
            }
911
912
            return $ret;
913
        }
914
915
        include_once __DIR__ . '/../include/functions.render.php';
916
        include_once __DIR__ . '/../include/functions.session.php';
917
        include_once __DIR__ . '/../include/functions.time.php';
918
        include_once __DIR__ . '/../include/functions.read.php';
919
        include_once __DIR__ . '/../include/functions.topic.php';
920
921
        $sticky    = 0;
922
        $topics    = [];
923
        $posters   = [];
924
        $reads     = [];
925
        $types     = [];
0 ignored issues
show
Unused Code introduced by
$types is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
926
        $forums    = [];
927
        $anonymous = $myts->htmlSpecialChars($GLOBALS['xoopsConfig']['anonymous']);
928
929
        while ($myrow = $this->handler->db->fetchArray($result)) {
930
            if ($myrow['topic_sticky']) {
931
                ++$sticky;
932
            }
933
934
            // ------------------------------------------------------
935
            // START irmtfan remove topic_icon hardcode smarty
936
            // topic_icon: just regular topic_icon
937 View Code Duplication
            if (!empty($myrow['icon'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
938
                $topic_icon = '<img align="middle" src="' . XOOPS_URL . '/images/subject/' . htmlspecialchars($myrow['icon']) . '" alt="" />';
939
            } else {
940
                $topic_icon = '<img align="middle" src="' . XOOPS_URL . '/images/icons/no_posticon.gif" alt="" />';
941
            }
942
            // END irmtfan remove topic_icon hardcode smarty
943
944
            // ------------------------------------------------------
945
            // rating_img
946
            $rating = number_format($myrow['rating'] / 2, 0);
947
            // irmtfan - add alt key for rating
948 View Code Duplication
            if ($rating < 1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
949
                $rating_img = newbbDisplayImage('blank');
950
            } else {
951
                $rating_img = newbbDisplayImage('rate' . $rating, constant('_MD_NEWBB_RATE' . $rating));
952
            }
953
954
            // ------------------------------------------------------
955
            // topic_page_jump
956
            $topic_page_jump      = '';
957
            $topic_page_jump_icon = '';
0 ignored issues
show
Unused Code introduced by
$topic_page_jump_icon is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
958
            $totalpages           = ceil(($myrow['topic_replies'] + 1) / $this->config['posts_per_page']);
959 View Code Duplication
            if ($totalpages > 1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
960
                $topic_page_jump .= '&nbsp;&nbsp;';
961
                $append          = false;
962
                for ($i = 1; $i <= $totalpages; ++$i) {
963
                    if ($i > 3 && $i < $totalpages) {
964
                        if (!$append) {
965
                            $topic_page_jump .= '...';
966
                            $append          = true;
967
                        }
968
                    } else {
969
                        $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>]';
970
                        // irmtfan remove here and move
971
                        //$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...
972
                    }
973
                }
974
            }
975
            // irmtfan - move here for both topics with and without pages - change topic_id to post_id
976
            $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>';
977
978
            // ------------------------------------------------------
979
            // => topic array
980
981
            $topic_title = $myts->htmlSpecialChars($myrow['topic_title']);
982
            // irmtfan use topic_title_excerpt for block topic title length
983
            $topic_title_excerpt = $topic_title;
984
            if (!empty($this->config['topic_title_excerpt'])) {
985
                $topic_title_excerpt = xoops_substr($topic_title, 0, $this->config['topic_title_excerpt']);
986
            }
987
            // irmtfan hardcode class commented
988
            //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...
989
            //   $topic_title = "<span class='digest'>" . $topic_title . "</span>";
990
            //}
991
992
            if (empty($this->config['post_excerpt'])) {
993
                $topic_excerpt = '';
994
            } elseif (($myrow['post_karma'] > 0 || $myrow['require_reply'] > 0) && !newbb_isAdmin($myrow['forum_id'])) {
995
                $topic_excerpt = '';
996 View Code Duplication
            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
997
                $topic_excerpt = xoops_substr(newbb_html2text($myts->displayTarea($myrow['post_text'])), 0, $this->config['post_excerpt']);
998
                $topic_excerpt = str_replace('[', '&#91;', $myts->htmlSpecialChars($topic_excerpt));
999
            }
1000
1001
            $topics[$myrow['topic_id']] = [
1002
                'topic_id'               => $myrow['topic_id'],
1003
                'topic_icon'             => $topic_icon,
1004
                'type_id'                => $myrow['type_id'],
1005
                'topic_title_excerpt'    => $topic_title_excerpt,
1006
                //irmtfan use topic_title_excerpt
1007
                //'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...
1008
                'topic_link'             => 'viewtopic.php?topic_id=' . $myrow['topic_id'],
1009
                // irmtfan remove hardcode link
1010
                'rating_img'             => $rating_img,
1011
                'votes'                  => $myrow['votes'],
1012
                //irmtfan added
1013
                'topic_page_jump'        => $topic_page_jump,
1014
                'topic_page_jump_icon'   => $topic_page_jump_icon,
1015
                'topic_replies'          => $myrow['topic_replies'],
1016
                'topic_poster_uid'       => $myrow['topic_poster'],
1017
                'topic_poster_name'      => !empty($myrow['poster_name']) ? $myts->htmlSpecialChars($myrow['poster_name']) : $anonymous,
1018
                'topic_views'            => $myrow['topic_views'],
1019
                'topic_time'             => newbb_formatTimestamp($myrow['topic_time']),
1020
                'topic_last_post_id'     => $myrow['topic_last_post_id'],
1021
                //irmtfan added
1022
                'topic_last_posttime'    => newbb_formatTimestamp($myrow['last_post_time']),
1023
                'topic_last_poster_uid'  => $myrow['uid'],
1024
                'topic_last_poster_name' => !empty($myrow['last_poster_name']) ? $myts->htmlSpecialChars($myrow['last_poster_name']) : $anonymous,
1025
                'topic_forum'            => $myrow['forum_id'],
1026
                'topic_excerpt'          => $topic_excerpt,
1027
                'sticky'                 => $myrow['topic_sticky'] ? newbbDisplayImage('topic_sticky', _MD_NEWBB_TOPICSTICKY) : '',
1028
                // irmtfan bug fixed
1029
                'lock'                   => $myrow['topic_status'] ? newbbDisplayImage('topic_locked', _MD_NEWBB_TOPICLOCK) : '',
1030
                //irmtfan added
1031
                'digest'                 => $myrow['topic_digest'] ? newbbDisplayImage('topic_digest', _MD_NEWBB_TOPICDIGEST) : '',
1032
                //irmtfan added
1033
                'poll'                   => $myrow['topic_haspoll'] ? newbbDisplayImage('poll', _MD_NEWBB_TOPICHASPOLL) : '',
1034
                //irmtfan added
1035
                'approve'                => $myrow['approved'],
1036
                //irmtfan added
1037
            ];
1038
1039
            /* users */
1040
            $posters[$myrow['topic_poster']] = 1;
1041
            $posters[$myrow['uid']]          = 1;
1042
            // reads
1043
            if (!empty($this->config['read_mode'])) {
1044
                $reads[$myrow['topic_id']] = ($this->config['read_mode'] == 1) ? $myrow['last_post_time'] : $myrow['topic_last_post_id'];
1045
            }
1046
            // types
1047
            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...
1048
                //$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...
1049
            }
1050
            // forums
1051
            $forums[$myrow['forum_id']] = 1;
1052
        }
1053
        $posters_name = newbb_getUnameFromIds(array_keys($posters), $this->config['show_realname'], true);
1054
        $topic_isRead = newbb_isRead('topic', $reads);
1055
        /*
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...
1056
        $type_list = array();
1057
        if (count($types) > 0) {
1058
            $typeHandler = xoops_getModuleHandler('type', 'newbb');
1059
            $type_list = $typeHandler->getAll(new Criteria("type_id", "(".implode(", ", array_keys($types)).")", "IN"), null, false);
1060
        }
1061
        */
1062
        $type_list = $this->getTypes();
1063
        /** @var \NewbbForumHandler $forumHandler */
1064
        $forumHandler = xoops_getModuleHandler('forum', 'newbb');
1065
1066
        if (count($forums) > 0) {
1067
            $forum_list = $forumHandler->getAll(new Criteria('forum_id', '(' . implode(', ', array_keys($forums)) . ')', 'IN'), ['forum_name', 'hot_threshold'], false);
1068
        } else {
1069
            $forum_list = $forumHandler->getAll();
1070
        }
1071
1072
        foreach (array_keys($topics) as $id) {
1073
            $topics[$id]['topic_read']       = empty($topic_isRead[$id]) ? 0 : 1; // add topic-read/topic-new smarty variable
1074
            $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>';
1075
1076
            //irmtfan use topic_title_excerpt -- add else
1077
            if (!empty($topics[$id]['type_id']) && isset($type_list[$topics[$id]['type_id']])) {
1078
                $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']);
1079
            } else {
1080
                $topics[$id]['topic_title'] = $topics[$id]['topic_title_excerpt'];
1081
            }
1082
            $topics[$id]['topic_poster']      = !empty($posters_name[$topics[$id]['topic_poster_uid']]) ? $posters_name[$topics[$id]['topic_poster_uid']] : $topics[$id]['topic_poster_name'];
1083
            $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'];
1084
            // ------------------------------------------------------
1085
            // START irmtfan remove hardcodes from topic_folder smarty
1086
            // topic_folder: priority: newhot -> hot/new -> regular
1087
            //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...
1088
            // START irmtfan - add topic_folder_text for alt
1089
            //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...
1090
            //    $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...
1091
            //    $topic_folder_text = _MD_NEWBB_TOPICLOCKED;
1092
            //} else {
1093
            //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...
1094
            //    $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...
1095
            //    $topic_folder_text = _MD_NEWBB_TOPICDIGEST;
1096
            if ($topics[$id]['topic_replies'] >= $forum_list[$topics[$id]['topic_forum']]['hot_threshold']) {
1097
                $topic_folder      = empty($topic_isRead[$id]) ? 'topic_hot_new' : 'topic_hot';
1098
                $topic_folder_text = empty($topic_isRead[$id]) ? _MD_NEWBB_MORETHAN : _MD_NEWBB_MORETHAN2;
1099 View Code Duplication
            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1100
                $topic_folder      = empty($topic_isRead[$id]) ? 'topic_new' : 'topic';
1101
                $topic_folder_text = empty($topic_isRead[$id]) ? _MD_NEWBB_NEWPOSTS : _MD_NEWBB_NONEWPOSTS;
1102
            }
1103
            //}
1104
            // END irmtfan remove hardcodes from topic_folder smarty
1105
            $topics[$id]['topic_folder'] = newbbDisplayImage($topic_folder, $topic_folder_text);
1106
            // END irmtfan - add topic_folder_text for alt
1107
1108
            unset($topics[$id]['topic_poster_name'], $topics[$id]['topic_last_poster_name']);// irmtfan remove $topics[$id]["stats"] because it is not exist now
1109
        }
1110
1111 View Code Duplication
        if (count($topics) > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1112
            $sql = ' SELECT DISTINCT topic_id FROM ' . $this->handler->db->prefix('newbb_posts') . " WHERE attachment != ''" . ' AND topic_id IN (' . implode(',', array_keys($topics)) . ')';
1113
            if ($result = $this->handler->db->query($sql)) {
1114
                while (list($topic_id) = $this->handler->db->fetchRow($result)) {
1115
                    $topics[$topic_id]['attachment'] = '&nbsp;' . newbbDisplayImage('attachment', _MD_NEWBB_TOPICSHASATT);
1116
                }
1117
            }
1118
        }
1119
1120
        if (is_object($xoopsTpl)) {
1121
            $xoopsTpl->assign_by_ref('sticky', $sticky);
1122
            $xoopsTpl->assign_by_ref('topics', $topics);
1123
1124
            return;
1125
        }
1126
1127
        return [$topics, $sticky];
1128
    }
1129
1130
    // START irmtfan to create an array from selected keys of an array
1131
1132
    /**
1133
     * @param        $array
1134
     * @param  null  $keys
1135
     * @return array
1136
     */
1137
    public function getFromKeys($array, $keys = null)
1138
    {
1139
        if (empty($keys)) {
1140
            return $array;
1141
        } // all keys
1142
        $keyarr = is_string($keys) ? explode(',', $keys) : $keys;
1143
        $keyarr = array_intersect(array_keys($array), $keyarr); // keys should be in array
1144
        $ret    = [];
1145
        foreach ($keyarr as $key) {
1146
            $ret[$key] = $array[$key];
1147
        }
1148
1149
        return $ret;
1150
    }
1151
    // END irmtfan to create an array from selected keys of an array
1152
}
1153