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

NewbbPostHandler::getByLimit()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 32
Code Lines 27

Duplication

Lines 7
Ratio 21.88 %

Importance

Changes 0
Metric Value
cc 2
eloc 27
nc 2
nop 7
dl 7
loc 32
rs 8.8571
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 42 and the first side effect is on line 37.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
//
3
//  ------------------------------------------------------------------------ //
4
//                XOOPS - PHP Content Management System                      //
5
//                  Copyright (c) 2000-2016 XOOPS.org                        //
6
//                       <http://xoops.org/>                             //
7
//  ------------------------------------------------------------------------ //
8
//  This program is free software; you can redistribute it and/or modify     //
9
//  it under the terms of the GNU General Public License as published by     //
10
//  the Free Software Foundation; either version 2 of the License, or        //
11
//  (at your option) any later version.                                      //
12
//                                                                           //
13
//  You may not change or alter any portion of this comment or credits       //
14
//  of supporting developers from this source code or any supporting         //
15
//  source code which is considered copyrighted (c) material of the          //
16
//  original comment or credit authors.                                      //
17
//                                                                           //
18
//  This program is distributed in the hope that it will be useful,          //
19
//  but WITHOUT ANY WARRANTY; without even the implied warranty of           //
20
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
21
//  GNU General Public License for more details.                             //
22
//                                                                           //
23
//  You should have received a copy of the GNU General Public License        //
24
//  along with this program; if not, write to the Free Software              //
25
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA //
26
//  ------------------------------------------------------------------------ //
27
//  Author: phppp (D.J., [email protected])                                  //
28
//  URL: http://xoops.org                                                    //
29
//  Project: Article Project                                                 //
30
//  ------------------------------------------------------------------------ //
31
32
use Xmf\Highlighter;
33
use Xmf\Request;
34
35
// 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...
36
37
defined('NEWBB_FUNCTIONS_INI') || include $GLOBALS['xoops']->path('modules/newbb/include/functions.ini.php');
38
39
/**
40
 * Class Post
41
 */
