Skip to content

Append shadow terms instead of replacing on associate and restore - #67

Open
jeremyfelt wants to merge 2 commits into
trunkfrom
fix/multi-association-preserve-terms
Open

Append shadow terms instead of replacing on associate and restore#67
jeremyfelt wants to merge 2 commits into
trunkfrom
fix/multi-association-preserve-terms

Conversation

@jeremyfelt

@jeremyfelt jeremyfelt commented Jun 26, 2026

Copy link
Copy Markdown
Member

Summary

wp_set_object_terms() defaults to $append = false, which replaces every term an object already has in the target taxonomy. Because a single {post_type}_connect taxonomy holds one term for every shadow post, a connected post can legitimately carry several terms in that one taxonomy. Three call sites managed a single shadow term without appending, so they silently wiped the connected post's other shadow-term associations.

Sites fixed (pass $append = true):

  • includes/sync.php:73 — restore loop when a shadow post returns to publish
  • includes/sync.php:110 — recovery loop when a published post's shadow term went missing
  • includes/taxonomy.php:170 — REST associate endpoint for a published shadow post

Why it's a real bug

The shadow taxonomy is shared across all posts of a type (e.g. example_connect holds acme, globex, …) and is attached to the connected post type. A connected post associated with two shadow posts holds two terms in that one taxonomy. Re-attaching one term without $append = true replaces the full set, dropping the rest.

Tests

Adds tests/test-multi-association.php with one regression test per call site. Each attaches a connected post to two shadow posts, exercises the relevant path, and asserts both associations survive.

Verified:

  • Red without the fix — all three tests fail (the other shadow term is wiped).
  • Green with the fixphpunit 23/23, phpcs clean, phpstan level 7 reports no errors.

Also addresses #68

This branch now also fixes a pre-existing edge case in the REST associate handler: when a published shadow post'''s term cannot be resolved (e.g. the term was deleted and the post not re-saved), get_term_id() returns 0, wp_set_object_terms() skips the non-existent ID, and the handler previously returned success: true with nothing attached. It now recreates the missing term (mirroring sync.php'''s recovery branch) and returns success: false only if a term still cannot be resolved. Covered by an added regression test. Closes #68.

🤖 Generated with Claude Code

`wp_set_object_terms()` defaults to `$append = false`, which replaces every
term an object has in the target taxonomy. Because a single `{post_type}_connect`
taxonomy holds a term for every shadow post, one connected post can legitimately
carry several terms in it. Three call sites managed a single shadow term without
appending, so they silently wiped the connected post's other associations:

- sync.php:73  — restore loop when a shadow post returns to publish
- sync.php:110 — recovery loop when a published post's term went missing
- taxonomy.php:170 — REST `associate` endpoint for a published shadow post

Pass `$append = true` at all three sites and add regression coverage in
tests/test-multi-association.php that fails without the fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

✅ Plugin Check passed

No errors or warnings from plugin check --categories=plugin_repo.

When the target shadow post is published but its term cannot be resolved
(`API\get_term_id()` returns 0 — e.g. the term was deleted directly and the
post has not been re-saved), `wp_set_object_terms()` skips the non-existent
term ID and the handler still returned `success: true` with no association
actually made.

Recreate the missing term before associating (mirroring the recovery branch in
sync.php) and, if a term still cannot be resolved, return `success: false`
instead of a misleading success. Reuse the already-resolved taxonomy slug and
term ID for the response query.

Adds a regression test that fails without the fix (the connected post gains no
term while the response reports success).

Closes #68

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

development Front or back-end development is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

REST associate endpoint silently succeeds when a published shadow post has no resolvable term

1 participant