Consulta meta com valor booleano verdadeiro / falso

8

Estou tentando mostrar todas as propriedades de aluguel, primeiro por todas as propriedades que não foram alugadas e, em seguida, por todas as propriedades atualmente alugadas. Há um tipo de mensagem personalizada 'rent' com meta post personalizada para preço alugado (_price_rented) que é uma caixa de seleção (retorna true ou false ... true se tiver sido alugada). Preciso alterar a consulta para mostrar todas as propriedades com as propriedades disponíveis (não alugadas) aparecendo primeiro e depois as propriedades alugadas aparecendo.

Aqui está minha consulta:

$ts_properties = new WP_Query( 
    array( 
    'post_type' => 'rent', 
    'paged' => $paged, 
    'posts_per_page' => -1,
    'meta_key' => '_price_rented',
    'orderby' => 'meta_value',
    'order' => 'DESC',
    'meta_query' => array(
        array(
        'key' => '_price_rented',
        'value' => false,
        'type' => 'BOOLEAN',
        ),
    ) 
) 
);

Por algum motivo, esta consulta mostra todas as propriedades que foram alugadas. Quando eu alterno o valor de 'false' para 'true' no meta_query, ele não mostra nenhuma propriedade.

Então, eu pensei, o valor de retorno é falso (para propriedades que são alugadas) ou NULL (para propriedades que NÃO são alugadas), mas não tenho certeza de como consultar um resultado NULL (não falso), adicionou um argumento 'compare' ao meta_query e definiu o valor para '! =', mas isso também não funcionou.

EDIT: var_dump retorna o seguinte para um apartamento disponível e não alugado: string(0) "" e para um apartamento alugado não disponível: string(1) "1"

    
por Kegan Quimby 31.07.2013 / 17:23

3 respostas

3

Eu enfrentei o mesmo problema e depois de uma hora de pesquisa, encontrei o "NOT EXISTS" e o "EXISTS" value ( only in WP >= 3.5 ) . Portanto, não há necessidade de pedir um valor meta, apenas verifique se o meta_key existe:

'meta_key'     =>   '_price_rented'  ,
'meta_compare' =>   'NOT EXISTS'     ,

Está funcionando perfeitamente para mim.

    
por Thibaut 11.12.2013 / 11:58
3

WP_Meta_Query é de alguma forma "não tão estável" parte no núcleo e se você não pagar muito atenção, pode facilmente deixar de ser confundido.

Quando você está fazendo um new WP_Query() e tem meta_query => array() argumentos ou seus pares equivalentes de chave / valor, então new WP_Meta_Query() salta, instantaneamente seguido por análise.

$this->meta_query = new WP_Meta_Query();
$this->meta_query->parse_query_vars( $q );

Valores permitidos

Quando você consulta metadados, há a opção bool . E se você usá-lo, ele retornaria para CHAR , que é o valor padrão como a matriz de valores permitidos:

'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'

onde NUMERIC será redefinido para SIGNED .

Depuração

Existem inúmeros filtros que podem afetar o processo de pós-salvamento, então a primeira coisa a fazer é verificar os valores diferentes dentro de algum loop:

var_dump( get_post_meta( get_the_ID(), '_price_rented', true ) );

Em seguida, dependendo do valor de retorno, você precisará usar SIGNED , se o resultado for 0 ou 1 , ou "true" ou "false" se o resultado for uma string. Se realmente for booleano, sugiro usar string apenas para garantir que ele passe $GLOBALS['wpdb'] , que só pode transmitir %s string e %d dígito.

Notas Adicionais

Como acabei de atualizar a entrada do Codex para WP_Meta_Query hoje, vi que há muitas saídas diferentes (adicionando numerosas quantidades desnecessárias de JOINS , que são discutidas em Trac aqui e aqui com out um único patch movido para o core) possível. (Bilhete de acompanhamento para AND parts aqui ) O ponto é que é possível para usar uma combinação dos argumentos meta_* junto com a matriz meta_query e seus subarrays. O resultado é praticamente desconhecido a menos que você o despeje, então IMHO é melhor usar o ou a outra forma de adicionar entradas . Especialmente quando você está somente usando meta_key , pois isso resulta em uma "consulta somente de chave" em alguns casos.

Solução

Como apontado nos comentários:

  

(...) var_dump retorna o seguinte para um apartamento disponível e não alugado: string(0) "" e para um apartamento não disponível alugado: string(1) "1"

Agora, o meta_query precisa usar

'meta_query' => array( 'relation' => 'OR', array(
    'meta_key'     => '_price_rented',
    'meta_value'   => '1',
    'meta_compare' => '='
) );

Se você deseja obter os "apartamentos alugados não disponíveis" ou use '!=' para recuperar os apartamentos "não alugados".

Observação: os valores possíveis para meta_compare são '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP' ou 'RLIKE' . O valor padrão é '=' .

    
por kaiser 31.07.2013 / 18:28
2
  

TL; DR: Esse problema provavelmente ocorre principalmente quando um campo booleano é criado como opcional. Você pode corrigi-lo tornando-o obrigatório ou usando uma consulta mais complexa para recuperar o caso padrão.

Mais detalhes:

Há dois problemas de representação de dados acontecendo aqui: um é quais valores de dados estão sendo usados para representar verdadeiro / falso e o outro é se o campo está sendo armazenado ou não, se for o valor padrão (geralmente falso) .

Parte 1: Eu olhei para o SQL gerado por WP_Meta_Query para comparações com true e false e descobri que para true substitui '1' e false '' (a string vazia). Portanto, o que quer que você escreva no banco de dados precisa concordar com isso se você estiver fazendo consultas comparando com os valores reais e falsos reais. Em particular, você não quer escrever '0' para falso. Pode ser mais seguro escrever e testar 0 e 1 (e muitos construtores de formulários fazem isso). Mas verifique o que está sendo gravado no banco de dados e tenha isso em mente ao criar sua consulta.

Parte 2: Assumindo que falso é o valor padrão, localizando registros cujo valor é verdade é fácil:

... 'meta_key' => 'my_key', 'meta_value' => 1 (ou verdadeiro)

Mas o outro lado é desafiador: pode haver um valor falso ou pode não haver nenhum valor. Isso pode acontecer se o valor foi listado como opcional em um formulário --- e desde que o usuário não o defina ou altere explicitamente, ele não será adicionado ao banco de dados. Observe que, se você estiver usando apenas get_post_meta , funcionará muito bem desta forma: retornar um valor falso e retornar nenhum valor realizará a mesma coisa.

Mas quando você está usando WP_Query , não é tão fácil. (Ou se for, eu não descobri como ainda).

Você tem duas (ou talvez três) opções:

  1. Certifique-se de que o campo seja sempre inicializado explicitamente para um valor real. Em alguns construtores de formulário, você faz isso tornando o campo obrigatório e fornecendo um valor padrão. Então você pode testar ...'meta_value' => 0 de forma confiável.

  2. Faça duas consultas, a primeira que testa um valor falso e a segunda que testa sem valor. Estes podem ser combinados em uma única WP_Query como esta:

    meta_query => {
        relation => 'OR'
        array(
            'key'     => 'my_key',
            'value'   => 0,
            'compare' => '='
        ),
        array(
            'key'     => 'my_key',
            'compare' => 'NOT EXISTS',
        ),
    )
    

Esta provavelmente não é uma consulta eficiente. Dependendo de muitos fatores, pode ser melhor retornar todos os objetos e filtrá-los em seu próprio código.

  1. É possível usar "sem valor" para dizer falso. Para fazer isso, sempre que o valor for definido como false, você precisará excluir o meta valor em vez de atualizar .

Nesse caso, uma única consulta 'NOT EXISTS' retornará com confiança os objetos corretos. (Eu não acho que muitos construtores de formulário ou plugins suportam esse comportamento, então eu só usaria em código puramente personalizado.)

    
por Denise Draper 13.11.2016 / 07:34