42
class NewbbPost extends XoopsObject
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...
43
{
44
    //class Post extends XoopsObject {
45
    public $attachmentArray = [];
46
47
    /**
48
     *
49
     */
50
    public function __construct()
51
    {
52
        parent::__construct();
53
54
        $this->initVar('post_id', XOBJ_DTYPE_INT);
55
        $this->initVar('topic_id', XOBJ_DTYPE_INT, 0, true);
56
        $this->initVar('forum_id', XOBJ_DTYPE_INT, 0, true);
57
        $this->initVar('post_time', XOBJ_DTYPE_INT, 0, true);
58
        //        $this->initVar('poster_ip', XOBJ_DTYPE_INT, 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...
59
        $this->initVar('poster_ip', XOBJ_DTYPE_TXTBOX, '');
60
        $this->initVar('poster_name', XOBJ_DTYPE_TXTBOX, '');
61
        $this->initVar('subject', XOBJ_DTYPE_TXTBOX, '', true);
62
        $this->initVar('pid', XOBJ_DTYPE_INT, 0);
63
        $this->initVar('dohtml', XOBJ_DTYPE_INT, 0);
64
        $this->initVar('dosmiley', XOBJ_DTYPE_INT, 1);
65
        $this->initVar('doxcode', XOBJ_DTYPE_INT, 1);
66
        $this->initVar('doimage', XOBJ_DTYPE_INT, 1);
67
        $this->initVar('dobr', XOBJ_DTYPE_INT, 1);
68
        $this->initVar('uid', XOBJ_DTYPE_INT, 1);
69
        $this->initVar('icon', XOBJ_DTYPE_TXTBOX, '');
70
        $this->initVar('attachsig', XOBJ_DTYPE_INT, 0);
71
        $this->initVar('approved', XOBJ_DTYPE_INT, 1);
72
        $this->initVar('post_karma', XOBJ_DTYPE_INT, 0);
73
        $this->initVar('require_reply', XOBJ_DTYPE_INT, 0);
74
        $this->initVar('attachment', XOBJ_DTYPE_TXTAREA, '');
75
        $this->initVar('post_text', XOBJ_DTYPE_TXTAREA, '');
76
        $this->initVar('post_edit', XOBJ_DTYPE_TXTAREA, '');
77
    }
78
79
    // ////////////////////////////////////////////////////////////////////////////////////
80
    // attachment functions    TODO: there should be a file/attachment management class
81
    /**
82
     * @return array|mixed|null
83
     */
84
    public function getAttachment()
85
    {
86
        if (count($this->attachmentArray)) {
87
            return $this->attachmentArray;
88
        }
89
        $attachment = $this->getVar('attachment');
90
        if (empty($attachment)) {
91
            $this->attachmentArray = [];
92
        } else {
93
            $this->attachmentArray = @unserialize(base64_decode($attachment));
94
        }
95
96
        return $this->attachmentArray;
97
    }
98
99
    /**
100
     * @param $attachKey
101
     * @return bool
102
     */
103
    public function incrementDownload($attachKey)
104
    {
105
        if (!$attachKey) {
106
            return false;
107
        }
108
        $this->attachmentArray[(string)$attachKey]['numDownload']++;
109
110
        return $this->attachmentArray[(string)$attachKey]['numDownload'];
111
    }
112
113
    /**
114
     * @return bool
115
     */
116
    public function saveAttachment()
0 ignored issues
show
Coding Style introduced by
saveAttachment 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...
117
    {
118
        $attachmentSave = '';
119 View Code Duplication
        if (is_array($this->attachmentArray) && count($this->attachmentArray) > 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...
120
            $attachmentSave = base64_encode(serialize($this->attachmentArray));
121
        }
122
        $this->setVar('attachment', $attachmentSave);
123
        $sql = 'UPDATE ' . $GLOBALS['xoopsDB']->prefix('newbb_posts') . ' SET attachment=' . $GLOBALS['xoopsDB']->quoteString($attachmentSave) . ' WHERE post_id = ' . $this->getVar('post_id');
124
        if (!$result = $GLOBALS['xoopsDB']->queryF($sql)) {
125
            //xoops_error($GLOBALS['xoopsDB']->error());
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...
126
            return false;
127
        }
128
129
        return true;
130
    }
131
132
    /**
133
     * @param  null $attachArray
134
     * @return bool
135
     */
136
    public function deleteAttachment($attachArray = null)
0 ignored issues
show
Coding Style introduced by
deleteAttachment 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...
137
    {
138
        $attachOld = $this->getAttachment();
139
        if (!is_array($attachOld) || count($attachOld) < 1) {
140
            return true;
141
        }
142
        $this->attachmentArray = [];
143
144
        if ($attachArray === null) {
145
            $attachArray = array_keys($attachOld);
146
        } // to delete all!
147
        if (!is_array($attachArray)) {
148
            $attachArray = [$attachArray];
149
        }
150
151
        foreach ($attachOld as $key => $attach) {
152
            if (in_array($key, $attachArray)) {
153
                @unlink($GLOBALS['xoops']->path($GLOBALS['xoopsModuleConfig']['dir_attachments'] . '/' . $attach['name_saved']));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
154
                @unlink($GLOBALS['xoops']->path($GLOBALS['xoopsModuleConfig']['dir_attachments'] . '/thumbs/' . $attach['name_saved'])); // delete thumbnails
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
155
                continue;
156
            }
157
            $this->attachmentArray[$key] = $attach;
158
        }
159
        $attachmentSave = '';
160 View Code Duplication
        if (is_array($this->attachmentArray) && count($this->attachmentArray) > 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...
161
            $attachmentSave = base64_encode(serialize($this->attachmentArray));
162
        }
163
        $this->setVar('attachment', $attachmentSave);
164
165
        return true;
166
    }
167
168
    /**
169
     * @param  string $name_saved
170
     * @param  string $nameDisplay
171
     * @param  string $mimetype
172
     * @param  int    $numDownload
173
     * @return bool
174
     */
175
    public function setAttachment($name_saved = '', $nameDisplay = '', $mimetype = '', $numDownload = 0)
176
    {
177
        static $counter = 0;
178
        $this->attachmentArray = $this->getAttachment();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getAttachment() of type * is incompatible with the declared type array of property $attachmentArray.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
179
        if ($name_saved) {
180
            $key                         = (string)(time() + $counter++);
181
            $this->attachmentArray[$key] = [
182
                'name_saved'  => $name_saved,
183
                'nameDisplay' => empty($nameDisplay) ? $nameDisplay : $name_saved,
184
                'mimetype'    => $mimetype,
185
                'numDownload' => empty($numDownload) ? (int)$numDownload : 0
186
            ];
187
        }
188
        $attachmentSave = null;
189
        if (is_array($this->attachmentArray)) {
190
            $attachmentSave = base64_encode(serialize($this->attachmentArray));
191
        }
192
        $this->setVar('attachment', $attachmentSave);
193
194
        return true;
195
    }
196
197
    /**
198
     * TODO: refactor
199
     * @param  bool $asSource
200
     * @return string
201
     */
202
    public function displayAttachment($asSource = false)
0 ignored issues
show
Coding Style introduced by
displayAttachment 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...
203
    {
204
        global $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
205
206
        $post_attachment = '';
207
        $attachments     = $this->getAttachment();
208
        if (is_array($attachments) && count($attachments) > 0) {
209
            $iconHandler = newbbGetIconHandler();
210
            $mime_path   = $iconHandler->getPath('mime');
211
            include_once dirname(__DIR__) . '/include/functions.image.php';
212
            $image_extensions = ['jpg', 'jpeg', 'gif', 'png', 'bmp']; // need improve !!!
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% 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...
213
            $post_attachment  .= '<br><strong>' . _MD_NEWBB_ATTACHMENT . '</strong>:';
214
            $post_attachment  .= '<br><hr size="1" noshade="noshade" /><br>';
215
            foreach ($attachments as $key => $att) {
216
                $file_extension = ltrim(strrchr($att['name_saved'], '.'), '.');
217
                $filetype       = $file_extension;
218
                if (file_exists($GLOBALS['xoops']->path($mime_path . '/' . $filetype . '.gif'))) {
219
                    $icon_filetype = XOOPS_URL . '/' . $mime_path . '/' . $filetype . '.gif';
220
                } else {
221
                    $icon_filetype = XOOPS_URL . '/' . $mime_path . '/unknown.gif';
222
                }
223
                $file_size = @filesize($GLOBALS['xoops']->path($GLOBALS['xoopsModuleConfig']['dir_attachments'] . '/' . $att['name_saved']));
224
                $file_size = number_format($file_size / 1024, 2) . ' KB';
225
                if (in_array(strtolower($file_extension), $image_extensions)
226
                    && $GLOBALS['xoopsModuleConfig']['media_allowed']) {
227
                    $post_attachment .= '<br><img src="' . $icon_filetype . '" alt="' . $filetype . '" /><strong>&nbsp; ' . $att['nameDisplay'] . '</strong> <small>(' . $file_size . ')</small>';
228
                    $post_attachment .= '<br>' . newbb_attachmentImage($att['name_saved']);
229
                    $isDisplayed     = true;
0 ignored issues
show
Unused Code introduced by
$isDisplayed 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...
230
                } else {
231
                    if (empty($GLOBALS['xoopsModuleConfig']['show_userattach'])) {
232
                        $post_attachment .= '<a href="'
233
                                            . XOOPS_URL
234
                                            . '/modules/'
235
                                            . $xoopsModule->getVar('dirname', 'n')
236
                                            . '/dl_attachment.php?attachid='
237
                                            . $key
238
                                            . '&amp;post_id='
239
                                            . $this->getVar('post_id')
240
                                            . '"> <img src="'
241
                                            . $icon_filetype
242
                                            . '" alt="'
243
                                            . $filetype
244
                                            . '" /> '
245
                                            . $att['nameDisplay']
246
                                            . '</a> '
247
                                            . _MD_NEWBB_FILESIZE
248
                                            . ': '
249
                                            . $file_size
250
                                            . '; '
251
                                            . _MD_NEWBB_HITS
252
                                            . ': '
253
                                            . $att['numDownload'];
254
                    } elseif ($GLOBALS['xoopsUser'] && $GLOBALS['xoopsUser']->uid() > 0
255
                              && $GLOBALS['xoopsUser']->isactive()) {
256
                        $post_attachment .= '<a href="'
257
                                            . XOOPS_URL
258
                                            . '/modules/'
259
                                            . $xoopsModule->getVar('dirname', 'n')
260
                                            . '/dl_attachment.php?attachid='
261
                                            . $key
262
                                            . '&amp;post_id='
263
                                            . $this->getVar('post_id')
264
                                            . '"> <img src="'
265
                                            . $icon_filetype
266
                                            . '" alt="'
267
                                            . $filetype
268
                                            . '" /> '
269
                                            . $att['nameDisplay']
270
                                            . '</a> '
271
                                            . _MD_NEWBB_FILESIZE
272
                                            . ': '
273
                                            . $file_size
274
                                            . '; '
275
                                            . _MD_NEWBB_HITS
276
                                            . ': '
277
                                            . $att['numDownload'];
278
                    } else {
279
                        $post_attachment .= _MD_NEWBB_SEENOTGUEST;
280
                    }
281
                }
282
                $post_attachment .= '<br>';
283
            }
284
        }
285
286
        return $post_attachment;
287
    }
288
    // attachment functions
289
    // ////////////////////////////////////////////////////////////////////////////////////
290
291
    /**
292
     * @param  string $poster_name
293
     * @param  string $post_editmsg
294
     * @return bool
295
     */
296
    public function setPostEdit($poster_name = '', $post_editmsg = '')
0 ignored issues
show
Coding Style introduced by
setPostEdit 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...
297
    {
298
        $edit_user = '';
299
        if (empty($GLOBALS['xoopsModuleConfig']['recordedit_timelimit'])
300
            || (time() - $this->getVar('post_time')) < $GLOBALS['xoopsModuleConfig']['recordedit_timelimit'] * 60
301
            || $this->getVar('approved') < 1) {
302
            return true;
303
        }
304 View Code Duplication
        if (is_object($GLOBALS['xoopsUser']) && $GLOBALS['xoopsUser']->isActive()) {
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...
305
            if ($GLOBALS['xoopsModuleConfig']['show_realname'] && $GLOBALS['xoopsUser']->getVar('name')) {
306
                $edit_user = $GLOBALS['xoopsUser']->getVar('name');
307
            } else {
308
                $edit_user = $GLOBALS['xoopsUser']->getVar('uname');
309
            }
310
        }
311
        $post_edit              = [];
312
        $post_edit['edit_user'] = $edit_user; // (?) The proper way is to store uid instead of name.
313
        // However, to save queries when displaying, the current way is ok.
314
        $post_edit['edit_time'] = time();
315
        $post_edit['edit_msg']  = $post_editmsg;
316
317
        $post_edits = $this->getVar('post_edit');
318
        if (!empty($post_edits)) {
319
            $post_edits = unserialize(base64_decode($post_edits));
320
        }
321
        if (!is_array($post_edits)) {
322
            $post_edits = [];
323
        }
324
        $post_edits[] = $post_edit;
325
        $post_edit    = base64_encode(serialize($post_edits));
326
        unset($post_edits);
327
        $this->setVar('post_edit', $post_edit);
328
329
        return true;
330
    }
331
332
    /**
333
     * @return bool|string
334
     */
335
    public function displayPostEdit()
0 ignored issues
show
Coding Style introduced by
displayPostEdit 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
        global $myts;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
338
339
        if (empty($GLOBALS['xoopsModuleConfig']['recordedit_timelimit'])) {
340
            return false;
341
        }
342
343
        $post_edit  = '';
344
        $post_edits = $this->getVar('post_edit');
345
        if (!empty($post_edits)) {
346
            $post_edits = unserialize(base64_decode($post_edits));
347
        }
348
        if (!isset($post_edits) || !is_array($post_edits)) {
349
            $post_edits = [];
350
        }
351
        if (is_array($post_edits) && count($post_edits) > 0) {
352
            foreach ($post_edits as $postedit) {
353
                $edit_time = (int)$postedit['edit_time'];
354
                $edit_user = $postedit['edit_user'];
355
                $edit_msg  = (!empty($postedit['edit_msg'])) ? $postedit['edit_msg'] : '';
356
                // Start irmtfan add option to do only the latest edit when do_latestedit=0 (Alfred)
357
                if (empty($GLOBALS['xoopsModuleConfig']['do_latestedit'])) {
358
                    $post_edit = '';
359
                }
360
                // End irmtfan add option to do only the latest edit when do_latestedit=0 (Alfred)
361
                // START hacked by irmtfan
362
                // display/save all edit records.
363
                $post_edit .= _MD_NEWBB_EDITEDBY . ' ' . $edit_user . ' ' . _MD_NEWBB_ON . ' ' . formatTimestamp((int)$edit_time) . '<br>';
364
                // if reason is not empty
365
                if ($edit_msg !== '') {
366
                    $post_edit .= _MD_NEWBB_EDITEDMSG . ' ' . $edit_msg . '<br>';
367
                }
368
                // START hacked by irmtfan
369
            }
370
        }
371
372
        return $post_edit;
373
    }
