Make WordPress Core

Ticket #34207: 34207.4.diff

File 34207.4.diff, 29.2 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 22c062b..d2ab6c5 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                 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' ) );
     79                if ( 0 === $post_id ) {
     80                        return new WP_Error( 'oembed_invalid_url', __( 'Invalid URL.' ), array( 'status' => 404 ) );
    16081                }
    16182
    162                 return $result;
     83                return get_oembed_response_data( $post_id, $request['maxwidth'] );
    16384        }
    16485}
  • 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 bbe9f24..0b923aa 100644
    add_filter( 'image_send_to_editor', 'image_add_caption', 20, 8 ); 
    438438add_filter( 'media_send_to_editor', 'image_media_send_to_editor', 10, 3 );
    439439
    440440// Embeds
    441 add_action( 'parse_query',          'wp_oembed_parse_query'                );
    442 
    443 add_action( 'wp_head',              'wp_oembed_add_discovery_links'        );
    444 add_action( 'wp_head',              'wp_oembed_add_host_js'                );
    445 
    446 add_action( 'embed_head',           'print_emoji_detection_script'         );
    447 add_action( 'embed_head',           'print_emoji_styles'                   );
    448 add_action( 'embed_head',           'print_embed_styles'                   );
    449 add_action( 'embed_head',           'print_embed_scripts'                  );
    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',         'wp_print_footer_scripts',       20    );
    457 
    458 add_filter( 'excerpt_more',         'wp_embed_excerpt_more',         20    );
    459 add_filter( 'the_excerpt_embed',    'wptexturize'                          );
    460 add_filter( 'the_excerpt_embed',    'convert_chars'                        );
    461 add_filter( 'the_excerpt_embed',    'wpautop'                              );
    462 add_filter( 'the_excerpt_embed',    'shortcode_unautop'                    );
    463 add_filter( 'the_excerpt_embed',    'wp_embed_excerpt_attachment'          );
    464 
    465 add_filter( 'oembed_dataparse',     'wp_filter_oembed_result',       10, 3 );
    466 add_filter( 'oembed_response_data', 'get_oembed_response_data_rich', 10, 4 );
     441add_action( 'rest_api_init',          'wp_oembed_register_route'              );
     442add_filter( 'rest_pre_serve_request', '_oembed_rest_pre_serve_request', 10, 4 );
     443
     444add_action( 'wp_head',                'wp_oembed_add_discovery_links'         );
     445add_action( 'wp_head',                'wp_oembed_add_host_js'                 );
     446
     447add_action( 'embed_head',             'print_emoji_detection_script'          );
     448add_action( 'embed_head',             'print_emoji_styles'                    );
     449add_action( 'embed_head',             'print_embed_styles'                    );
     450add_action( 'embed_head',             'print_embed_scripts'                   );
     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',           'wp_print_footer_scripts',        20    );
     458
     459add_filter( 'excerpt_more',           'wp_embed_excerpt_more',          20    );
     460add_filter( 'the_excerpt_embed',      'wptexturize'                           );
     461add_filter( 'the_excerpt_embed',      'convert_chars'                         );
     462add_filter( 'the_excerpt_embed',      'wpautop'                               );
     463add_filter( 'the_excerpt_embed',      'shortcode_unautop'                     );
     464add_filter( 'the_excerpt_embed',      'wp_embed_excerpt_attachment'           );
     465
     466add_filter( 'oembed_dataparse',       'wp_filter_oembed_result',        10, 3 );
     467add_filter( 'oembed_response_data',   'get_oembed_response_data_rich',  10, 4 );
    467468
    468469unset( $filter, $action );
  • src/wp-includes/embed-functions.php

    diff --git src/wp-includes/embed-functions.php src/wp-includes/embed-functions.php
    index 35e6587..a6c0f44 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 wp_oembed_ensure_format( $format ) { 
    645641}
    646642
    647643/**
     644 * Hooks into the REST API output to print XML instead of JSON.
     645 *
     646 * This is only done for the oEmbed API endpoint,
     647 * which supports both formats.
     648 *
     649 * @access private
     650 * @since 4.4.0
     651 *
     652 * @param bool                      $served  Whether the request has already been served.
     653 * @param WP_HTTP_ResponseInterface $result  Result to send to the client. Usually a WP_REST_Response.
     654 * @param WP_REST_Request           $request Request used to generate the response.
     655 * @param WP_REST_Server            $server  Server instance.
     656 * @return true
     657 */
     658function _oembed_rest_pre_serve_request( $served, $result, $request, $server ) {
     659        $params = $request->get_params();
     660
     661        if ( '/oembed/1.0/embed' !== $request->get_route() || 'GET' !== $request->get_method() ) {
     662                return $served;
     663        }
     664
     665        if ( ! isset( $params['format'] ) || 'xml' !== $params['format'] ) {
     666                return $served;
     667        }
     668
     669        // Embed links inside the request.
     670        $data = $server->response_to_data( $result, false );
     671
     672        if ( 404 === $result->get_status() ) {
     673                $data = $data[0];
     674        }
     675
     676        $result = _oembed_create_xml( $data );
     677
     678        // Bail if there's no XML.
     679        if ( ! $result ) {
     680                status_header( 501 );
     681                die( get_status_header_desc( 501 ) );
     682        }
     683
     684        if ( ! headers_sent() ) {
     685                $server->send_header( 'Content-Type', 'text/xml; charset=' . get_option( 'blog_charset' ) );
     686        }
     687
     688        echo $result;
     689
     690        return true;
     691}
     692
     693/**
    648694 * Creates an XML string from a given array.
    649695 *
    650696 * @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 34ce7dd..11be801 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/' );
    13113
    14                 $legacy_controller = new WP_oEmbed_Controller();
     114                $response = $this->server->dispatch( $request );
     115                $data     = $response->get_data();
    15116
    16                 $this->assertEquals( 'Invalid URL.', $legacy_controller->dispatch( $request ) );
     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' );
     126
     127                $response = $this->server->dispatch( $request );
     128                $data     = $response->get_data();
     129
     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                 );
     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 );
    36145
    37                 $legacy_controller = new WP_oEmbed_Controller();
    38 
    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 { 
    59167                $this->assertTrue( $data['width'] <= $request['maxwidth'] );
    60168        }
    61169
    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( '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 ) );
    118         }
    119 
    120170        function test_request_xml() {
    121171                $user = self::factory()->user->create_and_get( array(
    122172                        'display_name' => 'John Doe',
    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 { 
    161205                $this->assertTrue( $data['width'] <= $request['maxwidth'] );
    162206        }
    163207
    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 
    172208        /**
    173209         * @group multisite
    174210         */
    class Test_oEmbed_Controller extends WP_UnitTestCase { 
    202238                restore_current_blog();
    203239        }
    204240
    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' ) );
     241        function test_rest_pre_serve_request() {
     242                $user = $this->factory()->user->create_and_get( array(
     243                        'display_name' => 'John Doe',
     244                ) );
     245                $post = $this->factory()->post->create_and_get( array(
     246                        'post_author' => $user->ID,
     247                        'post_title'  => 'Hello World',
     248                ) );
    209249
    210                 $post_id     = self::factory()->post->create();
    211                 $url         = get_permalink( $post_id );
    212                 $url_encoded = urlencode( $url );
     250                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     251                $request->set_param( 'url', get_permalink( $post->ID ) );
     252                $request->set_param( 'format', 'xml' );
     253
     254                $response = $this->server->dispatch( $request );
     255
     256                ob_start();
     257                _oembed_rest_pre_serve_request( true, $response, $request, $this->server );
     258                $output = ob_get_clean();
    213259
    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' ) );
     260                $xml = simplexml_load_string( $output );
     261                $this->assertInstanceOf( 'SimpleXMLElement', $xml );
    216262        }
    217263
    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() ) );
     264        function test_rest_pre_serve_request_wrong_format() {
     265                $post = $this->factory()->post->create_and_get();
     266
     267                $request = new WP_REST_Request( 'GET', '/oembed/1.0/embed' );
     268                $request->set_param( 'url', get_permalink( $post->ID ) );
     269                $request->set_param( 'format', 'json' );
     270
     271                $response = $this->server->dispatch( $request );
     272
     273                $this->assertTrue( _oembed_rest_pre_serve_request( true, $response, $request, $this->server ) );
    224274        }
    225275
    226         function test_oembed_create_xml() {
    227                 $actual = _oembed_create_xml( array(
    228                         'foo'  => 'bar',
    229                         'bar'  => 'baz',
    230                         'ping' => 'pong',
    231                 ) );
     276        function test_rest_pre_serve_request_wrong_method() {
     277                $post = $this->factory()->post->create_and_get();
    232278
    233                 $expected = '<oembed><foo>bar</foo><bar>baz</bar><ping>pong</ping></oembed>';
     279                $request = new WP_REST_Request( 'HEAD', '/oembed/1.0/embed' );
     280                $request->set_param( 'url', get_permalink( $post->ID ) );
     281                $request->set_param( 'format', 'xml' );
    234282
    235                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     283                $response = $this->server->dispatch( $request );
    236284
    237                 $actual = _oembed_create_xml( array(
    238                         'foo'  => array(
    239                                 'bar' => 'baz',
    240                         ),
    241                         'ping' => 'pong',
    242                 ) );
     285                $this->assertTrue( _oembed_rest_pre_serve_request( true, $response, $request, $this->server ) );
     286        }
    243287
    244                 $expected = '<oembed><foo><bar>baz</bar></foo><ping>pong</ping></oembed>';
     288        function test_get_oembed_endpoint_url() {
     289                $this->assertEquals( home_url() . '/?rest_route=/oembed/1.0/embed', get_oembed_endpoint_url() );
     290                $this->assertEquals( home_url() . '/?rest_route=/oembed/1.0/embed', get_oembed_endpoint_url( '', 'json' ) );
     291                $this->assertEquals( home_url() . '/?rest_route=/oembed/1.0/embed', get_oembed_endpoint_url( '', 'xml' ) );
    245292
    246                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     293                $post_id     = $this->factory()->post->create();
     294                $url         = get_permalink( $post_id );
     295                $url_encoded = urlencode( $url );
    247296
    248                 $actual = _oembed_create_xml( array(
    249                         'foo'   => array(
    250                                 'bar' => array(
    251                                         'ping' => 'pong',
    252                                 ),
    253                         ),
    254                         'hello' => 'world',
    255                 ) );
     297                $this->assertEquals( home_url() . '/?rest_route=%2Foembed%2F1.0%2Fembed&url=' . $url_encoded, get_oembed_endpoint_url( $url ) );
     298                $this->assertEquals( home_url() . '/?rest_route=%2Foembed%2F1.0%2Fembed&url=' . $url_encoded . '&format=xml', get_oembed_endpoint_url( $url, 'xml' ) );
     299        }
    256300
    257                 $expected = '<oembed><foo><bar><ping>pong</ping></bar></foo><hello>world</hello></oembed>';
     301        function test_get_oembed_endpoint_url_pretty_permalinks() {
     302                update_option( 'permalink_structure', '/%postname%' );
    258303
    259                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     304                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed', get_oembed_endpoint_url() );
     305                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed', get_oembed_endpoint_url( '', 'xml' ) );
    260306
    261                 $actual = _oembed_create_xml( array(
    262                         array(
    263                                 'foo' => array(
    264                                         'bar',
    265                                 ),
    266                         ),
    267                         'helloworld',
    268                 ) );
     307                $post_id     = $this->factory()->post->create();
     308                $url         = get_permalink( $post_id );
     309                $url_encoded = urlencode( $url );
    269310
    270                 $expected = '<oembed><oembed><foo><oembed>bar</oembed></foo></oembed><oembed>helloworld</oembed></oembed>';
     311                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed?url=' . $url_encoded, get_oembed_endpoint_url( $url ) );
     312                $this->assertEquals( home_url() . '/wp-json/oembed/1.0/embed?url=' . $url_encoded . '&format=xml', get_oembed_endpoint_url( $url, 'xml' ) );
    271313
    272                 $this->assertStringEndsWith( $expected, trim( $actual ) );
     314                update_option( 'permalink_structure', '' );
    273315        }
    274316}
  • tests/phpunit/tests/oembed/headers.php

    diff --git tests/phpunit/tests/oembed/headers.php tests/phpunit/tests/oembed/headers.php
    index 3c9f80f..07a657b 100644
     
    33/**
    44 * @runTestsInSeparateProcesses
    55 * @preserveGlobalState disabled
    6  * @group oembed
    7  * @group oembed-headers
     6 * @group               oembed
     7 * @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();
    2824
    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         }
     25                $response = $server->dispatch( $request );
    4326
    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                 ) );
     27                ob_start();
     28                _oembed_rest_pre_serve_request( true, $response, $request, $server );
     29                $output = ob_get_clean();
    5230
    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 );
     31                $this->assertNotEmpty( $output );
    6132
    6233                $headers = xdebug_get_headers();
    6334
    6435                $this->assertTrue( in_array( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), $headers ) );
    6536        }
     37
    6638}