@@ -45,6 +45,72 @@ public function __construct() {
4545 // After a post is saved, cache oEmbed items via Ajax.
4646 add_action ( 'edit_form_advanced ' , array ( $ this , 'maybe_run_ajax_cache ' ) );
4747 add_action ( 'edit_page_form ' , array ( $ this , 'maybe_run_ajax_cache ' ) );
48+
49+ // Register oEmbed meta cleanup on post save.
50+ add_action ( 'save_post ' , array ( $ this , 'maybe_delete_orphaned_oembed_meta ' ), 10 , 3 );
51+ }
52+
53+ /**
54+ * Deletes orphaned oEmbed post meta when a post is saved.
55+ *
56+ * Removes any oEmbed cache post meta entries that no longer correspond to
57+ * an embed block or auto-embed URL in the post content. This helps prevent
58+ * orphaned oEmbed cache data from accumulating when embeds are removed.
59+ *
60+ * @since 6.6.0
61+ *
62+ * @param int $post_id Post ID.
63+ * @param WP_Post $post Post object.
64+ */
65+ public function maybe_delete_orphaned_oembed_meta ( $ post_id , $ post ) {
66+ // Only run for posts, not revisions or autosaves.
67+ if ( wp_is_post_revision ( $ post_id ) || wp_is_post_autosave ( $ post_id ) ) {
68+ return ;
69+ }
70+
71+ $ content = $ post ->post_content ;
72+ $ embed_urls = array ();
73+
74+ // Collect embed URLs from Gutenberg embed blocks.
75+ if ( function_exists ( 'has_blocks ' ) && has_blocks ( $ content ) ) {
76+ $ blocks = parse_blocks ( $ content );
77+ foreach ( $ blocks as $ block ) {
78+ if ( isset ( $ block ['blockName ' ] ) && 'core/embed ' === $ block ['blockName ' ] && ! empty ( $ block ['attrs ' ]['url ' ] ) ) {
79+ $ embed_urls [] = $ block ['attrs ' ]['url ' ];
80+ }
81+ }
82+ }
83+
84+ // Collect classic auto-embed URLs.
85+ $ lines = preg_split ( '/\r\n|\r|\n/ ' , $ content );
86+ foreach ( $ lines as $ line ) {
87+ $ line = trim ( $ line );
88+ if ( filter_var ( $ line , FILTER_VALIDATE_URL ) ) {
89+ $ embed_urls [] = $ line ;
90+ }
91+ }
92+ $ embed_urls = array_unique ( $ embed_urls );
93+
94+ // Remove orphaned oEmbed meta.
95+ $ meta = get_post_meta ( $ post_id );
96+ foreach ( $ meta as $ meta_key => $ values ) {
97+ if ( 0 === strpos ( $ meta_key , '_oembed_ ' ) ) {
98+ $ key_suffix = substr ( $ meta_key , 8 );
99+ $ found = false ;
100+ foreach ( $ embed_urls as $ url ) {
101+ $ expected_suffix = md5 ( $ url . serialize ( wp_embed_defaults ( $ url ) ) );
102+ if ( $ key_suffix === $ expected_suffix ) {
103+ $ found = true ;
104+ break ;
105+ }
106+ }
107+ if ( ! $ found ) {
108+ delete_post_meta ( $ post_id , $ meta_key );
109+ $ time_key = '_oembed_time_ ' . $ key_suffix ;
110+ delete_post_meta ( $ post_id , $ time_key );
111+ }
112+ }
113+ }
48114 }
49115
50116 /**
0 commit comments