This is very similar to this question.
We have to hook into check_ajax_referer
to address the internal linking feature only. Then we register an action for pre_get_posts
to extend the search to drafts and pending posts.
We will still get no pretty permalinks, because they are excluded in get_permalink
. So we register a filter for that too and ask WordPress again for a permalink, but with a faked post status.
As code:
add_action( 'check_ajax_referer', 'internal_links_for_drafts' );
/**
* Extend search for internal links to 'draft' and 'pending' statuses.
*
* @wp-hook check_ajax_referer
* @wp-hook pre_get_posts
* @param string|WP_Query $var
* @return boolean|void
*/
function internal_links_for_drafts( $var )
{
if ( 'check_ajax_referer' === current_filter() && 'internal-linking' === $var )
return add_action( 'pre_get_posts', __FUNCTION__ );
// now we are in the 'pre_get_posts' action.
$var->set( 'post_status', array( 'publish', 'pending', 'draft' ) );
remove_action( 'pre_get_posts', __FUNCTION__ );
add_filter( 'post_link', 'draft_permalink', 10, 2 );
}
/**
* Get permalink for drafts and pending posts.
*
* Dangerous, because their title can still change.
*
* @param string $permalink
* @param object $post
* @return string
*/
function draft_permalink( $permalink, $post )
{
remove_filter( current_filter(), __FUNCTION__ );
// swap status temporary
$original_status = $post->post_status;
$post->post_status="publish";
$url = get_permalink( $post );
$post->post_status = $original_status;
return $url;
}