[ Index ]
 

Code source de GeekLog 1.4.1

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/public_html/ -> pingback.php (source)

   1  <?php
   2  
   3  /* Reminder: always indent with 4 spaces (no tabs). */
   4  // +---------------------------------------------------------------------------+
   5  // | Geeklog 1.4                                                               |
   6  // +---------------------------------------------------------------------------+
   7  // | pingback.php                                                              |
   8  // |                                                                           |
   9  // | Handle pingbacks for stories and plugins.                                 |
  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: pingback.php,v 1.16 2006/09/30 19:15:27 dhaun Exp $
  33  
  34  require_once  ('lib-common.php');
  35  
  36  // once received, we're handling pingbacks like trackbacks,
  37  // so we use the trackback library even when trackback may be disabled
  38  require_once ($_CONF['path_system'] . 'lib-trackback.php');
  39  
  40  // PEAR class to handle XML-RPC
  41  require_once ('XML/RPC/Server.php');
  42  
  43  // Note: Error messages are hard-coded in English since there is no way of
  44  // knowing which language the sender of the pingback may prefer.
  45  $PNB_ERROR = array (
  46      'success'     => 'Thank you.', // success message; not an error ...
  47      'skipped'     => '(skipped)',  // not an error
  48      'spam'        => 'Spam detected.',
  49      'speedlimit'  => 'Your last pingback was %d seconds ago. This site requires at least %d seconds between pingbacks.',
  50      'disabled'    => 'Pingback is disabled.',
  51      'uri_invalid' => 'Invalid targetURI.',
  52      'no_access'   => 'Access denied.',
  53      'multiple'    => 'Multiple posts not allowed.'
  54  );
  55  
  56  
  57  /**
  58  * Handle a pingback for an entry.
  59  *
  60  * Also takes care of the speedlimit and spam. Assumes that the caller of this
  61  * function has already checked permissions!
  62  *
  63  * @param    string  $id     ID of entry that got pinged
  64  * @param    string  $type   type of that entry ('article' for stories, etc.)
  65  * @param    string  $url    URL of the page that pinged us
  66  * @param    string  $oururl URL that got pinged on our site
  67  * @return   object          XML-RPC response
  68  *
  69  */
  70  function PNB_handlePingback ($id, $type, $url, $oururl)
  71  {
  72      global $_CONF, $_TABLES, $PNB_ERROR;
  73  
  74      require_once ('HTTP/Request.php');
  75  
  76      if (!isset ($_CONF['check_trackback_link'])) {
  77          $_CONF['check_trackback_link'] = 2;
  78      }
  79  
  80      // handle pingbacks to articles on our own site
  81      $skip_speedlimit = false;
  82      if ($_SERVER['REMOTE_ADDR'] == $_SERVER['SERVER_ADDR']) {
  83          if (!isset ($_CONF['pingback_self'])) {
  84              $_CONF['pingback_self'] = 0; // default: skip self-pingbacks
  85          }
  86  
  87          if ($_CONF['pingback_self'] == 0) {
  88              return new XML_RPC_Response (new XML_RPC_Value ($PNB_ERROR['skipped']));
  89          } else if ($_CONF['pingback_self'] == 2) {
  90              $skip_speedlimit = true;
  91          }
  92      }
  93  
  94      COM_clearSpeedlimit ($_CONF['commentspeedlimit'], 'pingback');
  95      if (!$skip_speedlimit) {
  96          $last = COM_checkSpeedlimit ('pingback');
  97          if ($last > 0) {
  98              return new XML_RPC_Response (0, 49,
  99                      sprintf ($PNB_ERROR['speedlimit'], $last,
 100                               $_CONF['commentspeedlimit']));
 101          }
 102      }
 103  
 104      // update speed limit in any case
 105      COM_updateSpeedlimit ('pingback');
 106  
 107      if ($_SERVER['REMOTE_ADDR'] != $_SERVER['SERVER_ADDR']) {
 108          if ($_CONF['check_trackback_link'] & 4) {
 109              $parts = parse_url ($url);
 110              if (empty ($parts['host'])) {
 111                  TRB_logRejected ('Pingback: No valid URL', $url);
 112                  return new XML_RPC_Response (0, 33, $PNB_ERROR['uri_invalid']);
 113              } else {
 114                  $ip = gethostbyname ($parts['host']);
 115                  if ($ip != $_SERVER['REMOTE_ADDR']) {
 116                      TRB_logRejected ('Pingback: IP address mismatch', $url);
 117                      return new XML_RPC_Response (0, 49, $PNB_ERROR['spam']);
 118                  }
 119              }
 120          }
 121      }
 122  
 123      // See if we can read the page linking to us and extract at least
 124      // the page's title out of it ...
 125      $title = '';
 126      $req = new HTTP_Request ($url);
 127      $req->addHeader ('User-Agent', 'GeekLog/' . VERSION);
 128      $response = $req->sendRequest ();
 129      if (PEAR::isError ($response)) {
 130          if ($_CONF['check_trackback_link'] & 3) {
 131              // we were supposed to check for backlinks but didn't get the page
 132              COM_errorLog ("Pingback verification: " . $response->getMessage()
 133                            . " when requesting $url");
 134              return new XML_RPC_Response (0, 33, $PNB_ERROR['uri_invalid']);
 135          }
 136          // else: silently ignore errors - we'll simply do without the title
 137      } else {
 138          if ($req->getResponseCode () == 200) {
 139              $body = $req->getResponseBody ();
 140  
 141              if ($_CONF['check_trackback_link'] & 3) {
 142                  if (!TRB_containsBacklink ($body, $oururl)) {
 143                      TRB_logRejected ('Pingback: No link to us', $url);
 144                      $comment = TRB_formatComment ($url);
 145                      PLG_spamAction ($comment, $_CONF['spamx']);
 146  
 147                      return new XML_RPC_Response (0, 49, $PNB_ERROR['spam']);
 148                  }
 149              }
 150  
 151              preg_match (':<title>(.*)</title>:i', $body, $content);
 152              if (empty ($content[1])) {
 153                  $title = ''; // no title found
 154              } else {
 155                  $title = trim (COM_undoSpecialChars ($content[1]));
 156              }
 157  
 158              // we could also run the rest of the other site's page
 159              // through the spam filter here ...
 160          } else if ($_CONF['check_trackback_link'] & 3) {
 161              COM_errorLog ("Pingback verification: Got HTTP response code "
 162                            . $req->getResponseCode ()
 163                            . " when requesting $url");
 164              return new XML_RPC_Response (0, 33, $PNB_ERROR['uri_invalid']);
 165          }
 166          // else: silently ignore errors - we'll simply do without the title
 167      }
 168  
 169      // check for spam first
 170      $saved = TRB_checkForSpam ($url, $title);
 171  
 172      if ($saved == TRB_SAVE_SPAM) {
 173          return new XML_RPC_Response (0, 49, $PNB_ERROR['spam']);
 174      }
 175  
 176      // save as a trackback comment
 177      $saved = TRB_saveTrackbackComment ($id, $type, $url, $title);
 178  
 179      if ($saved == TRB_SAVE_REJECT) {
 180          return new XML_RPC_Response (0, 49, $PNB_ERROR['multiple']);
 181      }
 182  
 183      if (isset ($_CONF['notification']) &&
 184              in_array ('pingback', $_CONF['notification'])) {                  
 185          TRB_sendNotificationEmail ($saved, 'pingback');                               
 186      }
 187  
 188      return new XML_RPC_Response (new XML_RPC_Value ($PNB_ERROR['success']));
 189  }
 190  
 191  /**
 192  * Check if the targetURI really points to us
 193  *
 194  * @param    string  $url    targetURI, a URL on our site
 195  * @return   bool            true = is a URL on our site
 196  *
 197  */
 198  function PNB_validURL ($url)
 199  {
 200      global $_CONF;
 201  
 202      $retval = false;
 203  
 204      if (substr ($url, 0, strlen ($_CONF['site_url'])) == $_CONF['site_url']) {
 205          $retval = true;
 206      }
 207  
 208      return $retval;
 209  }
 210  
 211  /**
 212  * Try to determine what has been pinged
 213  *
 214  * Checks if the URL contains 'article.php' for articles. Otherwise tries to
 215  * figure out if a plugin's page has been pinged.
 216  *
 217  * @param    string  $url    targetURI, a URL on our site
 218  * @return   string          'article' or plugin name or empty string for error
 219  *
 220  */
 221  function PNB_getType ($url)
 222  {
 223      global $_CONF, $_TABLES;
 224  
 225      $retval = '';
 226  
 227      $part = substr ($url, strlen ($_CONF['site_url']) + 1);
 228      if (substr ($part, 0, strlen ('article.php')) == 'article.php') {
 229          $retval = 'article';
 230      } else {
 231          $parts = explode ('/', $part);
 232          if (strpos ($parts[0], '?') === false) {
 233              $plugin = addslashes ($parts[0]);
 234              if (DB_getItem ($_TABLES['plugins'], 'pi_enabled',
 235                              "pi_name = '$plugin'") == 1) {
 236                  $retval = $parts[0];
 237              }
 238          }
 239      }
 240  
 241      return $retval;
 242  }
 243  
 244  /**
 245  * Extract story ID (sid) from the URL
 246  *
 247  * Accepts rewritten and old-style URLs. Also checks permissions.
 248  *
 249  * @param    string  $url    targetURI, a URL on our site
 250  * @return   string          story ID or empty string for error
 251  *
 252  */
 253  function PNB_getSid ($url)
 254  {
 255      global $_CONF, $_TABLES;
 256  
 257      $retval = '';
 258  
 259      $sid = '';
 260      $params = substr ($url, strlen ($_CONF['site_url'] . '/article.php'));
 261      if (substr ($params, 0, 1) == '?') { // old-style URL
 262          $pos = strpos ($params, 'story=');
 263          if ($pos !== false) {
 264              $part = substr ($params, $pos + strlen ('story='));
 265              $parts = explode ('&', $part);
 266              $sid = $parts[0];
 267          }
 268      } else if (substr ($params, 0, 1) == '/') { // rewritten URL
 269          $parts = explode ('/', substr ($params, 1));
 270          $sid = $parts[0];
 271      }
 272      if (!empty ($sid)) {
 273          $parts = explode ('#', $sid);
 274          $sid = $parts[0];
 275      }
 276  
 277      // okay, so we have a SID - but are they allowed to access the story?
 278      if (!empty ($sid)) {
 279          $testsid = addslashes ($sid);
 280          $result = DB_query ("SELECT trackbackcode FROM {$_TABLES['stories']} WHERE sid = '$testsid'" . COM_getPermSql ('AND') . COM_getTopicSql ('AND'));
 281          if (DB_numRows ($result) == 1) {
 282              $A = DB_fetchArray ($result);
 283              if ($A['trackbackcode'] == 0) {
 284                  $retval = $sid;
 285              }
 286          }
 287      }
 288  
 289      return $retval;
 290  }
 291  
 292  /**
 293  * We've received a pingback - handle it ...
 294  *
 295  * @param    object  $params     parameters of the pingback XML-RPC call
 296  * @return   object              XML-RPC response
 297  *
 298  */
 299  function PNB_receivePing ($params)
 300  {
 301      global $_CONF, $_TABLES, $PNB_ERROR;
 302  
 303      if (!$_CONF['pingback_enabled']) {
 304          return new XML_RPC_Response (0, 33, $PNB_ERROR['disabled']);
 305      }
 306  
 307      $s = $params->getParam (0);
 308      $p1 = $s->scalarval (); // the page linking to us
 309  
 310      if (is_array ($p1)) {
 311          // WordPress sends the 2 URIs as an array ...
 312          $sourceURI = $p1[0]->scalarval ();
 313          $targetURI = $p1[1]->scalarval ();
 314      } else {
 315          $sourceURI = $p1;
 316  
 317          $s = $params->getParam (1);
 318          $targetURI = $s->scalarval (); // the page being linked to (on our site)
 319      }
 320  
 321      if (!PNB_validURL ($targetURI)) {
 322          return new XML_RPC_Response (0, 33, $PNB_ERROR['uri_invalid']);
 323      }
 324  
 325      $type = PNB_getType ($targetURI);
 326      if (empty ($type)) {
 327          return new XML_RPC_Response (0, 33, $PNB_ERROR['uri_invalid']);
 328      }
 329  
 330      if ($type == 'article') {
 331          $id = PNB_getSid ($targetURI);
 332      } else {
 333          $id = PLG_handlePingComment ($type, $targetURI, 'acceptByURI');
 334      }
 335      if (empty ($id)) {
 336          return new XML_RPC_Response (0, 49, $PNB_ERROR['no_access']);
 337      }
 338  
 339      return PNB_handlePingback ($id, $type, $sourceURI, $targetURI);
 340  }
 341  
 342  
 343  // MAIN
 344  
 345  // fire up the XML-RPC server - it does all the work for us
 346  $s = new XML_RPC_Server ( array (
 347          'pingback.ping' => array ('function'  => 'PNB_receivePing')
 348       ));
 349  
 350  ?>


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