Override has_post_thumbnail function

Yes, there is a way to do that… Let’s take a look at has_post_thumbnail function itself:

function has_post_thumbnail( $post = null ) {
    return (bool) get_post_thumbnail_id( $post );
}

As you can see, all it really does is getting post thumbnail ID and checking if it exists. But there are no filters in here. Let’s go deeper:

function get_post_thumbnail_id( $post = null ) {
    $post = get_post( $post );
    if ( ! $post ) {
        return '';
    }
    return get_post_meta( $post->ID, '_thumbnail_id', true );
}

Still no filters, but there is a hope:

function get_post_meta( $post_id, $key = '', $single = false ) {
    return get_metadata('post', $post_id, $key, $single);
}

And at last in get_metadata

function get_metadata($meta_type, $object_id, $meta_key = '', $single = false) {
    if ( ! $meta_type || ! is_numeric( $object_id ) ) {
        return false;
    }

    $object_id = absint( $object_id );
    if ( ! $object_id ) {
        return false;
    }

    /**
     * Filters whether to retrieve metadata of a specific type.
     *
     * The dynamic portion of the hook, `$meta_type`, refers to the meta
     * object type (comment, post, or user). Returning a non-null value
     * will effectively short-circuit the function.
     *
     * @since 3.1.0
     *
     * @param null|array|string $value     The value get_metadata() should return - a single metadata value,
     *                                     or an array of values.
     * @param int               $object_id Object ID.
     * @param string            $meta_key  Meta key.
     * @param bool              $single    Whether to return only the first value of the specified $meta_key.
     */
    $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single );
    if ( null !== $check ) {
        if ( $single && is_array( $check ) )
            return $check[0];
        else
            return $check;
    }
    ...

It looks like we can use get_post_metadata hook to override has_post_thumbnail result. The only thing you have to remember is that it will change the behavior of get_post_thumbnail_id also…

Something like this should do the trick:

function my_override_has_post_thumbnail( $result, $object_id, $meta_key, $single ) {
    if ( '_thumbnail_id' === $meta_key ) {
        // perform your checks and return some ID if thumbnail exists
    }

    return $result;
}
add_filter( 'get_post_metadata', 'my_override_has_post_thumbnail', 10, 4 );