예제 #1
0
/**
 * Save a comment
 *
 * @author   Vincent Furia, vinny01 AT users DOT sourceforge DOT net
 * @param    string      $title      Title of comment
 * @param    string      $comment    Text of comment
 * @param    string      $sid        ID of object receiving comment
 * @param    int         $pid        ID of parent comment
 * @param    string      $type       Type of comment this is (article, polls, etc)
 * @param    string      $postmode   Indicates if text is HTML or plain text
 * @return   int         -1 == queued, 0 == comment saved, > 0 indicates error
 *
 */
function CMT_saveComment($title, $comment, $sid, $pid, $type, $postmode)
{
    global $_CONF, $_TABLES, $_USER, $LANG03;
    $ret = 0;
    // Get a valid uid
    if (empty($_USER['uid'])) {
        $uid = 1;
    } else {
        $uid = $_USER['uid'];
    }
    // Sanity check
    if (empty($sid) || empty($title) || empty($comment) || empty($type)) {
        COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to submit a comment with one or more missing values.');
        return $ret = 1;
    }
    // Check that anonymous comments are allowed
    if ($uid == 1 && ($_CONF['loginrequired'] == 1 || $_CONF['commentsloginrequired'] == 1)) {
        COM_errorLog("CMT_saveComment: IP address {$_SERVER['REMOTE_ADDR']} " . 'attempted to save a comment with anonymous comments disabled for site.');
        return $ret = 2;
    }
    // Check for people breaking the speed limit
    COM_clearSpeedlimit($_CONF['commentspeedlimit'], 'comment');
    $last = COM_checkSpeedlimit('comment');
    if ($last > 0) {
        COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to submit a comment before the speed limit expired');
        return $ret = 3;
    }
    // Let plugins have a chance to check for spam
    $spamcheck = '<h1>' . $title . '</h1><p>' . $comment . '</p>';
    $result = PLG_checkforSpam($spamcheck, $_CONF['spamx']);
    // Now check the result and display message if spam action was taken
    if ($result > 0) {
        // update speed limit nonetheless
        COM_updateSpeedlimit('comment');
        // then tell them to get lost ...
        COM_displayMessageAndAbort($result, 'spamx', 403, 'Forbidden');
    }
    // Let plugins have a chance to decide what to do before saving the comment, return errors.
    if ($someError = PLG_commentPreSave($uid, $title, $comment, $sid, $pid, $type, $postmode)) {
        return $someError;
    }
    $comment = addslashes(CMT_prepareText($comment, $postmode, $type));
    $title = addslashes(COM_checkWords(strip_tags($title)));
    if ($uid == 1 && isset($_POST['username'])) {
        $anon = COM_getDisplayName(1);
        if (strcmp($_POST['username'], $anon) != 0) {
            $username = COM_checkWords(strip_tags(COM_stripslashes($_POST['username'])));
            setcookie($_CONF['cookie_anon_name'], $username, time() + 31536000, $_CONF['cookie_path'], $_CONF['cookiedomain'], $_CONF['cookiesecure']);
            $name = addslashes($username);
        }
    }
    // check for non-int pid's
    // this should just create a top level comment that is a reply to the original item
    if (!is_numeric($pid) || $pid < 0) {
        $pid = 0;
    }
    COM_updateSpeedlimit('comment');
    if (empty($title) || empty($comment)) {
        COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to submit a comment with invalid $title and/or $comment.');
        $ret = 5;
    } elseif ($_CONF['commentsubmission'] == 1 && !SEC_hasRights('comment.submit')) {
        // comment into comment submission table enabled
        if (isset($name)) {
            DB_save($_TABLES['commentsubmissions'], 'sid,uid,name,comment,date,title,pid,ipaddress,type', "'{$sid}',{$uid},'{$name}','{$comment}',NOW(),'{$title}',{$pid},'{$_SERVER['REMOTE_ADDR']}','{$type}'");
        } else {
            DB_save($_TABLES['commentsubmissions'], 'sid,uid,comment,date,title,pid,ipaddress,type', "'{$sid}',{$uid},'{$comment}',NOW(),'{$title}',{$pid},'{$_SERVER['REMOTE_ADDR']}','{$type}'");
        }
        $ret = -1;
        // comment queued
    } elseif ($pid > 0) {
        DB_lockTable($_TABLES['comments']);
        $result = DB_query("SELECT rht, indent FROM {$_TABLES['comments']} WHERE cid = {$pid} " . "AND sid = '{$sid}'");
        list($rht, $indent) = DB_fetchArray($result);
        if (!DB_error()) {
            DB_query("UPDATE {$_TABLES['comments']} SET lft = lft + 2 " . "WHERE sid = '{$sid}' AND type = '{$type}' AND lft >= {$rht}");
            DB_query("UPDATE {$_TABLES['comments']} SET rht = rht + 2 " . "WHERE sid = '{$sid}' AND type = '{$type}' AND rht >= {$rht}");
            if (isset($name)) {
                DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress,name', "'{$sid}',{$uid},'{$comment}',now(),'{$title}',{$pid},{$rht},{$rht}+1,{$indent}+1,'{$type}','{$_SERVER['REMOTE_ADDR']}','{$name}'");
            } else {
                DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress', "'{$sid}',{$uid},'{$comment}',now(),'{$title}',{$pid},{$rht},{$rht}+1,{$indent}+1,'{$type}','{$_SERVER['REMOTE_ADDR']}'");
            }
        } else {
            //replying to non-existent comment or comment in wrong article
            COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to reply to a non-existent comment or the pid/sid did not match');
            $ret = 4;
            // Cannot return here, tables locked!
        }
    } else {
        $rht = DB_getItem($_TABLES['comments'], 'MAX(rht)', "sid = '{$sid}'");
        if (DB_error()) {
            $rht = 0;
        }
        if (isset($name)) {
            DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress,name', "'{$sid}',{$uid},'{$comment}',now(),'{$title}',{$pid},{$rht}+1,{$rht}+2,0,'{$type}','{$_SERVER['REMOTE_ADDR']}','{$name}'");
        } else {
            $rht = DB_getItem($_TABLES['comments'], 'MAX(rht)', "sid = '{$sid}'");
            if (DB_error()) {
                $rht = 0;
            }
            DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress', "'{$sid}',{$uid},'{$comment}',now(),'{$title}',{$pid},{$rht}+1,{$rht}+2,0,'{$type}','{$_SERVER['REMOTE_ADDR']}'");
        }
    }
    $cid = DB_insertId();
    DB_unlockTable($_TABLES['comments']);
    // notify of new comment
    if ($_CONF['allow_reply_notifications'] == 1 && $pid > 0 && $ret == 0) {
        $result = DB_query("SELECT cid, uid, deletehash FROM {$_TABLES['commentnotifications']} WHERE cid = {$pid}");
        $A = DB_fetchArray($result);
        if ($A !== false) {
            CMT_sendReplyNotification($A);
        }
    }
    // save user notification information
    if (isset($_POST['notify']) && ($ret == -1 || $ret == 0)) {
        $deletehash = md5($title . $cid . $comment . rand());
        if ($ret == -1) {
            //null goes into cid, comment not published yet, set moderation queue id
            DB_save($_TABLES['commentnotifications'], 'uid,deletehash,mid', "{$uid},'{$deletehash}',{$cid}");
        } else {
            DB_save($_TABLES['commentnotifications'], 'cid,uid,deletehash', "{$cid},{$uid},'{$deletehash}'");
        }
    }
    // Send notification of comment if no errors and notifications enabled
    // for comments
    if (($ret == -1 || $ret == 0) && isset($_CONF['notification']) && in_array('comment', $_CONF['notification'])) {
        if ($ret == -1) {
            $cid = 0;
            // comment went into the submission queue
        }
        if ($uid == 1 && isset($username)) {
            CMT_sendNotification($title, $comment, $uid, $username, $_SERVER['REMOTE_ADDR'], $type, $cid);
        } else {
            CMT_sendNotification($title, $comment, $uid, '', $_SERVER['REMOTE_ADDR'], $type, $cid);
        }
    }
    return $ret;
}
예제 #2
0
function MG_saveComment($title, $comment, $sid, $pid, $type, $postmode, $uid, $cmtdate, $ipaddress = '')
{
    global $_CONF, $_TABLES, $_USER, $_SERVER, $LANG03;
    USES_lib_comment();
    $ret = 0;
    // Sanity check
    if (empty($sid) || empty($title) || empty($comment) || empty($type)) {
        COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to submit a comment with one or more missing values.');
        return $ret = 1;
    }
    // Check that anonymous comments are allowed
    if ($uid == 1 && ($_CONF['loginrequired'] == 1 || $_CONF['commentsloginrequired'] == 1)) {
        COM_errorLog("CMT_saveComment: IP address {$_SERVER['REMOTE_ADDR']} " . 'attempted to save a comment with anonymous comments disabled for site.');
        return $ret = 2;
    }
    // Let plugins have a chance to decide what to do before saving the comment, return errors.
    if ($someError = PLG_commentPreSave($uid, $title, $comment, $sid, $pid, $type, $postmode)) {
        return $someError;
    }
    if ($ipaddress == '') {
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    }
    // Clean 'em up a bit!
    if ($postmode == 'html') {
        $comment = COM_checkWords(COM_checkHTML(DB_escapeString($comment)));
    } else {
        $comment = htmlspecialchars(COM_checkWords($comment));
        $newcomment = COM_makeClickableLinks($comment);
        if (strcmp($comment, $newcomment) != 0) {
            $comment = nl2br($newcomment);
            $postmode = 'html';
        }
    }
    $title = COM_checkWords(strip_tags($title));
    // Get signature
    $sig = '';
    if ($uid > 1) {
        $sig = DB_getItem($_TABLES['users'], 'sig', "uid = '{$uid}'");
    }
    if (!empty($sig)) {
        if ($postmode == 'html') {
            $comment .= '<p>---<br>' . nl2br($sig);
        } else {
            $comment .= LB . LB . '---' . LB . $sig;
        }
    }
    // check for non-int pid's
    // this should just create a top level comment that is a reply to the original item
    if (!is_numeric($pid) || $pid < 0) {
        $pid = 0;
    }
    if (!empty($title) && !empty($comment)) {
        $title = DB_escapeString($title);
        $comment = DB_escapeString($comment);
        // Insert the comment into the comment table
        DB_query("LOCK TABLES {$_TABLES['comments']} WRITE");
        if ($pid > 0) {
            $result = DB_query("SELECT rht, indent FROM {$_TABLES['comments']} WHERE cid = {$pid} " . "AND sid = '{$sid}'");
            list($rht, $indent) = DB_fetchArray($result);
            if (!DB_error()) {
                DB_query("UPDATE {$_TABLES['comments']} SET lft = lft + 2 " . "WHERE sid = '{$sid}' AND type = '{$type}' AND lft >= {$rht}");
                DB_query("UPDATE {$_TABLES['comments']} SET rht = rht + 2 " . "WHERE sid = '{$sid}' AND type = '{$type}' AND rht >= {$rht}");
                DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress', "'{$sid}',{$uid},'{$comment}','{$cmtdate}','{$title}',{$pid},{$rht},{$rht}+1,{$indent}+1,'{$type}','{$ipaddress}'");
            } else {
                //replying to non-existent comment or comment in wrong article
                COM_errorLog("CMT_saveComment: {$uid} from {$ipaddress} tried " . 'to reply to a non-existent comment or the pid/sid did not match');
                $ret = 4;
                // Cannot return here, tables locked!
            }
        } else {
            $rht = DB_getItem($_TABLES['comments'], 'MAX(rht)', "sid = '{$sid}'");
            if (DB_error()) {
                $rht = 0;
            }
            DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress', "'{$sid}',{$uid},'{$comment}','{$cmtdate}','{$title}',{$pid},{$rht}+1,{$rht}+2,0,'{$type}','{$ipaddress}'");
        }
        $cid = DB_insertId();
        DB_query('UNLOCK TABLES');
        // Send notification of comment if no errors and notications enabled for comments
        if ($ret == 0 && isset($_CONF['notification']) && in_array('comment', $_CONF['notification'])) {
            CMT_sendNotification($title, $comment, $uid, $ipaddress, $type, $cid);
        }
    } else {
        COM_errorLog("CMT_saveComment: {$uid} from {$ipaddress} tried " . 'to submit a comment with invalid $title and/or $comment.');
        return $ret = 5;
    }
    return $ret;
}
예제 #3
0
/**
 * Save a comment
 *
 * @author   Vincent Furia, vinny01 AT users DOT sourceforge DOT net
 * @param    string      $title      Title of comment
 * @param    string      $comment    Text of comment
 * @param    string      $sid        ID of object receiving comment
 * @param    int         $pid        ID of parent comment
 * @param    string      $type       Type of comment this is (article, polls, etc)
 * @param    string      $postmode   Indicates if text is HTML or plain text
 * @return   int         -1 == queued, 0 == comment saved, > 0 indicates error
 *
 */
function CMT_saveComment($title, $comment, $sid, $pid, $type, $postmode)
{
    global $_CONF, $_TABLES, $_USER, $LANG03;
    $ret = 0;
    $cid = 0;
    // Get a valid uid
    if (empty($_USER['uid'])) {
        $uid = 1;
    } else {
        $uid = $_USER['uid'];
    }
    // Sanity check
    if (empty($sid) || empty($title) || empty($comment) || empty($type)) {
        COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to submit a comment with one or more missing values.');
        return $ret = 1;
    }
    // Check that anonymous comments are allowed
    if ($uid == 1 && ($_CONF['loginrequired'] == 1 || $_CONF['commentsloginrequired'] == 1)) {
        COM_errorLog("CMT_saveComment: IP address {$_SERVER['REMOTE_ADDR']} " . 'attempted to save a comment with anonymous comments disabled for site.');
        return $ret = 2;
    }
    // Check for people breaking the speed limit
    COM_clearSpeedlimit($_CONF['commentspeedlimit'], 'comment');
    $last = COM_checkSpeedlimit('comment');
    if ($last > 0) {
        COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to submit a comment before the speed limit expired');
        return $ret = 3;
    }
    // Let plugins have a chance to check for spam
    $spamcheck = '<h1>' . $title . '</h1><p>' . $comment . '</p>';
    $result = PLG_checkforSpam($spamcheck, $_CONF['spamx']);
    // Now check the result and display message if spam action was taken
    if ($result > 0) {
        COM_updateSpeedlimit('comment');
        // update speed limit nonetheless
        COM_displayMessageAndAbort($result, 'spamx', 403, 'Forbidden');
        // then tell them to get lost ...
    }
    // Let plugins have a chance to decide what to do before saving the comment, return errors.
    if ($someError = PLG_commentPreSave($uid, $title, $comment, $sid, $pid, $type, $postmode)) {
        return $someError;
    }
    // Store unescaped comment and title for use in notification.
    $comment0 = CMT_prepareText($comment, $postmode, $type);
    $title0 = COM_checkWords(strip_tags($title));
    $comment = DB_escapeString($comment0);
    $title = DB_escapeString($title0);
    if ($uid == 1 && isset($_POST[CMT_USERNAME])) {
        $anon = COM_getDisplayName(1);
        if (strcmp($_POST[CMT_USERNAME], $anon) != 0) {
            $username = COM_checkWords(strip_tags(COM_stripslashes($_POST[CMT_USERNAME])));
            setcookie($_CONF['cookie_anon_name'], $username, time() + 31536000, $_CONF['cookie_path'], $_CONF['cookiedomain'], $_CONF['cookiesecure']);
            $name = DB_escapeString($username);
        }
    }
    // check for non-int pid's
    // this should just create a top level comment that is a reply to the original item
    if (!is_numeric($pid) || $pid < 0) {
        $pid = 0;
    }
    COM_updateSpeedlimit('comment');
    if (empty($title) || empty($comment)) {
        COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to submit a comment with invalid $title and/or $comment.');
        return $ret = 5;
    }
    if ($_CONF['commentsubmission'] == 1 && !SEC_hasRights('comment.submit')) {
        // comment into comment submission table enabled
        if (isset($name)) {
            DB_query("INSERT INTO {$_TABLES['commentsubmissions']} (sid,uid,name,comment,type,date,title,pid,ipaddress) " . "VALUES ('{$sid}',{$uid},'{$name}','{$comment}','{$type}',NOW(),'{$title}',{$pid},'{$_SERVER['REMOTE_ADDR']}')");
        } else {
            DB_query("INSERT INTO {$_TABLES['commentsubmissions']} (sid,uid,comment,type,date,title,pid,ipaddress) " . "VALUES ('{$sid}',{$uid},'{$comment}','{$type}',NOW(),'{$title}',{$pid},'{$_SERVER['REMOTE_ADDR']}')");
        }
        $cid = DB_insertId('', $_TABLES['commentsubmissions'] . '_cid_seq');
        $ret = -1;
        // comment queued
    } elseif ($pid > 0) {
        DB_lockTable($_TABLES['comments']);
        $result = DB_query("SELECT rht, indent FROM {$_TABLES['comments']} WHERE cid = {$pid} AND sid = '{$sid}'");
        list($rht, $indent) = DB_fetchArray($result);
        if (!DB_error()) {
            $rht2 = $rht + 1;
            $indent += 1;
            DB_query("UPDATE {$_TABLES['comments']} SET lft = lft + 2 " . "WHERE sid = '{$sid}' AND type = '{$type}' AND lft >= {$rht}");
            DB_query("UPDATE {$_TABLES['comments']} SET rht = rht + 2 " . "WHERE sid = '{$sid}' AND type = '{$type}' AND rht >= {$rht}");
            if (isset($name)) {
                DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress,name', "'{$sid}',{$uid},'{$comment}',now(),'{$title}',{$pid},{$rht},{$rht2},{$indent},'{$type}','{$_SERVER['REMOTE_ADDR']}','{$name}'");
            } else {
                DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress', "'{$sid}',{$uid},'{$comment}',now(),'{$title}',{$pid},{$rht},{$rht2},{$indent},'{$type}','{$_SERVER['REMOTE_ADDR']}'");
            }
            $cid = DB_insertId('', $_TABLES['comments'] . '_cid_seq');
        } else {
            //replying to non-existent comment or comment in wrong article
            COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to reply to a non-existent comment or the pid/sid did not match');
            $ret = 4;
            // Cannot return here, tables locked!
        }
        DB_unlockTable($_TABLES['comments']);
        // Update Comment Feeds
        COM_rdfUpToDateCheck('comment');
        // Delete What's New block cache so it can get updated again
        if ($_CONF['whatsnew_cache_time'] > 0 and !$_CONF['hidenewcomments']) {
            $cacheInstance = 'whatsnew__';
            // remove all whatsnew instances
            CACHE_remove_instance($cacheInstance);
        }
        // notify parent of new comment
        // Must occur after table unlock, only with valid $cid and $pid
        // NOTE: This could be modified to send notifications to all parents in the comment tree
        //       with only a modification to the below SELECT statement
        //       See: http://wiki.geeklog.net/index.php/CommentAlgorithm
        if ($_CONF['allow_reply_notifications'] == 1 && $cid > 0 && $pid > 0) {
            // $sql = "SELECT cid, uid, deletehash FROM {$_TABLES['commentnotifications']} WHERE cid = $pid"; // Used in Geeklog 2.0.0 and before. Notification sent only if someone directly replies to the comment (not a reply of a reply)
            $sql = "SELECT cn.cid, cn.uid, cn.deletehash " . "FROM {$_TABLES['comments']} AS c, {$_TABLES['comments']} AS c2, " . "{$_TABLES['commentnotifications']} AS cn " . "WHERE c2.cid = cn.cid AND (c.lft >= c2.lft AND c.lft <= c2.rht) " . "AND c.cid = {$pid} GROUP BY cn.uid";
            $result = DB_query($sql);
            $A = DB_fetchArray($result);
            if ($A !== false) {
                CMT_sendReplyNotification($A);
            }
        }
    } else {
        DB_lockTable($_TABLES['comments']);
        $rht = DB_getItem($_TABLES['comments'], 'MAX(rht)', "sid = '{$sid}'");
        if (DB_error()) {
            $rht = 0;
        }
        $rht2 = $rht + 1;
        // value of new comment's "lft"
        $rht3 = $rht + 2;
        // value of new comment's "rht"
        if (isset($name)) {
            DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress,name', "'{$sid}',{$uid},'{$comment}',now(),'{$title}',{$pid},{$rht2},{$rht3},0,'{$type}','{$_SERVER['REMOTE_ADDR']}','{$name}'");
        } else {
            DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress', "'{$sid}',{$uid},'{$comment}',now(),'{$title}',{$pid},{$rht2},{$rht3},0,'{$type}','{$_SERVER['REMOTE_ADDR']}'");
        }
        $cid = DB_insertId('', $_TABLES['comments'] . '_cid_seq');
        DB_unlockTable($_TABLES['comments']);
        // Update Comment Feeds
        COM_rdfUpToDateCheck('comment');
        // Delete What's New block cache so it can get updated again
        if ($_CONF['whatsnew_cache_time'] > 0 and !$_CONF['hidenewcomments']) {
            $cacheInstance = 'whatsnew__';
            // remove all whatsnew instances
            CACHE_remove_instance($cacheInstance);
        }
    }
    // save user notification information
    if (isset($_POST['notify']) && ($ret == -1 || $ret == 0)) {
        $cid4hash = $cid == 0 ? '' : $cid;
        $cid4db = $cid == 0 ? null : $cid;
        $deletehash = md5($title . $cid4hash . $comment . rand());
        if ($ret == -1) {
            //null goes into cid, comment not published yet, set moderation queue id
            DB_save($_TABLES['commentnotifications'], 'uid,deletehash,mid', "{$uid},'{$deletehash}',{$cid4db}");
        } else {
            DB_save($_TABLES['commentnotifications'], 'cid,uid,deletehash', "{$cid4db},{$uid},'{$deletehash}'");
        }
    }
    // Send notification of comment if no errors and notifications enabled
    // for comments
    if (($ret == -1 || $ret == 0) && isset($_CONF['notification']) && in_array('comment', $_CONF['notification'])) {
        if ($ret == -1) {
            $cid = 0;
            // comment went into the submission queue
        }
        if ($uid == 1 && isset($username)) {
            CMT_sendNotification($title0, $comment0, $uid, $username, $_SERVER['REMOTE_ADDR'], $type, $cid);
        } else {
            CMT_sendNotification($title0, $comment0, $uid, '', $_SERVER['REMOTE_ADDR'], $type, $cid);
        }
    }
    return $ret;
}
예제 #4
0
/**
 * Save a comment
 *
 * @author   Vincent Furia, vinny01 AT users DOT sourceforge DOT net
 * @param    string      $title      Title of comment
 * @param    string      $comment    Text of comment
 * @param    string      $sid        ID of object receiving comment
 * @param    int         $pid        ID of parent comment
 * @param    string      $type       Type of comment this is (article, polls, etc)
 * @param    string      $postmode   Indicates if text is HTML or plain text
 * @return   int         0 for success, > 0 indicates error
 *
 */
