Skip to content

fix(network): describe the images the receiving site actually stores - #981

Open
rbcorrales wants to merge 3 commits into
mainfrom
fix/nppm-3181-media-data-source
Open

fix(network): describe the images the receiving site actually stores#981
rbcorrales wants to merge 3 commits into
mainfrom
fix/nppm-3181-media-data-source

Conversation

@rbcorrales

@rbcorrales rbcorrales commented Aug 27, 2026

Copy link
Copy Markdown
Member

All Submissions:

Changes proposed in this Pull Request:

Five fixes on the outgoing side of content distribution. #982 was folded in here rather than merged separately.

Distributed images opened at the wrong size. A distributed post carries a description of its images so the receiving site can size them, and that description was built by re-rendering the original post content, which is not the content the receiving site ends up with. An image missing from it arrives without dimensions, so a reader clicking it gets a scaled copy in the lightbox where the same click on the origin opens the full-size file. Most visible on a WordPress 7.1 dynamic gallery, which carries no image IDs until distribution resolves it into images, so none of its images were described at all.

The description now comes from the content the receiving site will actually store, branching the same way the receiving side does: the block-processed content for a block post, the filtered content for a classic one. Images that exist only because a the_content filter injected them, such as ads or related posts, stop being described. Content after a "read more" or a page break, and every image in a password-protected post, start being described.

Reading that content also had to move above the image-CDN override this code installs. The dynamic gallery processor installs and removes the same named callback, and WordPress keys hooks by name, so the nested removal took the outer override down with it and the URLs after that point came back rewritten to the origin's CDN.

One post save prepared the content for the wire six times. Several payload fields need it, and a partial distribution built the whole payload twice, once for the change hash and once for the slice it sends. It is now prepared once per payload, and the partial takes its slice from the payload the hash already used, so a dynamic gallery stops re-querying its images on every pass.

Outgoing logging was invisible in production. It went through a debugger that writes nothing unless NEWSPACK_NETWORK_DEBUG is defined, so a gallery that left without its images left no trace of why. It now also reaches the Newspack plugin's logger, the way the receiving side already does. A gallery whose source resolves to nothing is logged as debug rather than error, since that is what an empty gallery normally is.

A gallery whose images resolve but produce no markup keeps its caption, matching what the origin shows.

A distribution that failed to dispatch no longer records itself as delivered. The stored payload hash is what tells the next save there is nothing to send, so writing it after a failed send left the post silently stale until someone edited it again. The editor's own distribute button already guarded this; the two background paths did not.

Closes NPPM-3181.

How to test the changes in this Pull Request:

  1. On a hub running WordPress 7.1, create a post and upload three images to it.
  2. Remove the images from the content, leaving them attached to the post.
  3. Insert a Gallery block, pick the images attached to the post, and add a gallery caption. Publish.
  4. Distribute the post to a node, then pull it on the node. Images and caption match the hub.
  5. Click a gallery image on the node. The lightbox opens the full-size file.
  6. Click the same image on the hub. Both lightboxes open at the same size.
  7. Repeat with a plain Image block, which should keep opening at full size.
  8. Repeat with a classic-editor post holding a [caption] shortcode, which should also open at full size.
  9. On the hub, change a custom field on the distributed post without touching the content.
  10. Pull again on the node. The custom field follows and the content is unchanged.
  11. Hook the newspack_log action on the hub, then distribute a gallery on a post with no attached images.
  12. The action fires with code newspack_network_outgoing_post, no debug constant defined.

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 run tests with your changes locally?

An already-distributed post picks up the corrected image description on its next full distribution. If a background writer touches one of its post meta keys first, that sends a partial update and stores the new payload hash, which marks the correction as delivered without sending it. wp newspack network distribute post <id> forces it through per post. That partial-swallow behavior predates this PR and is left alone here.

Known gap: the Newspack logger branch of Outgoing_Post::log() is not covered by a test. Defining a Newspack\Logger mock would change which branch Incoming_Post::log() takes across the whole suite, so it needs its own test process rather than a mock file.

🤖 Generated with Claude Code

Copilot AI 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.

Pull request overview

This PR updates Newspack Network’s outgoing content distribution payload so media_data is derived from the same content representation that is distributed, addressing cases where block rewriting (notably WP 7.1 dynamic galleries) causes mismatches between described images and distributed content.

Changes:

  • Update Outgoing_Post::get_post_media_data() to derive attachments from distributed content rather than re-rendering original the_content.
  • Add unit tests to ensure media_data includes dimensions for images present in distributed content, excludes the_content-injected images, and covers WP 7.1 dynamic galleries once flattened.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
plugins/newspack-network/includes/content-distribution/class-outgoing-post.php Switches media scanning to use distributed content representation for media_data.
plugins/newspack-network/tests/unit-tests/content-distribution/test-outgoing-post.php Adds unit tests validating media_data coverage/exclusion behavior, including dynamic gallery cases.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread plugins/newspack-network/includes/content-distribution/class-outgoing-post.php Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

plugins/newspack-network/tests/unit-tests/content-distribution/test-outgoing-post.php:622

  • Block processor outgoing callbacks are invoked as callback( $block, $post_id ) (see Block_Processor::process_outgoing_block). This test registers a callback that declares no parameters, which will receive 2 args and can throw an ArgumentCountError on PHP 8+.
			'core/image',
			function () use ( $replacement ) {
				return parse_blocks( $replacement )[0];
			}
		);

plugins/newspack-network/tests/unit-tests/content-distribution/test-outgoing-post.php:647

  • Block processor outgoing callbacks are invoked as callback( $block, $post_id ). This callback only declares one parameter, so it will receive an unexpected second arg and can throw an ArgumentCountError on PHP 8+.
			'core/image',
			function ( $block ) {
				add_filter( 'jetpack_photon_override_image_downsize', '__return_true' );
				remove_filter( 'jetpack_photon_override_image_downsize', '__return_true' );
				return $block;

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@rbcorrales rbcorrales changed the title fix(network): derive media_data from the distributed content fix(network): describe the images the receiving site actually stores Sep 1, 2026
@rbcorrales
rbcorrales marked this pull request as ready for review September 1, 2026 21:55
@rbcorrales
rbcorrales requested a review from a team as a code owner September 1, 2026 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants