Issues (371)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

extras/newbb_5x/trunk_5_00/class/Post.php (69 issues)

1
<?php declare(strict_types=1);
2
3
/**
4
 * Newbb module
5
 *
6
 * You may not change or alter any portion of this comment or credits
7
 * of supporting developers from this source code or any supporting source code
8
 * which is considered copyrighted (c) material of the original comment or credit authors.
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
 *
13
 * @copyright       XOOPS Project (https://xoops.org)
14
 * @license         GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html)
15
 * @since           4.0
16
 * @author          Taiwen Jiang <[email protected]>
17
 */
18
19
use XoopsModules\Newbb;
20
use XoopsModules\Xoopspoll;
21
22
/**
23
 * Class post
24
 */
25
class Post extends \XoopsObject
26
{
27
    private $post_id;
0 ignored issues
show
The private property $post_id is not used, and could be removed.
Loading history...
28
    private $topic_id;
0 ignored issues
show
The private property $topic_id is not used, and could be removed.
Loading history...
29
    private $forum_id;
0 ignored issues
show
The private property $forum_id is not used, and could be removed.
Loading history...
30
    private $post_time;
0 ignored issues
show
The private property $post_time is not used, and could be removed.
Loading history...
31
    private $poster_ip;
0 ignored issues
show
The private property $poster_ip is not used, and could be removed.
Loading history...
32
    private $poster_name;
0 ignored issues
show
The private property $poster_name is not used, and could be removed.
Loading history...
33
    private $subject;
0 ignored issues
show
The private property $subject is not used, and could be removed.
Loading history...
34
    private $pid;
0 ignored issues
show
The private property $pid is not used, and could be removed.
Loading history...
35
    private $dohtml;
0 ignored issues
show
The private property $dohtml is not used, and could be removed.
Loading history...
36
    private $dosmiley;
0 ignored issues
show
The private property $dosmiley is not used, and could be removed.
Loading history...
37
    private $doxcode;
0 ignored issues
show
The private property $doxcode is not used, and could be removed.
Loading history...
38
    private $doimage;
0 ignored issues
show
The private property $doimage is not used, and could be removed.
Loading history...
39
    private $dobr;
0 ignored issues
show
The private property $dobr is not used, and could be removed.
Loading history...
40
    private $uid;
0 ignored issues
show
The private property $uid is not used, and could be removed.
Loading history...
41
    private $icon;
0 ignored issues
show
The private property $icon is not used, and could be removed.
Loading history...
42
    private $attachsig;
0 ignored issues
show
The private property $attachsig is not used, and could be removed.
Loading history...
43
    private $approved;
0 ignored issues
show
The private property $approved is not used, and could be removed.
Loading history...
44
    private $post_karma;
0 ignored issues
show
The private property $post_karma is not used, and could be removed.
Loading history...
45
    private $require_reply;
0 ignored issues
show
The private property $require_reply is not used, and could be removed.
Loading history...
46
    private $attachment;
0 ignored issues
show
The private property $attachment is not used, and could be removed.
Loading history...
47
    private $post_text;
0 ignored issues
show
The private property $post_text is not used, and could be removed.
Loading history...
48
    private $post_edit;
0 ignored issues
show
The private property $post_edit is not used, and could be removed.
Loading history...
49
50
    public $attachment_array = [];
51
52
    /**
53
     * Post constructor.
54
     */
55
    public function __construct()
56
    {
57
        //$this->ArtObject("bb_posts");
58
        $this->initVar('post_id', XOBJ_DTYPE_INT);
59
        $this->initVar('topic_id', XOBJ_DTYPE_INT, 0, true);
60
        $this->initVar('forum_id', XOBJ_DTYPE_INT, 0, true);
61
        $this->initVar('post_time', XOBJ_DTYPE_INT, 0, true);
62
        $this->initVar('poster_ip', XOBJ_DTYPE_INT, 0);
63
        $this->initVar('poster_name', XOBJ_DTYPE_TXTBOX, '');
64
        $this->initVar('subject', XOBJ_DTYPE_TXTBOX, '', true);
65
        $this->initVar('pid', XOBJ_DTYPE_INT, 0);
66
        $this->initVar('dohtml', XOBJ_DTYPE_INT, 0);
67
        $this->initVar('dosmiley', XOBJ_DTYPE_INT, 1);
68
        $this->initVar('doxcode', XOBJ_DTYPE_INT, 1);
69
        $this->initVar('doimage', XOBJ_DTYPE_INT, 1);
70
        $this->initVar('dobr', XOBJ_DTYPE_INT, 1);
71
        $this->initVar('uid', XOBJ_DTYPE_INT, 1);
72
        $this->initVar('icon', XOBJ_DTYPE_TXTBOX, '');
73
        $this->initVar('attachsig', XOBJ_DTYPE_INT, 0);
74
        $this->initVar('approved', XOBJ_DTYPE_INT, 1);
75
        $this->initVar('post_karma', XOBJ_DTYPE_INT, 0);
76
        $this->initVar('require_reply', XOBJ_DTYPE_INT, 0);
77
        $this->initVar('attachment', XOBJ_DTYPE_TXTAREA, '');
78
        $this->initVar('post_text', XOBJ_DTYPE_TXTAREA, '');
79
        $this->initVar('post_edit', XOBJ_DTYPE_TXTAREA, '');
80
    }
81
82
    // ////////////////////////////////////////////////////////////////////////////////////
83
    // attachment functions    TODO: there should be a file/attachment management class
84
85
    /**
86
     * @return array|mixed|null
87
     */
88
    public function getAttachment()
89
    {
90
        if (count($this->attachment_array)) {
91
            return $this->attachment_array;
92
        }
93
        $attachment = $this->getVar('attachment');
94
        if (empty($attachment)) {
95
            $this->attachment_array = null;
96
        } else {
97
            $this->attachment_array = @unserialize(base64_decode($attachment, true));
98
        }
99
100
        return $this->attachment_array;
101
    }
102
103
    /**
104
     * @param $attach_key
105
     * @return bool
106
     */
107
    public function incrementDownload($attach_key)
108
    {
109
        if (!$attach_key) {
110
            return false;
111
        }
112
        $this->attachment_array[(string)$attach_key]['num_download']++;
113
114
        return $this->attachment_array[(string)$attach_key]['num_download'];
115
    }
116
117
    /**
118
     * @return bool
119
     */
120
    public function saveAttachment()
121
    {
122
        $attachment_save = '';
123
        if ($this->attachment_array && is_array($this->attachment_array)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->attachment_array of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
124
            $attachment_save = base64_encode(serialize($this->attachment_array));
125
        }
126
        $this->setVar('attachment', $attachment_save);
127
        $sql = 'UPDATE ' . $GLOBALS['xoopsDB']->prefix('bb_posts') . ' SET attachment=' . $GLOBALS['xoopsDB']->quoteString($attachment_save) . ' WHERE post_id = ' . $this->getVar('post_id');
128
        if (!$result = $GLOBALS['xoopsDB']->queryF($sql)) {
0 ignored issues
show
The assignment to $result is dead and can be removed.
Loading history...
129
            //xoops_error($GLOBALS['xoopsDB']->error());
130
            return false;
131
        }
132
133
        return true;
134
    }
135
136
    /**
137
     * @param null $attach_array
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $attach_array is correct as it would always require null to be passed?
Loading history...
138
     * @return bool
139
     */
140
    public function deleteAttachment($attach_array = null)
141
    {
142
        /** @var Xoopspoll\Helper $helper */
143
        $helper = Xoopspoll\Helper::getInstance();
144
145
        $attach_old = $this->getAttachment();
146
        if (!is_array($attach_old) || count($attach_old) < 1) {
147
            return true;
148
        }
149
        $this->attachment_array = [];
150
151
        if (null === $attach_array) {
0 ignored issues
show
The condition null === $attach_array is always true.
Loading history...
152
            $attach_array = array_keys($attach_old);
153
        } // to delete all!
154
        if (!is_array($attach_array)) {
0 ignored issues
show
The condition is_array($attach_array) is always true.
Loading history...
155
            $attach_array = [$attach_array];
156
        }
157
158
        foreach ($attach_old as $key => $attach) {
159
            if (in_array($key, $attach_array, true)) {
160
                @unlink(XOOPS_ROOT_PATH . '/' . $helper->getConfig('dir_attachments') . '/' . $attach['name_saved']);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

160
                /** @scrutinizer ignore-unhandled */ @unlink(XOOPS_ROOT_PATH . '/' . $helper->getConfig('dir_attachments') . '/' . $attach['name_saved']);

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...
161
                @unlink(XOOPS_ROOT_PATH . '/' . $helper->getConfig('dir_attachments') . '/thumbs/' . $attach['name_saved']); // delete thumbnails
162
                continue;
163
            }
164
            $this->attachment_array[$key] = $attach;
165
        }
166
        $attachment_save = '';
167
        if ($this->attachment_array && is_array($this->attachment_array)) {
168
            $attachment_save = base64_encode(serialize($this->attachment_array));
169
        }
170
        $this->setVar('attachment', $attachment_save);
171
172
        return true;
173
    }
174
175
    /**
176
     * @param string $name_saved
177
     * @param string $name_display
178
     * @param string $mimetype
179
     * @param int    $num_download
180
     * @return bool
181
     */
182
    public function setAttachment($name_saved = '', $name_display = '', $mimetype = '', $num_download = 0)
183
    {
184
        static $counter = 0;
185
        $this->attachment_array = $this->getAttachment();
186
        if ($name_saved) {
187
            $key                          = (string)(time() + $counter++);
188
            $this->attachment_array[$key] = [
189
                'name_saved'   => $name_saved,
190
                'name_display' => $name_display ?? $name_saved,
191
                'mimetype'     => $mimetype,
192
                'num_download' => isset($num_download) ? (int)$num_download : 0,
193
            ];
194
        }
195
        $attachment_save = null;
196
        if (is_array($this->attachment_array)) {
197
            $attachment_save = base64_encode(serialize($this->attachment_array));
198
        }
199
        $this->setVar('attachment', $attachment_save);
200
201
        return true;
202
    }
203
204
    /**
205
     * TODO: refactor
206
     * @param bool $asSource
207
     * @return string
208
     */
209
    public function displayAttachment($asSource = false)
0 ignored issues
show
The parameter $asSource is not used and could be removed. ( Ignorable by Annotation )

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

209
    public function displayAttachment(/** @scrutinizer ignore-unused */ $asSource = false)

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

Loading history...
210
    {
211
        global $xoopsModule;
212
        /** @var Xoopspoll\Helper $helper */
213
        $helper = Xoopspoll\Helper::getInstance();
214
215
        $post_attachment = '';
216
        $attachments     = $this->getAttachment();
217
        if ($attachments && is_array($attachments)) {
218
            $iconHandler = newbb_getIconHandler();
0 ignored issues
show
The function newbb_getIconHandler was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

218
            $iconHandler = /** @scrutinizer ignore-call */ newbb_getIconHandler();
Loading history...
219
            $mime_path   = $iconHandler->getPath('mime');
220
            require_once XOOPS_ROOT_PATH . '/modules/' . $xoopsModule->getVar('dirname', 'n') . '/include/functions.image.php';
221
            $image_extensions = ['jpg', 'jpeg', 'gif', 'png', 'bmp']; // need improve !!!
222
            $post_attachment  .= '<br><strong>' . _MD_ATTACHMENT . '</strong>:';
223
            $post_attachment  .= '<br><hr size="1" noshade="noshade"><br>';
224
            foreach ($attachments as $key => $att) {
225
                $file_extension = ltrim(mb_strrchr($att['name_saved'], '.'), '.');
226
                $filetype       = $file_extension;
227
                if (file_exists(XOOPS_ROOT_PATH . '/' . $mime_path . '/' . $filetype . '.gif')) {
228
                    $icon_filetype = XOOPS_URL . '/' . $mime_path . '/' . $filetype . '.gif';
229
                } else {
230
                    $icon_filetype = XOOPS_URL . '/' . $mime_path . '/unknown.gif';
231
                }
232
                $file_size = @filesize(XOOPS_ROOT_PATH . '/' . $helper->getConfig('dir_attachments') . '/' . $att['name_saved']);
233
                $file_size = number_format($file_size / 1024, 2) . ' KB';
234
                if (in_array(mb_strtolower($file_extension), $image_extensions, true) && $helper->getConfig('media_allowed')) {
235
                    $post_attachment .= '<br><img src="' . $icon_filetype . '" alt="' . $filetype . '"><strong>&nbsp; ' . $att['name_display'] . '</strong> <small>(' . $file_size . ')</small>';
236
                    $post_attachment .= '<br>' . newbb_attachmentImage($att['name_saved']);
0 ignored issues
show
The function newbb_attachmentImage was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

236
                    $post_attachment .= '<br>' . /** @scrutinizer ignore-call */ newbb_attachmentImage($att['name_saved']);
Loading history...
237
                    $isDisplayed     = true;
0 ignored issues
show
The assignment to $isDisplayed is dead and can be removed.
Loading history...
238
                } else {
239
                    $post_attachment .= '<a href="'
240
                                        . XOOPS_URL
241
                                        . '/modules/'
242
                                        . $xoopsModule->getVar('dirname', 'n')
243
                                        . '/dl_attachment.php?attachid='
244
                                        . $key
245
                                        . '&amp;post_id='
246
                                        . $this->getVar('post_id')
247
                                        . '"> <img src="'
248
                                        . $icon_filetype
249
                                        . '" alt="'
250
                                        . $filetype
251
                                        . '"> '
252
                                        . $att['name_display']
253
                                        . '</a> '
254
                                        . _MD_FILESIZE
255
                                        . ': '
256
                                        . $file_size
257
                                        . '; '
258
                                        . _MD_HITS
259
                                        . ': '
260
                                        . $att['num_download'];
261
                }
262
                $post_attachment .= '<br>';
263
            }
264
        }
265
266
        return $post_attachment;
267
    }
268
269
    // attachment functions
270
    // ////////////////////////////////////////////////////////////////////////////////////
271
272
    /**
273
     * @param string $poster_name
274
     * @return bool
275
     */
276
    public function setPostEdit($poster_name = '')
0 ignored issues
show
The parameter $poster_name is not used and could be removed. ( Ignorable by Annotation )

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

276
    public function setPostEdit(/** @scrutinizer ignore-unused */ $poster_name = '')

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

Loading history...
277
    {
278
        global $xoopsUser;
279
        /** @var Xoopspoll\Helper $helper */
280
        $helper = Xoopspoll\Helper::getInstance();
281
282
        if (empty($helper->getConfig('recordedit_timelimit'))
283
            || (time() - $this->getVar('post_time')) < $helper->getConfig('recordedit_timelimit') * 60
284
            || $this->getVar('approved') < 1) {
285
            return true;
286
        }
287
        if (is_object($xoopsUser) && $xoopsUser->isActive()) {
288
            if ($helper->getConfig('show_realname') && $xoopsUser->getVar('name')) {
289
                $edit_user = $xoopsUser->getVar('name');
290
            } else {
291
                $edit_user = $xoopsUser->getVar('uname');
292
            }
293
        }
294
        $post_edit              = [];
295
        $post_edit['edit_user'] = $edit_user; // The proper way is to store uid instead of name. However, to save queries when displaying, the current way is ok.
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $edit_user does not seem to be defined for all execution paths leading up to this point.
Loading history...
296
        $post_edit['edit_time'] = time();
297
298
        $post_edits = $this->getVar('post_edit');
299
        if (!empty($post_edits)) {
300
            $post_edits = unserialize(base64_decode($post_edits, true));
301
        }
302
        if (!is_array($post_edits)) {
303
            $post_edits = [];
304
        }
305
        $post_edits[] = $post_edit;
306
        $post_edit    = base64_encode(serialize($post_edits));
307
        unset($post_edits);
308
        $this->setVar('post_edit', $post_edit);
309
310
        return true;
311
    }
312
313
    /**
314
     * @return bool|string
315
     */
316
    public function displayPostEdit()
317
    {
318
        global $myts;
319
        /** @var Xoopspoll\Helper $helper */
320
        $helper = Xoopspoll\Helper::getInstance();
321
322
        if (empty($helper->getConfig('recordedit_timelimit'))) {
323
            return false;
324
        }
325
326
        $post_edit  = '';
327
        $post_edits = $this->getVar('post_edit');
328
        if (!empty($post_edits)) {
329
            $post_edits = unserialize(base64_decode($post_edits, true));
330
        }
331
        if (!isset($post_edits) || !is_array($post_edits)) {
332
            $post_edits = [];
333
        }
334
        if ($post_edits && is_array($post_edits)) {
335
            foreach ($post_edits as $postedit) {
336
                $edit_time = (int)$postedit['edit_time'];
337
                $edit_user = ($postedit['edit_user']);
338
                $post_edit .= _MD_EDITEDBY . ' ' . $edit_user . ' ' . _MD_ON . ' ' . formatTimestamp($edit_time) . '<br>';
339
            }
340
        }
341
342
        return $post_edit;
343
    }
344
345
    /**
346
     * @return array
347
     */
348
    public function &getPostBody()
349
    {
350
        global $xoopsConfig, $xoopsUser, $myts;
351
        /** @var Xoopspoll\Helper $helper */
352
        $helper = Xoopspoll\Helper::getInstance();
353
354
        require_once XOOPS_ROOT_PATH . '/modules/newbb/include/functions.user.php';
355
        require_once XOOPS_ROOT_PATH . '/modules/newbb/include/functions.render.php';
356
357
        $uid          = is_object($xoopsUser) ? $xoopsUser->getVar('uid') : 0;
358
        $karmaHandler = Newbb\Helper::getInstance()->getHandler('Karma');
359
        $user_karma   = $karmaHandler->getUserKarma();
0 ignored issues
show
The method getUserKarma() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

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

359
        /** @scrutinizer ignore-call */ 
360
        $user_karma   = $karmaHandler->getUserKarma();
Loading history...
360
361
        $post               = [];
362
        $post['attachment'] = false;
363
        $post_text          = &newbb_displayTarea($this->vars['post_text']['value'], $this->getVar('dohtml'), $this->getVar('dosmiley'), $this->getVar('doxcode'), $this->getVar('doimage'), $this->getVar('dobr'));
0 ignored issues
show
The function newbb_displayTarea was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

363
        $post_text          = &/** @scrutinizer ignore-call */ newbb_displayTarea($this->vars['post_text']['value'], $this->getVar('dohtml'), $this->getVar('dosmiley'), $this->getVar('doxcode'), $this->getVar('doimage'), $this->getVar('dobr'));
Loading history...
364
        if (newbb_isAdmin($this->getVar('forum_id')) || $this->checkIdentity()) {
0 ignored issues
show
The function newbb_isAdmin was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

364
        if (/** @scrutinizer ignore-call */ newbb_isAdmin($this->getVar('forum_id')) || $this->checkIdentity()) {
Loading history...
365
            $post['text'] = $post_text . '<br>' . $this->displayAttachment();
366
        } elseif ($helper->getConfig('enable_karma') && $this->getVar('post_karma') > $user_karma) {
367
            $post['text'] = sprintf(_MD_KARMA_REQUIREMENT, $user_karma, $this->getVar('post_karma'));
0 ignored issues
show
It seems like $this->getVar('post_karma') can also be of type array and array; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

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

367
            $post['text'] = sprintf(_MD_KARMA_REQUIREMENT, $user_karma, /** @scrutinizer ignore-type */ $this->getVar('post_karma'));
Loading history...
368
        } elseif ($helper->getConfig('allow_require_reply') && $this->getVar('require_reply')
369
                  && (!$uid
370
                      || !isset($viewtopic_users[$uid]))) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $viewtopic_users seems to never exist and therefore isset should always be false.
Loading history...
371
            $post['text'] = _MD_REPLY_REQUIREMENT;
372
        } else {
373
            $post['text'] = $post_text . '<br>' . $this->displayAttachment();
374
        }
375
        /** @var \XoopsMemberHandler $memberHandler */
376
        $memberHandler = xoops_getHandler('member');
377
        $eachposter    = $memberHandler->getUser($this->getVar('uid'));
378
        if (is_object($eachposter) && $eachposter->isActive()) {
379
            if ($helper->getConfig('show_realname') && $eachposter->getVar('name')) {
380
                $post['author'] = $eachposter->getVar('name');
381
            } else {
382
                $post['author'] = $eachposter->getVar('uname');
383
            }
384
            unset($eachposter);
385
        } else {
386
            $post['author'] = $this->getVar('poster_name') ?: $xoopsConfig['anonymous'];
387
        }
388
389
        $post['subject'] = newbb_htmlspecialchars($this->vars['subject']['value']);
0 ignored issues
show
The function newbb_htmlspecialchars was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

389
        $post['subject'] = /** @scrutinizer ignore-call */ newbb_htmlspecialchars($this->vars['subject']['value']);
Loading history...
390
391
        $post['date'] = $this->getVar('post_time');
392
393
        return $post;
394
    }
395
396
    /**
397
     * @return bool
398
     */
399
    public function isTopic()
400
    {
401
        return !$this->getVar('pid');
402
    }
403
404
    /**
405
     * @param string $action_tag
406
     * @return bool
407
     */
408
    public function checkTimelimit($action_tag = 'edit_timelimit')
409
    {
410
        require_once XOOPS_ROOT_PATH . '/modules/newbb/include/functions.config.php';
411
        $newbb_config = newbb_loadConfig();
0 ignored issues
show
The function newbb_loadConfig was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

411
        $newbb_config = /** @scrutinizer ignore-call */ newbb_loadConfig();
Loading history...
412
        if (empty($newbb_config['edit_timelimit'])) {
413
            return true;
414
        }
415
416
        return ($this->getVar('post_time') > time() - $newbb_config[$action_tag] * 60);
417
    }
418
419
    /**
420
     * @param int $uid
421
     * @return bool
422
     */
423
    public function checkIdentity($uid = -1)
424
    {
425
        global $xoopsUser;
426
427
        $uid = ($uid > -1) ? $uid : (is_object($xoopsUser) ? $xoopsUser->getVar('uid') : 0);
428
        if ($this->getVar('uid') > 0) {
429
            $user_ok = $uid == $this->getVar('uid');
430
        } else {
431
            static $user_ip;
432
            if (!isset($user_ip)) {
433
                $user_ip = newbb_getIP();
0 ignored issues
show
The function newbb_getIP was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

433
                $user_ip = /** @scrutinizer ignore-call */ newbb_getIP();
Loading history...
434
            }
435
            $user_ok = $user_ip == $this->getVar('poster_ip');
436
        }
437
438
        return $user_ok;
439
    }
440
441
    // TODO: cleaning up and merge with post hanldings in viewpost.php
442
443
    /**
444
     * @param $isadmin
445
     * @return array
446
     */
447
    public function showPost($isadmin)
448
    {
449
        global $xoopsConfig, $xoopsModule, $xoopsUser, $myts;
450
        /** @var Xoopspoll\Helper $helper */
451
        $helper = Xoopspoll\Helper::getInstance();
452
453
        global $forumUrl, $forumImage;
454
        global $viewtopic_users, $viewtopic_posters, $forum_obj, $topic_obj, $online, $user_karma, $viewmode, $order, $start, $total_posts, $topic_status;
455
        static $post_NO = 0;
456
        static $name_anonymous;
457
458
        if (!isset($name_anonymous)) {
459
            $name_anonymous = htmlspecialchars($GLOBALS['xoopsConfig']['anonymous'], ENT_QUOTES | ENT_HTML5);
460
        }
461
462
        require_once XOOPS_ROOT_PATH . '/modules/newbb/include/functions.time.php';
463
        require_once XOOPS_ROOT_PATH . '/modules/newbb/include/functions.render.php';
464
465
        $post_id  = $this->getVar('post_id');
466
        $topic_id = $this->getVar('topic_id');
467
        $forum_id = $this->getVar('forum_id');
468
469
        $query_vars              = ['status', 'order', 'start', 'mode', 'viewmode'];
470
        $query_array             = [];
471
        $query_array['topic_id'] = "topic_id={$topic_id}";
472
        foreach ($query_vars as $var) {
473
            if (!empty($_GET[$var])) {
474
                $query_array[$var] = "{$var}={$_GET[$var]}";
475
            }
476
        }
477
        $page_query = htmlspecialchars(implode('&', array_values($query_array)), ENT_QUOTES | ENT_HTML5);
478
479
        $uid = is_object($xoopsUser) ? $xoopsUser->getVar('uid') : 0;
480
481
        ++$post_NO;
482
        if ('desc' === mb_strtolower($order)) {
483
            $post_no = $total_posts - ($start + $post_NO) + 1;
484
        } else {
485
            $post_no = $start + $post_NO;
486
        }
487
488
        if ($isadmin || $this->checkIdentity()) {
489
            $post_text       = $this->getVar('post_text');
490
            $post_attachment = $this->displayAttachment();
491
        } elseif ($helper->getConfig('enable_karma') && $this->getVar('post_karma') > $user_karma) {
492
            $post_text       = "<div class='karma'>" . sprintf(_MD_KARMA_REQUIREMENT, $user_karma, $this->getVar('post_karma')) . '</div>';
0 ignored issues
show
It seems like $this->getVar('post_karma') can also be of type array and array; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

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

492
            $post_text       = "<div class='karma'>" . sprintf(_MD_KARMA_REQUIREMENT, $user_karma, /** @scrutinizer ignore-type */ $this->getVar('post_karma')) . '</div>';
Loading history...
493
            $post_attachment = '';
494
        } elseif ($helper->getConfig('allow_require_reply') && $this->getVar('require_reply')
495
                  && (!$uid
496
                      || !in_array($uid, $viewtopic_posters, true))) {
497
            $post_text       = "<div class='karma'>" . _MD_REPLY_REQUIREMENT . '</div>';
498
            $post_attachment = '';
499
        } else {
500
            $post_text       = $this->getVar('post_text');
501
            $post_attachment = $this->displayAttachment();
502
        }
503
        if (isset($viewtopic_users[$this->getVar('uid')])) {
504
            $poster = $viewtopic_users[$this->getVar('uid')];
505
        } else {
506
            $name   = ($post_name = $this->getVar('poster_name')) ? $post_name : $name_anonymous;
507
            $poster = [
508
                'poster_uid' => 0,
509
                'name'       => $name,
510
                'link'       => $name,
511
            ];
512
        }
513
514
        $posticon = $this->getVar('icon');
515
        if ($posticon) {
516
            $post_image = '<a name="' . $post_id . '"><img src="' . XOOPS_URL . '/images/subject/' . $posticon . '" alt=""></a>';
517
        } else {
518
            $post_image = '<a name="' . $post_id . '"><img src="' . XOOPS_URL . '/images/icons/posticon.gif" alt=""></a>';
519
        }
520
521
        $thread_buttons = [];
522
523
        if ($GLOBALS['xoopsModuleConfig']['enable_permcheck']) {
524
            /** @var Newbb\TopicHandler $topicHandler */
525
            $topicHandler = Newbb\Helper::getInstance()->getHandler('Topic');
526
            $topic_status = $topic_obj->getVar('topic_status');
527
            if ($topicHandler->getPermission($forum_id, $topic_status, 'edit')) {
528
                $edit_ok = ($isadmin || ($this->checkIdentity() && $this->checkTimelimit('edit_timelimit')));
529
530
                if ($edit_ok) {
531
                    $thread_buttons['edit']['image'] = newbb_displayImage('p_edit', _EDIT);
0 ignored issues
show
The function newbb_displayImage was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

531
                    $thread_buttons['edit']['image'] = /** @scrutinizer ignore-call */ newbb_displayImage('p_edit', _EDIT);
Loading history...
532
                    $thread_buttons['edit']['link']  = "edit.php?{$page_query}";
533
                    $thread_buttons['edit']['name']  = _EDIT;
534
                }
535
            }
536
537
            if ($topicHandler->getPermission($forum_id, $topic_status, 'delete')) {
538
                $delete_ok = ($isadmin || ($this->checkIdentity() && $this->checkTimelimit('delete_timelimit')));
539
540
                if ($delete_ok) {
541
                    $thread_buttons['delete']['image'] = newbb_displayImage('p_delete', _DELETE);
542
                    $thread_buttons['delete']['link']  = "delete.php?{$page_query}";
543
                    $thread_buttons['delete']['name']  = _DELETE;
544
                }
545
            }
546
            if ($topicHandler->getPermission($forum_id, $topic_status, 'reply')) {
547
                $thread_buttons['reply']['image'] = newbb_displayImage('p_reply', _MD_REPLY);
548
                $thread_buttons['reply']['link']  = "reply.php?{$page_query}";
549
                $thread_buttons['reply']['name']  = _MD_REPLY;
550
551
                $thread_buttons['quote']['image'] = newbb_displayImage('p_quote', _MD_QUOTE);
552
                $thread_buttons['quote']['link']  = "reply.php?{$page_query}&amp;quotedac=1";
553
                $thread_buttons['quote']['name']  = _MD_QUOTE;
554
            }
555
        } else {
556
            $thread_buttons['edit']['image'] = newbb_displayImage('p_edit', _EDIT);
557
            $thread_buttons['edit']['link']  = "edit.php?{$page_query}";
558
            $thread_buttons['edit']['name']  = _EDIT;
559
560
            $thread_buttons['delete']['image'] = newbb_displayImage('p_delete', _DELETE);
561
            $thread_buttons['delete']['link']  = "delete.php?{$page_query}";
562
            $thread_buttons['delete']['name']  = _DELETE;
563
564
            $thread_buttons['reply']['image'] = newbb_displayImage('p_reply', _MD_REPLY);
565
            $thread_buttons['reply']['link']  = "reply.php?{$page_query}";
566
            $thread_buttons['reply']['name']  = _MD_REPLY;
567
        }
568
569
        if (!$isadmin && $helper->getConfig('reportmod_enabled')) {
570
            $thread_buttons['report']['image'] = newbb_displayImage('p_report', _MD_REPORT);
571
            $thread_buttons['report']['link']  = "report.php?{$page_query}";
572
            $thread_buttons['report']['name']  = _MD_REPORT;
573
        }
574
575
        $thread_action = [];
576
577
        $post = [
578
            'post_id'         => $post_id,
579
            'post_parent_id'  => $this->getVar('pid'),
580
            'post_date'       => newbb_formatTimestamp($this->getVar('post_time')),
0 ignored issues
show
The function newbb_formatTimestamp was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

580
            'post_date'       => /** @scrutinizer ignore-call */ newbb_formatTimestamp($this->getVar('post_time')),
Loading history...
581
            'post_image'      => $post_image,
582
            'post_title'      => $this->getVar('subject'),
583
            'post_text'       => $post_text,
584
            'post_attachment' => $post_attachment,
585
            'post_edit'       => $this->displayPostEdit(),
586
            'post_no'         => $post_no,
587
            'post_signature'  => $this->getVar('attachsig') ? @$poster['signature'] : '',
588
            'poster_ip'       => ($isadmin && $helper->getConfig('show_ip')) ? long2ip($this->getVar('poster_ip')) : '',
589
            'thread_action'   => $thread_action,
590
            'thread_buttons'  => $thread_buttons,
591
            'poster'          => $poster,
592
        ];
593
594
        unset($thread_buttons, $eachposter);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $eachposter does not exist. Did you maybe mean $poster?
Loading history...
595
596
        return $post;
597
    }
598
}
599
600
/**
601
 * Class PostHandler
602
 */