374
375
    /**
376
     * @return array
377
     */
378
    public function &getPostBody()
0 ignored issues
show
Coding Style introduced by
getPostBody 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...
379
    {
380
        global $viewtopic_users;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
381
        $newbbConfig = newbbLoadConfig();
382
        include_once __DIR__ . '/../include/functions.user.php';
383
        include_once __DIR__ . '/../include/functions.render.php';
384
385
        $uid = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0;
386
        /** @var NewbbKarmaHandler $karmaHandler */
387
        $karmaHandler = xoops_getModuleHandler('karma', 'newbb');
388
        $user_karma   = $karmaHandler->getUserKarma();
389
390
        $post               = [];
391
        $post['attachment'] = false;
392
        $post_text          = newbb_displayTarea($this->vars['post_text']['value'], $this->getVar('dohtml'), $this->getVar('dosmiley'), $this->getVar('doxcode'), $this->getVar('doimage'), $this->getVar('dobr'));
393
        if (newbb_isAdmin($this->getVar('forum_id')) || $this->checkIdentity()) {
394
            $post['text'] = $post_text . '<br>' . $this->displayAttachment();
395
        } elseif ($newbbConfig['enable_karma'] && $this->getVar('post_karma') > $user_karma) {
396
            $post['text'] = sprintf(_MD_NEWBB_KARMA_REQUIREMENT, $user_karma, $this->getVar('post_karma'));
397
        } elseif ($newbbConfig['allow_require_reply'] && $this->getVar('require_reply')
398
                  && (!$uid || !isset($viewtopic_users[$uid]))) {
399
            $post['text'] = _MD_NEWBB_REPLY_REQUIREMENT;
400
        } else {
401
            $post['text'] = $post_text . '<br>' . $this->displayAttachment();
402
        }
403
        /** @var XoopsMemberHandler $memberHandler */
404
        $memberHandler = xoops_getHandler('member');
405
        $eachposter    = $memberHandler->getUser($this->getVar('uid'));
406
        if (is_object($eachposter) && $eachposter->isActive()) {
407
            if ($newbbConfig['show_realname'] && $eachposter->getVar('name')) {
408
                $post['author'] = $eachposter->getVar('name');
409
            } else {
410
                $post['author'] = $eachposter->getVar('uname');
411
            }
412
            unset($eachposter);
413
        } else {
414
            $post['author'] = $this->getVar('poster_name') ?: $GLOBALS['xoopsConfig']['anonymous'];
415
        }
416
417
        $post['subject'] = newbb_htmlspecialchars($this->vars['subject']['value']);
418
419
        $post['date'] = $this->getVar('post_time');
420
421
        return $post;
422
    }
423
424
    /**
425
     * @return bool
426
     */
427
    public function isTopic()
428
    {
429
        return !$this->getVar('pid');
430
    }
431
432
    /**
433
     * @param  string $action_tag
434
     * @return bool
435
     */
436
    public function checkTimelimit($action_tag = 'edit_timelimit')
437
    {
438
        $newbbConfig = newbbLoadConfig();
439
        if (empty($newbbConfig['edit_timelimit'])) {
440
            return true;
441
        }
442
443
        return ($this->getVar('post_time') > time() - $newbbConfig[$action_tag] * 60);
444
    }
445
446
    /**
447
     * @param  int $uid
448
     * @return bool
449
     */
450
    public function checkIdentity($uid = -1)
0 ignored issues
show
Coding Style introduced by
checkIdentity 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...
451
    {
452
        $uid = ($uid > -1) ? $uid : (is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0);
453
        if ($this->getVar('uid') > 0) {
454
            $user_ok = ($uid == $this->getVar('uid'));
455
        } else {
456
            static $user_ip;
457
            if (!isset($user_ip)) {
458
                $user_ip = \Xmf\IPAddress::fromRequest()->asReadable();
459
            }
460
            $user_ok = ($user_ip == $this->getVar('poster_ip'));
461
        }
462
463
        return $user_ok;
464
    }
465
466
    // TODO: cleaning up and merge with post hanldings in viewpost.php
467
468
    /**
469
     * @param $isadmin
470
     * @return array
471
     */
472
    public function showPost($isadmin)
0 ignored issues
show
Coding Style introduced by
showPost 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...
473
    {
474
        global $xoopsModule, $myts;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
475
        global $forumUrl, $forumImage, $forum_obj, $online, $viewmode;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
476
        global $viewtopic_users, $viewtopic_posters, $topic_obj, $user_karma;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
477
        global $order, $start, $total_posts, $topic_status;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
478
        static $post_NO = 0;
479
        static $name_anonymous;
480
481
        if (!isset($name_anonymous)) {
482
            $name_anonymous = $myts->htmlSpecialChars($GLOBALS['xoopsConfig']['anonymous']);
483
        }
484
485
        include_once __DIR__ . '/../include/functions.time.php';
486
        include_once __DIR__ . '/../include/functions.render.php';
487
488
        $post_id  = $this->getVar('post_id');
489
        $topic_id = $this->getVar('topic_id');
490
        $forum_id = $this->getVar('forum_id');
491
492
        $query_vars              = ['status', 'order', 'start', 'mode', 'viewmode'];
493
        $query_array             = [];
494
        $query_array['topic_id'] = "topic_id={$topic_id}";
495
        foreach ($query_vars as $var) {
496
            if (Request::getString($var, '', 'GET')) {
497
                $query_array[$var] = "{$var}=" . Request::getString($var, '', 'GET');
498
            }
499
        }
500
        $page_query = htmlspecialchars(implode('&', array_values($query_array)));
501
502
        $uid = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0;
503
504
        ++$post_NO;
505
        if (strtolower($order) === 'desc') {
506
            $post_no = $total_posts - ($start + $post_NO) + 1;
507
        } else {
508
            $post_no = $start + $post_NO;
509
        }
510
511
        if ($isadmin || $this->checkIdentity()) {
512
            $post_text       = $this->getVar('post_text');
513
            $post_attachment = $this->displayAttachment();
514 View Code Duplication
        } elseif ($GLOBALS['xoopsModuleConfig']['enable_karma'] && $this->getVar('post_karma') > $user_karma) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
515
            $post_text       = "<div class='karma'>" . sprintf(_MD_NEWBB_KARMA_REQUIREMENT, $user_karma, $this->getVar('post_karma')) . '</div>';
516
            $post_attachment = '';
517
        } elseif ($GLOBALS['xoopsModuleConfig']['allow_require_reply'] && $this->getVar('require_reply')
518
                  && (!$uid || !in_array($uid, $viewtopic_posters))) {
519
            $post_text       = "<div class='karma'>" . _MD_NEWBB_REPLY_REQUIREMENT . '</div>';
520
            $post_attachment = '';
521
        } else {
522
            $post_text       = $this->getVar('post_text');
523
            $post_attachment = $this->displayAttachment();
524
        }
