Skip to content

fix(godam): protect activity player markup from content filters - #2387

Merged
KMchaudhary merged 2 commits into
developfrom
fix/godam-activity-player-content-filter-corruption
Oct 27, 2026
Merged

KMchaudhary merged 2 commits into
developfrom
fix/godam-activity-player-content-filter-corruption

Conversation

@KMchaudhary

@KMchaudhary KMchaudhary commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

What

When a GoDAM video is shown inside a BuddyPress activity item, the player markup was corrupted by the activity content filters, leaving the <video> with no source so playback never started. This PR makes the player injection immune to those filters.

Closes #2386.

Why it broke

templates/media/godam-integration.php expanded the player inline via do_shortcode() inside a bp_get_activity_content_body filter at priority 10, returning the full player HTML as part of the activity content. BuddyPress (and the theme) then run their formatting filters on that same content:

  • make_clickable @9, wptexturize / wpautop / force_balance_tags / nofollow @10 (BuddyPress core)
  • a theme #hashtag → ?activity_search= linkifier on top

Those filters found the #hex colour values (e.g. appearanceColor":"#fff") and URLs inside the player's data-controls / data-options attributes and wrapped each in an <a href="…">. Injecting an <a tag inside <div data-controls="…"> shatters the tag; the browser mis-parses the rest, Video.js can't read sources, and the <video> ends up with zero <source> children.

This surfaces most once a video has a layer (e.g. a CTA layer), because the layer causes the saved config to carry the control-bar appearance colours that the linkifiers latch onto.

The fix

Priority-agnostic late expansion:

  1. During normal filtering, emit a neutral placeholder that contains no # and no URL — <div class="godam-activity-player-placeholder" data-media-id="…" data-player-id="…" data-context="…"></div>. A <div> is left alone by wpautop, and there is nothing for make_clickable / the hashtag filter to linkify.
  2. A new bp_get_activity_content_body filter at PHP_INT_MAX replaces each placeholder with the real do_shortcode('[godam_video …]') output — running after every other content filter, so the player markup is never exposed to them.

Applied to both the activity-video and activity-comment paths. Surrounding activity text keeps its normal hashtag/URL formatting.

Behaviour / safety

  • Output for GoDAM videos is functionally identical — the same [godam_video] shortcode args, just injected later.
  • The late filter early-returns via a strpos guard when no placeholder is present, so it is a no-op for all non-GoDAM activity and every other bp_get_activity_content_body call.
  • Functions are defined only when RTMEDIA_GODAM_ACTIVE; the template is require_once'd, so no redeclaration risk.
  • Fix is display-time, so already-posted activity videos are repaired on next render (no re-save needed).

Testing

  • Reproduced the exact corruption (appearanceColor":"<a href="https…) and verified the placeholder survives the filter chain while the player renders clean with a <source>, and surrounding hashtags/URLs still linkify.
  • Manual check to do on review: an activity post with a GoDAM video + CTA layer plays, the CTA appears at its timestamp, and comment videos + the AJAX comment-load path work.

Acceptance criteria

  • Player <div> renders with intact data-controls (no injected <a>, no ?activity_search / debris attributes, no <p> wrap).
  • <video> has its <source> children; the video plays and the CTA layer appears.
  • Existing (already-posted) activity videos are fixed on reload.
  • Real hashtags/URLs in activity text still linkify; non-video and comment activity unaffected.

🤖 Generated with Claude Code

Verification evidence

Verified end-to-end on a real WordPress + BuddyPress + rtMedia + GoDAM stack, using a real GoDAM video with 7 layers and a #hex brand colour (#0095ff):

Before and after the fix: the activity video player is corrupted and unplayable before, and renders and plays after

  • Top (after fix): the player renders its real poster and plays.
  • Bottom (before fix): the activity content filters shatter the player markup — the #hex colours leak as text and get linkified — and the player has no playable source (the reported "video not playable").

An automated pass through the real bp_get_activity_content_body filter chain reproduces the exact corruption signature (appearanceColor":"<a href=) on the old inline path and confirms the player stays intact on the fixed path.

The GoDAM player was expanded inline into BuddyPress activity content and
then run through make_clickable, the theme hashtag linkifier and wpautop.
Those filters turned the #hex colours and URLs inside the player's data-*
attributes into <a> tags, shattering the markup so Video.js got no source
and the video could not play.

Emit a neutral placeholder during normal filtering and swap in the real
[godam_video] output on a PHP_INT_MAX pass, after every other
bp_get_activity_content_body filter has run. Covers the activity-video and
activity-comment paths; surrounding activity text keeps its formatting.

Closes #2386

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@Intenzi Intenzi 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.

The late-expansion placeholder pattern cleanly protects the main activity video from #hex and URL linkifier corruption (tested and verified with custom hashtag linkifiers).

However, comment video attachments render as empty, unexpanded placeholder <div> tags because comments follow the bp_activity_comment_content pipeline rather than bp_get_activity_content_body.

See the inline suggestion to add the missing filter hook 🙇

Image

Comment thread templates/media/godam-integration.php
Activity comments render via bp_get_activity_content + bp_activity_comment_content
and never hit bp_get_activity_content_body, so comment-video placeholders were
left in the DOM as empty <div>s. Also register the expansion on
bp_activity_comment_content (PHP_INT_MAX) so comment videos expand too.

Addresses review feedback on #2387.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@rtBot

rtBot commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Unable to PHPCS or SVG scan one or more files due to error running PHPCS/SVG scanner:

  • templates/media/godam-integration.php

The error may be temporary. If the error persists, please contact a human (commit-ID: c6bb314).

@KMchaudhary

Copy link
Copy Markdown
Contributor Author

Good catch, thanks @Intenzi — confirmed. Comments render via bp_get_activity_content + bp_activity_comment_content and never hit bp_get_activity_content_body, so the comment-video placeholders were left as empty

s. Added the expansion on bp_activity_comment_content at PHP_INT_MAX too (c6bb314), and verified on a real BuddyPress runtime that a comment placeholder now expands to the player. Both activity and comment paths are covered.

@KMchaudhary
KMchaudhary merged commit b3788ce into develop Oct 27, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GoDAM video in BuddyPress activity is unplayable — player markup corrupted by activity content filters

3 participants