603
class PostHandler extends \XoopsPersistableObjectHandler
604
{
605
    /**
606
     * @param null|\XoopsDatabase $db
607
     */
608
    public function __construct(\XoopsDatabase $db = null)
609
    {
610
        parent::__construct($db, 'bb_posts', 'Post', 'post_id', 'subject');
611
    }
612
613
    /**
614
     * @param mixed|null $id
615
     * @param null       $fields
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $fields is correct as it would always require null to be passed?
Loading history...
616
     * @return null|\XoopsObject
617
     */
618
    public function get($id = null, $fields = null)
619
    {
620
        $id    = (int)$id;
621
        $post  = null;
622
        $sql   = 'SELECT p.*, t.* FROM ' . $this->db->prefix('bb_posts') . ' p LEFT JOIN ' . $this->db->prefix('bb_posts_text') . ' t ON p.post_id=t.post_id WHERE p.post_id=' . $id;
623
        $array = $this->db->fetchArray($this->db->query($sql));
624
        if ($array) {
625
            $post = $this->create(false);
626
            $post->assignVars($array);
627
        }
628
629
        return $post;
630
    }
631
632
    /**
633
     * @param int $topic_id
634
     * @param int $limit
635
     * @param int $approved
636
     * @return array
637
     */
638
    public function &getByLimit($topic_id, $limit, $approved = 1)
639
    {
640
        $sql    = 'SELECT p.*, t.*, tp.topic_status FROM '
641
                  . $this->db->prefix('bb_posts')
642
                  . ' p LEFT JOIN '
643
                  . $this->db->prefix('bb_posts_text')
644
                  . ' t ON p.post_id=t.post_id LEFT JOIN '
645
                  . $this->db->prefix('bb_topics')
646
                  . ' tp ON tp.topic_id=p.topic_id WHERE p.topic_id='
647
                  . $topic_id
648
                  . ' AND p.approved ='
649
                  . $approved
650
                  . ' ORDER BY p.post_time DESC';
651
        $result = $this->db->query($sql, $limit, 0);
652
        $ret    = [];
653
        if ($result) {
654
            while (false !== ($myrow = $this->db->fetchArray($result))) {
655
                $post = $this->create(false);
656
                $post->assignVars($myrow);
657
658
                $ret[$myrow['post_id']] = $post;
659
                unset($post);
660
            }
661
        }
662
663
        return $ret;
664
    }
665
666
    /**
667
     * @param $post
668
     * @return mixed
669
     */
670
    public function getPostForPDF($post)
671
    {
672
        return $post->getPostBody(true);
673
    }
674
675
    /**
676
     * @param $post
677
     * @return mixed
678
     */
679
    public function getPostForPrint($post)
680
    {
681
        return $post->getPostBody();
682
    }
683
684
    /**
685
     * @param \XoopsObject  $post
686
     * @param bool  $force
687
     * @return bool
688
     */
689
    public function approve(&$post, $force = false)
690
    {
691
        if (empty($post)) {
692
            return false;
693
        }
694
        if (is_numeric($post)) {
0 ignored issues
show
The condition is_numeric($post) is always false.
Loading history...
695
            $post = $this->get($post);
696
        } else {
697
            $post->unsetNew();
698
        }
699
        $post_id     = $post->getVar('post_id');
0 ignored issues
show
The assignment to $post_id is dead and can be removed.
Loading history...
700
        $wasApproved = $post->getVar('approved');
701
        if (empty($force) && $wasApproved) {
702
            return true;
703
        }
704
        $post->setVar('approved', 1);
705
        $this->insert($post, true);
706
707
        /** @var Newbb\TopicHandler $topicHandler */
708
        $topicHandler = Newbb\Helper::getInstance()->getHandler('Topic');
709
        $topic_obj    = $topicHandler->get($post->getVar('topic_id'));
710
        if ($topic_obj->getVar('topic_last_post_id') < $post->getVar('post_id')) {
711
            $topic_obj->setVar('topic_last_post_id', $post->getVar('post_id'));
712
        }
713
        if ($post->isTopic()) {
0 ignored issues
show
The method isTopic() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as Post or XoopsModules\Newbb\Post. ( Ignorable by Annotation )

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

713
        if ($post->/** @scrutinizer ignore-call */ isTopic()) {
Loading history...
714
            $topic_obj->setVar('approved', 1);
715
        } else {
716
            $topic_obj->setVar('topic_replies', $topic_obj->getVar('topic_replies') + 1);
717
        }
718
        $topicHandler->insert($topic_obj, true);
0 ignored issues
show
It seems like $topic_obj can also be of type null; however, parameter $object of XoopsModules\Newbb\TopicHandler::insert() does only seem to accept XoopsObject, maybe add an additional type check? ( Ignorable by Annotation )

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

718
        $topicHandler->insert(/** @scrutinizer ignore-type */ $topic_obj, true);
Loading history...
719
720
        /** @var Newbb\ForumHandler $forumHandler */
721
        $forumHandler = Newbb\Helper::getInstance()->getHandler('Forum');
722
        $forum_obj    = $forumHandler->get($post->getVar('forum_id'));
723
        if ($forum_obj->getVar('forum_last_post_id') < $post->getVar('post_id')) {
724
            $forum_obj->setVar('forum_last_post_id', $post->getVar('post_id'));
725
        }
726
        $forum_obj->setVar('forum_posts', $forum_obj->getVar('forum_posts') + 1);
727
        if ($post->isTopic()) {
728
            $forum_obj->setVar('forum_topics', $forum_obj->getVar('forum_topics') + 1);
729
        }
730
        $forumHandler->insert($forum_obj, true);
731
732
        // Update user stats
733
        if ($post->getVar('uid') > 0) {
734
            /** @var \XoopsMemberHandler $memberHandler */
735
            $memberHandler = xoops_getHandler('member');
736
            $poster        = $memberHandler->getUser($post->getVar('uid'));
737
            if (is_object($poster) && $post->getVar('uid') == $poster->getVar('uid')) {
738
                $poster->setVar('posts', $poster->getVar('posts') + 1);
739
                $res = $memberHandler->insertUser($poster, true);
0 ignored issues
show
The assignment to $res is dead and can be removed.
Loading history...
740
                unset($poster);
741
            }
742
        }
743
744
        // Update forum stats
745
        $statsHandler = Newbb\Helper::getInstance()->getHandler('Stats');
746
        $statsHandler->update($post->getVar('forum_id'), 'post');
0 ignored issues
show
The method update() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

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

746
        $statsHandler->/** @scrutinizer ignore-call */ 
747
                       update($post->getVar('forum_id'), 'post');
Loading history...
747
        if ($post->isTopic()) {
748
            $statsHandler->update($post->getVar('forum_id'), 'topic');
749
        }
750
751
        return true;
752
    }
753
754
    /**
755
     * @param \XoopsObject $post
756
     * @param bool $force
757
     * @return bool
758
     */
759
    public function insert(\XoopsObject $post, $force = true)
760
    {
761
        global $xoopsUser;
762
763
        // Set the post time
764
        // The time should be "publish" time. To be adjusted later
765
        if (!$post->getVar('post_time')) {
766
            $post->setVar('post_time', time());
767
        }
768
769
        /** @var Newbb\TopicHandler $topicHandler */
770
        $topicHandler = Newbb\Helper::getInstance()->getHandler('Topic');
771
        // Verify the topic ID
772
        $topic_id = $post->getVar('topic_id');
773
        if ($topic_id) {
774
            $topic_obj = $topicHandler->get($topic_id);
775
            // Invalid topic OR the topic is no approved and the post is not top post
776
            if (!$topic_obj//    || (!$post->isTopic() && $topic_obj->getVar("approved") < 1)
777
            ) {
778
                return false;
779
            }
780
        }
781
        if (empty($topic_id)) {
782
            $post->setVar('topic_id', 0);
783
            $post->setVar('pid', 0);
784
            $post->setNew();
785
            $topic_obj = $topicHandler->create();
786
        }
787
        $textHandler    = Newbb\Helper::getInstance()->getHandler('Text');
788
        $post_text_vars = ['post_text', 'post_edit', 'dohtml', 'doxcode', 'dosmiley', 'doimage', 'dobr'];
789
        if ($post->isNew()) {
790
            if (!$topic_id = $post->getVar('topic_id')) {
791
                $topic_obj->setVar('topic_title', $post->getVar('subject', 'n'));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $topic_obj does not seem to be defined for all execution paths leading up to this point.
Loading history...
792
                $topic_obj->setVar('topic_poster', $post->getVar('uid'));
793
                $topic_obj->setVar('forum_id', $post->getVar('forum_id'));
794
                $topic_obj->setVar('topic_time', $post->getVar('post_time'));
795
                $topic_obj->setVar('poster_name', $post->getVar('poster_name'), true);
796
                $topic_obj->setVar('approved', $post->getVar('approved'), true);
797
                if (!$topic_id = $topicHandler->insert($topic_obj, $force)) {
798
                    $post->deleteAttachment();
0 ignored issues
show
The method deleteAttachment() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as Post or XoopsModules\Newbb\Post. ( Ignorable by Annotation )

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

798
                    $post->/** @scrutinizer ignore-call */ 
799
                           deleteAttachment();
Loading history...
799
                    $post->setErrors('insert topic error');
800
801
                    return false;
802
                }
803
                $post->setVar('topic_id', $topic_id);
804
805
                $pid = 0;
0 ignored issues
show
The assignment to $pid is dead and can be removed.
Loading history...
806
                $post->setVar('pid', 0);
807
            } elseif (!$post->getVar('pid')) {
808
                $pid = $topicHandler->getTopPostId($topic_id);
809
                $post->setVar('pid', $pid);
810
            }
811
812
            $text_obj = $textHandler->create();
813
            foreach ($post_text_vars as $key) {
814
                $text_obj->vars[$key] = $post->vars[$key];
815
            }
816
            $post->destroyVars($post_text_vars);
817
            if (!$post_id = parent::insert($post, $force)) {
818
                return false;
819
            }
820
            $text_obj->setVar('post_id', $post_id);
821
            if (!$textHandler->insert($text_obj, $force)) {
822
                $this->delete($post);
823
                $post->setErrors('post text insert error');
824
825
                return false;
826
            }
827
            if ($post->getVar('approved') > 0) {
828
                $this->approve($post, true);
829
            }
830
            $post->setVar('post_id', $post_id);
831
        } else {
832
            if ($post->isTopic()) {
833
                if ($post->getVar('subject') != $topic_obj->getVar('topic_title')) {
834
                    $topic_obj->setVar('topic_title', $post->getVar('subject', 'n'));
835
                }
836
                if ($post->getVar('approved') != $topic_obj->getVar('approved')) {
837
                    $topic_obj->setVar('approved', $post->getVar('approved'));
838
                }
839
                if (!$result = $topicHandler->insert($topic_obj, $force)) {
0 ignored issues
show
The assignment to $result is dead and can be removed.
Loading history...
840
                    $post->setErrors('update topic error');
841
842
                    return false;
843
                }
844
            }
845
            $text_obj = $textHandler->get($post->getVar('post_id'));
846
            $text_obj->setDirty();
847
            foreach ($post_text_vars as $key) {
848
                $text_obj->vars[$key] = $post->vars[$key];
849
            }
850
            $post->destroyVars($post_text_vars);
851
            if (!$post_id = parent::insert($post, $force)) {
0 ignored issues
show
The assignment to $post_id is dead and can be removed.
Loading history...
852
                return false;
853
            }
854
            if (!$textHandler->insert($text_obj, $force)) {
855
                $post->setErrors('update post text error');
856
857
                return false;
858
            }
859
        }
860
861
        return $post->getVar('post_id');
862
    }
863
864
    /**
865
     * @param \XoopsObject $post
866
     * @param bool $isDeleteOne
867
     * @param bool $force
868
     * @return bool
869
     */
870
    public function delete(\XoopsObject $post, $isDeleteOne = true, $force = false)
871
    {
872
        if (!is_object($post) || 0 == $post->getVar('post_id')) {
873
            return false;
874
        }
875
        if ($isDeleteOne) {
876
            if ($post->isTopic()) {
877
                $criteria = new \CriteriaCompo(new \Criteria('topic_id', $post->getVar('topic_id')));
0 ignored issues
show
It seems like $post->getVar('topic_id') can also be of type array and array; however, parameter $value of Criteria::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

877
                $criteria = new \CriteriaCompo(new \Criteria('topic_id', /** @scrutinizer ignore-type */ $post->getVar('topic_id')));
Loading history...
878
                $criteria->add(new \Criteria('approved', 1));
879
                $criteria->add(new \Criteria('pid', 0, '>'));
880
                if ($this->getPostCount($criteria) > 0) {
881
                    return false;
882
                }
883
            }
884
885
            return $this->_delete($post, $force);
886
        }
887
        require_once XOOPS_ROOT_PATH . '/class/xoopstree.php';
888
        $mytree = new \XoopsTree($this->db->prefix('bb_posts'), 'post_id', 'pid');
889
        $arr    = $mytree->getAllChild($post->getVar('post_id'));
890
        for ($i = 0, $iMax = count($arr); $i < $iMax; ++$i) {
0 ignored issues
show
It seems like $arr can also be of type mixed; however, parameter $value of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

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

890
        for ($i = 0, $iMax = count(/** @scrutinizer ignore-type */ $arr); $i < $iMax; ++$i) {
Loading history...
891
            $childpost = $this->create(false);
892
            $childpost->assignVars($arr[$i]);
893
            $this->_delete($childpost, $force);
894
            unset($childpost);
895
        }
896
        $this->_delete($post, $force);
897
898
        return true;
899
    }
900
901
    /**
902
     * @param       $post
903
     * @param bool  $force
904
     * @return bool
905
     */
906
    public function _delete($post, $force = false)
907
    {
908
        global $xoopsModule;
909
910
        if (!is_object($post) || 0 == $post->getVar('post_id')) {
911
            return false;
912
        }
913
914
        /* Set active post as deleted */
915
        if ($post->getVar('approved') > 0 && empty($force)) {
916
            $sql = 'UPDATE ' . $this->db->prefix('bb_posts') . ' SET approved = -1 WHERE post_id = ' . $post->getVar('post_id');
917
            if (!$result = $this->db->queryF($sql)) {
0 ignored issues
show
The assignment to $result is dead and can be removed.
Loading history...
918
            }
919
            /* delete pending post directly */
920
        } else {
921
            $sql = sprintf('DELETE FROM `%s` WHERE post_id = %u', $this->db->prefix('bb_posts'), $post->getVar('post_id'));
922
            if (!$result = $this->db->queryF($sql)) {
923
                $post->setErrors('delte post error: ' . $sql);
924
925
                return false;
926
            }
927
            $post->deleteAttachment();
928
929
            $sql = sprintf('DELETE FROM `%s` WHERE post_id = %u', $this->db->prefix('bb_posts_text'), $post->getVar('post_id'));
930
            if (!$result = $this->db->queryF($sql)) {
931
                $post->setErrors('Could not remove post text: ' . $sql);
932
933
                return false;
934
            }
935
        }
936
937
        if ($post->isTopic()) {
938
            /** @var Newbb\TopicHandler $topicHandler */
939
            $topicHandler = Newbb\Helper::getInstance()->getHandler('Topic');
940
            $topic_obj    = $topicHandler->get($post->getVar('topic_id'));
941
            if ($topic_obj instanceof Newbb\Topic) {
942
                if (($topic_obj->getVar('approved') > 0) && empty($force)) {
943
                    $topiccount_toupdate = 1;
0 ignored issues
show
The assignment to $topiccount_toupdate is dead and can be removed.
Loading history...
944
                    $topic_obj->setVar('approved', -1);
945
                    $topicHandler->insert($topic_obj);
946
                    xoops_notification_deletebyitem($xoopsModule->getVar('mid'), 'thread', $post->getVar('topic_id'));
947
                } else {
948
                    if ($topic_obj->getVar('approved') > 0) {
949
                        xoops_notification_deletebyitem($xoopsModule->getVar('mid'), 'thread', $post->getVar('topic_id'));
950
                    }
951
                    $poll_id = $topic_obj->getVar('poll_id');
952
                    if ($poll_id > 0) {
953
                        /** @var \XoopsModuleHandler $moduleHandler */
954
                        $moduleHandler      = xoops_getHandler('module');
955
                        $poll_moduleHandler = $moduleHandler->getByDirname('xoopspoll');
956
                        if (($poll_moduleHandler instanceof \XoopsModuleHandler) && $poll_moduleHandler->isactive()) {
0 ignored issues
show
The method isactive() does not exist on XoopsModuleHandler. ( Ignorable by Annotation )

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

956
                        if (($poll_moduleHandler instanceof \XoopsModuleHandler) && $poll_moduleHandler->/** @scrutinizer ignore-call */ isactive()) {

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

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

Loading history...
$poll_moduleHandler is never a sub-type of XoopsModuleHandler.
Loading history...
957
                            $pollHandler = Xoopspoll\Helper::getInstance()->getHandler('Poll');
958
                            if (false !== $pollHandler->deleteAll(new \Criteria('poll_id', $poll_id, '='))) {
959
                                $optionHandler = Xoopspoll\Helper::getInstance()->getHandler('Option');
960
                                $optionHandler->deleteAll(new \Criteria('poll_id', $poll_id, '='));
961
                                $logHandler = Xoopspoll\Helper::getInstance()->getHandler('Log');
962
                                $logHandler->deleteAll(new \Criteria('poll_id', $poll_id, '='));
963
                                xoops_comment_delete($GLOBALS['xoopsModule']->getVar('mid'), $poll_id);
964
                            }
965
                        }
966
                    }
967
                }
968
969
                $sql = sprintf('DELETE FROM `%s` WHERE topic_id = %u', $this->db->prefix('bb_topics'), $post->getVar('topic_id'));
970
                if (!$result = $this->db->queryF($sql)) {
971
                    //xoops_error($this->db->error());
972
                }
973
                $sql = sprintf('DELETE FROM `%s` WHERE topic_id = %u', $this->db->prefix('bb_votedata'), $post->getVar('topic_id'));
974
                if (!$result = $this->db->queryF($sql)) {
975
                    //xoops_error($this->db->error());
976
                }
977
            }
978
        } else {
979
            $sql = 'UPDATE ' . $this->db->prefix('bb_topics') . ' t
980
                            LEFT JOIN ' . $this->db->prefix('bb_posts') . ' p ON p.topic_id = t.topic_id
981
                            SET t.topic_last_post_id = p.post_id
982
                            WHERE t.topic_last_post_id = ' . $post->getVar('post_id') . '
983
                                    AND p.post_id = (SELECT MAX(post_id) FROM ' . $this->db->prefix('bb_posts') . ' WHERE topic_id=t.topic_id)';
984
            if (!$result = $this->db->queryF($sql)) {
985
            }
986
        }
987
988
        $postcount_toupdate = $post->getVar('approved');
989
990
        if ($postcount_toupdate > 0) {
991
            // Update user stats
992
            if ($post->getVar('uid') > 0) {
993
                /** @var \XoopsMemberHandler $memberHandler */
994
                $memberHandler = xoops_getHandler('member');
995
                $poster        = $memberHandler->getUser($post->getVar('uid'));
996
                if (is_object($poster) && $post->getVar('uid') == $poster->getVar('uid')) {
997
                    $poster->setVar('posts', $poster->getVar('posts') - 1);
998
                    $res = $memberHandler->insertUser($poster, true);
0 ignored issues
show
The assignment to $res is dead and can be removed.
Loading history...
999
                    unset($poster);
1000
                }
1001
            }
1002
1003
            $sql = 'UPDATE ' . $this->db->prefix('bb_posts') . ' SET pid = ' . $post->getVar('pid') . ' WHERE pid=' . $post->getVar('post_id');
1004
            if (!$result = $this->db->queryF($sql)) {
1005
                //xoops_error($this->db->error());
1006
            }
1007
        }
1008
1009
        return true;
1010
    }
1011
1012
    /**
1013
     * @param null $criteria
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $criteria is correct as it would always require null to be passed?
Loading history...
1014
     * @return int
1015
     */
1016
    public function getPostCount($criteria = null)
1017
    {
1018
        return parent::getCount($criteria);
1019
    }
1020
1021
    /*
1022
     * TODO: combining viewtopic.php
1023
     */
1024
1025
    /**
1026
     * @param null $criteria
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $criteria is correct as it would always require null to be passed?
Loading history...
1027
     * @param int  $limit
1028
     * @param int  $start
1029
     * @param null $join
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $join is correct as it would always require null to be passed?
Loading history...
1030
     * @return array
1031
     */
1032
    public function &getPostsByLimit($criteria = null, $limit = 1, $start = 0, $join = null)
1033
    {
1034
        $ret = [];
1035
        $sql = 'SELECT p.*, t.* ' . ' FROM ' . $this->db->prefix('bb_posts') . ' AS p' . ' LEFT JOIN ' . $this->db->prefix('bb_posts_text') . ' AS t ON t.post_id = p.post_id';
1036
        if (!empty($join)) {
1037
            $sql .= $join;
1038
        }
1039
        if (\is_object($criteria) && \is_subclass_of($criteria, \CriteriaElement::class)) {
1040
            $sql .= ' ' . $criteria->renderWhere();
1041
            if ('' != $criteria->getSort()) {
1042
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
1043
            }
1044
        }
1045
        $result = $this->db->query($sql, (int)$limit, (int)$start);
1046
        if ($result) {
1047
            while (false !== ($myrow = $this->db->fetchArray($result))) {
1048
                $post = $this->create(false);
1049
                $post->assignVars($myrow);
1050
                $ret[$myrow['post_id']] = $post;
1051
                unset($post);
1052
            }
1053
        }
1054
1055
        return $ret;
1056
    }
1057
1058
    /**
1059
     * clean orphan items from database
1060
     *
1061
     * @return bool true on success
1062
     */
1063
    public function cleanOrphan()
1064
    {
1065
        global $xoopsDB;
1066
        $this->deleteAll(new \Criteria('post_time', 0), true, true);
1067
        parent::cleanOrphan($this->db->prefix('bb_topics'), 'topic_id');
1068
        parent::cleanOrphan($this->db->prefix('bb_posts_text'), 'post_id');
1069
1070
        /* for MySQL 4.1+ */
1071
        if (version_compare(mysqli_get_server_info($xoopsDB->conn), '4.1.0', 'ge')):
1072
            $sql = 'DELETE FROM ' . $this->db->prefix('bb_posts_text') . " WHERE (post_id NOT IN ( SELECT DISTINCT post_id FROM {$this->table}) )";
1073
        else:
1074
            // for 4.0+
1075
1076
            $sql = 'DELETE ' . $this->db->prefix('bb_posts_text') . ' FROM ' . $this->db->prefix('bb_posts_text') . " LEFT JOIN {$this->table} AS aa ON " . $this->db->prefix('bb_posts_text') . '.post_id = aa.post_id ' . ' WHERE (aa.post_id IS NULL)';
1077
1078
            // Alternative for 4.1+
1079
            /*
1080
            $sql =     "DELETE bb FROM ".$this->db->prefix("bb_posts_text")." AS bb".
1081
                    " LEFT JOIN ".$this->table." AS aa ON bb.post_id = aa.post_id ".
1082
                    " WHERE (aa.post_id IS NULL)";
1083
            */ endif;
1084
        if (!$result = $this->db->queryF($sql)) {
0 ignored issues
show
The assignment to $result is dead and can be removed.
Loading history...
1085
            //xoops_error($this->db->error());
1086
            return false;
1087
        }
1088
1089
        return true;
1090
    }
1091
1092
    /**
1093
     * clean expired objects from database
1094
     *
1095
     * @param int $expire time limit for expiration
1096
     * @return bool true on success
1097
     */
1098
    public function cleanExpires($expire = 0)
1099
    {
1100
        $crit_expire = new \CriteriaCompo(new \Criteria('approved', 0, '<='));
1101
        //if (!empty($expire)) {
1102
        $crit_expire->add(new \Criteria('post_time', time() - (int)$expire, '<'));
1103
1104
        //}
1105
        return $this->deleteAll($crit_expire, true/*, true*/);
1106
    }
1107
}
1108