525
526
        // Hightlight search words
527
        $post_title = $this->getVar('subject');
528
        if ($keywords = Request::getString('keywords', '', 'GET')) {
529
            //$keywords   = $myts->htmlSpecialChars(trim(urldecode(Request::getString('keywords', '', 'GET'))));
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...
530
            $post_text  = Highlighter::apply($keywords, $post_text, '<mark>', '</mark>');
531
            $post_title = Highlighter::apply($keywords, $post_title, '<mark>', '</mark>');
532
        }
533
534
        if (isset($viewtopic_users[$this->getVar('uid')])) {
535
            $poster = $viewtopic_users[$this->getVar('uid')];
536
        } else {
537
            $name   = ($post_name = $this->getVar('poster_name')) ? $post_name : $name_anonymous;
538
            $poster = [
539
                'poster_uid' => 0,
540
                'name'       => $name,
541
                'link'       => $name
542
            ];
543
        }
544
545
        if ($posticon = $this->getVar('icon')) {
546
            $post_image = '<a name="' . $post_id . '"><img src="' . XOOPS_URL . '/images/subject/' . $posticon . '" alt="" /></a>';
547
        } else {
548
            $post_image = '<a name="' . $post_id . '"><img src="' . XOOPS_URL . '/images/icons/posticon.gif" alt="" /></a>';
549
        }
550
551
        $thread_buttons = [];
552
        $mod_buttons    = [];
553
554
        if ($isadmin && ($GLOBALS['xoopsUser'] && $GLOBALS['xoopsUser']->getVar('uid') !== $this->getVar('uid'))
555
            && $this->getVar('uid') > 0) {
556
            $mod_buttons['bann']['image']    = newbbDisplayImage('p_bann', _MD_NEWBB_SUSPEND_MANAGEMENT);
557
            $mod_buttons['bann']['link']     = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . '/moderate.php?forum=' . $forum_id . '&amp;uid=' . $this->getVar('uid');
558
            $mod_buttons['bann']['name']     = _MD_NEWBB_SUSPEND_MANAGEMENT;
559
            $thread_buttons['bann']['image'] = newbbDisplayImage('p_bann', _MD_NEWBB_SUSPEND_MANAGEMENT);
560
            $thread_buttons['bann']['link']  = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . '/moderate.php?forum=' . $forum_id . '&amp;uid=' . $this->getVar('uid');
561
            $thread_buttons['bann']['name']  = _MD_NEWBB_SUSPEND_MANAGEMENT;
562
        }
563
564
        if ($GLOBALS['xoopsModuleConfig']['enable_permcheck']) {
565
            /** @var NewbbTopicHandler $topicHandler */
566
            $topicHandler = xoops_getModuleHandler('topic', 'newbb');
567
            $topic_status = $topic_obj->getVar('topic_status');
568 View Code Duplication
            if ($topicHandler->getPermission($forum_id, $topic_status, 'edit')) {
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...
569
                $edit_ok = ($isadmin || ($this->checkIdentity() && $this->checkTimelimit('edit_timelimit')));
570
571
                if ($edit_ok) {
572
                    $thread_buttons['edit']['image'] = newbbDisplayImage('p_edit', _EDIT);
573
                    $thread_buttons['edit']['link']  = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . "/edit.php?{$page_query}";
574
                    $thread_buttons['edit']['name']  = _EDIT;
575
                    $mod_buttons['edit']['image']    = newbbDisplayImage('p_edit', _EDIT);
576
                    $mod_buttons['edit']['link']     = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . "/edit.php?{$page_query}";
577
                    $mod_buttons['edit']['name']     = _EDIT;
578
                }
579
            }
580
581 View Code Duplication
            if ($topicHandler->getPermission($forum_id, $topic_status, 'delete')) {
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...
582
                $delete_ok = ($isadmin || ($this->checkIdentity() && $this->checkTimelimit('delete_timelimit')));
583
584
                if ($delete_ok) {
585
                    $thread_buttons['delete']['image'] = newbbDisplayImage('p_delete', _DELETE);
586
                    $thread_buttons['delete']['link']  = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . "/delete.php?{$page_query}";
587
                    $thread_buttons['delete']['name']  = _DELETE;
588
                    $mod_buttons['delete']['image']    = newbbDisplayImage('p_delete', _DELETE);
589
                    $mod_buttons['delete']['link']     = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . "/delete.php?{$page_query}";
590
                    $mod_buttons['delete']['name']     = _DELETE;
591
                }
592
            }
593
            if ($topicHandler->getPermission($forum_id, $topic_status, 'reply')) {
594
                $thread_buttons['reply']['image'] = newbbDisplayImage('p_reply', _MD_NEWBB_REPLY);
595
                $thread_buttons['reply']['link']  = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . "/reply.php?{$page_query}";
596
                $thread_buttons['reply']['name']  = _MD_NEWBB_REPLY;
597
598
                $thread_buttons['quote']['image'] = newbbDisplayImage('p_quote', _MD_NEWBB_QUOTE);
599
                $thread_buttons['quote']['link']  = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . "/reply.php?{$page_query}&amp;quotedac=1";
600
                $thread_buttons['quote']['name']  = _MD_NEWBB_QUOTE;
601
            }
602
        } else {
603
            $mod_buttons['edit']['image'] = newbbDisplayImage('p_edit', _EDIT);
604
            $mod_buttons['edit']['link']  = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . "/edit.php?{$page_query}";
605
            $mod_buttons['edit']['name']  = _EDIT;
606
607
            $mod_buttons['delete']['image'] = newbbDisplayImage('p_delete', _DELETE);
608
            $mod_buttons['delete']['link']  = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . "/delete.php?{$page_query}";
609
            $mod_buttons['delete']['name']  = _DELETE;
610
611
            $thread_buttons['reply']['image'] = newbbDisplayImage('p_reply', _MD_NEWBB_REPLY);
612
            $thread_buttons['reply']['link']  = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . "/reply.php?{$page_query}";
613
            $thread_buttons['reply']['name']  = _MD_NEWBB_REPLY;
614
        }
615
616
        if (!$isadmin && $GLOBALS['xoopsModuleConfig']['reportmod_enabled']) {
617
            $thread_buttons['report']['image'] = newbbDisplayImage('p_report', _MD_NEWBB_REPORT);
618
            $thread_buttons['report']['link']  = XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . "/report.php?{$page_query}";
619
            $thread_buttons['report']['name']  = _MD_NEWBB_REPORT;
620
        }
621
622
        $thread_action = [];
623
        // irmtfan add pdf permission
