Make WordPress Core

Changeset 35436


Ignore:
Timestamp:
10/29/2015 10:50:13 PM (8 years ago)
Author:
pento
Message:

Embeds: Who put this REST API infrastructure in my WordPress?

Well, while it's here, we probably should make use of it. The oEmbed endpoint now uses the REST API infrastructure, instead of providing its own.

Props swissspidy.

Fixes #34207.

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-oembed-controller.php

    r35408 r35436  
    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
     
    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.
     
    4931         */
    5032        $maxwidth = apply_filters( 'oembed_default_width', 600 );
    51         $maxwidth = absint( get_query_var( 'maxwidth', $maxwidth ) );
    5233
    53         $callback = get_query_var( '_jsonp', false );
    54 
    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
     
    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 );
     81        if ( ! $data ) {
     82            return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) );
    9283        }
    9384
    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' ) );
    160         }
    161 
    162         return $result;
     85        return $data;
    16386    }
    16487}
  • trunk/src/wp-includes/class-wp.php

    r35333 r35436  
    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    /**
  • trunk/src/wp-includes/default-filters.php

    r35423 r35436  
    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 );
  • trunk/src/wp-includes/embed-functions.php

    r35432 r35436  
    329329
    330330/**
    331  * Parses an oEmbed API query.
    332  *
    333  * @since 4.4.0
    334  *
    335  * @see WP_oEmbed_Controller::parse_query()
    336  *
    337  * @param WP_Query $wp_query The current WP_Query instance.
    338  */
    339 function wp_oembed_parse_query( $wp_query ) {
     331 * Registers the oEmbed REST API route.
     332 *
     333 * @since 4.4.0
     334 */
     335function wp_oembed_register_route() {
    340336    $controller = new WP_oEmbed_Controller();
    341     $controller->parse_query( $wp_query );
     337    $controller->register_routes();
    342338}
    343339
     
    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 ) {
     
    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(
     
    645632
    646633    return $format;
     634}
     635
     636/**
     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;
    647689}
    648690
  • trunk/tests/phpunit/tests/oembed/controller.php

    r35408 r35436  
    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         );
    13 
    14         $legacy_controller = new WP_oEmbed_Controller();
    15 
    16         $this->assertEquals( get_status_header_desc( 404 ), $legacy_controller->dispatch( $request ) );
     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' );
     126
     127        $response = $this->server->dispatch( $request );
     128        $data     = $response->get_data();
     129
     130        $this->assertInternalType( 'array', $data );
     131        $this->assertNotEmpty( $data );
    17132    }
    18133
     
    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         );
    36 
    37         $legacy_controller = new WP_oEmbed_Controller();
    38 
    39         $data = json_decode( $legacy_controller->dispatch( $request ), true );
    40 
    41         $this->assertTrue( is_array( $data ) );
     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 );
     146
     147        $response = $this->server->dispatch( $request );
     148        $data     = $response->get_data();
     149
     150        $this->assertInternalType( 'array', $data );
     151        $this->assertNotEmpty( $data );
    42152
    43153        $this->assertArrayHasKey( 'version', $data );
     
    60170    }
    61171
    62     function test_request_jsonp() {
     172    function test_request_xml() {
    63173        $user = self::factory()->user->create_and_get( array(
    64174            'display_name' => 'John Doe',
     
    69179        ) );
    70180
    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 
    120     function test_request_xml() {
    121         $user = self::factory()->user->create_and_get( array(
    122             'display_name' => 'John Doe',
    123         ) );
    124         $post = self::factory()->post->create_and_get( array(
    125             'post_author' => $user->ID,
    126             'post_title'  => 'Hello World',
    127         ) );
    128 
    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();
    137 
    138         $data = $legacy_controller->dispatch( $request );
    139 
    140         $data = simplexml_load_string( $data );
    141         $this->assertInstanceOf( 'SimpleXMLElement', $data );
    142 
    143         $data = (array) $data;
     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 );
     185
     186        $response = $this->server->dispatch( $request );
     187        $data     = $response->get_data();
     188
     189        $this->assertInternalType( 'array', $data );
     190        $this->assertNotEmpty( $data );
    144191
    145192        $this->assertArrayHasKey( 'version', $data );
     
    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
     
    179218
    180219        $child = self::factory()->blog->create();
    181 
    182220        switch_to_blog( $child );
    183221
     
    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();
    196 
    197         $data = json_decode( $legacy_controller->dispatch( $request ), true );
     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 );
     229
     230        $response = $this->server->dispatch( $request );
     231        $data     = $response->get_data();
    198232
    199233        $this->assertInternalType( 'array', $data );
     
    203237    }
    204238
     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        ) );
     247
     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 ) );
     254
     255        $xml = simplexml_load_string( $output );
     256        $this->assertInstanceOf( 'SimpleXMLElement', $xml );
     257    }
     258
     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 ) );
     269    }
     270
     271    function test_rest_pre_serve_request_wrong_method() {
     272        $post = $this->factory()->post->create_and_get();
     273
     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' );
     277
     278        $response = $this->server->dispatch( $request );
     279
     280        $this->assertTrue( _oembed_rest_pre_serve_request( true, $response, $request, $this->server ) );
     281    }
     282
    205283    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' ) );
    209 
    210         $post_id     = self::factory()->post->create();
     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' ) );
     287
     288        $post_id     = $this->factory()->post->create();
    211289        $url         = get_permalink( $post_id );
    212290        $url_encoded = urlencode( $url );
    213291
    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' ) );
    216     }
    217 
    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     }
    225 
    226     function test_oembed_create_xml() {
    227         $actual = _oembed_create_xml( array(
    228             'foo'  => 'bar',
    229             'bar'  => 'baz',
    230             'ping' => 'pong',
    231         ) );
    232 
    233         $expected = '<oembed><foo>bar</foo><bar>baz</bar><ping>pong</ping></oembed>';
    234 
    235         $this->assertStringEndsWith( $expected, trim( $actual ) );
    236 
    237         $actual = _oembed_create_xml( array(
    238             'foo'  => array(
    239                 'bar' => 'baz',
    240             ),
    241             'ping' => 'pong',
    242         ) );
    243 
    244         $expected = '<oembed><foo><bar>baz</bar></foo><ping>pong</ping></oembed>';
    245 
    246         $this->assertStringEndsWith( $expected, trim( $actual ) );
    247 
    248         $actual = _oembed_create_xml( array(
    249             'foo'   => array(
    250                 'bar' => array(
    251                     'ping' => 'pong',
    252                 ),
    253             ),
    254             'hello' => 'world',
    255         ) );
    256 
    257         $expected = '<oembed><foo><bar><ping>pong</ping></bar></foo><hello>world</hello></oembed>';
    258 
    259         $this->assertStringEndsWith( $expected, trim( $actual ) );
    260 
    261         $actual = _oembed_create_xml( array(
    262             array(
    263                 'foo' => array(
    264                     'bar',
    265                 ),
    266             ),
    267             'helloworld',
    268         ) );
    269 
    270         $expected = '<oembed><oembed><foo><oembed>bar</oembed></foo></oembed><oembed>helloworld</oembed></oembed>';
    271 
    272         $this->assertStringEndsWith( $expected, trim( $actual ) );
     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    }
     295
     296    function test_get_oembed_endpoint_url_pretty_permalinks() {
     297        update_option( 'permalink_structure', '/%postname%' );
     298
     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' ) );
     301
     302        $post_id     = $this->factory()->post->create();
     303        $url         = get_permalink( $post_id );
     304        $url_encoded = urlencode( $url );
     305
     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' ) );
     308
     309        update_option( 'permalink_structure', '' );
    273310    }
    274311}
  • trunk/tests/phpunit/tests/oembed/discovery.php

    r35242 r35436  
    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
     
    1512        $post_id = self::factory()->post->create();
    1613        $this->go_to( get_permalink( $post_id ) );
    17 
    1814        $this->assertQueryTrue( 'is_single', 'is_singular' );
    19 
    20         ob_start();
    21         wp_oembed_add_discovery_links();
    22         $actual = ob_get_clean();
    2315
    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
     
    3325        ));
    3426        $this->go_to( get_permalink( $post_id ) );
    35 
    3627        $this->assertQueryTrue( 'is_page', 'is_singular' );
    37 
    38         ob_start();
    39         wp_oembed_add_discovery_links();
    40         $actual = ob_get_clean();
    4128
    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
     
    5441
    5542        $this->go_to( get_permalink( $attachment_id ) );
    56 
    5743        $this->assertQueryTrue( 'is_attachment', 'is_singular', 'is_single' );
    58 
    59         ob_start();
    60         wp_oembed_add_discovery_links();
    61         $actual = ob_get_clean();
    6244
    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}
  • trunk/tests/phpunit/tests/oembed/headers.php

    r35242 r35436  
    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();
  • trunk/tests/phpunit/tests/oembed/template.php

    r35432 r35436  
    250250
    251251    function test_add_host_js() {
    252         ob_start();
    253252        wp_oembed_add_host_js();
    254         ob_end_clean();
    255253
    256254        $this->assertTrue( wp_script_is( 'wp-embed' ) );
Note: See TracChangeset for help on using the changeset viewer.