[ Index ] |
|
Code source de Serendipity 1.2 |
1 <?php # $Id: functions_comments.inc.php 1779 2007-07-15 15:14:06Z garvinhicking $ 2 # Copyright (c) 2003-2005, Jannis Hermanns (on behalf the Serendipity Developer Team) 3 # All rights reserved. See LICENSE file for licensing details 4 5 if (IN_serendipity !== true) { 6 die ("Don't hack!"); 7 } 8 9 if (defined('S9Y_FRAMEWORK_COMMENTS')) { 10 return; 11 } 12 @define('S9Y_FRAMEWORK_COMMENTS', true); 13 14 /** 15 * Store the personal details of a commenting user in a cookie (or delete that cookie) 16 * 17 * @access public 18 * @return null 19 */ 20 function serendipity_rememberComment() { 21 global $serendipity; 22 23 if (isset($serendipity['POST']['remember'])) { 24 serendipity_rememberCommentDetails( 25 array( 26 'url' => $serendipity['POST']['url'], 27 'name' => $serendipity['POST']['name'], 28 'email' => $serendipity['POST']['email'], 29 'remember' => 'checked="checked"' 30 ) 31 ); 32 } elseif (isset($serendipity['POST']['comment'])) { 33 serendipity_forgetCommentDetails(array('url', 'name', 'email', 'remember')); 34 } 35 } 36 37 /** 38 * Store all options of an array within a permanent cookie 39 * 40 * @access public 41 * @param array input array 42 * @return null 43 */ 44 function serendipity_rememberCommentDetails($details) { 45 global $serendipity; 46 47 foreach ($details as $n => $v) { 48 serendipity_setCookie($n, $v); 49 } 50 } 51 52 /** 53 * Purge stored options from a permanent cookie 54 * 55 * LONG 56 * 57 * @access public 58 * @param array Array of key names that shall be deleted inside cookies 59 * @return null 60 */ 61 function serendipity_forgetCommentDetails($keys) { 62 global $serendipity; 63 if (!$serendipity['COOKIE']) { 64 return; 65 } 66 67 foreach ($keys AS $n) { 68 serendipity_deleteCookie($n); 69 } 70 } 71 72 /** 73 * Display the Comment form for entries 74 * 75 * @access public 76 * @param int The EntryID to show the commentform for 77 * @param string The URL that acts as the target of the HTML Form 78 * @param array Array of existing comments to this entry 79 * @param array Array of personal details data (i.e. from Cookie or POST input) 80 * @param boolean Toggle whether to show extended options of the comment form 81 * @param boolean Toggle whether comments to this entry are allowed 82 * @param array The data of the entry that the comment is referring to 83 * @return null 84 */ 85 function serendipity_displayCommentForm($id, $url = '', $comments = NULL, $data = NULL, $showToolbar = true, $moderate_comments = true, $entry = null) { 86 global $serendipity; 87 88 if ($comments == NULL) { 89 $comments = serendipity_fetchComments($id); 90 } 91 92 $commentform_data = array( 93 'commentform_action' => $url, 94 'commentform_id' => $id, 95 'commentform_name' => isset($data['name']) ? htmlspecialchars($data['name']) : (isset($serendipity['COOKIE']['name']) ? htmlspecialchars($serendipity['COOKIE']['name']) : ''), 96 'commentform_email' => isset($data['email']) ? htmlspecialchars($data['email']) : (isset($serendipity['COOKIE']['email']) ? htmlspecialchars($serendipity['COOKIE']['email']) : ''), 97 'commentform_url' => isset($data['url']) ? htmlspecialchars($data['url']) : (isset($serendipity['COOKIE']['url']) ? htmlspecialchars($serendipity['COOKIE']['url']) : ''), 98 'commentform_remember' => isset($data['remember']) ? 'checked="checked"' : (isset($serendipity['COOKIE']['remember']) ? 'checked="checked"' : ''), 99 'commentform_replyTo' => serendipity_generateCommentList($id, $comments, ((isset($data['replyTo']) && ($data['replyTo'])) ? $data['replyTo'] : 0)), 100 'commentform_subscribe' => isset($data['subscribe']) ? 'checked="checked"' : '', 101 'commentform_data' => isset($data['comment']) ? htmlspecialchars($data['comment']) : '', 102 'is_commentform_showToolbar' => $showToolbar, 103 'is_allowSubscriptions' => $serendipity['allowSubscriptions'], 104 'is_moderate_comments' => $moderate_comments, 105 'commentform_entry' => $entry 106 ); 107 108 $serendipity['smarty']->assign($commentform_data); 109 110 serendipity_smarty_fetch('COMMENTFORM', 'commentform.tpl'); 111 } 112 113 /** 114 * Fetch an array of comments to a specific entry id 115 * 116 * @access public 117 * @param int The Entry ID to fetch comments for 118 * @param int How many comments to fetch (empty: all) 119 * @param string How shall comments be ordered (ASC|DESC) 120 * @param boolean Shall non-approved comments be displayed? 121 * @param string Comment type to fetch 122 * @return array The SQL result of comments 123 */ 124 function serendipity_fetchComments($id, $limit = null, $order = '', $showAll = false, $type = 'NORMAL', $where = '') { 125 global $serendipity; 126 $and = ''; 127 128 if (!empty($limit)) { 129 $limit = serendipity_db_limit_sql($limit); 130 } else { 131 $limit = ''; 132 } 133 134 if ($type == 'comments' || empty($type)) { 135 $type = 'NORMAL'; 136 } elseif ($type == 'trackbacks') { 137 $type = 'TRACKBACK'; 138 } elseif ($type == 'comments_and_trackbacks') { 139 $type = '%'; 140 } 141 142 if (!empty($id)) { 143 $and .= " AND co.entry_id = '" . (int)$id ."'"; 144 } 145 146 if (!$showAll) { 147 $and .= ' AND co.status = \'approved\''; 148 } 149 150 $and .= $where; 151 152 if ($serendipity['dbType'] == 'postgres' || 153 $serendipity['dbType'] == 'pdo-postgres') { 154 $group = ''; 155 $distinct = 'DISTINCT'; 156 } else { 157 $group = 'GROUP BY co.id'; 158 $distinct = ''; 159 } 160 161 $query = "SELECT $distinct 162 co.id, 163 co.entry_id, co.timestamp, co.title AS ctitle, co.email, co.url, co.ip, co.body, co.type, co.subscribed, 164 co.author, 165 e.title, 166 e.timestamp AS entrytimestamp, 167 e.id AS entryid, 168 e.authorid, 169 co.id AS commentid, 170 co.parent_id AS parent_id 171 FROM 172 {$serendipity['dbPrefix']}comments AS co 173 LEFT JOIN {$serendipity['dbPrefix']}entries AS e ON (co.entry_id = e.id) 174 WHERE co.type LIKE '" . $type . "' AND co.entry_id > 0 $and 175 $group 176 ORDER BY 177 " . ($where != '' ? '' : 'co.id') . " " . ($order != '' ? $order : '') . " 178 $limit"; 179 $comments = serendipity_db_query($query, false, 'assoc'); 180 181 if (!is_array($comments)) { 182 return array(); 183 } 184 185 serendipity_plugin_api::hook_event('fetchcomments', $comments); 186 187 return $comments; 188 } 189 190 /** 191 * Create a HTML SELECT dropdown field which represents all hierarchical comments 192 * 193 * @access public 194 * @param int The entry ID to show comments for 195 * @param array The existing comments for this entry 196 * @param int The ID of the comment that is being referred to (last selection) 197 * @param int The parent ID of the last comment [for recursive usage] 198 * @param int The current nesting/hierarchy level [for recursive usage] 199 * @param string The HTML indention string that gets prepended to a comment [for recursive usage] 200 * @return string The HTML SELECT code 201 */ 202 function serendipity_generateCommentList($id, $comments = NULL, $selected = 0, $parent = 0, $level = 0, $indent = '') { 203 global $serendipity; 204 205 if (!is_array($comments)) { 206 if (empty($id)) { 207 $comments = array(); 208 } else { 209 $comments = serendipity_fetchComments($id); 210 } 211 } 212 213 $retval = $parent ? '' : '<select id="serendipity_replyTo" onchange="' . (!empty($serendipity['plugindata']['onchange']) ? $serendipity['plugindata']['onchange'] : '') . '" name="serendipity[replyTo]"><option value="0">[ ' . TOP_LEVEL . ' ]</option>'; 214 215 $i = 0; 216 foreach ($comments as $comment) { 217 if ($comment['parent_id'] == $parent) { 218 $i++; 219 $retval .= '<option value="' . $comment['id'] . '"'. ($selected == $comment['id'] || (isset($serendipity['POST']['replyTo']) && $comment['id'] == $serendipity['POST']['replyTo']) ? ' selected="selected"' : '') .'>' . str_repeat(' ', $level * 2) . '#' . $indent . $i . ': ' . (empty($comment['author']) ? ANONYMOUS : htmlspecialchars($comment['author'])) . ' ' . ON . ' ' . serendipity_mb('ucfirst', serendipity_strftime(DATE_FORMAT_SHORT, $comment['timestamp'])) . "</option>\n"; 220 $retval .= serendipity_generateCommentList($id, $comments, $selected, $comment['id'], $level + 1, $indent . $i . '.'); 221 } 222 } 223 $retval .= $parent ? '' : '</select>'; 224 225 return $retval; 226 } 227 228 /** 229 * Print a list of comments to an entry 230 * 231 * @access public 232 * @param array The list of comments to display 233 * @param int The parentID of a comment to show. Can contain the constant for VIEWMODE_THREADED/LINEAR. [recursive usage] 234 * @param int The current nesting depth of a comment [recursive usage] 235 * @param string A string repesenting the actual comment (1.1.2.1) 236 * @return string The HTML construct of all comments 237 */ 238 function serendipity_printComments($comments, $parentid = 0, $depth = 0, $trace = null, $smarty_block = 'COMMENTS', $smarty_file = 'comments.tpl') { 239 global $serendipity; 240 static $_smartyComments; 241 242 /* - $_smartyComments holds the ending smarty array. 243 - $depth is the current depth of the recurrence. 244 - $i is the position in the current depth. */ 245 246 if ($parentid === VIEWMODE_THREADED) { 247 $parentid = 0; 248 } 249 250 /* Wait a second, we just got attacked by a call with level 0, 251 this must mean we've started over */ 252 if ( $depth == 0 ) { 253 $_smartyComments = array(); 254 } 255 256 $i = 0; 257 foreach ($comments as $comment) { 258 if ($parentid === VIEWMODE_LINEAR || !isset($comment['parent_id']) || $comment['parent_id'] == $parentid) { 259 $i++; 260 261 $comment['comment'] = htmlspecialchars(strip_tags($comment['body'])); 262 $comment['url'] = strip_tags($comment['url']); 263 $comment['link_delete'] = $serendipity['baseURL'] . 'comment.php?serendipity[delete]=' . $comment['id'] . '&serendipity[entry]=' . $comment['entry_id'] . '&serendipity[type]=comments'; 264 265 /* Fix fucked links */ 266 if (!empty($comment['url']) && substr($comment['url'], 0, 7) != 'http://' && substr($comment['url'], 0, 8) != 'https://') { 267 $comment['url'] = 'http://' . $comment['url']; 268 } 269 270 if (!empty($comment['url'])) { 271 if (!@parse_url($comment['url'])) { 272 $comment['url'] = ''; 273 } 274 $comment['url'] = htmlspecialchars($comment['url'], ENT_QUOTES); 275 } 276 277 $addData = array('from' => 'functions_entries:printComments'); 278 serendipity_plugin_api::hook_event('frontend_display', $comment, $addData); 279 280 if (isset($comment['no_email']) && $comment['no_email']) { 281 $comment['email'] = false; 282 } elseif (!empty($comment['email'])) { 283 $comment['clear_email'] = $comment['email']; 284 $comment['email'] = htmlspecialchars(str_replace('@', '[at]', $comment['email'])); 285 } 286 287 $comment['body'] = $comment['comment']; 288 $comment['pos'] = $i; 289 $comment['trace'] = $trace . $i; 290 $comment['depth'] = $depth; 291 $comment['author'] = htmlspecialchars($comment['author']); 292 293 $_smartyComments[] = $comment; 294 if ($comment['id'] && $parentid !== VIEWMODE_LINEAR ) { 295 serendipity_printComments($comments, $comment['id'], ($depth+1), ($trace . $i . '.'), $smarty_block, $smarty_file); 296 } 297 } 298 } 299 300 /* We are inside a recusive child, and we need to break out */ 301 if ($depth !== 0) { 302 return true; 303 } 304 305 $serendipity['smarty']->assign_by_ref('comments', $_smartyComments); 306 unset($_smartyComments); 307 308 return serendipity_smarty_fetch($smarty_block, $smarty_file); 309 } 310 311 /** 312 * Fetches and prints a listing of comments by author 313 */ 314 function serendipity_printCommentsByAuthor() { 315 global $serendipity; 316 317 $type = serendipity_db_escape_string($serendipity['GET']['commentMode']); 318 319 if ($type == 'comments' || empty($type)) { 320 $type = 'NORMAL'; 321 } elseif ($type == 'trackbacks') { 322 $type = 'TRACKBACK'; 323 } elseif ($type == 'comments_and_trackbacks') { 324 $type = '%'; 325 } 326 327 if (!empty($serendipity['GET']['viewCommentAuthor'])) { 328 $sql_where = " AND co.author = '" . serendipity_db_escape_string($serendipity['GET']['viewCommentAuthor']) . "'"; 329 $group_by = "GROUP BY co.author"; 330 } else { 331 $sql_where = " AND 1"; // Required fake 'where' condition 332 $group_by = ""; 333 } 334 335 if (!empty($serendipity['GET']['commentStartTime'])) { 336 $sql_where .= " AND co.timestamp >= " . (int)$serendipity['GET']['commentStartTime']; 337 } 338 339 if (!empty($serendipity['GET']['commentEndTime'])) { 340 $sql_where .= " AND co.timestamp <= " . (int)$serendipity['GET']['commentEndTime']; 341 } 342 343 if (empty($serendipity['GET']['page'])) { 344 $serendipity['GET']['page'] = 1; 345 } 346 $sql_limit = $serendipity['fetchLimit'] * ($serendipity['GET']['page']-1) . ',' . $serendipity['fetchLimit']; 347 $c = serendipity_fetchComments(null, $sql_limit, 'co.entry_id DESC, co.id ASC', false, $type, $sql_where); 348 349 $entry_comments = array(); 350 foreach($c as $i => $comment) { 351 if (!isset($entry_comments[$comment['entry_id']])) { 352 $comment['link'] = serendipity_archiveURL($comment['entry_id'], $comment['title'], 'serendipityHTTPPath', true, array('timestamp' => $comment['entrytimestamp'])); 353 $entry_comments[$comment['entry_id']] = $comment; 354 } 355 $entry_comments[$comment['entry_id']]['comments'][] = $comment; 356 } 357 358 foreach($entry_comments AS $entry_id => $_data) { 359 $entry_comments[$entry_id]['tpl_comments'] =& serendipity_printComments($_data['comments'], VIEWMODE_LINEAR, 0, null, 'COMMENTS', 'comments.tpl'); 360 } 361 362 $serendipity['smarty']->assign_by_ref('comments_by_authors', $entry_comments); 363 364 if (!empty($id)) { 365 $and .= " AND co.entry_id = '" . (int)$id ."'"; 366 } 367 368 if (!$showAll) { 369 $and .= ' AND co.status = \'approved\''; 370 } 371 372 $fc = "SELECT count(co.id) AS counter 373 FROM {$serendipity['dbPrefix']}comments AS co 374 WHERE co.entry_id > 0 375 AND co.type LIKE '" . $type . "' 376 AND co.status = 'approved' " . $sql_where . " " 377 . $group_by; 378 $cc = serendipity_db_query($fc, true, 'assoc'); 379 if (!isset($cc['counter'])) { 380 $totalComments = 0; 381 } else { 382 $totalComments = $cc['counter']; 383 } 384 serendipity_printEntryFooter('', $totalComments); 385 386 serendipity_smarty_fetch('ENTRIES', 'comments_by_author.tpl'); 387 388 return true; 389 } 390 391 /** 392 * Delete a specific comment 393 * 394 * @access public 395 * @param int The ID of the comment to delete 396 * @param int The ID of the entry the comment belongs to [safety] 397 * @param string The type of a comment (comments/trackback) 398 * @return boolean Return whether the action was successful) 399 */ 400 function serendipity_deleteComment($id, $entry_id, $type='comments') { 401 global $serendipity; 402 403 $id = (int)$id; 404 $entry_id = (int)$entry_id; 405 if ($id < 1 OR $entry_id < 1) { 406 return false; 407 } 408 409 if ($_SESSION['serendipityAuthedUser'] === true) { 410 $admin = ''; 411 if (!serendipity_checkPermission('adminEntriesMaintainOthers')) { 412 $admin = " AND authorid = " . (int)$_SESSION['serendipityAuthorid']; 413 } 414 415 /* We have to figure out if the comment we are about to delete, is awaiting approval, 416 if so - we should *not* subtract it from the entries table */ 417 $sql = serendipity_db_query("SELECT type, status, parent_id, body FROM {$serendipity['dbPrefix']}comments 418 WHERE entry_id = ". $entry_id ." 419 AND id = ". $id, true); 420 421 422 /* Check to see if the comment has children 423 * if it does, don't delete, but replace with "*(COMMENT DELETED)*" 424 to delete a tree, delete children first */ 425 $has_parent = serendipity_db_query("SELECT count(id) AS count 426 FROM {$serendipity['dbPrefix']}comments 427 WHERE parent_id = ". $id . " 428 LIMIT 1", true); 429 430 if (is_array($has_parent) && isset($has_parent['count']) && $has_parent['count'] > 0 && $sql['body'] != 'COMMENT_DELETED') { 431 // Comment has childs, so don't delete it. 432 serendipity_db_query("UPDATE {$serendipity['dbPrefix']}comments 433 SET body = 'COMMENT_DELETED' 434 WHERE id = " . $id); 435 } else { 436 // Comment has no childs or had already been deleted., it can be safely removed. 437 serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}comments 438 WHERE entry_id = ". $entry_id ." 439 AND id = ". $id); 440 441 if (is_array($sql) && $sql['status'] !== 'pending') { 442 if (!empty($sql['type']) && $sql['type'] != 'NORMAL') { 443 $type = 'trackbacks'; 444 } else { 445 $type = 'comments'; 446 } 447 serendipity_db_query("UPDATE {$serendipity['dbPrefix']}entries SET $type = $type-1 WHERE id = ". $entry_id ." AND $type > 0 $admin"); 448 } 449 450 serendipity_db_query("UPDATE {$serendipity['dbPrefix']}comments SET parent_id = " . (int)$sql['parent_id'] . " WHERE parent_id = " . $id); 451 } 452 453 $addData = array('cid' => $id, 'entry_id' => $entry_id); 454 serendipity_plugin_api::hook_event('backend_deletecomment', $sql, $addData); 455 456 return true; 457 } else { 458 return false; 459 } 460 } 461 462 /** 463 * Toggle whether an entry allows comments 464 * 465 * @access public 466 * @param int The ID of the entry where the switch shall be toggled 467 * @param string Whether the entry shall be opened or closed for comments 468 * @return null 469 */ 470 function serendipity_allowCommentsToggle($entry_id, $switch = 'disable') { 471 global $serendipity; 472 473 if ($_SESSION['serendipityAuthedUser'] === true) { 474 $admin = ''; 475 if (!serendipity_checkPermission('adminEntriesMaintainOthers')) { 476 $admin = " AND authorid = " . (int)$_SESSION['serendipityAuthorid']; 477 } 478 479 $query = "UPDATE {$serendipity['dbPrefix']}entries SET allow_comments = '" . ($switch == 'disable' ? 'false' : 'true') . "' WHERE id = '". (int)$entry_id ."' $admin"; 480 serendipity_db_query($query); 481 if (serendipity_isResponseClean($_SERVER['HTTP_REFERER'])) { 482 header('Location: '. $_SERVER['HTTP_REFERER']); 483 } 484 } else { 485 die('What are you up to? You need to be an admin to close comments'); 486 } 487 } 488 489 /** 490 * Approve a comment 491 * 492 * LONG 493 * 494 * @access public 495 * @param int The ID of the comment to approve 496 * @param int The ID of the entry a comment belongs to 497 * @param boolean Whether to force approving a comment despite of its current status 498 * @return boolean Success or failure 499 */ 500 function serendipity_approveComment($cid, $entry_id, $force = false) { 501 global $serendipity; 502 503 /* Get data about the comment, we need this query because this function can be called from anywhere */ 504 /* This also makes sure we are either the author of the comment, or a USERLEVEL_ADMIN */ 505 $sql = "SELECT c.*, e.title, a.email as authoremail, a.mail_comments, e.timestamp AS entry_timestamp, e.last_modified AS entry_last_modified 506 FROM {$serendipity['dbPrefix']}comments c 507 LEFT JOIN {$serendipity['dbPrefix']}entries e ON (e.id = c.entry_id) 508 LEFT JOIN {$serendipity['dbPrefix']}authors a ON (e.authorid = a.authorid) 509 WHERE c.id = '". (int)$cid ."' 510 ". ((!serendipity_checkPermission('adminEntriesMaintainOthers') && $force !== true) ? "AND e.authorid = '". (int)$serendipity['authorid'] ."'" : '') ." 511 ". (($force === true) ? "" : "AND status = 'pending'"); 512 $rs = serendipity_db_query($sql, true); 513 514 /* It's already approved, don't spam people */ 515 if ( $rs === false ) { 516 return false; 517 } 518 519 $sql = "UPDATE {$serendipity['dbPrefix']}comments SET status = 'approved' WHERE id = ". (int)$cid; 520 serendipity_db_query($sql); 521 522 $field = ($rs['type'] == 'NORMAL' ? 'comments' : 'trackbacks'); 523 // Check when the entry was published. If it is older than max_last_modified allows, the last_modified date of that entry 524 // will not be pushed. With this we make sure that an RSS feed will not be updated on a client's reader and marked as new 525 // only because someone made an comment to an old entry. 526 if ($rs['entry_timestamp'] > time() - $serendipity['max_last_modified']) { 527 $lm = time(); 528 } else { 529 $lm = (int)$rs['entry_last_modified']; 530 } 531 532 $query = "UPDATE {$serendipity['dbPrefix']}entries SET $field=$field+1, last_modified=". $lm ." WHERE id='". (int)$entry_id ."'"; 533 serendipity_db_query($query); 534 535 if ($serendipity['allowSubscriptions']) { 536 serendipity_mailSubscribers($entry_id, $rs['author'], $rs['email'], $rs['title'], $rs['authoremail'], $cid); 537 } 538 539 serendipity_plugin_api::hook_event('backend_approvecomment', $rs); 540 return true; 541 } 542 543 /** 544 * Save a comment made by a visitor 545 * 546 * @access public 547 * @param int The ID of an entry 548 * @param array An array that holds the input data from the visitor 549 * @param string The type of a comment (normal/trackback) 550 * @param string Where did a comment come from? (internal|trackback|plugin) 551 * @return boolean Returns true if the comment could be added 552 */ 553 function serendipity_saveComment($id, $commentInfo, $type = 'NORMAL', $source = 'internal') { 554 global $serendipity; 555 556 $query = "SELECT id, allow_comments, moderate_comments, last_modified, timestamp, title FROM {$serendipity['dbPrefix']}entries WHERE id = '". (int)$id ."'"; 557 $ca = serendipity_db_query($query, true); 558 559 $commentInfo['type'] = $type; 560 $commentInfo['source'] = $source; 561 serendipity_plugin_api::hook_event('frontend_saveComment', $ca, $commentInfo); 562 if (!is_array($ca) || serendipity_db_bool($ca['allow_comments'])) { 563 $title = serendipity_db_escape_string(isset($commentInfo['title']) ? $commentInfo['title'] : ''); 564 $comments = $commentInfo['comment']; 565 $ip = serendipity_db_escape_string(isset($commentInfo['ip']) ? $commentInfo['ip'] : $_SERVER['REMOTE_ADDR']); 566 $commentsFixed = serendipity_db_escape_string($commentInfo['comment']); 567 $name = serendipity_db_escape_string($commentInfo['name']); 568 $url = serendipity_db_escape_string($commentInfo['url']); 569 $email = serendipity_db_escape_string($commentInfo['email']); 570 $parentid = (isset($commentInfo['parent_id']) && is_numeric($commentInfo['parent_id'])) ? $commentInfo['parent_id'] : 0; 571 $status = serendipity_db_escape_string(isset($commentInfo['status']) ? $commentInfo['status'] : (serendipity_db_bool($ca['moderate_comments']) ? 'pending' : 'approved')); 572 $t = serendipity_db_escape_string(isset($commentInfo['time']) ? $commentInfo['time'] : time()); 573 $referer = substr((isset($_SESSION['HTTP_REFERER']) ? serendipity_db_escape_string($_SESSION['HTTP_REFERER']) : ''), 0, 200); 574 575 $query = "SELECT a.email, e.title, a.mail_comments, a.mail_trackbacks 576 FROM {$serendipity['dbPrefix']}entries e, {$serendipity['dbPrefix']}authors a 577 WHERE e.id = '". (int)$id ."' 578 AND e.isdraft = 'false' 579 AND e.timestamp <= " . time() . " 580 AND e.authorid = a.authorid"; 581 $row = serendipity_db_query($query, true); // Get info on author/entry 582 if (!is_array($row) || empty($id)) { 583 // No associated entry found. 584 return false; 585 } 586 587 if (isset($commentInfo['subscribe'])) { 588 $subscribe = 'true'; 589 } else { 590 $subscribe = 'false'; 591 } 592 593 $query = "INSERT INTO {$serendipity['dbPrefix']}comments (entry_id, parent_id, ip, author, email, url, body, type, timestamp, title, subscribed, status, referer)"; 594 $query .= " VALUES ('". (int)$id ."', '$parentid', '$ip', '$name', '$email', '$url', '$commentsFixed', '$type', '$t', '$title', '$subscribe', '$status', '$referer')"; 595 596 serendipity_db_query($query); 597 $cid = serendipity_db_insert_id('comments', 'id'); 598 599 // Send mail to the author if he chose to receive these mails, or if the comment is awaiting moderation 600 if (serendipity_db_bool($ca['moderate_comments']) 601 || ($type == 'NORMAL' && serendipity_db_bool($row['mail_comments'])) 602 || ($type == 'TRACKBACK' && serendipity_db_bool($row['mail_trackbacks']))) { 603 serendipity_sendComment($cid, $row['email'], $name, $email, $url, $id, $row['title'], $comments, $type, serendipity_db_bool($ca['moderate_comments'])); 604 } 605 606 // Approve with force, if moderation is disabled 607 if (empty($ca['moderate_comments']) || serendipity_db_bool($ca['moderate_comments']) == false) { 608 serendipity_approveComment($cid, $id, true); 609 } 610 serendipity_purgeEntry($id, $t); 611 return true; 612 } else { 613 return false; 614 } 615 } 616 617 /** 618 * Send a mail to all subscribers of an entry about a new comment 619 * 620 * @access public 621 * @param int The ID of the entry where a new comment has been made 622 * @param string The name of the latest poster to an entry 623 * @param string The email addre ssof the latest poster to an entry 624 * @param string The title of the entry 625 * @param string The mail address used to send emails from 626 * @param int The ID of the comment that has been made 627 * @return null 628 */ 629 function serendipity_mailSubscribers($entry_id, $poster, $posterMail, $title, $fromEmail = 'none@example.com', $cid = null) { 630 global $serendipity; 631 632 $entryURI = serendipity_archiveURL($entry_id, $title, 'baseURL') . ($cid > 0 ? '#c' . $cid : ''); 633 $subject = sprintf(NEW_COMMENT_TO_SUBSCRIBED_ENTRY, $title); 634 635 $pgsql_insert = ''; 636 $mysql_insert = ''; 637 if ($serendipity['dbType'] == 'postgres' || 638 $serendipity['dbType'] == 'pdo-postgres') { 639 $pgsql_insert = 'DISTINCT ON (email)'; 640 } else { 641 $mysql_insert = 'GROUP BY email'; 642 } 643 644 $sql = "SELECT $pgsql_insert author, email, type 645 FROM {$serendipity['dbPrefix']}comments 646 WHERE entry_id = '". (int)$entry_id ."' 647 AND email <> '" . serendipity_db_escape_string($posterMail) . "' 648 AND email <> '' 649 AND subscribed = 'true' $mysql_insert"; 650 $subscribers = serendipity_db_query($sql); 651 652 if (!is_array($subscribers)) { 653 return; 654 } 655 656 foreach ($subscribers as $subscriber) { 657 if ($subscriber['type'] == 'TRACKBACK') { 658 $text = sprintf( 659 SUBSCRIPTION_TRACKBACK_MAIL, 660 661 $subscriber['author'], 662 $serendipity['blogTitle'], 663 $title, 664 $poster, 665 $entryURI, 666 serendipity_rewriteURL('unsubscribe/' . urlencode($subscriber['email']) . '/' . (int)$entry_id, 'baseURL') 667 ); 668 } else { 669 $text = sprintf( 670 SUBSCRIPTION_MAIL, 671 672 $subscriber['author'], 673 $serendipity['blogTitle'], 674 $title, 675 $poster, 676 $entryURI, 677 serendipity_rewriteURL('unsubscribe/' . urlencode($subscriber['email']) . '/' . (int)$entry_id, 'baseURL') 678 ); 679 } 680 681 serendipity_sendMail($subscriber['email'], $subject, $text, $fromEmail); 682 } 683 } 684 685 /** 686 * Cancel a subscription to an entry 687 * 688 * @access public 689 * @param string E-Mail address to cancel subscription 690 * @param int The entry ID to unsubscribe from 691 * @return int Return number of unsubscriptions 692 */ 693 function serendipity_cancelSubscription($email, $entry_id) { 694 global $serendipity; 695 $sql = "UPDATE {$serendipity['dbPrefix']}comments 696 SET subscribed = 'false' 697 WHERE entry_id = '". (int)$entry_id ."' 698 AND email = '" . serendipity_db_escape_string($email) . "'"; 699 serendipity_db_query($sql); 700 701 return serendipity_db_affected_rows(); 702 } 703 704 /** 705 * Send a comment notice to the admin/author of an entry 706 * 707 * @access public 708 * @param int ID of the comment that has been made 709 * @param string Author's email address to send the mail to 710 * @param string The name of the sender 711 * @param string The URL of the sender 712 * @param int The ID of the entry that has been commented 713 * @param string The title of the entry that has been commented 714 * @param string The text of the comment 715 * @param string The type of the comment (normal|trackback) 716 * @param boolean Toggle Whether comments to this entry need approval 717 * @return boolean Return success of sending the mails 718 */ 719 function serendipity_sendComment($comment_id, $to, $fromName, $fromEmail, $fromUrl, $id, $title, $comment, $type = 'NORMAL', $moderate_comment = false) { 720 global $serendipity; 721 722 if (empty($fromName)) { 723 $fromName = ANONYMOUS; 724 } 725 726 $entryURI = serendipity_archiveURL($id, $title, 'baseURL'); 727 $path = ($type == 'TRACKBACK') ? 'trackback' : 'comment'; 728 $deleteURI = serendipity_rewriteURL(PATH_DELETE . '/'. $path .'/' . $comment_id . '/' . $id . '-' . serendipity_makeFilename($title) . '.html', 'baseURL'); 729 $approveURI = serendipity_rewriteURL(PATH_APPROVE . '/'. $path .'/' . $comment_id . '/' . $id . '-' . serendipity_makeFilename($title) . '.html', 'baseURL'); 730 731 if ($type == 'TRACKBACK') { 732 733 /******************* TRACKBACKS *******************/ 734 $subject = ($moderate_comment ? '[' . REQUIRES_REVIEW . '] ' : '') . NEW_TRACKBACK_TO . ' ' . $title; 735 $text = sprintf(A_NEW_TRACKBACK_BLAHBLAH, $title) 736 . "\n" 737 . "\n" . REQUIRES_REVIEW . ': ' . (($moderate_comment) ? YES : NO) . (isset($serendipity['moderate_reason']) ? ' (' . $serendipity['moderate_reason'] . ')' : '') 738 . "\n" . LINK_TO_ENTRY . ': ' . $entryURI 739 . "\n" . 'Weblog ' . NAME . ': ' . stripslashes($fromName) 740 . "\n" . LINK_TO_REMOTE_ENTRY . ': ' . $fromUrl 741 . "\n" 742 . "\n" . EXCERPT . ':' 743 . "\n" . strip_tags($comment) 744 . "\n" 745 . "\n" . '----' 746 . "\n" . YOU_HAVE_THESE_OPTIONS 747 . (($moderate_comment) ? "\n" . str_repeat(' ', 2) . THIS_TRACKBACK_NEEDS_REVIEW : '') 748 . "\n" . str_repeat(' ', 3) . str_pad(VIEW_ENTRY, 15) . ' -- '. $entryURI 749 . "\n" . str_repeat(' ', 3) . str_pad(DELETE_TRACKBACK, 15) . ' -- '. $deleteURI 750 . (($moderate_comment) ? "\n" . str_repeat(' ', 3) . str_pad(APPROVE_TRACKBACK, 15) . ' -- '. $approveURI : ''); 751 752 } else { 753 754 /******************* COMMENTS *********************/ 755 $subject = ($moderate_comment ? '[' . REQUIRES_REVIEW . '] ' : '') . NEW_COMMENT_TO . ' ' . $title; 756 $text = sprintf(A_NEW_COMMENT_BLAHBLAH, $serendipity['blogTitle'], $title) 757 . "\n" . LINK_TO_ENTRY . ': ' . $entryURI 758 . "\n" 759 . "\n" . REQUIRES_REVIEW . ': ' . (($moderate_comment) ? YES : NO) . (isset($serendipity['moderate_reason']) ? ' (' . $serendipity['moderate_reason'] . ')' : '') 760 . "\n" . USER . ' ' . IP_ADDRESS . ': ' . $_SERVER['REMOTE_ADDR'] 761 . "\n" . USER . ' ' . NAME . ': ' . $fromName 762 . "\n" . USER . ' ' . EMAIL . ': ' . $fromEmail 763 . "\n" . USER . ' ' . HOMEPAGE . ': ' . $fromUrl 764 . "\n" 765 . "\n" . COMMENTS . ': ' 766 . "\n" . strip_tags($comment) 767 . "\n" 768 . "\n" . '----' 769 . "\n" . YOU_HAVE_THESE_OPTIONS 770 . (($moderate_comment) ? "\n" . str_repeat(' ', 2) . THIS_COMMENT_NEEDS_REVIEW : '') 771 . "\n" . str_repeat(' ', 3) . str_pad(VIEW_COMMENT, 15) . ' -- '. $entryURI .'#c'. $comment_id 772 . "\n" . str_repeat(' ', 3) . str_pad(DELETE_COMMENT, 15) . ' -- '. $deleteURI 773 . (($moderate_comment) ? "\n" . str_repeat(' ', 3) . str_pad(APPROVE_COMMENT, 15) . ' -- '. $approveURI : ''); 774 } 775 776 return serendipity_sendMail($to, $subject, $text, $fromEmail, null, $fromName); 777 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sat Nov 24 09:00:37 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |