Meta consulta com valor booleano verdadeiro / falso

11

Estou tentando mostrar todas as propriedades de aluguel, primeiro todas as propriedades que não foram alugadas e depois todas as propriedades que estão alugadas no momento. Existe um tipo de postagem personalizado 'aluguel' com uma meta de postagem personalizada para o preço alugado (_price_rented), que é uma caixa de seleção (retorna verdadeiro ou falso ... verdadeiro se tiver sido alugado). 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á a 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, essa consulta mostra todas as propriedades que foram alugadas. Quando alterno o valor de 'false' para 'true' na meta_query, ele não mostra nenhuma propriedade.

Então, 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 sei como consultar um resultado NULL (não falso), adicionei um ' compare 'argumento com a meta_query e defina o valor como'! = ', mas isso também não funcionou.

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

Kegan Quimby
fonte
usando os valores 1 e 0, talvez?
31713 reikyoushin
meta_query type => string. Os valores possíveis são 'NUMÉRICO', 'BINÁRIO', 'CHAR', 'DATA', 'DATETIME', 'DECIMAL', 'ASSINADO', 'HORA', 'NÃO ASSINADO'. O valor padrão é 'CHAR'.
IEmanuele 31/07
@reikyoushin: usar um '1' retorna todas as propriedades alugadas e um '0' não retorna nenhuma propriedade.
precisa
11
@ iEmanuele: mudar isso parece não ter efeito (pensei a mesma coisa). Eu vi isso neste artigo: thethemefoundry.com/blog/…
Kegan Quimby 31/07/2013
11
_price_rentedNa verdade, está definido para ambos truee falsevalores, ou está definido apenas para true? Verifique o banco de dados, por favor. Eu perguntei porque uma caixa de seleção desmarcada não é passada POST, então estou me perguntando se o valor está definido para esses casos.
Julio

Respostas:

4

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

Quando você está fazendo a new WP_Query()e possui meta_query => array()argumentos ou seu único par de chave / valor equivalente, new WP_Meta_Query()entra em ação , seguido instantaneamente pela análise.

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

Valores permitidos

Quando você consulta metadados, há uma boolopção. E se você usá-lo, ele retornará a CHAR, qual o valor padrão como a matriz de valores permitidos é:

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

onde NUMERICserá redefinido para SIGNED.

Depuração

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

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

Então, dependendo do valor de retorno, você terá que usar SIGNED, se o resultado for 0ou 1, ou "true"ou "false"se o resultado for uma sequência. Se for realmente booleano, ainda assim sugiro usar stringapenas para garantir que ele passe $GLOBALS['wpdb'], o que só pode passar uma %sstring e um %ddígito.

Notas Adicionais

Como eu só atualizou a entrada Codex paraWP_Meta_Query hoje, eu vi que lá está muitas saídas diferentes (adicionando inúmeras quantidades de desnecessários JOINS, que são discutidas no Trac aqui e aqui com a um único patch mudou para core) possível. (Ticket de acompanhamento de ANDpeças aqui ) O ponto é que é possível usar uma combinação de meta_*argumentos ao lado da meta_querymatriz e de seus subarrays. O resultado é praticamente desconhecido, a menos que você o despeje, então IMHO é melhor usar uma ou a outra maneira de adicionar entradas. Especialmente quando você é apenasusando meta_key, pois isso resulta em uma "consulta apenas de chave" em alguns casos.

Solução

Como apontado nos comentários:

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

Agora o meta_querytem que 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 usar '!='para recuperar os apartamentos "não alugados".

Nota: Valores possíveis para meta_comparesão '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP'ou 'RLIKE'. O valor padrão é '='.

kaiser
fonte
3

Eu enfrentei o mesmo problema e após uma hora de pesquisa encontrou o "NOT EXISTS"e "EXISTS"valor ( only in WP >= 3.5 ). Portanto, não é necessário solicitar um valor meta, basta verificar se a meta_key existe:

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

Está funcionando perfeitamente para mim.

Thibaut
fonte
3

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

Mais detalhes:

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

Parte 1: Examinei o SQL gerado por WP_Meta_Querypara comparações com true e false, e descobri que true substitui '1' e false '' (a sequência vazia). Portanto, o que quer que você escreva no banco de dados precisa concordar com isso, se você for fazer consultas comparadas aos valores reais e falsos reais. Em particular, você não deseja escrever '0' para falso. Pode ser mais infalível 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 lembre-se disso ao criar sua consulta.

Parte 2: Assumindo que false é o valor padrão, é fácil encontrar registros cujo valor é true:

... '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 tiver sido listado como opcional em um formulário - desde que o usuário não o configure ou altere explicitamente, ele não será adicionado ao banco de dados. Observe que, se você estiver usando apenas get_post_meta, funcionará bem desta maneira: 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, ainda não descobri como).

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

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

  2. Faça duas consultas, a primeira que testa um valor falso e a segunda que testa nenhum valor. Eles podem ser combinados em um único WP_Query como este:

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

Provavelmente, essa 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 significar falso. Para fazer isso, sempre que o valor deve ser definido como falso, você deve excluir o valor meta em vez de atualizá- lo.

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

Denise Draper
fonte