OSDN Git Service

Security fix
[nucleus-jp/nucleus-jp-ancient.git] / utf8 / nucleus / libs / COMMENTS.php
1 <?php
2
3 /*
4  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5  * Copyright (C) 2002-2007 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-2007 The Nucleus Group
18  * @version $Id: COMMENTS.php,v 1.9 2007-03-20 19:31:29 kmorimatsu Exp $
19  * $NucleusJP: COMMENTS.php,v 1.8 2007/03/13 05:12:19 shizuki Exp $
20  */
21
22 if ( !function_exists('requestVar') ) exit;
23 require_once dirname(__FILE__) . '/COMMENTACTIONS.php';
24
25 class COMMENTS {
26
27         // item for which comment are being displayed
28         var $itemid;
29
30         // reference to the itemActions object that is calling the showComments function
31         var $itemActions;
32
33         // total amount of comments displayed
34         var $commentcount;
35
36         /**
37          * Creates a new COMMENTS object for the given blog and item
38          *
39          * @param $itemid
40          *              id of the item
41          */
42         function COMMENTS($itemid) {
43                 $this->itemid = intval($itemid);
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 = mysql_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 = mysql_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                 mysql_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 = mysql_fetch_row($res);
130
131                 return $arr[0];
132         }
133
134
135         function addComment($timestamp, $comment) {
136                 global $CONF, $member, $manager;
137
138                 $blogid = getBlogIDFromItemID($this->itemid);
139
140                 $settings =& $manager->getBlog($blogid);
141                 $settings->readSettings();
142
143                 if (!$settings->commentsEnabled())
144                         return _ERROR_COMMENTS_DISABLED;
145
146                 if (!$settings->isPublic() && !$member->isLoggedIn())
147                         return _ERROR_COMMENTS_NONPUBLIC;
148
149                 // member name protection
150                 if ($CONF['ProtectMemNames'] && !$member->isLoggedIn() && MEMBER::isNameProtected($comment['user']))
151                         return _ERROR_COMMENTS_MEMBERNICK;
152
153                 // email required protection
154                 if ($settings->emailRequired() && strlen($comment['email']) == 0 && !$member->isLoggedIn()) {
155                         return _ERROR_EMAIL_REQUIRED;
156                 }
157
158                 $comment['timestamp'] = $timestamp;
159                 $comment['host'] = gethostbyaddr(serverVar('REMOTE_ADDR'));
160                 $comment['ip'] = serverVar('REMOTE_ADDR');
161
162                 // if member is logged in, use that data
163                 if ($member->isLoggedIn()) {
164                         $comment['memberid'] = $member->getID();
165                         $comment['user'] = '';
166                         $comment['userid'] = '';
167                         $comment['email'] = '';
168                 } else {
169                         $comment['memberid'] = 0;
170                 }
171
172                 // spam check
173                 $continue = false;
174                 $plugins = array();
175
176                 if (isset($manager->subscriptions['ValidateForm']))
177                         $plugins = array_merge($plugins, $manager->subscriptions['ValidateForm']);
178
179                 if (isset($manager->subscriptions['PreAddComment']))
180                         $plugins = array_merge($plugins, $manager->subscriptions['PreAddComment']);
181
182                 if (isset($manager->subscriptions['PostAddComment']))
183                         $plugins = array_merge($plugins, $manager->subscriptions['PostAddComment']);
184
185                 $plugins = array_unique($plugins);
186
187                 while (list(,$plugin) = each($plugins)) {
188                         $p = $manager->getPlugin($plugin);
189                         $continue = $continue || $p->supportsFeature('handleSpam');
190                 }
191
192                 $spamcheck = array (
193                         'type'          => 'comment',
194                         'body'          => $comment['body'],
195                         'id'        => $comment['itemid'],
196                         'live'          => true,
197                         'return'        => $continue
198                 );
199
200                 if ($member->isLoggedIn()) {
201                         $spamcheck['author'] = $member->displayname;
202                         $spamcheck['email'] = $member->email;
203                 } else {
204                         $spamcheck['author'] = $comment['user'];
205                         $spamcheck['email'] = $comment['email'];
206                         $spamcheck['url'] = $comment['userid'];
207                 }
208
209                 $manager->notify('SpamCheck', array ('spamcheck' => &$spamcheck));
210
211                 if (!$continue && isset($spamcheck['result']) && $spamcheck['result'] == true)
212                         return _ERROR_COMMENTS_SPAM;
213
214
215                 // isValidComment returns either "1" or an error message
216                 $isvalid = $this->isValidComment($comment, $spamcheck);
217                 if ($isvalid != 1)
218                         return $isvalid;
219
220                 // send email to notification address, if any
221                 if ($settings->getNotifyAddress() && $settings->notifyOnComment()) {
222
223                         $mailto_msg = _NOTIFY_NC_MSG . ' ' . $this->itemid . "\n";
224 //                      $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $this->itemid . "\n\n";
225                         $temp = parse_url($CONF['Self']);
226                         if ($temp['scheme']) {
227                                 $mailto_msg .= createItemLink($this->itemid) . "\n\n";
228                         } else {
229                                 $tempurl = $settings->getURL();
230                                 if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {
231                                         $mailto_msg .= $tempurl . '?itemid=' . $this->itemid . "\n\n";
232                                 } else {
233                                         $mailto_msg .= $tempurl . '/?itemid=' . $this->itemid . "\n\n";
234                                 }
235                         }
236                         if ($comment['memberid'] == 0) {
237                                 $mailto_msg .= _NOTIFY_USER . ' ' . $comment['user'] . "\n";
238                                 $mailto_msg .= _NOTIFY_USERID . ' ' . $comment['userid'] . "\n";
239                         } else {
240                                 $mailto_msg .= _NOTIFY_MEMBER .' ' . $member->getDisplayName() . ' (ID=' . $member->getID() . ")\n";
241                         }
242                         $mailto_msg .= _NOTIFY_HOST . ' ' . $comment['host'] . "\n";
243                         $mailto_msg .= _NOTIFY_COMMENT . "\n " . $comment['body'] . "\n";
244                         $mailto_msg .= getMailFooter();
245
246                         $item =& $manager->getItem($this->itemid, 0, 0);
247                         $mailto_title = _NOTIFY_NC_TITLE . ' ' . strip_tags($item['title']) . ' (' . $this->itemid . ')';
248
249                         $frommail = $member->getNotifyFromMailAddress($comment['userid']);
250
251                         $notify =& new NOTIFICATION($settings->getNotifyAddress());
252                         $notify->notify($mailto_title, $mailto_msg , $frommail);
253                 }
254
255                 $comment = COMMENT::prepare($comment);
256
257                 $manager->notify('PreAddComment',array('comment' => &$comment, 'spamcheck' => &$spamcheck));
258
259                 $name           = addslashes($comment['user']);
260                 $url            = addslashes($comment['userid']);
261                 $email      = addslashes($comment['email']);
262                 $body           = addslashes($comment['body']);
263                 $host           = addslashes($comment['host']);
264                 $ip                     = addslashes($comment['ip']);
265                 $memberid       = intval($comment['memberid']);
266                 $timestamp      = date('Y-m-d H:i:s', $comment['timestamp']);
267                 $itemid         = $this->itemid;
268
269                 $query = 'INSERT INTO '.sql_table('comment').' (CUSER, CMAIL, CEMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CIP, CBLOG) '
270                            . "VALUES ('$name', '$url', '$email', $memberid, '$body', $itemid, '$timestamp', '$host', '$ip', '$blogid')";
271
272                 sql_query($query);
273
274                 // post add comment
275                 $commentid = mysql_insert_id();
276                 $manager->notify('PostAddComment',array('comment' => &$comment, 'commentid' => &$commentid, 'spamcheck' => &$spamcheck));
277
278                 // succeeded !
279                 return true;
280         }
281
282
283         function isValidComment($comment, & $spamcheck) {
284                 global $member, $manager;
285
286                 // check if there exists a item for this date
287                 $item =& $manager->getItem($this->itemid,0,0);
288
289                 if (!$item)
290                         return _ERROR_NOSUCHITEM;
291
292                 if ($item['closed'])
293                         return _ERROR_ITEMCLOSED;
294
295                 // don't allow words that are too long
296                 if (eregi('[a-zA-Z0-9|\.,;:!\?=\/\\]{90,90}',$comment['body']) != false)
297                         return _ERROR_COMMENT_LONGWORD;
298
299                 // check lengths of comment
300                 if (strlen($comment['body'])<3)
301                         return _ERROR_COMMENT_NOCOMMENT;
302
303                 if (strlen($comment['body'])>5000)
304                         return _ERROR_COMMENT_TOOLONG;
305
306                 // only check username if no member logged in
307                 if (!$member->isLoggedIn())
308                         if (strlen($comment['user'])<2)
309                                 return _ERROR_COMMENT_NOUSERNAME;
310
311                 if ((strlen($comment['email']) != 0) && !(isValidMailAddress($comment['email']))) {
312                         return _ERROR_BADMAILADDRESS;
313                 }
314
315                 // let plugins do verification (any plugin which thinks the comment is invalid
316                 // can change 'error' to something other than '1')
317                 $result = 1;
318                 $manager->notify('ValidateForm', array('type' => 'comment', 'comment' => &$comment, 'error' => &$result, 'spamcheck' => &$spamcheck));
319
320                 return $result;
321         }
322
323 }
324
325 ?>