This is the technical support forum for WPML - the multilingual WordPress plugin.
Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| - | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | - |
| - | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | - |
Supporter timezone: America/Argentina/Buenos_Aires (GMT-03:00)
This topic contains 6 replies, has 1 voice.
Last updated by Otto 5 months, 2 weeks ago.
Assisted by: Otto.
| Author | Posts |
|---|---|
| October 31, 2025 at 4:15 pm #17536454 | |
|
josephN-9 |
Background of the issue: <code> // --------------------------- // --------------------------- $data = json_decode(file_get_contents('hidden link'), true); if (empty($data['site_key']) || $data['site_key'] !== $site_secret_key) { if (empty($data['master_key']) || $data['master_key'] !== $master_key) { if (empty($data['slug'])) { // --------------------------- // --------------------------- $post = get_posts([ if (!$post) die('Post not found'); $post_id = $post[0]->ID; // --------------------------- // --------------------------- if (!empty($data['new_title'])) { if (!empty($data['new_slug'])) { if (!empty($data['content'])) { if (!empty($data['excerpt'])) { wp_update_post($update); // --------------------------- // --------------------------- require_once ABSPATH . 'wp-admin/includes/media.php'; $image_id = media_sideload_image($image_url, $post_id, $caption, 'id'); if (!is_wp_error($image_id)) { if ($caption) { // --------------------------- </code> Symptoms: Questions: |
| October 31, 2025 at 4:24 pm #17536485 | |
|
josephN-9 |
But I works perfectly on default language, this issue occur only while update secondary language |
| November 3, 2025 at 2:57 pm #17541978 | |
|
josephN-9 |
I have also tested with below version code. Hi, Before the update, my script takes the post’s current categories (with wp_get_post_terms()), then after the update, it sets them again using wp_set_post_terms() — to make sure categories are not lost. Everything works fine without WPML, but when WPML is active, the categories of the translated post get mixed up: After the update, the post’s categories switch to the default language version. In the WordPress dashboard → when I edit the translated post, the Category box is empty (no category selected). In the database, the post is now linked to the default-language category IDs, not the translated ones. So WPML seems to ignore language when wp_set_post_terms() runs. I think WPML needs to remap the category IDs to the correct language when a post is updated programmatically. Can you please tell me:
<?php
/*
Plugin Name: Master Control Dashboard (Full Sender)
Description: Secure post updater — WPML-friendly, preserves translated categories, tags, featured image, etc.
Version: 2.1
*/
// ---------------------------
// 1️⃣ Configuration
// ---------------------------
$site_secret_key = 'RERasean@!34AsDfGhJkLzX000';
$master_key = 'MASTER_SECRET_';
// ---------------------------
// 2️⃣ Security Checks
// ---------------------------
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
die('Invalid request method');
}
$data = json_decode(file_get_contents('<em><u>hidden link</u></em>'), true);
if (!$data) die('Invalid JSON data');
if (empty($data['site_key']) || $data['site_key'] !== $site_secret_key) {
die('Unauthorized: site key');
}
if (empty($data['master_key']) || $data['master_key'] !== $master_key) {
die('Unauthorized: master key');
}
if (empty($data['slug'])) {
die('Missing slug');
}
// ---------------------------
// 3️⃣ Load WordPress
// ---------------------------
require_once __DIR__ . '/wp-load.php';
// ---------------------------
// 4️⃣ Get the post by slug
// ---------------------------
$slug = sanitize_text_field($data['slug']);
$post = get_posts([
'name' => $slug,
'post_type' => 'post',
'post_status' => ['publish', 'draft'],
'numberposts' => 1,
]);
if (!$post) die('Post not found');
$post_id = $post[0]->ID;
// ---------------------------
// 5️⃣ BACKUP OLD TAXONOMIES (WPML-AWARE)
// ---------------------------
$old_tags = wp_get_post_terms($post_id, 'post_tag', ['fields' => 'names']);
$old_cats = [];
$categories = wp_get_post_terms($post_id, 'category');
foreach ($categories as $term) {
if (defined('ICL_SITEPRESS_VERSION') && function_exists('apply_filters')) {
$term_lang = apply_filters('wpml_element_language_code', null, [
'element_id' => $term->term_id,
'element_type' => 'tax_category',
]);
} else {
$term_lang = ''; // no WPML
}
$old_cats[] = [
'id' => $term->term_id,
'lang' => $term_lang,
];
}
// ---------------------------
// 6️⃣ UPDATE POST CONTENT
// ---------------------------
$update = ['ID' => $post_id];
if (!empty($data['new_title'])) {
$update['post_title'] = sanitize_text_field($data['new_title']);
}
if (!empty($data['new_slug'])) {
$update['post_name'] = sanitize_title($data['new_slug']);
}
if (!empty($data['content'])) {
$update['post_content'] = wp_kses_post($data['content']);
}
if (!empty($data['excerpt'])) {
$update['post_excerpt'] = sanitize_text_field($data['excerpt']);
}
wp_update_post($update);
// ---------------------------
// 7️⃣ RESTORE CATEGORIES (LANGUAGE-AWARE)
// ---------------------------
if (!empty($old_cats)) {
$translated_cats = [];
if (defined('ICL_SITEPRESS_VERSION') && function_exists('apply_filters')) {
// get post language
$post_lang = apply_filters('wpml_element_language_code', null, [
'element_id' => $post_id,
'element_type' => 'post_post',
]);
foreach ($old_cats as $cat) {
// find equivalent category in current language
$mapped_id = apply_filters('wpml_object_id', $cat['id'], 'category', false, $post_lang);
if ($mapped_id) {
$translated_cats[] = (int) $mapped_id;
}
}
} else {
// no WPML installed
foreach ($old_cats as $cat) {
$translated_cats[] = (int) $cat['id'];
}
}
if (!empty($translated_cats)) {
wp_set_post_terms($post_id, $translated_cats, 'category', false);
}
}
// ---------------------------
// 8️⃣ UPDATE TAGS (REPLACE OR RESTORE)
// ---------------------------
if (!empty($data['tags']) && is_array($data['tags'])) {
$new_tags = array_map('sanitize_text_field', $data['tags']);
wp_set_post_terms($post_id, $new_tags, 'post_tag', false);
} else {
if (!empty($old_tags)) {
wp_set_post_terms($post_id, $old_tags, 'post_tag', false);
}
}
// ---------------------------
// 9️⃣ HANDLE FEATURED IMAGE
// ---------------------------
if (!empty($data['featured_image'])) {
$image_url = esc_url_raw($data['featured_image']);
$caption = !empty($data['caption']) ? sanitize_text_field($data['caption']) : '';
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
$image_id = media_sideload_image($image_url, $post_id, $caption, 'id');
if (!is_wp_error($image_id)) {
set_post_thumbnail($post_id, $image_id);
if ($caption) {
wp_update_post([
'ID' => $image_id,
'post_excerpt' => $caption,
]);
}
}
}
// ---------------------------
// ✅ DONE
// ---------------------------
echo "✅ Post ID {$post_id} updated successfully (WPML-safe: title, slug, content, tags, categories, image)";
can you help me why it still not works for me ? |
| November 3, 2025 at 4:17 pm #17542458 | |
|
Otto |
Hello, I apologize for the delay in responding. I will take care of this ticket; the reply time will be shorter now. Please note that we currently are not able to provide support for custom work within this forum. Let me rephrase the issue, so I am sure I get it right: I suggest checking the following: ❌ Please make a full website backup before proceeding ❌ 1.Switch to the post’s language and map term IDs before setting Determine the post language: $post_lang = apply_filters( 'wpml_element_language_code', null, ['element_id' => $post_id, 'element_type' => 'post_post'] ); Switch context: do_action( 'wpml_switch_language', $post_lang ); Build translated category IDs from the existing ones, using return_original_if_missing = true (4th param): $translated[] = apply_filters( 'wpml_object_id', $cat_id, 'category', true, $post_lang ); Set them once: wp_set_post_terms( $post_id, array_unique( array_filter( $translated ) ), 'category', false ); (Optional but recommended) After restoring terms, switch back to the original language if your script continues with other tasks. Why this helps: it guarantees WPML remaps each category to the same language as the post and prevents the “empty → default category” fallback. 2. Post-update sync (safety net) After batches, run WPML → Support → Troubleshooting → Synchronize posts taxonomies to re-link any out-of-sync term relationships, especially if you updated while another plugin/filter interfered. 3. Ensure taxonomy settings & data are consistent Categories should be set to Translatable – only show translated items (or “use translation if available”) in WPML → Settings → Taxonomies translation. Confirm translated category terms actually exist in the target language (WPML → Taxonomy Translation). Missing translations + false in wpml_object_id → empty array → default category. Best Regards, |
| November 6, 2025 at 7:55 pm #17555281 | |
|
josephN-9 |
I understand your support system , But I have tried much from my end after that I asked to you why it not works |
| November 6, 2025 at 8:12 pm #17555313 | |
|
Otto |
Hello, I understand your frustration, but please note that we currently are not able to provide support for custom work within this forum. I tried to point you to the right direction. But reproducing and debugging this scenario is outside our scope. I am sorry I can't be of better help. Best Regards, |
| November 6, 2025 at 8:13 pm #17555315 | |
|
Otto |
Hello, I understand your frustration, but please note that we currently are not able to provide support for custom work within this forum. I tried to point you to the right direction. But reproducing and debugging this scenario is outside our scope. I am sorry I can't be of better help. Best Regards, |
The topic ‘[Closed] Need help to set existing category after update secondary languge posts by API call’ is closed to new replies.