function CMT_saveComment($title, $comment, $sid, $pid, $type, $postmode)
{
    global $_CONF, $_TABLES, $_USER, $LANG03;
    $ret = 0;
    // Get a valid uid
    if (empty($_USER['uid'])) {
        $uid = 1;
    } else {
        $uid = $_USER['uid'];
    }
    // Sanity check
    if (empty($sid) || empty($title) || empty($comment) || empty($type)) {
        COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to submit a comment with one or more missing values.');
        if (SESS_isSet('glfusion.commentpresave.error')) {
            $msg = SESS_getVar('glfusion.commentpresave.error') . '<br/>' . $LANG03[12];
        } else {
            $msg = $LANG03[12];
        }
        SESS_setVar('glfusion.commentpresave.error', $msg);
        return $ret = 1;
    }
    // Check that anonymous comments are allowed
    if ($uid == 1 && ($_CONF['loginrequired'] == 1 || $_CONF['commentsloginrequired'] == 1)) {
        COM_errorLog("CMT_saveComment: IP address {$_SERVER['REMOTE_ADDR']} " . 'attempted to save a comment with anonymous comments disabled for site.');
        return $ret = 2;
    }
    // Check for people breaking the speed limit
    COM_clearSpeedlimit($_CONF['commentspeedlimit'], 'comment');
    $last = COM_checkSpeedlimit('comment');
    if ($last > 0) {
        COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to submit a comment before the speed limit expired');
        return $ret = 3;
    }
    // Let plugins have a chance to check for spam
    $spamcheck = '<h1>' . $title . '</h1><p>' . $comment . '</p>';
    $result = PLG_checkforSpam($spamcheck, $_CONF['spamx']);
    // Now check the result and display message if spam action was taken
    if ($result > 0) {
        // update speed limit nonetheless
        COM_updateSpeedlimit('comment');
        // then tell them to get lost ...
        COM_displayMessageAndAbort($result, 'spamx', 403, 'Forbidden');
    }
    // Let plugins have a chance to decide what to do before saving the comment, return errors.
    if ($someError = PLG_commentPreSave($uid, $title, $comment, $sid, $pid, $type, $postmode)) {
        return $someError;
    }
    $title = COM_checkWords(strip_tags($title));
    $comment = CMT_prepareText($comment, $postmode);
    // check for non-int pid's
    // this should just create a top level comment that is a reply to the original item
    if (!is_numeric($pid) || $pid < 0) {
        $pid = 0;
    }
    if (!empty($title) && !empty($comment)) {
        COM_updateSpeedlimit('comment');
        $title = DB_escapeString($title);
        $comment = DB_escapeString($comment);
        $type = DB_escapeString($type);
        // Insert the comment into the comment table
        DB_lockTable($_TABLES['comments']);
        if ($pid > 0) {
            $result = DB_query("SELECT rht, indent FROM {$_TABLES['comments']} WHERE cid = " . (int) $pid . " AND sid = '" . DB_escapeString($sid) . "'");
            list($rht, $indent) = DB_fetchArray($result);
            if (!DB_error()) {
                DB_query("UPDATE {$_TABLES['comments']} SET lft = lft + 2 " . "WHERE sid = '" . DB_escapeString($sid) . "' AND type = '{$type}' AND lft >= {$rht}");
                DB_query("UPDATE {$_TABLES['comments']} SET rht = rht + 2 " . "WHERE sid = '" . DB_escapeString($sid) . "' AND type = '{$type}' AND rht >= {$rht}");
                DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress', "'" . DB_escapeString($sid) . "',{$uid},'{$comment}',now(),'{$title}'," . (int) $pid . ",{$rht},{$rht}+1,{$indent}+1,'{$type}','" . DB_escapeString($_SERVER['REMOTE_ADDR']) . "'");
            } else {
                //replying to non-existent comment or comment in wrong article
                COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to reply to a non-existent comment or the pid/sid did not match');
                $ret = 4;
                // Cannot return here, tables locked!
            }
        } else {
            $rht = DB_getItem($_TABLES['comments'], 'MAX(rht)', "sid = '" . DB_escapeString($sid) . "'");
            if (DB_error()) {
                $rht = 0;
            }
            DB_save($_TABLES['comments'], 'sid,uid,comment,date,title,pid,lft,rht,indent,type,ipaddress', "'" . DB_escapeString($sid) . "'," . (int) $uid . ",'{$comment}',now(),'{$title}'," . (int) $pid . ",{$rht}+1,{$rht}+2,0,'{$type}','" . DB_escapeString($_SERVER['REMOTE_ADDR']) . "'");
        }
        $cid = DB_insertId();
        //set Anonymous user name if present
        if (isset($_POST['username'])) {
            $name = strip_tags(USER_sanitizeName($_POST['username']));
            DB_change($_TABLES['comments'], 'name', DB_escapeString($name), 'cid', (int) $cid);
        }
        DB_unlockTable($_TABLES['comments']);
        CACHE_remove_instance('whatsnew');
        if ($type == 'article') {
            CACHE_remove_instance('story_' . $sid);
        }
        // check to see if user has subscribed....
        if (!COM_isAnonUser()) {
            if (isset($_POST['subscribe']) && $_POST['subscribe'] == 1) {
                $itemInfo = PLG_getItemInfo($type, $sid, 'url,title');
                if (isset($itemInfo['title'])) {
                    $id_desc = $itemInfo['title'];
                } else {
                    $id_desc = 'not defined';
                }
                $rc = PLG_subscribe('comment', $type, $sid, $uid, $type, $id_desc);
            } else {
                PLG_unsubscribe('comment', $type, $sid);
            }
        }
        // Send notification of comment if no errors and notications enabled for comments
        if ($ret == 0 && isset($_CONF['notification']) && in_array('comment', $_CONF['notification'])) {
            CMT_sendNotification($title, $comment, $uid, $_SERVER['REMOTE_ADDR'], $type, $cid);
        }
        if ($ret == 0) {
            PLG_sendSubscriptionNotification('comment', $type, $sid, $cid, $uid);
        }
    } else {
        COM_errorLog("CMT_saveComment: {$uid} from {$_SERVER['REMOTE_ADDR']} tried " . 'to submit a comment with invalid $title and/or $comment.');
        return $ret = 5;
    }
    return $ret;
}