Skip to content

fix(reader-activation): Content Gate metadata for legacy ESP sync#4742

Merged
miguelpeixe merged 6 commits into
releasefrom
feat/content-gate-legacy-metadata
May 21, 2026
Merged

fix(reader-activation): Content Gate metadata for legacy ESP sync#4742
miguelpeixe merged 6 commits into
releasefrom
feat/content-gate-legacy-metadata

Conversation

@miguelpeixe

@miguelpeixe miguelpeixe commented May 18, 2026

Copy link
Copy Markdown
Member

All Submissions:

Changes proposed in this Pull Request:

The Content Access contact-metadata fields (NP_Content Access, NP_Content Access Source, NP_Content Access Group) were previously only available to sites running the v1 Reader Activation sync metadata schema. Adopting v1 requires a disruptive cutover that renames/splits most legacy fields and breaks ESP segments built on the old field names.

This makes the Content Access fields available on the legacy sync schema as well, so sites can adopt them without the v1 cutover. The fields flow through the existing legacy sync and normalization path with no other behavior changes; field names are unchanged.

Additionally, the Content Access fields are now offered (in both the legacy and v1 schemas) only when the Content Gate feature is enabled (NEWSPACK_CONTENT_GATES). On sites without the feature, the fields no longer appear in the per-integration field selector and are not synced as permanently-empty values.

No backfill of existing ESP contacts is included — existing contacts populate the fields on their next per-contact sync (unchanged limitation).

How to test the changes in this Pull Request:

  1. On a site without NEWSPACK_CONTENT_GATES defined, on the legacy sync schema (default), open the Reader Activation ESP sync field selector and confirm there is no "Content Access" group/fields.
  2. Define define( 'NEWSPACK_CONTENT_GATES', true ); in wp-config.php. Reload the field selector and confirm a "Content Access" group now appears with the three fields, on the legacy schema (no NEWSPACK_SYNC_METADATA_VERSION* constant needed).
  3. Create a published Content Gate with custom access active (e.g. an email-domain rule the test reader matches). Enable the "Content Access" field for the ESP integration.
  4. Trigger a contact sync for a reader that passes the gate; confirm the ESP receives NP_Content Access = Yes (and Source/Group as applicable).
  5. Confirm a reader that does not pass the gate syncs NP_Content Access = No.
  6. Disable the "Content Access" field in the field selector; confirm it is no longer included in the sync payload (legacy basic/payment fields continue to sync unchanged).
  7. Repeat steps 2-6 with the v1 schema (define( 'NEWSPACK_SYNC_METADATA_VERSION_1', true );) to confirm v1 behavior is unchanged aside from the shared feature-flag gating.

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully ran tests with your changes locally?

@miguelpeixe miguelpeixe marked this pull request as ready for review May 18, 2026 18:58
@miguelpeixe miguelpeixe requested a review from a team as a code owner May 18, 2026 18:58
@miguelpeixe miguelpeixe self-assigned this May 18, 2026
@miguelpeixe miguelpeixe added the [Status] Needs Review The issue or pull request needs to be reviewed label May 18, 2026
@miguelpeixe miguelpeixe changed the title feat(reader-activation): Content Gate metadata for legacy ESP sync fix(reader-activation): Content Gate metadata for legacy ESP sync May 20, 2026
@miguelpeixe miguelpeixe changed the base branch from trunk to release May 20, 2026 16:55
@dkoo dkoo self-assigned this May 20, 2026
@miguelpeixe miguelpeixe force-pushed the feat/content-gate-legacy-metadata branch from 024b907 to 2d87606 Compare May 20, 2026 17:26

@dkoo dkoo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changeset is tiny and clean. However, manual and unit testing fail for a couple of reasons:

🔴 Missing Content_Access_Group field

The failing unit test is because the Content_Access_Group field isn't in the parent release branch yet. This field was added in #4697, which hasn't yet made it to release.

Test_Content_Gate_Legacy::test_legacy_schema_exposes_content_access_fields
Failed asserting that an array has the key 'Content_Access_Group'.