624
        if (file_exists(XOOPS_PATH . '/vendor/tcpdf/tcpdf.php')
625
            && $topicHandler->getPermission($forum_id, $topic_status, 'pdf')) {
0 ignored issues
show
Bug introduced by
The variable $topicHandler 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...
626
            $thread_action['pdf']['image']  = newbbDisplayImage('pdf', _MD_NEWBB_PDF);
627
            $thread_action['pdf']['link']   = XOOPS_URL . '/modules/newbb/makepdf.php?type=post&amp;pageid=0';
628
            $thread_action['pdf']['name']   = _MD_NEWBB_PDF;
629
            $thread_action['pdf']['target'] = '_blank';
630
        }
631
        // irmtfan add print permission
632
        if ($topicHandler->getPermission($forum_id, $topic_status, 'print')) {
633
            $thread_action['print']['image']  = newbbDisplayImage('printer', _MD_NEWBB_PRINT);
634
            $thread_action['print']['link']   = XOOPS_URL . '/modules/newbb/print.php?form=2&amp;forum=' . $forum_id . '&amp;topic_id=' . $topic_id;
635
            $thread_action['print']['name']   = _MD_NEWBB_PRINT;
636
            $thread_action['print']['target'] = '_blank';
637
        }
638
639
        if ($GLOBALS['xoopsModuleConfig']['show_sociallinks']) {
640
            $full_title  = $this->getVar('subject');
641
            $clean_title = preg_replace('/[^A-Za-z0-9-]+/', '+', $this->getVar('subject'));
642
            $full_link   = XOOPS_URL . '/modules/newbb/viewtopic.php?post_id=' . $post_id;
643
644
            $thread_action['social_twitter']['image']  = newbbDisplayImage('twitter', _MD_NEWBB_SHARE_TWITTER);
645
            $thread_action['social_twitter']['link']   = 'http://twitter.com/share?text=' . $clean_title . '&amp;url=' . $full_link;
646
            $thread_action['social_twitter']['name']   = _MD_NEWBB_SHARE_TWITTER;
647
            $thread_action['social_twitter']['target'] = '_blank';
648
649
            $thread_action['social_facebook']['image']  = newbbDisplayImage('facebook', _MD_NEWBB_SHARE_FACEBOOK);
650
            $thread_action['social_facebook']['link']   = 'http://www.facebook.com/sharer.php?u=' . $full_link;
651
            $thread_action['social_facebook']['name']   = _MD_NEWBB_SHARE_FACEBOOK;
652
            $thread_action['social_facebook']['target'] = '_blank';
653
654
            $thread_action['social_gplus']['image']  = newbbDisplayImage('googleplus', _MD_NEWBB_SHARE_GOOGLEPLUS);
655
            $thread_action['social_gplus']['link']   = 'https://plusone.google.com/_/+1/confirm?hl=en&url=' . $full_link;
656
            $thread_action['social_gplus']['name']   = _MD_NEWBB_SHARE_GOOGLEPLUS;
657
            $thread_action['social_gplus']['target'] = '_blank';
658
659
            $thread_action['social_linkedin']['image']  = newbbDisplayImage('linkedin', _MD_NEWBB_SHARE_LINKEDIN);
660
            $thread_action['social_linkedin']['link']   = 'http://www.linkedin.com/shareArticle?mini=true&amp;title=' . $full_title . '&amp;url=' . $full_link;
661
            $thread_action['social_linkedin']['name']   = _MD_NEWBB_SHARE_LINKEDIN;
662
            $thread_action['social_linkedin']['target'] = '_blank';
663
664
            $thread_action['social_delicious']['image']  = newbbDisplayImage('delicious', _MD_NEWBB_SHARE_DELICIOUS);
665
            $thread_action['social_delicious']['link']   = 'http://del.icio.us/post?title=' . $full_title . '&amp;url=' . $full_link;
666
            $thread_action['social_delicious']['name']   = _MD_NEWBB_SHARE_DELICIOUS;
667
            $thread_action['social_delicious']['target'] = '_blank';
668
669
            $thread_action['social_digg']['image']  = newbbDisplayImage('digg', _MD_NEWBB_SHARE_DIGG);
670
            $thread_action['social_digg']['link']   = 'http://digg.com/submit?phase=2&amp;title=' . $full_title . '&amp;url=' . $full_link;
671
            $thread_action['social_digg']['name']   = _MD_NEWBB_SHARE_DIGG;
672
            $thread_action['social_digg']['target'] = '_blank';
673
674
            $thread_action['social_reddit']['image']  = newbbDisplayImage('reddit', _MD_NEWBB_SHARE_REDDIT);
675
            $thread_action['social_reddit']['link']   = 'http://reddit.com/submit?title=' . $full_title . '&amp;url=' . $full_link;
676
            $thread_action['social_reddit']['name']   = _MD_NEWBB_SHARE_REDDIT;
677
            $thread_action['social_reddit']['target'] = '_blank';
678
679
            $thread_action['social_wong']['image']  = newbbDisplayImage('wong', _MD_NEWBB_SHARE_MRWONG);
680
            $thread_action['social_wong']['link']   = 'http://www.mister-wong.de/index.php?action=addurl&bm_url=' . $full_link;
681
            $thread_action['social_wong']['name']   = _MD_NEWBB_SHARE_MRWONG;
682
            $thread_action['social_wong']['target'] = '_blank';
683
        }
684
685
        $post = [
686
            'post_id'         => $post_id,
687
            'post_parent_id'  => $this->getVar('pid'),
688
            'post_date'       => newbb_formatTimestamp($this->getVar('post_time')),
689
            'post_image'      => $post_image,
690
            'post_title'      => $post_title,
691
            // irmtfan $post_title to add highlight keywords
692
            'post_text'       => $post_text,
693
            'post_attachment' => $post_attachment,
694
            'post_edit'       => $this->displayPostEdit(),
695
            'post_no'         => $post_no,
696
            'post_signature'  => $this->getVar('attachsig') ? @$poster['signature'] : '',
697
            //            'poster_ip'       => ($isadmin && $GLOBALS['xoopsModuleConfig']['show_ip']) ? long2ip($this->getVar('poster_ip')) : '',
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...
698
            'poster_ip'       => ($isadmin
699
                                  && $GLOBALS['xoopsModuleConfig']['show_ip']) ? $this->getVar('poster_ip') : '',
700
            'thread_action'   => $thread_action,
701
            'thread_buttons'  => $thread_buttons,
702
            'mod_buttons'     => $mod_buttons,
703
            'poster'          => $poster,
704
            'post_permalink'  => '<a href="' . XOOPS_URL . '/modules/' . $xoopsModule->getVar('dirname') . '/viewtopic.php?post_id=' . $post_id . '"></a>'
705
        ];
706
707
        unset($thread_buttons, $mod_buttons, $eachposter);
708
709
        return $post;
710
    }
711
}
712
713
/**
714
 * Class NewbbPostHandler
715
 */
716
class NewbbPostHandler extends XoopsPersistableObjectHandler
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

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

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

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

namespace YourVendor;

class YourClass { }

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

