meta_query pour les clés qui ne sont pas encore définies

8

J'essaie de rechercher un type de publication personnalisé pour un système de galerie. J'ai une case à cocher pour définir une galerie en tant que galerie "en vedette" (configurée via le plugin More Fields) - si cette case est cochée, la méta-valeur devient 1, puis si elle n'est pas cochée, elle devient 0. Tout va bien. Cependant, si la case n'a jamais été cochée, la méta-clé n'est jamais créée, ce qui signifie que je ne peux pas rechercher NOT LIKE 1 car il n'existe pas.

La requête que je veux est de retirer 4 galeries qui ne sont pas marquées comme «1» dans cette méta-valeur, mais aussi celles qui n'ont pas cette valeur du tout. Existe-t-il un moyen de toujours donner aux publications nouvellement ajoutées une valeur par défaut pour cette clé méta (c.-à-d. Toujours les rendre 0 par défaut si la case n'est pas cochée) ou existe-t-il un moyen de rechercher la clé qui n'est pas encore définie?

Ma requête actuelle est:

$args = array(
                        'post_type' => 'gallery',
                        'showposts' => 4,
                        'meta_key' => 'gal-ID',
                        'order_by' => 'meta_value',
                        'order' => 'ASC',
                        'meta_query' => array( array(
                                            'key' => 'main-gal',
                                            'value' => false,
                                        ) ),
                        ) );

Et j'ai essayé plusieurs tentatives avec 'compare' => 'NOT LIKE', '! =' Etc etc.

Des idées? Ce ticket semble impliquer que c'est quelque chose qui devrait être réglé:

http://core.trac.wordpress.org/ticket/18158

Merci!

parcs d'art
la source

Réponses:

7

Cette fonction massive était un peu effrayante, je l'ai fait fonctionner comme ça - avec deux arguments (qui excluent les fonctionnalités)

$args = array(

    'meta_query' => array(
        'relation' => 'OR',
            array( // new and edited posts
                'key' => 'Set as Featured Post',
                'compare' => '!=',
                'value' => 1
            ),

            array( // get old posts w/out custom field
                'key' => 'Set as Featured Post',
                'value' => '1',
                'compare' => 'NOT EXISTS'
            ) 
        ),
    'posts_per_page' => 30

);
ArleyM
la source
Mon premier tableau remplace le second avec cette solution. Il semble que vous ne puissiez pas double-interroger le même champ?
Allen Gingrich
3

Selon les paramètres de champ personnalisés du Codex, une NOT EXISTScomparaison spéciale est disponible depuis WP version 3.5

Techniquement, cela produit quelque chose comme la requête SQL suivante dans les demandes de publication:

$posts = get_posts( array(
    'meta_query' => array(
        array(
            'key'     => 'wrong',
            'compare' => 'NOT EXISTS',
        ),
    ),
) );
SELECT *,wp_posts.ID
FROM wp_posts
LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'wrong')
WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish') AND (wp_postmeta.post_id IS NULL)
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 5

Il fonctionne en joignant la méta-table sur la clé fournie et en sélectionnant uniquement les enregistrements où cela n'avait pas donné lieu à des données significatives ( IS NULL). Donc, cela ne fonctionne que pour le cas où la clé n'existe pas du tout et ne fonctionnera pas pour les clés qui existent avec des valeurs fausses .

Rarst
la source
Je suis intrigué par cette NOT EXISTScomparaison. Pour contourner save_postles méta-clés non définies , je sauvegarde simplement un 0 sur le crochet si la méta-clé n'est pas définie. Comment ça NOT EXISTSmarche? Va-t-il trier la requête de l'OP par main-gal, puis remplir le 4 avec les messages qui n'ont pas cette méta?
helgatheviking
@helgatheviking J'ai élaboré sur la mécanique en réponse
Rarst
2

Comme l'a souligné le ticket, il n'est pas pris en charge .. jusque-là, vous devrez compter sur une solution personnalisée.

Quelques utilisateurs l'ont déjà demandé, ou du moins demandé comment le faire sur les forums WordPress.org, j'ai donc écrit une fonction pour faire le travail que je n'ai jamais gardé (coller), heureusement j'ai trouvé le sujet d'origine où j'ai fourni le lien pastebin (qui ne devrait pas expirer).

http://pastebin.com/kgLt1RrG

Je l'ai écrit il y a 8 mois et je ne l'ai pas testé (depuis), alors faites-moi part de tout problème.

J'espère que cela pourra aider..

t31os
la source
Cool, merci pour cela - le testera plus tard ce soir et vous fera savoir ce qui se passe.
artparks
1

La méthode la plus simple, mais pas la plus propre:

$args = array(
    'post_type' => 'gallery',
    'posts_per_page' => -1,
    'meta_key' => 'gal-ID',
    'order_by' => 'meta_value',
    'order' => 'ASC',
    'meta_key' => 'main-gal',
    ) );

Cela vous donnera toutes vos galeries triées par la clé méta. L'étape suivante consiste à déterminer si les galeries avec la valeur 1 viennent après ou avant les autres publications. De cette façon, vous pouvez soit:

  • Traitez les éléments jusqu'à ce que vous ayez traité 4 éléments de la galerie ou atteint une publication avec une méta-valeur de 1
  • Sautez les messages avec une méta valeur 1 puis commencez le traitement lorsque vous atteignez la première valeur non 1

Autres méthodes ne nécessitant pas d'instruction SQL personnalisée:

  • Faire une requête pour trouver les galeries dont vous ne voulez pas, l'utiliser pour remplir un tableau d'ID de publication, puis faire une deuxième requête, en passant ce tableau en tant que publications à exclure
  • Utiliser une taxonomie au lieu de champs personnalisés (résout cela très bien et met beaucoup d'autres belles améliorations gratuitement, ce qui vous fait gagner du temps aussi)
Tom J Nowell
la source