Suggested fix: I opened #4746 to cherry-pick that PR to release as a hotfix. Once that PR lands we can rebase this branch on release to resolve things. Alternatively, you can just cherry-pick that same commit hash 8d71495 to this branch since it's also a hotfix, and then I'll close #4746.

🔴 Unprefixed meta fields get silently dropped before the sync

Unlike Legacy_Basic and Legacy_Payment classes, Content_Gate doesn't normalize its own fields using Legacy_Metadata::normalize_contact_data() before appending its fields, so the Content Access fields get appended without NP_ (or custom) prefix. This causes the fields to be silently dropped from the contact before getting synced to the ESP.

Suggested fix: Normalize all fields, either by adding a handler to prefix Content_Gate fields before returning for a legacy sync, or by moving Legacy_Metadata::normalize_contact_data() outside of the individual Legacy_* classes and to a later point where it can run on all fields collected for a legacy sync but before it gets passed to the sync handler.

@github-actions github-actions Bot added the [Status] Needs Changes or Feedback The issue or pull request needs action from the original creator label May 20, 2026

@dkoo dkoo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional feedback in inline comments. Also, this doesn't originate in this PR, but the includes/reader-activation/sync/contact-metadata/class-content-gate.php file has incorrect newspack text domains throughout—let's find/replace with newspack-plugin to keep it in line with the rest of the plugin.

Comment thread includes/reader-activation/sync/class-metadata.php
@miguelpeixe

miguelpeixe commented May 21, 2026

Copy link
Copy Markdown
Member Author

@dkoo Thanks for the review!

🔴 Unprefixed Content_Gate fields silently dropped

