| [ XREF Home ] [ Index ] |
PHP Cross Reference of WordPress TrunkProvided by Yoast |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * API for fetching the HTML to embed remote content based on a provided URL. 4 * Used internally by the {@link WP_Embed} class, but is designed to be generic. 5 * 6 * @link http://codex.wordpress.org/oEmbed oEmbed Codex Article 7 * @link http://oembed.com/ oEmbed Homepage 8 * 9 * @package WordPress 10 * @subpackage oEmbed 11 */ 12 13 /** 14 * oEmbed class. 15 * 16 * @package WordPress 17 * @subpackage oEmbed 18 * @since 2.9.0 19 */ 20 class WP_oEmbed { 21 var $providers = array(); 22 23 /** 24 * Constructor 25 * 26 * @uses apply_filters() Filters a list of pre-defined oEmbed providers. 27 */ 28 function __construct() { 29 // List out some popular sites that support oEmbed. 30 // The WP_Embed class disables discovery for non-unfiltered_html users, so only providers in this array will be used for them. 31 // Add to this list using the wp_oembed_add_provider() function (see it's PHPDoc for details). 32 $this->providers = apply_filters( 'oembed_providers', array( 33 '#http://(www\.)?youtube.com/watch.*#i' => array( 'http://www.youtube.com/oembed', true ), 34 'http://youtu.be/*' => array( 'http://www.youtube.com/oembed', false ), 35 'http://blip.tv/*' => array( 'http://blip.tv/oembed/', false ), 36 '#http://(www\.)?vimeo\.com/.*#i' => array( 'http://www.vimeo.com/api/oembed.{format}', true ), 37 '#http://(www\.)?dailymotion\.com/.*#i' => array( 'http://www.dailymotion.com/api/oembed', true ), 38 '#http://(www\.)?flickr\.com/.*#i' => array( 'http://www.flickr.com/services/oembed/', true ), 39 '#http://(.+)?smugmug\.com/.*#i' => array( 'http://api.smugmug.com/services/oembed/', true ), 40 '#http://(www\.)?hulu\.com/watch/.*#i' => array( 'http://www.hulu.com/api/oembed.{format}', true ), 41 '#http://(www\.)?viddler\.com/.*#i' => array( 'http://lab.viddler.com/services/oembed/', true ), 42 'http://qik.com/*' => array( 'http://qik.com/api/oembed.{format}', false ), 43 'http://revision3.com/*' => array( 'http://revision3.com/api/oembed/', false ), 44 'http://i*.photobucket.com/albums/*' => array( 'http://photobucket.com/oembed', false ), 45 'http://gi*.photobucket.com/groups/*' => array( 'http://photobucket.com/oembed', false ), 46 '#http://(www\.)?scribd\.com/.*#i' => array( 'http://www.scribd.com/services/oembed', true ), 47 'http://wordpress.tv/*' => array( 'http://wordpress.tv/oembed/', false ), 48 '#http://(answers|surveys)\.polldaddy.com/.*#i' => array( 'http://polldaddy.com/oembed/', true ), 49 '#http://(www\.)?funnyordie\.com/videos/.*#i' => array( 'http://www.funnyordie.com/oembed', true ), 50 ) ); 51 52 // Fix any embeds that contain new lines in the middle of the HTML which breaks wpautop(). 53 add_filter( 'oembed_dataparse', array(&$this, '_strip_newlines'), 10, 3 ); 54 } 55 56 /** 57 * The do-it-all function that takes a URL and attempts to return the HTML. 58 * 59 * @see WP_oEmbed::discover() 60 * @see WP_oEmbed::fetch() 61 * @see WP_oEmbed::data2html() 62 * 63 * @param string $url The URL to the content that should be attempted to be embedded. 64 * @param array $args Optional arguments. Usually passed from a shortcode. 65 * @return bool|string False on failure, otherwise the UNSANITIZED (and potentially unsafe) HTML that should be used to embed. 66 */ 67 function get_html( $url, $args = '' ) { 68 $provider = false; 69 70 if ( !isset($args['discover']) ) 71 $args['discover'] = true; 72 73 foreach ( $this->providers as $matchmask => $data ) { 74 list( $providerurl, $regex ) = $data; 75 76 // Turn the asterisk-type provider URLs into regex 77 if ( !$regex ) 78 $matchmask = '#' . str_replace( '___wildcard___', '(.+)', preg_quote( str_replace( '*', '___wildcard___', $matchmask ), '#' ) ) . '#i'; 79 80 if ( preg_match( $matchmask, $url ) ) { 81 $provider = str_replace( '{format}', 'json', $providerurl ); // JSON is easier to deal with than XML 82 break; 83 } 84 } 85 86 if ( !$provider && $args['discover'] ) 87 $provider = $this->discover( $url ); 88 89 if ( !$provider || false === $data = $this->fetch( $provider, $url, $args ) ) 90 return false; 91 92 return apply_filters( 'oembed_result', $this->data2html( $data, $url ), $url, $args ); 93 } 94 95 /** 96 * Attempts to find oEmbed provider discovery <link> tags at the given URL. 97 * 98 * @param string $url The URL that should be inspected for discovery <link> tags. 99 * @return bool|string False on failure, otherwise the oEmbed provider URL. 100 */ 101 function discover( $url ) { 102 $providers = array(); 103 104 // Fetch URL content 105 if ( $html = wp_remote_retrieve_body( wp_remote_get( $url ) ) ) { 106 107 // <link> types that contain oEmbed provider URLs 108 $linktypes = apply_filters( 'oembed_linktypes', array( 109 'application/json+oembed' => 'json', 110 'text/xml+oembed' => 'xml', 111 'application/xml+oembed' => 'xml', // Incorrect, but used by at least Vimeo 112 ) ); 113 114 // Strip <body> 115 $html = substr( $html, 0, stripos( $html, '</head>' ) ); 116 117 // Do a quick check 118 $tagfound = false; 119 foreach ( $linktypes as $linktype => $format ) { 120 if ( stripos($html, $linktype) ) { 121 $tagfound = true; 122 break; 123 } 124 } 125 126 if ( $tagfound && preg_match_all( '/<link([^<>]+)>/i', $html, $links ) ) { 127 foreach ( $links[1] as $link ) { 128 $atts = shortcode_parse_atts( $link ); 129 130 if ( !empty($atts['type']) && !empty($linktypes[$atts['type']]) && !empty($atts['href']) ) { 131 $providers[$linktypes[$atts['type']]] = $atts['href']; 132 133 // Stop here if it's JSON (that's all we need) 134 if ( 'json' == $linktypes[$atts['type']] ) 135 break; 136 } 137 } 138 } 139 } 140 141 // JSON is preferred to XML 142 if ( !empty($providers['json']) ) 143 return $providers['json']; 144 elseif ( !empty($providers['xml']) ) 145 return $providers['xml']; 146 else 147 return false; 148 } 149 150 /** 151 * Connects to a oEmbed provider and returns the result. 152 * 153 * @param string $provider The URL to the oEmbed provider. 154 * @param string $url The URL to the content that is desired to be embedded. 155 * @param array $args Optional arguments. Usually passed from a shortcode. 156 * @return bool|object False on failure, otherwise the result in the form of an object. 157 */ 158 function fetch( $provider, $url, $args = '' ) { 159 $args = wp_parse_args( $args, wp_embed_defaults() ); 160 161 $provider = add_query_arg( 'maxwidth', (int) $args['width'], $provider ); 162 $provider = add_query_arg( 'maxheight', (int) $args['height'], $provider ); 163 $provider = add_query_arg( 'url', urlencode($url), $provider ); 164 165 foreach( array( 'json', 'xml' ) as $format ) { 166 $result = $this->_fetch_with_format( $provider, $format ); 167 if ( is_wp_error( $result ) && 'not-implemented' == $result->get_error_code() ) 168 continue; 169 return ( $result && ! is_wp_error( $result ) ) ? $result : false; 170 } 171 return false; 172 } 173 174 /** 175 * Fetches result from an oEmbed provider for a specific format and complete provider URL 176 * 177 * @since 3.0.0 178 * @access private 179 * @param string $provider_url_with_args URL to the provider with full arguments list (url, maxheight, etc.) 180 * @param string $format Format to use 181 * @return bool|object False on failure, otherwise the result in the form of an object. 182 */ 183 function _fetch_with_format( $provider_url_with_args, $format ) { 184 $provider_url_with_args = add_query_arg( 'format', $format, $provider_url_with_args ); 185 $response = wp_remote_get( $provider_url_with_args ); 186 if ( 501 == wp_remote_retrieve_response_code( $response ) ) 187 return new WP_Error( 'not-implemented' ); 188 if ( ! $body = wp_remote_retrieve_body( $response ) ) 189 return false; 190 $parse_method = "_parse_$format"; 191 return $this->$parse_method( $body ); 192 } 193 194 /** 195 * Parses a json response body. 196 * 197 * @since 3.0.0 198 * @access private 199 */ 200 function _parse_json( $response_body ) { 201 return ( ( $data = json_decode( trim( $response_body ) ) ) && is_object( $data ) ) ? $data : false; 202 } 203 204 /** 205 * Parses an XML response body. 206 * 207 * @since 3.0.0 208 * @access private 209 */ 210 function _parse_xml( $response_body ) { 211 if ( function_exists('simplexml_load_string') ) { 212 $errors = libxml_use_internal_errors( 'true' ); 213 $data = simplexml_load_string( $response_body ); 214 libxml_use_internal_errors( $errors ); 215 if ( is_object( $data ) ) 216 return $data; 217 } 218 return false; 219 } 220 221 /** 222 * Converts a data object from {@link WP_oEmbed::fetch()} and returns the HTML. 223 * 224 * @param object $data A data object result from an oEmbed provider. 225 * @param string $url The URL to the content that is desired to be embedded. 226 * @return bool|string False on error, otherwise the HTML needed to embed. 227 */ 228 function data2html( $data, $url ) { 229 if ( !is_object($data) || empty($data->type) ) 230 return false; 231 232 switch ( $data->type ) { 233 case 'photo': 234 if ( empty($data->url) || empty($data->width) || empty($data->height) ) 235 return false; 236 237 $title = ( !empty($data->title) ) ? $data->title : ''; 238 $return = '<a href="' . esc_url( $url ) . '"><img src="' . esc_url( $data->url ) . '" alt="' . esc_attr($title) . '" width="' . esc_attr($data->width) . '" height="' . esc_attr($data->height) . '" /></a>'; 239 break; 240 241 case 'video': 242 case 'rich': 243 $return = ( !empty($data->html) ) ? $data->html : false; 244 break; 245 246 case 'link': 247 $return = ( !empty($data->title) ) ? '<a href="' . esc_url($url) . '">' . esc_html($data->title) . '</a>' : false; 248 break; 249 250 default; 251 $return = false; 252 } 253 254 // You can use this filter to add support for custom data types or to filter the result 255 return apply_filters( 'oembed_dataparse', $return, $data, $url ); 256 } 257 258 /** 259 * Strip any new lines from the HTML. 260 * 261 * @access private 262 * @param string $html Existing HTML. 263 * @param object $data Data object from WP_oEmbed::data2html() 264 * @param string $url The original URL passed to oEmbed. 265 * @return string Possibly modified $html 266 */ 267 function _strip_newlines( $html, $data, $url ) { 268 if ( false !== strpos( $html, "\n" ) ) 269 $html = str_replace( array( "\r\n", "\n" ), '', $html ); 270 271 return $html; 272 } 273 } 274 275 /** 276 * Returns the initialized {@link WP_oEmbed} object 277 * 278 * @since 2.9.0 279 * @access private 280 * 281 * @see WP_oEmbed 282 * @uses WP_oEmbed 283 * 284 * @return WP_oEmbed object. 285 */ 286 function &_wp_oembed_get_object() { 287 static $wp_oembed; 288 289 if ( is_null($wp_oembed) ) 290 $wp_oembed = new WP_oEmbed(); 291 292 return $wp_oembed; 293 } 294 295 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jun 1 08:30:02 2011 |
Cross-referenced by PHPXref 0.7 Provided by Yoast and awesome WordPress Hosting |