Include drafts in internal link dialog

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;
}