Notes:
It looks like you're not using $wpdb->prepare()
, so you risk SQL injections.
I also think you're missing parentheses around the relevant OR parts, so you don't end up displaying drafts, for example.
Alternative:
Instead of writing an hardcoded SQL query, we should be able to use the WP_Query
class, with some modifications through hooks/filters.
Here's an example (PHP 5.4+):
$args = [
'_meta_or_like_title' => $trimmed, // Our new custom argument!
'post_type' => 'product',
'post_status' => 'publish',
'meta_query' => [
[
'key' => 'product_model',
'value' => $trimmed, // Your meta value
'compare' => 'LIKE'
]
],
'tax_query' => [
[
'taxonomy' => 'product-brand',
'field' => 'slug',
'terms' => $protected, // Your terms array
'operator' => 'NOT IN'
]
]
];
where the custom _meta_or_like_title
argument is supported by a slightly modified plugin I wrote for another question here.
Plugin:
<?php
/**
* Plugin Name: Meta OR LIKE Title query in WP_Query
* Description: Activated through the '_meta_or_like_title' argument of WP_Query
* Plugin URI: https://mcmap.net/q/880971/-how-to-exclude-results-from-custom-wordpress-mysql-query-by-taxonomy-term
* Plugin Author: Birgir Erlendsson (birgire)
* Version: 0.0.1
*/
add_action( 'pre_get_posts', function( $q )
{
if( $title = $q->get( '_meta_or_like_title' ) )
{
add_filter( 'get_meta_sql', function( $sql ) use ( $title )
{
global $wpdb;
// Only run once:
static $nr = 0;
if( 0 != $nr++ ) return $sql;
// Modify WHERE part:
$sql['where'] = sprintf(
" AND ( %s OR %s ) ",
$wpdb->prepare(
"{$wpdb->posts}.post_title LIKE '%%%s%%'",
$wpdb->esc_like( $title )
),
mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
);
return $sql;
});
}
}, PHP_INT_MAX );
posts_*
filter way. Like your custom approach better than mine :-) – Monniemono