Skip to content

Instantly share code, notes, and snippets.

@WPprodigy
Last active September 9, 2020 20:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WPprodigy/a6e42dcb94bf4fb93201cf9065d79a7f to your computer and use it in GitHub Desktop.
Save WPprodigy/a6e42dcb94bf4fb93201cf9065d79a7f to your computer and use it in GitHub Desktop.
Co-Author Plus ES query fix
<?php
/**
* Co-Author Plus ES query fix.
*
* With CAP, authors are attached either with the traditional
* author field or via an "author" taxonomy. So we need to check both.
*/
add_filter( 'es_posts_request', function( $es_args, $query ) {
if ( ! $query->is_author() ) {
return $es_args;
}
// Remove default author filter, as it needs to be in an "OR" block instead.
$removed_author = false;
if ( isset( $es_args['filter']['and'] ) ) {
foreach ( $es_args['filter']['and'] as $index => $es_filter ) {
if ( isset( $es_filter['term']['author_login'] ) ) {
$removed_author = true;
unset( $es_args['filter']['and'][ $index ] );
}
}
}
// There isn't a query based on the author_name, so let's not continue.
if ( ! $removed_author || empty( $query->query_vars['author_name'] ) ) {
return $es_args;
}
$author_name = sanitize_title( $query->query_vars['author_name'] );
$new_filters = array(
array( 'term' => array( 'author_login' => $author_name ) ),
array( 'term' => array( 'taxonomy.author.name.raw_lc' => $author_name ) ),
);
// Merge the two new filters into an "OR" block.
$filter_or = isset( $es_args['filter']['or'] ) ? $es_args['filter']['or'] : array();
$es_args['filter']['or'] = array_merge( $filter_or, $new_filters );
return $es_args;
}, 20, 2 );
@WPprodigy
Copy link
Author

WPprodigy commented Sep 9, 2020

Not fully tested, but the elasticpress version would look something like this:

add_filter( 'ep_formatted_args', function( $formatted_args, $args, $wp_query ) {
	if ( is_admin() || ! $wp_query->is_author() ) {
		return $formatted_args;
	}

	// Try to remove the default author filter if one exists, as it needs to be in an "or/should" block instead.
	$removed_author = null;
	if ( isset( $formatted_args['post_filter']['bool']['must'] ) ) {
		foreach ( $formatted_args['post_filter']['bool']['must'] as $index => $es_filter ) {
			if ( isset( $es_filter['term']['post_author.id'] ) ) {
				$removed_author = $es_filter['term']['post_author.id'];
				unset( $formatted_args['post_filter']['bool']['must'][ $index ] );
			}
		}
	}

	// There isn't a query based on the author, so let's not continue.
	if ( null === $removed_author || empty( $wp_query->query_vars['author_name'] ) ) {
		return $formatted_args;
	}

	$author_name = sanitize_title( $wp_query->query_vars['author_name'] );
	$new_filters = array(
		array( 'term' => array( 'post.author.id' => $removed_author ) ),
		array( 'terms' => array( 'terms.author.name.raw' => $author_name ) ),
	);

	// Merge the two new filters into an "OR" block.
	$filter_or = isset( $formatted_args['post_filter']['bool']['should'] ) ? $formatted_args['post_filter']['bool']['should'] : [];
	$formatted_args['post_filter']['bool']['should'] = array_merge( $filter_or, $new_filters );

	return $formatted_args;
}, 10, 3 );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment