wp/wp-includes/class-wp-oembed.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
     2 /**
     2 /**
     3  * API for fetching the HTML to embed remote content based on a provided URL
     3  * API for fetching the HTML to embed remote content based on a provided URL
     4  *
     4  *
     5  * Used internally by the WP_Embed class, but is designed to be generic.
     5  * Used internally by the WP_Embed class, but is designed to be generic.
     6  *
     6  *
     7  * @link https://wordpress.org/support/article/embeds/
     7  * @link https://developer.wordpress.org/advanced-administration/wordpress/oembed/
     8  * @link http://oembed.com/
     8  * @link http://oembed.com/
     9  *
     9  *
    10  * @package WordPress
    10  * @package WordPress
    11  * @subpackage oEmbed
    11  * @subpackage oEmbed
    12  */
    12  */
    14 /**
    14 /**
    15  * Core class used to implement oEmbed functionality.
    15  * Core class used to implement oEmbed functionality.
    16  *
    16  *
    17  * @since 2.9.0
    17  * @since 2.9.0
    18  */
    18  */
       
    19 #[AllowDynamicProperties]
    19 class WP_oEmbed {
    20 class WP_oEmbed {
    20 
    21 
    21 	/**
    22 	/**
    22 	 * A list of oEmbed providers.
    23 	 * A list of oEmbed providers.
    23 	 *
    24 	 *
    51 		$host      = urlencode( home_url() );
    52 		$host      = urlencode( home_url() );
    52 		$providers = array(
    53 		$providers = array(
    53 			'#https?://((m|www)\.)?youtube\.com/watch.*#i' => array( 'https://www.youtube.com/oembed', true ),
    54 			'#https?://((m|www)\.)?youtube\.com/watch.*#i' => array( 'https://www.youtube.com/oembed', true ),
    54 			'#https?://((m|www)\.)?youtube\.com/playlist.*#i' => array( 'https://www.youtube.com/oembed', true ),
    55 			'#https?://((m|www)\.)?youtube\.com/playlist.*#i' => array( 'https://www.youtube.com/oembed', true ),
    55 			'#https?://((m|www)\.)?youtube\.com/shorts/*#i' => array( 'https://www.youtube.com/oembed', true ),
    56 			'#https?://((m|www)\.)?youtube\.com/shorts/*#i' => array( 'https://www.youtube.com/oembed', true ),
       
    57 			'#https?://((m|www)\.)?youtube\.com/live/*#i'  => array( 'https://www.youtube.com/oembed', true ),
    56 			'#https?://youtu\.be/.*#i'                     => array( 'https://www.youtube.com/oembed', true ),
    58 			'#https?://youtu\.be/.*#i'                     => array( 'https://www.youtube.com/oembed', true ),
    57 			'#https?://(.+\.)?vimeo\.com/.*#i'             => array( 'https://vimeo.com/api/oembed.{format}', true ),
    59 			'#https?://(.+\.)?vimeo\.com/.*#i'             => array( 'https://vimeo.com/api/oembed.{format}', true ),
    58 			'#https?://(www\.)?dailymotion\.com/.*#i'      => array( 'https://www.dailymotion.com/services/oembed', true ),
    60 			'#https?://(www\.)?dailymotion\.com/.*#i'      => array( 'https://www.dailymotion.com/services/oembed', true ),
    59 			'#https?://dai\.ly/.*#i'                       => array( 'https://www.dailymotion.com/services/oembed', true ),
    61 			'#https?://dai\.ly/.*#i'                       => array( 'https://www.dailymotion.com/services/oembed', true ),
    60 			'#https?://(www\.)?flickr\.com/.*#i'           => array( 'https://www.flickr.com/services/oembed/', true ),
    62 			'#https?://(www\.)?flickr\.com/.*#i'           => array( 'https://www.flickr.com/services/oembed/', true ),
    61 			'#https?://flic\.kr/.*#i'                      => array( 'https://www.flickr.com/services/oembed/', true ),
    63 			'#https?://flic\.kr/.*#i'                      => array( 'https://www.flickr.com/services/oembed/', true ),
    62 			'#https?://(.+\.)?smugmug\.com/.*#i'           => array( 'https://api.smugmug.com/services/oembed/', true ),
    64 			'#https?://(.+\.)?smugmug\.com/.*#i'           => array( 'https://api.smugmug.com/services/oembed/', true ),
    63 			'#https?://(www\.)?scribd\.com/(doc|document)/.*#i' => array( 'https://www.scribd.com/services/oembed', true ),
    65 			'#https?://(www\.)?scribd\.com/(doc|document)/.*#i' => array( 'https://www.scribd.com/services/oembed', true ),
    64 			'#https?://wordpress\.tv/.*#i'                 => array( 'https://wordpress.tv/oembed/', true ),
    66 			'#https?://wordpress\.tv/.*#i'                 => array( 'https://wordpress.tv/oembed/', true ),
       
    67 			'#https?://(.+\.)?crowdsignal\.net/.*#i'       => array( 'https://api.crowdsignal.com/oembed', true ),
    65 			'#https?://(.+\.)?polldaddy\.com/.*#i'         => array( 'https://api.crowdsignal.com/oembed', true ),
    68 			'#https?://(.+\.)?polldaddy\.com/.*#i'         => array( 'https://api.crowdsignal.com/oembed', true ),
    66 			'#https?://poll\.fm/.*#i'                      => array( 'https://api.crowdsignal.com/oembed', true ),
    69 			'#https?://poll\.fm/.*#i'                      => array( 'https://api.crowdsignal.com/oembed', true ),
    67 			'#https?://(.+\.)?survey\.fm/.*#i'             => array( 'https://api.crowdsignal.com/oembed', true ),
    70 			'#https?://(.+\.)?survey\.fm/.*#i'             => array( 'https://api.crowdsignal.com/oembed', true ),
    68 			'#https?://(www\.)?twitter\.com/\w{1,15}/status(es)?/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
    71 			'#https?://(www\.)?twitter\.com/\w{1,15}/status(es)?/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
    69 			'#https?://(www\.)?twitter\.com/\w{1,15}$#i'   => array( 'https://publish.twitter.com/oembed', true ),
    72 			'#https?://(www\.)?twitter\.com/\w{1,15}$#i'   => array( 'https://publish.twitter.com/oembed', true ),
    70 			'#https?://(www\.)?twitter\.com/\w{1,15}/likes$#i' => array( 'https://publish.twitter.com/oembed', true ),
    73 			'#https?://(www\.)?twitter\.com/\w{1,15}/likes$#i' => array( 'https://publish.twitter.com/oembed', true ),
    71 			'#https?://(www\.)?twitter\.com/\w{1,15}/lists/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
    74 			'#https?://(www\.)?twitter\.com/\w{1,15}/lists/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
    72 			'#https?://(www\.)?twitter\.com/\w{1,15}/timelines/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
    75 			'#https?://(www\.)?twitter\.com/\w{1,15}/timelines/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
    73 			'#https?://(www\.)?twitter\.com/i/moments/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
    76 			'#https?://(www\.)?twitter\.com/i/moments/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
    74 			'#https?://(www\.)?soundcloud\.com/.*#i'       => array( 'https://soundcloud.com/oembed', true ),
    77 			'#https?://(www\.)?soundcloud\.com/.*#i'       => array( 'https://soundcloud.com/oembed', true ),
    75 			'#https?://(.+?\.)?slideshare\.net/.*#i'       => array( 'https://www.slideshare.net/api/oembed/2', true ),
       
    76 			'#https?://(open|play)\.spotify\.com/.*#i'     => array( 'https://embed.spotify.com/oembed/', true ),
    78 			'#https?://(open|play)\.spotify\.com/.*#i'     => array( 'https://embed.spotify.com/oembed/', true ),
    77 			'#https?://(.+\.)?imgur\.com/.*#i'             => array( 'https://api.imgur.com/oembed', true ),
    79 			'#https?://(.+\.)?imgur\.com/.*#i'             => array( 'https://api.imgur.com/oembed', true ),
    78 			'#https?://(www\.)?issuu\.com/.+/docs/.+#i'    => array( 'https://issuu.com/oembed_wp', true ),
    80 			'#https?://(www\.)?issuu\.com/.+/docs/.+#i'    => array( 'https://issuu.com/oembed_wp', true ),
    79 			'#https?://(www\.)?mixcloud\.com/.*#i'         => array( 'https://www.mixcloud.com/oembed', true ),
    81 			'#https?://(www\.)?mixcloud\.com/.*#i'         => array( 'https://app.mixcloud.com/oembed/', true ),
    80 			'#https?://(www\.|embed\.)?ted\.com/talks/.*#i' => array( 'https://www.ted.com/services/v1/oembed.{format}', true ),
    82 			'#https?://(www\.|embed\.)?ted\.com/talks/.*#i' => array( 'https://www.ted.com/services/v1/oembed.{format}', true ),
    81 			'#https?://(www\.)?(animoto|video214)\.com/play/.*#i' => array( 'https://animoto.com/oembeds/create', true ),
    83 			'#https?://(www\.)?(animoto|video214)\.com/play/.*#i' => array( 'https://animoto.com/oembeds/create', true ),
    82 			'#https?://(.+)\.tumblr\.com/post/.*#i'        => array( 'https://www.tumblr.com/oembed/1.0', true ),
    84 			'#https?://(.+)\.tumblr\.com/.*#i'             => array( 'https://www.tumblr.com/oembed/1.0', true ),
    83 			'#https?://(www\.)?kickstarter\.com/projects/.*#i' => array( 'https://www.kickstarter.com/services/oembed', true ),
    85 			'#https?://(www\.)?kickstarter\.com/projects/.*#i' => array( 'https://www.kickstarter.com/services/oembed', true ),
    84 			'#https?://kck\.st/.*#i'                       => array( 'https://www.kickstarter.com/services/oembed', true ),
    86 			'#https?://kck\.st/.*#i'                       => array( 'https://www.kickstarter.com/services/oembed', true ),
    85 			'#https?://cloudup\.com/.*#i'                  => array( 'https://cloudup.com/oembed', true ),
    87 			'#https?://cloudup\.com/.*#i'                  => array( 'https://cloudup.com/oembed', true ),
    86 			'#https?://(www\.)?reverbnation\.com/.*#i'     => array( 'https://www.reverbnation.com/oembed', true ),
    88 			'#https?://(www\.)?reverbnation\.com/.*#i'     => array( 'https://www.reverbnation.com/oembed', true ),
    87 			'#https?://videopress\.com/v/.*#'              => array( 'https://public-api.wordpress.com/oembed/?for=' . $host, true ),
    89 			'#https?://videopress\.com/v/.*#'              => array( 'https://public-api.wordpress.com/oembed/?for=' . $host, true ),
   100 			'#https?://(www\.)?z\.cn/.*#i'                 => array( 'https://read.amazon.cn/kp/api/oembed', true ),
   102 			'#https?://(www\.)?z\.cn/.*#i'                 => array( 'https://read.amazon.cn/kp/api/oembed', true ),
   101 			'#https?://www\.someecards\.com/.+-cards/.+#i' => array( 'https://www.someecards.com/v2/oembed/', true ),
   103 			'#https?://www\.someecards\.com/.+-cards/.+#i' => array( 'https://www.someecards.com/v2/oembed/', true ),
   102 			'#https?://www\.someecards\.com/usercards/viewcard/.+#i' => array( 'https://www.someecards.com/v2/oembed/', true ),
   104 			'#https?://www\.someecards\.com/usercards/viewcard/.+#i' => array( 'https://www.someecards.com/v2/oembed/', true ),
   103 			'#https?://some\.ly\/.+#i'                     => array( 'https://www.someecards.com/v2/oembed/', true ),
   105 			'#https?://some\.ly\/.+#i'                     => array( 'https://www.someecards.com/v2/oembed/', true ),
   104 			'#https?://(www\.)?tiktok\.com/.*/video/.*#i'  => array( 'https://www.tiktok.com/oembed', true ),
   106 			'#https?://(www\.)?tiktok\.com/.*/video/.*#i'  => array( 'https://www.tiktok.com/oembed', true ),
       
   107 			'#https?://(www\.)?tiktok\.com/@.*#i'          => array( 'https://www.tiktok.com/oembed', true ),
   105 			'#https?://([a-z]{2}|www)\.pinterest\.com(\.(au|mx))?/.*#i' => array( 'https://www.pinterest.com/oembed.json', true ),
   108 			'#https?://([a-z]{2}|www)\.pinterest\.com(\.(au|mx))?/.*#i' => array( 'https://www.pinterest.com/oembed.json', true ),
   106 			'#https?://(www\.)?wolframcloud\.com/obj/.+#i' => array( 'https://www.wolframcloud.com/oembed', true ),
   109 			'#https?://(www\.)?wolframcloud\.com/obj/.+#i' => array( 'https://www.wolframcloud.com/oembed', true ),
       
   110 			'#https?://pca\.st/.+#i'                       => array( 'https://pca.st/oembed.json', true ),
       
   111 			'#https?://((play|www)\.)?anghami\.com/.*#i'   => array( 'https://api.anghami.com/rest/v1/oembed.view', true ),
       
   112 			'#https?://bsky.app/profile/.*/post/.*#i'      => array( 'https://embed.bsky.app/oembed', true ),
   107 		);
   113 		);
   108 
   114 
   109 		if ( ! empty( self::$early_providers['add'] ) ) {
   115 		if ( ! empty( self::$early_providers['add'] ) ) {
   110 			foreach ( self::$early_providers['add'] as $format => $data ) {
   116 			foreach ( self::$early_providers['add'] as $format => $data ) {
   111 				$providers[ $format ] = $data;
   117 				$providers[ $format ] = $data;
   139 		 * | YouTube      | youtube.com/watch                         | 2.9.0   |
   145 		 * | YouTube      | youtube.com/watch                         | 2.9.0   |
   140 		 * | Crowdsignal  | polldaddy.com                             | 3.0.0   |
   146 		 * | Crowdsignal  | polldaddy.com                             | 3.0.0   |
   141 		 * | SmugMug      | smugmug.com                               | 3.0.0   |
   147 		 * | SmugMug      | smugmug.com                               | 3.0.0   |
   142 		 * | YouTube      | youtu.be                                  | 3.0.0   |
   148 		 * | YouTube      | youtu.be                                  | 3.0.0   |
   143 		 * | Twitter      | twitter.com                               | 3.4.0   |
   149 		 * | Twitter      | twitter.com                               | 3.4.0   |
   144 		 * | Slideshare   | slideshare.net                            | 3.5.0   |
       
   145 		 * | SoundCloud   | soundcloud.com                            | 3.5.0   |
   150 		 * | SoundCloud   | soundcloud.com                            | 3.5.0   |
   146 		 * | Dailymotion  | dai.ly                                    | 3.6.0   |
   151 		 * | Dailymotion  | dai.ly                                    | 3.6.0   |
   147 		 * | Flickr       | flic.kr                                   | 3.6.0   |
   152 		 * | Flickr       | flic.kr                                   | 3.6.0   |
   148 		 * | Spotify      | spotify.com                               | 3.6.0   |
   153 		 * | Spotify      | spotify.com                               | 3.6.0   |
   149 		 * | Imgur        | imgur.com                                 | 3.9.0   |
   154 		 * | Imgur        | imgur.com                                 | 3.9.0   |
   179 		 * | Someecards   | some.ly                                   | 4.9.0   |
   184 		 * | Someecards   | some.ly                                   | 4.9.0   |
   180 		 * | Crowdsignal  | survey.fm                                 | 5.1.0   |
   185 		 * | Crowdsignal  | survey.fm                                 | 5.1.0   |
   181 		 * | TikTok       | tiktok.com                                | 5.4.0   |
   186 		 * | TikTok       | tiktok.com                                | 5.4.0   |
   182 		 * | Pinterest    | pinterest.com                             | 5.9.0   |
   187 		 * | Pinterest    | pinterest.com                             | 5.9.0   |
   183 		 * | WolframCloud | wolframcloud.com                          | 5.9.0   |
   188 		 * | WolframCloud | wolframcloud.com                          | 5.9.0   |
       
   189 		 * | Pocket Casts | pocketcasts.com                           | 6.1.0   |
       
   190 		 * | Crowdsignal  | crowdsignal.net                           | 6.2.0   |
       
   191 		 * | Anghami      | anghami.com                               | 6.3.0   |
       
   192 		 * | Bluesky      | bsky.app                                  | 6.6.0   |
   184 		 *
   193 		 *
   185 		 * No longer supported providers:
   194 		 * No longer supported providers:
   186 		 *
   195 		 *
   187 		 * |   Provider   |        Flavor        |   Since   |  Removed  |
   196 		 * |   Provider   |        Flavor        |   Since   |  Removed  |
   188 		 * | ------------ | -------------------- | --------- | --------- |
   197 		 * | ------------ | -------------------- | --------- | --------- |
   202 		 * | Instagram TV | instagram.com        | 5.1.0     | 5.5.2     |
   211 		 * | Instagram TV | instagram.com        | 5.1.0     | 5.5.2     |
   203 		 * | Instagram TV | instagr.am           | 5.1.0     | 5.5.2     |
   212 		 * | Instagram TV | instagr.am           | 5.1.0     | 5.5.2     |
   204 		 * | Facebook     | facebook.com         | 4.7.0     | 5.5.2     |
   213 		 * | Facebook     | facebook.com         | 4.7.0     | 5.5.2     |
   205 		 * | Meetup.com   | meetup.com           | 3.9.0     | 6.0.1     |
   214 		 * | Meetup.com   | meetup.com           | 3.9.0     | 6.0.1     |
   206 		 * | Meetup.com   | meetu.ps             | 3.9.0     | 6.0.1     |
   215 		 * | Meetup.com   | meetu.ps             | 3.9.0     | 6.0.1     |
       
   216 		 * | SlideShare   | slideshare.net       | 3.5.0     | 6.6.0     |
   207 		 *
   217 		 *
   208 		 * @see wp_oembed_add_provider()
   218 		 * @see wp_oembed_add_provider()
   209 		 *
   219 		 *
   210 		 * @since 2.9.0
   220 		 * @since 2.9.0
   211 		 *
   221 		 *
   228 	 */
   238 	 */
   229 	public function __call( $name, $arguments ) {
   239 	public function __call( $name, $arguments ) {
   230 		if ( in_array( $name, $this->compat_methods, true ) ) {
   240 		if ( in_array( $name, $this->compat_methods, true ) ) {
   231 			return $this->$name( ...$arguments );
   241 			return $this->$name( ...$arguments );
   232 		}
   242 		}
       
   243 
   233 		return false;
   244 		return false;
   234 	}
   245 	}
   235 
   246 
   236 	/**
   247 	/**
   237 	 * Takes a URL and returns the corresponding oEmbed provider's URL, if there is one.
   248 	 * Takes a URL and returns the corresponding oEmbed provider's URL, if there is one.
   506 			return false;
   517 			return false;
   507 		}
   518 		}
   508 	}
   519 	}
   509 
   520 
   510 	/**
   521 	/**
   511 	 * Connects to a oEmbed provider and returns the result.
   522 	 * Connects to an oEmbed provider and returns the result.
   512 	 *
   523 	 *
   513 	 * @since 2.9.0
   524 	 * @since 2.9.0
   514 	 *
   525 	 *
   515 	 * @param string       $provider The URL to the oEmbed provider.
   526 	 * @param string       $provider The URL to the oEmbed provider.
   516 	 * @param string       $url      The URL to the content that is desired to be embedded.
   527 	 * @param string       $url      The URL to the content that is desired to be embedded.
   542 		foreach ( array( 'json', 'xml' ) as $format ) {
   553 		foreach ( array( 'json', 'xml' ) as $format ) {
   543 			$result = $this->_fetch_with_format( $provider, $format );
   554 			$result = $this->_fetch_with_format( $provider, $format );
   544 			if ( is_wp_error( $result ) && 'not-implemented' === $result->get_error_code() ) {
   555 			if ( is_wp_error( $result ) && 'not-implemented' === $result->get_error_code() ) {
   545 				continue;
   556 				continue;
   546 			}
   557 			}
       
   558 
   547 			return ( $result && ! is_wp_error( $result ) ) ? $result : false;
   559 			return ( $result && ! is_wp_error( $result ) ) ? $result : false;
   548 		}
   560 		}
       
   561 
   549 		return false;
   562 		return false;
   550 	}
   563 	}
   551 
   564 
   552 	/**
   565 	/**
   553 	 * Fetches result from an oEmbed provider for a specific format and complete provider URL
   566 	 * Fetches result from an oEmbed provider for a specific format and complete provider URL
   563 
   576 
   564 		/** This filter is documented in wp-includes/class-wp-oembed.php */
   577 		/** This filter is documented in wp-includes/class-wp-oembed.php */
   565 		$args = apply_filters( 'oembed_remote_get_args', array(), $provider_url_with_args );
   578 		$args = apply_filters( 'oembed_remote_get_args', array(), $provider_url_with_args );
   566 
   579 
   567 		$response = wp_safe_remote_get( $provider_url_with_args, $args );
   580 		$response = wp_safe_remote_get( $provider_url_with_args, $args );
   568 		if ( 501 == wp_remote_retrieve_response_code( $response ) ) {
   581 
       
   582 		if ( 501 === wp_remote_retrieve_response_code( $response ) ) {
   569 			return new WP_Error( 'not-implemented' );
   583 			return new WP_Error( 'not-implemented' );
   570 		}
   584 		}
       
   585 
   571 		$body = wp_remote_retrieve_body( $response );
   586 		$body = wp_remote_retrieve_body( $response );
   572 		if ( ! $body ) {
   587 		if ( ! $body ) {
   573 			return false;
   588 			return false;
   574 		}
   589 		}
       
   590 
   575 		$parse_method = "_parse_$format";
   591 		$parse_method = "_parse_$format";
       
   592 
   576 		return $this->$parse_method( $body );
   593 		return $this->$parse_method( $body );
   577 	}
   594 	}
   578 
   595 
   579 	/**
   596 	/**
   580 	 * Parses a json response body.
   597 	 * Parses a json response body.
   584 	 * @param string $response_body
   601 	 * @param string $response_body
   585 	 * @return object|false
   602 	 * @return object|false
   586 	 */
   603 	 */
   587 	private function _parse_json( $response_body ) {
   604 	private function _parse_json( $response_body ) {
   588 		$data = json_decode( trim( $response_body ) );
   605 		$data = json_decode( trim( $response_body ) );
       
   606 
   589 		return ( $data && is_object( $data ) ) ? $data : false;
   607 		return ( $data && is_object( $data ) ) ? $data : false;
   590 	}
   608 	}
   591 
   609 
   592 	/**
   610 	/**
   593 	 * Parses an XML response body.
   611 	 * Parses an XML response body.
   601 		if ( ! function_exists( 'libxml_disable_entity_loader' ) ) {
   619 		if ( ! function_exists( 'libxml_disable_entity_loader' ) ) {
   602 			return false;
   620 			return false;
   603 		}
   621 		}
   604 
   622 
   605 		if ( PHP_VERSION_ID < 80000 ) {
   623 		if ( PHP_VERSION_ID < 80000 ) {
   606 			// This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading
   624 			/*
   607 			// is disabled by default, so this function is no longer needed to protect against XXE attacks.
   625 			 * This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading
   608 			// phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.libxml_disable_entity_loaderDeprecated
   626 			 * is disabled by default, so this function is no longer needed to protect against XXE attacks.
       
   627 			 */
   609 			$loader = libxml_disable_entity_loader( true );
   628 			$loader = libxml_disable_entity_loader( true );
   610 		}
   629 		}
   611 
   630 
   612 		$errors = libxml_use_internal_errors( true );
   631 		$errors = libxml_use_internal_errors( true );
   613 
   632 
   634 	private function _parse_xml_body( $response_body ) {
   653 	private function _parse_xml_body( $response_body ) {
   635 		if ( ! function_exists( 'simplexml_import_dom' ) || ! class_exists( 'DOMDocument', false ) ) {
   654 		if ( ! function_exists( 'simplexml_import_dom' ) || ! class_exists( 'DOMDocument', false ) ) {
   636 			return false;
   655 			return false;
   637 		}
   656 		}
   638 
   657 
   639 		$dom     = new DOMDocument;
   658 		$dom     = new DOMDocument();
   640 		$success = $dom->loadXML( $response_body );
   659 		$success = $dom->loadXML( $response_body );
   641 		if ( ! $success ) {
   660 		if ( ! $success ) {
   642 			return false;
   661 			return false;
   643 		}
   662 		}
   644 
   663 
   655 		$xml = simplexml_import_dom( $dom );
   674 		$xml = simplexml_import_dom( $dom );
   656 		if ( ! $xml ) {
   675 		if ( ! $xml ) {
   657 			return false;
   676 			return false;
   658 		}
   677 		}
   659 
   678 
   660 		$return = new stdClass;
   679 		$return = new stdClass();
   661 		foreach ( $xml as $key => $value ) {
   680 		foreach ( $xml as $key => $value ) {
   662 			$return->$key = (string) $value;
   681 			$return->$key = (string) $value;
   663 		}
   682 		}
   664 
   683 
   665 		return $return;
   684 		return $return;
   735 	 * @param object $data Data object from WP_oEmbed::data2html()
   754 	 * @param object $data Data object from WP_oEmbed::data2html()
   736 	 * @param string $url The original URL passed to oEmbed.
   755 	 * @param string $url The original URL passed to oEmbed.
   737 	 * @return string Possibly modified $html
   756 	 * @return string Possibly modified $html
   738 	 */
   757 	 */
   739 	public function _strip_newlines( $html, $data, $url ) {
   758 	public function _strip_newlines( $html, $data, $url ) {
   740 		if ( false === strpos( $html, "\n" ) ) {
   759 		if ( ! str_contains( $html, "\n" ) ) {
   741 			return $html;
   760 			return $html;
   742 		}
   761 		}
   743 
   762 
   744 		$count     = 1;
   763 		$count     = 1;
   745 		$found     = array();
   764 		$found     = array();