[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-forums/bbpress/bb-includes/ -> class.bb-pingbacks.php (source)

   1  <?php
   2  /**
   3   * bbPress class to handle pinging
   4   *
   5   * @package bbPress
   6   */
   7  class BB_Pingbacks
   8  {
   9      /**
  10       * Gets the Pingback endpoint URI provided by a web page specified by URL
  11       *
  12       * @return string|boolean Returns the Pingback endpoint URI if found or false
  13       */
  14  	function get_endpoint_uri( $url )
  15      {
  16          // First check for an X-pingback header
  17          if ( !$response = wp_remote_head( $url ) ) {
  18              return false;
  19          }
  20          if ( !$content_type = wp_remote_retrieve_header( $response, 'content-type' ) ) {
  21              return false;
  22          }
  23          if ( preg_match( '#(image|audio|video|model)/#is', $content_type ) ) {
  24              return false;
  25          }
  26          if ( $x_pingback = wp_remote_retrieve_header( $response, 'x-pingback' ) ) {
  27              return trim( $x_pingback );
  28          }
  29  
  30          // Fall back to extracting it from the HTML link
  31          if ( !$response = wp_remote_get( $url ) ) {
  32              return false;
  33          }
  34          if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
  35              return false;
  36          }
  37          if ( '' === $response_body = wp_remote_retrieve_body( $response ) ) {
  38              return false;
  39          }
  40          if ( !preg_match_all( '@<link([^>]+)>@im', $response_body, $response_links ) ) {
  41              return false;
  42          }
  43  
  44          foreach ( $response_links[1] as $response_link_attributes ) {
  45              $_link = array( 'rel' => false, 'href' => false );
  46              $response_link_attributes = preg_split( '@\s+@im', $response_link_attributes, -1, PREG_SPLIT_NO_EMPTY );
  47              foreach ( $response_link_attributes as $response_link_attribute ) {
  48                  if ( $_link['rel'] == 'pingback' && $_link['href'] ) {
  49                      return $_link['href'];
  50                  }
  51                  if ( strpos( $response_link_attribute, '=', 1 ) !== false ) {
  52                      list( $_key, $_value ) = explode( '=', $response_link_attribute, 2 );
  53                      $_link[strtolower( $_key )] = trim( $_value, "'\"" );
  54                  }
  55              }
  56          }
  57  
  58          // Fail
  59          return false;
  60      }
  61  
  62      /**
  63       * Sends all pingbacks and other ping like requests
  64       *
  65       * At the moment only sends normal pingbacks, but may be
  66       * expanded in the future.
  67       *
  68       * @return integer The number of pings sent
  69       */
  70  	function send_all()
  71      {
  72          $pings = BB_Pingbacks::send_all_pingbacks();
  73  
  74          return $pings;
  75      }
  76  
  77      /**
  78       * Sends all pingbacks
  79       *
  80       * @return integer The number of pings sent
  81       */
  82  	function send_all_pingbacks()
  83      {
  84          global $bbdb;
  85  
  86          $posts = $bbdb->get_results(
  87              "SELECT
  88                  {$bbdb->posts}.post_id,
  89                  {$bbdb->posts}.topic_id,
  90                  {$bbdb->posts}.post_text
  91              FROM {$bbdb->posts}, {$bbdb->meta}
  92              WHERE {$bbdb->posts}.post_id = {$bbdb->meta}.object_id
  93                  AND {$bbdb->meta}.object_type = 'bb_post'
  94                  AND {$bbdb->meta}.meta_key = 'pingback_queued';"
  95          );
  96  
  97          $pings = 0;
  98          foreach ( $posts as $post ) {
  99              if ( $sent = BB_Pingbacks::send_pingback( $post->topic_id, $post->post_text ) ) {
 100                  $pings += $sent;
 101                  bb_delete_postmeta( $post->post_id, 'pingback_queued' );
 102              }
 103          }
 104  
 105          return $pings;
 106      }
 107  
 108      /**
 109       * Sends a single pingback if a link is found
 110       *
 111       * @return integer The number of pingbacks sent
 112       */
 113  	function send_pingback( $topic_id, $post_text )
 114      {
 115          if ( !$topic_id || !$post_text ) {
 116              return 0;
 117          }
 118  
 119          // Get all links in the text and add them to an array
 120          if ( !preg_match_all( '@<a ([^>]+)>@im', make_clickable( $post_text ), $post_links ) ) {
 121              return 0;
 122          }
 123  
 124          $_links = array();
 125          foreach ( $post_links[1] as $post_link_attributes ) {
 126              $post_link_attributes = preg_split( '@\s+@im', $post_link_attributes, -1, PREG_SPLIT_NO_EMPTY );
 127              foreach ( $post_link_attributes as $post_link_attribute ) {
 128                  if ( strpos( $post_link_attribute, '=', 1 ) !== false ) {
 129                      list( $_key, $_value ) = explode( '=', $post_link_attribute, 2 );
 130                      if ( strtolower( $_key ) === 'href' ) {
 131                          $_links[] = trim( $_value, "'\"" );
 132                      }
 133                  }
 134              }
 135          }
 136  
 137          // Get pingbacks which have already been performed from this topic
 138          $past_pingbacks = bb_get_topicmeta( $topic_id, 'pingback_performed' );
 139          $new_pingbacks = array();
 140  
 141          foreach ( $_links as $_link ) {
 142              // If it's already been pingbacked, then skip it
 143              if ( $past_pingbacks && in_array( $_link, $past_pingbacks ) ) {
 144                  continue;
 145              }
 146  
 147              // If it's trying to ping itself, then skip it
 148              if ( $topic = bb_get_topic_from_uri( $_link ) ) {
 149                  if ( $topic->topic_id === $topic_id ) {
 150                      continue;
 151                  }
 152              }
 153  
 154              // Make sure it's a page on a site and not the root
 155              if ( !$_url = parse_url( $_link ) ) {
 156                  continue;
 157              }
 158              if ( !isset( $_url['query'] ) ) {
 159                  if ( $_url['path'] == '' || $_url['path'] == '/' ) {
 160                      continue;
 161                  }
 162              }
 163  
 164              // Add the URL to the array of those to be pingbacked
 165              $new_pingbacks[] = $_link;
 166          }
 167  
 168          include_once( BACKPRESS_PATH . '/class.ixr.php' );
 169  
 170          $count = 0;
 171          foreach ( $new_pingbacks as $pingback_to_url ) {
 172              if ( !$pingback_endpoint_uri = BB_Pingbacks::get_endpoint_uri( $pingback_to_url ) ) {
 173                  continue;
 174              }
 175  
 176              // Stop this nonsense after 60 seconds
 177              @set_time_limit( 60 );
 178  
 179              // Get the URL to pingback from
 180              $pingback_from_url = get_topic_link( $topic_id );
 181  
 182              // Using a timeout of 3 seconds should be enough to cover slow servers
 183              $client = new IXR_Client( $pingback_endpoint_uri );
 184              $client->timeout = 3;
 185              $client->useragent .= ' -- bbPress/' . bb_get_option( 'version' );
 186  
 187              // When set to true, this outputs debug messages by itself
 188              $client->debug = false;
 189  
 190              // If successful or the ping already exists then add to the pingbacked list
 191              if (
 192                  $client->query( 'pingback.ping', $pingback_from_url, $pingback_to_url ) ||
 193                  ( isset( $client->error->code ) && 48 == $client->error->code )
 194              ) {
 195                  $count++;
 196                  $past_pingbacks[] = $pingback_to_url;
 197              }
 198          }
 199  
 200          bb_update_topicmeta( $topic_id, 'pingback_performed', $past_pingbacks );
 201  
 202          return $count;
 203      }
 204  } // END class BB_Pingbacks


Generated: Thu Dec 7 01:01:35 2017 Cross-referenced by PHPXref 0.7.1