OSDN Git Service

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