[ Index ]
 

Code source de GeekLog 1.4.1

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/system/ -> lib-trackback.php (source)

   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 ('&lt;', '&gt;', '&apos;'), $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 ('&lt;', '&gt;', '&apos;'), $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 .= '&amp;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 ('&#36;', '&#123;', '&#126;'), $title);
 284      $excerpt = str_replace (array ('$',     '{',      '}'),
 285                              array ('&#36;', '&#123;', '&#126;'), $excerpt);
 286      $blog    = str_replace (array ('$',     '{',      '}'),
 287                              array ('&#36;', '&#123;', '&#126;'), $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&amp;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  ?>


Généré le : Wed Nov 21 12:27:40 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics