I can see two different ways to achieve this.
Solution 1 (file from the media library)
There is a filter that you can use to override (or provide a default value) for the get_the_post_thumbnail_url() function.
During the process, the function will call get_post_meta() which will eventually call the filter get_{$meta_type}_metadata.
What you can do is hook this filter with something like :
add_filter( 'get_post_metadata', function ( $metadata, int $object_id, string $meta_key, bool $single, string $meta_type ) {
// @todo fetch a predefined file ID (this must be an existing file from the media library).
return $metadata;
}, 10, );
The drawback form this method is that you cannot provide some random URL, but you need to use an existing file from the media library.
Solution 2 (any custom URL)
In order to provide a fully customizable URL for your post thumbnail, you will need to hook 3 different functions.
add_filter( 'has_post_thumbnail', 'so52332168_hasPostThumbnail', 10, 3 );
add_filter( 'get_post_metadata', 'so52332168_getPostThumbnailFileId', 10, 4 );
add_filter( 'wp_get_attachment_image_src', 'so52332168_getPostThumbnailSrc', 10, 4 );
/**
* Use any way you want to determine if your post should have a custom thumbnail URL.
*
* @param $has_thumbnail
* @param $post_id
* @param $thumbnail_id
*
* @return bool
*/
function so52332168_hasPostThumbnail( $has_thumbnail, $post_id, $thumbnail_id ) {
if ( ! $has_thumbnail ) {
// @todo check if the $post_id match any rule to get a custom thumbnail.
// if so, return true here
return true;
}
return $has_thumbnail;
}
/**
* Force override the thumbnail URL.
*
* @param $value
* @param $object_id
* @param $meta_key
* @param $single
*
* @return int
*/
function so52332168_getPostThumbnailFileId( $value, $object_id, $meta_key, $single ) {
if ( '_thumbnail_id' === $meta_key ) {
// @todo check if the current $object_id should get a custom thumbnail (probably the same check as above)
global $customPostThumbnailUrl;
$customPostThumbnailUrl = 'https://placekitten.com/300/300';
// return the fake thumbnail id -> this should absolutely never match an actual file id
return PHP_INT_MAX;
}
}
}
return $value;
}
/**
* Eventually return the URL that we "calculate" for the post.
*
* @param $image
* @param $attachment_id
* @param $size
* @param $icon
*
* @return array
*/
function so52332168_getPostThumbnailSrc( $image, $attachment_id, $size, $icon ) {
global $customPostThumbnailUrl;
// check that the attachment id is the one we returned previously
if ( (PHP_INT_MAX === $attachment_id) && $customPostThumbnailUrl ) {
// return our custom image URL
return [ $customPostThumbnailUrl ];
}
return $image;
}