wp/wp-includes/class-wp-embed.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
     7  * @since 2.9.0
     7  * @since 2.9.0
     8  */
     8  */
     9 class WP_Embed {
     9 class WP_Embed {
    10 	public $handlers = array();
    10 	public $handlers = array();
    11 	public $post_ID;
    11 	public $post_ID;
    12 	public $usecache = true;
    12 	public $usecache      = true;
    13 	public $linkifunknown = true;
    13 	public $linkifunknown = true;
    14 	public $last_attr = array();
    14 	public $last_attr     = array();
    15 	public $last_url = '';
    15 	public $last_url      = '';
    16 
    16 
    17 	/**
    17 	/**
    18 	 * When a URL cannot be embedded, return false instead of returning a link
    18 	 * When a URL cannot be embedded, return false instead of returning a link
    19 	 * or the URL.
    19 	 * or the URL.
    20 	 *
    20 	 *
    79 	 * an Ajax request that will call WP_Embed::cache_oembed().
    79 	 * an Ajax request that will call WP_Embed::cache_oembed().
    80 	 */
    80 	 */
    81 	public function maybe_run_ajax_cache() {
    81 	public function maybe_run_ajax_cache() {
    82 		$post = get_post();
    82 		$post = get_post();
    83 
    83 
    84 		if ( ! $post || empty( $_GET['message'] ) )
    84 		if ( ! $post || empty( $_GET['message'] ) ) {
    85 			return;
    85 			return;
    86 
    86 		}
    87 ?>
    87 
       
    88 		?>
    88 <script type="text/javascript">
    89 <script type="text/javascript">
    89 	jQuery(document).ready(function($){
    90 	jQuery(document).ready(function($){
    90 		$.get("<?php echo admin_url( 'admin-ajax.php?action=oembed-cache&post=' . $post->ID, 'relative' ); ?>");
    91 		$.get("<?php echo admin_url( 'admin-ajax.php?action=oembed-cache&post=' . $post->ID, 'relative' ); ?>");
    91 	});
    92 	});
    92 </script>
    93 </script>
    93 <?php
    94 		<?php
    94 	}
    95 	}
    95 
    96 
    96 	/**
    97 	/**
    97 	 * Registers an embed handler.
    98 	 * Registers an embed handler.
    98 	 *
    99 	 *
   104 	 * @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.
   105 	 * @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.
   106 	 * @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 (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 	 */
   108 	 */
   108 	public function register_handler( $id, $regex, $callback, $priority = 10 ) {
   109 	public function register_handler( $id, $regex, $callback, $priority = 10 ) {
   109 		$this->handlers[$priority][$id] = array(
   110 		$this->handlers[ $priority ][ $id ] = array(
   110 			'regex'    => $regex,
   111 			'regex'    => $regex,
   111 			'callback' => $callback,
   112 			'callback' => $callback,
   112 		);
   113 		);
   113 	}
   114 	}
   114 
   115 
   154 			$this->last_attr = $attr;
   155 			$this->last_attr = $attr;
   155 			return '';
   156 			return '';
   156 		}
   157 		}
   157 
   158 
   158 		$rawattr = $attr;
   159 		$rawattr = $attr;
   159 		$attr = wp_parse_args( $attr, wp_embed_defaults( $url ) );
   160 		$attr    = wp_parse_args( $attr, wp_embed_defaults( $url ) );
   160 
   161 
   161 		$this->last_attr = $attr;
   162 		$this->last_attr = $attr;
   162 
   163 
   163 		// kses converts & into &amp; and we need to undo this
   164 		// kses converts & into &amp; and we need to undo this
   164 		// See https://core.trac.wordpress.org/ticket/11311
   165 		// See https://core.trac.wordpress.org/ticket/11311
   167 		// Look for known internal handlers
   168 		// Look for known internal handlers
   168 		ksort( $this->handlers );
   169 		ksort( $this->handlers );
   169 		foreach ( $this->handlers as $priority => $handlers ) {
   170 		foreach ( $this->handlers as $priority => $handlers ) {
   170 			foreach ( $handlers as $id => $handler ) {
   171 			foreach ( $handlers as $id => $handler ) {
   171 				if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) {
   172 				if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) {
   172 					if ( false !== $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ) )
   173 					if ( false !== $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ) ) {
   173 						/**
   174 						/**
   174 						 * Filters the returned embed handler.
   175 						 * Filters the returned embed handler.
   175 						 *
   176 						 *
   176 						 * @since 2.9.0
   177 						 * @since 2.9.0
   177 						 *
   178 						 *
   180 						 * @param mixed  $return The shortcode callback function to call.
   181 						 * @param mixed  $return The shortcode callback function to call.
   181 						 * @param string $url    The attempted embed URL.
   182 						 * @param string $url    The attempted embed URL.
   182 						 * @param array  $attr   An array of shortcode attributes.
   183 						 * @param array  $attr   An array of shortcode attributes.
   183 						 */
   184 						 */
   184 						return apply_filters( 'embed_handler_html', $return, $url, $attr );
   185 						return apply_filters( 'embed_handler_html', $return, $url, $attr );
       
   186 					}
   185 				}
   187 				}
   186 			}
   188 			}
   187 		}
   189 		}
   188 
   190 
   189 		$post_ID = ( ! empty( $post->ID ) ) ? $post->ID : null;
   191 		$post_ID = ( ! empty( $post->ID ) ) ? $post->ID : null;
   214 		$cache_time = 0;
   216 		$cache_time = 0;
   215 
   217 
   216 		$cached_post_id = $this->find_oembed_post_id( $key_suffix );
   218 		$cached_post_id = $this->find_oembed_post_id( $key_suffix );
   217 
   219 
   218 		if ( $post_ID ) {
   220 		if ( $post_ID ) {
   219 			$cache = get_post_meta( $post_ID, $cachekey, true );
   221 			$cache      = get_post_meta( $post_ID, $cachekey, true );
   220 			$cache_time = get_post_meta( $post_ID, $cachekey_time, true );
   222 			$cache_time = get_post_meta( $post_ID, $cachekey_time, true );
   221 
   223 
   222 			if ( ! $cache_time ) {
   224 			if ( ! $cache_time ) {
   223 				$cache_time = 0;
   225 				$cache_time = 0;
   224 			}
   226 			}
   283 				// Prevent KSES from corrupting JSON in post_content.
   285 				// Prevent KSES from corrupting JSON in post_content.
   284 				kses_remove_filters();
   286 				kses_remove_filters();
   285 			}
   287 			}
   286 
   288 
   287 			$insert_post_args = array(
   289 			$insert_post_args = array(
   288 				'post_name' => $key_suffix,
   290 				'post_name'   => $key_suffix,
   289 				'post_status' => 'publish',
   291 				'post_status' => 'publish',
   290 				'post_type' => 'oembed_cache',
   292 				'post_type'   => 'oembed_cache',
   291 			);
   293 			);
   292 
   294 
   293 			if ( $html ) {
   295 			if ( $html ) {
   294 				if ( $cached_post_id ) {
   296 				if ( $cached_post_id ) {
   295 					wp_update_post( wp_slash( array(
   297 					wp_update_post(
   296 						'ID' => $cached_post_id,
   298 						wp_slash(
   297 						'post_content' => $html,
   299 							array(
   298 					) ) );
   300 								'ID'           => $cached_post_id,
       
   301 								'post_content' => $html,
       
   302 							)
       
   303 						)
       
   304 					);
   299 				} else {
   305 				} else {
   300 					wp_insert_post( wp_slash( array_merge(
   306 					wp_insert_post(
   301 						$insert_post_args,
   307 						wp_slash(
   302 						array(
   308 							array_merge(
   303 							'post_content' => $html,
   309 								$insert_post_args,
       
   310 								array(
       
   311 									'post_content' => $html,
       
   312 								)
       
   313 							)
   304 						)
   314 						)
   305 					) ) );
   315 					);
   306 				}
   316 				}
   307 			} elseif ( ! $cache ) {
   317 			} elseif ( ! $cache ) {
   308 				wp_insert_post( wp_slash( array_merge(
   318 				wp_insert_post(
   309 					$insert_post_args,
   319 					wp_slash(
   310 					array(
   320 						array_merge(
   311 						'post_content' => '{{unknown}}',
   321 							$insert_post_args,
       
   322 							array(
       
   323 								'post_content' => '{{unknown}}',
       
   324 							)
       
   325 						)
   312 					)
   326 					)
   313 				) ) );
   327 				);
   314 			}
   328 			}
   315 
   329 
   316 			if ( $has_kses ) {
   330 			if ( $has_kses ) {
   317 				kses_init_filters();
   331 				kses_init_filters();
   318 			}
   332 			}
   333 	 *
   347 	 *
   334 	 * @param int $post_ID Post ID to delete the caches for.
   348 	 * @param int $post_ID Post ID to delete the caches for.
   335 	 */
   349 	 */
   336 	public function delete_oembed_caches( $post_ID ) {
   350 	public function delete_oembed_caches( $post_ID ) {
   337 		$post_metas = get_post_custom_keys( $post_ID );
   351 		$post_metas = get_post_custom_keys( $post_ID );
   338 		if ( empty($post_metas) )
   352 		if ( empty( $post_metas ) ) {
   339 			return;
   353 			return;
       
   354 		}
   340 
   355 
   341 		foreach ( $post_metas as $post_meta_key ) {
   356 		foreach ( $post_metas as $post_meta_key ) {
   342 			if ( '_oembed_' == substr( $post_meta_key, 0, 8 ) )
   357 			if ( '_oembed_' == substr( $post_meta_key, 0, 8 ) ) {
   343 				delete_post_meta( $post_ID, $post_meta_key );
   358 				delete_post_meta( $post_ID, $post_meta_key );
       
   359 			}
   344 		}
   360 		}
   345 	}
   361 	}
   346 
   362 
   347 	/**
   363 	/**
   348 	 * Triggers a caching of all oEmbed results.
   364 	 * Triggers a caching of all oEmbed results.
   356 		/**
   372 		/**
   357 		 * Filters the array of post types to cache oEmbed results for.
   373 		 * Filters the array of post types to cache oEmbed results for.
   358 		 *
   374 		 *
   359 		 * @since 2.9.0
   375 		 * @since 2.9.0
   360 		 *
   376 		 *
   361 		 * @param array $post_types Array of post types to cache oEmbed results for. Defaults to post types with `show_ui` set to true.
   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.
   362 		 */
   378 		 */
   363 		if ( empty( $post->ID ) || ! in_array( $post->post_type, apply_filters( 'embed_cache_oembed_types', $post_types ) ) ){
   379 		if ( empty( $post->ID ) || ! in_array( $post->post_type, apply_filters( 'embed_cache_oembed_types', $post_types ) ) ) {
   364 			return;
   380 			return;
   365 		}
   381 		}
   366 
   382 
   367 		// Trigger a caching
   383 		// Trigger a caching
   368 		if ( ! empty( $post->post_content ) ) {
   384 		if ( ! empty( $post->post_content ) ) {
   369 			$this->post_ID = $post->ID;
   385 			$this->post_ID  = $post->ID;
   370 			$this->usecache = false;
   386 			$this->usecache = false;
   371 
   387 
   372 			$content = $this->run_shortcode( $post->post_content );
   388 			$content = $this->run_shortcode( $post->post_content );
   373 			$this->autoembed( $content );
   389 			$this->autoembed( $content );
   374 
   390 
   404 	 *
   420 	 *
   405 	 * @param array $match A regex match array.
   421 	 * @param array $match A regex match array.
   406 	 * @return string The embed HTML on success, otherwise the original URL.
   422 	 * @return string The embed HTML on success, otherwise the original URL.
   407 	 */
   423 	 */
   408 	public function autoembed_callback( $match ) {
   424 	public function autoembed_callback( $match ) {
   409 		$oldval = $this->linkifunknown;
   425 		$oldval              = $this->linkifunknown;
   410 		$this->linkifunknown = false;
   426 		$this->linkifunknown = false;
   411 		$return = $this->shortcode( array(), $match[2] );
   427 		$return              = $this->shortcode( array(), $match[2] );
   412 		$this->linkifunknown = $oldval;
   428 		$this->linkifunknown = $oldval;
   413 
   429 
   414 		return $match[1] . $return . $match[3];
   430 		return $match[1] . $return . $match[3];
   415 	}
   431 	}
   416 
   432 
   423 	public function maybe_make_link( $url ) {
   439 	public function maybe_make_link( $url ) {
   424 		if ( $this->return_false_on_fail ) {
   440 		if ( $this->return_false_on_fail ) {
   425 			return false;
   441 			return false;
   426 		}
   442 		}
   427 
   443 
   428 		$output = ( $this->linkifunknown ) ? '<a href="' . esc_url($url) . '">' . esc_html($url) . '</a>' : $url;
   444 		$output = ( $this->linkifunknown ) ? '<a href="' . esc_url( $url ) . '">' . esc_html( $url ) . '</a>' : $url;
   429 
   445 
   430 		/**
   446 		/**
   431 		 * Filters the returned, maybe-linked embed URL.
   447 		 * Filters the returned, maybe-linked embed URL.
   432 		 *
   448 		 *
   433 		 * @since 2.9.0
   449 		 * @since 2.9.0
   452 
   468 
   453 		if ( $oembed_post_id && 'oembed_cache' === get_post_type( $oembed_post_id ) ) {
   469 		if ( $oembed_post_id && 'oembed_cache' === get_post_type( $oembed_post_id ) ) {
   454 			return $oembed_post_id;
   470 			return $oembed_post_id;
   455 		}
   471 		}
   456 
   472 
   457 		$oembed_post_query = new WP_Query( array(
   473 		$oembed_post_query = new WP_Query(
   458 			'post_type'              => 'oembed_cache',
   474 			array(
   459 			'post_status'            => 'publish',
   475 				'post_type'              => 'oembed_cache',
   460 			'name'                   => $cache_key,
   476 				'post_status'            => 'publish',
   461 			'posts_per_page'         => 1,
   477 				'name'                   => $cache_key,
   462 			'no_found_rows'          => true,
   478 				'posts_per_page'         => 1,
   463 			'cache_results'          => true,
   479 				'no_found_rows'          => true,
   464 			'update_post_meta_cache' => false,
   480 				'cache_results'          => true,
   465 			'update_post_term_cache' => false,
   481 				'update_post_meta_cache' => false,
   466 			'lazy_load_term_meta'    => false,
   482 				'update_post_term_cache' => false,
   467 		) );
   483 				'lazy_load_term_meta'    => false,
       
   484 			)
       
   485 		);
   468 
   486 
   469 		if ( ! empty( $oembed_post_query->posts ) ) {
   487 		if ( ! empty( $oembed_post_query->posts ) ) {
   470 			// Note: 'fields'=>'ids' is not being used in order to cache the post object as it will be needed.
   488 			// Note: 'fields'=>'ids' is not being used in order to cache the post object as it will be needed.
   471 			$oembed_post_id = $oembed_post_query->posts[0]->ID;
   489 			$oembed_post_id = $oembed_post_query->posts[0]->ID;
   472 			wp_cache_set( $cache_key, $oembed_post_id, $cache_group );
   490 			wp_cache_set( $cache_key, $oembed_post_id, $cache_group );