OSDN Git Service

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