|
1 <?php |
|
2 /** |
|
3 * WP_oEmbed_Controller class, used to provide an oEmbed endpoint. |
|
4 * |
|
5 * @package WordPress |
|
6 * @subpackage Embeds |
|
7 * @since 4.4.0 |
|
8 */ |
|
9 |
|
10 /** |
|
11 * oEmbed API endpoint controller. |
|
12 * |
|
13 * Registers the API route and delivers the response data. |
|
14 * The output format (XML or JSON) is handled by the REST API. |
|
15 * |
|
16 * @since 4.4.0 |
|
17 */ |
|
18 final class WP_oEmbed_Controller { |
|
19 /** |
|
20 * Register the oEmbed REST API route. |
|
21 * |
|
22 * @since 4.4.0 |
|
23 */ |
|
24 public function register_routes() { |
|
25 /** |
|
26 * Filters the maxwidth oEmbed parameter. |
|
27 * |
|
28 * @since 4.4.0 |
|
29 * |
|
30 * @param int $maxwidth Maximum allowed width. Default 600. |
|
31 */ |
|
32 $maxwidth = apply_filters( 'oembed_default_width', 600 ); |
|
33 |
|
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 ) ); |
|
54 |
|
55 register_rest_route( 'oembed/1.0', '/proxy', array( |
|
56 array( |
|
57 'methods' => WP_REST_Server::READABLE, |
|
58 'callback' => array( $this, 'get_proxy_item' ), |
|
59 'permission_callback' => array( $this, 'get_proxy_item_permissions_check' ), |
|
60 'args' => array( |
|
61 'url' => array( |
|
62 'description' => __( 'The URL of the resource for which to fetch oEmbed data.' ), |
|
63 'type' => 'string', |
|
64 'required' => true, |
|
65 'sanitize_callback' => 'esc_url_raw', |
|
66 ), |
|
67 'format' => array( |
|
68 'description' => __( 'The oEmbed format to use.' ), |
|
69 'type' => 'string', |
|
70 'default' => 'json', |
|
71 'enum' => array( |
|
72 'json', |
|
73 'xml', |
|
74 ), |
|
75 ), |
|
76 'maxwidth' => array( |
|
77 'description' => __( 'The maximum width of the embed frame in pixels.' ), |
|
78 'type' => 'integer', |
|
79 'default' => $maxwidth, |
|
80 'sanitize_callback' => 'absint', |
|
81 ), |
|
82 'maxheight' => array( |
|
83 'description' => __( 'The maximum height of the embed frame in pixels.' ), |
|
84 'type' => 'integer', |
|
85 'sanitize_callback' => 'absint', |
|
86 ), |
|
87 'discover' => array( |
|
88 'description' => __( 'Whether to perform an oEmbed discovery request for non-whitelisted providers.' ), |
|
89 'type' => 'boolean', |
|
90 'default' => true, |
|
91 ), |
|
92 ), |
|
93 ), |
|
94 ) ); |
|
95 } |
|
96 |
|
97 /** |
|
98 * Callback for the embed API endpoint. |
|
99 * |
|
100 * Returns the JSON object for the post. |
|
101 * |
|
102 * @since 4.4.0 |
|
103 * |
|
104 * @param WP_REST_Request $request Full data about the request. |
|
105 * @return WP_Error|array oEmbed response data or WP_Error on failure. |
|
106 */ |
|
107 public function get_item( $request ) { |
|
108 $post_id = url_to_postid( $request['url'] ); |
|
109 |
|
110 /** |
|
111 * Filters the determined post ID. |
|
112 * |
|
113 * @since 4.4.0 |
|
114 * |
|
115 * @param int $post_id The post ID. |
|
116 * @param string $url The requested URL. |
|
117 */ |
|
118 $post_id = apply_filters( 'oembed_request_post_id', $post_id, $request['url'] ); |
|
119 |
|
120 $data = get_oembed_response_data( $post_id, $request['maxwidth'] ); |
|
121 |
|
122 if ( ! $data ) { |
|
123 return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) ); |
|
124 } |
|
125 |
|
126 return $data; |
|
127 } |
|
128 |
|
129 /** |
|
130 * Checks if current user can make a proxy oEmbed request. |
|
131 * |
|
132 * @since 4.8.0 |
|
133 * |
|
134 * @return true|WP_Error True if the request has read access, WP_Error object otherwise. |
|
135 */ |
|
136 public function get_proxy_item_permissions_check() { |
|
137 if ( ! current_user_can( 'edit_posts' ) ) { |
|
138 return new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to make proxied oEmbed requests.' ), array( 'status' => rest_authorization_required_code() ) ); |
|
139 } |
|
140 return true; |
|
141 } |
|
142 |
|
143 /** |
|
144 * Callback for the proxy API endpoint. |
|
145 * |
|
146 * Returns the JSON object for the proxied item. |
|
147 * |
|
148 * @since 4.8.0 |
|
149 * |
|
150 * @see WP_oEmbed::get_html() |
|
151 * @param WP_REST_Request $request Full data about the request. |
|
152 * @return object|WP_Error oEmbed response data or WP_Error on failure. |
|
153 */ |
|
154 public function get_proxy_item( $request ) { |
|
155 $args = $request->get_params(); |
|
156 |
|
157 // Serve oEmbed data from cache if set. |
|
158 unset( $args['_wpnonce'] ); |
|
159 $cache_key = 'oembed_' . md5( serialize( $args ) ); |
|
160 $data = get_transient( $cache_key ); |
|
161 if ( ! empty( $data ) ) { |
|
162 return $data; |
|
163 } |
|
164 |
|
165 $url = $request['url']; |
|
166 unset( $args['url'] ); |
|
167 |
|
168 // Copy maxwidth/maxheight to width/height since WP_oEmbed::fetch() uses these arg names. |
|
169 if ( isset( $args['maxwidth'] ) ) { |
|
170 $args['width'] = $args['maxwidth']; |
|
171 } |
|
172 if ( isset( $args['maxheight'] ) ) { |
|
173 $args['height'] = $args['maxheight']; |
|
174 } |
|
175 |
|
176 $data = _wp_oembed_get_object()->get_data( $url, $args ); |
|
177 |
|
178 if ( false === $data ) { |
|
179 return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) ); |
|
180 } |
|
181 |
|
182 /** |
|
183 * Filters the oEmbed TTL value (time to live). |
|
184 * |
|
185 * Similar to the {@see 'oembed_ttl'} filter, but for the REST API |
|
186 * oEmbed proxy endpoint. |
|
187 * |
|
188 * @since 4.8.0 |
|
189 * |
|
190 * @param int $time Time to live (in seconds). |
|
191 * @param string $url The attempted embed URL. |
|
192 * @param array $args An array of embed request arguments. |
|
193 */ |
|
194 $ttl = apply_filters( 'rest_oembed_ttl', DAY_IN_SECONDS, $url, $args ); |
|
195 |
|
196 set_transient( $cache_key, $data, $ttl ); |
|
197 |
|
198 return $data; |
|
199 } |
|
200 } |