run:R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
23.8 KB
2026-03-11 16:18:51
R W Run
7.8 KB
2026-03-11 16:18:52
R W Run
36.1 KB
2026-03-11 16:18:51
R W Run
11.9 KB
2026-03-11 16:18:52
R W Run
18.94 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:52
R W Run
28.6 KB
2026-03-11 16:18:51
R W Run
316 By
2026-03-11 16:18:51
R W Run
12.9 KB
2026-03-11 16:18:51
R W Run
61.02 KB
2026-03-11 16:18:52
R W Run
15 KB
2026-03-11 16:18:51
R W Run
112.05 KB
2026-03-11 16:18:51
R W Run
12.47 KB
2026-03-11 16:18:51
R W Run
15.07 KB
2026-03-11 16:18:52
R W Run
9.84 KB
2026-03-11 16:18:52
R W Run
13.17 KB
2026-03-11 16:18:52
R W Run
33.83 KB
2026-03-11 16:18:51
R W Run
42.63 KB
2026-03-11 16:18:51
R W Run
55.71 KB
2026-03-11 16:18:52
R W Run
12.53 KB
2026-03-11 16:18:51
R W Run
2.55 KB
2026-03-11 16:18:52
R W Run
28.92 KB
2026-03-11 16:18:52
R W Run
539 By
2026-03-11 16:18:51
R W Run
367 By
2026-03-11 16:18:52
R W Run
42.65 KB
2026-03-11 16:18:51
R W Run
401 By
2026-03-11 16:18:51
R W Run
6.61 KB
2026-03-11 16:18:51
R W Run
664 By
2026-03-11 16:18:52
R W Run
20.63 KB
2026-03-11 16:18:51
R W Run
2.18 KB
2026-03-11 16:18:52
R W Run
453 By
2026-03-11 16:18:52
R W Run
457 By
2026-03-11 16:18:51
R W Run
36.83 KB
2026-03-11 16:18:52
R W Run
2.41 KB
2026-03-11 16:18:52
R W Run
8.28 KB
2026-03-11 16:18:51
R W Run
13.89 KB
2026-03-11 16:18:51
R W Run
11.76 KB
2026-03-11 16:18:51
R W Run
2.65 KB
2026-03-11 16:18:51
R W Run
7.43 KB
2026-03-11 16:18:51
R W Run
17.46 KB
2026-03-11 16:18:51
R W Run
5.14 KB
2026-03-11 16:18:52
R W Run
16.7 KB
2026-03-11 16:18:51
R W Run
8.28 KB
2026-03-11 16:18:52
R W Run
2.92 KB
2026-03-11 16:18:52
R W Run
1.32 KB
2026-03-11 16:18:51
R W Run
4.6 KB
2026-03-11 16:18:52
R W Run
11.62 KB
2026-03-11 16:18:52
R W Run
2.5 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
11.25 KB
2026-03-11 16:18:52
R W Run
5.32 KB
2026-03-11 16:18:51
R W Run
10.99 KB
2026-03-11 16:18:52
R W Run
68.32 KB
2026-03-11 16:18:51
R W Run
6.34 KB
2026-03-11 16:18:51
R W Run
5.49 KB
2026-03-11 16:18:51
R W Run
1.99 KB
2026-03-11 16:18:52
R W Run
7.02 KB
2026-03-11 16:18:51
R W Run
4.91 KB
2026-03-11 16:18:52
R W Run
16.86 KB
2026-03-11 16:18:51
R W Run
24.23 KB
2026-03-11 16:18:51
R W Run
3.97 KB
2026-03-11 16:18:51
R W Run
47.66 KB
2026-03-11 16:18:51
R W Run
9.22 KB
2026-03-11 16:18:51
R W Run
25.51 KB
2026-03-11 16:18:51
R W Run
198.38 KB
2026-03-11 16:18:52
R W Run
56.65 KB
2026-03-11 16:18:51
R W Run
10.46 KB
2026-03-11 16:18:51
R W Run
10.95 KB
2026-03-11 16:18:52
R W Run
29.26 KB
2026-03-11 16:18:51
R W Run
70.91 KB
2026-03-11 16:18:52
R W Run
35.3 KB
2026-03-11 16:18:52
R W Run
16.61 KB
2026-03-11 16:18:52
R W Run
2.57 KB
2026-03-11 16:18:52
R W Run
39.83 KB
2026-03-11 16:18:51
R W Run
70.64 KB
2026-03-11 16:18:51
R W Run
15.56 KB
2026-03-11 16:18:52
R W Run
7.33 KB
2026-03-11 16:18:52
R W Run
253 By
2026-03-11 16:18:51
R W Run
7.96 KB
2026-03-11 16:18:52
R W Run
3.23 KB
2026-03-11 16:18:52
R W Run
969 By
2026-03-11 16:18:52
R W Run
16.28 KB
2026-03-11 16:18:51
R W Run
7.22 KB
2026-03-11 16:18:51
R W Run
12.95 KB
2026-03-11 16:18:51
R W Run
6.53 KB
2026-03-11 16:18:51
R W Run
3.42 KB
2026-03-11 16:18:52
R W Run
5.84 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
4.3 KB
2026-03-11 16:18:52
R W Run
2.91 KB
2026-03-11 16:18:51
R W Run
16.46 KB
2026-03-11 16:18:52
R W Run
40.6 KB
2026-03-11 16:18:51
R W Run
20.22 KB
2026-03-11 16:18:51
R W Run
36.11 KB
2026-03-11 16:18:52
R W Run
17.01 KB
2026-03-11 16:18:51
R W Run
7.27 KB
2026-03-11 16:18:52
R W Run
6.62 KB
2026-03-11 16:18:52
R W Run
16.49 KB
2026-03-11 16:18:52
R W Run
1.79 KB
2026-03-11 16:18:52
R W Run
29.82 KB
2026-03-11 16:18:51
R W Run
6.67 KB
2026-03-11 16:18:52
R W Run
8.98 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:51
R W Run
12.01 KB
2026-03-11 16:18:51
R W Run
17.11 KB
2026-03-11 16:18:51
R W Run
6.74 KB
2026-03-11 16:18:52
R W Run
30.93 KB
2026-03-11 16:18:51
R W Run
4.99 KB
2026-03-11 16:18:51
R W Run
4.25 KB
2026-03-11 16:18:51
R W Run
24.72 KB
2026-03-11 16:18:51
R W Run
29.96 KB
2026-03-11 16:18:52
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
160 KB
2026-03-11 16:18:51
R W Run
6.72 KB
2026-03-11 16:18:52
R W Run
10.92 KB
2026-03-11 16:18:51
R W Run
4.77 KB
2026-03-11 16:18:51
R W Run
3.38 KB
2026-03-11 16:18:51
R W Run
11.18 KB
2026-03-11 16:18:51
R W Run
62.19 KB
2026-03-11 16:18:51
R W Run
2.46 KB
2026-03-11 16:18:51
R W Run
9.17 KB
2026-03-11 16:18:51
R W Run
32.15 KB
2026-03-11 16:18:51
R W Run
34.05 KB
2026-03-11 16:18:52
R W Run
7.15 KB
2026-03-11 16:18:51
R W Run
3.47 KB
2026-03-11 16:18:52
R W Run
1.87 KB
2026-03-11 16:18:52
R W Run
30.91 KB
2026-03-11 16:18:51
R W Run
7.29 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:51
R W Run
12.54 KB
2026-03-11 16:18:51
R W Run
19.12 KB
2026-03-11 16:18:51
R W Run
18.12 KB
2026-03-11 16:18:52
R W Run
39.99 KB
2026-03-11 16:18:52
R W Run
5.17 KB
2026-03-11 16:18:52
R W Run
979 By
2026-03-11 16:18:51
R W Run
18.44 KB
2026-03-11 16:18:52
R W Run
10.24 KB
2026-03-11 16:18:51
R W Run
1.77 KB
2026-03-11 16:18:52
R W Run
34.9 KB
2026-03-11 16:18:51
R W Run
7.19 KB
2026-03-11 16:18:52
R W Run
160.5 KB
2026-03-11 16:18:51
R W Run
64.27 KB
2026-03-11 16:18:51
R W Run
27.95 KB
2026-03-11 16:18:51
R W Run
4.69 KB
2026-03-11 16:18:51
R W Run
2.94 KB
2026-03-11 16:18:51
R W Run
43.13 KB
2026-03-11 16:18:52
R W Run
2.25 KB
2026-03-11 16:18:52
R W Run
22.5 KB
2026-03-11 16:18:51
R W Run
13.01 KB
2026-03-11 16:18:52
R W Run
3.27 KB
2026-03-11 16:18:51
R W Run
18 KB
2026-03-11 16:18:51
R W Run
210.4 KB
2026-03-11 16:18:52
R W Run
25.86 KB
2026-03-11 16:18:52
R W Run
115.85 KB
2026-03-11 16:18:51
R W Run
373 By
2026-03-11 16:18:52
R W Run
343 By
2026-03-11 16:18:52
R W Run
338 By
2026-03-11 16:18:51
R W Run
100.73 KB
2026-03-11 16:18:52
R W Run
130.93 KB
2026-03-11 16:18:51
R W Run
19.1 KB
2026-03-11 16:18:51
R W Run
17.41 KB
2026-03-11 16:18:52
R W Run
41.98 KB
2026-03-11 16:18:52
R W Run
400 By
2026-03-11 16:18:52
R W Run
11.1 KB
2026-03-11 16:18:52
R W Run
37.02 KB
2026-03-11 16:18:51
R W Run
2.24 KB
2026-03-11 16:18:51
R W Run
188.13 KB
2026-03-11 16:18:51
R W Run
338 By
2026-03-11 16:18:51
R W Run
38 KB
2026-03-11 16:18:51
R W Run
4.02 KB
2026-03-11 16:18:52
R W Run
5.38 KB
2026-03-11 16:18:51
R W Run
3.05 KB
2026-03-11 16:18:52
R W Run
2.61 KB
2026-03-11 16:18:51
R W Run
1.16 KB
2026-03-11 16:18:52
R W Run
4.04 KB
2026-03-11 16:18:51
R W Run
3.71 KB
2026-03-11 16:18:51
R W Run
24.6 KB
2026-03-11 16:18:51
R W Run
9.56 KB
2026-03-11 16:18:51
R W Run
346.43 KB
2026-03-11 16:18:52
R W Run
281.84 KB
2026-03-11 16:18:52
R W Run
14.95 KB
2026-03-11 16:18:51
R W Run
8.44 KB
2026-03-11 16:18:52
R W Run
168.95 KB
2026-03-11 16:18:52
R W Run
20.71 KB
2026-03-11 16:18:52
R W Run
25.27 KB
2026-03-11 16:18:51
R W Run
5.72 KB
2026-03-11 16:18:51
R W Run
4.63 KB
2026-03-11 16:18:52
R W Run
81.73 KB
2026-03-11 16:18:51
R W Run
67.18 KB
2026-03-11 16:18:51
R W Run
156.36 KB
2026-03-11 16:18:52
R W Run
55.19 KB
2026-03-11 16:18:51
R W Run
162 By
2026-03-11 16:18:51
R W Run
61.72 KB
2026-03-11 16:18:51
R W Run
216.06 KB
2026-03-11 16:18:52
R W Run
65.09 KB
2026-03-11 16:18:51
R W Run
25.24 KB
2026-03-11 16:18:52
R W Run
4.81 KB
2026-03-11 16:18:51
R W Run
6.48 KB
2026-03-11 16:18:52
R W Run
21.25 KB
2026-03-11 16:18:51
R W Run
2.79 KB
2026-03-11 16:18:52
R W Run
89.69 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:52
R W Run
3.69 KB
2026-03-11 16:18:52
R W Run
4.11 KB
2026-03-11 16:18:51
R W Run
40.74 KB
2026-03-11 16:18:51
R W Run
25.38 KB
2026-03-11 16:18:51
R W Run
43.31 KB
2026-03-11 16:18:52
R W Run
102.57 KB
2026-03-11 16:18:52
R W Run
6.18 KB
2026-03-11 16:18:51
R W Run
124.47 KB
2026-03-11 16:18:52
R W Run
35.65 KB
2026-03-11 16:18:52
R W Run
6.94 KB
2026-03-11 16:18:52
R W Run
67.04 KB
2026-03-11 16:18:52
R W Run
10.62 KB
2026-03-11 16:18:51
R W Run
289.35 KB
2026-03-11 16:18:52
R W Run
36.23 KB
2026-03-11 16:18:51
R W Run
200 By
2026-03-11 16:18:52
R W Run
200 By
2026-03-11 16:18:52
R W Run
98.29 KB
2026-03-11 16:18:52
R W Run
30.02 KB
2026-03-11 16:18:52
R W Run
19.03 KB
2026-03-11 16:18:52
R W Run
5.06 KB
2026-03-11 16:18:52
R W Run
255 By
2026-03-11 16:18:51
R W Run
22.66 KB
2026-03-11 16:18:52
R W Run
154.63 KB
2026-03-11 16:18:51
R W Run
9.68 KB
2026-03-11 16:18:51
R W Run
258 By
2026-03-11 16:18:51
R W Run
23.49 KB
2026-03-11 16:18:51
R W Run
3.16 KB
2026-03-11 16:18:51
R W Run
8.4 KB
2026-03-11 16:18:52
R W Run
441 By
2026-03-11 16:18:51
R W Run
7.39 KB
2026-03-11 16:18:51
R W Run
173 KB
2026-03-11 16:18:52
R W Run
544 By
2026-03-11 16:18:52
R W Run
4.17 KB
2026-03-11 16:18:51
R W Run
35.97 KB
2026-03-11 16:18:52
R W Run
1.69 KB
2026-03-11 16:18:51
R W Run
2.84 KB
2026-03-11 16:18:52
R W Run
6.09 KB
2026-03-11 16:18:51
R W Run
8.71 KB
2026-03-11 16:18:51
R W Run
131.84 KB
2026-03-11 16:18:51
R W Run
37.45 KB
2026-03-11 16:18:51
R W Run
173.89 KB
2026-03-11 16:18:51
R W Run
7.09 KB
2026-03-11 16:18:51
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
1.08 KB
2026-03-11 16:18:51
R W Run
69.46 KB
2026-03-11 16:18:52
R W Run
445 By
2026-03-11 16:18:51
R W Run
799 By
2026-03-11 16:18:52
R W Run
error_log
📄class-wp-embed.php
1<?php
2/**
3 * API for easily embedding rich media such as videos and images into content.
4 *
5 * @package WordPress
6 * @subpackage Embed
7 * @since 2.9.0
8 */
9#[AllowDynamicProperties]
10class WP_Embed {
11 public $handlers = array();
12 public $post_ID;
13 public $usecache = true;
14 public $linkifunknown = true;
15 public $last_attr = array();
16 public $last_url = '';
17
18 /**
19 * When a URL cannot be embedded, return false instead of returning a link
20 * or the URL.
21 *
22 * Bypasses the {@see 'embed_maybe_make_link'} filter.
23 *
24 * @var bool
25 */
26 public $return_false_on_fail = false;
27
28 /**
29 * Constructor
30 */
31 public function __construct() {
32 // Hack to get the [embed] shortcode to run before wpautop().
33 add_filter( 'the_content', array( $this, 'run_shortcode' ), 8 );
34 add_filter( 'widget_text_content', array( $this, 'run_shortcode' ), 8 );
35 add_filter( 'widget_block_content', array( $this, 'run_shortcode' ), 8 );
36
37 // Shortcode placeholder for strip_shortcodes().
38 add_shortcode( 'embed', '__return_false' );
39
40 // Attempts to embed all URLs in a post.
41 add_filter( 'the_content', array( $this, 'autoembed' ), 8 );
42 add_filter( 'widget_text_content', array( $this, 'autoembed' ), 8 );
43 add_filter( 'widget_block_content', array( $this, 'autoembed' ), 8 );
44
45 // After a post is saved, cache oEmbed items via Ajax.
46 add_action( 'edit_form_advanced', array( $this, 'maybe_run_ajax_cache' ) );
47 add_action( 'edit_page_form', array( $this, 'maybe_run_ajax_cache' ) );
48 }
49
50 /**
51 * Processes the [embed] shortcode.
52 *
53 * Since the [embed] shortcode needs to be run earlier than other shortcodes,
54 * this function removes all existing shortcodes, registers the [embed] shortcode,
55 * calls do_shortcode(), and then re-registers the old shortcodes.
56 *
57 * @global array $shortcode_tags
58 *
59 * @param string $content Content to parse.
60 * @return string Content with shortcode parsed.
61 */
62 public function run_shortcode( $content ) {
63 global $shortcode_tags;
64
65 // Back up current registered shortcodes and clear them all out.
66 $orig_shortcode_tags = $shortcode_tags;
67 remove_all_shortcodes();
68
69 add_shortcode( 'embed', array( $this, 'shortcode' ) );
70
71 // Do the shortcode (only the [embed] one is registered).
72 $content = do_shortcode( $content, true );
73
74 // Put the original shortcodes back.
75 $shortcode_tags = $orig_shortcode_tags;
76
77 return $content;
78 }
79
80 /**
81 * If a post/page was saved, then output JavaScript to make
82 * an Ajax request that will call WP_Embed::cache_oembed().
83 */
84 public function maybe_run_ajax_cache() {
85 $post = get_post();
86
87 if ( ! $post || empty( $_GET['message'] ) ) {
88 return;
89 }
90 ?>
91<script type="text/javascript">
92 jQuery( function($) {
93 $.get("<?php echo esc_url( admin_url( 'admin-ajax.php', 'relative' ) ) . '?action=oembed-cache&post=' . $post->ID; ?>");
94 } );
95</script>
96 <?php
97 }
98
99 /**
100 * Registers an embed handler.
101 *
102 * Do not use this function directly, use wp_embed_register_handler() instead.
103 *
104 * This function should probably also only be used for sites that do not support oEmbed.
105 *
106 * @param string $id An internal ID/name for the handler. Needs to be unique.
107 * @param string $regex The regex that will be used to see if this handler should be used for a URL.
108 * @param callable $callback The callback function that will be called if the regex is matched.
109 * @param int $priority Optional. Used to specify the order in which the registered handlers will be tested.
110 * Lower numbers correspond with earlier testing, and handlers with the same priority are
111 * tested in the order in which they were added to the action. Default 10.
112 */
113 public function register_handler( $id, $regex, $callback, $priority = 10 ) {
114 $this->handlers[ $priority ][ $id ] = array(
115 'regex' => $regex,
116 'callback' => $callback,
117 );
118 }
119
120 /**
121 * Unregisters a previously-registered embed handler.
122 *
123 * Do not use this function directly, use wp_embed_unregister_handler() instead.
124 *
125 * @param string $id The handler ID that should be removed.
126 * @param int $priority Optional. The priority of the handler to be removed (default: 10).
127 */
128 public function unregister_handler( $id, $priority = 10 ) {
129 unset( $this->handlers[ $priority ][ $id ] );
130 }
131
132 /**
133 * Returns embed HTML for a given URL from embed handlers.
134 *
135 * Attempts to convert a URL into embed HTML by checking the URL
136 * against the regex of the registered embed handlers.
137 *
138 * @since 5.5.0
139 *
140 * @param array $attr {
141 * Shortcode attributes. Optional.
142 *
143 * @type int $width Width of the embed in pixels.
144 * @type int $height Height of the embed in pixels.
145 * }
146 * @param string $url The URL attempting to be embedded.
147 * @return string|false The embed HTML on success, false otherwise.
148 */
149 public function get_embed_handler_html( $attr, $url ) {
150 $rawattr = $attr;
151 $attr = wp_parse_args( $attr, wp_embed_defaults( $url ) );
152
153 ksort( $this->handlers );
154 foreach ( $this->handlers as $priority => $handlers ) {
155 foreach ( $handlers as $id => $handler ) {
156 if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) {
157 $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr );
158 if ( false !== $return ) {
159 /**
160 * Filters the returned embed HTML.
161 *
162 * @since 2.9.0
163 *
164 * @see WP_Embed::shortcode()
165 *
166 * @param string $return The HTML result of the shortcode.
167 * @param string $url The embed URL.
168 * @param array $attr An array of shortcode attributes.
169 */
170 return apply_filters( 'embed_handler_html', $return, $url, $attr );
171 }
172 }
173 }
174 }
175
176 return false;
177 }
178
179 /**
180 * The do_shortcode() callback function.
181 *
182 * Attempts to convert a URL into embed HTML. Starts by checking the URL against the regex of
183 * the registered embed handlers. If none of the regex matches and it's enabled, then the URL
184 * will be given to the WP_oEmbed class.
185 *
186 * @param array $attr {
187 * Shortcode attributes. Optional.
188 *
189 * @type int $width Width of the embed in pixels.
190 * @type int $height Height of the embed in pixels.
191 * }
192 * @param string $url The URL attempting to be embedded.
193 * @return string|false The embed HTML on success, otherwise the original URL.
194 * `->maybe_make_link()` can return false on failure.
195 */
196 public function shortcode( $attr, $url = '' ) {
197 $post = get_post();
198
199 if ( empty( $url ) && ! empty( $attr['src'] ) ) {
200 $url = $attr['src'];
201 }
202
203 $this->last_url = $url;
204
205 if ( empty( $url ) ) {
206 $this->last_attr = $attr;
207 return '';
208 }
209
210 $rawattr = $attr;
211 $attr = wp_parse_args( $attr, wp_embed_defaults( $url ) );
212
213 $this->last_attr = $attr;
214
215 /*
216 * KSES converts & into &amp; and we need to undo this.
217 * See https://core.trac.wordpress.org/ticket/11311
218 */
219 $url = str_replace( '&amp;', '&', $url );
220
221 // Look for known internal handlers.
222 $embed_handler_html = $this->get_embed_handler_html( $rawattr, $url );
223 if ( false !== $embed_handler_html ) {
224 return $embed_handler_html;
225 }
226
227 $post_id = ( ! empty( $post->ID ) ) ? $post->ID : null;
228
229 // Potentially set by WP_Embed::cache_oembed().
230 if ( ! empty( $this->post_ID ) ) {
231 $post_id = $this->post_ID;
232 }
233
234 // Check for a cached result (stored as custom post or in the post meta).
235 $key_suffix = md5( $url . serialize( $attr ) );
236 $cachekey = '_oembed_' . $key_suffix;
237 $cachekey_time = '_oembed_time_' . $key_suffix;
238
239 /**
240 * Filters the oEmbed TTL value (time to live).
241 *
242 * @since 4.0.0
243 *
244 * @param int $time Time to live (in seconds).
245 * @param string $url The attempted embed URL.
246 * @param array $attr An array of shortcode attributes.
247 * @param int $post_id Post ID.
248 */
249 $ttl = apply_filters( 'oembed_ttl', DAY_IN_SECONDS, $url, $attr, $post_id );
250
251 $cache = '';
252 $cache_time = 0;
253
254 $cached_post_id = $this->find_oembed_post_id( $key_suffix );
255
256 if ( $post_id ) {
257 $cache = get_post_meta( $post_id, $cachekey, true );
258 $cache_time = get_post_meta( $post_id, $cachekey_time, true );
259
260 if ( ! $cache_time ) {
261 $cache_time = 0;
262 }
263 } elseif ( $cached_post_id ) {
264 $cached_post = get_post( $cached_post_id );
265
266 $cache = $cached_post->post_content;
267 $cache_time = strtotime( $cached_post->post_modified_gmt );
268 }
269
270 $cached_recently = ( time() - $cache_time ) < $ttl;
271
272 if ( $this->usecache || $cached_recently ) {
273 // Failures are cached. Serve one if we're using the cache.
274 if ( '{{unknown}}' === $cache ) {
275 return $this->maybe_make_link( $url );
276 }
277
278 if ( ! empty( $cache ) ) {
279 /**
280 * Filters the cached oEmbed HTML.
281 *
282 * @since 2.9.0
283 *
284 * @see WP_Embed::shortcode()
285 *
286 * @param string $cache The cached HTML result, stored in post meta.
287 * @param string $url The attempted embed URL.
288 * @param array $attr An array of shortcode attributes.
289 * @param int $post_id Post ID.
290 */
291 return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_id );
292 }
293 }
294
295 /**
296 * Filters whether to inspect the given URL for discoverable link tags.
297 *
298 * @since 2.9.0
299 * @since 4.4.0 The default value changed to true.
300 *
301 * @see WP_oEmbed::discover()
302 *
303 * @param bool $enable Whether to enable `<link>` tag discovery. Default true.
304 */
305 $attr['discover'] = apply_filters( 'embed_oembed_discover', true );
306
307 // Use oEmbed to get the HTML.
308 $html = wp_oembed_get( $url, $attr );
309
310 if ( $post_id ) {
311 if ( $html ) {
312 update_post_meta( $post_id, $cachekey, $html );
313 update_post_meta( $post_id, $cachekey_time, time() );
314 } elseif ( ! $cache ) {
315 update_post_meta( $post_id, $cachekey, '{{unknown}}' );
316 }
317 } else {
318 $has_kses = false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' );
319
320 if ( $has_kses ) {
321 // Prevent KSES from corrupting JSON in post_content.
322 kses_remove_filters();
323 }
324
325 $insert_post_args = array(
326 'post_name' => $key_suffix,
327 'post_status' => 'publish',
328 'post_type' => 'oembed_cache',
329 );
330
331 if ( $html ) {
332 if ( $cached_post_id ) {
333 wp_update_post(
334 wp_slash(
335 array(
336 'ID' => $cached_post_id,
337 'post_content' => $html,
338 )
339 )
340 );
341 } else {
342 wp_insert_post(
343 wp_slash(
344 array_merge(
345 $insert_post_args,
346 array(
347 'post_content' => $html,
348 )
349 )
350 )
351 );
352 }
353 } elseif ( ! $cache ) {
354 wp_insert_post(
355 wp_slash(
356 array_merge(
357 $insert_post_args,
358 array(
359 'post_content' => '{{unknown}}',
360 )
361 )
362 )
363 );
364 }
365
366 if ( $has_kses ) {
367 kses_init_filters();
368 }
369 }
370
371 // If there was a result, return it.
372 if ( $html ) {
373 /** This filter is documented in wp-includes/class-wp-embed.php */
374 return apply_filters( 'embed_oembed_html', $html, $url, $attr, $post_id );
375 }
376
377 // Still unknown.
378 return $this->maybe_make_link( $url );
379 }
380
381 /**
382 * Deletes all oEmbed caches. Unused by core as of 4.0.0.
383 *
384 * @param int $post_id Post ID to delete the caches for.
385 */
386 public function delete_oembed_caches( $post_id ) {
387 $post_metas = get_post_custom_keys( $post_id );
388 if ( empty( $post_metas ) ) {
389 return;
390 }
391
392 foreach ( $post_metas as $post_meta_key ) {
393 if ( str_starts_with( $post_meta_key, '_oembed_' ) ) {
394 delete_post_meta( $post_id, $post_meta_key );
395 }
396 }
397 }
398
399 /**
400 * Triggers a caching of all oEmbed results.
401 *
402 * @param int $post_id Post ID to do the caching for.
403 */
404 public function cache_oembed( $post_id ) {
405 $post = get_post( $post_id );
406
407 $post_types = get_post_types( array( 'show_ui' => true ) );
408
409 /**
410 * Filters the array of post types to cache oEmbed results for.
411 *
412 * @since 2.9.0
413 *
414 * @param string[] $post_types Array of post type names to cache oEmbed results for. Defaults to post types with `show_ui` set to true.
415 */
416 $cache_oembed_types = apply_filters( 'embed_cache_oembed_types', $post_types );
417
418 if ( empty( $post->ID ) || ! in_array( $post->post_type, $cache_oembed_types, true ) ) {
419 return;
420 }
421
422 // Trigger a caching.
423 if ( ! empty( $post->post_content ) ) {
424 $this->post_ID = $post->ID;
425 $this->usecache = false;
426
427 $content = $this->run_shortcode( $post->post_content );
428 $this->autoembed( $content );
429
430 $this->usecache = true;
431 }
432 }
433
434 /**
435 * Passes any unlinked URLs that are on their own line to WP_Embed::shortcode() for potential embedding.
436 *
437 * @see WP_Embed::autoembed_callback()
438 *
439 * @param string $content The content to be searched.
440 * @return string Potentially modified $content.
441 */
442 public function autoembed( $content ) {
443 // Replace line breaks from all HTML elements with placeholders.
444 $content = wp_replace_in_html_tags( $content, array( "\n" => '<!-- wp-line-break -->' ) );
445
446 if ( preg_match( '#(^|\s|>)https?://#i', $content ) ) {
447 // Find URLs on their own line.
448 $content = preg_replace_callback( '|^(\s*)(https?://[^\s<>"]+)(\s*)$|im', array( $this, 'autoembed_callback' ), $content );
449 // Find URLs in their own paragraph.
450 $content = preg_replace_callback( '|(<p(?: [^>]*)?>\s*)(https?://[^\s<>"]+)(\s*<\/p>)|i', array( $this, 'autoembed_callback' ), $content );
451 }
452
453 // Put the line breaks back.
454 return str_replace( '<!-- wp-line-break -->', "\n", $content );
455 }
456
457 /**
458 * Callback function for WP_Embed::autoembed().
459 *
460 * @param array $matches A regex match array.
461 * @return string The embed HTML on success, otherwise the original URL.
462 */
463 public function autoembed_callback( $matches ) {
464 $oldval = $this->linkifunknown;
465 $this->linkifunknown = false;
466 $return = $this->shortcode( array(), $matches[2] );
467 $this->linkifunknown = $oldval;
468
469 return $matches[1] . $return . $matches[3];
470 }
471
472 /**
473 * Conditionally makes a hyperlink based on an internal class variable.
474 *
475 * @param string $url URL to potentially be linked.
476 * @return string|false Linked URL or the original URL. False if 'return_false_on_fail' is true.
477 */
478 public function maybe_make_link( $url ) {
479 if ( $this->return_false_on_fail ) {
480 return false;
481 }
482
483 $output = ( $this->linkifunknown ) ? '<a href="' . esc_url( $url ) . '">' . esc_html( $url ) . '</a>' : $url;
484
485 /**
486 * Filters the returned, maybe-linked embed URL.
487 *
488 * @since 2.9.0
489 *
490 * @param string $output The linked or original URL.
491 * @param string $url The original URL.
492 */
493 return apply_filters( 'embed_maybe_make_link', $output, $url );
494 }
495
496 /**
497 * Finds the oEmbed cache post ID for a given cache key.
498 *
499 * @since 4.9.0
500 *
501 * @param string $cache_key oEmbed cache key.
502 * @return int|null Post ID on success, null on failure.
503 */
504 public function find_oembed_post_id( $cache_key ) {
505 $cache_group = 'oembed_cache_post';
506 $oembed_post_id = wp_cache_get( $cache_key, $cache_group );
507
508 if ( $oembed_post_id && 'oembed_cache' === get_post_type( $oembed_post_id ) ) {
509 return $oembed_post_id;
510 }
511
512 $oembed_post_query = new WP_Query(
513 array(
514 'post_type' => 'oembed_cache',
515 'post_status' => 'publish',
516 'name' => $cache_key,
517 'posts_per_page' => 1,
518 'no_found_rows' => true,
519 'cache_results' => true,
520 'update_post_meta_cache' => false,
521 'update_post_term_cache' => false,
522 'lazy_load_term_meta' => false,
523 )
524 );
525
526 if ( ! empty( $oembed_post_query->posts ) ) {
527 // Note: 'fields' => 'ids' is not being used in order to cache the post object as it will be needed.
528 $oembed_post_id = $oembed_post_query->posts[0]->ID;
529 wp_cache_set( $cache_key, $oembed_post_id, $cache_group );
530
531 return $oembed_post_id;
532 }
533
534 return null;
535 }
536}
537