Loading history...
717
{
718
    /**
719
     * @param XoopsDatabase|null $db
720
     */
721
    public function __construct(XoopsDatabase $db)
722
    {
723
        parent::__construct($db, 'newbb_posts', 'NewbbPost', 'post_id', 'subject');
724
    }
725
726
    /**
727
     * @param  mixed $id
728
     * @param  null  $var
729
     * @return null|XoopsObject
730
     */
731
    public function get($id = null, $var = null) //get($id)
732
    {
733
        $id   = (int)$id;
734
        $post = null;
735
        $sql  = 'SELECT p.*, t.* FROM ' . $this->db->prefix('newbb_posts') . ' p LEFT JOIN ' . $this->db->prefix('newbb_posts_text') . ' t ON p.post_id=t.post_id WHERE p.post_id=' . $id;
736 View Code Duplication
        if ($array = $this->db->fetchArray($this->db->query($sql))) {
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...
737
            $post = $this->create(false);
738
            $post->assignVars($array);
739
        }
740
741
        return $post;
742
    }
743
744
    /**
745
     * @param  int             $limit
746
     * @param  int             $start
747
     * @param  CriteriaElement $criteria
748
     * @param  null            $fields
749
     * @param  bool            $asObject
750
     * @param  int             $topic_id
751
     * @param  int             $approved
752
     * @return array
753
     */
754
    //    public function getByLimit($topic_id, $limit, $approved = 1)
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% 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...
755
    public function &getByLimit(
756
        $limit = 0,
757
        $start = 0,
758
        CriteriaElement $criteria = null,
759
        $fields = null,
760
        $asObject = true,
761
        $topic_id = 0,
762
        $approved = 1
763
    ) {
764
        $sql    = 'SELECT p.*, t.*, tp.topic_status FROM '
765
                  . $this->db->prefix('newbb_posts')
766
                  . ' p LEFT JOIN '
767
                  . $this->db->prefix('newbb_posts_text')
768
                  . ' t ON p.post_id=t.post_id LEFT JOIN '
769
                  . $this->db->prefix('newbb_topics')
770
                  . ' tp ON tp.topic_id=p.topic_id WHERE p.topic_id='
771
                  . $topic_id
772
                  . ' AND p.approved ='
773
                  . $approved
774
                  . ' ORDER BY p.post_time DESC';
775
        $result = $this->db->query($sql, $limit, 0);
776
        $ret    = [];
777 View Code Duplication
        while ($myrow = $this->db->fetchArray($result)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
778
            $post = $this->create(false);
779
            $post->assignVars($myrow);
780
781
            $ret[$myrow['post_id']] = $post;
782
            unset($post);
783
        }
784
785
        return $ret;
786
    }
787
788
    /**
789
     * @param NewbbPost $post
790
     * @return mixed
791
     */
792
    public function getPostForPDF(&$post)
793
    {
794
        return $post->getPostBody(true);
795
    }
796
797
    /**
798
     * @param NewbbPost $post
799
     * @return mixed
800
     */
801
    public function getPostForPrint(&$post)
802
    {
803
        return $post->getPostBody();
804
    }
805
806
    /**
807
     * @param  NewbbPost $post
808
     * @param  bool      $force
809
     * @return bool
810
     */
811
    public function approve(&$post, $force = false)
812
    {
813
        if (empty($post)) {
814
            return false;
815
        }
816
        if (is_numeric($post)) {
817
            $post = $this->get($post);
818
        }
819
        $post_id = $post->getVar('post_id');
0 ignored issues
show
Unused Code introduced by
$post_id 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...
820
821
        $wasApproved = $post->getVar('approved');
822
        // irmtfan approve post if the approved = 0 (pending) or -1 (deleted)
823
        if (empty($force) && $wasApproved > 0) {
824
            return true;
825
        }
826
        $post->setVar('approved', 1);
827
        $this->insert($post, true);
828
829
        /** @var \NewbbTopicHandler $topicHandler */
830
        $topicHandler = xoops_getModuleHandler('topic', 'newbb');
831
        $topic_obj    = $topicHandler->get($post->getVar('topic_id'));
832
        if ($topic_obj->getVar('topic_last_post_id') < $post->getVar('post_id')) {
833
            $topic_obj->setVar('topic_last_post_id', $post->getVar('post_id'));
834
        }
835
        if ($post->isTopic()) {
836
            $topic_obj->setVar('approved', 1);
837
        } else {
838
            $topic_obj->setVar('topic_replies', $topic_obj->getVar('topic_replies') + 1);
839
        }
840
        $topicHandler->insert($topic_obj, true);
841
842
        /** @var \NewbbForumHandler $forumHandler */
843
        $forumHandler = xoops_getModuleHandler('forum', 'newbb');
844
        $forum_obj    = $forumHandler->get($post->getVar('forum_id'));
845
        if ($forum_obj->getVar('forum_last_post_id') < $post->getVar('post_id')) {
846
            $forum_obj->setVar('forum_last_post_id', $post->getVar('post_id'));
847
        }
848
        $forum_obj->setVar('forum_posts', $forum_obj->getVar('forum_posts') + 1);
849
        if ($post->isTopic()) {
850
            $forum_obj->setVar('forum_topics', $forum_obj->getVar('forum_topics') + 1);
851
        }
852
        $forumHandler->insert($forum_obj, true);
853
854
        // Update user stats
855 View Code Duplication
        if ($post->getVar('uid') > 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...
856
            /** @var XoopsMemberHandler $memberHandler */
857
            $memberHandler = xoops_getHandler('member');
858
            $poster        = $memberHandler->getUser($post->getVar('uid'));
859
            if (is_object($poster) && $post->getVar('uid') == $poster->getVar('uid')) {
860
                $poster->setVar('posts', $poster->getVar('posts') + 1);
861
                $res = $memberHandler->insertUser($poster, true);
0 ignored issues
show
Unused Code introduced by
$res 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...
862
                unset($poster);
863
            }
864
        }
865
866
        // Update forum stats
867
        /** @var NewbbStatsHandler $statsHandler */
868
        $statsHandler = xoops_getModuleHandler('stats', 'newbb');
869
        $statsHandler->update($post->getVar('forum_id'), 'post');
870
        if ($post->isTopic()) {
871
            $statsHandler->update($post->getVar('forum_id'), 'topic');
872
        }
873
874
        return true;
875
    }
876
877
    /**
878
     * @param  XoopsObject $post
879
     * @param  bool        $force
880
     * @return bool
881
     */
882
    public function insert(XoopsObject $post, $force = true) //insert(&$post, $force = true)
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...
883
    {
884
        $topic_obj = null;
885
        // Set the post time
886
        // The time should be "publish" time. To be adjusted later
887
        if (!$post->getVar('post_time')) {
888
            $post->setVar('post_time', time());
889
        }
890
891
        /** @var \NewbbTopicHandler $topicHandler */
892
        $topicHandler = xoops_getModuleHandler('topic', 'newbb');
893
        // Verify the topic ID
894
        if ($topic_id = $post->getVar('topic_id')) {
895
            $topic_obj = $topicHandler->get($topic_id);
896
            // Invalid topic OR the topic is no approved and the post is not top post
897
            if (!$topic_obj//    || (!$post->isTopic() && $topic_obj->getVar("approved") < 1)
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% 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...
898
            ) {
899
                return false;
900
            }
901
        }
902
        if (empty($topic_id)) {
903
            $post->setVar('topic_id', 0);
904
            $post->setVar('pid', 0);
905
            $post->setNew();
906
            $topic_obj = $topicHandler->create();
907
        }
908
        $textHandler    = xoops_getModuleHandler('text', 'newbb');
909
        $post_text_vars = ['post_text', 'post_edit', 'dohtml', 'doxcode', 'dosmiley', 'doimage', 'dobr'];
910
        if ($post->isNew()) {
911
            if (!$topic_id = $post->getVar('topic_id')) {
912
                $topic_obj->setVar('topic_title', $post->getVar('subject', 'n'));
913
                $topic_obj->setVar('topic_poster', $post->getVar('uid'));
914
                $topic_obj->setVar('forum_id', $post->getVar('forum_id'));
915
                $topic_obj->setVar('topic_time', $post->getVar('post_time'));
916
                $topic_obj->setVar('poster_name', $post->getVar('poster_name'));
917
                $topic_obj->setVar('approved', $post->getVar('approved'));
918
919
                if (!$topic_id = $topicHandler->insert($topic_obj, $force)) {
920
                    $post->deleteAttachment();
921
                    $post->setErrors('insert topic error');
922
923
                    //xoops_error($topic_obj->getErrors());
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% 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...
924
                    return false;
925
                }
926
                $post->setVar('topic_id', $topic_id);
927
928
                $pid = 0;
0 ignored issues
show
Unused Code introduced by
$pid is not used, you could remove the assignment.

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

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

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

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

Loading history...
929
                $post->setVar('pid', 0);
930
            } elseif (!$post->getVar('pid')) {
931
                $pid = $topicHandler->getTopPostId($topic_id);
932
                $post->setVar('pid', $pid);
933
            }
934
935
            $text_obj = $textHandler->create();
936
            foreach ($post_text_vars as $key) {
937
                $text_obj->vars[$key] = $post->vars[$key];
938
            }
939
            $post->destroyVars($post_text_vars);
940
941
            //            if (!$post_id = parent::insert($post, $force)) {
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...
942
            //                return false;
943
            //            }
944
945
            if (!$post_id = parent::insert($post, $force)) {
946
                return false;
947
            } else {
948
                $post->unsetNew();
949
            }
950
951
            $text_obj->setVar('post_id', $post_id);
952
            if (!$textHandler->insert($text_obj, $force)) {
953
                $this->delete($post);
954
                $post->setErrors('post text insert error');
955
956
                //xoops_error($text_obj->getErrors());
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% 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...
957
                return false;
958
            }
959
            if ($post->getVar('approved') > 0) {
960
                $this->approve($post, true);
961
            }
962
            $post->setVar('post_id', $post_id);
963
        } else {
964
            if ($post->isTopic()) {
965
                if ($post->getVar('subject') !== $topic_obj->getVar('topic_title')) {
966
                    $topic_obj->setVar('topic_title', $post->getVar('subject', 'n'));
967
                }
968
                if ($post->getVar('approved') !== $topic_obj->getVar('approved')) {
969
                    $topic_obj->setVar('approved', $post->getVar('approved'));
970
                }
971
                $topic_obj->setDirty();
972
                if (!$result = $topicHandler->insert($topic_obj, $force)) {
973
                    $post->setErrors('update topic error');
974
975
                    //xoops_error($topic_obj->getErrors());
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% 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...
976
                    return false;
977
                }
978
            }
979
            $text_obj = $textHandler->get($post->getVar('post_id'));
980
            $text_obj->setDirty();
981
            foreach ($post_text_vars as $key) {
982
                $text_obj->vars[$key] = $post->vars[$key];
983
            }
984
            $post->destroyVars($post_text_vars);
985
            if (!$post_id = parent::insert($post, $force)) {
986
                //xoops_error($post->getErrors());
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% 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...
987
                return false;
988
            } else {
989
                $post->unsetNew();
990
            }
991
            if (!$textHandler->insert($text_obj, $force)) {
992
                $post->setErrors('update post text error');
993
994
                //xoops_error($text_obj->getErrors());
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% 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...
995
                return false;
996
            }
997
        }
998
999
        return $post->getVar('post_id');
1000
    }
1001
1002
    /**
1003
     * @param  XoopsObject|NewbbPost $post
1004
     * @param  bool                  $isDeleteOne
1005
     * @param  bool                  $force
1006
     * @return bool
1007
     */
1008
    public function delete(XoopsObject $post, $isDeleteOne = true, $force = false)
0 ignored issues
show
Coding Style introduced by
delete 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...
1009
    {
1010
        if (!is_object($post) || $post->getVar('post_id') == 0) {
1011
            return false;
1012
        }
1013
1014
        if ($isDeleteOne) {
1015
            if ($post->isTopic()) {
1016
                $criteria = new CriteriaCompo(new Criteria('topic_id', $post->getVar('topic_id')));
1017
                $criteria->add(new Criteria('approved', 1));
1018
                $criteria->add(new Criteria('pid', 0, '>'));
1019
                if ($this->getPostCount($criteria) > 0) {
1020
                    return false;
1021
                }
1022
            }
1023
1024
            return $this->_delete($post, $force);
1025
        } else {
1026
            require_once $GLOBALS['xoops']->path('class/xoopstree.php');
1027
            $mytree = new XoopsTree($this->db->prefix('newbb_posts'), 'post_id', 'pid');
1028
            $arr    = $mytree->getAllChild($post->getVar('post_id'));
1029
            // irmtfan - delete childs in a reverse order
1030
            for ($i = count($arr) - 1; $i >= 0; $i--) {
1031
                $childpost = $this->create(false);
1032
                $childpost->assignVars($arr[$i]);
1033
                $this->_delete($childpost, $force);
1034
                unset($childpost);
1035
            }
1036
            $this->_delete($post, $force);
1037
        }
1038
1039
        return true;
1040
    }
1041
1042
    /**
1043
     * @param  NewbbPost $post
1044
     * @param  bool      $force
1045
     * @return bool
1046
     */
1047
    public function _delete(NewbbPost $post, $force = false)
1048
    {
1049
        global $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1050
1051
        if (!is_object($post) || $post->getVar('post_id') == 0) {
1052
            return false;
1053
        }
1054
1055
        /* Set active post as deleted */
1056
        if ($post->getVar('approved') > 0 && empty($force)) {
1057
            $sql = 'UPDATE ' . $this->db->prefix('newbb_posts') . ' SET approved = -1 WHERE post_id = ' . $post->getVar('post_id');
1058
            if (!$result = $this->db->queryF($sql)) {
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...
1059
            }
1060
            /* delete pending post directly */
1061
        } else {
1062
            $sql = sprintf('DELETE FROM %s WHERE post_id = %u', $this->db->prefix('newbb_posts'), $post->getVar('post_id'));
1063 View Code Duplication
            if (!$result = $this->db->queryF($sql)) {
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...
1064
                $post->setErrors('delete post error: ' . $sql);
1065
1066
                return false;
1067
            }
1068
            $post->deleteAttachment();
1069
1070
            $sql = sprintf('DELETE FROM %s WHERE post_id = %u', $this->db->prefix('newbb_posts_text'), $post->getVar('post_id'));
1071 View Code Duplication
            if (!$result = $this->db->queryF($sql)) {
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...
1072
                $post->setErrors('Could not remove post text: ' . $sql);
1073
1074
                return false;
1075
            }
1076
        }
1077
1078
        if ($post->isTopic()) {
1079
            $topicHandler = xoops_getModuleHandler('topic', 'newbb');
1080
            /** @var Topic $topic_obj */
1081
            $topic_obj = $topicHandler->get($post->getVar('topic_id'));
1082
            if (is_object($topic_obj) && $topic_obj->getVar('approved') > 0 && empty($force)) {
1083
                $topiccount_toupdate = 1;
0 ignored issues
show
Unused Code introduced by
$topiccount_toupdate 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...
1084
                $topic_obj->setVar('approved', -1);
1085
                $topicHandler->insert($topic_obj);
1086
                xoops_notification_deletebyitem($xoopsModule->getVar('mid'), 'thread', $post->getVar('topic_id'));
1087
            } else {
1088
                if (is_object($topic_obj)) {
1089
                    if ($topic_obj->getVar('approved') > 0) {
1090
                        xoops_notification_deletebyitem($xoopsModule->getVar('mid'), 'thread', $post->getVar('topic_id'));
1091
                    }
1092
1093
                    $poll_id = $topic_obj->getVar('poll_id');
1094
                    // START irmtfan poll_module
1095
                    $topic_obj->deletePoll($poll_id);
1096
                    // END irmtfan poll_module
1097
                }
1098
1099
                $sql = sprintf('DELETE FROM %s WHERE topic_id = %u', $this->db->prefix('newbb_topics'), $post->getVar('topic_id'));
1100
                if (!$result = $this->db->queryF($sql)) {
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...
1101
                    //xoops_error($this->db->error());
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% 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
                }
1103
                $sql = sprintf('DELETE FROM %s WHERE topic_id = %u', $this->db->prefix('newbb_votedata'), $post->getVar('topic_id'));
1104
                if (!$result = $this->db->queryF($sql)) {
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...
1105
                    //xoops_error($this->db->error());
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% 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...
1106
                }
1107
            }
1108
        } else {
1109
            $sql = 'UPDATE ' . $this->db->prefix('newbb_topics') . ' t
1110
                            LEFT JOIN ' . $this->db->prefix('newbb_posts') . ' p ON p.topic_id = t.topic_id
1111
                            SET t.topic_last_post_id = p.post_id
1112
                            WHERE t.topic_last_post_id = ' . $post->getVar('post_id') . '
1113
                                    AND p.post_id = (SELECT MAX(post_id) FROM ' . $this->db->prefix('newbb_posts') . ' WHERE topic_id=t.topic_id)';
1114
            if (!$result = $this->db->queryF($sql)) {
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...
1115
            }
1116
        }
1117
1118
        $postcount_toupdate = $post->getVar('approved');
1119
1120
        if ($postcount_toupdate > 0) {
1121
1122
            // Update user stats
1123 View Code Duplication
            if ($post->getVar('uid') > 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...
1124
                /** @var \XoopsMemberHandler $memberHandler */
1125
                $memberHandler = xoops_getHandler('member');
1126
                $poster        = $memberHandler->getUser($post->getVar('uid'));
1127
                if (is_object($poster) && $post->getVar('uid') == $poster->getVar('uid')) {
1128
                    $poster->setVar('posts', $poster->getVar('posts') - 1);
1129
                    $res = $memberHandler->insertUser($poster, true);
0 ignored issues
show
Unused Code introduced by
$res 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...
1130
                    unset($poster);
1131
                }
1132
            }
1133
            // irmtfan - just update the pid for approved posts when the post is not topic (pid=0)
1134
            if (!$post->isTopic()) {
1135
                $sql = 'UPDATE ' . $this->db->prefix('newbb_posts') . ' SET pid = ' . $post->getVar('pid') . ' WHERE approved=1 AND pid=' . $post->getVar('post_id');
1136
                if (!$result = $this->db->queryF($sql)) {
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...
1137
                    //xoops_error($this->db->error());
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% 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...
1138
                }
1139
            }
1140
        }
1141
1142
        return true;
1143
    }
1144
1145
    // START irmtfan enhance getPostCount when there is join (read_mode = 2)
1146
1147
    /**
1148
     * @param  null $criteria
1149
     * @param  null $join
1150
     * @return int|null
1151
     */
1152
    public function getPostCount($criteria = null, $join = null)
1153
    {
1154
        // if not join get the count from XOOPS/class/model/stats as before
1155
        if (empty($join)) {
1156
            return parent::getCount($criteria);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getCount() instead of getPostCount()). Are you sure this is correct? If so, you might want to change this to $this->getCount().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
1157
        }
1158
1159
        $sql = 'SELECT COUNT(*) as count' . ' FROM ' . $this->db->prefix('newbb_posts') . ' AS p' . ' LEFT JOIN ' . $this->db->prefix('newbb_posts_text') . ' AS t ON t.post_id = p.post_id';
1160
        // LEFT JOIN
1161
        $sql .= $join;
1162
        // WHERE
1163
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
1164
            $sql .= ' ' . $criteria->renderWhere();
1165
        }
