I am the developer for WP-Members. I looked into this and found the issue. As you’ll see below, this can lead to a general improvement in how both plugins handle pre_get_posts
.
Both plugins use pre_get_posts
to apply an array of posts to posts__not_in
. The problem is that both apply their array in a way that assumes there are no other values in posts__not_in
, which cannot be assumed regardless of whether these two plugins are used together or not.
Search Exclude uses this for obvious reasons – it’s how the excluded posts are removed from the main query. WP-Members uses this for a similar purpose – the plugin has a setting to set posts as “hidden” which not only would exclude them from search, but any other use within the Loop.
WP-Members can improve the process (and will) based on merging any existing values already in post__not_in
. But if another plugin (such as Search Exclude, but not exclusive to this) applies values to post__not_in
assuming it is empty, then while WP-Members’ solution to this solves it for the other plugin, the other plugin would interfere with WP-Members removing its posts. (This would be true of any pair of plugins – not just these two that we’re discussing.)
I’ll be including a change in the next WP-Members update to merge in any existing values already in post__not_in
. In the meantime, I’ve posted the changed file (so anyone could apply this patch right away) as a gist here. For simplicity’s sake, you can just replace the /includes/class-wp-members.php file with the gist version to apply the change.
I would recommend that Search Exclude make a similar change in order to not assume that post__not_in
is empty, thus overwriting any existing values already being excluded.
In Search Exclude’s search-exclude.php, the searchFilter()
method is where post__not_in
is set, merging the plugin’s own array into an empty array:
if ($exclude) {
$query->set('post__not_in', array_merge(array(), $this->getExcluded()));
}
If you were to change that to merge the excluded values into any values already in post__not_in
, then it will include values from any other process excluding posts:
if ($exclude) {
$query->set('post__not_in', array_merge($query->query_vars['post__not_in'], $this->getExcluded()));
}
You might also want to experiment with changing the priority of your pre_get_posts
action. Right now, at the default, if something comes later, it could end up dumping Search Exclude’s post__not_in
for its own (such as the case in this issue, since WP-Members, while firing at the default “10” actually fires after Search Exclude because they are loaded in alphabetical order). I’m going to look at moving WP-Members pre_get_posts
action to 20 so that something early doesn’t inadvertently dump WP-Members’ array. You might want to consider a similar change.
Hope that explains the issue, offers some help, and moves forward to improving both plugins. I consider that it improves WP-Members, so thank you for bringing it up.