/** * WP_oEmbed_Controller class, used to provide an oEmbed endpoint. * * @package WordPress * @subpackage Embeds * @since 4.4.0 */ /** * oEmbed API endpoint controller. * * Registers the REST API route and delivers the response data. * The output format (XML or JSON) is handled by the REST API. * * @since 4.4.0 */ #[AllowDynamicProperties] final class WP_oEmbed_Controller { /** * Register the oEmbed REST API route. * * @since 4.4.0 */ public function register_routes() { /** * Filters the maxwidth oEmbed parameter. * * @since 4.4.0 * * @param int $maxwidth Maximum allowed width. Default 600. */ $maxwidth = apply_filters( 'oembed_default_width', 600 ); register_rest_route( 'oembed/1.0', '/embed', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => '__return_true', 'args' => array( 'url' => array( 'description' => __( 'The URL of the resource for which to fetch oEmbed data.' ), 'required' => true, 'type' => 'string', 'format' => 'uri', ), 'format' => array( 'default' => 'json', 'sanitize_callback' => 'wp_oembed_ensure_format', ), 'maxwidth' => array( 'default' => $maxwidth, 'sanitize_callback' => 'absint', ), ), ), ) ); register_rest_route( 'oembed/1.0', '/proxy', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_proxy_item' ), 'permission_callback' => array( $this, 'get_proxy_item_permissions_check' ), 'args' => array( 'url' => array( 'description' => __( 'The URL of the resource for which to fetch oEmbed data.' ), 'required' => true, 'type' => 'string', 'format' => 'uri', ), 'format' => array( 'description' => __( 'The oEmbed format to use.' ), 'type' => 'string', 'default' => 'json', 'enum' => array( 'json', 'xml', ), ), 'maxwidth' => array( 'description' => __( 'The maximum width of the embed frame in pixels.' ), 'type' => 'integer', 'default' => $maxwidth, 'sanitize_callback' => 'absint', ), 'maxheight' => array( 'description' => __( 'The maximum height of the embed frame in pixels.' ), 'type' => 'integer', 'sanitize_callback' => 'absint', ), 'discover' => array( 'description' => __( 'Whether to perform an oEmbed discovery request for unsanctioned providers.' ), 'type' => 'boolean', 'default' => true, ), ), ), ) ); } /** * Callback for the embed API endpoint. * * Returns the JSON object for the post. * * @since 4.4.0 * * @param WP_REST_Request $request Full data about the request. * @return array|WP_Error oEmbed response data or WP_Error on failure. */ public function get_item( $request ) { $post_id = url_to_postid( $request['url'] ); /** * Filters the determined post ID. * * @since 4.4.0 * * @param int $post_id The post ID. * @param string $url The requested URL. */ $post_id = apply_filters( 'oembed_request_post_id', $post_id, $request['url'] ); $data = get_oembed_response_data( $post_id, $request['maxwidth'] ); if ( ! $data ) { return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) ); } return $data; } /** * Checks if current user can make a proxy oEmbed request. * * @since 4.8.0 * * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_proxy_item_permissions_check() { if ( ! current_user_can( 'edit_posts' ) ) { return new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to make proxied oEmbed requests.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Callback for the proxy API endpoint. * * Returns the JSON object for the proxied item. * * @since 4.8.0 * * @see WP_oEmbed::get_html() * @global WP_Embed $wp_embed WordPress Embed object. * @global WP_Scripts $wp_scripts * * @param WP_REST_Request $request Full data about the request. * @return object|WP_Error oEmbed response data or WP_Error on failure. */ public function get_proxy_item( $request ) { global $wp_embed, $wp_scripts; $args = $request->get_params(); // Serve oEmbed data from cache if set. unset( $args['_wpnonce'] ); $cache_key = 'oembed_' . md5( serialize( $args ) ); $data = get_transient( $cache_key ); if ( ! empty( $data ) ) { return $data; } $url = $request['url']; unset( $args['url'] ); // Copy maxwidth/maxheight to width/height since WP_oEmbed::fetch() uses these arg names. if ( isset( $args['maxwidth'] ) ) { $args['width'] = $args['maxwidth']; } if ( isset( $args['maxheight'] ) ) { $args['height'] = $args['maxheight']; } // Short-circuit process for URLs belonging to the current site. $data = get_oembed_response_data_for_url( $url, $args ); if ( $data ) { return $data; } $data = _wp_oembed_get_object()->get_data( $url, $args ); if ( false === $data ) { // Try using a classic embed, instead. /* @var WP_Embed $wp_embed */ $html = $wp_embed->get_embed_handler_html( $args, $url ); if ( $html ) { // Check if any scripts were enqueued by the shortcode, and include them in the response. $enqueued_scripts = array(); foreach ( $wp_scripts->queue as $script ) { $enqueued_scripts[] = $wp_scripts->registered[ $script ]->src; } return (object) array( 'provider_name' => __( 'Embed Handler' ), 'html' => $html, 'scripts' => $enqueued_scripts, ); } return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) ); } /** This filter is documented in wp-includes/class-wp-oembed.php */ $data->html = apply_filters( 'oembed_result', _wp_oembed_get_object()->data2html( (object) $data, $url ), $url, $args ); /** * Filters the oEmbed TTL value (time to live). * * Similar to the {@see 'oembed_ttl'} filter, but for the REST API * oEmbed proxy endpoint. * * @since 4.8.0 * * @param int $time Time to live (in seconds). * @param string $url The attempted embed URL. * @param array $args An array of embed request arguments. */ $ttl = apply_filters( 'rest_oembed_ttl', DAY_IN_SECONDS, $url, $args ); set_transient( $cache_key, $data, $ttl ); return $data; } } https://validator.w3.org/feed/docs/rss2.html No deposit Added bonus casino Chipspalace no deposit bonus Rules Updated 2026! 50 Totally free Diceland casino signup bonus Revolves No-deposit 2026 Best Also provides Ninja Magic Big Kahuna real money Position RTP, Bonus and British Casinos The Fruity Burst online slot newest On the web Cellular Casinos Southern area Africa 2026: Greatest The new Sites Better 34 Australian casino Zeus Slots Free Play Casinos on the internet for real Profit 2026 Gamble 19,610+ Online Harbors Zero Download Queen Isabella slot or Registration! 5 Better Websites having The newest Web based casinos Analysis 2025: Specialist Investigation and Safe casino no deposit YoyoSpins Gambling Finest Neteller On-line casino Websites Ghost Slider big win and Apps in the August 2026 Secret Museum Position Comment 2026, Billionairespin live login Free Play 95 58percent RTP Mr Cashback Position Video game Demo Gamble and 100 percent iWinFortune bonus code free Revolves Better Crazywinners casino free spins On line Pokies around australia to try out for real Currency 2025 Enjoy Cellular Pokies and Software in australia 1XSlot free spins no deposit Canada 2025 2026 Miss Kitty casino Elvis the King Rtp Position Demo: The new Return Processor chip Lottery Told me Merry sizzling hot play Xmas Slot Remark 2026 100 percent free Gamble Demo Mega Beach Life Rtp $1 deposit Moolah Position Opinion 2026 Free to Play Demo Enjoy and Winnings to your Certified casino Castle $100 free spins Webpages Enjoy Major Millions Position at hyperlink no cost No deposit Incentives At the United states casino Bovada mobile Online casinos Zodiac critical link Casino! Better Instant Withdrawal Crypto Gambling enterprises to possess BeOnBet casino bonus 2026 Lord FairSpin casino login of one’s Ocean Slot Comment Have fun with the Video game for free Wade Wild regarding the Pets and Keks slot more which have Kitty Glitter Greatest Lucky Mermaid slot games Web based casinos one Deal with Apple Shell out Play for A real income inside the 2025 Super Hook up Pokie On the Attack of the Zombies play slot internet Real cash Australia Leprechaun Goes Egypt Position BetPrimeiro app download Free Enjoy Online casino Harbors Zero Download King Of one’s Nile Slot Opinion 2026 Free Ladbrokes 25 free spins no deposit real money Play Demo Finest Totally free casino Next no deposit bonus Revolves No deposit Incentive Also provides inside Web based casinos 2026 120 Totally free Spins Xon Bet bonus No-deposit Necessary Win Real money Metal Casino World online Wikipedia The best Casinos Having fifty No-deposit Free Revolves good site 2026 Immortal Love Free Position to play On the web and No online casino with Betvictor 200 free spins Download Microgaming Thunderstruck Slot Remark and Totally free Trial FairSpin login 96 10percent RTP Best Superstar Nip bonus casino Bovada Glides Hot Meaning, Definition casino Raw casino and Synonyms Win Sakura Fortune Rtp slot free spins a great 20 Walmart or Amazon Provide Credit or PayPal Dollars! Happiest Xmas Tree Slot Remark: RTP and Queen Isabella online slot Have 120 100 percent free Spins free Big Dollar 40 spins no deposit 2023 No deposit Needed Earn Real cash Gonzo’s Trip Trial casino Ghostbusters Rtp Enjoy and Local casino Added bonus ZA 2026 Watch: Earliest live casino Rajahbet mobile results of Fantastic from KPop Devil Seekers Authoritative Website Demo and Real money slot Reel Em in IGT Gold-rush Ports Gambling enterprise: Earn up Jokers Cap $1 deposit to 500 spins Finest 100 percent Lemur Does Vegas Easter Edition slot free spins free Revolves Gambling enterprises 2026 An informed 50 Free Revolves No deposit Bonus play Firemen real money inside the 2026 Better Totally free Revolves casino Seasons Rtp Casinos 2026 Enjoy Funky Fruits Farm Position: Review, Mr Cash Back bonus Gambling enterprises, Extra and Video Blox Fruits Newest casino Bingofest 20 free spins Stock August 2026 Live Reputation Fresh fruit Appreciate Software on Big Bear Rtp casino google Gamble Dragon Dance Demo Play Totally free 15 free bingo no deposit free bingo no deposit Ports from the Higher com No deposit Free Spins to possess Trendy Fruits Euroslots casino bonus withdrawal rules because of the Playtech Instantaneous Cleopatra Plus Rtp slot machine and On the web