distributor icon indicating copy to clipboard operation
distributor copied to clipboard

Using Distributor and the Rewrite & Republish function of Duplicate Post plugin

Open mrrrlou opened this issue 1 year ago • 4 comments

Is your enhancement related to a problem? Please describe.

Using Distributor and the Rewrite & Republish function of Duplicate Post plugin Using Distributor in combination with the Rewrite & Republish function of Duplicate Post plugin seems to be an issue. This is because the R & R function creates a (temporary) draft version, which causes the distributed content to no longer work as expected.

The following is what happens:

  • The original content exists on site A. This content has (for example) ID 01. This content is distributed to site B (and it has been published).
  • We then rewrite the content on site A => this will create a draft post with ID 02 (on site A)
  • The content on site B gets connected to the draft with ID 02 of site A
  • The draft (ID 02) on site A is then published. This will merge it into content with ID 01. Draft post with ID 02 will be deleted.
  • However, on site B, the content on this site will be converted from ‘published’ to ‘draft’ status. It will still be connected to the draft with ID 02 on site A (which no longer exists).
  • On site A, when you check if it has distributed content, you’ll still see that it’s still connected to the content on Site B. However, when you click on the link it will throw a 404.
  • On site B, if you either edit or publish that distributed content and then navigate away from that content, it will disappear completely! It’s not even in the trash, it just seems to have been deleted.

Our client's work-around for now (which is tedious when you have multiple sites):

  • Again, the original content exists on site A. This has been distributed to sites B, C and D.
  • Go to distributed content on sites B, C and D => manually select ‘Unlink from Original’
  • On site A, 'Rewrite & Republish' content and publish (either planned or direct)
  • Go to sites B, C and D, to the previously unlinked content and link it again to original content

Request:

  • Possible fix so it works correctly? Could the filter mentioned here https://10up.github.io/distributor/dt_distributable_post_statuses.html fix this?
  • Or this would be of help as well: https://github.com/10up/distributor/issues/1291

Designs

No response

Describe alternatives you've considered

No response

Code of Conduct

  • [x] I agree to follow this project's Code of Conduct

mrrrlou avatar Feb 11 '25 16:02 mrrrlou

@mrrrlou my initial assumption is that the R&R plugin is copying the Distributor meta where it stores the mapping from origin to remote posts, so you might also want to look into how the Yoast R&R plugin could be extended to specifically NOT copy that metadata when creating a duplicate post.

jeffpaul avatar Feb 11 '25 16:02 jeffpaul

Thanks! We'll have a try with that suggestion

mrrrlou avatar Feb 27 '25 09:02 mrrrlou

Hi @jeffpaul

We've discovered that when using the "Rewrite & republish" feature of Yoast Duplicate post, all filters are getting bypassed. Therefore the filter documented on this Distributor documentation page gets bypassed, and does not work.

And this causes the problems as described by @mrrrlou.

  • When you "merge" the rewritten post to the original post, distributor deletes the distributed post on the other subsite (as after merging, the rewritten post gets deleted)
  • When you edit a concept rewritten post, the changes are directly distributed to the distributed post on the other subsite.

The best fix would be to ask Yoast why using filters is disabled in the "Rewrite & republish" feature. And hopefully then allowing filtering again.

In the meantime, we've come up with a little hacky solution to bypass the issue. When a post is copied for rewriting (detected using add/update meta hook), delete all distributor meta from the copy. The code looks like the following

class YoastDuplicatePostDistributorConflicts {

	public function register_hooks(): void {
		add_filter( 'duplicate_post_excludelist_filter', array( $this, 'exclude_distributor_meta' ) );
		add_action( 'update_post_meta', array( $this, 'delete_distributor_meta_after_creating_copy_for_rewriting_update_meta' ), 10, 4 );
		add_action( 'add_post_meta', array( $this, 'delete_distributor_meta_after_creating_copy_for_rewriting_add_meta' ), 10, 3 );
	}

	/**
	 * Get the distributor meta keys that should be excluded from duplication.
	 *
	 * @return string[]
	 */
	protected function get_distributor_meta_keys(): array {
		return array(
			'dt_connection_map',
			'dt_subscription_update',
			'dt_subscriptions',
			'dt_subscription_signature',
		);
	}

	/**
	 * Exclude distributor meta from being duplicated with Yoast Duplicate Post.
	 * This will make sure that the copy of the post does not keep the same
	 * distributor relations to the distributed version of the original post.
	 *
	 * @param string[] $meta_excludelist
	 * @return string[]
	 */
	public function exclude_distributor_meta( array $meta_excludelist ): array {
		// Merges the defaults array with our own array of custom fields.
		return array_merge( $meta_excludelist, $this->get_distributor_meta_keys() );
	}

	public function delete_distributor_meta_after_creating_copy_for_rewriting_update_meta( int $meta_id, int $post_id, string $meta_key, mixed $meta_value ): void {
		$this->maybe_delete_distributor_meta_after_creating_copy_for_rewriting( $post_id, $meta_key, $meta_value );
	}

	public function delete_distributor_meta_after_creating_copy_for_rewriting_add_meta( int $post_id, string $meta_key, mixed $meta_value ): void {
		$this->maybe_delete_distributor_meta_after_creating_copy_for_rewriting( $post_id, $meta_key, $meta_value );
	}

	/**
	 * After a copy of the post is created for rewriting, delete the distributor
	 * meta from the copy. This will prevent conflicts with the distributor plugin
	 *
	 * - Prevents issue where saving a copy will overwrite the distributed post
	 *   with the copy that's not done yet.
	 * - Prevents issue where the distributed version is deleted if the copy is deleted.
	 */
	private function maybe_delete_distributor_meta_after_creating_copy_for_rewriting( int $post_id, string $meta_key, mixed $meta_value ): void {
		// If incorrect meta key, return.
		if ( $meta_key !== '_dp_is_rewrite_republish_copy' ) {
			return;
		}

		// If meta value is not true (when converted to bool), return.
		if ( ! filter_var( $meta_value, FILTER_VALIDATE_BOOL ) ) {
			return;
		}

		// Delete the distributor meta from the copy.
		foreach ( $this->get_distributor_meta_keys() as $meta_key ) {
			delete_post_meta( $post_id, $meta_key );
		}
	}
}

menno-ll avatar Apr 08 '25 11:04 menno-ll

I've created an issue in the Yoast Duplicate Post plugin repo to hopefully get a more permanent solution for everyone.

menno-ll avatar Apr 08 '25 12:04 menno-ll