_wp_old_date, _wp_old_slug, and ActivityPub’s federation-state meta (activitypub_status, activitypub_deleted_at) are excluded so new drafts don’t inherit stale redirect data or a false “already federated” flag.lh_copy_to_draft( $post_id = null ), echoes a “Copy” link for use in themes (single-post copy, independent of the bulk action). If no $post_id is passed it falls back to the current post in the loop.lh_more_modal_template_list_end filter, if a theme/plugin provides that hook.The copy action is gated on WordPress’s own edit_post capability check for each specific post being copied — anyone who can already edit a given post can duplicate it. There is no separate admin settings screen, so install_plugins is not used here.
bulk-{plural}) before handle_bulk_actions-edit-{post_type} is ever called, so no additional nonce handling is required in the plugin.wp_nonce_url() using the action lh_copy_to_draft-{post_id}, and the handler (admin_action_lh_copy_to_draft_save_as_new_post) verifies that nonce with check_admin_referer() before performing the capability check and copy.No settings page. A Copy to draft option is added to the Bulk Actions dropdown on the list table screen for each applicable post type, and an admin notice reports the result after running it.
None. Uses core wp_posts, wp_postmeta, and term relationship tables only, via wp_insert_post(), add_post_meta(), and wp_set_post_terms().
None.
Some plugins store post-related data in their own custom tables rather than postmeta (e.g. an events plugin storing start/end dates for indexed queries). This plugin has no knowledge of any such table, and deliberately stays that way — but it provides a hook so other plugins can carry their own data across on copy:
do_action( 'lh_copy_to_draft_after_duplicate_post', $new_post_id, $post_object, $custom_overrides );
Fired after core fields, meta, and taxonomy terms have all been copied. $custom_overrides is an opaque array supplied by the caller — this plugin never inspects or validates its contents; it’s entirely up to the consuming plugin to interpret it and act.
If a consuming plugin’s data is also mirrored into postmeta, it can exclude that meta key from the default copy via lh_copy_to_draft_meta_defaults_filter (set the key to false), so it isn’t copied as a stale value before the consuming plugin re-derives the correct one in its own hook callback.