BB_Pingbacks

BbPress class to handle pinging.

Defined (1)

The class is defined in the following location(s).

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