12 * |
12 * |
13 * Should probably only be used for sites that do not support oEmbed. |
13 * Should probably only be used for sites that do not support oEmbed. |
14 * |
14 * |
15 * @since 2.9.0 |
15 * @since 2.9.0 |
16 * |
16 * |
17 * @global WP_Embed $wp_embed |
17 * @global WP_Embed $wp_embed WordPress Embed object. |
18 * |
18 * |
19 * @param string $id An internal ID/name for the handler. Needs to be unique. |
19 * @param string $id An internal ID/name for the handler. Needs to be unique. |
20 * @param string $regex The regex that will be used to see if this handler should be used for a URL. |
20 * @param string $regex The regex that will be used to see if this handler should be used for a URL. |
21 * @param callable $callback The callback function that will be called if the regex is matched. |
21 * @param callable $callback The callback function that will be called if the regex is matched. |
22 * @param int $priority Optional. Used to specify the order in which the registered handlers will |
22 * @param int $priority Optional. Used to specify the order in which the registered handlers will |
30 /** |
30 /** |
31 * Unregisters a previously-registered embed handler. |
31 * Unregisters a previously-registered embed handler. |
32 * |
32 * |
33 * @since 2.9.0 |
33 * @since 2.9.0 |
34 * |
34 * |
35 * @global WP_Embed $wp_embed |
35 * @global WP_Embed $wp_embed WordPress Embed object. |
36 * |
36 * |
37 * @param string $id The handler ID that should be removed. |
37 * @param string $id The handler ID that should be removed. |
38 * @param int $priority Optional. The priority of the handler to be removed. Default 10. |
38 * @param int $priority Optional. The priority of the handler to be removed. Default 10. |
39 */ |
39 */ |
40 function wp_embed_unregister_handler( $id, $priority = 10 ) { |
40 function wp_embed_unregister_handler( $id, $priority = 10 ) { |
228 * |
228 * |
229 * Catches YouTube iframe embed URLs that are not parsable by oEmbed but can be translated into a URL that is. |
229 * Catches YouTube iframe embed URLs that are not parsable by oEmbed but can be translated into a URL that is. |
230 * |
230 * |
231 * @since 4.0.0 |
231 * @since 4.0.0 |
232 * |
232 * |
233 * @global WP_Embed $wp_embed |
233 * @global WP_Embed $wp_embed WordPress Embed object. |
234 * |
234 * |
235 * @param array $matches The RegEx matches from the provided regex when calling |
235 * @param array $matches The RegEx matches from the provided regex when calling |
236 * wp_embed_register_handler(). |
236 * wp_embed_register_handler(). |
237 * @param array $attr Embed attributes. |
237 * @param array $attr Embed attributes. |
238 * @param string $url The original URL that was matched by the regex. |
238 * @param string $url The original URL that was matched by the regex. |
242 function wp_embed_handler_youtube( $matches, $attr, $url, $rawattr ) { |
242 function wp_embed_handler_youtube( $matches, $attr, $url, $rawattr ) { |
243 global $wp_embed; |
243 global $wp_embed; |
244 $embed = $wp_embed->autoembed( sprintf( 'https://youtube.com/watch?v=%s', urlencode( $matches[2] ) ) ); |
244 $embed = $wp_embed->autoembed( sprintf( 'https://youtube.com/watch?v=%s', urlencode( $matches[2] ) ) ); |
245 |
245 |
246 /** |
246 /** |
247 * Filters the YoutTube embed output. |
247 * Filters the YouTube embed output. |
248 * |
248 * |
249 * @since 4.0.0 |
249 * @since 4.0.0 |
250 * |
250 * |
251 * @see wp_embed_handler_youtube() |
251 * @see wp_embed_handler_youtube() |
252 * |
252 * |
334 */ |
334 */ |
335 function wp_oembed_add_discovery_links() { |
335 function wp_oembed_add_discovery_links() { |
336 $output = ''; |
336 $output = ''; |
337 |
337 |
338 if ( is_singular() ) { |
338 if ( is_singular() ) { |
339 $output .= '<link rel="alternate" type="application/json+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink() ) ) . '" />' . "\n"; |
339 $output .= '<link rel="alternate" title="' . _x( 'oEmbed (JSON)', 'oEmbed resource link name' ) . '" type="application/json+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink() ) ) . '" />' . "\n"; |
340 |
340 |
341 if ( class_exists( 'SimpleXMLElement' ) ) { |
341 if ( class_exists( 'SimpleXMLElement' ) ) { |
342 $output .= '<link rel="alternate" type="text/xml+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink(), 'xml' ) ) . '" />' . "\n"; |
342 $output .= '<link rel="alternate" title="' . _x( 'oEmbed (XML)', 'oEmbed resource link name' ) . '" type="text/xml+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink(), 'xml' ) ) . '" />' . "\n"; |
343 } |
343 } |
344 } |
344 } |
345 |
345 |
346 /** |
346 /** |
347 * Filters the oEmbed discovery links HTML. |
347 * Filters the oEmbed discovery links HTML. |
424 * @since 4.4.0 |
424 * @since 4.4.0 |
425 * |
425 * |
426 * @param string $embed_url The post embed URL. |
426 * @param string $embed_url The post embed URL. |
427 * @param WP_Post $post The corresponding post object. |
427 * @param WP_Post $post The corresponding post object. |
428 */ |
428 */ |
429 return esc_url_raw( apply_filters( 'post_embed_url', $embed_url, $post ) ); |
429 return sanitize_url( apply_filters( 'post_embed_url', $embed_url, $post ) ); |
430 } |
430 } |
431 |
431 |
432 /** |
432 /** |
433 * Retrieves the oEmbed endpoint URL for a given permalink. |
433 * Retrieves the oEmbed endpoint URL for a given permalink. |
434 * |
434 * |
508 ) |
508 ) |
509 ), |
509 ), |
510 esc_attr( $secret ) |
510 esc_attr( $secret ) |
511 ); |
511 ); |
512 |
512 |
513 // Note that the script must be placed after the <blockquote> and <iframe> due to a regexp parsing issue in |
513 /* |
514 // `wp_filter_oembed_result()`. Because of the regex pattern starts with `|(<blockquote>.*?</blockquote>)?.*|` |
514 * Note that the script must be placed after the <blockquote> and <iframe> due to a regexp parsing issue in |
515 // wherein the <blockquote> is marked as being optional, if it is not at the beginning of the string then the group |
515 * `wp_filter_oembed_result()`. Because of the regex pattern starts with `|(<blockquote>.*?</blockquote>)?.*|` |
516 // will fail to match and everything will be matched by `.*` and not included in the group. This regex issue goes |
516 * wherein the <blockquote> is marked as being optional, if it is not at the beginning of the string then the group |
517 // back to WordPress 4.4, so in order to not break older installs this script must come at the end. |
517 * will fail to match and everything will be matched by `.*` and not included in the group. This regex issue goes |
|
518 * back to WordPress 4.4, so in order to not break older installs this script must come at the end. |
|
519 */ |
518 $output .= wp_get_inline_script_tag( |
520 $output .= wp_get_inline_script_tag( |
519 file_get_contents( ABSPATH . WPINC . '/js/wp-embed' . wp_scripts_get_suffix() . '.js' ) |
521 file_get_contents( ABSPATH . WPINC . '/js/wp-embed' . wp_scripts_get_suffix() . '.js' ) |
520 ); |
522 ); |
521 |
523 |
522 /** |
524 /** |
535 /** |
537 /** |
536 * Retrieves the oEmbed response data for a given post. |
538 * Retrieves the oEmbed response data for a given post. |
537 * |
539 * |
538 * @since 4.4.0 |
540 * @since 4.4.0 |
539 * |
541 * |
540 * @param WP_Post|int $post Post object or ID. |
542 * @param WP_Post|int $post Post ID or post object. |
541 * @param int $width The requested width. |
543 * @param int $width The requested width. |
542 * @return array|false Response data on success, false if post doesn't exist |
544 * @return array|false Response data on success, false if post doesn't exist |
543 * or is not publicly viewable. |
545 * or is not publicly viewable. |
544 */ |
546 */ |
545 function get_oembed_response_data( $post, $width ) { |
547 function get_oembed_response_data( $post, $width ) { |
573 'max' => 600, |
575 'max' => 600, |
574 ) |
576 ) |
575 ); |
577 ); |
576 |
578 |
577 $width = min( max( $min_max_width['min'], $width ), $min_max_width['max'] ); |
579 $width = min( max( $min_max_width['min'], $width ), $min_max_width['max'] ); |
578 $height = max( ceil( $width / 16 * 9 ), 200 ); |
580 $height = max( (int) ceil( $width / 16 * 9 ), 200 ); |
579 |
581 |
580 $data = array( |
582 $data = array( |
581 'version' => '1.0', |
583 'version' => '1.0', |
582 'provider_name' => get_bloginfo( 'name' ), |
584 'provider_name' => get_bloginfo( 'name' ), |
583 'provider_url' => get_home_url(), |
585 'provider_url' => get_home_url(), |
623 if ( is_multisite() ) { |
625 if ( is_multisite() ) { |
624 $url_parts = wp_parse_args( |
626 $url_parts = wp_parse_args( |
625 wp_parse_url( $url ), |
627 wp_parse_url( $url ), |
626 array( |
628 array( |
627 'host' => '', |
629 'host' => '', |
|
630 'port' => null, |
628 'path' => '/', |
631 'path' => '/', |
629 ) |
632 ) |
630 ); |
633 ); |
631 |
634 |
632 $qv = array( |
635 $qv = array( |
633 'domain' => $url_parts['host'], |
636 'domain' => $url_parts['host'] . ( $url_parts['port'] ? ':' . $url_parts['port'] : '' ), |
634 'path' => '/', |
637 'path' => '/', |
635 'update_site_meta_cache' => false, |
638 'update_site_meta_cache' => false, |
636 ); |
639 ); |
637 |
640 |
638 // In case of subdirectory configs, set the path. |
641 // In case of subdirectory configs, set the path. |
961 |
964 |
962 $html = wp_kses( $html, $allowed_html ); |
965 $html = wp_kses( $html, $allowed_html ); |
963 |
966 |
964 if ( ! empty( $content[1] ) ) { |
967 if ( ! empty( $content[1] ) ) { |
965 // We have a blockquote to fall back on. Hide the iframe by default. |
968 // We have a blockquote to fall back on. Hide the iframe by default. |
966 $html = str_replace( '<iframe', '<iframe style="position: absolute; clip: rect(1px, 1px, 1px, 1px);"', $html ); |
969 $html = str_replace( '<iframe', '<iframe style="position: absolute; visibility: hidden;"', $html ); |
967 $html = str_replace( '<blockquote', '<blockquote class="wp-embedded-content"', $html ); |
970 $html = str_replace( '<blockquote', '<blockquote class="wp-embedded-content"', $html ); |
968 } |
971 } |
969 |
972 |
970 $html = str_ireplace( '<iframe', '<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"', $html ); |
973 $html = str_ireplace( '<iframe', '<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"', $html ); |
971 |
974 |
1055 */ |
1058 */ |
1056 do_action( 'enqueue_embed_scripts' ); |
1059 do_action( 'enqueue_embed_scripts' ); |
1057 } |
1060 } |
1058 |
1061 |
1059 /** |
1062 /** |
1060 * Prints the CSS in the embed iframe header. |
1063 * Enqueues the CSS in the embed iframe header. |
1061 * |
1064 * |
1062 * @since 4.4.0 |
1065 * @since 6.4.0 |
1063 */ |
1066 */ |
1064 function print_embed_styles() { |
1067 function wp_enqueue_embed_styles() { |
1065 $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; |
1068 // Back-compat for plugins that disable functionality by unhooking this action. |
1066 $suffix = SCRIPT_DEBUG ? '' : '.min'; |
1069 if ( ! has_action( 'embed_head', 'print_embed_styles' ) ) { |
1067 ?> |
1070 return; |
1068 <style<?php echo $type_attr; ?>> |
1071 } |
1069 <?php echo file_get_contents( ABSPATH . WPINC . "/css/wp-embed-template$suffix.css" ); ?> |
1072 remove_action( 'embed_head', 'print_embed_styles' ); |
1070 </style> |
1073 |
1071 <?php |
1074 $suffix = wp_scripts_get_suffix(); |
|
1075 $handle = 'wp-embed-template'; |
|
1076 wp_register_style( $handle, false ); |
|
1077 wp_add_inline_style( $handle, file_get_contents( ABSPATH . WPINC . "/css/wp-embed-template$suffix.css" ) ); |
|
1078 wp_enqueue_style( $handle ); |
1072 } |
1079 } |
1073 |
1080 |
1074 /** |
1081 /** |
1075 * Prints the JavaScript in the embed iframe header. |
1082 * Prints the JavaScript in the embed iframe header. |
1076 * |
1083 * |
1090 * |
1097 * |
1091 * @param string $content The content to filter. |
1098 * @param string $content The content to filter. |
1092 * @return string The filtered content. |
1099 * @return string The filtered content. |
1093 */ |
1100 */ |
1094 function _oembed_filter_feed_content( $content ) { |
1101 function _oembed_filter_feed_content( $content ) { |
1095 return str_replace( '<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);"', '<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"', $content ); |
1102 $p = new WP_HTML_Tag_Processor( $content ); |
|
1103 while ( $p->next_tag( array( 'tag_name' => 'iframe' ) ) ) { |
|
1104 if ( $p->has_class( 'wp-embedded-content' ) ) { |
|
1105 $p->remove_attribute( 'style' ); |
|
1106 } |
|
1107 } |
|
1108 return $p->get_updated_html(); |
1096 } |
1109 } |
1097 |
1110 |
1098 /** |
1111 /** |
1099 * Prints the necessary markup for the embed comments button. |
1112 * Prints the necessary markup for the embed comments button. |
1100 * |
1113 * |
1149 */ |
1162 */ |
1150 function print_embed_sharing_dialog() { |
1163 function print_embed_sharing_dialog() { |
1151 if ( is_404() ) { |
1164 if ( is_404() ) { |
1152 return; |
1165 return; |
1153 } |
1166 } |
|
1167 |
|
1168 $unique_suffix = get_the_ID() . '-' . wp_rand(); |
|
1169 $share_tab_wordpress_id = 'wp-embed-share-tab-wordpress-' . $unique_suffix; |
|
1170 $share_tab_html_id = 'wp-embed-share-tab-html-' . $unique_suffix; |
|
1171 $description_wordpress_id = 'wp-embed-share-description-wordpress-' . $unique_suffix; |
|
1172 $description_html_id = 'wp-embed-share-description-html-' . $unique_suffix; |
1154 ?> |
1173 ?> |
1155 <div class="wp-embed-share-dialog hidden" role="dialog" aria-label="<?php esc_attr_e( 'Sharing options' ); ?>"> |
1174 <div class="wp-embed-share-dialog hidden" role="dialog" aria-label="<?php esc_attr_e( 'Sharing options' ); ?>"> |
1156 <div class="wp-embed-share-dialog-content"> |
1175 <div class="wp-embed-share-dialog-content"> |
1157 <div class="wp-embed-share-dialog-text"> |
1176 <div class="wp-embed-share-dialog-text"> |
1158 <ul class="wp-embed-share-tabs" role="tablist"> |
1177 <ul class="wp-embed-share-tabs" role="tablist"> |
1159 <li class="wp-embed-share-tab-button wp-embed-share-tab-button-wordpress" role="presentation"> |
1178 <li class="wp-embed-share-tab-button wp-embed-share-tab-button-wordpress" role="presentation"> |
1160 <button type="button" role="tab" aria-controls="wp-embed-share-tab-wordpress" aria-selected="true" tabindex="0"><?php esc_html_e( 'WordPress Embed' ); ?></button> |
1179 <button type="button" role="tab" aria-controls="<?php echo $share_tab_wordpress_id; ?>" aria-selected="true" tabindex="0"><?php esc_html_e( 'WordPress Embed' ); ?></button> |
1161 </li> |
1180 </li> |
1162 <li class="wp-embed-share-tab-button wp-embed-share-tab-button-html" role="presentation"> |
1181 <li class="wp-embed-share-tab-button wp-embed-share-tab-button-html" role="presentation"> |
1163 <button type="button" role="tab" aria-controls="wp-embed-share-tab-html" aria-selected="false" tabindex="-1"><?php esc_html_e( 'HTML Embed' ); ?></button> |
1182 <button type="button" role="tab" aria-controls="<?php echo $share_tab_html_id; ?>" aria-selected="false" tabindex="-1"><?php esc_html_e( 'HTML Embed' ); ?></button> |
1164 </li> |
1183 </li> |
1165 </ul> |
1184 </ul> |
1166 <div id="wp-embed-share-tab-wordpress" class="wp-embed-share-tab" role="tabpanel" aria-hidden="false"> |
1185 <div id="<?php echo $share_tab_wordpress_id; ?>" class="wp-embed-share-tab" role="tabpanel" aria-hidden="false"> |
1167 <input type="text" value="<?php the_permalink(); ?>" class="wp-embed-share-input" aria-describedby="wp-embed-share-description-wordpress" tabindex="0" readonly/> |
1186 <input type="text" value="<?php the_permalink(); ?>" class="wp-embed-share-input" aria-label="<?php esc_attr_e( 'URL' ); ?>" aria-describedby="<?php echo $description_wordpress_id; ?>" tabindex="0" readonly/> |
1168 |
1187 |
1169 <p class="wp-embed-share-description" id="wp-embed-share-description-wordpress"> |
1188 <p class="wp-embed-share-description" id="<?php echo $description_wordpress_id; ?>"> |
1170 <?php _e( 'Copy and paste this URL into your WordPress site to embed' ); ?> |
1189 <?php _e( 'Copy and paste this URL into your WordPress site to embed' ); ?> |
1171 </p> |
1190 </p> |
1172 </div> |
1191 </div> |
1173 <div id="wp-embed-share-tab-html" class="wp-embed-share-tab" role="tabpanel" aria-hidden="true"> |
1192 <div id="<?php echo $share_tab_html_id; ?>" class="wp-embed-share-tab" role="tabpanel" aria-hidden="true"> |
1174 <textarea class="wp-embed-share-input" aria-describedby="wp-embed-share-description-html" tabindex="0" readonly><?php echo esc_textarea( get_post_embed_html( 600, 400 ) ); ?></textarea> |
1193 <textarea class="wp-embed-share-input" aria-label="<?php esc_attr_e( 'HTML' ); ?>" aria-describedby="<?php echo $description_html_id; ?>" tabindex="0" readonly><?php echo esc_textarea( get_post_embed_html( 600, 400 ) ); ?></textarea> |
1175 |
1194 |
1176 <p class="wp-embed-share-description" id="wp-embed-share-description-html"> |
1195 <p class="wp-embed-share-description" id="<?php echo $description_html_id; ?>"> |
1177 <?php _e( 'Copy and paste this code into your site to embed' ); ?> |
1196 <?php _e( 'Copy and paste this code into your site to embed' ); ?> |
1178 </p> |
1197 </p> |
1179 </div> |
1198 </div> |
1180 </div> |
1199 </div> |
1181 |
1200 |