Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,21 @@ function cdcf_enqueue_translations_for_submission(int $en_post_id, string $post_
$translations = pll_get_post_translations($en_post_id);
$translations['en'] = $en_post_id;

error_log(sprintf(
'cdcf_enqueue_translations_for_submission: ENTER post_id=%d post_type=%s pre_seed_group=%s',
$en_post_id,
$post_type,
cdcf_format_lang_map($translations)
));

// Phase 1: create draft siblings + per-post language assignment.
// Group save is intentionally NOT called here — see file-level
// docblock for the lost-update race rationale.
$newly_created = [];
$newly_created = [];
$already_linked = [];
foreach ($target_langs as $lang) {
if (!empty($translations[$lang])) {
$already_linked[$lang] = (int) $translations[$lang];
continue;
}

Expand All @@ -120,27 +129,46 @@ function cdcf_enqueue_translations_for_submission(int $en_post_id, string $post_
$newly_created[$lang] = $trans_id;
}

error_log(sprintf(
'cdcf_enqueue_translations_for_submission: PHASE_1_DONE post_id=%d newly_created=%s already_linked=%s',
$en_post_id,
cdcf_format_lang_map($newly_created),
cdcf_format_lang_map($already_linked)
));

if (empty($newly_created)) {
// Nothing new to link or enqueue.
error_log(sprintf(
'cdcf_enqueue_translations_for_submission: NO_OP post_id=%d (all target langs already pre-seeded); exiting without group save.',
$en_post_id
));
return;
}

// Phase 2: one atomic group save with the full {lang => post_id} map.
$save_result = pll_save_post_translations($translations);
if ($save_result === false) {
error_log(sprintf(
'cdcf_enqueue_translations_for_submission: pll_save_post_translations returned false for post %d; rolling back %d draft(s).',
'cdcf_enqueue_translations_for_submission: PHASE_2_FAIL post_id=%d pll_save_post_translations returned false; rolling back %d draft(s): %s',
$en_post_id,
count($newly_created)
count($newly_created),
cdcf_format_lang_map($newly_created)
));
foreach ($newly_created as $trans_id) {
wp_delete_post($trans_id, true);
}
return;
}

error_log(sprintf(
'cdcf_enqueue_translations_for_submission: PHASE_2_OK post_id=%d atomic group save succeeded; final_group=%s',
$en_post_id,
cdcf_format_lang_map($translations)
));

// Phase 3: enqueue translation jobs for the newly-created siblings only.
// (Existing siblings from the pre-seed already had their content done.)
$queue_name = function_exists('cdcf_enqueue_translation') ? 'redis' : 'wp-cron';
foreach ($newly_created as $lang => $trans_id) {
if (function_exists('cdcf_enqueue_translation')) {
cdcf_enqueue_translation($trans_id, $en_post_id, $lang);
Expand All @@ -149,6 +177,30 @@ function cdcf_enqueue_translations_for_submission(int $en_post_id, string $post_
spawn_cron();
}
}

error_log(sprintf(
'cdcf_enqueue_translations_for_submission: PHASE_3_DONE post_id=%d queued %d job(s) via %s: %s',
$en_post_id,
count($newly_created),
$queue_name,
cdcf_format_lang_map($newly_created)
));
}

/**
* Format a {lang => post_id} map for compact inclusion in error_log
* lines. Returns "{lang:id, lang:id, ...}" or "{}" if empty.
* Used by the diagnostic logs in cdcf_enqueue_translations_for_submission.
*/
function cdcf_format_lang_map(array $map): string {
if (empty($map)) {
return '{}';
}
$parts = [];
foreach ($map as $lang => $id) {
$parts[] = $lang . ':' . (int) $id;
}
return '{' . implode(', ', $parts) . '}';
}

/**
Expand Down
30 changes: 30 additions & 0 deletions wordpress/themes/cdcf-headless/tests/SubmissionLifecycleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,36 @@ function (int $id, bool $force) use (&$deleted): array {
);
}

// ─── cdcf_format_lang_map ─────────────────────────────────────────

public function test_format_lang_map_empty_array_returns_curly_braces(): void
{
$this->assertSame('{}', cdcf_format_lang_map([]));
}

public function test_format_lang_map_single_entry(): void
{
$this->assertSame('{en:42}', cdcf_format_lang_map(['en' => 42]));
}

public function test_format_lang_map_six_languages_preserves_input_order(): void
{
// The diagnostic log lines rely on stable key order (en first when
// pre-seeding, target langs in target_langs order otherwise) — assert
// PHP's insertion-order array iteration carries through.
$this->assertSame(
'{en:1508, it:1521, es:1522, fr:1523, pt:1524, de:1525}',
cdcf_format_lang_map(['en' => 1508, 'it' => 1521, 'es' => 1522, 'fr' => 1523, 'pt' => 1524, 'de' => 1525])
);
}

public function test_format_lang_map_coerces_string_ids_to_int(): void
{
// ACF and some Polylang return paths hand back string-numeric IDs;
// the helper coerces them so the log line is uniform.
$this->assertSame('{en:10, it:11}', cdcf_format_lang_map(['en' => '10', 'it' => '11']));
}

// ─── cdcf_repend_submission_on_untrash ────────────────────────────

public function test_repend_ignores_status_transitions_that_arent_trash_to_draft(): void
Expand Down