Skip to content
Subset

For developers

Developer reference

Duplicating from your own code, the filters that decide what is copied and by whom, the REST route and the WP-CLI command.

Every way of duplicating a post — the list actions, both editors, the admin bar, REST and WP-CLI — goes through one permission check and one engine, so the hooks on this page apply everywhere.

Duplicating from your own code

<?php
use Subset\Duplicator\Plugin;

$plugin = Plugin::instance();

// The engine does not check permissions itself, so check first.
$error = $plugin->permissions()->check( $post_id ); // null, or a WP_Error with an HTTP status
if ( null === $error ) {
	$copy_id = $plugin->duplicator()->duplicate(
		$post_id,
		array( 'title' => 'Landing page B' )
	);
}

duplicate() returns the copy’s ID or a WP_Error. If any step fails, the copy and any attachments it was given are deleted, so there is never a half-made post.

What gets copied

<?php
// Which post types can be duplicated at all.
add_filter( 'subset_dup_supported_post_types', function ( array $types ): array {
	return $types;
} );

// The fields passed to wp_insert_post() for the copy.
add_filter( 'subset_dup_post_data', function ( array $data, WP_Post $original, array $args ): array {
	$data['post_status'] = 'pending'; // send copies straight to review
	return $data;
}, 10, 3 );

// Meta keys left out. `*` matches any run of characters.
add_filter( 'subset_dup_excluded_meta_keys', function ( array $keys ): array {
	$keys[] = '_my_plugin_cache_*';
	return $keys;
} );

subset_dup_copy_title, subset_dup_meta_value, subset_dup_taxonomies and subset_dup_copy_attachments cover the title, individual meta values, taxonomies and attachment copies the same way.

Who may duplicate

<?php
// The last word, after the built-in checks.
add_filter( 'subset_dup_can_duplicate', function ( bool $can, int $post_id, int $user_id ): bool {
	return $can && ! get_post_meta( $post_id, '_locked', true );
}, 10, 3 );

Reacting to a copy

<?php
add_action( 'subset_dup_after_duplicate', function ( int $copy_id, int $original_id, array $args ) {
	// e.g. reset a view counter on the copy
}, 10, 3 );

subset_dup_before_duplicate fires before the copy is made. A copy records its original in the protected meta key _subset_dup_original.

REST

POST /wp-json/subset-duplicator/v1/posts/{id}/duplicate

It takes an optional title and attachments, and returns 201 with the copy’s id, original, type, status, title and edit_link.

WP-CLI

wp subset duplicator duplicate 42 43 --user=admin --title="Landing page B"

It runs as --user, through the same permission check and settings. Each ID that fails is reported, the rest are still duplicated, and the command exits 1 if any failed.