1166
        if (!$result = $this->db->query($sql)) {
1167
            //xoops_error($this->db->error().'<br>'.$sql);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
1168
            return null;
1169
        }
1170
        $myrow = $this->db->fetchArray($result);
1171
        $count = $myrow['count'];
1172
1173
        return $count;
1174
    }
1175
    // END irmtfan enhance getPostCount when there is join (read_mode = 2)
1176
    /*
1177
     * TODO: combining viewtopic.php
1178
     */
1179
    /**
1180
     * @param  null $criteria
1181
     * @param  int  $limit
1182
     * @param  int  $start
1183
     * @param  null $join
1184
     * @return array
1185
     */
1186
    public function getPostsByLimit($criteria = null, $limit = 1, $start = 0, $join = null)
1187
    {
1188
        $ret = [];
1189
        $sql = 'SELECT p.*, t.* ' . ' FROM ' . $this->db->prefix('newbb_posts') . ' AS p' . ' LEFT JOIN ' . $this->db->prefix('newbb_posts_text') . ' AS t ON t.post_id = p.post_id';
1190
        if (!empty($join)) {
1191
            $sql .= $join;
1192
        }
1193
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
1194
            $sql .= ' ' . $criteria->renderWhere();
1195
            if ($criteria->getSort() !== '') {
1196
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
1197
            }
1198
        }
