26 |
26 |
27 /** |
27 /** |
28 * Constructor |
28 * Constructor |
29 */ |
29 */ |
30 public function __construct() { |
30 public function __construct() { |
31 // Hack to get the [embed] shortcode to run before wpautop() |
31 // Hack to get the [embed] shortcode to run before wpautop(). |
32 add_filter( 'the_content', array( $this, 'run_shortcode' ), 8 ); |
32 add_filter( 'the_content', array( $this, 'run_shortcode' ), 8 ); |
33 add_filter( 'widget_text_content', array( $this, 'run_shortcode' ), 8 ); |
33 add_filter( 'widget_text_content', array( $this, 'run_shortcode' ), 8 ); |
34 |
34 |
35 // Shortcode placeholder for strip_shortcodes() |
35 // Shortcode placeholder for strip_shortcodes(). |
36 add_shortcode( 'embed', '__return_false' ); |
36 add_shortcode( 'embed', '__return_false' ); |
37 |
37 |
38 // Attempts to embed all URLs in a post |
38 // Attempts to embed all URLs in a post. |
39 add_filter( 'the_content', array( $this, 'autoembed' ), 8 ); |
39 add_filter( 'the_content', array( $this, 'autoembed' ), 8 ); |
40 add_filter( 'widget_text_content', array( $this, 'autoembed' ), 8 ); |
40 add_filter( 'widget_text_content', array( $this, 'autoembed' ), 8 ); |
41 |
41 |
42 // After a post is saved, cache oEmbed items via Ajax |
42 // After a post is saved, cache oEmbed items via Ajax. |
43 add_action( 'edit_form_advanced', array( $this, 'maybe_run_ajax_cache' ) ); |
43 add_action( 'edit_form_advanced', array( $this, 'maybe_run_ajax_cache' ) ); |
44 add_action( 'edit_page_form', array( $this, 'maybe_run_ajax_cache' ) ); |
44 add_action( 'edit_page_form', array( $this, 'maybe_run_ajax_cache' ) ); |
45 } |
45 } |
46 |
46 |
47 /** |
47 /** |
57 * @return string Content with shortcode parsed |
57 * @return string Content with shortcode parsed |
58 */ |
58 */ |
59 public function run_shortcode( $content ) { |
59 public function run_shortcode( $content ) { |
60 global $shortcode_tags; |
60 global $shortcode_tags; |
61 |
61 |
62 // Back up current registered shortcodes and clear them all out |
62 // Back up current registered shortcodes and clear them all out. |
63 $orig_shortcode_tags = $shortcode_tags; |
63 $orig_shortcode_tags = $shortcode_tags; |
64 remove_all_shortcodes(); |
64 remove_all_shortcodes(); |
65 |
65 |
66 add_shortcode( 'embed', array( $this, 'shortcode' ) ); |
66 add_shortcode( 'embed', array( $this, 'shortcode' ) ); |
67 |
67 |
68 // Do the shortcode (only the [embed] one is registered) |
68 // Do the shortcode (only the [embed] one is registered). |
69 $content = do_shortcode( $content, true ); |
69 $content = do_shortcode( $content, true ); |
70 |
70 |
71 // Put the original shortcodes back |
71 // Put the original shortcodes back. |
72 $shortcode_tags = $orig_shortcode_tags; |
72 $shortcode_tags = $orig_shortcode_tags; |
73 |
73 |
74 return $content; |
74 return $content; |
75 } |
75 } |
76 |
76 |
99 * |
99 * |
100 * Do not use this function directly, use wp_embed_register_handler() instead. |
100 * Do not use this function directly, use wp_embed_register_handler() instead. |
101 * |
101 * |
102 * This function should probably also only be used for sites that do not support oEmbed. |
102 * This function should probably also only be used for sites that do not support oEmbed. |
103 * |
103 * |
104 * @param string $id An internal ID/name for the handler. Needs to be unique. |
104 * @param string $id An internal ID/name for the handler. Needs to be unique. |
105 * @param string $regex The regex that will be used to see if this handler should be used for a URL. |
105 * @param string $regex The regex that will be used to see if this handler should be used for a URL. |
106 * @param callable $callback The callback function that will be called if the regex is matched. |
106 * @param callable $callback The callback function that will be called if the regex is matched. |
107 * @param int $priority Optional. Used to specify the order in which the registered handlers will be tested (default: 10). Lower numbers correspond with earlier testing, and handlers with the same priority are tested in the order in which they were added to the action. |
107 * @param int $priority Optional. Used to specify the order in which the registered handlers will be tested. |
|
108 * Lower numbers correspond with earlier testing, and handlers with the same priority are |
|
109 * tested in the order in which they were added to the action. Default 10. |
108 */ |
110 */ |
109 public function register_handler( $id, $regex, $callback, $priority = 10 ) { |
111 public function register_handler( $id, $regex, $callback, $priority = 10 ) { |
110 $this->handlers[ $priority ][ $id ] = array( |
112 $this->handlers[ $priority ][ $id ] = array( |
111 'regex' => $regex, |
113 'regex' => $regex, |
112 'callback' => $callback, |
114 'callback' => $callback, |
116 /** |
118 /** |
117 * Unregisters a previously-registered embed handler. |
119 * Unregisters a previously-registered embed handler. |
118 * |
120 * |
119 * Do not use this function directly, use wp_embed_unregister_handler() instead. |
121 * Do not use this function directly, use wp_embed_unregister_handler() instead. |
120 * |
122 * |
121 * @param string $id The handler ID that should be removed. |
123 * @param string $id The handler ID that should be removed. |
122 * @param int $priority Optional. The priority of the handler to be removed (default: 10). |
124 * @param int $priority Optional. The priority of the handler to be removed (default: 10). |
123 */ |
125 */ |
124 public function unregister_handler( $id, $priority = 10 ) { |
126 public function unregister_handler( $id, $priority = 10 ) { |
125 unset( $this->handlers[ $priority ][ $id ] ); |
127 unset( $this->handlers[ $priority ][ $id ] ); |
|
128 } |
|
129 |
|
130 /** |
|
131 * Returns embed HTML for a given URL from embed handlers. |
|
132 * |
|
133 * Attempts to convert a URL into embed HTML by checking the URL |
|
134 * against the regex of the registered embed handlers. |
|
135 * |
|
136 * @since 5.5.0 |
|
137 * |
|
138 * @param array $attr { |
|
139 * Shortcode attributes. Optional. |
|
140 * |
|
141 * @type int $width Width of the embed in pixels. |
|
142 * @type int $height Height of the embed in pixels. |
|
143 * } |
|
144 * @param string $url The URL attempting to be embedded. |
|
145 * @return string|false The embed HTML on success, false otherwise. |
|
146 */ |
|
147 public function get_embed_handler_html( $attr, $url ) { |
|
148 $rawattr = $attr; |
|
149 $attr = wp_parse_args( $attr, wp_embed_defaults( $url ) ); |
|
150 |
|
151 ksort( $this->handlers ); |
|
152 foreach ( $this->handlers as $priority => $handlers ) { |
|
153 foreach ( $handlers as $id => $handler ) { |
|
154 if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) { |
|
155 $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ); |
|
156 if ( false !== $return ) { |
|
157 /** |
|
158 * Filters the returned embed HTML. |
|
159 * |
|
160 * @since 2.9.0 |
|
161 * |
|
162 * @see WP_Embed::shortcode() |
|
163 * |
|
164 * @param string|false $return The HTML result of the shortcode, or false on failure. |
|
165 * @param string $url The embed URL. |
|
166 * @param array $attr An array of shortcode attributes. |
|
167 */ |
|
168 return apply_filters( 'embed_handler_html', $return, $url, $attr ); |
|
169 } |
|
170 } |
|
171 } |
|
172 } |
|
173 |
|
174 return false; |
126 } |
175 } |
127 |
176 |
128 /** |
177 /** |
129 * The do_shortcode() callback function. |
178 * The do_shortcode() callback function. |
130 * |
179 * |
131 * Attempts to convert a URL into embed HTML. Starts by checking the URL against the regex of |
180 * Attempts to convert a URL into embed HTML. Starts by checking the URL against the regex of |
132 * the registered embed handlers. If none of the regex matches and it's enabled, then the URL |
181 * the registered embed handlers. If none of the regex matches and it's enabled, then the URL |
133 * will be given to the WP_oEmbed class. |
182 * will be given to the WP_oEmbed class. |
134 * |
183 * |
135 * @param array $attr { |
184 * @param array $attr { |
136 * Shortcode attributes. Optional. |
185 * Shortcode attributes. Optional. |
137 * |
186 * |
138 * @type int $width Width of the embed in pixels. |
187 * @type int $width Width of the embed in pixels. |
139 * @type int $height Height of the embed in pixels. |
188 * @type int $height Height of the embed in pixels. |
140 * } |
189 * } |
159 $rawattr = $attr; |
208 $rawattr = $attr; |
160 $attr = wp_parse_args( $attr, wp_embed_defaults( $url ) ); |
209 $attr = wp_parse_args( $attr, wp_embed_defaults( $url ) ); |
161 |
210 |
162 $this->last_attr = $attr; |
211 $this->last_attr = $attr; |
163 |
212 |
164 // kses converts & into & and we need to undo this |
213 // KSES converts & into & and we need to undo this. |
165 // See https://core.trac.wordpress.org/ticket/11311 |
214 // See https://core.trac.wordpress.org/ticket/11311 |
166 $url = str_replace( '&', '&', $url ); |
215 $url = str_replace( '&', '&', $url ); |
167 |
216 |
168 // Look for known internal handlers |
217 // Look for known internal handlers. |
169 ksort( $this->handlers ); |
218 $embed_handler_html = $this->get_embed_handler_html( $rawattr, $url ); |
170 foreach ( $this->handlers as $priority => $handlers ) { |
219 if ( false !== $embed_handler_html ) { |
171 foreach ( $handlers as $id => $handler ) { |
220 return $embed_handler_html; |
172 if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) { |
|
173 if ( false !== $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ) ) { |
|
174 /** |
|
175 * Filters the returned embed handler. |
|
176 * |
|
177 * @since 2.9.0 |
|
178 * |
|
179 * @see WP_Embed::shortcode() |
|
180 * |
|
181 * @param mixed $return The shortcode callback function to call. |
|
182 * @param string $url The attempted embed URL. |
|
183 * @param array $attr An array of shortcode attributes. |
|
184 */ |
|
185 return apply_filters( 'embed_handler_html', $return, $url, $attr ); |
|
186 } |
|
187 } |
|
188 } |
|
189 } |
221 } |
190 |
222 |
191 $post_ID = ( ! empty( $post->ID ) ) ? $post->ID : null; |
223 $post_ID = ( ! empty( $post->ID ) ) ? $post->ID : null; |
192 |
224 |
193 // Potentially set by WP_Embed::cache_oembed(). |
225 // Potentially set by WP_Embed::cache_oembed(). |
245 * |
277 * |
246 * @since 2.9.0 |
278 * @since 2.9.0 |
247 * |
279 * |
248 * @see WP_Embed::shortcode() |
280 * @see WP_Embed::shortcode() |
249 * |
281 * |
250 * @param mixed $cache The cached HTML result, stored in post meta. |
282 * @param string|false $cache The cached HTML result, stored in post meta. |
251 * @param string $url The attempted embed URL. |
283 * @param string $url The attempted embed URL. |
252 * @param array $attr An array of shortcode attributes. |
284 * @param array $attr An array of shortcode attributes. |
253 * @param int $post_ID Post ID. |
285 * @param int $post_ID Post ID. |
254 */ |
286 */ |
255 return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_ID ); |
287 return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_ID ); |
256 } |
288 } |
257 } |
289 } |
258 |
290 |
367 */ |
399 */ |
368 public function cache_oembed( $post_ID ) { |
400 public function cache_oembed( $post_ID ) { |
369 $post = get_post( $post_ID ); |
401 $post = get_post( $post_ID ); |
370 |
402 |
371 $post_types = get_post_types( array( 'show_ui' => true ) ); |
403 $post_types = get_post_types( array( 'show_ui' => true ) ); |
|
404 |
372 /** |
405 /** |
373 * Filters the array of post types to cache oEmbed results for. |
406 * Filters the array of post types to cache oEmbed results for. |
374 * |
407 * |
375 * @since 2.9.0 |
408 * @since 2.9.0 |
376 * |
409 * |
377 * @param string[] $post_types Array of post type names to cache oEmbed results for. Defaults to post types with `show_ui` set to true. |
410 * @param string[] $post_types Array of post type names to cache oEmbed results for. Defaults to post types with `show_ui` set to true. |
378 */ |
411 */ |
379 if ( empty( $post->ID ) || ! in_array( $post->post_type, apply_filters( 'embed_cache_oembed_types', $post_types ) ) ) { |
412 $cache_oembed_types = apply_filters( 'embed_cache_oembed_types', $post_types ); |
|
413 |
|
414 if ( empty( $post->ID ) || ! in_array( $post->post_type, $cache_oembed_types, true ) ) { |
380 return; |
415 return; |
381 } |
416 } |
382 |
417 |
383 // Trigger a caching |
418 // Trigger a caching. |
384 if ( ! empty( $post->post_content ) ) { |
419 if ( ! empty( $post->post_content ) ) { |
385 $this->post_ID = $post->ID; |
420 $this->post_ID = $post->ID; |
386 $this->usecache = false; |
421 $this->usecache = false; |
387 |
422 |
388 $content = $this->run_shortcode( $post->post_content ); |
423 $content = $this->run_shortcode( $post->post_content ); |
483 'lazy_load_term_meta' => false, |
518 'lazy_load_term_meta' => false, |
484 ) |
519 ) |
485 ); |
520 ); |
486 |
521 |
487 if ( ! empty( $oembed_post_query->posts ) ) { |
522 if ( ! empty( $oembed_post_query->posts ) ) { |
488 // Note: 'fields'=>'ids' is not being used in order to cache the post object as it will be needed. |
523 // Note: 'fields' => 'ids' is not being used in order to cache the post object as it will be needed. |
489 $oembed_post_id = $oembed_post_query->posts[0]->ID; |
524 $oembed_post_id = $oembed_post_query->posts[0]->ID; |
490 wp_cache_set( $cache_key, $oembed_post_id, $cache_group ); |
525 wp_cache_set( $cache_key, $oembed_post_id, $cache_group ); |
491 |
526 |
492 return $oembed_post_id; |
527 return $oembed_post_id; |
493 } |
528 } |