WordPress.org

Make WordPress Core

Opened 7 years ago

Last modified 10 months ago

#23983 reviewing enhancement

Add filter to get_post_thumbnail_id to override default thumbnail use

Reported by: Jesper800 Owned by: SergeyBiryukov
Milestone: Future Release Priority: normal
Severity: normal Version:
Component: Media Keywords: 2nd-opinion needs-testing has-patch
Focuses: Cc:
PR Number:

Description

The current function for getting the post thumbnail ID, used in among others get_the_post_thumbnail, is as follows:

function get_post_thumbnail_id( $post_id = null ) {
	$post_id = ( null === $post_id ) ? get_the_ID() : $post_id;
	return get_post_meta( $post_id, '_thumbnail_id', true );
}

In my opinion, this needs a filter, so the user can override this by the attachment of his choosing, such as an Advanced Custom Fields image attached to the post.

Something like:

function get_post_thumbnail_id( $post_id = null ) {
	$post_id = ( null === $post_id ) ? get_the_ID() : $post_id;
	return apply_filters( 'post_thumbnail_id', get_post_meta( $post_id, '_thumbnail_id', true ), $post_id );
}

I know you can hook into the get_{$meta_type}_metadata filter, but getting the post thumbnail ID should still be possible by using get_post_meta, the other thumbnail should just be used for displaying.

Attachments (2)

23983.patch (548 bytes) - added by gilbitron 5 years ago.
23983.2.patch (814 bytes) - added by sebastian.pisula 3 years ago.

Download all attachments as: .zip

Change History (18)

#1 @alexvorn2
7 years ago

this needs a filter, so the user can override this by the attachment of his choosing, such as an Advanced Custom Fields image attached to the post

This can confuse people.

Last edited 7 years ago by alexvorn2 (previous) (diff)

#2 @engelen
5 years ago

  • Keywords has-patch added

(formerly Jesper800)

Why would this confuse people? Hooking directly into get_post_meta would confuse people, but allowing a function return value to be filterable shouldn't. We're requesting the featured image for a post, not a raw database value. Allowing get_the_title to be filterable doesn't confuse people either, does it?

In my opinion this should be filterable, as it provides flexibility in a currently quite rigid thumbnail system. For example, one might want to use the thumbnail of a parent post if the post itself doesn't have one. Adding a filter adds more flexibility, there are more than enough realistic use cases, and it doesn't add any confusion.

In dire need of a second opinion :-).

#3 @wonderboymusic
5 years ago

  • Keywords needs-patch added; has-patch removed

@gilbitron
5 years ago

#4 @gilbitron
5 years ago

  • Keywords needs-testing added; needs-patch removed

#5 @sebastian.pisula
3 years ago

Second example: Via filter we can set the default thumbnail if post not set featured image

#6 @sebastian.pisula
3 years ago

  • Keywords has-patch added

#7 @SergeyBiryukov
3 years ago

Related: #40547 (suggests a filter for get_the_post_thumbnail_url()).

#8 @sebastian.pisula
3 years ago

I haven't control to overwrite meta value via get_post_metadata filter. Why? Because I can't check that post has _thumbnail_id.

In my filter I can check:

<?php
if (empty ($ post_thumbnail_id)) {
$post_thumbnail_id = 5;
}

return $post_thumbnail_id;

Additional solution is compatibility with has_post_thumbnail function :-)

#9 follow-up: @leogermani
2 years ago

+1 for this

hooking in get_%type%_metadata is messy, because you can not easily check wether the post has a post thumbnail or not inside your filter, you would end up in an endless loop if you call has_post_thumbnail()

In that case you have to do something like inside your callback:

$wpdb->get_var("SELECT meta_value FROM $wpdb->postmeta WHERE meta_key = '_thumbnail_id' AND post_id = $object_id");

not really beautiful.

#10 @SergeyBiryukov
20 months ago

  • Milestone changed from Awaiting Review to 5.0
  • Owner set to SergeyBiryukov
  • Status changed from new to reviewing

#11 @rzen
15 months ago

Adding my voice as a +1 to this. There have been so many cases over the years where I've desired to override the post thumbnail behavior by specifying an alternative post image.

Being able to filter this value as well as the has_post_thumbnail() are a necessary part of that process since different plugins or themes may (properly) be checking for has_post_thumbnail() before utilizing get_the_post_thumbnail() or get_the_post_thumbnail_url().

I don't see a ticket for the latter, so I'm going to go ahead and create that one now.

#12 in reply to: ↑ 9 @SergeyBiryukov
15 months ago

Replying to leogermani:

hooking in get_%type%_metadata is messy, because you can not easily check wether the post has a post thumbnail or not inside your filter, you would end up in an endless loop if you call has_post_thumbnail()

You can avoid an endless loop by removing and re-adding the filter:

function wp23983_get_featured_image_id( $null, $object_id, $meta_key, $single ) {
	if ( '_thumbnail_id' !== $meta_key ) {
		return $null;
	}

	if ( is_admin() ) {
		return $null;
	}

	remove_filter( 'get_post_metadata', __FUNCTION__, 10, 4 );

	$featured_image_id = get_post_thumbnail_id( $object_id );

	add_filter( 'get_post_metadata', __FUNCTION__, 10, 4 );

	// The post has a featured image.
	if ( $featured_image_id ) {
		return $featured_image_id;
	}

	// Do something else
	...

	return $featured_image_id;
}
add_filter( 'get_post_metadata', 'wp23983_get_featured_image_id', 10, 4 );

I agree it's not pretty though, and a filter would be helpful.

This ticket was mentioned in Slack in #core-media by joemcgill. View the logs.


14 months ago

#14 @joemcgill
14 months ago

A filter makes sense to me, although I'm unsure if filtering the ID is the correct approach, since someone might also want to replace the thumbnail with an outside source that doesn't have an ID. However, adding a filter to get_post_thumbnail_id() before the post meta lookup seems like a fine enhancement.

#15 @peterwilsoncc
13 months ago

  • Milestone changed from 5.0 to 5.1

Moving to the 5.1 milestone due to the WordPress 5.0 focus on the new
editor (Gutenberg).

#16 @pento
10 months ago

  • Milestone changed from 5.1 to Future Release

Bumping, as this needs further consideration as to whether it's the correct solution.

Note: See TracTickets for help on using tickets.