@@ -26,88 +26,90 @@ class BCC_Keep_Translated_Posts_Status_Same_As_Original {
2626 /**
2727 * Initialize the plugin.
2828 */
29- private function __construct (){
30-
29+ private function __construct () {
3130 $ this ->plugin = plugin_basename ( __FILE__ );
3231 $ this ->plugin_slug = plugin_basename ( __DIR__ );
3332
3433 $ this ->_updater = new BCC_Keep_Translated_Posts_Status_Same_As_Original_Updater ( $ this ->plugin , $ this ->plugin_slug , $ this ->plugin_version , $ this ->plugin_name );
3534
36- /**
37- * 1) Guardrail at save-time: before WordPress writes to DB, make translation status match its source.
38- */
39- add_filter ('wp_insert_post_data ' , function ( $ data , $ postarr ) {
40- // Only operate on posts (incl. CPTs) that already have an ID (updates) — new posts will be handled by the WPML hook below.
41- $ maybe_id = isset ($ postarr ['ID ' ]) ? (int ) $ postarr ['ID ' ] : 0 ;
42- if ( $ maybe_id <= 0 ) {
43- return $ data ;
44- }
45-
46- // Skip autosaves/revisions
47- if ( defined ('DOING_AUTOSAVE ' ) && DOING_AUTOSAVE ) { return $ data ; }
48- if ( wp_is_post_revision ( $ maybe_id ) ) { return $ data ; }
35+ add_filter ( 'wp_insert_post_data ' , array ( $ this , 'bcc_filter_on_wp_insert_post_data ' ), 20 , 2 );
36+ add_action ('wpml_pro_translation_completed ' , array ( $ this , 'bcc_action_wpml_translation_completed ' ), 20 );
37+ add_action ( 'admin_menu ' , array ( $ this , 'bcc_post_status_mismatch_settings_page ' ) );
38+ }
4939
50- $ source = bcc_wpml_get_source_post ( $ maybe_id );
51- if ( ! $ source ) {
52- // This is the source itself, or we can't find it — nothing to sync.
53- return $ data ;
54- }
40+ /**
41+ * 1) Guardrail at save-time: before WordPress writes to DB, make translation status match its source.
42+ */
43+ function bcc_filter_on_wp_insert_post_data ( $ data , $ postarr ) {
44+ // Only operate on posts (incl. CPTs) that already have an ID (updates) — new posts will be handled by the WPML hook below.
45+ $ maybe_id = isset ($ postarr ['ID ' ]) ? (int ) $ postarr ['ID ' ] : 0 ;
46+ if ( $ maybe_id <= 0 ) {
47+ return $ data ;
48+ }
5549
56- $ source_status = $ source ->post_status ; // 'draft', 'publish', 'pending', 'private', etc.
57- if ( ! empty ($ source_status ) && $ data ['post_status ' ] !== $ source_status && $ data ['post_status ' ] != 'trash ' ) {
58- $ data ['post_status ' ] = $ source_status ;
59- }
50+ // Skip autosaves/revisions
51+ if ( defined ('DOING_AUTOSAVE ' ) && DOING_AUTOSAVE ) { return $ data ; }
52+ if ( wp_is_post_revision ( $ maybe_id ) ) { return $ data ; }
6053
54+ $ source = bcc_wpml_get_source_post ( $ maybe_id );
55+ if ( ! $ source ) {
56+ // This is the source itself, or we can't find it — nothing to sync.
6157 return $ data ;
62- }, 20 , 2 );
63-
64- /**
65- * 2) When WPML TM (Phrase) finishes a translation and creates/updates the translated post,
66- * force status to match the source.
67- *
68- * Hook signature: do_action( 'wpml_pro_translation_completed', $post_id, $fields, $job );
69- * This fires on imports from translation services like Phrase.
70- */
71- add_action ('wpml_pro_translation_completed ' , function ( $ translated_post_id ) {
72- static $ in_progress = [];
73-
74- $ translated_post_id = (int ) $ translated_post_id ;
75- if ( $ translated_post_id <= 0 ) { return ; }
76-
77- // Prevent loops if wp_update_post triggers the same hook chain
78- if ( isset ($ in_progress [$ translated_post_id ]) ) { return ; }
79- $ in_progress [$ translated_post_id ] = true ;
80-
81- $ source = bcc_wpml_get_source_post ( $ translated_post_id );
82- if ( $ source ) {
83- $ source_status = $ source ->post_status ;
84- $ translated = get_post ( $ translated_post_id );
85-
86- if ( $ translated && $ translated ->post_status !== $ source_status ) {
87- // Update translated post to match source status
88- wp_update_post (array (
89- 'ID ' => $ translated_post_id ,
90- 'post_status ' => $ source_status ,
91- ));
92- }
58+ }
59+
60+ $ source_status = $ source ->post_status ; // 'draft', 'publish', 'pending', 'private', etc.
61+ if ( ! empty ($ source_status ) && $ data ['post_status ' ] !== $ source_status && $ data ['post_status ' ] != 'trash ' ) {
62+ $ data ['post_status ' ] = $ source_status ;
63+ }
64+
65+ return $ data ;
66+ }
67+
68+ /**
69+ * 2) When WPML TM (Phrase) finishes a translation and creates/updates the translated post,
70+ * force status to match the source.
71+ *
72+ * Hook signature: do_action( 'wpml_pro_translation_completed', $post_id, $fields, $job );
73+ * This fires on imports from translation services like Phrase.
74+ */
75+ function bcc_action_wpml_translation_completed ( $ translated_post_id ) {
76+ static $ in_progress = [];
77+
78+ $ translated_post_id = (int ) $ translated_post_id ;
79+ if ( $ translated_post_id <= 0 ) { return ; }
80+
81+ // Prevent loops if wp_update_post triggers the same hook chain
82+ if ( isset ($ in_progress [$ translated_post_id ]) ) { return ; }
83+ $ in_progress [$ translated_post_id ] = true ;
84+
85+ $ source = bcc_wpml_get_source_post ( $ translated_post_id );
86+ if ( $ source ) {
87+ $ source_status = $ source ->post_status ;
88+ $ translated = get_post ( $ translated_post_id );
89+
90+ if ( $ translated && $ translated ->post_status !== $ source_status ) {
91+ // Update translated post to match source status
92+ wp_update_post (array (
93+ 'ID ' => $ translated_post_id ,
94+ 'post_status ' => $ source_status ,
95+ ));
9396 }
97+ }
9498
95- unset($ in_progress [$ translated_post_id ]);
96- }, 20 );
97-
98- /**
99- * Admin menu.
100- */
101- add_action ( 'admin_menu ' , function () {
102- add_options_page (
103- 'Post status mismatch ' ,
104- 'Post status mismatch ' ,
105- 'manage_options ' ,
106- 'bcc-post-status-mismatch ' ,
107- 'bcc_post_status_mismatch_page '
108- );
109- } );
99+ unset($ in_progress [$ translated_post_id ]);
100+ }
110101
102+ /**
103+ * Admin menu.
104+ */
105+ function bcc_post_status_mismatch_settings_page () {
106+ add_options_page (
107+ 'Post status mismatch ' ,
108+ 'Post status mismatch ' ,
109+ 'manage_options ' ,
110+ 'bcc-post-status-mismatch ' ,
111+ array ( $ this , 'bcc_post_status_mismatch_page ' )
112+ );
111113 }
112114
113115 /**
@@ -196,7 +198,7 @@ function bcc_post_status_mismatch_page() {
196198
197199 $ translation = get_post ($ details ->element_id );
198200
199- if ( $ translation ->post_status !== $ source ->post_status ) {
201+ if ( $ translation && $ source && $ translation ->post_status !== $ source ->post_status ) {
200202 $ rows [] = array (
201203 'ptype ' => $ post_type ,
202204 'title ' => get_the_title ( $ translation ->ID ),
0 commit comments