Changeset 3203556
- Timestamp:
- 12/06/2024 11:10:22 AM (4 months ago)
- Location:
- content-update-scheduler
- Files:
-
- 2 edited
- 3 copied
Legend:
- Unmodified
- Added
- Removed
-
content-update-scheduler/tags/2.3.5/content-update-scheduler.php
r3194088 r3203556 8 8 * Author: Infinitnet 9 9 * Author URI: https://infinitnet.io/ 10 * Version: 2.3. 410 * Version: 2.3.5 11 11 * License: GPLv3 12 12 * Text Domain: content-update-scheduler … … 88 88 89 89 /** 90 * Handles the CSS copying for Elementor and Oxygen plugins. 91 * 92 * @param int $source_post_id The source post ID. 93 * @param int $destination_post_id The destination post ID. 94 * 95 * @return void 96 */ 97 private static function handle_plugin_css_copy($source_post_id, $destination_post_id) 98 { 99 // Elementor plugin active. 100 if (in_array('elementor/elementor.php', apply_filters('active_plugins', get_option('active_plugins')))) { 90 * Copies Elementor-specific data between posts 91 * 92 * @param int $source_id Source post ID 93 * @param int $destination_id Destination post ID 94 * @return bool Success status 95 */ 96 private static function copy_elementor_data($source_id, $destination_id) { 97 // Early exit if Elementor isn't active 98 if (!defined('ELEMENTOR_VERSION')) { 99 return false; 100 } 101 102 try { 103 // Core Elementor meta keys that must be preserved 104 $elementor_meta_keys = [ 105 '_elementor_data', 106 '_elementor_edit_mode', 107 '_elementor_page_settings', 108 '_elementor_version', 109 '_elementor_template_type', 110 '_elementor_controls_usage' 111 ]; 112 113 // Get all meta at once for efficiency 114 $source_meta = get_post_meta($source_id); 115 116 foreach ($elementor_meta_keys as $key) { 117 if (!isset($source_meta[$key][0])) { 118 continue; 119 } 120 121 $value = $source_meta[$key][0]; 122 123 // Special handling for Elementor's JSON data 124 if ($key === '_elementor_data') { 125 // Ensure valid JSON 126 $decoded = json_decode($value); 127 if (json_last_error() === JSON_ERROR_NONE) { 128 // Preserve exact JSON structure with proper slashing 129 update_post_meta($destination_id, $key, wp_slash($value)); 130 } else { 131 error_log(sprintf( 132 'Content Update Scheduler: Invalid Elementor JSON in post %d', 133 $source_id 134 )); 135 } 136 continue; 137 } 138 139 // Copy other Elementor meta directly 140 update_post_meta($destination_id, $key, maybe_unserialize($value)); 141 } 142 143 // Copy Elementor CSS file 101 144 $upload_dir = wp_upload_dir(); 102 $source_css = $upload_dir['basedir'] . '/elementor/css/post-' . $source_ post_id . '.css';103 $dest ination_css = $upload_dir['basedir'] . '/elementor/css/post-' . $destination_post_id . '.css';104 145 $source_css = $upload_dir['basedir'] . '/elementor/css/post-' . $source_id . '.css'; 146 $dest_css = $upload_dir['basedir'] . '/elementor/css/post-' . $destination_id . '.css'; 147 105 148 if (file_exists($source_css)) { 106 copy($source_css, $destination_css); 107 } 108 109 } 110 111 // Oxygen plugin active. 112 if (in_array('oxygen/functions.php', apply_filters('active_plugins', get_option('active_plugins')))) { 149 @copy($source_css, $dest_css); 150 } 151 152 return true; 153 154 } catch (Exception $e) { 155 error_log(sprintf( 156 'Content Update Scheduler: Error copying Elementor data: %s', 157 $e->getMessage() 158 )); 159 return false; 160 } 161 } 162 163 /** 164 * Handles the Oxygen builder CSS copying 165 * 166 * @param int $source_id Source post ID 167 * @param int $destination_id Destination post ID 168 * @return bool Success status 169 */ 170 private static function handle_wpml_relationships($source_id, $destination_id, $is_publishing = false) { 171 // Early exit if WPML isn't active 172 if (!defined('ICL_SITEPRESS_VERSION')) { 173 return false; 174 } 175 176 try { 177 // Basic validation 178 $post_type = get_post_type($source_id); 179 if (!$post_type || $post_type !== get_post_type($destination_id)) { 180 return false; 181 } 182 183 $element_type = 'post_' . $post_type; 184 185 // Get source language details 186 $source_details = apply_filters('wpml_element_language_details', null, array( 187 'element_id' => $source_id, 188 'element_type' => $element_type 189 )); 190 191 if (!$source_details) { 192 return false; 193 } 194 195 /** 196 * Filter whether to create new translation group 197 * 198 * @param bool $create_new_group Whether to create new translation group 199 * @param int $source_id Source post ID 200 * @param int $destination_id Destination post ID 201 * @param bool $is_publishing Whether this is a publish operation 202 */ 203 $create_new_group = apply_filters( 204 'content_update_scheduler_wpml_new_translation_group', 205 !$is_publishing, 206 $source_id, 207 $destination_id, 208 $is_publishing 209 ); 210 211 // Set language details 212 do_action('wpml_set_element_language_details', array( 213 'element_id' => $destination_id, 214 'element_type' => $element_type, 215 'trid' => $create_new_group ? null : apply_filters('wpml_element_trid', null, $source_id, $element_type), 216 'language_code' => $source_details->language_code, 217 'source_language_code' => $source_details->source_language_code 218 )); 219 220 // Copy essential WPML meta 221 $wpml_meta_keys = array( 222 '_wpml_media_featured', 223 '_wpml_media_duplicate', 224 '_wpml_media_processed' 225 ); 226 227 foreach ($wpml_meta_keys as $meta_key) { 228 $value = get_post_meta($source_id, $meta_key, true); 229 if ($value !== '') { 230 update_post_meta($destination_id, $meta_key, $value); 231 } 232 } 233 234 /** 235 * Fires after WPML relationships have been handled 236 * 237 * @param int $source_id Source post ID 238 * @param int $destination_id Destination post ID 239 * @param bool $is_publishing Whether this is a publish operation 240 */ 241 do_action('content_update_scheduler_after_wpml_handling', 242 $source_id, 243 $destination_id, 244 $is_publishing 245 ); 246 247 return true; 248 249 } catch (Exception $e) { 250 error_log(sprintf( 251 'Content Update Scheduler: WPML handling error for posts %d->%d: %s', 252 $source_id, 253 $destination_id, 254 $e->getMessage() 255 )); 256 return false; 257 } 258 } 259 260 private static function copy_oxygen_data($source_id, $destination_id) { 261 // Early exit if Oxygen isn't active 262 if (!in_array('oxygen/functions.php', apply_filters('active_plugins', get_option('active_plugins')))) { 263 return false; 264 } 265 266 try { 113 267 $upload_dir = wp_upload_dir(); 114 $dir = $upload_dir['basedir'] . '/oxygen/css/' . get_post_field('post_name', $source_post_id) . '-' . $source_post_id . '.css'; 115 $chdir = $upload_dir['basedir'] . '/oxygen/css/' . get_post_field('post_name', $destination_post_id) . '-' . $destination_post_id . '.css'; 116 117 if (!file_exists($chdir)) { 118 fopen($chdir, "w"); 119 } 120 if (!file_exists($dir)) { 121 fopen($dir, "w"); 122 } 123 copy($dir, $chdir); 268 $source_css = $upload_dir['basedir'] . '/oxygen/css/' . 269 get_post_field('post_name', $source_id) . '-' . $source_id . '.css'; 270 $dest_css = $upload_dir['basedir'] . '/oxygen/css/' . 271 get_post_field('post_name', $destination_id) . '-' . $destination_id . '.css'; 272 273 // Create destination file if it doesn't exist 274 if (!file_exists($dest_css)) { 275 @touch($dest_css); 276 } 277 278 // Copy CSS if source exists 279 if (file_exists($source_css)) { 280 @copy($source_css, $dest_css); 281 } 282 283 return true; 284 285 } catch (Exception $e) { 286 error_log(sprintf( 287 'Content Update Scheduler: Error copying Oxygen data: %s', 288 $e->getMessage() 289 )); 290 return false; 124 291 } 125 292 } … … 804 971 } 805 972 806 self::handle_plugin_css_copy($post->ID, $new_post_id); 973 self::copy_elementor_data($post->ID, $new_post_id); 974 self::copy_oxygen_data($post->ID, $new_post_id); 975 self::handle_wpml_relationships($post->ID, $new_post_id); 807 976 808 977 // copy meta and terms over to the new post. … … 886 1055 } 887 1056 888 public static function copy_meta_and_terms($source_post_id, $destination_post_id, $restore_references = false) 1057 /** 1058 * Copies meta and terms from one post to another 1059 * 1060 * @param int $source_post_id The post from which to copy. 1061 * @param int $destination_post_id The post which will get the meta and terms. 1062 * @param bool $restore_references Whether to restore references to the original post ID. 1063 * 1064 * @return void 1065 */ 1066 private static function copy_meta_and_terms($source_post_id, $destination_post_id, $restore_references = false) 889 1067 { 890 1068 $source_post = get_post($source_post_id); 891 1069 $destination_post = get_post($destination_post_id); 892 1070 893 // abort if any of the ids is not a post.894 if (! $source_post || !$destination_post) {1071 // Abort if any of the ids is not a post. 1072 if (!$source_post || !$destination_post) { 895 1073 return; 896 1074 } 897 1075 898 // Copy meta 899 $meta = get_post_meta($source_post->ID); 900 foreach ($meta as $key => $values) { 901 delete_post_meta($destination_post->ID, $key); 902 foreach ($values as $value) { 903 $processed_value = self::copy_meta_value($value); 904 905 if ($restore_references && is_string($processed_value) && 906 strpos($processed_value, (string)$source_post->ID) !== false) { 907 $processed_value = str_replace( 908 (string)$source_post->ID, 909 (string)$destination_post->ID, 910 $processed_value 911 ); 912 } 913 914 add_post_meta($destination_post->ID, $key, $processed_value); 915 } 916 } 917 918 919 // and now for copying the terms. 920 $taxonomies = get_object_taxonomies($source_post->post_type); 921 foreach ($taxonomies as $taxonomy) { 922 $post_terms = wp_get_object_terms($source_post->ID, $taxonomy, array( 923 'orderby' => 'term_order', 924 )); 925 $terms = array(); 926 foreach ($post_terms as $term) { 927 $terms[] = $term->slug; 928 } 929 // reset taxonomy to empty. 930 wp_set_object_terms($destination_post->ID, null, $taxonomy); 931 // then add new terms. 932 wp_set_object_terms($destination_post->ID, $terms, $taxonomy); 1076 // Store current kses status and temporarily disable filters. 1077 $should_filter = ! current_filter('content_save_pre'); 1078 if ($should_filter) { 1079 remove_filter('content_save_pre', 'wp_filter_post_kses'); 1080 remove_filter('db_insert_value', 'wp_filter_kses'); 1081 } 1082 1083 try { 1084 // Copy meta. 1085 $meta = get_post_meta($source_post->ID); 1086 foreach ($meta as $key => $values) { 1087 delete_post_meta($destination_post->ID, $key); 1088 foreach ($values as $value) { 1089 $processed_value = self::copy_meta_value($value); 1090 1091 if ($restore_references && is_string($processed_value) && 1092 strpos($processed_value, (string)$source_post->ID) !== false) { 1093 $processed_value = str_replace( 1094 (string)$source_post->ID, 1095 (string)$destination_post->ID, 1096 $processed_value 1097 ); 1098 } 1099 1100 add_post_meta($destination_post->ID, $key, $processed_value); 1101 } 1102 } 1103 1104 // Copy terms. 1105 $taxonomies = get_object_taxonomies($source_post->post_type); 1106 foreach ($taxonomies as $taxonomy) { 1107 $post_terms = wp_get_object_terms($source_post->ID, $taxonomy, array( 1108 'orderby' => 'term_order', 1109 )); 1110 $terms = array(); 1111 foreach ($post_terms as $term) { 1112 $terms[] = $term->slug; 1113 } 1114 wp_set_object_terms($destination_post->ID, null, $taxonomy); 1115 wp_set_object_terms($destination_post->ID, $terms, $taxonomy); 1116 } 1117 } finally { 1118 // Restore filters if they were active. 1119 if ($should_filter) { 1120 add_filter('content_save_pre', 'wp_filter_post_kses'); 1121 add_filter('db_insert_value', 'wp_filter_kses'); 1122 } 933 1123 } 934 1124 } … … 1104 1294 $original_stock_quantity = get_post_meta($orig->ID, '_stock', true); 1105 1295 1106 self::handle_plugin_css_copy($post->ID, $orig_id); 1296 self::copy_elementor_data($post->ID, $orig_id); 1297 self::copy_oxygen_data($post->ID, $orig_id); 1298 self::handle_wpml_relationships($post->ID, $orig_id, true); 1107 1299 1108 1300 /** -
content-update-scheduler/tags/2.3.5/readme.txt
r3194096 r3203556 3 3 Tags: schedule, scheduling, update, republish, publication 4 4 Requires at least: 5.0 5 Tested up to: 6.7 6 Stable tag: 2.3. 45 Tested up to: 6.7.1 6 Stable tag: 2.3.5 7 7 Requires PHP: 7.4 8 8 License: GPLv3 … … 62 62 63 63 == Changelog == 64 65 = 2.3.5 = 66 * refactor: Improve meta and terms copying with filter management and visibility 67 * refactor: Improve Elementor and Oxygen data copying with focused, robust methods 68 * refactor: Add WPML relationship handling for duplicated posts 64 69 65 70 = 2.3.4 = -
content-update-scheduler/trunk/content-update-scheduler.php
r3194088 r3203556 8 8 * Author: Infinitnet 9 9 * Author URI: https://infinitnet.io/ 10 * Version: 2.3. 410 * Version: 2.3.5 11 11 * License: GPLv3 12 12 * Text Domain: content-update-scheduler … … 88 88 89 89 /** 90 * Handles the CSS copying for Elementor and Oxygen plugins. 91 * 92 * @param int $source_post_id The source post ID. 93 * @param int $destination_post_id The destination post ID. 94 * 95 * @return void 96 */ 97 private static function handle_plugin_css_copy($source_post_id, $destination_post_id) 98 { 99 // Elementor plugin active. 100 if (in_array('elementor/elementor.php', apply_filters('active_plugins', get_option('active_plugins')))) { 90 * Copies Elementor-specific data between posts 91 * 92 * @param int $source_id Source post ID 93 * @param int $destination_id Destination post ID 94 * @return bool Success status 95 */ 96 private static function copy_elementor_data($source_id, $destination_id) { 97 // Early exit if Elementor isn't active 98 if (!defined('ELEMENTOR_VERSION')) { 99 return false; 100 } 101 102 try { 103 // Core Elementor meta keys that must be preserved 104 $elementor_meta_keys = [ 105 '_elementor_data', 106 '_elementor_edit_mode', 107 '_elementor_page_settings', 108 '_elementor_version', 109 '_elementor_template_type', 110 '_elementor_controls_usage' 111 ]; 112 113 // Get all meta at once for efficiency 114 $source_meta = get_post_meta($source_id); 115 116 foreach ($elementor_meta_keys as $key) { 117 if (!isset($source_meta[$key][0])) { 118 continue; 119 } 120 121 $value = $source_meta[$key][0]; 122 123 // Special handling for Elementor's JSON data 124 if ($key === '_elementor_data') { 125 // Ensure valid JSON 126 $decoded = json_decode($value); 127 if (json_last_error() === JSON_ERROR_NONE) { 128 // Preserve exact JSON structure with proper slashing 129 update_post_meta($destination_id, $key, wp_slash($value)); 130 } else { 131 error_log(sprintf( 132 'Content Update Scheduler: Invalid Elementor JSON in post %d', 133 $source_id 134 )); 135 } 136 continue; 137 } 138 139 // Copy other Elementor meta directly 140 update_post_meta($destination_id, $key, maybe_unserialize($value)); 141 } 142 143 // Copy Elementor CSS file 101 144 $upload_dir = wp_upload_dir(); 102 $source_css = $upload_dir['basedir'] . '/elementor/css/post-' . $source_ post_id . '.css';103 $dest ination_css = $upload_dir['basedir'] . '/elementor/css/post-' . $destination_post_id . '.css';104 145 $source_css = $upload_dir['basedir'] . '/elementor/css/post-' . $source_id . '.css'; 146 $dest_css = $upload_dir['basedir'] . '/elementor/css/post-' . $destination_id . '.css'; 147 105 148 if (file_exists($source_css)) { 106 copy($source_css, $destination_css); 107 } 108 109 } 110 111 // Oxygen plugin active. 112 if (in_array('oxygen/functions.php', apply_filters('active_plugins', get_option('active_plugins')))) { 149 @copy($source_css, $dest_css); 150 } 151 152 return true; 153 154 } catch (Exception $e) { 155 error_log(sprintf( 156 'Content Update Scheduler: Error copying Elementor data: %s', 157 $e->getMessage() 158 )); 159 return false; 160 } 161 } 162 163 /** 164 * Handles the Oxygen builder CSS copying 165 * 166 * @param int $source_id Source post ID 167 * @param int $destination_id Destination post ID 168 * @return bool Success status 169 */ 170 private static function handle_wpml_relationships($source_id, $destination_id, $is_publishing = false) { 171 // Early exit if WPML isn't active 172 if (!defined('ICL_SITEPRESS_VERSION')) { 173 return false; 174 } 175 176 try { 177 // Basic validation 178 $post_type = get_post_type($source_id); 179 if (!$post_type || $post_type !== get_post_type($destination_id)) { 180 return false; 181 } 182 183 $element_type = 'post_' . $post_type; 184 185 // Get source language details 186 $source_details = apply_filters('wpml_element_language_details', null, array( 187 'element_id' => $source_id, 188 'element_type' => $element_type 189 )); 190 191 if (!$source_details) { 192 return false; 193 } 194 195 /** 196 * Filter whether to create new translation group 197 * 198 * @param bool $create_new_group Whether to create new translation group 199 * @param int $source_id Source post ID 200 * @param int $destination_id Destination post ID 201 * @param bool $is_publishing Whether this is a publish operation 202 */ 203 $create_new_group = apply_filters( 204 'content_update_scheduler_wpml_new_translation_group', 205 !$is_publishing, 206 $source_id, 207 $destination_id, 208 $is_publishing 209 ); 210 211 // Set language details 212 do_action('wpml_set_element_language_details', array( 213 'element_id' => $destination_id, 214 'element_type' => $element_type, 215 'trid' => $create_new_group ? null : apply_filters('wpml_element_trid', null, $source_id, $element_type), 216 'language_code' => $source_details->language_code, 217 'source_language_code' => $source_details->source_language_code 218 )); 219 220 // Copy essential WPML meta 221 $wpml_meta_keys = array( 222 '_wpml_media_featured', 223 '_wpml_media_duplicate', 224 '_wpml_media_processed' 225 ); 226 227 foreach ($wpml_meta_keys as $meta_key) { 228 $value = get_post_meta($source_id, $meta_key, true); 229 if ($value !== '') { 230 update_post_meta($destination_id, $meta_key, $value); 231 } 232 } 233 234 /** 235 * Fires after WPML relationships have been handled 236 * 237 * @param int $source_id Source post ID 238 * @param int $destination_id Destination post ID 239 * @param bool $is_publishing Whether this is a publish operation 240 */ 241 do_action('content_update_scheduler_after_wpml_handling', 242 $source_id, 243 $destination_id, 244 $is_publishing 245 ); 246 247 return true; 248 249 } catch (Exception $e) { 250 error_log(sprintf( 251 'Content Update Scheduler: WPML handling error for posts %d->%d: %s', 252 $source_id, 253 $destination_id, 254 $e->getMessage() 255 )); 256 return false; 257 } 258 } 259 260 private static function copy_oxygen_data($source_id, $destination_id) { 261 // Early exit if Oxygen isn't active 262 if (!in_array('oxygen/functions.php', apply_filters('active_plugins', get_option('active_plugins')))) { 263 return false; 264 } 265 266 try { 113 267 $upload_dir = wp_upload_dir(); 114 $dir = $upload_dir['basedir'] . '/oxygen/css/' . get_post_field('post_name', $source_post_id) . '-' . $source_post_id . '.css'; 115 $chdir = $upload_dir['basedir'] . '/oxygen/css/' . get_post_field('post_name', $destination_post_id) . '-' . $destination_post_id . '.css'; 116 117 if (!file_exists($chdir)) { 118 fopen($chdir, "w"); 119 } 120 if (!file_exists($dir)) { 121 fopen($dir, "w"); 122 } 123 copy($dir, $chdir); 268 $source_css = $upload_dir['basedir'] . '/oxygen/css/' . 269 get_post_field('post_name', $source_id) . '-' . $source_id . '.css'; 270 $dest_css = $upload_dir['basedir'] . '/oxygen/css/' . 271 get_post_field('post_name', $destination_id) . '-' . $destination_id . '.css'; 272 273 // Create destination file if it doesn't exist 274 if (!file_exists($dest_css)) { 275 @touch($dest_css); 276 } 277 278 // Copy CSS if source exists 279 if (file_exists($source_css)) { 280 @copy($source_css, $dest_css); 281 } 282 283 return true; 284 285 } catch (Exception $e) { 286 error_log(sprintf( 287 'Content Update Scheduler: Error copying Oxygen data: %s', 288 $e->getMessage() 289 )); 290 return false; 124 291 } 125 292 } … … 804 971 } 805 972 806 self::handle_plugin_css_copy($post->ID, $new_post_id); 973 self::copy_elementor_data($post->ID, $new_post_id); 974 self::copy_oxygen_data($post->ID, $new_post_id); 975 self::handle_wpml_relationships($post->ID, $new_post_id); 807 976 808 977 // copy meta and terms over to the new post. … … 886 1055 } 887 1056 888 public static function copy_meta_and_terms($source_post_id, $destination_post_id, $restore_references = false) 1057 /** 1058 * Copies meta and terms from one post to another 1059 * 1060 * @param int $source_post_id The post from which to copy. 1061 * @param int $destination_post_id The post which will get the meta and terms. 1062 * @param bool $restore_references Whether to restore references to the original post ID. 1063 * 1064 * @return void 1065 */ 1066 private static function copy_meta_and_terms($source_post_id, $destination_post_id, $restore_references = false) 889 1067 { 890 1068 $source_post = get_post($source_post_id); 891 1069 $destination_post = get_post($destination_post_id); 892 1070 893 // abort if any of the ids is not a post.894 if (! $source_post || !$destination_post) {1071 // Abort if any of the ids is not a post. 1072 if (!$source_post || !$destination_post) { 895 1073 return; 896 1074 } 897 1075 898 // Copy meta 899 $meta = get_post_meta($source_post->ID); 900 foreach ($meta as $key => $values) { 901 delete_post_meta($destination_post->ID, $key); 902 foreach ($values as $value) { 903 $processed_value = self::copy_meta_value($value); 904 905 if ($restore_references && is_string($processed_value) && 906 strpos($processed_value, (string)$source_post->ID) !== false) { 907 $processed_value = str_replace( 908 (string)$source_post->ID, 909 (string)$destination_post->ID, 910 $processed_value 911 ); 912 } 913 914 add_post_meta($destination_post->ID, $key, $processed_value); 915 } 916 } 917 918 919 // and now for copying the terms. 920 $taxonomies = get_object_taxonomies($source_post->post_type); 921 foreach ($taxonomies as $taxonomy) { 922 $post_terms = wp_get_object_terms($source_post->ID, $taxonomy, array( 923 'orderby' => 'term_order', 924 )); 925 $terms = array(); 926 foreach ($post_terms as $term) { 927 $terms[] = $term->slug; 928 } 929 // reset taxonomy to empty. 930 wp_set_object_terms($destination_post->ID, null, $taxonomy); 931 // then add new terms. 932 wp_set_object_terms($destination_post->ID, $terms, $taxonomy); 1076 // Store current kses status and temporarily disable filters. 1077 $should_filter = ! current_filter('content_save_pre'); 1078 if ($should_filter) { 1079 remove_filter('content_save_pre', 'wp_filter_post_kses'); 1080 remove_filter('db_insert_value', 'wp_filter_kses'); 1081 } 1082 1083 try { 1084 // Copy meta. 1085 $meta = get_post_meta($source_post->ID); 1086 foreach ($meta as $key => $values) { 1087 delete_post_meta($destination_post->ID, $key); 1088 foreach ($values as $value) { 1089 $processed_value = self::copy_meta_value($value); 1090 1091 if ($restore_references && is_string($processed_value) && 1092 strpos($processed_value, (string)$source_post->ID) !== false) { 1093 $processed_value = str_replace( 1094 (string)$source_post->ID, 1095 (string)$destination_post->ID, 1096 $processed_value 1097 ); 1098 } 1099 1100 add_post_meta($destination_post->ID, $key, $processed_value); 1101 } 1102 } 1103 1104 // Copy terms. 1105 $taxonomies = get_object_taxonomies($source_post->post_type); 1106 foreach ($taxonomies as $taxonomy) { 1107 $post_terms = wp_get_object_terms($source_post->ID, $taxonomy, array( 1108 'orderby' => 'term_order', 1109 )); 1110 $terms = array(); 1111 foreach ($post_terms as $term) { 1112 $terms[] = $term->slug; 1113 } 1114 wp_set_object_terms($destination_post->ID, null, $taxonomy); 1115 wp_set_object_terms($destination_post->ID, $terms, $taxonomy); 1116 } 1117 } finally { 1118 // Restore filters if they were active. 1119 if ($should_filter) { 1120 add_filter('content_save_pre', 'wp_filter_post_kses'); 1121 add_filter('db_insert_value', 'wp_filter_kses'); 1122 } 933 1123 } 934 1124 } … … 1104 1294 $original_stock_quantity = get_post_meta($orig->ID, '_stock', true); 1105 1295 1106 self::handle_plugin_css_copy($post->ID, $orig_id); 1296 self::copy_elementor_data($post->ID, $orig_id); 1297 self::copy_oxygen_data($post->ID, $orig_id); 1298 self::handle_wpml_relationships($post->ID, $orig_id, true); 1107 1299 1108 1300 /** -
content-update-scheduler/trunk/readme.txt
r3194096 r3203556 3 3 Tags: schedule, scheduling, update, republish, publication 4 4 Requires at least: 5.0 5 Tested up to: 6.7 6 Stable tag: 2.3. 45 Tested up to: 6.7.1 6 Stable tag: 2.3.5 7 7 Requires PHP: 7.4 8 8 License: GPLv3 … … 62 62 63 63 == Changelog == 64 65 = 2.3.5 = 66 * refactor: Improve meta and terms copying with filter management and visibility 67 * refactor: Improve Elementor and Oxygen data copying with focused, robust methods 68 * refactor: Add WPML relationship handling for duplicated posts 64 69 65 70 = 2.3.4 =
Note: See TracChangeset
for help on using the changeset viewer.