Make WordPress Core

Ticket #34207: 34207.5.diff

File 34207.5.diff, 33.9 KB (added by swissspidy, 9 years ago)
  • src/wp-includes/class-wp-oembed-controller.php

    diff --git src/wp-includes/class-wp-oembed-controller.php src/wp-includes/class-wp-oembed-controller.php
    index a613d06..0db5340 100644
     
    1010/**
    1111 * oEmbed API endpoint controller.
    1212 *
    13  * Parses the oEmbed API requests and delivers
    14  * XML and JSON responses.
     13 * Registers the API route and delivers the response data.
     14 * The output format (XML or JSON) is handled by the REST API.
    1515 *
    1616 * @since 4.4.0
    1717 */
    1818final class WP_oEmbed_Controller {
    1919        /**
    20          * Hook into the query parsing to detect oEmbed requests.
    21          *
    22          * If an oEmbed request is made, trigger the output.
     20         * Register the oEmbed REST API route.
    2321         *
    2422         * @since 4.4.0
    25          *
    26          * @param WP_Query $wp_query The WP_Query instance (passed by reference).
    2723         */
    28         public function parse_query( $wp_query ) {
    29                 if ( false === $wp_query->get( 'oembed', false ) ) {
    30                         return;
    31                 }
    32 
    33                 if ( false === $wp_query->get( 'url', false ) ) {
    34                         status_header( 400 );
    35                         return get_status_header_desc( 400 );
    36                         exit;
    37                 }
    38 
    39                 $url = esc_url_raw( get_query_var( 'url' ) );
    40 
    41                 $format = wp_oembed_ensure_format( get_query_var( 'format' ) );
    42 
     24        public function register_routes() {
    4325                /**
    4426                 * Filter the maxwidth oEmbed parameter.
    4527                 *
    final class WP_oEmbed_Controller { 
    4830                 * @param int $maxwidth Maximum allowed width. Default 600.
    4931                 */
    5032                $maxwidth = apply_filters( 'oembed_default_width', 600 );
    51                 $maxwidth = absint( get_query_var( 'maxwidth', $maxwidth ) );
    52 
    53                 $callback = get_query_var( '_jsonp', false );
    5433
    55                 $request = array(
    56                         'url'      => $url,
    57                         'format'   => $format,
    58                         'maxwidth' => $maxwidth,
    59                         'callback' => $callback,
    60                 );
    61 
    62                 echo $this->dispatch( $request );
    63                 exit;
     34                register_rest_route( 'oembed/1.0/', '/embed', array(
     35                        array(
     36                                'methods'  => WP_REST_Server::READABLE,
     37                                'callback' => array( $this, 'get_item' ),
     38                                'args'     => array(
     39                                        'url'      => array(
     40                                                'required'          => true,
     41                                                'sanitize_callback' => 'esc_url_raw',
     42                                        ),
     43                                        'format'   => array(
     44                                                'default'           => 'json',
     45                                                'sanitize_callback' => 'wp_oembed_ensure_format',
     46                                        ),
     47                                        'maxwidth' => array(
     48                                                'default'           => $maxwidth,
     49                                                'sanitize_callback' => 'absint',
     50                                        ),
     51                                ),
     52                        ),
     53                ) );
    6454        }
    6555
    6656        /**
    67          * Handle the whole request and print the response.
     57         * Callback for the API endpoint.
     58         *
     59         * Returns the JSON object for the post.
    6860         *
    6961         * @since 4.4.0
    7062         *
    71          * @param array $request The request arguments.
    72          * @return string The oEmbed API response.
     63         * @param WP_REST_Request $request Full data about the request.
     64         * @return WP_Error|array oEmbed response data or WP_Error on failure.
    7365         */
    74         public function dispatch( $request ) {
     66        public function get_item( $request ) {
    7567                $post_id = url_to_postid( $request['url'] );
    7668
    7769                /**
    final class WP_oEmbed_Controller { 
    8678
    8779                $data = get_oembed_response_data( $post_id, $request['maxwidth'] );
    8880
    89                 if ( false === $data ) {
    90                         status_header( 404 );
    91                         return get_status_header_desc( 404 );
    92                 }
    93 
    94                 if ( 'json' === $request['format'] ) {
    95                         return $this->json_response( $data, $request );
    96                 }
    97 
    98                 return $this->xml_response( $data );
    99         }
    100 
    101         /**
    102          * Print the oEmbed JSON response.
    103          *
    104          * @since 4.4.0
    105          *
    106          * @param array $data     The oEmbed response data.
    107          * @param array $request  The request arguments.
    108          * @return string The JSON response data.
    109          */
    110         public function json_response( $data, $request ) {
    111                 if ( ! is_string( $request['callback'] ) || preg_match( '/[^\w\.]/', $request['callback'] ) ) {
    112                         $request['callback'] = false;
    113                 }
    114 
    115                 $result = wp_json_encode( $data );
    116 
    117                 // Bail if the result couldn't be JSON encoded.
    118                 if ( ! $result || ! is_array( $data ) || empty( $data ) ) {
    119                         status_header( 501 );
    120                         return get_status_header_desc( 501 );
    121                 }
    122 
    123                 if ( ! headers_sent() ) {
    124                         $content_type = $request['callback'] ? 'application/javascript' : 'application/json';
    125                         header( 'Content-Type: ' . $content_type . '; charset=' . get_option( 'blog_charset' ) );
    126                         header( 'X-Content-Type-Options: nosniff' );
    127                 }
    128 
    129                 if ( $request['callback'] ) {
    130                         return '/**/' . $request['callback'] . '(' . $result . ')';
    131                 }
    132 
    133                 return $result;
    134         }
    135 
    136         /**
    137          * Print the oEmbed XML response.
    138          *
    139          * @since 4.4.0
    140          *
    141          * @param array $data The oEmbed response data.
    142          * @return string The XML response data.
    143          */
    144         public function xml_response( $data ) {
    145                 if ( ! class_exists( 'SimpleXMLElement' ) ) {
    146                         status_header( 501 );
    147                         return get_status_header_desc( 501 );
    148                 }
    149 
    150                 $result = _oembed_create_xml( $data );
    151 
    152                 // Bail if there's no XML.
    153                 if ( ! $result ) {
    154                         status_header( 501 );
    155                         return get_status_header_desc( 501 );
    156                 }
    157 
    158                 if ( ! headers_sent() ) {
    159                         header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ) );
     81                if ( ! $data ) {
     82                        return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) );
    16083                }
    16184
    162                 return $result;
     85                return $data;
    16386        }
    16487}
  • src/wp-includes/class-wp.php

    diff --git src/wp-includes/class-wp.php src/wp-includes/class-wp.php
    index 0f86251..555167b 100644
    class WP { 
    1515         * @access public
    1616         * @var array
    1717         */
    18         public $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term', 'cpage', 'post_type', 'title', 'embed', 'oembed', 'format', 'url', '_jsonp', 'maxwidth' );
     18        public $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term', 'cpage', 'post_type', 'title', 'embed' );
    1919
    2020        /**
    2121         * Private query variables.
  • src/wp-includes/default-filters.php

    diff --git src/wp-includes/default-filters.php src/wp-includes/default-filters.php
    index 0bda80e..70a9791 100644
    add_filter( 'image_send_to_editor', 'image_add_caption', 20, 8 ); 
    439439add_filter( 'media_send_to_editor', 'image_media_send_to_editor', 10, 3 );
    440440
    441441// Embeds
    442 add_action( 'parse_query',          'wp_oembed_parse_query'                );
    443 
    444 add_action( 'wp_head',              'wp_oembed_add_discovery_links'        );
    445 add_action( 'wp_head',              'wp_oembed_add_host_js'                );
    446 
    447 add_action( 'embed_head',           'print_emoji_detection_script'         );
    448 add_action( 'embed_head',           'print_emoji_styles'                   );
    449 add_action( 'embed_head',           'print_embed_styles'                   );
    450 add_action( 'embed_head',           'wp_print_head_scripts',         20    );
    451 add_action( 'embed_head',           'wp_print_styles',               20    );
    452 add_action( 'embed_head',           'wp_no_robots'                         );
    453 add_action( 'embed_head',           'rel_canonical'                        );
    454 add_action( 'embed_head',           'locale_stylesheet'                    );
    455 
    456 add_action( 'embed_footer',         'print_embed_scripts'                  );
    457 add_action( 'embed_footer',         'wp_print_footer_scripts',       20    );
    458 
    459 add_filter( 'excerpt_more',         'wp_embed_excerpt_more',         20    );
    460 add_filter( 'the_excerpt_embed',    'wptexturize'                          );
    461 add_filter( 'the_excerpt_embed',    'convert_chars'                        );
    462 add_filter( 'the_excerpt_embed',    'wpautop'                              );
    463 add_filter( 'the_excerpt_embed',    'shortcode_unautop'                    );
    464 add_filter( 'the_excerpt_embed',    'wp_embed_excerpt_attachment'          );
    465 
    466 add_filter( 'oembed_dataparse',     'wp_filter_oembed_result',       10, 3 );
    467 add_filter( 'oembed_response_data', 'get_oembed_response_data_rich', 10, 4 );
     442add_action( 'rest_api_init',          'wp_oembed_register_route'              );
     443add_filter( 'rest_pre_serve_request', '_oembed_rest_pre_serve_request', 10, 4 );
     444
     445add_action( 'wp_head',                'wp_oembed_add_discovery_links'         );
     446add_action( 'wp_head',                'wp_oembed_add_host_js'                 );
     447
     448add_action( 'embed_head',             'print_emoji_detection_script'          );
     449add_action( 'embed_head',             'print_emoji_styles'                    );
     450add_action( 'embed_head',             'print_embed_styles'                    );
     451add_action( 'embed_head',             'wp_print_head_scripts',          20    );
     452add_action( 'embed_head',             'wp_print_styles',                20    );
     453add_action( 'embed_head',             'wp_no_robots'                          );
     454add_action( 'embed_head',             'rel_canonical'                         );
     455add_action( 'embed_head',             'locale_stylesheet'                     );
     456
     457add_action( 'embed_footer',           'print_embed_scripts'                   );
     458add_action( 'embed_footer',           'wp_print_footer_scripts',        20    );
     459
     460add_filter( 'excerpt_more',           'wp_embed_excerpt_more',          20    );
     461add_filter( 'the_excerpt_embed',      'wptexturize'                           );
     462add_filter( 'the_excerpt_embed',      'convert_chars'                         );
     463add_filter( 'the_excerpt_embed',      'wpautop'                               );
     464add_filter( 'the_excerpt_embed',      'shortcode_unautop'                     );
     465add_filter( 'the_excerpt_embed',      'wp_embed_excerpt_attachment'           );
     466
     467add_filter( 'oembed_dataparse',       'wp_filter_oembed_result',        10, 3 );
     468add_filter( 'oembed_response_data',   'get_oembed_response_data_rich',  10, 4 );
    468469
    469470unset( $filter, $action );
  • src/wp-includes/embed-functions.php

    diff --git src/wp-includes/embed-functions.php src/wp-includes/embed-functions.php
    index 3fe4e1a..8a17f93 100644
    function wp_embed_handler_video( $matches, $attr, $url, $rawattr ) { 
    328328}
    329329
    330330/**
    331  * Parses an oEmbed API query.
     331 * Registers the oEmbed REST API route.
    332332 *
    333333 * @since 4.4.0
    334  *
    335  * @see WP_oEmbed_Controller::parse_query()
    336  *
    337  * @param WP_Query $wp_query The current WP_Query instance.
    338334 */
    339 function wp_oembed_parse_query( $wp_query ) {
     335function wp_oembed_register_route() {
    340336        $controller = new WP_oEmbed_Controller();
    341         $controller->parse_query( $wp_query );
     337        $controller->register_routes();
    342338}
    343339
    344340/**
    function get_post_embed_url( $post = null ) { 
    421417 * @return string The oEmbed endpoint URL.
    422418 */
    423419function get_oembed_endpoint_url( $permalink = '', $format = 'json' ) {
    424         $url = add_query_arg( array( 'oembed' => 'true' ), home_url( '/' ) );
     420        $url = rest_url( 'oembed/1.0/embed' );
    425421
    426422        if ( 'json' === $format ) {
    427423                $format = false;
    function get_oembed_response_data( $post = null, $width ) { 
    545541                'max' => 600
    546542        ) );
    547543
    548         if ( $width < $min_max_width['min'] ) {
    549                 $width = $min_max_width['min'];
    550         } elseif ( $width > $min_max_width['max'] ) {
    551                 $width = $min_max_width['max'];
    552         }
    553 
    554         $height = ceil( $width / 16 * 9 );
    555 
    556         if ( 200 > $height ) {
    557                 $height = 200;
    558         }
     544        $width  = min( max( $min_max_width['min'], $width ), $min_max_width['max'] );
     545        $height = max( ceil( $width / 16 * 9 ), 200 );
    559546
    560547        $data = array(
    561548                'version'       => '1.0',
    function wp_oembed_ensure_format( $format ) { 
    647634}
    648635
    649636/**
     637 * Hooks into the REST API output to print XML instead of JSON.
     638 *
     639 * This is only done for the oEmbed API endpoint,
     640 * which supports both formats.
     641 *
     642 * @access private
     643 * @since 4.4.0
     644 *
     645 * @param bool                      $served  Whether the request has already been served.
     646 * @param WP_HTTP_ResponseInterface $result  Result to send to the client. Usually a WP_REST_Response.
     647 * @param WP_REST_Request           $request Request used to generate the response.
     648 * @param WP_REST_Server            $server  Server instance.
     649 * @return true
     650 */
     651function _oembed_rest_pre_serve_request( $served, $result, $request, $server ) {
     652        $params = $request->get_params();
     653
     654        if ( '/oembed/1.0/embed' !== $request->get_route() || 'GET' !== $request->get_method() ) {
     655                return $served;
     656        }
     657
     658        if ( ! isset( $params['format'] ) || 'xml' !== $params['format'] ) {
     659                return $served;
     660        }
     661
     662        // Embed links inside the request.
     663        $data = $server->response_to_data( $result, false );
     664
     665        if ( 404 === $result->get_status() ) {
     666                $data = $data[0];
     667        }
     668
     669        if ( ! class_exists( 'SimpleXMLElement' ) ) {
     670                status_header( 501 );
     671                die( get_status_header_desc( 501 ) );
     672        }
     673
     674        $result = _oembed_create_xml( $data );
     675
     676        // Bail if there's no XML.
     677        if ( ! $result ) {
     678                status_header( 501 );
     679                return get_status_header_desc( 501 );
     680        }
     681
     682        if ( ! headers_sent() ) {
     683                $server->send_header( 'Content-Type', 'text/xml; charset=' . get_option( 'blog_charset' ) );
     684        }
     685
     686        echo $result;
     687
     688        return true;
     689}
     690
     691/**
    650692 * Creates an XML string from a given array.
    651693 *
    652694 * @since 4.4.0
  • tests/phpunit/tests/oembed/controller.php

    diff --git tests/phpunit/tests/oembed/controller.php tests/phpunit/tests/oembed/controller.php
    index 51c6302..9410e00 100644
     
    22
    33/**
    44 * @group oembed
     5 * @group restapi
    56 */
    67class Test_oEmbed_Controller extends WP_UnitTestCase {
     8        /**
     9         * @var WP_REST_Server
     10         */
     11        protected $server;
     12
     13        public function setUp() {
     14                parent::setUp();
     15
     16                /** @var WP_REST_Server $wp_rest_server */
     17                global $wp_rest_server;
     18                $this->server = $wp_rest_server = new Spy_REST_Server();
     19
     20                do_action( 'rest_api_init', $this->server );
     21        }
     22
     23        function test_wp_oembed_ensure_format() {
     24                $this->assertEquals( 'json', wp_oembed_ensure_format( 'json' ) );
     25                $this->assertEquals( 'xml', wp_oembed_ensure_format( 'xml' ) );
     26                $this->assertEquals( 'json', wp_oembed_ensure_format( 123 ) );
     27                $this->assertEquals( 'json', wp_oembed_ensure_format( 'random' ) );
     28                $this->assertEquals( 'json', wp_oembed_ensure_format( array() ) );
     29        }
     30
     31        function test_oembed_create_xml() {
     32                $actual = _oembed_create_xml( array(
     33                        'foo'  => 'bar',
     34                        'bar'  => 'baz',
     35                        'ping' => 'pong',
     36                ) );
     37
     38                $expected = '<oembed><foo>bar</foo><bar>baz</bar><ping>pong</ping></oembed>';
     39
     40                $this->assertStringEndsWith( $expected, trim( $actual ) );
     41
     42                $actual = _oembed_create_xml( array(
     43                        'foo'  => array(
     44                                'bar' => 'baz',
     45                        ),
     46                        'ping' => 'pong',
     47                ) );
     48
     49                $expected = '<oembed><foo><bar>baz</bar></foo><ping>pong</ping></oembed>';
     50
     51                $this->assertStringEndsWith( $expected, trim( $actual ) );
     52
     53                $actual = _oembed_create_xml( array(
     54                        'foo'   => array(
     55                                'bar' => array(
     56                                        'ping' => 'pong',
     57                                ),
     58                        ),
     59                        'hello' => 'world',
     60                ) );
     61
     62                $expected = '<oembed><foo><bar><ping>pong</ping></bar></foo><hello>world</hello></oembed>';
     63
     64                $this->assertStringEndsWith( $expected, trim( $actual ) );
     65
     66                $actual = _oembed_create_xml( array(
     67                        array(
     68                                'foo' => array(
     69                                        'bar',
     70                                ),
     71                        ),
     72                        'helloworld',
     73                ) );
     74
     75                $expected = '<oembed><oembed><foo><oembed>bar</oembed></foo></oembed><oembed>helloworld</oembed></oembed>';
     76
     77                $this->assertStringEndsWith( $expected, trim( $actual ) );
     78        }
     79
     80        public function test_route_availability() {
     81                // Check the route was registered correctly.
     82                $filtered_routes = $this->server->get_routes();
     83                $this->assertArrayHasKey( '/oembed/1.0/embed', $filtered_routes );
     84                $route = $filtered_routes['/oembed/1.0/embed'];
     85                $this->assertCount( 1, $route );
     86                $this->assertArrayHasKey( 'callback', $route[0] );
     87                $this->assertArrayHasKey( 'methods', $route[0] );
     88                $this->assertArrayHasKey( 'args', $route[0] );
     89        }
     90
     91        function test_request_with_wrong_method() {
     92                $request = new WP_REST_Request( 'POST', '/oembed/1.0/embed' );
     93
     94                $response = $this->server->dispatch( $request );
     95                $data     = $response->get_data();
     96
     97                $this->assertEquals( 'rest_no_route', $data[0]['code'] );
     98        }
     99
     100        function test_request_without_url_param() {
     101                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     102
     103                $response = $this->server->dispatch( $request );
     104                $data     = $response->get_data();
     105
     106                $this->assertEquals( 'rest_missing_callback_param', $data[0]['code'] );
     107                $this->assertEquals( 'url', $data[0]['data']['params'][0] );
     108        }
     109
    7110        function test_request_with_bad_url() {
    8                 $request = array(
    9                         'url'      => '',
    10                         'format'   => 'json',
    11                         'maxwidth' => 600,
    12                 );
     111                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     112                $request->set_param( 'url', 'http://google.com/' );
     113
     114                $response = $this->server->dispatch( $request );
     115                $data     = $response->get_data();
    13116
    14                 $legacy_controller = new WP_oEmbed_Controller();
     117                $this->assertEquals( 'oembed_invalid_url', $data[0]['code'] );
     118        }
     119
     120        function test_request_invalid_format() {
     121                $post_id = $this->factory()->post->create();
     122
     123                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     124                $request->set_param( 'url', get_permalink( $post_id ) );
     125                $request->set_param( 'format', 'random' );
    15126
    16                 $this->assertEquals( get_status_header_desc( 404 ), $legacy_controller->dispatch( $request ) );
     127                $response = $this->server->dispatch( $request );
     128                $data     = $response->get_data();
     129
     130                $this->assertInternalType( 'array', $data );
     131                $this->assertNotEmpty( $data );
    17132        }
    18133
    19134        function test_request_json() {
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    25140                        'post_title'  => 'Hello World',
    26141                ) );
    27142
    28                 // WP_Query arguments.
    29                 $request = array(
    30                         'url'      => get_permalink( $post->ID ),
    31                         'format'   => 'json',
    32                         'maxwidth' => 400,
    33                         'callback' => '',
    34                         'oembed'   => true,
    35                 );
     143                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     144                $request->set_param( 'url', get_permalink( $post->ID ) );
     145                $request->set_param( 'maxwidth', 400 );
    36146
    37                 $legacy_controller = new WP_oEmbed_Controller();
     147                $response = $this->server->dispatch( $request );
     148                $data     = $response->get_data();
    38149
    39                 $data = json_decode( $legacy_controller->dispatch( $request ), true );
    40 
    41                 $this->assertTrue( is_array( $data ) );
     150                $this->assertInternalType( 'array', $data );
     151                $this->assertNotEmpty( $data );
    42152
    43153                $this->assertArrayHasKey( 'version', $data );
    44154                $this->assertArrayHasKey( 'provider_name', $data );
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    59169                $this->assertTrue( $data['width'] <= $request['maxwidth'] );
    60170        }
    61171
    62         function test_request_jsonp() {
    63                 $user = self::factory()->user->create_and_get( array(
    64                         'display_name' => 'John Doe',
    65                 ) );
    66                 $post = self::factory()->post->create_and_get( array(
    67                         'post_author' => $user->ID,
    68                         'post_title'  => 'Hello World',
    69                 ) );
    70 
    71                 $request = array(
    72                         'url'      => get_permalink( $post->ID ),
    73                         'format'   => 'json',
    74                         'maxwidth' => 600,
    75                         'callback' => 'mycallback',
    76                 );
    77 
    78                 $legacy_controller = new WP_oEmbed_Controller();
    79 
    80                 $data = $legacy_controller->dispatch( $request );
    81 
    82                 $this->assertEquals( 0, strpos( $data, '/**/mycallback(' ) );
    83         }
    84 
    85         function test_request_jsonp_invalid_callback() {
    86                 $user = self::factory()->user->create_and_get( array(
    87                         'display_name' => 'John Doe',
    88                 ) );
    89                 $post = self::factory()->post->create_and_get( array(
    90                         'post_author' => $user->ID,
    91                         'post_title'  => 'Hello World',
    92                 ) );
    93 
    94                 $request = array(
    95                         'url'      => get_permalink( $post->ID ),
    96                         'format'   => 'json',
    97                         'maxwidth' => 600,
    98                         'callback' => array( 'foo', 'bar' ),
    99                 );
    100 
    101                 $legacy_controller = new WP_oEmbed_Controller();
    102 
    103                 $data = $legacy_controller->dispatch( $request );
    104 
    105                 $this->assertFalse( strpos( $data, '/**/' ) );
    106         }
    107 
    108         function test_request_json_invalid_data() {
    109                 $request = array(
    110                         'callback' => '',
    111                 );
    112 
    113                 $legacy_controller = new WP_oEmbed_Controller();
    114 
    115                 $this->assertEquals( get_status_header_desc( 501 ), $legacy_controller->json_response( null, $request ) );
    116                 $this->assertEquals( get_status_header_desc( 501 ), $legacy_controller->json_response( 123, $request ) );
    117                 $this->assertEquals( get_status_header_desc( 501 ), $legacy_controller->json_response( array(), $request ) );
    118         }
    119 
    120172        function test_request_xml() {
    121173                $user = self::factory()->user->create_and_get( array(
    122174                        'display_name' => 'John Doe',
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    126178                        'post_title'  => 'Hello World',
    127179                ) );
    128180
    129                 $request = array(
    130                         'url'     => get_permalink( $post->ID ),
    131                         'format'   => 'xml',
    132                         'maxwidth' => 400,
    133                         'callback' => '',
    134                 );
    135 
    136                 $legacy_controller = new WP_oEmbed_Controller();
     181                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     182                $request->set_param( 'url', get_permalink( $post->ID ) );
     183                $request->set_param( 'format', 'xml' );
     184                $request->set_param( 'maxwidth', 400 );
    137185
    138                 $data = $legacy_controller->dispatch( $request );
     186                $response = $this->server->dispatch( $request );
     187                $data     = $response->get_data();
    139188
    140                 $data = simplexml_load_string( $data );
    141                 $this->assertInstanceOf( 'SimpleXMLElement', $data );
    142 
    143                 $data = (array) $data;
     189                $this->assertInternalType( 'array', $data );
     190                $this->assertNotEmpty( $data );
    144191
    145192                $this->assertArrayHasKey( 'version', $data );
    146193                $this->assertArrayHasKey( 'provider_name', $data );
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    161208                $this->assertTrue( $data['width'] <= $request['maxwidth'] );
    162209        }
    163210
    164         function test_request_xml_invalid_data() {
    165                 $legacy_controller = new WP_oEmbed_Controller();
    166 
    167                 $this->assertEquals( get_status_header_desc( 501 ),  $legacy_controller->xml_response( null ) );
    168                 $this->assertEquals( get_status_header_desc( 501 ),  $legacy_controller->xml_response( 123 ) );
    169                 $this->assertEquals( get_status_header_desc( 501 ),  $legacy_controller->xml_response( array() ) );
    170         }
    171 
    172211        /**
    173212         * @group multisite
    174213         */
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    178217                }
    179218
    180219                $child = self::factory()->blog->create();
    181 
    182220                switch_to_blog( $child );
    183221
    184222                $post = self::factory()->post->create_and_get( array(
    185223                        'post_title' => 'Hello Child Blog',
    186224                ) );
    187225
    188                 $request = array(
    189                         'url'      => get_permalink( $post->ID ),
    190                         'format'   => 'json',
    191                         'maxwidth' => 600,
    192                         'callback' => '',
    193                 );
    194 
    195                 $legacy_controller = new WP_oEmbed_Controller();
     226                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     227                $request->set_param( 'url', get_permalink( $post->ID ) );
     228                $request->set_param( 'maxwidth', 400 );
    196229
    197                 $data = json_decode( $legacy_controller->dispatch( $request ), true );
     230                $response = $this->server->dispatch( $request );
     231                $data     = $response->get_data();
    198232
    199233                $this->assertInternalType( 'array', $data );
    200234                $this->assertNotEmpty( $data );
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    202236                restore_current_blog();
    203237        }
    204238
    205         function test_get_oembed_endpoint_url() {
    206                 $this->assertEquals( home_url() . '/?oembed=true', get_oembed_endpoint_url() );
    207                 $this->assertEquals( home_url() . '/?oembed=true', get_oembed_endpoint_url( '', 'json' ) );
    208                 $this->assertEquals( home_url() . '/?oembed=true', get_oembed_endpoint_url( '', 'xml' ) );
     239        function test_rest_pre_serve_request() {
     240                $user = $this->factory()->user->create_and_get( array(
     241                        'display_name' => 'John Doe',
     242                ) );
     243                $post = $this->factory()->post->create_and_get( array(
     244                        'post_author' => $user->ID,
     245                        'post_title'  => 'Hello World',
     246                ) );
    209247
    210                 $post_id     = self::factory()->post->create();
    211                 $url         = get_permalink( $post_id );
    212                 $url_encoded = urlencode( $url );
     248                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     249                $request->set_param( 'url', get_permalink( $post->ID ) );
     250                $request->set_param( 'format', 'xml' );
     251
     252                $response = $this->server->dispatch( $request );
     253                $output   = get_echo( '_oembed_rest_pre_serve_request', array( true, $response, $request, $this->server ) );
    213254
    214                 $this->assertEquals( home_url() . '/?oembed=true&url=' . $url_encoded, get_oembed_endpoint_url( $url ) );
    215                 $this->assertEquals( home_url() . '/?oembed=true&url=' . $url_encoded . '&format=xml', get_oembed_endpoint_url( $url, 'xml' ) );
     255                $xml = simplexml_load_string( $output );
     256                $this->assertInstanceOf( 'SimpleXMLElement', $xml );
    216257        }
    217258
    218         function test_wp_oembed_ensure_format() {
    219                 $this->assertEquals( 'json', wp_oembed_ensure_format( 'json' ) );
    220                 $this->assertEquals( 'xml', wp_oembed_ensure_format( 'xml' ) );
    221                 $this->assertEquals( 'json', wp_oembed_ensure_format( 123 ) );
    222                 $this->assertEquals( 'json', wp_oembed_ensure_format( 'random' ) );
    223                 $this->assertEquals( 'json', wp_oembed_ensure_format( array() ) );
     259        function test_rest_pre_serve_request_wrong_format() {
     260                $post = $this->factory()->post->create_and_get();
     261
     262                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     263                $request->set_param( 'url', get_permalink( $post->ID ) );
     264                $request->set_param( 'format', 'json' );
     265
     266                $response = $this->server->dispatch( $request );
     267
     268                $this->assertTrue( _oembed_rest_pre_serve_request( true, $response, $request, $this->server ) );
    224269        }
    225270
    226         function test_oembed_create_xml() {
    227                 $actual = _oembed_create_xml( array(
    228                         'foo'  => 'bar',
    229                         'bar'  => 'baz',
    230                         'ping' => 'pong',
    231                 ) );
     271        function test_rest_pre_serve_request_wrong_method() {
     272                $post = $this->factory()->post->create_and_get();
    232273
    233                 $expected = '<oembed><foo>bar</foo><bar>baz</bar><ping>pong</ping></oembed>';
     274                $request = new WP_REST_Request( 'HEAD', '/oembed/1.0/embed' );
     275                $request->set_param( 'url', get_permalink( $post->ID ) );
     276                $request->set_param( 'format', 'xml' );
    234277
    235                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     278                $response = $this->server->dispatch( $request );
    236279
    237                 $actual = _oembed_create_xml( array(
    238                         'foo'  => array(
    239                                 'bar' => 'baz',
    240                         ),
    241                         'ping' => 'pong',
    242                 ) );
     280                $this->assertTrue( _oembed_rest_pre_serve_request( true, $response, $request, $this->server ) );
     281        }
    243282
    244                 $expected = '<oembed><foo><bar>baz</bar></foo><ping>pong</ping></oembed>';
     283        function test_get_oembed_endpoint_url() {
     284                $this->assertEquals( home_url() . '/?rest_route=/oembed/1.0/embed', get_oembed_endpoint_url() );
     285                $this->assertEquals( home_url() . '/?rest_route=/oembed/1.0/embed', get_oembed_endpoint_url( '', 'json' ) );
     286                $this->assertEquals( home_url() . '/?rest_route=/oembed/1.0/embed', get_oembed_endpoint_url( '', 'xml' ) );
    245287
    246                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     288                $post_id     = $this->factory()->post->create();
     289                $url         = get_permalink( $post_id );
     290                $url_encoded = urlencode( $url );
    247291
    248                 $actual = _oembed_create_xml( array(
    249                         'foo'   => array(
    250                                 'bar' => array(
    251                                         'ping' => 'pong',
    252                                 ),
    253                         ),
    254                         'hello' => 'world',
    255                 ) );
     292                $this->assertEquals( home_url() . '/?rest_route=%2Foembed%2F1.0%2Fembed&url=' . $url_encoded, get_oembed_endpoint_url( $url ) );
     293                $this->assertEquals( home_url() . '/?rest_route=%2Foembed%2F1.0%2Fembed&url=' . $url_encoded . '&format=xml', get_oembed_endpoint_url( $url, 'xml' ) );
     294        }
    256295
    257                 $expected = '<oembed><foo><bar><ping>pong</ping></bar></foo><hello>world</hello></oembed>';
     296        function test_get_oembed_endpoint_url_pretty_permalinks() {
     297                update_option( 'permalink_structure', '/%postname%' );
    258298
    259                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     299                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed', get_oembed_endpoint_url() );
     300                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed', get_oembed_endpoint_url( '', 'xml' ) );
    260301
    261                 $actual = _oembed_create_xml( array(
    262                         array(
    263                                 'foo' => array(
    264                                         'bar',
    265                                 ),
    266                         ),
    267                         'helloworld',
    268                 ) );
     302                $post_id     = $this->factory()->post->create();
     303                $url         = get_permalink( $post_id );
     304                $url_encoded = urlencode( $url );
    269305
    270                 $expected = '<oembed><oembed><foo><oembed>bar</oembed></foo></oembed><oembed>helloworld</oembed></oembed>';
     306                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed?url=' . $url_encoded, get_oembed_endpoint_url( $url ) );
     307                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed?url=' . $url_encoded . '&format=xml', get_oembed_endpoint_url( $url, 'xml' ) );
    271308
    272                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     309                update_option( 'permalink_structure', '' );
    273310        }
    274311}
  • tests/phpunit/tests/oembed/discovery.php

    diff --git tests/phpunit/tests/oembed/discovery.php tests/phpunit/tests/oembed/discovery.php
    index e7615f9..63eb5bb 100644
     
    55 */
    66class Tests_oEmbed_Discovery extends WP_UnitTestCase {
    77        function test_add_oembed_discovery_links_non_singular() {
    8                 ob_start();
    9                 wp_oembed_add_discovery_links();
    10                 $actual = ob_get_clean();
    11                 $this->assertSame( '', $actual );
     8                $this->assertSame( '', get_echo( 'wp_oembed_add_discovery_links' ) );
    129        }
    1310
    1411        function test_add_oembed_discovery_links_to_post() {
    1512                $post_id = self::factory()->post->create();
    1613                $this->go_to( get_permalink( $post_id ) );
    17 
    1814                $this->assertQueryTrue( 'is_single', 'is_singular' );
    1915
    20                 ob_start();
    21                 wp_oembed_add_discovery_links();
    22                 $actual = ob_get_clean();
    23 
    2416                $expected = '<link rel="alternate" type="application/json+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink() ) ) . '" />' . "\n";
    2517                $expected .= '<link rel="alternate" type="text/xml+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink(), 'xml' ) ) . '" />' . "\n";
    2618
    27                 $this->assertEquals( $expected, $actual );
     19                $this->assertEquals( $expected, get_echo( 'wp_oembed_add_discovery_links' ) );
    2820        }
    2921
    3022        function test_add_oembed_discovery_links_to_page() {
    class Tests_oEmbed_Discovery extends WP_UnitTestCase { 
    3224                        'post_type' => 'page'
    3325                ));
    3426                $this->go_to( get_permalink( $post_id ) );
    35 
    3627                $this->assertQueryTrue( 'is_page', 'is_singular' );
    3728
    38                 ob_start();
    39                 wp_oembed_add_discovery_links();
    40                 $actual = ob_get_clean();
    41 
    4229                $expected = '<link rel="alternate" type="application/json+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink() ) ) . '" />' . "\n";
    4330                $expected .= '<link rel="alternate" type="text/xml+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink(), 'xml' ) ) . '" />' . "\n";
    4431
    45                 $this->assertEquals( $expected, $actual );
     32                $this->assertEquals( $expected, get_echo( 'wp_oembed_add_discovery_links' ) );
    4633        }
    4734
    4835        function test_add_oembed_discovery_links_to_attachment() {
    class Tests_oEmbed_Discovery extends WP_UnitTestCase { 
    5340                ) );
    5441
    5542                $this->go_to( get_permalink( $attachment_id ) );
    56 
    5743                $this->assertQueryTrue( 'is_attachment', 'is_singular', 'is_single' );
    5844
    59                 ob_start();
    60                 wp_oembed_add_discovery_links();
    61                 $actual = ob_get_clean();
    62 
    6345                $expected = '<link rel="alternate" type="application/json+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink() ) ) . '" />' . "\n";
    6446                $expected .= '<link rel="alternate" type="text/xml+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink(), 'xml' ) ) . '" />' . "\n";
    6547
    66                 $this->assertEquals( $expected, $actual );
     48                $this->assertEquals( $expected, get_echo( 'wp_oembed_add_discovery_links' ) );
    6749        }
    6850}
  • tests/phpunit/tests/oembed/headers.php

    diff --git tests/phpunit/tests/oembed/headers.php tests/phpunit/tests/oembed/headers.php
    index 3c9f80f..b0bc2c8 100644
     
    77 * @group oembed-headers
    88 */
    99class Tests_oEmbed_HTTP_Headers extends WP_UnitTestCase {
    10         function test_request_json_response_headers() {
     10        function test_rest_pre_serve_request_headers() {
    1111                if ( ! function_exists( 'xdebug_get_headers' ) ) {
    1212                        $this->markTestSkipped( 'xdebug is required for this test' );
    1313                }
    1414
    15                 $post = self::factory()->post->create_and_get( array(
     15                $post = $this->factory()->post->create_and_get( array(
    1616                        'post_title'  => 'Hello World',
    1717                ) );
    1818
    19                 $request = array(
    20                         'url'      => get_permalink( $post->ID ),
    21                         'format'   => 'json',
    22                         'maxwidth' => 600,
    23                         'callback' => '',
    24                 );
     19                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     20                $request->set_param( 'url', get_permalink( $post->ID ) );
     21                $request->set_param( 'format', 'xml' );
    2522
    26                 $legacy_controller = new WP_oEmbed_Controller();
    27                 $legacy_controller->dispatch( $request );
     23                $server   = new WP_REST_Server();
     24                $response = $server->dispatch( $request );
     25                $output   = get_echo( '_oembed_rest_pre_serve_request', array( true, $response, $request, $server ) );
    2826
    29                 $headers = xdebug_get_headers();
    30 
    31                 $this->assertTrue( in_array( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ), $headers ) );
    32                 $this->assertTrue( in_array( 'X-Content-Type-Options: nosniff', $headers ) );
    33 
    34                 $request['callback'] = 'foobar';
    35 
    36                 $legacy_controller->dispatch( $request );
    37 
    38                 $headers = xdebug_get_headers();
    39 
    40                 $this->assertTrue( in_array( 'Content-Type: application/javascript; charset=' . get_option( 'blog_charset' ), $headers ) );
    41                 $this->assertTrue( in_array( 'X-Content-Type-Options: nosniff', $headers ) );
    42         }
    43 
    44         function test_request_xml_response_headers() {
    45                 if ( ! function_exists( 'xdebug_get_headers' ) ) {
    46                         $this->markTestSkipped( 'xdebug is required for this test' );
    47                 }
    48 
    49                 $post = self::factory()->post->create_and_get( array(
    50                         'post_title'  => 'Hello World',
    51                 ) );
    52 
    53                 $request = array(
    54                         'url'      => get_permalink( $post->ID ),
    55                         'format'   => 'xml',
    56                         'maxwidth' => 600,
    57                 );
    58 
    59                 $legacy_controller = new WP_oEmbed_Controller();
    60                 $legacy_controller->dispatch( $request );
     27                $this->assertNotEmpty( $output );
    6128
    6229                $headers = xdebug_get_headers();
    6330
  • tests/phpunit/tests/oembed/template.php

    diff --git tests/phpunit/tests/oembed/template.php tests/phpunit/tests/oembed/template.php
    index b0bb1a3..b45b930 100644
    class Tests_Embed_Template extends WP_UnitTestCase { 
    248248        }
    249249
    250250        function test_add_host_js() {
    251                 ob_start();
    252251                wp_oembed_add_host_js();
    253                 ob_end_clean();
    254252
    255253                $this->assertTrue( wp_script_is( 'wp-embed' ) );
    256254        }