OSDN Git Service

コピーライトの期間表記を「2002-2012」に更新
[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-2012 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-2012 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                         $param = array('comment' => &$comment);
110                         $manager->notify('PreComment', $param);
111                         $parser->parse($template['COMMENTS_BODY']);
112                         $param = array('comment' => &$comment);
113                         $manager->notify('PostComment', $param);
114                 }
115
116                 $parser->parse($template['COMMENTS_FOOTER']);
117
118                 sql_free_result($comments);
119
120                 return $this->commentcount;
121         }
122
123         /**
124          * Returns the amount of comments for this itemid
125          */
126         function amountComments() {
127                 $query =  'SELECT COUNT(*)'
128                            . ' FROM '.sql_table('comment').' as c'
129                            . ' WHERE c.citem='. $this->itemid;
130                 $res = sql_query($query);
131                 $arr = sql_fetch_row($res);
132
133                 return $arr[0];
134         }
135
136         /**
137          * Adds a new comment to the database
138          * @param string $timestamp
139          * @param array $comment
140          * @return mixed
141          */
142         function addComment($timestamp, $comment)
143         {
144                 global $CONF, $member, $manager;
145
146                 $blogid = getBlogIDFromItemID($this->itemid);
147
148                 $settings =& $manager->getBlog($blogid);
149                 $settings->readSettings();
150
151                 // begin if: comments disabled
152                 if ( !$settings->commentsEnabled() )
153                 {
154                         return _ERROR_COMMENTS_DISABLED;
155                 } // end if
156
157                 // begin if: public cannot comment
158                 if ( !$settings->isPublic() && !$member->isLoggedIn() )
159                 {
160                         return _ERROR_COMMENTS_NONPUBLIC;
161                 } // end if
162
163                 // begin if: comment uses a protected member name
164                 if ( $CONF['ProtectMemNames'] && !$member->isLoggedIn() && MEMBER::isNameProtected($comment['user']) )
165                 {
166                         return _ERROR_COMMENTS_MEMBERNICK;
167                 } // end if
168
169                 // begin if: email required, but missing (doesn't apply to members)
170                 if ( $settings->emailRequired() && strlen($comment['email']) == 0 && !$member->isLoggedIn() )
171                 {
172                         return _ERROR_EMAIL_REQUIRED;
173                 } // end if
174
175                 ## Note usage of mb_strlen() vs strlen() below ##
176
177                 // begin if: commenter's name is too long
178                 if ( mb_strlen($comment['user']) > 40 )
179                 {
180                         return _ERROR_USER_TOO_LONG;
181                 } // end if
182
183                 // begin if: commenter's email is too long
184                 if ( mb_strlen($comment['email']) > 100 )
185                 {
186                         return _ERROR_EMAIL_TOO_LONG;
187                 } // end if
188
189                 // begin if: commenter's url is too long
190                 if ( mb_strlen($comment['userid']) > 100 )
191                 {
192                         return _ERROR_URL_TOO_LONG;
193                 } // end if
194
195                 $comment['timestamp'] = $timestamp;
196                 $comment['host'] = gethostbyaddr(serverVar('REMOTE_ADDR') );
197                 $comment['ip'] = serverVar('REMOTE_ADDR');
198
199                 // begin if: member is logged in, use that data
200                 if ( $member->isLoggedIn() )
201                 {
202                         $comment['memberid'] = $member->getID();
203                         $comment['user'] = '';
204                         $comment['userid'] = '';
205                         $comment['email'] = '';
206                 }
207                 else
208                 {
209                         $comment['memberid'] = 0;
210                 }
211
212                 // spam check
213                 $continue = FALSE;
214                 $plugins = array();
215
216                 if ( isset($manager->subscriptions['ValidateForm']) )
217                 {
218                         $plugins = array_merge($plugins, $manager->subscriptions['ValidateForm']);
219                 }
220
221                 if ( isset($manager->subscriptions['PreAddComment']) )
222                 {
223                         $plugins = array_merge($plugins, $manager->subscriptions['PreAddComment']);
224                 }
225
226                 if ( isset($manager->subscriptions['PostAddComment']) )
227                 {
228                         $plugins = array_merge($plugins, $manager->subscriptions['PostAddComment']);
229                 }
230
231                 $plugins = array_unique($plugins);
232
233                 while ( list(, $plugin) = each($plugins) )
234                 {
235                         $p = $manager->getPlugin($plugin);
236                         $continue = $continue || $p->supportsFeature('handleSpam');
237                 }
238
239                 $spamcheck = array(
240                         'type'          => 'comment',
241                         'body'          => $comment['body'],
242                         'id'        => $comment['itemid'],
243                         'live'          => TRUE,
244                         'return'        => $continue
245                 );
246
247                 // begin if: member logged in
248                 if ( $member->isLoggedIn() )
249                 {
250                         $spamcheck['author'] = $member->displayname;
251                         $spamcheck['email'] = $member->email;
252                 }
253                 // else: public
254                 else
255                 {
256                         $spamcheck['author'] = $comment['user'];
257                         $spamcheck['email'] = $comment['email'];
258                         $spamcheck['url'] = $comment['userid'];
259                 } // end if
260
261                 $param = array('spamcheck' => &$spamcheck);
262                 $manager->notify('SpamCheck', $param);
263
264                 if ( !$continue && isset($spamcheck['result']) && $spamcheck['result'] == TRUE )
265                 {
266                         return _ERROR_COMMENTS_SPAM;
267                 }
268
269                 // isValidComment returns either "1" or an error message
270                 $isvalid = $this->isValidComment($comment, $spamcheck);
271
272                 if ( $isvalid != 1 )
273                 {
274                         return $isvalid;
275                 }
276
277                 // begin if: send email to notification address
278                 if ( $settings->getNotifyAddress() && $settings->notifyOnComment() )
279                 {
280
281                         $mailto_msg = _NOTIFY_NC_MSG . ' ' . $this->itemid . "\n";
282 //                      $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $this->itemid . "\n\n";
283                         $temp = parse_url($CONF['Self']);
284
285                         if ( $temp['scheme'] )
286                         {
287                                 $mailto_msg .= createItemLink($this->itemid) . "\n\n";
288                         }
289                         else
290                         {
291                                 $tempurl = $settings->getURL();
292
293                                 if ( substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php' )
294                                 {
295                                         $mailto_msg .= $tempurl . '?itemid=' . $this->itemid . "\n\n";
296                                 }
297                                 else
298                                 {
299                                         $mailto_msg .= $tempurl . '/?itemid=' . $this->itemid . "\n\n";
300                                 }
301                         }
302
303                         if ( $comment['memberid'] == 0 )
304                         {
305                                 $mailto_msg .= _NOTIFY_USER . ' ' . $comment['user'] . "\n";
306                                 $mailto_msg .= _NOTIFY_USERID . ' ' . $comment['userid'] . "\n";
307                         }
308                         else
309                         {
310                                 $mailto_msg .= _NOTIFY_MEMBER .' ' . $member->getDisplayName() . ' (ID=' . $member->getID() . ")\n";
311                         }
312
313                         $mailto_msg .= _NOTIFY_HOST . ' ' . $comment['host'] . "\n";
314                         $mailto_msg .= _NOTIFY_COMMENT . "\n " . $comment['body'] . "\n";
315                         $mailto_msg .= getMailFooter();
316
317                         $item =& $manager->getItem($this->itemid, 0, 0);
318                         $mailto_title = _NOTIFY_NC_TITLE . ' ' . strip_tags($item['title']) . ' (' . $this->itemid . ')';
319
320                         $frommail = $member->getNotifyFromMailAddress($comment['email']);
321
322                         $notify = new NOTIFICATION($settings->getNotifyAddress() );
323                         $notify->notify($mailto_title, $mailto_msg , $frommail);
324                 }
325
326                 $comment = COMMENT::prepare($comment);
327
328                 $param = array(
329                         'comment'       => &$comment,
330                         'spamcheck'     => &$spamcheck
331                 );
332                 $manager->notify('PreAddComment', $param);
333
334                 $name           = sql_real_escape_string($comment['user']);
335                 $url            = sql_real_escape_string($comment['userid']);
336                 $email      = sql_real_escape_string($comment['email']);
337                 $body           = sql_real_escape_string($comment['body']);
338                 $host           = sql_real_escape_string($comment['host']);
339                 $ip                     = sql_real_escape_string($comment['ip']);
340                 $memberid       = intval($comment['memberid']);
341                 $timestamp      = date('Y-m-d H:i:s', $comment['timestamp']);
342                 $itemid         = $this->itemid;
343
344                 $qSql       = 'SELECT COUNT(*) AS result '
345                                         . 'FROM ' . sql_table('comment')
346                                         . ' WHERE '
347                                         .      'cmail   = "' . $url . '"'
348                                         . ' AND cmember = "' . $memberid . '"'
349                                         . ' AND cbody   = "' . $body . '"'
350                                         . ' AND citem   = "' . $itemid . '"'
351                                         . ' AND cblog   = "' . $blogid . '"';
352                 $result     = (integer) quickQuery($qSql);
353
354                 if ( $result > 0 )
355                 {
356                         return _ERROR_BADACTION;
357                 }
358
359                 $query = 'INSERT INTO '.sql_table('comment').' (CUSER, CMAIL, CEMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CIP, CBLOG) '
360                            . "VALUES ('$name', '$url', '$email', $memberid, '$body', $itemid, '$timestamp', '$host', '$ip', '$blogid')";
361
362                 sql_query($query);
363
364                 // post add comment
365                 $commentid = sql_insert_id();
366                 $param = array(
367                         'comment'       => &$comment,
368                         'commentid'     => &$commentid,
369                         'spamcheck'     => &$spamcheck
370                 );
371                 $manager->notify('PostAddComment', $param);
372
373                 // succeeded !
374                 return TRUE;
375         }
376
377
378         /**
379          * Checks if a comment is valid and call plugins
380          * that can check if the comment is a spam comment        
381          */
382         function isValidComment(&$comment, &$spamcheck) {
383
384                 global $member, $manager;
385
386                 // check if there exists a item for this date
387                 $item =& $manager->getItem($this->itemid, 0, 0);
388
389                 if (!$item)
390                 {
391                         return _ERROR_NOSUCHITEM;
392                 }
393
394                 if ($item['closed'])
395                 {
396                         return _ERROR_ITEMCLOSED;
397                 }
398
399                 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
400                 # original eregi comparison: eregi('[a-zA-Z0-9|\.,;:!\?=\/\\]{90,90}', $comment['body']) != FALSE
401
402                 // don't allow words that are too long
403                 if (preg_match('/[a-zA-Z0-9|\.,;:!\?=\/\\\\]{90,90}/', $comment['body']) != 0)
404                 {
405                         return _ERROR_COMMENT_LONGWORD;
406                 }
407
408                 // check lengths of comment
409                 if (strlen($comment['body']) < 3)
410                 {
411                         return _ERROR_COMMENT_NOCOMMENT;
412                 }
413
414                 if (strlen($comment['body']) > 5000)
415                 {
416                         return _ERROR_COMMENT_TOOLONG;
417                 }
418
419                 // only check username if no member logged in
420                 if (!$member->isLoggedIn() )
421                 {
422
423                         if (strlen($comment['user']) < 2)
424                         {
425                                 return _ERROR_COMMENT_NOUSERNAME;
426                         }
427
428                 }
429
430                 if ((strlen($comment['email']) != 0) && !(isValidMailAddress(trim($comment['email']) ) ) )
431                 {
432                         return _ERROR_BADMAILADDRESS;
433                 }
434
435                 // let plugins do verification (any plugin which thinks the comment is invalid
436                 // can change 'error' to something other than '1')
437                 $result = 1;
438                 $param = array(
439                         'type'          => 'comment',
440                         'comment'       => &$comment,
441                         'error'         => &$result,
442                         'spamcheck'     => &$spamcheck
443                 );
444                 $manager->notify('ValidateForm', $param);
445
446                 return $result;
447         }
448
449 }
450
451 ?>