| [ Index ] |
PHP Cross Reference of Wordpress 2.9.1 |
[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 * PHP4 constructor 25 */ 26 function WP_oEmbed() { 27 return $this->__construct(); 28 } 29 30 /** 31 * PHP5 constructor 32 * 33 * @uses apply_filters() Filters a list of pre-defined oEmbed providers. 34 */ 35 function __construct() { 36 // List out some popular sites that support oEmbed. 37 // The WP_Embed class disables discovery for non-unfiltered_html users, so only providers in this array will be used for them. 38 // Add to this list using the wp_oembed_add_provider() function (see it's PHPDoc for details). 39 $this->providers = apply_filters( 'oembed_providers', array( 40 '#http://(www\.)?youtube.com/watch.*#i' => array( 'http://www.youtube.com/oembed', true ), 41 'http://blip.tv/file/*' => array( 'http://blip.tv/oembed/', false ), 42 '#http://(www\.)?vimeo\.com/.*#i' => array( 'http://www.vimeo.com/api/oembed.{format}', true ), 43 '#http://(www\.)?dailymotion\.com/.*#i' => array( 'http://www.dailymotion.com/api/oembed', true ), 44 '#http://(www\.)?flickr\.com/.*#i' => array( 'http://www.flickr.com/services/oembed/', true ), 45 '#http://(www\.)?hulu\.com/watch/.*#i' => array( 'http://www.hulu.com/api/oembed.{format}', true ), 46 '#http://(www\.)?viddler\.com/.*#i' => array( 'http://lab.viddler.com/services/oembed/', true ), 47 'http://qik.com/*' => array( 'http://qik.com/api/oembed.{format}', false ), 48 'http://revision3.com/*' => array( 'http://revision3.com/api/oembed/', false ), 49 'http://i*.photobucket.com/albums/*' => array( 'http://photobucket.com/oembed', false ), 50 'http://gi*.photobucket.com/groups/*' => array( 'http://photobucket.com/oembed', false ), 51 '#http://(www\.)?scribd\.com/.*#i' => array( 'http://www.scribd.com/services/oembed', true ), 52 'http://wordpress.tv/*' => array( 'http://wordpress.tv/oembed/', false ), 53 ) ); 54 55 // Fix Scribd embeds. They contain new lines in the middle of the HTML which breaks wpautop(). 56 add_filter( 'oembed_dataparse', array(&$this, 'strip_scribd_newlines'), 10, 3 ); 57 } 58 59 /** 60 * The do-it-all function that takes a URL and attempts to return the HTML. 61 * 62 * @see WP_oEmbed::discover() 63 * @see WP_oEmbed::fetch() 64 * @see WP_oEmbed::data2html() 65 * 66 * @param string $url The URL to the content that should be attempted to be embedded. 67 * @param array $args Optional arguments. Usually passed from a shortcode. 68 * @return bool|string False on failure, otherwise the UNSANITIZED (and potentially unsafe) HTML that should be used to embed. 69 */ 70 function get_html( $url, $args = '' ) { 71 $provider = false; 72 73 if ( !isset($args['discover']) ) 74 $args['discover'] = true; 75 76 foreach ( $this->providers as $matchmask => $data ) { 77 list( $providerurl, $regex ) = $data; 78 79 // Turn the asterisk-type provider URLs into regex 80 if ( !$regex ) 81 $matchmask = '#' . str_replace( '___wildcard___', '(.+)', preg_quote( str_replace( '*', '___wildcard___', $matchmask ), '#' ) ) . '#i'; 82 83 if ( preg_match( $matchmask, $url ) ) { 84 $provider = str_replace( '{format}', 'json', $providerurl ); // JSON is easier to deal with than XML 85 break; 86 } 87 } 88 89 if ( !$provider && $args['discover'] ) 90 $provider = $this->discover( $url ); 91 92 if ( !$provider || false === $data = $this->fetch( $provider, $url, $args ) ) 93 return false; 94 95 return apply_filters( 'oembed_result', $this->data2html( $data, $url ), $url, $args ); 96 } 97 98 /** 99 * Attempts to find oEmbed provider discovery <link> tags at the given URL. 100 * 101 * @param string $url The URL that should be inspected for discovery <link> tags. 102 * @return bool|string False on failure, otherwise the oEmbed provider URL. 103 */ 104 function discover( $url ) { 105 $providers = array(); 106 107 // Fetch URL content 108 if ( $html = wp_remote_retrieve_body( wp_remote_get( $url ) ) ) { 109 110 // <link> types that contain oEmbed provider URLs 111 $linktypes = apply_filters( 'oembed_linktypes', array( 112 'application/json+oembed' => 'json', 113 'text/xml+oembed' => 'xml', 114 'application/xml+oembed' => 'xml', // Incorrect, but used by at least Vimeo 115 ) ); 116 117 // Strip <body> 118 $html = substr( $html, 0, stripos( $html, '</head>' ) ); 119 120 // Do a quick check 121 $tagfound = false; 122 foreach ( $linktypes as $linktype => $format ) { 123 if ( stripos($html, $linktype) ) { 124 $tagfound = true; 125 break; 126 } 127 } 128 129 if ( $tagfound && preg_match_all( '/<link([^<>]+)>/i', $html, $links ) ) { 130 foreach ( $links[1] as $link ) { 131 $atts = shortcode_parse_atts( $link ); 132 133 if ( !empty($atts['type']) && !empty($linktypes[$atts['type']]) && !empty($atts['href']) ) { 134 $providers[$linktypes[$atts['type']]] = $atts['href']; 135 136 // Stop here if it's JSON (that's all we need) 137 if ( 'json' == $linktypes[$atts['type']] ) 138 break; 139 } 140 } 141 } 142 } 143 144 // JSON is preferred to XML 145 if ( !empty($providers['json']) ) 146 return $providers['json']; 147 elseif ( !empty($providers['xml']) ) 148 return $providers['xml']; 149 else 150 return false; 151 } 152 153 /** 154 * Connects to a oEmbed provider and returns the result. 155 * 156 * @param string $provider The URL to the oEmbed provider. 157 * @param string $url The URL to the content that is desired to be embedded. 158 * @param array $args Optional arguments. Usually passed from a shortcode. 159 * @return bool|object False on failure, otherwise the result in the form of an object. 160 */ 161 function fetch( $provider, $url, $args = '' ) { 162 $args = wp_parse_args( $args, wp_embed_defaults() ); 163 164 $provider = add_query_arg( 'format', 'json', $provider ); // JSON is easier to deal with than XML 165 166 $provider = add_query_arg( 'maxwidth', $args['width'], $provider ); 167 $provider = add_query_arg( 'maxheight', $args['height'], $provider ); 168 $provider = add_query_arg( 'url', urlencode($url), $provider ); 169 170 if ( !$result = wp_remote_retrieve_body( wp_remote_get( $provider ) ) ) 171 return false; 172 173 $result = trim( $result ); 174 175 // JSON? 176 // Example content: http://vimeo.com/api/oembed.json?url=http%3A%2F%2Fvimeo.com%2F240975 177 if ( $data = json_decode($result) ) { 178 return $data; 179 } 180 181 // Must be XML. Only parse it if PHP5 is installed. (PHP4 isn't worth the trouble.) 182 // Example content: http://vimeo.com/api/oembed.xml?url=http%3A%2F%2Fvimeo.com%2F240975 183 elseif ( function_exists('simplexml_load_string') ) { 184 $errors = libxml_use_internal_errors( 'true' ); 185 186 $data = simplexml_load_string( $result ); 187 188 libxml_use_internal_errors( $errors ); 189 190 if ( is_object($data) ) 191 return $data; 192 } 193 194 return false; 195 } 196 197 /** 198 * Converts a data object from {@link WP_oEmbed::fetch()} and returns the HTML. 199 * 200 * @param object $data A data object result from an oEmbed provider. 201 * @param string $url The URL to the content that is desired to be embedded. 202 * @return bool|string False on error, otherwise the HTML needed to embed. 203 */ 204 function data2html( $data, $url ) { 205 if ( !is_object($data) || empty($data->type) ) 206 return false; 207 208 switch ( $data->type ) { 209 case 'photo': 210 if ( empty($data->url) || empty($data->width) || empty($data->height) ) 211 return false; 212 213 $title = ( !empty($data->title) ) ? $data->title : ''; 214 $return = '<img src="' . esc_attr( clean_url( $data->url ) ) . '" alt="' . esc_attr($title) . '" width="' . esc_attr($data->width) . '" height="' . esc_attr($data->height) . '" />'; 215 break; 216 217 case 'video': 218 case 'rich': 219 $return = ( !empty($data->html) ) ? $data->html : false; 220 break; 221 222 case 'link': 223 $return = ( !empty($data->title) ) ? '<a href="' . clean_url($url) . '">' . esc_html($data->title) . '</a>' : false; 224 break; 225 226 default; 227 $return = false; 228 } 229 230 // You can use this filter to add support for custom data types or to filter the result 231 return apply_filters( 'oembed_dataparse', $return, $data, $url ); 232 } 233 234 /** 235 * Strip new lines from the HTML if it's a Scribd embed. 236 * 237 * @param string $html Existing HTML. 238 * @param object $data Data object from WP_oEmbed::data2html() 239 * @param string $url The original URL passed to oEmbed. 240 * @return string Possibly modified $html 241 */ 242 function strip_scribd_newlines( $html, $data, $url ) { 243 if ( preg_match( '#http://(www\.)?scribd.com/.*#i', $url ) ) 244 $html = str_replace( array( "\r\n", "\n" ), '', $html ); 245 246 return $html; 247 } 248 } 249 250 /** 251 * Returns the initialized {@link WP_oEmbed} object 252 * 253 * @since 2.9.0 254 * @access private 255 * 256 * @see WP_oEmbed 257 * @uses WP_oEmbed 258 * 259 * @return WP_oEmbed object. 260 */ 261 function &_wp_oembed_get_object() { 262 static $wp_oembed; 263 264 if ( is_null($wp_oembed) ) 265 $wp_oembed = new WP_oEmbed(); 266 267 return $wp_oembed; 268 } 269 270 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Fri Jan 8 00:19:48 2010 | Cross-referenced by PHPXref 0.7 |