[ Index ] |
|
Code source de GeekLog 1.4.1 |
1 <?php 2 3 /* Reminder: always indent with 4 spaces (no tabs). */ 4 // +---------------------------------------------------------------------------+ 5 // | Geeklog 1.4 | 6 // +---------------------------------------------------------------------------+ 7 // | lib-trackback.php | 8 // | | 9 // | Functions needed to handle trackback comments. | 10 // +---------------------------------------------------------------------------+ 11 // | Copyright (C) 2005-2006 by the following authors: | 12 // | | 13 // | Author: Dirk Haun - dirk AT haun-online DOT de | 14 // +---------------------------------------------------------------------------+ 15 // | | 16 // | This program is free software; you can redistribute it and/or | 17 // | modify it under the terms of the GNU General Public License | 18 // | as published by the Free Software Foundation; either version 2 | 19 // | of the License, or (at your option) any later version. | 20 // | | 21 // | This program is distributed in the hope that it will be useful, | 22 // | but WITHOUT ANY WARRANTY; without even the implied warranty of | 23 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 24 // | GNU General Public License for more details. | 25 // | | 26 // | You should have received a copy of the GNU General Public License | 27 // | along with this program; if not, write to the Free Software Foundation, | 28 // | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 29 // | | 30 // +---------------------------------------------------------------------------+ 31 // 32 // $Id: lib-trackback.php,v 1.45 2006/10/24 07:50:17 ospiess Exp $ 33 34 if (strpos ($_SERVER['PHP_SELF'], 'lib-trackback.php') !== false) { 35 die ('This file can not be used on its own!'); 36 } 37 38 // result codes for TRB_saveTrackbackComment 39 define ('TRB_SAVE_OK', 0); 40 define ('TRB_SAVE_SPAM', -1); 41 define ('TRB_SAVE_REJECT', -2); 42 43 // set to true to log rejected Trackbacks 44 $_TRB_LOG_REJECTS = false; 45 46 47 /** 48 * Send a trackback response message 49 * 50 * @param int $error 0 = OK, 1 = an error occured 51 * @param string $errormsg the error message (ignored for $error == 0) 52 * @param int $http_status optional HTTP status code 53 * @param string $http_text optional HTTP status code text 54 * @return void 55 * 56 */ 57 function TRB_sendTrackbackResponse ($error, $errormsg = '', $http_status = 200, $http_text = "OK") 58 { 59 $display = '<?xml version="1.0" encoding="iso-8859-1"?>' . LB 60 . '<response>' . LB 61 . '<error>' . $error . '</error>' . LB; 62 if (($error != 0) && !empty ($errormsg)) { 63 // we're creating XML, so encode these ... 64 $errormsg = str_replace (array ('<', '>', "'"), 65 array ('<', '>', '''), $errormsg); 66 $display .= '<message>' . $errormsg . '</message>' . LB; 67 } 68 $display .= '</response>'; 69 70 if ($http_status != 200) 71 { 72 header ("HTTP/1.1 $http_status $http_text"); 73 header ("Status: $http_status $http_text"); 74 } 75 header ('Content-Type: text/xml'); 76 echo $display; 77 } 78 79 /** 80 * Helper function for the curious: Log rejected trackbacks 81 * 82 * @param string $logmsg Message to log 83 * @return void 84 * 85 */ 86 function TRB_logRejected ($reason, $url = '') 87 { 88 global $_TRB_LOG_REJECTS; 89 90 if ($_TRB_LOG_REJECTS) { 91 92 $logmsg = 'Trackback from IP ' . $_SERVER['REMOTE_ADDR'] 93 . ' rejected for ' . $reason . ', URL: ' . $url; 94 95 if (function_exists ('SPAMX_log')) { 96 SPAMX_log ($logmsg); 97 } else { 98 COM_errorLog ($logmsg); 99 } 100 } 101 } 102 103 /** 104 * Creates a piece of RDF pointing out the trackback URL 105 * 106 * Note: When putting this in an HTML page, it may be advisable to enclose it 107 * in HTML comments, i.e. <!-- ... --> 108 * 109 * @param string $article_url URL of our entry 110 * @param string $title title of that entry 111 * @param string $trackback_url trackback URL for our entry 112 * @return string RDF code with our information embedded 113 * 114 */ 115 function TRB_trackbackRdf ($article_url, $title, $trackback_url) 116 { 117 // we're creating XML, so encode these ... 118 $title = str_replace (array ('<', '>', "'"), 119 array ('<', '>', '''), $title); 120 121 $retval = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"' . LB 122 . ' xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"' . LB 123 . ' xmlns:dc="http://purl.org/dc/elements/1.1/">' . LB; 124 $retval .= '<rdf:Description' . LB 125 . ' rdf:about="' . $article_url . '"' . LB 126 . ' trackback:ping="' . $trackback_url . '"' .LB 127 . ' dc:title="' . $title . '"' . LB 128 . ' dc:identifier="' . $article_url . '" />' . LB; 129 $retval .= '</rdf:RDF>'; 130 131 return $retval; 132 } 133 134 /** 135 * Returns the trackback URL for an entry 136 * 137 * Note: Trackback pings default to stories, so we leave off the type if it 138 * is 'article' to create shorter URLs. 139 * 140 * @param string $id the entry's ID 141 * @param string $type type of the entry ('article' = story, etc.) 142 * @return string trackback URL for that entry 143 * 144 */ 145 function TRB_makeTrackbackUrl ($id, $type = 'article') 146 { 147 global $_CONF; 148 149 $url = $_CONF['site_url'] . '/trackback.php?id=' . $id; 150 if (!empty ($type) && ($type != 'article')) { 151 $url .= '&type=' . $type; 152 } 153 154 return COM_buildUrl ($url); 155 } 156 157 /** 158 * Filter the title for a trackback comment we've received 159 * 160 * @param string $title title of the comment 161 * @return string filtered title 162 * 163 */ 164 function TRB_filterTitle ($title) 165 { 166 return htmlspecialchars (COM_checkWords (strip_tags (COM_stripslashes ($title)))); 167 } 168 169 /** 170 * Filter the blog name for a trackback comment we've received 171 * 172 * @param string $blogname blog name for the comment 173 * @return string filtered blog name 174 * 175 */ 176 function TRB_filterBlogname ($blogname) 177 { 178 return htmlspecialchars (COM_checkWords (strip_tags (COM_stripslashes ($blogname)))); 179 } 180 181 /** 182 * Filter the excerpt of a trackback comment we've received 183 * 184 * Note: Does not truncate the excerpt. 185 * 186 * @param string $excerpt excerpt of the trackback comment 187 * @return string filtered excerpt 188 * 189 */ 190 function TRB_filterExcerpt ($excerpt) 191 { 192 return COM_checkWords (strip_tags (COM_stripslashes ($excerpt))); 193 } 194 195 /** 196 * Check if the current user is allowed to delete trackback comments. 197 * 198 * @param string $sid ID of the parent object of the comment 199 * @param string $type type of the parent object ('article' = story, etc.) 200 * @return bool true = user can delete the comment, false = nope 201 * 202 */ 203 function TRB_allowDelete ($sid, $type) 204 { 205 global $_TABLES; 206 207 $allowed = false; 208 209 if ($type == 'article') { 210 $sid = addslashes ($sid); 211 $result = DB_query ("SELECT owner_id,group_id,perm_owner,perm_group,perm_members,perm_anon FROM {$_TABLES['stories']} WHERE sid = '$sid'" . COM_getPermSql ('AND', 0, 3) . COM_getTopicSql ('AND')); 212 $A = DB_fetchArray ($result); 213 214 if (SEC_hasRights ('story.edit') && (SEC_hasAccess ($A['owner_id'], 215 $A['group_id'], $A['perm_owner'], $A['perm_group'], 216 $A['perm_members'], $A['perm_anon']) == 3)) { 217 $allowed = true; 218 } else { 219 $allowed = false; 220 } 221 } else { 222 $allowed = PLG_handlePingComment ($type, $sid, 'delete'); 223 } 224 225 return $allowed; 226 } 227 228 /** 229 * Check a trackback / pingback for spam 230 * 231 * @param string $url URL of the trackback comment 232 * @param string $title title of the comment (set to $url if empty) 233 * @param string $blog name of the blog that sent the comment 234 * @param string $excerpt excerpt from the comment 235 * @return int TRB_SAVE_OK or TRB_SAVE_SPAM 236 * 237 */ 238 function TRB_checkForSpam ($url, $title = '', $blog = '', $excerpt = '') 239 { 240 global $_CONF; 241 242 $comment = TRB_formatComment ($url, $title, $blog, $excerpt); 243 $result = PLG_checkforSpam ($comment, $_CONF['spamx']); 244 245 if ($result > 0) { 246 return TRB_SAVE_SPAM; 247 } 248 249 return TRB_SAVE_OK; 250 } 251 252 /** 253 * Save a trackback (or pingback) comment. 254 * 255 * Also filters parameters and handles multiple trackbacks from the same source. 256 * 257 * Note: Spam check should have been done before calling this function. 258 * 259 * @param string $sid entry id 260 * @param string $type type of entry ('article' = story, etc.) 261 * @param string $url URL of the trackback comment 262 * @param string $title title of the comment (set to $url if empty) 263 * @param string $blog name of the blog that sent the comment 264 * @param string $excerpt excerpt from the comment 265 * @return int < 0: error, > 0: ID of the trackback comment 266 * 267 */ 268 function TRB_saveTrackbackComment ($sid, $type, $url, $title = '', $blog = '', $excerpt = '') 269 { 270 global $_CONF, $_TABLES; 271 272 $url = COM_applyFilter ($url); 273 $title = TRB_filterTitle ($title); 274 $blog = TRB_filterBlogname ($blog); 275 $excerpt = TRB_filterExcerpt ($excerpt); 276 277 // MT does that, so follow its example ... 278 if (MBYTE_strlen ($excerpt) > 255) { 279 $excerpt = MBYTE_substr ($excerpt, 0, 252) . '...'; 280 } 281 282 $title = str_replace (array ('$', '{', '}'), 283 array ('$', '{', '~'), $title); 284 $excerpt = str_replace (array ('$', '{', '}'), 285 array ('$', '{', '~'), $excerpt); 286 $blog = str_replace (array ('$', '{', '}'), 287 array ('$', '{', '~'), $blog); 288 289 $url = addslashes ($url); 290 $title = addslashes ($title); 291 $blog = addslashes ($blog); 292 $excerpt = addslashes ($excerpt); 293 294 if ($_CONF['multiple_trackbacks'] == 0) { 295 // multiple trackbacks not allowed - check if we have this one already 296 if (DB_count ($_TABLES['trackback'], array ('url', 'sid', 'type'), 297 array ($url, $sid, $type)) >= 1) { 298 return TRB_SAVE_REJECT; 299 } 300 } else if ($_CONF['multiple_trackbacks'] == 1) { 301 // delete any earlier trackbacks from the same URL 302 DB_delete ($_TABLES['trackback'], array ('url', 'sid', 'type'), 303 array ($url, $sid, $type)); 304 } // else: multiple trackbacks allowed 305 306 DB_save ($_TABLES['trackback'], 'sid,url,title,blog,excerpt,date,type,ipaddress', 307 "'$sid','$url','$title','$blog','$excerpt',NOW(),'$type','{$_SERVER['REMOTE_ADDR']}'"); 308 309 $comment_id = DB_insertId (); 310 311 if ($type == 'article') { 312 DB_query ("UPDATE {$_TABLES['stories']} SET trackbacks = trackbacks + 1 WHERE (sid = '$sid')"); 313 } 314 315 return $comment_id; 316 } 317 318 /** 319 * Delete a trackback comment 320 * 321 * Note: Permission checks have to be done by the caller. 322 * 323 * @param int $cid ID of the trackback comment 324 * @return void 325 * 326 */ 327 function TRB_deleteTrackbackComment ($cid) 328 { 329 global $_TABLES; 330 331 $cid = addslashes ($cid); 332 DB_delete ($_TABLES['trackback'], 'cid', $cid); 333 } 334 335 /** 336 * Format one trackback comment for display 337 * 338 * Note: $excerpt is not truncated - this should have been done elsewhere 339 * 340 * @param string $url URL of the trackback comment 341 * @param string $title title of the comment (set to $url if empty) 342 * @param string $blog name of the blog that sent the comment 343 * @param string $excerpt excerpt from the comment 344 * @param timestamp $date date and time when the comment was sent 345 * @param bool $delete_option whether to display a link to delete the trackback comment 346 * @param string $cid id of this trackback comment 347 * @param string $ipaddress IP address the comment was sent from 348 * @return string HTML of the formatted trackback comment 349 * 350 */ 351 function TRB_formatComment ($url, $title = '', $blog = '', $excerpt = '', $date = 0, $delete_option = false, $cid = '', $ipaddress = '') 352 { 353 global $_CONF, $LANG01, $LANG_TRB, $MESSAGE; 354 355 if (empty ($title)) { 356 $title = $url; 357 } 358 359 if ($date == 0) { 360 $date = time (); 361 } 362 $curtime = COM_getUserDateTimeFormat ($date); 363 364 $template = new Template ($_CONF['path_layout'] . 'trackback'); 365 $template->set_file (array ('comment' => 'formattedcomment.thtml')); 366 $template->set_var ('site_url', $_CONF['site_url']); 367 $template->set_var ('layout_url', $_CONF['layout_url']); 368 369 $template->set_var ('lang_from', $LANG_TRB['from']); 370 $template->set_var ('lang_tracked_on', $LANG_TRB['tracked_on']); 371 $template->set_var ('lang_readmore', $LANG_TRB['read_more']); 372 373 $anchor = '<a href="' . $url . '">'; 374 $readmore = $anchor . $LANG_TRB['read_more'] . '</a>'; 375 376 $template->set_var ('readmore_link', $readmore); 377 $template->set_var ('start_readmore_anchortag', $anchor); 378 $template->set_var ('end_readmore_anchortag', '</a>'); 379 380 $template->set_var ('trackback_url', $url); 381 $template->set_var ('trackback_title', $title); 382 $template->set_var ('trackback_blog_name', $blog); 383 $template->set_var ('trackback_date', $curtime[0]); 384 385 if (empty ($blog)) { 386 $template->set_var ('trackback_from_blog_name', ''); 387 } else { 388 $template->set_var ('trackback_from_blog_name', $LANG_TRB['from'] . ' ' 389 . $blog); 390 } 391 if (empty ($excerpt)) { 392 $template->set_var ('trackback_excerpt', ''); 393 $template->set_var ('trackback_excerpt_readmore', ''); 394 $template->set_var ('excerpt_br', ''); 395 } else { 396 $template->set_var ('trackback_excerpt', $excerpt); 397 $template->set_var ('trackback_excerpt_readmore', 398 $excerpt . ' ' . $readmore); 399 $template->set_var ('excerpt_br', '<br>'); 400 } 401 402 $deloption = ''; 403 if ($delete_option) { 404 $deloption .= '[ '; 405 $deloption .= '<a href="' . $_CONF['site_admin_url'] 406 . '/trackback.php?mode=delete&cid=' . $cid 407 . '" onclick="return confirm(\'' . $MESSAGE[76] . '\');">' 408 . $LANG01[28] . '</a>'; 409 if (!empty ($ipaddress)) { 410 if (empty ($_CONF['ip_lookup'])) { 411 $deloption .= ' | ' . $ipaddress; 412 } else { 413 $iplookup = str_replace ('*', $ipaddress, $_CONF['ip_lookup']); 414 $deloption .= ' | <a href="' . $iplookup . '">' . $ipaddress 415 . '</a>'; 416 } 417 } 418 $deloption .= ' ]'; 419 } 420 $template->set_var ('delete_option', $deloption); 421 422 $template->parse ('output', 'comment'); 423 return $template->finish ($template->get_var ('output')); 424 } 425 426 /** 427 * Perform a backlink check on an HTML page 428 * 429 * @param string $body complete HTML page to check 430 * @param string $urlToCheck URL to find in that page 431 * @return boolean true: found a link to us; false: no link to us 432 * 433 */ 434 function TRB_containsBacklink ($body, $urlToCheck) 435 { 436 global $_CONF; 437 438 if (($_CONF['check_trackback_link'] & 3) == 0) { 439 // we shouldn't be here - don't do anything 440 return true; 441 } 442 443 $retval = false; 444 445 preg_match_all ("/<a[^>]*href=[\"']([^\"']*)[\"'][^>]*>/i", 446 $body, $matches); 447 for ($i = 0; $i < count ($matches[0]); $i++) { 448 if ($_CONF['check_trackback_link'] & 1) { 449 if (strpos ($matches[1][$i], $urlToCheck) === 0) { 450 // found it! 451 $retval = true; 452 break; 453 } 454 } else { 455 if ($matches[1][$i] == $urlToCheck) { 456 // found it! 457 $retval = true; 458 break; 459 } 460 } 461 } 462 463 return $retval; 464 } 465 466 /** 467 * Check if a given web page links to us 468 * 469 * @param string $sid ID of entry that got pinged 470 * @param string $type type of that entry ('article' for stories, etc.) 471 * @para string $urlToGet URL of the page that supposedly links to us 472 * @return bool true = links to us, false = doesn't 473 * 474 */ 475 function TRB_linksToUs ($sid, $type, $urlToGet) 476 { 477 global $_CONF; 478 479 if (!isset ($_CONF['check_trackback_link'])) { 480 $_CONF['check_trackback_link'] = 2; 481 } 482 483 if (($_CONF['check_trackback_link'] & 3) == 0) { 484 // we shouldn't be here - don't do anything 485 return true; 486 } 487 488 require_once ('HTTP/Request.php'); 489 490 $retval = false; 491 492 if ($_CONF['check_trackback_link'] & 2) { 493 // build the URL of the pinged page on our site 494 if ($type == 'article') { 495 $urlToCheck = COM_buildUrl ($_CONF['site_url'] 496 . '/article.php?story=' . $sid); 497 } else { 498 $urlToCheck = PLG_getItemInfo ($type, $sid, 'url'); 499 } 500 } else { 501 // check only against the site_url 502 $urlToCheck = $_CONF['site_url']; 503 } 504 505 $req = new HTTP_Request ($urlToGet); 506 $req->addHeader ('User-Agent', 'GeekLog/' . VERSION); 507 $response = $req->sendRequest (); 508 if (PEAR::isError ($response)) { 509 COM_errorLog ("Trackback verification: " . $response->getMessage() 510 . " when requesting $urlToGet"); 511 } else { 512 if ($req->getResponseCode () == 200) { 513 $body = $req->getResponseBody (); 514 $retval = TRB_containsBacklink ($body, $urlToCheck); 515 } else { 516 COM_errorLog ("Trackback verification: Got HTTP response code " 517 . $req->getResponseCode () 518 . " when requesting $urlToGet"); 519 } 520 } 521 522 return $retval; 523 } 524 525 /** 526 * Handles a trackback ping for an entry. 527 * 528 * Also takes care of the speedlimit and spam. Assumes that the caller of this 529 * function has already checked permissions! 530 * 531 * Note: Error messages are XML-formatted and echo'd out directly, as they 532 * are supposed to be processed by some sort of software. 533 * 534 * @param string $sid ID of entry that got pinged 535 * @param string $type type of that entry ('article' for stories, etc.) 536 * @return bool true = success, false = an error occured 537 * 538 * P.S. "Critical" errors are rejected with a HTTP 403 Forbidden status code. 539 * According to RFC2616, this status code means 540 * "The server understood the request, but is refusing to fulfill it. 541 * Authorization will not help and the request SHOULD NOT be repeated." 542 * See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4 543 * 544 */ 545 function TRB_handleTrackbackPing ($sid, $type = 'article') 546 { 547 global $_CONF, $_TABLES; 548 549 // Note: Error messages are hard-coded in English since there is no way of 550 // knowing which language the sender of the trackback ping may prefer. 551 $TRB_ERROR = array ( 552 'no_url' => 'No URL given.', 553 'rejected' => 'Multiple posts not allowed.', 554 'spam' => 'Spam detected.', 555 'speedlimit' => 'Your last trackback comment was %d seconds ago. This site requires at least %d seconds between trackback comments.', 556 'no_link' => 'Trackback rejected as you do not seem to link to us.' 557 ); 558 559 // the speed limit applies to trackback comments, too 560 if (isset ($_CONF['trackbackspeedlimit'])) { 561 $speedlimit = $_CONF['trackbackspeedlimit']; 562 } else { 563 $speedlimit = $_CONF['commentspeedlimit']; 564 } 565 COM_clearSpeedlimit ($speedlimit, 'trackback'); 566 $last = COM_checkSpeedlimit ('trackback'); 567 if ($last > 0) { 568 TRB_sendTrackbackResponse (1, sprintf ($TRB_ERROR['speedlimit'], 569 $last, $speedlimit), 403, 'Forbidden'); 570 TRB_logRejected ('Speedlimit', $_POST['url']); 571 572 return false; 573 } 574 575 // update speed limit now in any case 576 COM_updateSpeedlimit ('trackback'); 577 578 if (isset ($_POST['url'])) { // a URL is mandatory ... 579 580 if (substr ($_POST['url'], 0, 4) != 'http') { 581 TRB_sendTrackbackResponse (1, $TRB_ERROR['no_url'], 582 403, 'Forbidden'); 583 TRB_logRejected ('No valid URL', $_POST['url']); 584 585 return false; 586 } 587 588 // do spam check on the unfiltered post 589 $result = TRB_checkForSpam ($_POST['url'], $_POST['title'], 590 $_POST['blog_name'], $_POST['excerpt']); 591 592 if ($result == TRB_SAVE_SPAM) { 593 TRB_sendTrackbackResponse (1, $TRB_ERROR['spam'], 403, 'Forbidden'); 594 TRB_logRejected ('Spam detected', $_POST['url']); 595 596 return false; 597 } 598 599 if (!isset ($_CONF['check_trackback_link'])) { 600 $_CONF['check_trackback_link'] = 2; 601 } 602 603 if ($_CONF['check_trackback_link'] & 4) { 604 $parts = parse_url ($_POST['url']); 605 if (empty ($parts['host'])) { 606 TRB_sendTrackbackResponse (1, $TRB_ERROR['no_url'], 607 403, 'Forbidden'); 608 TRB_logRejected ('No valid URL', $_POST['url']); 609 610 return false; 611 } else { 612 $ip = gethostbyname ($parts['host']); 613 if ($ip != $_SERVER['REMOTE_ADDR']) { 614 TRB_sendTrackbackResponse (1, $TRB_ERROR['spam'], 615 403, 'Forbidden'); 616 TRB_logRejected ('IP address mismatch', $_POST['url']); 617 618 return false; 619 } 620 } 621 } 622 623 if ($_CONF['check_trackback_link'] & 3) { 624 if (!TRB_linksToUs ($sid, $type, $_POST['url'])) { 625 TRB_sendTrackbackResponse (1, $TRB_ERROR['no_link'], 626 403, 'Forbidden'); 627 $comment = TRB_formatComment ($_POST['url'], $_POST['title'], 628 $_POST['blog_name'], $_POST['excerpt']); 629 PLG_spamAction ($comment, $_CONF['spamx']); 630 TRB_logRejected ('No link to us', $_POST['url']); 631 632 return false; 633 } 634 } 635 636 $saved = TRB_saveTrackbackComment ($sid, $type, $_POST['url'], 637 $_POST['title'], $_POST['blog_name'], $_POST['excerpt']); 638 639 if ($saved == TRB_SAVE_REJECT) { 640 TRB_sendTrackbackResponse (1, $TRB_ERROR['rejected'], 641 403, 'Forbidden'); 642 TRB_logRejected ('Multiple Trackbacks', $_POST['url']); 643 644 return false; 645 } 646 647 if (isset ($_CONF['notification']) && 648 in_array ('trackback', $_CONF['notification'])) { 649 TRB_sendNotificationEmail ($saved, 'trackback'); 650 } 651 652 TRB_sendTrackbackResponse (0); 653 654 return true; 655 } else { 656 TRB_sendTrackbackResponse (1, $TRB_ERROR['no_url']); 657 TRB_logRejected ('No URL', $_POST['url']); 658 } 659 660 return false; 661 } 662 663 /** 664 * Render all the trackback comments for a specific entry 665 * 666 * @param string $sid entry id 667 * @param string $type type of entry ('article' = story, etc.) 668 * @param string $title the entry's title 669 * @param string $permalink link to the entry 670 * @param string trackback_url trackback URL for this entry 671 * @return string HTML (formatted list of trackback comments) 672 * 673 */ 674 function TRB_renderTrackbackComments ($sid, $type, $title, $permalink, $trackback_url = '') 675 { 676 global $_CONF, $_TABLES, $LANG_TRB; 677 678 $link_and_title = '<a href="' . $permalink . '">' . $title . '</a>'; 679 if (empty ($trackback_url)) { 680 $trackback_url = TRB_makeTrackbackUrl ($sid, $type); 681 } 682 683 $template = new Template ($_CONF['path_layout'] . 'trackback'); 684 $template->set_file (array ('trackback' => 'trackback.thtml', 685 'comment' => 'trackbackcomment.thtml')); 686 $template->set_var ('site_url', $_CONF['site_url']); 687 $template->set_var ('layout_url', $_CONF['layout_url']); 688 689 $template->set_var ('lang_trackback', $LANG_TRB['trackback']); 690 $template->set_var ('lang_trackback_url', $LANG_TRB['this_trackback_url']); 691 692 $template->set_var ('permalink', $permalink); 693 $template->set_var ('permalink_and_title', $link_and_title); 694 $template->set_var ('trackback_url', $trackback_url); 695 696 $result = DB_query ("SELECT cid,url,title,blog,excerpt,ipaddress,UNIX_TIMESTAMP(date) AS day " 697 . "FROM {$_TABLES['trackback']} WHERE sid = '$sid' AND type = '$type' ORDER BY date"); 698 $numrows = DB_numRows ($result); 699 700 $template->set_var ('trackback_comment_count', $numrows); 701 $num_comments = sprintf ($LANG_TRB['num_comments'], $numrows); 702 $template->set_var ('trackback_comment_text', $num_comments); 703 if ($numrows == 0) { 704 $template->set_var ('lang_trackback_comments', 705 $LANG_TRB['no_comments']); 706 $template->set_var ('lang_trackback_comments_no_link', 707 $LANG_TRB['no_comments']); 708 } else { 709 $template->set_var ('lang_trackback_comments', 710 sprintf ($LANG_TRB['intro_text'], $link_and_title)); 711 $template->set_var ('lang_trackback_comments_no_link', 712 sprintf ($LANG_TRB['intro_text'], $title)); 713 } 714 715 $delete_option = TRB_allowDelete ($sid, $type); 716 717 for ($i = 0; $i < $numrows; $i++) { 718 $A = DB_fetchArray ($result); 719 $comment = TRB_formatComment ($A['url'], $A['title'], $A['blog'], 720 $A['excerpt'], $A['day'], $delete_option, $A['cid'], 721 $A['ipaddress']); 722 $template->set_var ('formatted_comment', $comment); 723 $template->parse ('trackback_comments', 'comment', true); 724 } 725 $template->parse ('output', 'trackback'); 726 727 return $template->finish ($template->get_var ('output')); 728 } 729 730 /** 731 * Send a trackback ping 732 * 733 * Based on a code snippet by Jannis Hermanns, 734 * http://www.jannis.to/programming/trackback.html 735 * 736 * @param string $targeturl URL to ping 737 * @param string $url URL of our entry 738 * @param string $title title of our entry 739 * @param string $excerpt text excerpt from our entry 740 * @param string $blog name of our Geeklog site 741 * @return mixed true = success, otherwise: error message 742 * 743 */ 744 function TRB_sendTrackbackPing ($targeturl, $url, $title, $excerpt, $blog = '') 745 { 746 global $_CONF, $LANG_TRB, $LANG_CHARSET; 747 748 if (empty ($blog)) { 749 $blog = $_CONF['site_name']; 750 } 751 752 $target = parse_url ($targeturl); 753 if (!isset ($target['query'])) { 754 $target['query'] = ''; 755 } else if (!empty ($target['query'])) { 756 $target['query'] = '?' . $target['query']; 757 } 758 if (!isset ($target['port']) || !is_numeric ($target['port'])) { 759 $target['port'] = 80; 760 } 761 762 $sock = fsockopen ($target['host'], $target['port']); 763 if (!is_resource ($sock)) { 764 COM_errorLog ('Trackback: Could not connect to ' . $targeturl); 765 766 return $LANG_TRB['error_socket']; 767 } 768 769 $toSend = 'url=' . rawurlencode ($url) . '&title=' . rawurlencode ($title) 770 . '&blog_name=' . rawurlencode ($blog) . '&excerpt=' 771 . rawurlencode ($excerpt); 772 773 if (empty ($LANG_CHARSET)) { 774 $charset = $_CONF['default_charset']; 775 776 if (empty ($charset)) { 777 $charset = 'iso-8859-1'; 778 } 779 } else { 780 $charset = $LANG_CHARSET; 781 } 782 783 fputs ($sock, 'POST ' . $target['path'] . $target['query'] . " HTTP/1.0\r\n"); 784 fputs ($sock, 'Host: ' . $target['host'] . "\r\n"); 785 fputs ($sock, 'Content-type: application/x-www-form-urlencoded; charset=' 786 . $charset . "\r\n"); 787 fputs ($sock, 'Content-length: ' . MBYTE_strlen ($toSend) . "\r\n"); 788 fputs ($sock, 'User-Agent: GeekLog/' . VERSION . "\r\n"); 789 fputs ($sock, "Connection: close\r\n\r\n"); 790 fputs ($sock, $toSend); 791 792 $res = ''; 793 while (!feof ($sock)) { 794 $res .= fgets ($sock, 128); 795 } 796 797 fclose($sock); 798 799 // firing up the XML parser for this would be overkill ... 800 $r1 = strpos ($res, '<error>'); 801 $r2 = strpos ($res, '</error>'); 802 if (($r1 === false) || ($r2 === false)) { 803 return $LANG_TRB['error_response']; 804 } 805 $r1 += strlen ('<error>'); 806 $e = trim (substr ($res, $r1, $r2 - $r1)); 807 808 if ($e != 0) { 809 $r1 = strpos ($res, '<message>'); 810 $r2 = strpos ($res, '</message>'); 811 $r1 += strlen ('<message>'); 812 if (($r1 === false) || ($r2 === false)) { 813 return $LANG_TRB['error_unspecified']; 814 } 815 $m = trim (substr ($res, $r1, $r2 - $r1)); 816 817 return $m; 818 } 819 820 return true; 821 } 822 823 /** 824 * Attempt to auto-detect the Trackback URL of a post. 825 * 826 * @param string $url URL of post with embedded RDF for the Trackback URL 827 * @return mixed Trackback URL, or false on error 828 * 829 * Note: The RDF, if found, is only parsed using a regular expression. Using 830 * the XML parser may be more successful on some occassions ... 831 * 832 */ 833 function TRB_detectTrackbackUrl ($url) 834 { 835 require_once ('HTTP/Request.php'); 836 837 $retval = false; 838 839 $req = new HTTP_Request ($url); 840 $req->setMethod (HTTP_REQUEST_METHOD_GET); 841 $req->addHeader ('User-Agent', 'GeekLog/' . VERSION); 842 843 $response = $req->sendRequest (); 844 if (PEAR::isError ($response)) { 845 COM_errorLog ('TRB_detectTrackbackUrl: ' . $response->getMessage()); 846 847 return false; 848 } 849 850 $page = $req->getResponseBody (); 851 852 // search for the RDF first 853 $startpos = strpos ($page, '<rdf:RDF '); 854 if ($startpos !== false) { 855 $endpos = strpos ($page, '</rdf:RDF>', $startpos); 856 857 $endpos += strlen ('</rdf:RDF>'); 858 $rdf = substr ($page, $startpos, $endpos - $startpos); 859 860 // Okay, we COULD fire up the XML parser now. But then again ... 861 if (preg_match ('/trackback:ping="(.*)"/', $rdf, $matches) == 1) { 862 if (!empty ($matches[1])) { 863 $retval = $matches[1]; 864 } 865 } 866 } 867 868 // no luck with the RDF? try searching for a rel="trackback" link 869 if ($retval === false) { 870 // remove all linefeeds first to help the regexp below 871 $page = preg_replace( "/(\015\012)|(\015)|(\012)/", '', $page); 872 873 preg_match_all( "/<a[^>]*href=[\"']([^\"']*)[\"'][^>]*>(.*?)<\/a>/i", $page, $matches ); 874 for ($i = 0; $i < count ($matches[0]); $i++) { 875 $link = $matches[0][$i]; 876 if (strpos ($link, 'rel="trackback"') !== false) { 877 $retval = $matches[1][$i]; 878 break; 879 } 880 } 881 } 882 883 return $retval; 884 } 885 886 /** 887 * Send a notification email when a new trackback comment has been posted 888 * 889 * @param int $cid ID of the trackback comment 890 * @param string $what type of notification: 'trackback' or 'pingback' 891 * @return void 892 * 893 */ 894 function TRB_sendNotificationEmail ($cid, $what = 'trackback') 895 { 896 global $_CONF, $_TABLES, $LANG03, $LANG08, $LANG09, $LANG29, $LANG_TRB; 897 898 $cid = addslashes ($cid); 899 $result = DB_query ("SELECT sid,type,title,excerpt,url,blog,ipaddress FROM {$_TABLES['trackback']} WHERE (cid = '$cid')"); 900 $A = DB_fetchArray ($result); 901 $type = $A['type']; 902 $id = $A['sid']; 903 904 $mailbody = ''; 905 if (!empty ($A['title'])) { 906 $mailbody .= $LANG03[16] . ': ' . $A['title'] . "\n"; 907 } 908 $mailbody .= $LANG_TRB['blog_name'] . ': '; 909 if (!empty ($A['blog'])) { 910 $mailbody .= $A['blog'] . ' '; 911 } 912 $mailbody .= '(' . $A['ipaddress'] . ")\n"; 913 $mailbody .= $LANG29[12] . ': ' . $A['url'] . "\n"; 914 915 if ($type != 'article') { 916 $mailbody .= $LANG09[5] . ': ' . $type . "\n"; 917 } 918 919 if (!empty ($A['excerpt'])) { 920 // the excerpt is max. 255 characters long anyway, so we add it 921 // in its entirety 922 $mailbody .= $A['excerpt'] . "\n\n"; 923 } 924 925 if ($type == 'article') { 926 $commenturl = COM_buildUrl ($_CONF['site_url'] . '/article.php?story=' 927 . $id) . '#trackback'; 928 } else { 929 $commenturl = PLG_getItemInfo ($type, $id, 'url'); 930 } 931 932 $mailbody .= $LANG08[33] . ' <' . $commenturl . ">\n\n"; 933 934 $mailbody .= "\n------------------------------\n"; 935 $mailbody .= "\n$LANG08[34]\n"; 936 $mailbody .= "\n------------------------------\n"; 937 938 if ($what == 'pingback') { 939 $mailsubject = $_CONF['site_name'] . ' ' . $LANG_TRB['pingback']; 940 } else { 941 $mailsubject = $_CONF['site_name'] . ' ' . $LANG_TRB['trackback']; 942 $mailbody .= "\n" . $LANG_TRB['delete_trackback'] . "<" . $_CONF['site_admin_url'] . '/trackback.php?mode=delete&cid=' . $cid . ">\n"; 943 } 944 945 COM_mail ($_CONF['site_mail'], $mailsubject, $mailbody); 946 } 947 948 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Wed Nov 21 12:27:40 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |