4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5 * Copyright (C) 2002-2009 The Nucleus Group
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 * (see nucleus/documentation/index.html#license for more info)
14 * A class representing the comments (all of them) for a certain post on a ceratin blog
16 * @license http://nucleuscms.org/license.txt GNU General Public License
17 * @copyright Copyright (C) 2002-2009 The Nucleus Group
18 * @version $Id: COMMENTS.php 1527 2011-06-21 10:43:44Z sakamocchi $
21 if ( !function_exists('requestVar') ) exit;
22 require_once dirname(__FILE__) . '/COMMENTACTIONS.php';
26 // item for which comment are being displayed
29 // reference to the itemActions object that is calling the showComments function
32 // total amount of comments displayed
36 * Creates a new COMMENTS object for the given blog and item
41 function COMMENTS($itemid) {
42 $this->itemid = intval($itemid);
46 * Used when parsing comments
49 * itemActions object, that will take care of the parsing
51 function setItemActions(&$itemActions) {
52 $this->itemActions =& $itemActions;
56 * Shows maximum $max comments to the given item using the given template
57 * returns the amount of shown comments (if maxToShow = -1, then there is no limit)
62 * max. comments to show
64 * indicates if the 'no comments' thingie should be outputted when there are no comments
65 * (useful for closed items)
67 * Highlight to use (if any)
69 function showComments($template, $maxToShow = -1, $showNone = 1, $highlight = '') {
70 global $CONF, $manager;
72 // create parser object & action handler
73 $actions = new COMMENTACTIONS($this);
74 $parser = new PARSER($actions->getDefinedActions(),$actions);
75 $actions->setTemplate($template);
76 $actions->setParser($parser);
78 if ($maxToShow == 0) {
79 $this->commentcount = $this->amountComments();
81 $query = 'SELECT c.citem as itemid, c.cnumber as commentid, c.cbody as body, c.cuser as user, c.cmail as userid, c.cemail as email, c.cmember as memberid, c.ctime, c.chost as host, c.cip as ip, c.cblog as blogid'
82 . ' FROM '.sql_table('comment').' as c'
83 . ' WHERE c.citem=' . $this->itemid
84 . ' ORDER BY c.ctime';
86 $comments = sql_query($query);
87 $this->commentcount = sql_num_rows($comments);
90 // if no result was found
91 if ($this->commentcount == 0) {
92 // note: when no reactions, COMMENTS_HEADER and COMMENTS_FOOTER are _NOT_ used
93 if ($showNone) $parser->parse($template['COMMENTS_NONE']);
97 // if too many comments to show
98 if (($maxToShow != -1) && ($this->commentcount > $maxToShow)) {
99 $parser->parse($template['COMMENTS_TOOMUCH']);
103 $parser->parse($template['COMMENTS_HEADER']);
105 while ( $comment = sql_fetch_assoc($comments) ) {
106 $comment['timestamp'] = strtotime($comment['ctime']);
107 $actions->setCurrentComment($comment);
108 $actions->setHighlight($highlight);
109 $manager->notify('PreComment', array('comment' => &$comment));
110 $parser->parse($template['COMMENTS_BODY']);
111 $manager->notify('PostComment', array('comment' => &$comment));
114 $parser->parse($template['COMMENTS_FOOTER']);
116 sql_free_result($comments);
118 return $this->commentcount;
122 * Returns the amount of comments for this itemid
124 function amountComments() {
125 $query = 'SELECT COUNT(*)'
126 . ' FROM '.sql_table('comment').' as c'
127 . ' WHERE c.citem='. $this->itemid;
128 $res = sql_query($query);
129 $arr = sql_fetch_row($res);
135 * Adds a new comment to the database
136 * @param string $timestamp
137 * @param array $comment
140 function addComment($timestamp, $comment)
142 global $CONF, $member, $manager;
144 $blogid = getBlogIDFromItemID($this->itemid);
146 $settings =& $manager->getBlog($blogid);
147 $settings->readSettings();
149 // begin if: comments disabled
150 if ( !$settings->commentsEnabled() )
152 return _ERROR_COMMENTS_DISABLED;
155 // begin if: public cannot comment
156 if ( !$settings->isPublic() && !$member->isLoggedIn() )
158 return _ERROR_COMMENTS_NONPUBLIC;
161 // begin if: comment uses a protected member name
162 if ( $CONF['ProtectMemNames'] && !$member->isLoggedIn() && MEMBER::isNameProtected($comment['user']) )
164 return _ERROR_COMMENTS_MEMBERNICK;
167 // begin if: email required, but missing (doesn't apply to members)
168 if ( $settings->emailRequired() && i18n::strlen($comment['email']) == 0 && !$member->isLoggedIn() )
170 return _ERROR_EMAIL_REQUIRED;
173 // begin if: commenter's name is too long
174 if ( i18n::strlen($comment['user']) > 40 )
176 return _ERROR_USER_TOO_LONG;
179 // begin if: commenter's email is too long
180 if ( i18n::strlen($comment['email']) > 100 )
182 return _ERROR_EMAIL_TOO_LONG;
185 // begin if: commenter's url is too long
186 if ( i18n::strlen($comment['userid']) > 100 )
188 return _ERROR_URL_TOO_LONG;
191 $comment['timestamp'] = $timestamp;
192 $comment['host'] = gethostbyaddr(serverVar('REMOTE_ADDR') );
193 $comment['ip'] = serverVar('REMOTE_ADDR');
195 // begin if: member is logged in, use that data
196 if ( $member->isLoggedIn() )
198 $comment['memberid'] = $member->getID();
199 $comment['user'] = '';
200 $comment['userid'] = '';
201 $comment['email'] = '';
205 $comment['memberid'] = 0;
212 if ( isset($manager->subscriptions['ValidateForm']) )
214 $plugins = array_merge($plugins, $manager->subscriptions['ValidateForm']);
217 if ( isset($manager->subscriptions['PreAddComment']) )
219 $plugins = array_merge($plugins, $manager->subscriptions['PreAddComment']);
222 if ( isset($manager->subscriptions['PostAddComment']) )
224 $plugins = array_merge($plugins, $manager->subscriptions['PostAddComment']);
227 $plugins = array_unique($plugins);
229 while ( list(, $plugin) = each($plugins) )
231 $p = $manager->getPlugin($plugin);
232 $continue = $continue || $p->supportsFeature('handleSpam');
237 'body' => $comment['body'],
238 'id' => $comment['itemid'],
240 'return' => $continue
243 // begin if: member logged in
244 if ( $member->isLoggedIn() )
246 $spamcheck['author'] = $member->displayname;
247 $spamcheck['email'] = $member->email;
252 $spamcheck['author'] = $comment['user'];
253 $spamcheck['email'] = $comment['email'];
254 $spamcheck['url'] = $comment['userid'];
257 $manager->notify('SpamCheck', array('spamcheck' => &$spamcheck) );
259 if ( !$continue && isset($spamcheck['result']) && $spamcheck['result'] == TRUE )
261 return _ERROR_COMMENTS_SPAM;
264 // isValidComment returns either "1" or an error message
265 $isvalid = $this->isValidComment($comment, $spamcheck);
272 // begin if: send email to notification address
273 if ( $settings->getNotifyAddress() && $settings->notifyOnComment() )
276 $mailto_msg = _NOTIFY_NC_MSG . ' ' . $this->itemid . "\n";
277 // $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $this->itemid . "\n\n";
278 $temp = parse_url($CONF['Self']);
280 if ( $temp['scheme'] )
282 $mailto_msg .= createItemLink($this->itemid) . "\n\n";
286 $tempurl = $settings->getURL();
288 if ( i18n::substr($tempurl, -1) == '/' || i18n::substr($tempurl, -4) == '.php' )
290 $mailto_msg .= $tempurl . '?itemid=' . $this->itemid . "\n\n";
294 $mailto_msg .= $tempurl . '/?itemid=' . $this->itemid . "\n\n";
298 if ( $comment['memberid'] == 0 )
300 $mailto_msg .= _NOTIFY_USER . ' ' . $comment['user'] . "\n";
301 $mailto_msg .= _NOTIFY_USERID . ' ' . $comment['userid'] . "\n";
305 $mailto_msg .= _NOTIFY_MEMBER .' ' . $member->getDisplayName() . ' (ID=' . $member->getID() . ")\n";
308 $mailto_msg .= _NOTIFY_HOST . ' ' . $comment['host'] . "\n";
309 $mailto_msg .= _NOTIFY_COMMENT . "\n " . $comment['body'] . "\n";
310 $mailto_msg .= getMailFooter();
312 $item =& $manager->getItem($this->itemid, 0, 0);
313 $mailto_title = _NOTIFY_NC_TITLE . ' ' . strip_tags($item['title']) . ' (' . $this->itemid . ')';
315 $frommail = $member->getNotifyFromMailAddress($comment['email']);
317 $notify = new NOTIFICATION($settings->getNotifyAddress() );
318 $notify->notify($mailto_title, $mailto_msg , $frommail);
321 $comment = COMMENT::prepare($comment);
323 $manager->notify('PreAddComment', array('comment' => &$comment, 'spamcheck' => &$spamcheck) );
325 $name = sql_real_escape_string($comment['user']);
326 $url = sql_real_escape_string($comment['userid']);
327 $email = sql_real_escape_string($comment['email']);
328 $body = sql_real_escape_string($comment['body']);
329 $host = sql_real_escape_string($comment['host']);
330 $ip = sql_real_escape_string($comment['ip']);
331 $memberid = intval($comment['memberid']);
332 $timestamp = date('Y-m-d H:i:s', $comment['timestamp']);
333 $itemid = $this->itemid;
335 $qSql = 'SELECT COUNT(*) AS result '
336 . 'FROM ' . sql_table('comment')
338 . 'cmail = "' . $url . '"'
339 . ' AND cmember = "' . $memberid . '"'
340 . ' AND cbody = "' . $body . '"'
341 . ' AND citem = "' . $itemid . '"'
342 . ' AND cblog = "' . $blogid . '"';
343 $result = (integer) quickQuery($qSql);
347 return _ERROR_BADACTION;
350 $query = 'INSERT INTO '.sql_table('comment').' (CUSER, CMAIL, CEMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CIP, CBLOG) '
351 . "VALUES ('$name', '$url', '$email', $memberid, '$body', $itemid, '$timestamp', '$host', '$ip', '$blogid')";
356 $commentid = sql_insert_id();
357 $manager->notify('PostAddComment', array('comment' => &$comment, 'commentid' => &$commentid, 'spamcheck' => &$spamcheck) );
365 * Checks if a comment is valid and call plugins
366 * that can check if the comment is a spam comment
368 function isValidComment(&$comment, &$spamcheck) {
370 global $member, $manager;
372 // check if there exists a item for this date
373 $item =& $manager->getItem($this->itemid, 0, 0);
377 return _ERROR_NOSUCHITEM;
382 return _ERROR_ITEMCLOSED;
385 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
386 # original eregi comparison: eregi('[a-zA-Z0-9|\.,;:!\?=\/\\]{90,90}', $comment['body']) != FALSE
388 // don't allow words that are too long
389 if (preg_match('/[a-zA-Z0-9|\.,;:!\?=\/\\\\]{90,90}/', $comment['body']) != 0)
391 return _ERROR_COMMENT_LONGWORD;
394 // check lengths of comment
395 if (i18n::strlen($comment['body']) < 3)
397 return _ERROR_COMMENT_NOCOMMENT;
400 if (i18n::strlen($comment['body']) > 5000)
402 return _ERROR_COMMENT_TOOLONG;
405 // only check username if no member logged in
406 if (!$member->isLoggedIn() )
409 if (i18n::strlen($comment['user']) < 2)
411 return _ERROR_COMMENT_NOUSERNAME;
416 if ((i18n::strlen($comment['email']) != 0) && !(isValidMailAddress(trim($comment['email']) ) ) )
418 return _ERROR_BADMAILADDRESS;
421 // let plugins do verification (any plugin which thinks the comment is invalid
422 // can change 'error' to something other than '1')
424 $manager->notify('ValidateForm', array('type' => 'comment', 'comment' => &$comment, 'error' => &$result, 'spamcheck' => &$spamcheck) );