wp/wp-includes/class-wp-embed.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    26 
    26 
    27 	/**
    27 	/**
    28 	 * Constructor
    28 	 * Constructor
    29 	 */
    29 	 */
    30 	public function __construct() {
    30 	public function __construct() {
    31 		// Hack to get the [embed] shortcode to run before wpautop()
    31 		// Hack to get the [embed] shortcode to run before wpautop().
    32 		add_filter( 'the_content', array( $this, 'run_shortcode' ), 8 );
    32 		add_filter( 'the_content', array( $this, 'run_shortcode' ), 8 );
    33 		add_filter( 'widget_text_content', array( $this, 'run_shortcode' ), 8 );
    33 		add_filter( 'widget_text_content', array( $this, 'run_shortcode' ), 8 );
    34 
    34 
    35 		// Shortcode placeholder for strip_shortcodes()
    35 		// Shortcode placeholder for strip_shortcodes().
    36 		add_shortcode( 'embed', '__return_false' );
    36 		add_shortcode( 'embed', '__return_false' );
    37 
    37 
    38 		// Attempts to embed all URLs in a post
    38 		// Attempts to embed all URLs in a post.
    39 		add_filter( 'the_content', array( $this, 'autoembed' ), 8 );
    39 		add_filter( 'the_content', array( $this, 'autoembed' ), 8 );
    40 		add_filter( 'widget_text_content', array( $this, 'autoembed' ), 8 );
    40 		add_filter( 'widget_text_content', array( $this, 'autoembed' ), 8 );
    41 
    41 
    42 		// After a post is saved, cache oEmbed items via Ajax
    42 		// After a post is saved, cache oEmbed items via Ajax.
    43 		add_action( 'edit_form_advanced', array( $this, 'maybe_run_ajax_cache' ) );
    43 		add_action( 'edit_form_advanced', array( $this, 'maybe_run_ajax_cache' ) );
    44 		add_action( 'edit_page_form', array( $this, 'maybe_run_ajax_cache' ) );
    44 		add_action( 'edit_page_form', array( $this, 'maybe_run_ajax_cache' ) );
    45 	}
    45 	}
    46 
    46 
    47 	/**
    47 	/**
    57 	 * @return string Content with shortcode parsed
    57 	 * @return string Content with shortcode parsed
    58 	 */
    58 	 */
    59 	public function run_shortcode( $content ) {
    59 	public function run_shortcode( $content ) {
    60 		global $shortcode_tags;
    60 		global $shortcode_tags;
    61 
    61 
    62 		// Back up current registered shortcodes and clear them all out
    62 		// Back up current registered shortcodes and clear them all out.
    63 		$orig_shortcode_tags = $shortcode_tags;
    63 		$orig_shortcode_tags = $shortcode_tags;
    64 		remove_all_shortcodes();
    64 		remove_all_shortcodes();
    65 
    65 
    66 		add_shortcode( 'embed', array( $this, 'shortcode' ) );
    66 		add_shortcode( 'embed', array( $this, 'shortcode' ) );
    67 
    67 
    68 		// Do the shortcode (only the [embed] one is registered)
    68 		// Do the shortcode (only the [embed] one is registered).
    69 		$content = do_shortcode( $content, true );
    69 		$content = do_shortcode( $content, true );
    70 
    70 
    71 		// Put the original shortcodes back
    71 		// Put the original shortcodes back.
    72 		$shortcode_tags = $orig_shortcode_tags;
    72 		$shortcode_tags = $orig_shortcode_tags;
    73 
    73 
    74 		return $content;
    74 		return $content;
    75 	}
    75 	}
    76 
    76 
    99 	 *
    99 	 *
   100 	 * Do not use this function directly, use wp_embed_register_handler() instead.
   100 	 * Do not use this function directly, use wp_embed_register_handler() instead.
   101 	 *
   101 	 *
   102 	 * This function should probably also only be used for sites that do not support oEmbed.
   102 	 * This function should probably also only be used for sites that do not support oEmbed.
   103 	 *
   103 	 *
   104 	 * @param string $id An internal ID/name for the handler. Needs to be unique.
   104 	 * @param string   $id       An internal ID/name for the handler. Needs to be unique.
   105 	 * @param string $regex The regex that will be used to see if this handler should be used for a URL.
   105 	 * @param string   $regex    The regex that will be used to see if this handler should be used for a URL.
   106 	 * @param callable $callback The callback function that will be called if the regex is matched.
   106 	 * @param callable $callback The callback function that will be called if the regex is matched.
   107 	 * @param int $priority Optional. Used to specify the order in which the registered handlers will be tested (default: 10). Lower numbers correspond with earlier testing, and handlers with the same priority are tested in the order in which they were added to the action.
   107 	 * @param int      $priority Optional. Used to specify the order in which the registered handlers will be tested.
       
   108 	 *                           Lower numbers correspond with earlier testing, and handlers with the same priority are
       
   109 	 *                           tested in the order in which they were added to the action. Default 10.
   108 	 */
   110 	 */
   109 	public function register_handler( $id, $regex, $callback, $priority = 10 ) {
   111 	public function register_handler( $id, $regex, $callback, $priority = 10 ) {
   110 		$this->handlers[ $priority ][ $id ] = array(
   112 		$this->handlers[ $priority ][ $id ] = array(
   111 			'regex'    => $regex,
   113 			'regex'    => $regex,
   112 			'callback' => $callback,
   114 			'callback' => $callback,
   116 	/**
   118 	/**
   117 	 * Unregisters a previously-registered embed handler.
   119 	 * Unregisters a previously-registered embed handler.
   118 	 *
   120 	 *
   119 	 * Do not use this function directly, use wp_embed_unregister_handler() instead.
   121 	 * Do not use this function directly, use wp_embed_unregister_handler() instead.
   120 	 *
   122 	 *
   121 	 * @param string $id The handler ID that should be removed.
   123 	 * @param string $id       The handler ID that should be removed.
   122 	 * @param int $priority Optional. The priority of the handler to be removed (default: 10).
   124 	 * @param int    $priority Optional. The priority of the handler to be removed (default: 10).
   123 	 */
   125 	 */
   124 	public function unregister_handler( $id, $priority = 10 ) {
   126 	public function unregister_handler( $id, $priority = 10 ) {
   125 		unset( $this->handlers[ $priority ][ $id ] );
   127 		unset( $this->handlers[ $priority ][ $id ] );
       
   128 	}
       
   129 
       
   130 	/**
       
   131 	 * Returns embed HTML for a given URL from embed handlers.
       
   132 	 *
       
   133 	 * Attempts to convert a URL into embed HTML by checking the URL
       
   134 	 * against the regex of the registered embed handlers.
       
   135 	 *
       
   136 	 * @since 5.5.0
       
   137 	 *
       
   138 	 * @param array  $attr {
       
   139 	 *     Shortcode attributes. Optional.
       
   140 	 *
       
   141 	 *     @type int $width  Width of the embed in pixels.
       
   142 	 *     @type int $height Height of the embed in pixels.
       
   143 	 * }
       
   144 	 * @param string $url The URL attempting to be embedded.
       
   145 	 * @return string|false The embed HTML on success, false otherwise.
       
   146 	 */
       
   147 	public function get_embed_handler_html( $attr, $url ) {
       
   148 		$rawattr = $attr;
       
   149 		$attr    = wp_parse_args( $attr, wp_embed_defaults( $url ) );
       
   150 
       
   151 		ksort( $this->handlers );
       
   152 		foreach ( $this->handlers as $priority => $handlers ) {
       
   153 			foreach ( $handlers as $id => $handler ) {
       
   154 				if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) {
       
   155 					$return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr );
       
   156 					if ( false !== $return ) {
       
   157 						/**
       
   158 						 * Filters the returned embed HTML.
       
   159 						 *
       
   160 						 * @since 2.9.0
       
   161 						 *
       
   162 						 * @see WP_Embed::shortcode()
       
   163 						 *
       
   164 						 * @param string|false $return The HTML result of the shortcode, or false on failure.
       
   165 						 * @param string       $url    The embed URL.
       
   166 						 * @param array        $attr   An array of shortcode attributes.
       
   167 						 */
       
   168 						return apply_filters( 'embed_handler_html', $return, $url, $attr );
       
   169 					}
       
   170 				}
       
   171 			}
       
   172 		}
       
   173 
       
   174 		return false;
   126 	}
   175 	}
   127 
   176 
   128 	/**
   177 	/**
   129 	 * The do_shortcode() callback function.
   178 	 * The do_shortcode() callback function.
   130 	 *
   179 	 *
   131 	 * Attempts to convert a URL into embed HTML. Starts by checking the URL against the regex of
   180 	 * Attempts to convert a URL into embed HTML. Starts by checking the URL against the regex of
   132 	 * the registered embed handlers. If none of the regex matches and it's enabled, then the URL
   181 	 * the registered embed handlers. If none of the regex matches and it's enabled, then the URL
   133 	 * will be given to the WP_oEmbed class.
   182 	 * will be given to the WP_oEmbed class.
   134 	 *
   183 	 *
   135 	 * @param array $attr {
   184 	 * @param array  $attr {
   136 	 *     Shortcode attributes. Optional.
   185 	 *     Shortcode attributes. Optional.
   137 	 *
   186 	 *
   138 	 *     @type int $width  Width of the embed in pixels.
   187 	 *     @type int $width  Width of the embed in pixels.
   139 	 *     @type int $height Height of the embed in pixels.
   188 	 *     @type int $height Height of the embed in pixels.
   140 	 * }
   189 	 * }
   159 		$rawattr = $attr;
   208 		$rawattr = $attr;
   160 		$attr    = wp_parse_args( $attr, wp_embed_defaults( $url ) );
   209 		$attr    = wp_parse_args( $attr, wp_embed_defaults( $url ) );
   161 
   210 
   162 		$this->last_attr = $attr;
   211 		$this->last_attr = $attr;
   163 
   212 
   164 		// kses converts & into & and we need to undo this
   213 		// KSES converts & into & and we need to undo this.
   165 		// See https://core.trac.wordpress.org/ticket/11311
   214 		// See https://core.trac.wordpress.org/ticket/11311
   166 		$url = str_replace( '&', '&', $url );
   215 		$url = str_replace( '&', '&', $url );
   167 
   216 
   168 		// Look for known internal handlers
   217 		// Look for known internal handlers.
   169 		ksort( $this->handlers );
   218 		$embed_handler_html = $this->get_embed_handler_html( $rawattr, $url );
   170 		foreach ( $this->handlers as $priority => $handlers ) {
   219 		if ( false !== $embed_handler_html ) {
   171 			foreach ( $handlers as $id => $handler ) {
   220 			return $embed_handler_html;
   172 				if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) {
       
   173 					if ( false !== $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ) ) {
       
   174 						/**
       
   175 						 * Filters the returned embed handler.
       
   176 						 *
       
   177 						 * @since 2.9.0
       
   178 						 *
       
   179 						 * @see WP_Embed::shortcode()
       
   180 						 *
       
   181 						 * @param mixed  $return The shortcode callback function to call.
       
   182 						 * @param string $url    The attempted embed URL.
       
   183 						 * @param array  $attr   An array of shortcode attributes.
       
   184 						 */
       
   185 						return apply_filters( 'embed_handler_html', $return, $url, $attr );
       
   186 					}
       
   187 				}
       
   188 			}
       
   189 		}
   221 		}
   190 
   222 
   191 		$post_ID = ( ! empty( $post->ID ) ) ? $post->ID : null;
   223 		$post_ID = ( ! empty( $post->ID ) ) ? $post->ID : null;
   192 
   224 
   193 		// Potentially set by WP_Embed::cache_oembed().
   225 		// Potentially set by WP_Embed::cache_oembed().
   245 				 *
   277 				 *
   246 				 * @since 2.9.0
   278 				 * @since 2.9.0
   247 				 *
   279 				 *
   248 				 * @see WP_Embed::shortcode()
   280 				 * @see WP_Embed::shortcode()
   249 				 *
   281 				 *
   250 				 * @param mixed  $cache   The cached HTML result, stored in post meta.
   282 				 * @param string|false $cache   The cached HTML result, stored in post meta.
   251 				 * @param string $url     The attempted embed URL.
   283 				 * @param string       $url     The attempted embed URL.
   252 				 * @param array  $attr    An array of shortcode attributes.
   284 				 * @param array        $attr    An array of shortcode attributes.
   253 				 * @param int    $post_ID Post ID.
   285 				 * @param int          $post_ID Post ID.
   254 				 */
   286 				 */
   255 				return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_ID );
   287 				return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_ID );
   256 			}
   288 			}
   257 		}
   289 		}
   258 
   290 
   336 		if ( $html ) {
   368 		if ( $html ) {
   337 			/** This filter is documented in wp-includes/class-wp-embed.php */
   369 			/** This filter is documented in wp-includes/class-wp-embed.php */
   338 			return apply_filters( 'embed_oembed_html', $html, $url, $attr, $post_ID );
   370 			return apply_filters( 'embed_oembed_html', $html, $url, $attr, $post_ID );
   339 		}
   371 		}
   340 
   372 
   341 		// Still unknown
   373 		// Still unknown.
   342 		return $this->maybe_make_link( $url );
   374 		return $this->maybe_make_link( $url );
   343 	}
   375 	}
   344 
   376 
   345 	/**
   377 	/**
   346 	 * Delete all oEmbed caches. Unused by core as of 4.0.0.
   378 	 * Delete all oEmbed caches. Unused by core as of 4.0.0.
   352 		if ( empty( $post_metas ) ) {
   384 		if ( empty( $post_metas ) ) {
   353 			return;
   385 			return;
   354 		}
   386 		}
   355 
   387 
   356 		foreach ( $post_metas as $post_meta_key ) {
   388 		foreach ( $post_metas as $post_meta_key ) {
   357 			if ( '_oembed_' == substr( $post_meta_key, 0, 8 ) ) {
   389 			if ( '_oembed_' === substr( $post_meta_key, 0, 8 ) ) {
   358 				delete_post_meta( $post_ID, $post_meta_key );
   390 				delete_post_meta( $post_ID, $post_meta_key );
   359 			}
   391 			}
   360 		}
   392 		}
   361 	}
   393 	}
   362 
   394 
   367 	 */
   399 	 */
   368 	public function cache_oembed( $post_ID ) {
   400 	public function cache_oembed( $post_ID ) {
   369 		$post = get_post( $post_ID );
   401 		$post = get_post( $post_ID );
   370 
   402 
   371 		$post_types = get_post_types( array( 'show_ui' => true ) );
   403 		$post_types = get_post_types( array( 'show_ui' => true ) );
       
   404 
   372 		/**
   405 		/**
   373 		 * Filters the array of post types to cache oEmbed results for.
   406 		 * Filters the array of post types to cache oEmbed results for.
   374 		 *
   407 		 *
   375 		 * @since 2.9.0
   408 		 * @since 2.9.0
   376 		 *
   409 		 *
   377 		 * @param string[] $post_types Array of post type names to cache oEmbed results for. Defaults to post types with `show_ui` set to true.
   410 		 * @param string[] $post_types Array of post type names to cache oEmbed results for. Defaults to post types with `show_ui` set to true.
   378 		 */
   411 		 */
   379 		if ( empty( $post->ID ) || ! in_array( $post->post_type, apply_filters( 'embed_cache_oembed_types', $post_types ) ) ) {
   412 		$cache_oembed_types = apply_filters( 'embed_cache_oembed_types', $post_types );
       
   413 
       
   414 		if ( empty( $post->ID ) || ! in_array( $post->post_type, $cache_oembed_types, true ) ) {
   380 			return;
   415 			return;
   381 		}
   416 		}
   382 
   417 
   383 		// Trigger a caching
   418 		// Trigger a caching.
   384 		if ( ! empty( $post->post_content ) ) {
   419 		if ( ! empty( $post->post_content ) ) {
   385 			$this->post_ID  = $post->ID;
   420 			$this->post_ID  = $post->ID;
   386 			$this->usecache = false;
   421 			$this->usecache = false;
   387 
   422 
   388 			$content = $this->run_shortcode( $post->post_content );
   423 			$content = $this->run_shortcode( $post->post_content );
   432 
   467 
   433 	/**
   468 	/**
   434 	 * Conditionally makes a hyperlink based on an internal class variable.
   469 	 * Conditionally makes a hyperlink based on an internal class variable.
   435 	 *
   470 	 *
   436 	 * @param string $url URL to potentially be linked.
   471 	 * @param string $url URL to potentially be linked.
   437 	 * @return false|string Linked URL or the original URL. False if 'return_false_on_fail' is true.
   472 	 * @return string|false Linked URL or the original URL. False if 'return_false_on_fail' is true.
   438 	 */
   473 	 */
   439 	public function maybe_make_link( $url ) {
   474 	public function maybe_make_link( $url ) {
   440 		if ( $this->return_false_on_fail ) {
   475 		if ( $this->return_false_on_fail ) {
   441 			return false;
   476 			return false;
   442 		}
   477 		}
   483 				'lazy_load_term_meta'    => false,
   518 				'lazy_load_term_meta'    => false,
   484 			)
   519 			)
   485 		);
   520 		);
   486 
   521 
   487 		if ( ! empty( $oembed_post_query->posts ) ) {
   522 		if ( ! empty( $oembed_post_query->posts ) ) {
   488 			// Note: 'fields'=>'ids' is not being used in order to cache the post object as it will be needed.
   523 			// Note: 'fields' => 'ids' is not being used in order to cache the post object as it will be needed.
   489 			$oembed_post_id = $oembed_post_query->posts[0]->ID;
   524 			$oembed_post_id = $oembed_post_query->posts[0]->ID;
   490 			wp_cache_set( $cache_key, $oembed_post_id, $cache_group );
   525 			wp_cache_set( $cache_key, $oembed_post_id, $cache_group );
   491 
   526 
   492 			return $oembed_post_id;
   527 			return $oembed_post_id;
   493 		}
   528 		}