Issues (212)

Security Analysis    not enabled

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

  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.
  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.
  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.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  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.
  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.
  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.
  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.
  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.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  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.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
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/article.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
//
3
// ------------------------------------------------------------------------ //
4
// This program is free software; you can redistribute it and/or modify     //
5
// it under the terms of the GNU General Public License as published by     //
6
// the Free Software Foundation; either version 2 of the License, or        //
7
// (at your option) any later version.                                      //
8
//                                                                          //
9
// You may not change or alter any portion of this comment or credits       //
10
// of supporting developers from this source code or any supporting         //
11
// source code which is considered copyrighted (c) material of the          //
12
// original comment or credit authors.                                      //
13
//                                                                          //
14
// This program is distributed in the hope that it will be useful,          //
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of           //
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
17
// GNU General Public License for more details.                             //
18
//                                                                          //
19
// You should have received a copy of the GNU General Public License        //
20
// along with this program; if not, write to the Free Software              //
21
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA //
22
// ------------------------------------------------------------------------ //
23
// Author: phppp (D.J., [email protected])                                  //
24
// URL: https://xoops.org                         //
25
// Project: Article Project                                                 //
26
// ------------------------------------------------------------------------ //
27
/**
28
 * @package   module::article
29
 * @copyright copyright &copy; 2005 XoopsForge.com
30
 */
31
32
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
33
require_once __DIR__ . '/../include/vars.php';
34
//mod_loadFunctions('', $GLOBALS['moddirname']);
35
36
/**
37
 * Article
38
 *
39
 * @author    D.J. (phppp)
40
 * @copyright copyright &copy; 2005 XoopsForge.com
41
 * @package   module::article
42
 *
43
 * {@link XoopsObject}
44
 **/
45
if (!class_exists('Barticle')):
46
47
    /**
48
     * Class Barticle
49
     */
50
    class Barticle extends XoopsObject
51
    {
52
        /**
53
         * Constructor
54
         *
55
         * @param int $id ID of the article
56
         */
57
        public function __construct($id = null)
58
        {
59
            //            $this->ArtObject();
60
            $this->table = planet_DB_prefix('article');
61
            $this->initVar('art_id', XOBJ_DTYPE_INT, null, false);
62
            $this->initVar('blog_id', XOBJ_DTYPE_INT, 0, true);
63
64
            $this->initVar('art_title', XOBJ_DTYPE_TXTBOX, '');
65
            $this->initVar('art_content', XOBJ_DTYPE_TXTAREA, '');
66
            $this->initVar('art_link', XOBJ_DTYPE_TXTBOX, '');
67
            $this->initVar('art_time', XOBJ_DTYPE_INT, 0);
68
            $this->initVar('art_author', XOBJ_DTYPE_TXTBOX, '');
69
70
            $this->initVar('art_views', XOBJ_DTYPE_INT, 0);
71
            $this->initVar('art_rating', XOBJ_DTYPE_INT, 0);
72
            $this->initVar('art_rates', XOBJ_DTYPE_INT, 0);
73
            $this->initVar('art_comments', XOBJ_DTYPE_INT, 0);
74
75
            $this->initVar('dohtml', XOBJ_DTYPE_INT, 1);
76
            $this->initVar('dosmiley', XOBJ_DTYPE_INT, 1);
77
            $this->initVar('doxcode', XOBJ_DTYPE_INT, 1);
78
            $this->initVar('doimage', XOBJ_DTYPE_INT, 1);
79
            $this->initVar('dobr', XOBJ_DTYPE_INT, 1);
80
        }
81
82
        /**
83
         * get title of the article
84
         *
85
         * @return string
86
         */
87
        public function getTitle()
88
        {
89
            $title = $this->getVar('art_title');
90
91
            return $title;
92
        }
93
94
        /**
95
         * get formatted publish time of the article
96
         *
97
         * {@link Config}
98
         *
99
         * @param  string $format format of time
100
         * @return string
101
         */
102
        public function getTime($format = 'c')
103
        {
104
            $time = $this->getVar('art_time');
105
            if (empty($time)) {
106
                $time = time();
107
            }
108
            $time = PlanetUtility::planetFormatTimestamp($time, $format);
109
110
            return $time;
111
        }
112
113
        /**
114
         * get summary of the article
115
         *
116
         * @param int $length
117
         * @return string $summary
118
         */
119
        public function &getSummary($length = 0)
120
        {
121
            $content = $this->getVar('art_content');
122
            $summary =& PlanetUtility::planetHtml2text($content);
123
            if (empty($length)) {
124
                $length = $GLOBALS['xoopsModuleConfig']['display_summary'];
125
            }
126
            if (!empty($length)) {
127
                $summary = xoops_substr($summary, 0, $length);
128
            }
129
130
            return $summary;
131
        }
132
133
        /**
134
         * get rating average of the article
135
         *
136
         * @param  int $decimals decimal length
137
         * @return numeric
138
         */
139 View Code Duplication
        public function getRatingAverage($decimals = 1)
0 ignored issues
show
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...
140
        {
141
            $ave = 3;
142
            if ($this->getVar('art_rates')) {
143
                $ave = number_format($this->getVar('art_rating') / $this->getVar('art_rates'), $decimals);
144
            }
145
146
            return $ave;
147
        }
148
149
        /**
150
         * @return numeric
151
         */
152
        public function getStar()
153
        {
154
            return $this->getRatingAverage(0);
155
        }
156
    }
157
endif;
158
159
/**
160
 * Article object handler class.
161
 * @package   module::article
162
 *
163
 * @author    D.J. (phppp)
164
 * @copyright copyright &copy; 2000 XOOPS Project
165
 *
166
 * {@link XoopsPersistableObjectHandler}
167
 *
168
 * @param CLASS_PREFIX variable prefix for the class name
169
 */
170
171
PlanetUtility::planetParseClass('
172
class [CLASS_PREFIX]ArticleHandler extends XoopsPersistableObjectHandler
173
{
174
    /**
175
     * Constructor
176
     *
177
     * @param object $db reference to the {@link XoopsDatabase} object
178
     **/
179
    public function __construct(\XoopsDatabase $db) {
180
        parent::__construct($db, planet_DB_prefix("article", true), "Barticle", "art_id", "art_title");
181
    }
182
183
    /**
184
     * insert new articles if content is changed
185
     *
186
     * @param  array $articles
187
     * @param  int   $blog_id
188
     * @return int   inserted article count
189
     */
190
    public function do_update(&$articles, $blog_id = 0)
191
    {
192
        if ($blog_id>0) {
193
            $crit_blog = new \Criteria("blog_id", $blog_id);
194
        } else {
195
            $crit_blog = null;
196
        }
197
        $count = 0;
198
        foreach ($articles as $article) {
199
            $criteria = new \CriteriaCompo();
200
            if ($article["blog_id"]) {
201
                $criteria->add(new \Criteria("blog_id", $article["blog_id"]));
202
            } else {
203
                $criteria->add($crit_blog);
204
            }
205
            $criteria->add(new \Criteria("art_link", $article["art_link"]));
206
            $_count = $this->getCount($criteria);
207
            unset($criteria);
208
            if($_count>0) continue;
209
            $article_obj = $this->create();
210
            $article_obj->setVars($article, true);
211
            $this->insert($article_obj, true);
212
            unset($article_obj);
213
            ++$count ;
214
        }
215
216
        return $count;
217
    }
218
219
    /**
220
     * get a list of articles matching a condition of a category
221
     *
222
     * @param  object $criteria {@link CriteriaElement} to match
223
     * @param  array  $tags     variables to fetch
224
     * @param  bool   $asObject flag indicating as object, otherwise as array
225
     * @return array  of articles {@link Barticle}
226
     */
227
       public function &getByCategory($criteria = null, $tags = null, $asObject=true)
228
    {
229
        if (is_array($tags) && count($tags)>0) {
230
            if(!in_array($this->keyName, $tags)) $tags[] = $this->keyName;
231
            $select = implode(",", $tags);
232
        } else $select = "*";
233
        $limit = null;
234
        $start = null;
235
        $sql = "SELECT $select".
236
                " FROM " . $this->table. " AS a".
237
                //" LEFT JOIN (SELECT blog_id, cat_id FROM ".planet_DB_prefix("blogcat").") AS bc ON a.blog_id = bc.blog_id";
238
                " LEFT JOIN ".planet_DB_prefix("blogcat")." AS bc ON a.blog_id = bc.blog_id";
239
        if (isset($criteria) && is_subclass_of($criteria, "criteriaelement")) {
240
            $sql .= " ".$criteria->renderWhere();
241
            if ($criteria->getSort() != "") {
242
                $sql .= " ORDER BY ".$criteria->getSort()." ".$criteria->getOrder();
243
                $orderSet = true;
244
            }
245
            $limit = $criteria->getLimit();
246
            $start = $criteria->getStart();
247
        }
248
        if(empty($orderSet)) $sql .= " ORDER BY ".$this->keyName." DESC";
249
        $result = $this->db->query($sql, $limit, $start);
250
        $ret = array();
251
       while (false !== ($myrow = $this->db->fetchArray($result))) {
252
            $object = $this->create(false);
253
            $object->assignVars($myrow);
254
            if ($asObject) {
255
                $ret[$myrow[$this->keyName]] = $object;
256
            } else {
257
                foreach ($myrow as $key=>$val) {
258
                    $ret[$myrow[$this->keyName]][$key] = ($object->vars[$key]["changed"])?$object->getVar($key):$val;
259
                }
260
            }
261
            unset($object);
262
        }
263
264
        return $ret;
265
    }
266
267
    /**
268
     * count articles matching a condition of a category (categories)
269
     *
270
     * @param  object $criteria {@link CriteriaElement} to match
271
     * @return int    count of articles
272
     */
273
       public function getCountByCategory($criteria = null)
274
    {
275
        $sql = "SELECT COUNT(DISTINCT a.art_id) AS count".
276
                " FROM " . $this->table. " AS a".
277
                //" LEFT JOIN (SELECT blog_id, cat_id FROM ".planet_DB_prefix("blogcat").") AS bc ON a.blog_id = bc.blog_id";
278
                " LEFT JOIN ".planet_DB_prefix("blogcat")." AS bc ON a.blog_id = bc.blog_id";
279
        if (isset($criteria) && is_subclass_of($criteria, "criteriaelement")) {
280
            $sql .= " ".$criteria->renderWhere();
281
        }
282
        if (!$result = $this->db->query($sql)) {
283
            return false;
284
        }
285
        $myrow = $this->db->fetchArray($result);
286
287
        return (int)($myrow["count"]);
288
    }
289
290
       public function getCountsByCategory($criteria = null)
291
    {
292
        $sql = "SELECT bc.cat_id, COUNT(*)".
293
                " FROM " . $this->table. " AS a".
294
                //" LEFT JOIN (SELECT blog_id, cat_id FROM ".planet_DB_prefix("blogcat").") AS bc ON a.blog_id = bc.blog_id";
295
                " LEFT JOIN ".planet_DB_prefix("blogcat")." AS bc ON a.blog_id = bc.blog_id";
296
        if (isset($criteria) && is_subclass_of($criteria, "criteriaelement")) {
297
            $sql .= " ".$criteria->renderWhere();
298
        }
299
        $sql .=" GROUP BY bc.cat_id";
300
        if (!$result = $this->db->query($sql)) {
301
            return false;
302
        }
303
        $ret = array();
304
        while (false !== (list($id, $count) = $this->db->fetchRow($result))) {
305
            $ret[$id] = $count;
306
        }
307
308
        return $ret;
309
    }
310
311
    /**
312
     * get a list of articles matching a condition of user bookmark
313
     *
314
     * @param  object $criteria {@link CriteriaElement} to match
315
     * @param  array  $tags     variables to fetch
316
     * @param  bool   $asObject flag indicating as object, otherwise as array
317
     * @return array  of articles {@link Barticle}
318
     */
319
       public function &getByBookmark($criteria = null, $tags = null, $asObject=true)
320
    {
321
        if (is_array($tags) && count($tags)>0) {
322
            if(!in_array($this->keyName, $tags)) $tags[] = $this->keyName;
323
            $select = implode(",", $tags);
324
        } else $select = "*";
325
        $limit = null;
326
        $start = null;
327
        $sql = "SELECT $select".
328
                " FROM " . $this->table. " AS a".
329
                //" LEFT JOIN (SELECT blog_id, bm_uid FROM ".planet_DB_prefix("bookmark").") AS bm ON a.blog_id = bm.blog_id";
330
                " LEFT JOIN ".planet_DB_prefix("bookmark")." AS bm ON a.blog_id = bm.blog_id";
331
        if (isset($criteria) && is_subclass_of($criteria, "criteriaelement")) {
332
            $sql .= " ".$criteria->renderWhere();
333
            if ($criteria->getSort() != "") {
334
                $sql .= " ORDER BY ".$criteria->getSort()." ".$criteria->getOrder();
335
                $orderSet = true;
336
            }
337
            $limit = $criteria->getLimit();
338
            $start = $criteria->getStart();
339
        }
340
        if(empty($orderSet)) $sql .= " ORDER BY ".$this->keyName." DESC";
341
        $result = $this->db->query($sql, $limit, $start);
342
        $ret = array();
343
       while (false !== ($myrow = $this->db->fetchArray($result))) {
344
            $object = $this->create(false);
345
            $object->assignVars($myrow);
346
            if ($asObject) {
347
                $ret[$myrow[$this->keyName]] = $object;
348
            } else {
349
                foreach ($myrow as $key=>$val) {
350
                    $ret[$myrow[$this->keyName]][$key] = ($object->vars[$key]["changed"])?$object->getVar($key):$val;
351
                }
352
            }
353
            unset($object);
354
        }
355
356
        return $ret;
357
    }
358
359
    /**
360
     * count blogs matching a condition of user bookmark
361
     *
362
     * @param  object $criteria {@link CriteriaElement} to match
363
     * @return int    count of blogs
364
     */
365
       public function getCountByBookmark($criteria = null)
366
    {
367
        $sql = "SELECT COUNT(DISTINCT a.art_id) AS count".
368
                " FROM " . $this->table. " AS a".
369
                //" LEFT JOIN (SELECT blog_id, bm_uid FROM ".planet_DB_prefix("bookmark").") AS bm ON a.blog_id = bm.blog_id";
370
                " LEFT JOIN ".planet_DB_prefix("bookmark")." AS bm ON a.blog_id = bm.blog_id";
371
        if (isset($criteria) && is_subclass_of($criteria, "criteriaelement")) {
372
            $sql .= " ".$criteria->renderWhere();
373
        }
374
        if (!$result = $this->db->query($sql)) {
375
            return false;
376
        }
377
        $myrow = $this->db->fetchArray($result);
378
379
        return (int)($myrow["count"]);
380
    }
381
    /**
382
     * Get the previous article and the next article of an article
383
     *
384
     * @param  object $article reference to the article
385
     * @param  int    $blog    blog ID
386
     * @return array
387
     **/
388
    // To be optimized
389
    public function &getSibling(&$article, $blog = 0)
390
    {
391
        $ret = array();
392
393
        $crit_prev = new \CriteriaCompo(new \Criteria("art_id", $article->getVar("art_id"), "<"));
394
        if ($blog>0) {
395
            $crit_prev->add(new \Criteria("blog_id", $blog));
396
        }
397
        $crit_prev->setSort("art_id");
398
        $crit_prev->setOrder("DESC");
399
        $crit_prev->setLimit(1);
400
        $art_prev =& $this->getObjects($crit_prev);
401
        if (count($art_prev)>0) {
402
            $ret["previous"] = array("id"=>$art_prev[0]->getVar("art_id"),"title"=>$art_prev[0]->getVar("art_title"));
403
            unset($art_prev);
404
        }
405
406
        $crit_next = new \CriteriaCompo(new \Criteria("art_id", $article->getVar("art_id"), ">"));
407
        if ($blog>0) {
408
            $crit_next->add(new \Criteria("blog_id", $blog));
409
        }
410
        $crit_next->setSort("art_id");
411
        $crit_next->setOrder("DESC");
412
        $crit_next->setLimit(1);
413
        $art_next =& $this->getObjects($crit_next);
414
        if (count($art_next)>0) {
415
            $ret["next"] = array("id"=>$art_next[0]->getVar("art_id"),"title"=>$art_next[0]->getVar("art_title"));
416
            unset($art_next);
417
        }
418
419
        return $ret;
420
    }
421
422
    /**
423
     * Update comment count of the article
424
     *
425
     * @param  object $article {@link Article} reference to Article
426
     * @param  int    $total   total comment count
427
     * @return bool   true on success
428
     */
429
   public function updateComments(&$article, $total)
430
    {
431
        $article->setVar("art_comments", (int)($total), true);
432
433
        return $this->insert($article, true);
434
    }
435
436
    /**
437
     * delete an article from the database
438
     *
439
     * {@link Text}
440
     *
441
     * @param  object $article {@link Article} reference to Article
442
     * @param  bool   $force   flag to force the query execution despite security settings
443
     * @return bool   true on success
444
     */
445
    public function delete(\XoopsObject $article, $force = true)
446
    {
447
        $rateHandler = xoops_getModuleHandler("rate", $GLOBALS["moddirname"]);
448
        $rateHandler->deleteAll(new \Criteria("art_id", $article->getVar("art_id")));
449
450
        xoops_comment_delete($GLOBALS["xoopsModule"]->getVar("mid"), $article->getVar("art_id"));
451
        xoops_notification_deletebyitem($GLOBALS["xoopsModule"]->getVar("mid"), "article", $article->getVar("art_id"));
452
453
        parent::delete($article, $force);
454
455
        $article = null;
456
        unset($article);
457
458
        return true;
459
    }
460
}
461
');
462