Make WordPress Core

Ticket #34207: 34207.2.diff

File 34207.2.diff, 31.1 KB (added by swissspidy, 8 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 2da7f3e..dda8038 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                         echo 'URL parameter missing';
    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|WP_REST_Response
    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 { 
    8476                 */
    8577                $post_id = apply_filters( 'oembed_request_post_id', $post_id, $request['url'] );
    8678
    87                 $data = get_oembed_response_data( $post_id, $request['maxwidth'] );
    88 
    89                 if ( false === $data ) {
    90                         status_header( 404 );
    91                         return __( 'Invalid URL.' );
    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 'Not implemented';
    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                 $result = _oembed_create_xml( $data );
    146 
    147                 // Bail if there's no XML.
    148                 if ( ! $result ) {
    149                         status_header( 501 );
    150                         return 'Not implemented';
    151                 }
    152 
    153                 if ( ! headers_sent() ) {
    154                         header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ) );
     79                if ( 0 === $post_id ) {
     80                        return new WP_Error( 'oembed_invalid_url', __( 'Invalid URL.', 'oembed-api' ), array( 'status' => 404 ) );
    15581                }
    15682
    157                 return $result;
     83                return get_oembed_response_data( $post_id, $request['maxwidth'] );
    15884        }
    15985}
  • src/wp-includes/class-wp.php

    diff --git src/wp-includes/class-wp.php src/wp-includes/class-wp.php
    index bba47ff..608a1c7 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 8bdebe5..ec90308 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( 'oembed_head',          'print_emoji_detection_script'         );
    448 add_action( 'oembed_head',          'print_emoji_styles'                   );
    449 add_action( 'oembed_head',          'print_oembed_embed_styles'            );
    450 add_action( 'oembed_head',          'print_oembed_embed_scripts'           );
    451 add_action( 'oembed_head',          'wp_print_head_scripts',         20    );
    452 add_action( 'oembed_head',          'wp_print_styles',               20    );
    453 add_action( 'oembed_head',          'wp_no_robots'                         );
    454 add_action( 'oembed_head',          'rel_canonical'                        );
    455 add_action( 'oembed_head',          'locale_stylesheet'                    );
    456 
    457 add_action( 'oembed_footer',        'wp_print_footer_scripts',       20    );
    458 
    459 add_filter( 'excerpt_more',         'wp_oembed_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_oembed_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( 'oembed_head',            'print_emoji_detection_script'          );
     449add_action( 'oembed_head',            'print_emoji_styles'                    );
     450add_action( 'oembed_head',            'print_oembed_embed_styles'             );
     451add_action( 'oembed_head',            'print_oembed_embed_scripts'            );
     452add_action( 'oembed_head',            'wp_print_head_scripts',          20    );
     453add_action( 'oembed_head',            'wp_print_styles',                20    );
     454add_action( 'oembed_head',            'wp_no_robots'                          );
     455add_action( 'oembed_head',            'rel_canonical'                         );
     456add_action( 'oembed_head',            'locale_stylesheet'                     );
     457
     458add_action( 'oembed_footer',          'wp_print_footer_scripts',        20    );
     459
     460add_filter( 'excerpt_more',           'wp_oembed_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_oembed_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 094d8cd..5047d63 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 ) { 
    418414 * @return string The oEmbed endpoint URL.
    419415 */
    420416function get_oembed_endpoint_url( $permalink = '', $format = 'json' ) {
    421         $url = add_query_arg( array( 'oembed' => 'true' ), home_url( '/' ) );
     417        $url = rest_url( 'oembed/1.0/embed' );
    422418
    423419        if ( 'json' === $format ) {
    424420                $format = false;
    function wp_oembed_ensure_format( $format ) { 
    642638}
    643639
    644640/**
     641 * Hooks into the REST API output to print XML instead of JSON.
     642 *
     643 * This is only done for the oEmbed API endpoint,
     644 * which supports both formats.
     645 *
     646 * @access private
     647 * @since 4.4.0
     648 *
     649 * @param bool                      $served  Whether the request has already been served.
     650 * @param WP_HTTP_ResponseInterface $result  Result to send to the client. Usually a WP_REST_Response.
     651 * @param WP_REST_Request           $request Request used to generate the response.
     652 * @param WP_REST_Server            $server  Server instance.
     653 * @return true
     654 */
     655function _oembed_rest_pre_serve_request( $served, $result, $request, $server ) {
     656        $params = $request->get_params();
     657
     658        if ( '/oembed/1.0/embed' !== $request->get_route() || 'GET' !== $request->get_method() ) {
     659                return $served;
     660        }
     661
     662        if ( ! isset( $params['format'] ) || 'xml' !== $params['format'] ) {
     663                return $served;
     664        }
     665
     666        // Embed links inside the request.
     667        $data = $server->response_to_data( $result, false );
     668
     669        if ( 404 === $result->get_status() ) {
     670                $data = $data[0];
     671        }
     672
     673        $result = _oembed_create_xml( $data );
     674
     675        // Bail if there's no XML.
     676        if ( ! $result ) {
     677                status_header( 501 );
     678                die( 'Not implemented' );
     679        }
     680
     681        if ( ! headers_sent() ) {
     682                $server->send_header( 'Content-Type', 'text/xml; charset=' . get_option( 'blog_charset' ) );
     683        }
     684
     685        echo $result;
     686
     687        return true;
     688}
     689
     690/**
    645691 * Creates an XML string from a given array.
    646692 *
    647693 * @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 4c0771b..f8d061b 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();
     116
     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' );
    13126
    14                 $legacy_controller = new WP_oEmbed_Controller();
     127                $response = $this->server->dispatch( $request );
     128                $data     = $response->get_data();
    15129
    16                 $this->assertEquals( 'Invalid URL.', $legacy_controller->dispatch( $request ) );
     130                $this->assertTrue( is_array( $data ) );
    17131        }
    18132
    19133        function test_request_json() {
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    25139                        'post_title'  => 'Hello World',
    26140                ) );
    27141
    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                 );
    36 
    37                 $legacy_controller = new WP_oEmbed_Controller();
     142                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     143                $request->set_param( 'url', get_permalink( $post->ID ) );
     144                $request->set_param( 'maxwidth', 400 );
    38145
    39                 $data = json_decode( $legacy_controller->dispatch( $request ), true );
     146                $response = $this->server->dispatch( $request );
     147                $data     = $response->get_data();
    40148
    41149                $this->assertTrue( is_array( $data ) );
    42150
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    56164                $this->assertEquals( get_author_posts_url( $user->ID, $user->user_nicename ), $data['author_url'] );
    57165                $this->assertEquals( $post->post_title, $data['title'] );
    58166                $this->assertEquals( 'rich', $data['type'] );
    59                 $this->assertTrue( $data['width'] <= $request['maxwidth'] );
    60         }
    61 
    62         function test_request_jsonp() {
    63                 $user = $this->factory->user->create_and_get( array(
    64                         'display_name' => 'John Doe',
    65                 ) );
    66                 $post = $this->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 = $this->factory->user->create_and_get( array(
    87                         'display_name' => 'John Doe',
    88                 ) );
    89                 $post = $this->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( 'Not implemented',  $legacy_controller->json_response( null, $request ) );
    116                 $this->assertEquals( 'Not implemented',  $legacy_controller->json_response( 123, $request ) );
    117                 $this->assertEquals( 'Not implemented',  $legacy_controller->json_response( array(), $request ) );
     167                $this->assertTrue( $data['width'] <= $request->get_param( 'maxwidth' ) );
    118168        }
    119169
    120170        function test_request_xml() {
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    126176                        'post_title'  => 'Hello World',
    127177                ) );
    128178
    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();
     179                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     180                $request->set_param( 'url', get_permalink( $post->ID ) );
     181                $request->set_param( 'format', 'xml' );
     182                $request->set_param( 'maxwidth', 400 );
    137183
    138                 $data = $legacy_controller->dispatch( $request );
     184                $response = $this->server->dispatch( $request );
     185                $data     = $response->get_data();
    139186
    140                 $data = simplexml_load_string( $data );
    141                 $this->assertInstanceOf( 'SimpleXMLElement', $data );
    142 
    143                 $data = (array) $data;
     187                $this->assertTrue( is_array( $data ) );
    144188
    145189                $this->assertArrayHasKey( 'version', $data );
    146190                $this->assertArrayHasKey( 'provider_name', $data );
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    158202                $this->assertEquals( get_author_posts_url( $user->ID, $user->user_nicename ), $data['author_url'] );
    159203                $this->assertEquals( $post->post_title, $data['title'] );
    160204                $this->assertEquals( 'rich', $data['type'] );
    161                 $this->assertTrue( $data['width'] <= $request['maxwidth'] );
     205                $this->assertTrue( $data['width'] <= $request->get_param( 'maxwidth' ) );
    162206        }
    163207
    164         function test_request_xml_invalid_data() {
    165                 $legacy_controller = new WP_oEmbed_Controller();
     208        function test_rest_pre_serve_request() {
     209                $user = $this->factory->user->create_and_get( array(
     210                        'display_name' => 'John Doe',
     211                ) );
     212                $post = $this->factory->post->create_and_get( array(
     213                        'post_author' => $user->ID,
     214                        'post_title'  => 'Hello World',
     215                ) );
    166216
    167                 $this->assertEquals( 'Not implemented',  $legacy_controller->xml_response( null ) );
    168                 $this->assertEquals( 'Not implemented',  $legacy_controller->xml_response( 123 ) );
    169                 $this->assertEquals( 'Not implemented',  $legacy_controller->xml_response( array() ) );
    170         }
     217                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     218                $request->set_param( 'url', get_permalink( $post->ID ) );
     219                $request->set_param( 'format', 'xml' );
    171220
    172         /**
    173          * @group multisite
    174          */
    175         function test_request_ms_child_in_root_blog() {
    176                 if ( ! is_multisite() ) {
    177                         $this->markTestSkipped( __METHOD__ . ' is a multisite-only test.' );
    178                 }
     221                $response = $this->server->dispatch( $request );
    179222
    180                 $child = $this->factory->blog->create();
     223                ob_start();
     224                _oembed_rest_pre_serve_request( true, $response, $request, $this->server );
     225                $output = ob_get_clean();
    181226
    182                 switch_to_blog( $child );
     227                $xml = simplexml_load_string( $output );
     228                $this->assertInstanceOf( 'SimpleXMLElement', $xml );
     229        }
    183230
    184                 $post = $this->factory->post->create_and_get( array(
    185                         'post_title' => 'Hello Child Blog',
    186                 ) );
     231        function test_rest_pre_serve_request_wrong_format() {
     232                $post = $this->factory->post->create_and_get();
    187233
    188                 $request = array(
    189                         'url'      => get_permalink( $post->ID ),
    190                         'format'   => 'json',
    191                         'maxwidth' => 600,
    192                         'callback' => '',
    193                 );
     234                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     235                $request->set_param( 'url', get_permalink( $post->ID ) );
     236                $request->set_param( 'format', 'json' );
    194237
    195                 $legacy_controller = new WP_oEmbed_Controller();
     238                $response = $this->server->dispatch( $request );
    196239
    197                 $data = json_decode( $legacy_controller->dispatch( $request ), true );
     240                $this->assertTrue( _oembed_rest_pre_serve_request( true, $response, $request, $this->server ) );
     241        }
    198242
    199                 $this->assertInternalType( 'array', $data );
    200                 $this->assertNotEmpty( $data );
     243        function test_rest_pre_serve_request_wrong_method() {
     244                $post = $this->factory->post->create_and_get();
    201245
    202                 restore_current_blog();
     246                $request = new WP_REST_Request( 'HEAD', '/oembed/1.0/embed' );
     247                $request->set_param( 'url', get_permalink( $post->ID ) );
     248                $request->set_param( 'format', 'xml' );
     249
     250                $response = $this->server->dispatch( $request );
     251
     252                $this->assertTrue( _oembed_rest_pre_serve_request( true, $response, $request, $this->server ) );
    203253        }
    204254
    205255        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' ) );
     256                $this->assertEquals( home_url() . '/?rest_route=/oembed/1.0/embed', get_oembed_endpoint_url() );
     257                $this->assertEquals( home_url() . '/?rest_route=/oembed/1.0/embed', get_oembed_endpoint_url( '', 'json' ) );
     258                $this->assertEquals( home_url() . '/?rest_route=/oembed/1.0/embed', get_oembed_endpoint_url( '', 'xml' ) );
    209259
    210260                $post_id     = $this->factory->post->create();
    211261                $url         = get_permalink( $post_id );
    212262                $url_encoded = urlencode( $url );
    213263
    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' ) );
     264                $this->assertEquals( home_url() . '/?rest_route=%2Foembed%2F1.0%2Fembed&url=' . $url_encoded, get_oembed_endpoint_url( $url ) );
     265                $this->assertEquals( home_url() . '/?rest_route=%2Foembed%2F1.0%2Fembed&url=' . $url_encoded . '&format=xml', get_oembed_endpoint_url( $url, 'xml' ) );
    216266        }
    217267
    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() ) );
    224         }
     268        function test_get_oembed_endpoint_url_pretty_permalinks() {
     269                update_option( 'permalink_structure', '/%postname%' );
    225270
    226         function test_oembed_create_xml() {
    227                 $actual = _oembed_create_xml( array(
    228                         'foo'  => 'bar',
    229                         'bar'  => 'baz',
    230                         'ping' => 'pong',
    231                 ) );
     271                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed', get_oembed_endpoint_url() );
     272                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed', get_oembed_endpoint_url( '', 'xml' ) );
    232273
    233                 $expected = '<oembed><foo>bar</foo><bar>baz</bar><ping>pong</ping></oembed>';
     274                $post_id     = $this->factory->post->create();
     275                $url         = get_permalink( $post_id );
     276                $url_encoded = urlencode( $url );
    234277
    235                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     278                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed?url=' . $url_encoded, get_oembed_endpoint_url( $url ) );
     279                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed?url=' . $url_encoded . '&format=xml', get_oembed_endpoint_url( $url, 'xml' ) );
    236280
    237                 $actual = _oembed_create_xml( array(
    238                         'foo'  => array(
    239                                 'bar' => 'baz',
    240                         ),
    241                         'ping' => 'pong',
    242                 ) );
     281                update_option( 'permalink_structure', '' );
     282        }
    243283
    244                 $expected = '<oembed><foo><bar>baz</bar></foo><ping>pong</ping></oembed>';
     284        function test_request_ms_child_in_root_blog() {
     285                if ( ! is_multisite() ) {
     286                        $this->markTestSkipped( __METHOD__ . ' is a multisite-only test.' );
     287                }
    245288
    246                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     289                $child = $this->factory->blog->create();
    247290
    248                 $actual = _oembed_create_xml( array(
    249                         'foo'   => array(
    250                                 'bar' => array(
    251                                         'ping' => 'pong',
    252                                 ),
    253                         ),
    254                         'hello' => 'world',
     291                switch_to_blog( $child );
     292
     293                $post = $this->factory->post->create_and_get( array(
     294                        'post_title' => 'Hello Child Blog',
    255295                ) );
    256296
    257                 $expected = '<oembed><foo><bar><ping>pong</ping></bar></foo><hello>world</hello></oembed>';
     297                $user = $this->factory->user->create_and_get( array(
     298                        'display_name' => 'John Doe',
     299                ) );
     300                $post = $this->factory->post->create_and_get( array(
     301                        'post_author' => $user->ID,
     302                        'post_title'  => 'Hello World',
     303                ) );
    258304
    259                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     305                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     306                $request->set_param( 'url', get_permalink( $post->ID ) );
    260307
    261                 $actual = _oembed_create_xml( array(
    262                         array(
    263                                 'foo' => array(
    264                                         'bar',
    265                                 ),
    266                         ),
    267                         'helloworld',
    268                 ) );
     308                $response = $this->server->dispatch( $request );
     309                $data     = $response->get_data();
    269310
    270                 $expected = '<oembed><oembed><foo><oembed>bar</oembed></foo></oembed><oembed>helloworld</oembed></oembed>';
     311                $this->assertTrue( is_array( $data ) );
    271312
    272                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     313                $this->assertArrayHasKey( 'version', $data );
     314                $this->assertArrayHasKey( 'provider_name', $data );
     315                $this->assertArrayHasKey( 'provider_url', $data );
     316                $this->assertArrayHasKey( 'author_name', $data );
     317                $this->assertArrayHasKey( 'author_url', $data );
     318                $this->assertArrayHasKey( 'title', $data );
     319                $this->assertArrayHasKey( 'type', $data );
     320
     321                restore_current_blog();
    273322        }
    274323}
  • tests/phpunit/tests/oembed/headers.php

    diff --git tests/phpunit/tests/oembed/headers.php tests/phpunit/tests/oembed/headers.php
    index 2ee7a4f..f89f816 100644
     
    55 * @preserveGlobalState disabled
    66 * @group oembed
    77 * @group oembed-headers
     8 * @group restapi
    89 */
    910class Tests_oEmbed_HTTP_Headers extends WP_UnitTestCase {
    10         function test_request_json_response_headers() {
     11        /**
     12         * Test HTTP headers set by the rest_pre_serve_request method.
     13         */
     14        function test_rest_pre_serve_request_headers() {
    1115                if ( ! function_exists( 'xdebug_get_headers' ) ) {
    1216                        $this->markTestSkipped( 'xdebug is required for this test' );
    1317                }
    1418
     19                $user = $this->factory->user->create_and_get( array(
     20                        'display_name' => 'John Doe',
     21                ) );
    1522                $post = $this->factory->post->create_and_get( array(
     23                        'post_author' => $user->ID,
    1624                        'post_title'  => 'Hello World',
    1725                ) );
    1826
    19                 $request = array(
    20                         'url'      => get_permalink( $post->ID ),
    21                         'format'   => 'json',
    22                         'maxwidth' => 600,
    23                         'callback' => '',
    24                 );
    25 
    26                 $legacy_controller = new WP_oEmbed_Controller();
    27                 $legacy_controller->dispatch( $request );
    28 
    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 ) );
     27                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     28                $request->set_param( 'url', get_permalink( $post->ID ) );
     29                $request->set_param( 'format', 'xml' );
    3330
    34                 $request['callback'] = 'foobar';
     31                $server = new WP_REST_Server;
    3532
    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 = $this->factory->post->create_and_get( array(
    50                         'post_title'  => 'Hello World',
    51                 ) );
     33                $response = $server->dispatch( $request );
    5234
    53                 $request = array(
    54                         'url'      => get_permalink( $post->ID ),
    55                         'format'   => 'xml',
    56                         'maxwidth' => 600,
    57                 );
     35                ob_start();
     36                _oembed_rest_pre_serve_request( true, $response, $request, $server );
     37                $output = ob_get_clean();
    5838
    59                 $legacy_controller = new WP_oEmbed_Controller();
    60                 $legacy_controller->dispatch( $request );
     39                $this->assertNotEmpty( $output );
    6140
    6241                $headers = xdebug_get_headers();
    6342