1199
        $result = $this->db->query($sql, (int)$limit, (int)$start);
1200
        if (!$result) {
1201
            //xoops_error($this->db->error());
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% 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...
1202
            return $ret;
1203
        }
1204 View Code Duplication
        while ($myrow = $this->db->fetchArray($result)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1205
            $post = $this->create(false);
1206
            $post->assignVars($myrow);
1207
            $ret[$myrow['post_id']] = $post;
1208
            unset($post);
1209
        }
1210
1211
        return $ret;
1212
    }
1213
1214
    /**
1215
     * @return bool
1216
     */
1217
    public function synchronization()
1218
    {
1219
        //$this->cleanOrphan();
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...
1220
        return true;
1221
    }
1222
1223
    /**
1224
     * clean orphan items from database
1225
     *
1226
     * @param  string $table_link
1227
     * @param  string $field_link
1228
     * @param  string $field_object
1229
     * @return bool   true on success
1230
     */
1231
    public function cleanOrphan($table_link = '', $field_link = '', $field_object = '') //cleanOrphan()
1232
    {
1233
        $this->deleteAll(new Criteria('post_time', 0), true, true);
1234
        parent::cleanOrphan($this->db->prefix('newbb_topics'), 'topic_id');
1235
        parent::cleanOrphan($this->db->prefix('newbb_posts_text'), 'post_id');
1236
1237
        $sql = 'DELETE FROM ' . $this->db->prefix('newbb_posts_text') . ' WHERE (post_id NOT IN ( SELECT DISTINCT post_id FROM ' . $this->table . ') )';
1238
        if (!$result = $this->db->queryF($sql)) {
1239
            //xoops_error($this->db->error());
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% 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...
1240
            return false;
1241
        }
1242
1243
        return true;
1244
    }
1245
1246
    /**
1247
     * clean expired objects from database
1248
     *
1249
     * @param  int $expire time limit for expiration
1250
     * @return bool true on success
1251
     */
1252 View Code Duplication
    public function cleanExpires($expire = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1253
    {
1254
        // irmtfan if 0 no cleanup look include/plugin.php
1255
        if (!func_num_args()) {
1256
            $newbbConfig = newbbLoadConfig();
1257
            $expire      = isset($newbbConfig['pending_expire']) ? (int)$newbbConfig['pending_expire'] : 7;
1258
            $expire      = $expire * 24 * 3600; // days to seconds
1259
        }
1260
        if (empty($expire)) {
1261
            return false;
1262
        }
1263
        $crit_expire = new CriteriaCompo(new Criteria('approved', 0, '<='));
1264
        //if (!empty($expire)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
82% 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...
1265
        $crit_expire->add(new Criteria('post_time', time() - (int)$expire, '<'));
1266
1267
        //}
1268
        return $this->deleteAll($crit_expire, true/*, true*/);
1269
    }
1270
}
1271