Search SOMENTE por meta key / meta values

4

Estou quase lá nessa.

Em functions.php eu tenho isso:

function base_home_product_post_type( $query ) {

    if($query->is_search() && $_POST['box'] == 'sku') {
        $query->query_vars['post_type'] = 'product';
        $query->query_vars['meta_key'] = 'sku';
        $query->query_vars['meta_value'] = $query->query_vars['s'];
        return;
    }

}
add_action('pre_get_posts', 'base_home_product_post_type', 1);

E faz o que é dito. Procura pela cadeia de pesquisa na meta_key 'sku'. O problema aqui é que, por padrão, o objeto de consulta retornado do WordPress também contém isso e consulta post_title e post_content por padrão:

SELECT SQL_CALC_FOUND_ROWS  whirl_2_posts.ID FROM whirl_2_posts  INNER JOIN whirl_2_postmeta ON (whirl_2_posts.ID = whirl_2_postmeta.post_id) WHERE 1=1  AND (((whirl_2_posts.post_title LIKE '%__SEARCH_STRING__%')  OR (whirl_2_posts.post_content LIKE '%__SEARCH_STRING__%')))

Eu realmente não quero isso quando estou procurando apenas pelo valor "sku", então eu tentei removê-lo usando posts_where e alguns REGEX bastante feios como este (aviso, hacky e bugs):

function get_rid_of_titles($search) {
    if(is_search() && $_POST['box'] == 'sku') {
    $search = preg_filter('|AND\s\({3}\w*\.post_title\sLIKE\s\'\%[^%]*\%\'\) OR \(\w*\.post_content\sLIKE\s\'\%[^%]*\%\'\){3}\s|', '', $search);
    }
    return $search;
}
add_filter('posts_where','get_rid_of_titles');

Mas sem sorte. Alguém pode me apontar os procedimentos para pesquisar onlu para o valor personalizado nesse caso?

SOLUÇÃO

Graças ao @kaiser abaixo, consegui este trabalho:

function get_rid_of_titles($search) {

    if(is_search() && $_POST['box'] == 'sku') {

          $sku = $_POST['s'];          // get search string
          $needle = "LIKE '%$sku%'";   // search only for LIKE '%_SEARCH_STRING_%'. This is a multisite environment, so involving table names directly is a bad idea
          $replace = "LIKE '%'";       // replace it with SQL Wildcard so any title and any content are welcome
          $count = 2;                  // only the first 2 occurrencies which happen to be post_title and post_content
          return str_replace($needle,$replace,$search, $count);

    }
}
add_filter('posts_where','get_rid_of_titles');
    
por moraleida 30.08.2012 / 03:12

1 resposta

2

Você pode fazer duas coisas:

A) substitua a pesquisa por uma consulta SQL que pesquise apenas a tabela postmeta (mais rápido, já que não há JOIN envolvido - você pode obter a postagem via ID mais tarde, ao exibir os resultados).

B) Divida a string logo após WHERE 1=1 e solte a parte posterior. Você pode usar um simples return str_replace( $query_part_below, '', $search ); .

 AND (
    (whirl_2_posts.post_title LIKE '%__SEARCH_STRING__%')  
    OR (whirl_2_posts.post_content LIKE '%__SEARCH_STRING__%')
)

Certifique-se de que você usou $wpdb->prepare() corretamente antes de voltar a inseri-lo.

    
por kaiser 30.08.2012 / 03:55