Fixed in f3077f1. Content_Gate::get_metadata() now runs its output through Legacy_Metadata::normalize_contact_data() when Metadata::get_version() === 'legacy', returning prefixed keys to match Legacy_Basic / Legacy_Payment. Added Test_Content_Gate_Legacy::test_content_gate_fields_arrive_prefixed_from_get_contact_with_metadata to lock in the wire-format expectation (the existing test had the wrong path because it called Metadata::normalize_contact_data() explicitly — production doesn't in legacy mode). Updated Test_Content_Gate_Metadata to force Metadata::$version = '1.0' so its raw-shape assertions still hold; the legacy wire format is now tested in Test_Content_Gate_Legacy instead.

🔴 Missing Content_Access_Group field

I worked around the CI failure by dropping the assertion (so other fixes could land green). Once #4746 lands on release I'll rebase this branch and restore the Content_Access_Group assertion.

@miguelpeixe miguelpeixe requested a review from dkoo May 21, 2026 14:25

@dkoo dkoo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miguelpeixe latest changes look good, thanks for the updates! I'll hold off approving until merge conflicts are resolved.

@miguelpeixe miguelpeixe force-pushed the feat/content-gate-legacy-metadata branch from f3077f1 to cf33f4b Compare May 21, 2026 16:17
@miguelpeixe

Copy link
Copy Markdown
Member Author

@dkoo Rebased onto release now that #4746 landed — Content_Access_Group is on release, so:

  • Restored the Content_Access_Group assertion in Test_Content_Gate_Legacy::test_legacy_schema_exposes_content_access_fields (was the workaround drop from before).
  • Resolved conflicts in includes/reader-activation/sync/contact-metadata/class-content-gate.php (kept release's 3-key collect_labels shape for v1 and stacked the legacy normalize on top) and tests/.../class-content-gate-metadata.php (merged the version-snapshot setup with the new group/institution test scaffolding).
  • Updated the institution-path test to expect the new 'institution' source label (release renamed it from 'group' in feat(access-control): add group subscription identifier to metadata #4697).

54/54 tests in the Content_Gate_Metadata, Content_Gate_Legacy, and prepare_contact groups pass locally. New tip: cf33f4b.

@miguelpeixe miguelpeixe requested a review from dkoo May 21, 2026 16:18
@miguelpeixe miguelpeixe removed the [Status] Needs Changes or Feedback The issue or pull request needs action from the original creator label May 21, 2026

@dkoo dkoo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passes manual testing, and I see all three NP_Content Access fields being synced now. A couple of non-blocking nitpicks inline, but nothing urgent.

Comment thread includes/reader-activation/sync/class-metadata.php Outdated
@github-actions github-actions Bot added [Status] Approved The pull request has been reviewed and is ready to merge and removed [Status] Needs Review The issue or pull request needs to be reviewed labels May 21, 2026
@miguelpeixe

miguelpeixe commented May 21, 2026

Copy link
Copy Markdown
Member Author

@dkoo Thanks for the approval and the follow-up nits!

Text domain fix — Done in 3f29a4f. Find/replaced 'newspack''newspack-plugin' in class-content-gate.php (only one occurrence on this branch, at the get_section_name() translation).

newspack_esp_sync_normalize_contact fires multiple times — Agreed this is the architecturally cleaner shape, but I'd like to defer it to a follow-up PR since it touches Legacy_Basic / Legacy_Payment (currently the only legacy normalizers) and changes where the merged contact gets normalized in the main sync path. The fix is mechanical but it's outside the scope of "unblock Content Gate fields for legacy sync" — keeping it separate makes the bisect/revert story cleaner if anything regresses. I'll open the follow-up after this lands and tag you.

@miguelpeixe miguelpeixe requested a review from dkoo May 21, 2026 19:37

@dkoo dkoo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! Thanks, @miguelpeixe

@miguelpeixe miguelpeixe merged commit 28f543a into release May 21, 2026
11 checks passed
@miguelpeixe miguelpeixe deleted the feat/content-gate-legacy-metadata branch May 21, 2026 19:41
@github-actions

Copy link
Copy Markdown

Hey @miguelpeixe, good job getting this PR merged! 🎉

Now, the needs-changelog label has been added to it.

Please check if this PR needs to be included in the "Upcoming Changes" and "Release Notes" doc. If it doesn't, simply remove the label.

If it does, please add an entry to our shared document, with screenshots and testing instructions if applicable, then remove the label.

Thank you! ❤️

matticbot pushed a commit that referenced this pull request May 21, 2026
## [6.41.2](v6.41.1...v6.41.2) (2026-05-21)

### Bug Fixes

* **reader-activation:** Content Gate metadata for legacy ESP sync ([#4742](#4742)) ([28f543a](28f543a))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 6.41.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

github-actions Bot pushed a commit to Automattic/newspack-workspace that referenced this pull request May 22, 2026
## [6.41.2](Automattic/newspack-plugin@v6.41.1...v6.41.2) (2026-05-21)

### Bug Fixes

* **reader-activation:** Content Gate metadata for legacy ESP sync ([#4742](Automattic/newspack-plugin#4742)) ([66998c2](Automattic/newspack-plugin@66998c2))
matticbot pushed a commit that referenced this pull request May 25, 2026
# [6.42.0-alpha.3](v6.42.0-alpha.2...v6.42.0-alpha.3) (2026-05-25)

### Bug Fixes

* **editor:** exclude Customizer Additional CSS from iframed editor ([#4750](#4750)) ([3aaf8f6](3aaf8f6))
* **reader-activation:** Content Gate metadata for legacy ESP sync ([#4742](#4742)) ([28f543a](28f543a))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 6.42.0-alpha.3 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

adekbadek pushed a commit to Automattic/newspack-workspace that referenced this pull request May 28, 2026
* **editor:** exclude Customizer Additional CSS from iframed editor ([#4750](Automattic/newspack-plugin#4750)) ([123c507](Automattic/newspack-plugin@123c507))
* **reader-activation:** Content Gate metadata for legacy ESP sync ([#4742](Automattic/newspack-plugin#4742)) ([66998c2](Automattic/newspack-plugin@66998c2))

(cherry picked from commit 8edeec2b01fb32cbfbcd24847cbcc664581160a4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Status] Approved The pull request has been reviewed and is ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants