1<?php
2/**
3 * XOOPS comment
4 *
5 * You may not change or alter any portion of this comment or credits
6 * of supporting developers from this source code or any supporting source code
7 * which is considered copyrighted (c) material of the original comment or credit authors.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
13 * @license             GNU GPL 2 (http://www.gnu.org/licenses/gpl-2.0.html)
14 * @package             kernel
15 * @since               2.0.0
16 * @author              Kazumi Ono (AKA onokazu) http://www.myweb.ne.jp/, http://jp.xoops.org/
17 */
18
19defined('XOOPS_ROOT_PATH') || exit('Restricted access');
20
21include_once $GLOBALS['xoops']->path('include/comment_constants.php');
22
23xoops_loadLanguage('comment');
24
25if ('system' === $xoopsModule->getVar('dirname')) {
26    $com_id = isset($_POST['com_id']) ? (int)$_POST['com_id'] : 0;
27    if (empty($com_id)) {
28        exit();
29    }
30    /* @var  XoopsCommentHandler $comment_handler */
31    $comment_handler = xoops_getHandler('comment');
32    $comment         = $comment_handler->get($com_id);
33    $module_handler  = xoops_getHandler('module');
34    $module          = $module_handler->get($comment->getVar('com_modid'));
35    $comment_config  = $module->getInfo('comments');
36    $com_modid       = $module->getVar('mid');
37    $redirect_page   = XOOPS_URL . '/modules/system/admin.php?fct=comments&com_modid=' . $com_modid . '&com_itemid';
38    $moddir          = $module->getVar('dirname');
39    unset($comment);
40} else {
41    $com_id = isset($_POST['com_id']) ? (int)$_POST['com_id'] : 0;
42    if (XOOPS_COMMENT_APPROVENONE == $xoopsModuleConfig['com_rule']) {
43        exit();
44    }
45    $comment_config = $xoopsModule->getInfo('comments');
46    $com_modid      = $xoopsModule->getVar('mid');
47    $redirect_page  = $comment_config['pageName'] . '?';
48    if (isset($comment_config['extraParams']) && is_array($comment_config['extraParams'])) {
49        $extra_params = '';
50        foreach ($comment_config['extraParams'] as $extra_param) {
51            $extra_params .= isset($_POST[$extra_param]) ? $extra_param . '=' . htmlspecialchars($_POST[$extra_param]) . '&amp;' : $extra_param . '=&amp;';
52        }
53        $redirect_page .= $extra_params;
54    }
55    $redirect_page .= $comment_config['itemName'];
56    $comment_url = $redirect_page;
57    $moddir      = $xoopsModule->getVar('dirname');
58}
59
60$op            = '';
61$error_message = '';
62$com_user      = '';
63$com_email     = '';
64$com_url       = '';
65
66if (!empty($_POST)) {
67    if (isset($_POST['com_dopost'])) {
68        $op = 'post';
69    } elseif (isset($_POST['com_dopreview'])) {
70        $op = 'preview';
71    }
72    if (isset($_POST['com_dodelete'])) {
73        $op = 'delete';
74    }
75    if ($op === 'preview' || $op === 'post') {
76        if (!$GLOBALS['xoopsSecurity']->check()) {
77            $op = '';
78        }
79    }
80    if ($op === 'post' && !is_object($xoopsUser)) {
81        xoops_load('XoopsCaptcha');
82        $xoopsCaptcha = XoopsCaptcha::getInstance();
83        if (!$xoopsCaptcha->verify()) {
84            $error_message .= $xoopsCaptcha->getMessage() . '<br>';
85        }
86
87        // Start add by voltan
88        xoops_load('XoopsUserUtility');
89        xoops_loadLanguage('user');
90        $myts = MyTextSanitizer::getInstance();
91
92        // Check user name
93        $search_arr  = array(
94            '&nbsp;',
95            "\t",
96            "\r\n",
97            "\r",
98            "\n",
99            ',',
100            '.',
101            "'",
102            ';',
103            ':',
104            ')',
105            '(',
106            '"',
107            '?',
108            '!',
109            '{',
110            '}',
111            '[',
112            ']',
113            '<',
114            '>',
115            '/',
116            '+',
117            '-',
118            '_',
119            '\\',
120            '*',
121            '=',
122            '@',
123            '#',
124            '$',
125            '%',
126            '^',
127            '&');
128        $replace_arr = array(
129            ' ',
130            ' ',
131            ' ',
132            ' ',
133            ' ',
134            ' ',
135            ' ',
136            ' ',
137            ' ',
138            ' ',
139            ' ',
140            ' ',
141            ' ',
142            ' ',
143            ' ',
144            ' ',
145            ' ',
146            ' ',
147            ' ',
148            ' ',
149            ' ',
150            ' ',
151            ' ',
152            ' ',
153            ' ',
154            ' ',
155            ' ',
156            ' ',
157            ' ',
158            ' ',
159            ' ',
160            ' ',
161            ' ',
162            '');
163        $com_user    = trim($_POST['com_user']);
164        $com_user    = $myts->stripSlashesGPC($com_user);
165        $com_user    = $myts->xoopsCodeDecode($com_user);
166        $com_user    = $myts->filterXss($com_user);
167        $com_user    = strip_tags($com_user);
168        $com_user    = strtolower($com_user);
169        $com_user    = htmlentities($com_user, ENT_COMPAT, 'utf-8');
170        $com_user    = preg_replace('`\[.*\]`U', ' ', $com_user);
171        $com_user    = preg_replace('`&(amp;)?#?[a-z0-9]+;`i', ' ', $com_user);
172        $com_user    = preg_replace('`&([a-z])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig);`i', '\\1', $com_user);
173        $com_user    = str_replace($search_arr, $replace_arr, $com_user);
174
175        // Check Url
176        if (!empty($_POST['com_url'])) {
177            $com_url = trim($_POST['com_url']);
178            $com_url = filter_var($com_url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED);
179        }
180
181        // Check Email
182        $com_email = $myts->stripSlashesGPC(trim($_POST['com_email']));
183        $com_email = htmlspecialchars(trim($com_email), ENT_QUOTES);
184        $com_email = filter_var($com_email, FILTER_VALIDATE_EMAIL);
185        // Invalid email address
186        if (!checkEmail($com_email)) {
187            $error_message .= _US_INVALIDMAIL . '<br>';
188        }
189        if (strrpos($com_email, ' ') > 0) {
190            $error_message .= _US_EMAILNOSPACES . '<br>';
191        }
192        // Check forbidden email address if current operator is not an administrator
193        if (!$xoopsUser_isAdmin) {
194            foreach ($xoopsConfigUser['bad_emails'] as $be) {
195                if (!empty($be) && preg_match('/' . $be . '/i', $com_email)) {
196                    $error_message .= _US_INVALIDMAIL . '<br>';
197                    break;
198                }
199            }
200        }
201        if (!empty($error_message)) {
202            $op = 'preview';
203        }
204        // End add by voltan
205    }
206
207    $com_mode   = isset($_POST['com_mode']) ? htmlspecialchars(trim($_POST['com_mode']), ENT_QUOTES) : 'flat';
208    $com_order  = isset($_POST['com_order']) ? (int)$_POST['com_order'] : XOOPS_COMMENT_OLD1ST;
209    $com_itemid = isset($_POST['com_itemid']) ? (int)$_POST['com_itemid'] : 0;
210    $com_pid    = isset($_POST['com_pid']) ? (int)$_POST['com_pid'] : 0;
211    $com_rootid = isset($_POST['com_rootid']) ? (int)$_POST['com_rootid'] : 0;
212    $com_status = isset($_POST['com_status']) ? (int)$_POST['com_status'] : 0;
213    $dosmiley   = (isset($_POST['dosmiley']) && (int)$_POST['dosmiley'] > 0) ? 1 : 0;
214    $doxcode    = (isset($_POST['doxcode']) && (int)$_POST['doxcode'] > 0) ? 1 : 0;
215    $dobr       = (isset($_POST['dobr']) && (int)$_POST['dobr'] > 0) ? 1 : 0;
216    $dohtml     = (isset($_POST['dohtml']) && (int)$_POST['dohtml'] > 0) ? 1 : 0;
217    $doimage    = (isset($_POST['doimage']) && (int)$_POST['doimage'] > 0) ? 1 : 0;
218    $com_icon   = isset($_POST['com_icon']) ? trim($_POST['com_icon']) : '';
219} else {
220    exit();
221}
222/* @var  XoopsUser $xoopsUser */
223switch ($op) {
224    case 'delete':
225        include_once $GLOBALS['xoops']->path('include/comment_delete.php');
226        break;
227
228    case 'preview':
229        $myts      = MyTextSanitizer::getInstance();
230        $doimage   = 1;
231        $com_title = $myts->htmlSpecialChars($myts->stripSlashesGPC($_POST['com_title']));
232        if ($dohtml != 0) {
233            if (is_object($xoopsUser)) {
234                if (!$xoopsUser->isAdmin($com_modid)) {
235                    include_once $GLOBALS['xoops']->path('modules/system/constants.php');
236                    /* @var XoopsGroupPermHandler $sysperm_handler */
237                    $sysperm_handler = xoops_getHandler('groupperm');
238                    if (!$sysperm_handler->checkRight('system_admin', XOOPS_SYSTEM_COMMENT, $xoopsUser->getGroups())) {
239                        $dohtml = 0;
240                    }
241                }
242            } else {
243                $dohtml = 0;
244            }
245        }
246        $p_comment =& $myts->previewTarea($_POST['com_text'], $dohtml, $dosmiley, $doxcode, $doimage, $dobr);
247        $noname    = isset($noname) ? (int)$noname : 0;
248        $com_text  = $myts->htmlSpecialChars($myts->stripSlashesGPC($_POST['com_text']));
249        if ($xoopsModule->getVar('dirname') !== 'system') {
250            include_once $GLOBALS['xoops']->path('header.php');
251            if (!empty($error_message)) {
252                xoops_error($error_message);
253            }
254            echo '<table cellpadding="4" cellspacing="1" width="98%" class="outer">
255                  <tr><td class="head">' . $com_title . '</td></tr>
256                  <tr><td><br>' . $p_comment . '<br></td></tr>
257                  </table>';
258            include_once $GLOBALS['xoops']->path('include/comment_form.php');
259            include_once $GLOBALS['xoops']->path('footer.php');
260        } else {
261            xoops_cp_header();
262            echo '<table cellpadding="4" cellspacing="1" width="98%" class="outer">
263                  <tr><td class="head">' . $com_title . '</td></tr>
264                  <tr><td><br>' . $p_comment . '<br></td></tr>
265                  </table>';
266            include_once $GLOBALS['xoops']->path('include/comment_form.php');
267            xoops_cp_footer();
268        }
269        break;
270
271    case 'post':
272        XoopsLoad::load('XoopsRequest');
273        $doimage         = 1;
274        $comment_handler = xoops_getHandler('comment');
275        // Start add by voltan
276        $myts = MyTextSanitizer::getInstance();
277        // Edit add by voltan
278        $add_userpost     = false;
279        $call_approvefunc = false;
280        $call_updatefunc  = false;
281        // RMV-NOTIFY - this can be set to 'comment' or 'comment_submit'
282        $notify_event = false;
283        if (!empty($com_id)) {
284            $comment     = $comment_handler->get($com_id);
285            $accesserror = false;
286
287            if (is_object($xoopsUser)) {
288                include_once $GLOBALS['xoops']->path('modules/system/constants.php');
289                /* @var XoopsGroupPermHandler $sysperm_handler */
290                $sysperm_handler = xoops_getHandler('groupperm');
291                if ($xoopsUser->isAdmin($com_modid) || $sysperm_handler->checkRight('system_admin', XOOPS_SYSTEM_COMMENT, $xoopsUser->getGroups())) {
292                    if (!empty($com_status) && $com_status != XOOPS_COMMENT_PENDING) {
293                        $old_com_status = $comment->getVar('com_status');
294                        $comment->setVar('com_status', $com_status);
295                        // if changing status from pending state, increment user post
296                        if (XOOPS_COMMENT_PENDING == $old_com_status) {
297                            $add_userpost = true;
298                            if (XOOPS_COMMENT_ACTIVE == $com_status) {
299                                $call_updatefunc  = true;
300                                $call_approvefunc = true;
301                                // RMV-NOTIFY
302                                $notify_event = 'comment';
303                            }
304                        } elseif (XOOPS_COMMENT_HIDDEN == $old_com_status && XOOPS_COMMENT_ACTIVE == $com_status) {
305                            $call_updatefunc = true;
306                            // Comments can not be directly posted hidden,
307                            // no need to send notification here
308                        } elseif (XOOPS_COMMENT_ACTIVE == $old_com_status && XOOPS_COMMENT_HIDDEN == $com_status) {
309                            $call_updatefunc = true;
310                        }
311                    }
312                } else {
313                    $dohtml = 0;
314                    if ($comment->getVar('com_uid') != $xoopsUser->getVar('uid')) {
315                        $accesserror = true;
316                    }
317                }
318            } else {
319                $dohtml      = 0;
320                $accesserror = true;
321            }
322            if (false !== $accesserror) {
323                redirect_header($redirect_page . '=' . $com_itemid . '&amp;com_id=' . $com_id . '&amp;com_mode=' . $com_mode . '&amp;com_order=' . $com_order, 1, _NOPERM);
324            }
325        } else {
326            $comment = $comment_handler->create();
327            $comment->setVar('com_created', time());
328            $comment->setVar('com_pid', $com_pid);
329            $comment->setVar('com_itemid', $com_itemid);
330            $comment->setVar('com_rootid', $com_rootid);
331            $comment->setVar('com_ip', \Xmf\IPAddress::fromRequest()->asReadable());
332            if (is_object($xoopsUser)) {
333                include_once $GLOBALS['xoops']->path('modules/system/constants.php');
334                /* @var XoopsGroupPermHandler $sysperm_handler */
335                $sysperm_handler = xoops_getHandler('groupperm');
336                if ($xoopsUser->isAdmin($com_modid) || $sysperm_handler->checkRight('system_admin', XOOPS_SYSTEM_COMMENT, $xoopsUser->getGroups())) {
337                    $comment->setVar('com_status', XOOPS_COMMENT_ACTIVE);
338                    $add_userpost     = true;
339                    $call_approvefunc = true;
340                    $call_updatefunc  = true;
341                    // RMV-NOTIFY
342                    $notify_event = 'comment';
343                } else {
344                    $dohtml = 0;
345                    switch ($xoopsModuleConfig['com_rule']) {
346                        case XOOPS_COMMENT_APPROVEALL:
347                        case XOOPS_COMMENT_APPROVEUSER:
348                            $comment->setVar('com_status', XOOPS_COMMENT_ACTIVE);
349                            $add_userpost     = true;
350                            $call_approvefunc = true;
351                            $call_updatefunc  = true;
352                            // RMV-NOTIFY
353                            $notify_event = 'comment';
354                            break;
355                        case XOOPS_COMMENT_APPROVEADMIN:
356                        default:
357                            $comment->setVar('com_status', XOOPS_COMMENT_PENDING);
358                            $notify_event = 'comment_submit';
359                            break;
360                    }
361                }
362                if (!empty($xoopsModuleConfig['com_anonpost']) && !empty($noname)) {
363                    $uid = 0;
364                } else {
365                    $uid = $xoopsUser->getVar('uid');
366                }
367            } else {
368                $dohtml = 0;
369                $uid    = 0;
370                if ($xoopsModuleConfig['com_anonpost'] != 1) {
371                    redirect_header($redirect_page . '=' . $com_itemid . '&amp;com_id=' . $com_id . '&amp;com_mode=' . $com_mode . '&amp;com_order=' . $com_order, 1, _NOPERM);
372                }
373            }
374            if ($uid == 0) {
375                switch ($xoopsModuleConfig['com_rule']) {
376                    case XOOPS_COMMENT_APPROVEALL:
377                        $comment->setVar('com_status', XOOPS_COMMENT_ACTIVE);
378                        $add_userpost     = true;
379                        $call_approvefunc = true;
380                        $call_updatefunc  = true;
381                        // RMV-NOTIFY
382                        $notify_event = 'comment';
383                        break;
384                    case XOOPS_COMMENT_APPROVEADMIN:
385                    case XOOPS_COMMENT_APPROVEUSER:
386                    default:
387                        $comment->setVar('com_status', XOOPS_COMMENT_PENDING);
388                        // RMV-NOTIFY
389                        $notify_event = 'comment_submit';
390                        break;
391                }
392            }
393            $comment->setVar('com_uid', $uid);
394        }
395        $comment->setVar('com_title', XoopsRequest::getString('com_title', _NOTITLE, 'POST'));
396        $comment->setVar('com_text', XoopsRequest::getString('com_text', '', 'POST'));
397        $comment->setVar('dohtml', $dohtml);
398        $comment->setVar('dosmiley', $dosmiley);
399        $comment->setVar('doxcode', $doxcode);
400        $comment->setVar('doimage', $doimage);
401        $comment->setVar('dobr', $dobr);
402        $comment->setVar('com_icon', $com_icon);
403        $comment->setVar('com_modified', time());
404        $comment->setVar('com_modid', $com_modid);
405        // Start add by voltan
406        $comment->setVar('com_user', $com_user);
407        $comment->setVar('com_email', $com_email);
408        $comment->setVar('com_url', $com_url);
409        // End add by voltan
410        if (isset($extra_params)) {
411            $comment->setVar('com_exparams', $extra_params);
412        }
413        if (false !== $comment_handler->insert($comment)) {
414            $newcid = $comment->getVar('com_id');
415            // set own id as root id if this is a top comment
416            if ($com_rootid == 0) {
417                $com_rootid = $newcid;
418                if (!$comment_handler->updateByField($comment, 'com_rootid', $com_rootid)) {
419                    $comment_handler->delete($comment);
420                    include $GLOBALS['xoops']->path('header.php');
421                    xoops_error();
422                    include $GLOBALS['xoops']->path('footer.php');
423                }
424            }
425            // call custom approve function if any
426            if (false !== $call_approvefunc && isset($comment_config['callback']['approve']) && trim($comment_config['callback']['approve']) != '') {
427                $skip = false;
428                if (!function_exists($comment_config['callback']['approve'])) {
429                    if (isset($comment_config['callbackFile'])) {
430                        $callbackfile = trim($comment_config['callbackFile']);
431                        if ($callbackfile != '' && file_exists($GLOBALS['xoops']->path('modules/' . $moddir . '/' . $callbackfile))) {
432                            include_once $GLOBALS['xoops']->path('modules/' . $moddir . '/' . $callbackfile);
433                        }
434                        if (!function_exists($comment_config['callback']['approve'])) {
435                            $skip = true;
436                        }
437                    } else {
438                        $skip = true;
439                    }
440                }
441                if (!$skip) {
442                    $comment_config['callback']['approve']($comment);
443                }
444            }
445
446            // call custom update function if any
447            if (false !== $call_updatefunc && isset($comment_config['callback']['update']) && trim($comment_config['callback']['update']) != '') {
448                $skip = false;
449                if (!function_exists($comment_config['callback']['update'])) {
450                    if (isset($comment_config['callbackFile'])) {
451                        $callbackfile = trim($comment_config['callbackFile']);
452                        if ($callbackfile != '' && file_exists($GLOBALS['xoops']->path('modules/' . $moddir . '/' . $callbackfile))) {
453                            include_once $GLOBALS['xoops']->path('modules/' . $moddir . '/' . $callbackfile);
454                        }
455                        if (!function_exists($comment_config['callback']['update'])) {
456                            $skip = true;
457                        }
458                    } else {
459                        $skip = true;
460                    }
461                }
462                if (!$skip) {
463                    $criteria = new CriteriaCompo(new Criteria('com_modid', $com_modid));
464                    $criteria->add(new Criteria('com_itemid', $com_itemid));
465                    $criteria->add(new Criteria('com_status', XOOPS_COMMENT_ACTIVE));
466                    $comment_count = $comment_handler->getCount($criteria);
467                    $func          = $comment_config['callback']['update'];
468                    call_user_func_array($func, array(
469                        $com_itemid,
470                        $comment_count,
471                        $comment->getVar('com_id')));
472                }
473            }
474
475            // increment user post if needed
476            $uid = $comment->getVar('com_uid');
477            if ($uid > 0 && false !== $add_userpost) {
478                /* @var XoopsMemberHandler $member_handler */
479                $member_handler = xoops_getHandler('member');
480                $poster         = $member_handler->getUser($uid);
481                if (is_object($poster)) {
482                    $member_handler->updateUserByField($poster, 'posts', $poster->getVar('posts') + 1);
483                }
484            }
485
486            // RMV-NOTIFY
487            // trigger notification event if necessary
488            if ($notify_event) {
489                $not_modid = $com_modid;
490                include_once $GLOBALS['xoops']->path('include/notification_functions.php');
491                $not_catinfo  =& notificationCommentCategoryInfo($not_modid);
492                $not_category = $not_catinfo['name'];
493                $not_itemid   = $com_itemid;
494                $not_event    = $notify_event;
495                // Build an ABSOLUTE URL to view the comment.  Make sure we
496                // point to a viewable page (i.e. not the system administration
497                // module).
498                $comment_tags = array();
499                if ('system' === $xoopsModule->getVar('dirname')) {
500                    /* @var XoopsModuleHandler $module_handler */
501                    $module_handler = xoops_getHandler('module');
502                    $not_module     = $module_handler->get($not_modid);
503                } else {
504                    $not_module =& $xoopsModule;
505                }
506                if (!isset($comment_url)) {
507                    $com_config  =& $not_module->getInfo('comments');
508                    $comment_url = $com_config['pageName'] . '?';
509                    if (isset($com_config['extraParams']) && is_array($com_config['extraParams'])) {
510                        $extra_params = '';
511                        foreach ($com_config['extraParams'] as $extra_param) {
512                            $extra_params .= isset($_POST[$extra_param]) ? $extra_param . '=' . htmlspecialchars($_POST[$extra_param]) . '&amp;' : $extra_param . '=&amp;';
513                        }
514                        $comment_url .= $extra_params;
515                    }
516                    $comment_url .= $com_config['itemName'];
517                }
518                $comment_tags['X_COMMENT_URL'] = XOOPS_URL . '/modules/' . $not_module->getVar('dirname') . '/' . $comment_url . '=' . $com_itemid . '&amp;com_id=' . $newcid . '&amp;com_rootid=' . $com_rootid . '&amp;com_mode=' . $com_mode . '&amp;com_order=' . $com_order . '#comment' . $newcid;
519                /* @var  XoopsNotificationHandler $notification_handler */
520                $notification_handler          = xoops_getHandler('notification');
521                $notification_handler->triggerEvent($not_category, $not_itemid, $not_event, $comment_tags, false, $not_modid);
522            }
523            if (!isset($comment_post_results)) {
524                // if the comment is active, redirect to posted comment
525                if ($comment->getVar('com_status') == XOOPS_COMMENT_ACTIVE) {
526                    redirect_header($redirect_page . '=' . $com_itemid . '&amp;com_id=' . $newcid . '&amp;com_rootid=' . $com_rootid . '&amp;com_mode=' . $com_mode . '&amp;com_order=' . $com_order . '#comment' . $newcid, 1, _CM_THANKSPOST);
527                } else {
528                    // not active, so redirect to top comment page
529                    redirect_header($redirect_page . '=' . $com_itemid . '&amp;com_mode=' . $com_mode . '&amp;com_order=' . $com_order . '#comment' . $newcid, 1, _CM_THANKSPOST);
530                }
531            }
532        } else {
533            if (!isset($purge_comment_post_results)) {
534                include_once $GLOBALS['xoops']->path('header.php');
535                xoops_error($comment->getHtmlErrors());
536                include_once $GLOBALS['xoops']->path('footer.php');
537            } else {
538                $comment_post_results = $comment->getErrors();
539            }
540        }
541        break;
542    default:
543        redirect_header(XOOPS_URL . '/', 1, implode('<br>', $GLOBALS['xoopsSecurity']->getErrors()));
544        break;
545}
546