[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
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
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Dec 7 01:01:35 2017 | Cross-referenced by PHPXref 0.7.1 |