Home › Forums › Backend Issues (wp-admin) › Post object option ignores a custom post type › Reply To: Post object option ignores a custom post type
Hi,
I don’t know if we are sharing the same issue (and for me, the issue stretches further back than 5.2.5) but I’ve figured out mine.
The Context:
The project I’m currently working on uses Polylang for translations. Custom fields aren’t set to be translated, their data is synced manually.
I have a post object setup to retrieve posts from two custom post types: partner
and sponsor
. These post types aren’t configured to be multilingual.
The Issue:
In acf_field_post_object::render_field()
, if there’s a saved value, ACF will retrieve all posts matching the saved value (in order to pre-populate the rendered field).
$posts = acf_get_posts(array(
'post__in' => $field['value']
));
Unfortunately, this returns an empty array because acf_get_posts()
will default to loading from all available post types. In my case, acf_get_post_types()
returns: post
, page
, attachment
, partner
, and sponsor
.
And this is the key problem: post
and page
are configured to be multilingual. This triggers Polylang to add a condition to fetch posts in the current language which the non-multilingual post types can’t fulfill.
First Solution:
Require ACF to pass along the filtered list of post types:
$posts = acf_get_posts(array(
'post__in' => $field['value'],
'post_type' => $field['post_type']
));
The one downside of this is if the list of filtered post types changes (e.g., a post type is removed), it will affect any currently saved value assigned to that now-removed post type.
Second Solution:
Intercept Polylang before it adds that language condition to the WP_query
. I accomplish this using a backtrace to figure out if the WP_query
was called by acf_get_posts()
by way of acf_field->render_field()
.
**Updated 2015-05-21T17:22-05:00**
add_action( 'pre_get_posts', function ( &$wp_query ) {
$is_acf_get_posts = (
( $e = new Exception )
&& ( $trace = $e->getTraceAsString() )
&& false !== strpos( $trace, 'acf_get_posts(Array)' )
&& (
( is_admin() && false !== strpos( $trace, '->render_field(Array)' ) )
|| ( ! is_admin() && false !== strpos( $trace, '->format_value(' ) )
)
);
if ( $is_acf_get_posts && pll_is_not_translated_post_type( $wp_query->get('post_type') ) ) {
pll_remove_language_query_var( $wp_query );
}
}, 9 );
function pll_is_not_translated_post_type( $post_type ) {
global $polylang;
if ( isset( $polylang ) ) {
$pll_post_types = $polylang->model->get_translated_post_types( false );
return ( is_array( $post_type ) && array_diff( $post_type, $pll_post_types ) || in_array( $post_type, $pll_post_types ) );
}
return false;
}
function pll_remove_language_query_var( &$query ) {
$qv = &$query->query_vars;
unset( $qv['lang'] );
if ( ! empty( $qv['tax_query'] ) ) {
foreach ( $qv['tax_query'] as $i => $tax_query ) {
if ( isset( $tax_query['taxonomy'] ) && 'language' === $tax_query['taxonomy'] ) {
unset( $qv['tax_query'][ $i ] );
}
}
}
}
I made this filter very verbose just to make sure the idea is understand. I’m using a much more compact version in my project. This function can also be easily translated to your multilingual-plugin flavour (e.g., WPML).
Cheers,
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.