Issues (278)

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.

class/EntrydataHandler.php (1 issue)

1
<?php
2
3
namespace XoopsModules\Soapbox;
4
5
/*
6
 * You may not change or alter any portion of this comment or credits
7
 * of supporting developers from this source code or any supporting source code
8
 * which is considered copyrighted (c) material of the original comment or credit authors.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/**
16
 * @copyright    XOOPS Project https://xoops.org/
17
 * @license      GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
18
 * @package
19
 * @since
20
 * @author       XOOPS Development Team, Kazumi Ono (AKA onokazu)
21
 */
22
23
use XoopsModules\Soapbox;
24
25
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
26
$moduleDirName = basename(dirname(__DIR__));
27
if ('soapbox' !== $moduleDirName && '' !== $moduleDirName && !preg_match('/^(\D+)(\d*)$/', $moduleDirName)) {
28
    echo('invalid dirname: ' . htmlspecialchars($this->mydirname, ENT_QUOTES | ENT_HTML5));
29
}
30
31
/**
32
 * Soapbox entrydata handler class.
33
 * This class provides simple interface (a facade class) for handling sbarticles/sbcolumns/sbvotedata
34
 * entrydata.
35
 *
36
 *
37
 * @author  domifara
38
 * @package modules
39
 */
40
class EntrydataHandler extends \XoopsModules\Soapbox\EntrygetHandler
41
{
42
    /**
43
     * constructor
44
     * @param \XoopsDatabase|null $db
45
     */
46
    public function __construct(\XoopsDatabase $db = null)
47
    {
48
        parent::__construct($db);
49
        global $moduleDirName;
50
        $this->sbArticleHandler = new ArticlesHandler($db);
51
        $this->sbColumnHandler  = new ColumnsHandler($db);
52
        $this->sbVoteHandler    = new VotedataHandler($db);
53
        $_mymoduleHandler       = xoops_getHandler('module');
54
        $_mymodule              = $_mymoduleHandler->getByDirname('soapbox');
55
        if (!is_object($_mymodule)) {
56
            exit('not found dirname');
57
        }
58
        $this->moduleDirName = $moduleDirName;
59
        $this->moduleId      = $_mymodule->getVar('mid');
60
    }
61
62
    /**
63
     * create a new Article
64
     *
65
     * @param  bool $isNew
66
     * @return object Articles reference to the new Article
67
     */
68
    public function createArticle($isNew = true)
69
    {
70
        $ret = $this->sbArticleHandler->create($isNew);
71
72
        return $ret;
73
    }
74
75
    /**
76
     * create a new Column
77
     *
78
     * @param  bool $isNew
79
     * @return object Columns reference to the new Column
80
     */
81
    public function createColumn($isNew = true)
82
    {
83
        $ret = $this->sbColumnHandler->create($isNew);
84
85
        return $ret;
86
    }
87
88
    /**
89
     * create a new Votedata
90
     *
91
     * @param  bool $isNew
92
     * @return object Votedata reference to the new Votedata
93
     */
94
    public function createVotedata($isNew = true)
95
    {
96
        $ret = $this->sbVoteHandler->create($isNew);
97
98
        return $ret;
99
    }
100
101
    /**
102
     * insert a new entry in the database
103
     *
104
     * @param  Articles $sbarticle reference to the {@link Articles} object
105
     * @param  bool     $force
106
     * @return bool              FALSE if failed, TRUE if already present and unchanged or successful
107
     */
108
    public function insertArticle(Articles $sbarticle, $force = false)
109
    {
110
        if (!$this->sbArticleHandler->insert($sbarticle, $force)) {
111
            return false;
112
        }
113
        // re count ----------------------------------
114
        $this->updateTotalByColumnID($sbarticle->getVar('columnID'));
115
116
        // re count ----------------------------------
117
        return true;
118
    }
119
120
    /**
121
     * insert a new Column in the database
122
     *
123
     * @param  object $sbcolumn reference to the {@link Columns} object
124
     * @param  bool   $force
125
     * @return bool   FALSE if failed, TRUE if already present and unchanged or successful
126
     */
127
    public function insertColumn($sbcolumn, $force = false)
128
    {
129
        if (!$this->sbColumnHandler->insert($sbcolumn, $force)) {
130
            return false;
131
        }
132
133
        return true;
134
    }
135
136
    /**
137
     * insert a new Votedata in the database
138
     *
139
     * @param  object $sbvotedata reference to the {@link Votedata} object
140
     * @param  bool   $force
141
     * @return bool   FALSE if failed, TRUE if already present and unchanged or successful
142
     */
143
    public function insertVotedata($sbvotedata, $force = false)
144
    {
145
        if (!$this->sbVoteHandler->insert($sbvotedata, $force)) {
146
            return false;
147
        }
148
149
        return true;
150
    }
151
152
    /**
153
     * delete a Article from the database
154
     *
155
     * @param  object $sbarticle reference to the Article to delete
156
     * @param  bool   $force
157
     * @param  bool   $re_count
158
     * @return bool   FALSE if failed.
159
     */
160
    public function deleteArticle($sbarticle, $force = false, $re_count = true)
161
    {
162
        // delete Article
163
        if (!$this->sbArticleHandler->delete($sbarticle, $force)) {
164
            return false;
165
        }
166
        // delete Votedata
167
        $criteria = new \CriteriaCompo();
168
        $criteria->add(new \Criteria('lid', $sbarticle->getVar('articleID')));
169
        $this->sbVoteHandler->deleteEntrys($criteria, $force);
170
        unset($criteria);
171
        // delete comments
172
        xoops_comment_delete($this->moduleId, $sbarticle->getVar('articleID'));
173
        // re count ----------------------------------
174
        if ($re_count) {
175
            $this->updateTotalByColumnID($sbarticle->getVar('columnID'));
176
        }
177
178
        // re count ----------------------------------
179
        return true;
180
    }
181
182
    /**
183
     * delete a Column from the database
184
     *
185
     * @param  object $sbcolumn reference to the Column to delete
186
     * @param  bool   $force
187
     * @return bool   FALSE if failed.
188
     */
189
    public function deleteColumn($sbcolumn, $force = false)
190
    {
191
        // delete Column
192
        if (!$this->sbColumnHandler->delete($sbcolumn, $force)) {
193
            return false;
194
        }
195
        $criteria = new \CriteriaCompo();
196
        $criteria->add(new \Criteria('columnID', $sbcolumn->getVar('columnID')));
197
        $this->deleteArticlesEntrys($criteria, $force, false);
198
        unset($criteria);
199
200
        return true;
201
    }
202
203
    /**
204
     * delete a Votedata from the database
205
     *
206
     * @param  Votedata $sbvotedata reference to the Votedata to delete
207
     * @param  bool     $force
208
     * @return bool   FALSE if failed.
209
     */
210
    public function deleteVotedata($sbvotedata, $force = false)
211
    {
212
        // delete Votedata
213
        if (!$this->sbVoteHandler->delete($sbvotedata, $force)) {
214
            return false;
215
        }
216
217
        return true;
218
    }
219
220
    /**
221
     * delete  entrys from the database
222
     *
223
     * @param  \CriteriaElement $criteria {@link CriteriaElement} conditions to be match
224
     * @param  bool             $force
225
     * @param  bool             $re_count
226
     * @return bool   FALSE if failed.
227
     */
228
    public function deleteArticlesEntrys(\CriteriaElement $criteria = null, $force = false, $re_count = false)
229
    {
230
        $_sbarticles_arr = $this->getArticles($criteria);
231
        if (empty($_sbarticles_arr) || 0 === count($_sbarticles_arr)) {
232
            return false;
233
        }
234
        foreach ($_sbarticles_arr as $sbarticle) {
235
            $this->deleteArticle($sbarticle, $force, false);
236
        }
237
238
        return true;
239
    }
240
241
    /**
242
     * @param       $sbarticle
243
     * @param  bool $force
244
     * @return bool
245
     */
246
    public function updateRating(&$sbarticle, $force = false) // updates rating data in itemtable for a given item
247
    {
248
        if (mb_strtolower(get_class($sbarticle)) !== mb_strtolower(Articles::class)) {
249
            return false;
250
        }
251
        $totalrating = 0.00;
252
        $votesDB     = 0;
253
        $finalrating = 0;
254
255
        $sbvotedata_arr = $this->getVotedatasByArticleID($sbarticle->getVar('articleID'), true, 0, 0);
256
        $votesDB        = count($sbvotedata_arr);
257
        if (empty($sbvotedata_arr) || 0 === $votesDB) {
258
            return false;
259
        }
260
        foreach ($sbvotedata_arr as $sbvotedata) {
261
            if (is_object($sbvotedata)) {
262
                $totalrating += $sbvotedata->getVar('rating');
263
            }
264
        }
265
        if (0 !== $totalrating && 0 !== $votesDB) {
0 ignored issues
show
The condition 0 !== $totalrating is always false.
Loading history...
266
            $finalrating = ($totalrating / $votesDB) + 0.00005;
267
            $finalrating = number_format($finalrating, 4);
268
        }
269
270
        $sbarticle->setVar('rating', $finalrating);
271
        $sbarticle->setVar('votes', $votesDB);
272
        if (!$this->insertArticle($sbarticle, $force)) {
273
            return false;
274
        }
275
276
        return true;
277
    }
278
279
    /**
280
     * @param       $columnID
281
     * @param  bool $force
282
     * @return bool
283
     */
284
    public function updateTotalByColumnID($columnID, $force = false)
285
    {
286
        // re count ----------------------------------
287
        $sbcolumns = $this->getColumn($columnID);
288
        if (is_object($sbcolumns)) {
289
            $criteria = new \CriteriaCompo();
290
            $criteria->add(new \Criteria('datesub', time(), '<'));
291
            $criteria->add(new \Criteria('datesub', 0, '>'));
292
            $criteria->add(new \Criteria('submit', 0));
293
            $criteria->add(new \Criteria('offline', 0));
294
            $sbcolumns->setVar('total', $this->getArticleCount($criteria));
295
            unset($criteria);
296
            $this->insertColumn($sbcolumns, $force);
297
        }
298
299
        // re count ----------------------------------
300
        return true;
301
    }
302
303
    /**
304
     * updates a single field in a Article record
305
     *
306
     * @param  Articles $sbarticle  reference to the {@link Articles} object
307
     * @param  string   $fieldName  name of the field to update
308
     * @param  string   $fieldValue updated value for the field
309
     * @return bool   TRUE if success or unchanged, FALSE on failure
310
     */
311
    public function updateArticleByField($sbarticle, $fieldName, $fieldValue)
312
    {
313
        return $this->sbArticleHandler->updateByField($sbarticle, $fieldName, $fieldValue);
314
    }
315
316
    /**
317
     * updates a single field in a Column record
318
     *
319
     * @param  Columns $sbcolumns  reference to the {@link Columns} object
320
     * @param  string  $fieldName  name of the field to update
321
     * @param  string  $fieldValue updated value for the field
322
     * @return bool   TRUE if success or unchanged, FALSE on failure
323
     */
324
    public function updateColumnByField($sbcolumns, $fieldName, $fieldValue)
325
    {
326
        return $this->sbColumnHandler->updateByField($sbcolumns, $fieldName, $fieldValue);
327
    }
328
329
    /**
330
     * updates a single field in a Votedata record
331
     *
332
     * @param         $sbvotedata
333
     * @param  string $fieldName  name of the field to update
334
     * @param  string $fieldValue updated value for the field
335
     * @return bool   TRUE if success or unchanged, FALSE on failure
336
     * @internal param object $user reference to the {@link Columns} object object
337
     */
338
    public function updateVotedataByField(&$sbvotedata, $fieldName, $fieldValue)
339
    {
340
        return $this->sbVoteHandler->updateByField($sbvotedata, $fieldName, $fieldValue);
341
    }
342
343
    /**
344
     * weight update
345
     *
346
     * @param  array $weight to match
347
     * @return bool  FALSE if failed.
348
     */
349
    public function reorderColumnsUpdate($weight)
350
    {
351
        if (!isset($weight) || empty($weight) || !is_array($weight)) {
352
            return false;
353
        }
354
        foreach ($weight as $columnID => $order) {
355
            $weight[$columnID] = (int)$order;
356
        }
357
        array_unique($weight);
358
        foreach ($weight as $columnID => $order) {
359
            if (isset($columnID) && is_numeric($columnID) && isset($order)) {
360
                $sbcolumn = $this->getColumn($columnID);
361
                if (is_object($sbcolumn)) {
362
                    if (!is_numeric($order) || empty($order)) {
363
                        $order = 0;
364
                    }
365
                    $this->updateColumnByField($sbcolumn, 'weight', $order);
366
                }
367
            }
368
        }
369
370
        return true;
371
    }
372
373
    /**
374
     * weight update
375
     *
376
     * @param  array $weight to match
377
     * @return bool  FALSE if failed.
378
     */
379
    public function reorderArticlesUpdate($weight)
380
    {
381
        if (!isset($weight) || empty($weight) || !is_array($weight)) {
382
            return false;
383
        }
384
        foreach ($weight as $articleID => $order) {
385
            $weight[$articleID] = (int)$order;
386
        }
387
        array_unique($weight);
388
        foreach ($weight as $articleID => $order) {
389
            if (isset($articleID) && is_numeric($articleID) && isset($order)) {
390
                $sbarticle = $this->getArticle($articleID);
391
                if (is_object($sbarticle)) {
392
                    if (!is_numeric($order) || empty($order)) {
393
                        $order = 0;
394
                    }
395
                    $this->updateArticleByField($sbarticle, 'weight', $order);
396
                }
397
            }
398
        }
399
400
        return true;
401
    }
402
403
    /**
404
     * newarticleTriggerEvent a category of this columnID from the database
405
     *
406
     * @param  object $sbcolumn reference to the category to delete
407
     * @param  string $events
408
     * @return bool   FALSE if failed.
409
     * @internal param bool $force
410
     */
411
    public function newColumnTriggerEvent($sbcolumn, $events = 'new_column')
412
    {
413
        if (mb_strtolower(get_class($sbcolumn)) !== mb_strtolower(Columns::class)) {
414
            return false;
415
        }
416
        if (1 !== $sbcolumn->getVar('notifypub')) {
417
            return false;
418
        }
419
        // Notify of new link (anywhere) and new link in category
420
        $tags                = [];
421
        $tags['COLUMN_NAME'] = $sbcolumn->getVar('name');
422
        $tags['COLUMN_URL']  = XOOPS_URL . '/modules/' . $this->moduleDirName . '/column.php?columnID=' . $sbcolumn->getVar('columnID');
423
        /** @var \XoopsNotificationHandler $notificationHandler */
424
        $notificationHandler = xoops_getHandler('notification');
425
        $notificationHandler->triggerEvent('global', 0, 'new_column', $tags);
426
427
        return true;
428
    }
429
430
    /**
431
     * new articleTriggerEvent counter a new entry in the database
432
     *
433
     * @param         $sbarticle
434
     * @param  string $events
435
     * @return bool   FALSE if failed, TRUE if already present and unchanged or successful
436
     * @internal param object $criteria {@link CriteriaElement} conditions to be match conditions to be match
437
     */
438
    public function newArticleTriggerEvent(&$sbarticle, $events = 'new_article')
439
    {
440
        if (mb_strtolower(get_class($sbarticle)) !== mb_strtolower(Articles::class)) {
441
            return false;
442
        }
443
        $sbcolumns = $this->getColumn($sbarticle->getVar('columnID'));
444
        if (!is_object($sbcolumns)) {
445
            return false;
446
        }
447
        // Notify of new link (anywhere) and new link in category
448
        $tags                 = [];
449
        $tags['ARTICLE_NAME'] = $sbarticle->getVar('headline');
450
        $tags['ARTICLE_URL']  = XOOPS_URL . '/modules/' . $this->moduleDirName . '/article.php?articleID=' . $sbarticle->getVar('articleID');
451
        $tags['COLUMN_NAME']  = $sbcolumns->getVar('name');
452
        $tags['COLUMN_URL']   = XOOPS_URL . '/modules/' . $this->moduleDirName . '/column.php?columnID=' . $sbarticle->getVar('columnID');
453
        // Notify of to admin only for approve article_submit
454
        $tags['WAITINGSTORIES_URL'] = XOOPS_URL . '/modules/' . $this->moduleDirName . '/admin/submissions.php?op=col';
455
        $notificationHandler        = xoops_getHandler('notification');
456
        //approve evevt
457
        if ('article_submit' === $events) {
458
            $notificationHandler->triggerEvent('global', 0, 'article_submit', $tags);
459
            $notificationHandler->triggerEvent('column', $sbarticle->getVar('columnID'), 'article_submit', $tags);
460
        } elseif ('approve' === $events) {
461
            $notificationHandler->triggerEvent('article', $sbarticle->getVar('articleID'), 'approve', $tags);
462
        }
463
        //online
464
        if (0 === $sbarticle->getVar('offline') && 0 === $sbarticle->getVar('submit')) {
465
            //when offline ,update offline changed to visible --> event
466
            if (1 === $sbarticle->pre_offline && 1 === $sbarticle->getVar('notifypub')) {
467
                $notificationHandler->triggerEvent('global', 0, 'new_article', $tags);
468
                $notificationHandler->triggerEvent('column', $sbarticle->getVar('columnID'), 'new_article', $tags);
469
            }
470
        }
471
472
        return true;
473
    }
474
}
475