OSDN Git Service

92adf96641265b155950a412f84c37007239bf53
[nucleus-jp/nucleus-jp-ancient.git] / nucleus / libs / COMMENTS.php
1 <?php
2
3 /*
4  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5  * Copyright (C) 2002-2011 The Nucleus Group
6  *
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)
12  */
13 /**
14  * A class representing the comments (all of them) for a certain post on a ceratin blog
15  *
16  * @license http://nucleuscms.org/license.txt GNU General Public License
17  * @copyright Copyright (C) 2002-2011 The Nucleus Group
18  * @version $Id$
19  */
20
21 if ( !function_exists('requestVar') ) exit;
22 require_once dirname(__FILE__) . '/COMMENTACTIONS.php';
23
24 class COMMENTS {
25
26         // item for which comment are being displayed
27         var $itemid;
28
29         // reference to the itemActions object that is calling the showComments function
30         var $itemActions;
31
32         // total amount of comments displayed
33         var $commentcount;
34
35         /**
36          * Creates a new COMMENTS object for the given blog and item
37          *
38          * @param $itemid
39          *              id of the item
40          */
41         function COMMENTS($itemid) {
42                 $this->itemid = intval($itemid);
43         }
44         
45         /**
46          * Used when parsing comments
47          *
48          * @param $itemActions
49          *              itemActions object, that will take care of the parsing
50          */
51         function setItemActions(&$itemActions) {
52                 $this->itemActions =& $itemActions;
53         }
54
55         /**
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)
58          *
59          * @param template
60          *              template to use
61          * @param maxToShow
62          *              max. comments to show
63          * @param showNone
64          *              indicates if the 'no comments' thingie should be outputted when there are no comments
65          *              (useful for closed items)
66          * @param highlight
67          *              Highlight to use (if any)
68          */
69         function showComments($template, $maxToShow = -1, $showNone = 1, $highlight = '') {
70                 global $CONF, $manager;
71
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);
77
78                 if ($maxToShow == 0) {
79                         $this->commentcount = $this->amountComments();
80                 } else {
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';
85
86                         $comments = sql_query($query);
87                         $this->commentcount = sql_num_rows($comments);
88                 }
89
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']);
94                         return 0;
95                 }
96
97                 // if too many comments to show
98                 if (($maxToShow != -1) && ($this->commentcount > $maxToShow)) {
99                         $parser->parse($template['COMMENTS_TOOMUCH']);
100                         return 0;
101                 }
102
103                 $parser->parse($template['COMMENTS_HEADER']);
104
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));
112                 }
113
114                 $parser->parse($template['COMMENTS_FOOTER']);
115
116                 sql_free_result($comments);
117
118                 return $this->commentcount;
119         }
120
121         /**
122          * Returns the amount of comments for this itemid
123          */
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);
130
131                 return $arr[0];
132         }
133
134         /**
135          * Adds a new comment to the database
136          * @param string $timestamp
137          * @param array $comment
138          * @return mixed
139          */
140         function addComment($timestamp, $comment)
141         {
142                 global $CONF, $member, $manager;
143
144                 $blogid = getBlogIDFromItemID($this->itemid);
145
146                 $settings =& $manager->getBlog($blogid);
147                 $settings->readSettings();
148
149                 // begin if: comments disabled
150                 if ( !$settings->commentsEnabled() )
151                 {
152                         return _ERROR_COMMENTS_DISABLED;
153                 } // end if
154
155                 // begin if: public cannot comment
156                 if ( !$settings->isPublic() && !$member->isLoggedIn() )
157                 {
158                         return _ERROR_COMMENTS_NONPUBLIC;
159                 } // end if
160
161                 // begin if: comment uses a protected member name
162                 if ( $CONF['ProtectMemNames'] && !$member->isLoggedIn() && MEMBER::isNameProtected($comment['user']) )
163                 {
164                         return _ERROR_COMMENTS_MEMBERNICK;
165                 } // end if
166
167                 // begin if: email required, but missing (doesn't apply to members)
168                 if ( $settings->emailRequired() && strlen($comment['email']) == 0 && !$member->isLoggedIn() )
169                 {
170                         return _ERROR_EMAIL_REQUIRED;
171                 } // end if
172
173                 ## Note usage of mb_strlen() vs strlen() below ##
174
175                 // begin if: commenter's name is too long
176                 if ( mb_strlen($comment['user']) > 40 )
177                 {
178                         return _ERROR_USER_TOO_LONG;
179                 } // end if
180
181                 // begin if: commenter's email is too long
182                 if ( mb_strlen($comment['email']) > 100 )
183                 {
184                         return _ERROR_EMAIL_TOO_LONG;
185                 } // end if
186
187                 // begin if: commenter's url is too long
188                 if ( mb_strlen($comment['userid']) > 100 )
189                 {
190                         return _ERROR_URL_TOO_LONG;
191                 } // end if
192
193                 $comment['timestamp'] = $timestamp;
194                 $comment['host'] = gethostbyaddr(serverVar('REMOTE_ADDR') );
195                 $comment['ip'] = serverVar('REMOTE_ADDR');
196
197                 // begin if: member is logged in, use that data
198                 if ( $member->isLoggedIn() )
199                 {
200                         $comment['memberid'] = $member->getID();
201                         $comment['user'] = '';
202                         $comment['userid'] = '';
203                         $comment['email'] = '';
204                 }
205                 else
206                 {
207                         $comment['memberid'] = 0;
208                 }
209
210                 // spam check
211                 $continue = FALSE;
212                 $plugins = array();
213
214                 if ( isset($manager->subscriptions['ValidateForm']) )
215                 {
216                         $plugins = array_merge($plugins, $manager->subscriptions['ValidateForm']);
217                 }
218
219                 if ( isset($manager->subscriptions['PreAddComment']) )
220                 {
221                         $plugins = array_merge($plugins, $manager->subscriptions['PreAddComment']);
222                 }
223
224                 if ( isset($manager->subscriptions['PostAddComment']) )
225                 {
226                         $plugins = array_merge($plugins, $manager->subscriptions['PostAddComment']);
227                 }
228
229                 $plugins = array_unique($plugins);
230
231                 while ( list(, $plugin) = each($plugins) )
232                 {
233                         $p = $manager->getPlugin($plugin);
234                         $continue = $continue || $p->supportsFeature('handleSpam');
235                 }
236
237                 $spamcheck = array(
238                         'type'          => 'comment',
239                         'body'          => $comment['body'],
240                         'id'        => $comment['itemid'],
241                         'live'          => TRUE,
242                         'return'        => $continue
243                 );
244
245                 // begin if: member logged in
246                 if ( $member->isLoggedIn() )
247                 {
248                         $spamcheck['author'] = $member->displayname;
249                         $spamcheck['email'] = $member->email;
250                 }
251                 // else: public
252                 else
253                 {
254                         $spamcheck['author'] = $comment['user'];
255                         $spamcheck['email'] = $comment['email'];
256                         $spamcheck['url'] = $comment['userid'];
257                 } // end if
258
259                 $manager->notify('SpamCheck', array('spamcheck' => &$spamcheck) );
260
261                 if ( !$continue && isset($spamcheck['result']) && $spamcheck['result'] == TRUE )
262                 {
263                         return _ERROR_COMMENTS_SPAM;
264                 }
265
266                 // isValidComment returns either "1" or an error message
267                 $isvalid = $this->isValidComment($comment, $spamcheck);
268
269                 if ( $isvalid != 1 )
270                 {
271                         return $isvalid;
272                 }
273
274                 // begin if: send email to notification address
275                 if ( $settings->getNotifyAddress() && $settings->notifyOnComment() )
276                 {
277
278                         $mailto_msg = _NOTIFY_NC_MSG . ' ' . $this->itemid . "\n";
279 //                      $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $this->itemid . "\n\n";
280                         $temp = parse_url($CONF['Self']);
281
282                         if ( $temp['scheme'] )
283                         {
284                                 $mailto_msg .= createItemLink($this->itemid) . "\n\n";
285                         }
286                         else
287                         {
288                                 $tempurl = $settings->getURL();
289
290                                 if ( substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php' )
291                                 {
292                                         $mailto_msg .= $tempurl . '?itemid=' . $this->itemid . "\n\n";
293                                 }
294                                 else
295                                 {
296                                         $mailto_msg .= $tempurl . '/?itemid=' . $this->itemid . "\n\n";
297                                 }
298                         }
299
300                         if ( $comment['memberid'] == 0 )
301                         {
302                                 $mailto_msg .= _NOTIFY_USER . ' ' . $comment['user'] . "\n";
303                                 $mailto_msg .= _NOTIFY_USERID . ' ' . $comment['userid'] . "\n";
304                         }
305                         else
306                         {
307                                 $mailto_msg .= _NOTIFY_MEMBER .' ' . $member->getDisplayName() . ' (ID=' . $member->getID() . ")\n";
308                         }
309
310                         $mailto_msg .= _NOTIFY_HOST . ' ' . $comment['host'] . "\n";
311                         $mailto_msg .= _NOTIFY_COMMENT . "\n " . $comment['body'] . "\n";
312                         $mailto_msg .= getMailFooter();
313
314                         $item =& $manager->getItem($this->itemid, 0, 0);
315                         $mailto_title = _NOTIFY_NC_TITLE . ' ' . strip_tags($item['title']) . ' (' . $this->itemid . ')';
316
317                         $frommail = $member->getNotifyFromMailAddress($comment['email']);
318
319                         $notify =& new NOTIFICATION($settings->getNotifyAddress() );
320                         $notify->notify($mailto_title, $mailto_msg , $frommail);
321                 }
322
323                 $comment = COMMENT::prepare($comment);
324
325                 $manager->notify('PreAddComment', array('comment' => &$comment, 'spamcheck' => &$spamcheck) );
326
327                 $name           = sql_real_escape_string($comment['user']);
328                 $url            = sql_real_escape_string($comment['userid']);
329                 $email      = sql_real_escape_string($comment['email']);
330                 $body           = sql_real_escape_string($comment['body']);
331                 $host           = sql_real_escape_string($comment['host']);
332                 $ip                     = sql_real_escape_string($comment['ip']);
333                 $memberid       = intval($comment['memberid']);
334                 $timestamp      = date('Y-m-d H:i:s', $comment['timestamp']);
335                 $itemid         = $this->itemid;
336
337                 $qSql       = 'SELECT COUNT(*) AS result '
338                                         . 'FROM ' . sql_table('comment')
339                                         . ' WHERE '
340                                         .      'cmail   = "' . $url . '"'
341                                         . ' AND cmember = "' . $memberid . '"'
342                                         . ' AND cbody   = "' . $body . '"'
343                                         . ' AND citem   = "' . $itemid . '"'
344                                         . ' AND cblog   = "' . $blogid . '"';
345                 $result     = (integer) quickQuery($qSql);
346
347                 if ( $result > 0 )
348                 {
349                         return _ERROR_BADACTION;
350                 }
351
352                 $query = 'INSERT INTO '.sql_table('comment').' (CUSER, CMAIL, CEMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CIP, CBLOG) '
353                            . "VALUES ('$name', '$url', '$email', $memberid, '$body', $itemid, '$timestamp', '$host', '$ip', '$blogid')";
354
355                 sql_query($query);
356
357                 // post add comment
358                 $commentid = sql_insert_id();
359                 $manager->notify('PostAddComment', array('comment' => &$comment, 'commentid' => &$commentid, 'spamcheck' => &$spamcheck) );
360
361                 // succeeded !
362                 return TRUE;
363         }
364
365
366         /**
367          * Checks if a comment is valid and call plugins
368          * that can check if the comment is a spam comment        
369          */
370         function isValidComment(&$comment, &$spamcheck) {
371
372                 global $member, $manager;
373
374                 // check if there exists a item for this date
375                 $item =& $manager->getItem($this->itemid, 0, 0);
376
377                 if (!$item)
378                 {
379                         return _ERROR_NOSUCHITEM;
380                 }
381
382                 if ($item['closed'])
383                 {
384                         return _ERROR_ITEMCLOSED;
385                 }
386
387                 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
388                 # original eregi comparison: eregi('[a-zA-Z0-9|\.,;:!\?=\/\\]{90,90}', $comment['body']) != FALSE
389
390                 // don't allow words that are too long
391                 if (preg_match('/[a-zA-Z0-9|\.,;:!\?=\/\\\\]{90,90}/', $comment['body']) != 0)
392                 {
393                         return _ERROR_COMMENT_LONGWORD;
394                 }
395
396                 // check lengths of comment
397                 if (strlen($comment['body']) < 3)
398                 {
399                         return _ERROR_COMMENT_NOCOMMENT;
400                 }
401
402                 if (strlen($comment['body']) > 5000)
403                 {
404                         return _ERROR_COMMENT_TOOLONG;
405                 }
406
407                 // only check username if no member logged in
408                 if (!$member->isLoggedIn() )
409                 {
410
411                         if (strlen($comment['user']) < 2)
412                         {
413                                 return _ERROR_COMMENT_NOUSERNAME;
414                         }
415
416                 }
417
418                 if ((strlen($comment['email']) != 0) && !(isValidMailAddress(trim($comment['email']) ) ) )
419                 {
420                         return _ERROR_BADMAILADDRESS;
421                 }
422
423                 // let plugins do verification (any plugin which thinks the comment is invalid
424                 // can change 'error' to something other than '1')
425                 $result = 1;
426                 $manager->notify('ValidateForm', array('type' => 'comment', 'comment' => &$comment, 'error' => &$result, 'spamcheck' => &$spamcheck) );
427
428                 return $result;
429         }
430
431 }
432
433 ?>