meta_query für Schlüssel, die noch nicht festgelegt sind

8

Ich versuche, einen benutzerdefinierten Beitragstyp für ein Galeriesystem abzufragen. Ich habe ein Kontrollkästchen, um eine Galerie als "vorgestellte" Galerie festzulegen (eingerichtet über das Plugin "Weitere Felder"). Wenn dieses Kontrollkästchen aktiviert ist, wird der Metawert 1 und wenn es deaktiviert ist, wird er 0. Alles gut. Wenn das Kontrollkästchen jedoch noch nie aktiviert wurde, wird der Metaschlüssel nie erstellt. Dies bedeutet, dass ich NICHT nach NOT LIKE 1 abfragen kann, da er nicht vorhanden ist.

Die Abfrage, die ich möchte, besteht darin, 4 Galerien herauszuziehen, die in diesem Metawert nicht als '1' markiert sind, aber auch solche, die diesen Wert überhaupt nicht haben. Gibt es eine Möglichkeit, neu hinzugefügten Posts immer einen Standardwert für diesen Metaschlüssel zuzuweisen (dh sie standardmäßig immer auf 0 zu setzen, wenn das Kontrollkästchen nicht aktiviert ist), oder gibt es eine Möglichkeit, den noch nicht festgelegten Schlüssel abzufragen?

Meine aktuelle Anfrage lautet:

$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,
                                        ) ),
                        ) );

Und ich habe verschiedene Versuche mit 'compare' => 'NOT LIKE', '! =' Usw. usw. versucht.

Irgendwelche Ideen? Dieses Ticket scheint zu implizieren, dass es etwas ist, das aussortiert werden sollte:

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

Vielen Dank!

Artparks
quelle

Antworten:

7

Diese massive Funktion war ein bisschen beängstigend, ich habe das so gemacht - mit zwei Argumenten (die die Features ausschließen)

$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
quelle
Mein erstes Array überschreibt mein zweites mit dieser Lösung. Vielleicht können Sie nicht dasselbe Feld doppelt abfragen?
Allen Gingrich
3

Gemäß den benutzerdefinierten Feldparametern im Codex NOT EXISTSist seit WP Version 3.5 ein spezieller Vergleich verfügbar

Technisch erzeugt es so etwas wie die folgende SQL-Abfrage in Posts-Anfragen:

$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

Es funktioniert, indem die Metatabelle mit dem bereitgestellten Schlüssel verknüpft und nur Datensätze ausgewählt werden, bei denen dies nicht zu aussagekräftigen Daten geführt hat ( IS NULL). Es funktioniert also nur für den Fall, dass der Schlüssel überhaupt nicht vorhanden ist, und nicht für Schlüssel, die mit falschen Werten vorhanden sind.

Selten
quelle
Dieser NOT EXISTSVergleich fasziniert mich . Um dieses Problem zu umgehen, speichere ich nur eine 0 am save_postHook, wenn der Metaschlüssel nicht festgelegt ist. Wie funktioniert das NOT EXISTS? Sortiert es die Abfrage des OP nach main-galund füllt dann die 4 mit den Posts aus, die dieses Meta nicht haben?
Helgatheviking
@helgatheviking Ich habe die Mechanik als Antwort ausgearbeitet
Rarst
2

Wie das Ticket hervorhob, wird es nicht unterstützt. Bis dahin müssen Sie sich auf eine benutzerdefinierte Lösung verlassen.

Einige Benutzer haben schon früher danach gefragt oder zumindest in den WordPress.org-Foren gefragt, wie es geht. Deshalb habe ich eine Funktion geschrieben, um die Arbeit zu erledigen, die ich nie behalten habe (pastebinned). Zum Glück habe ich das ursprüngliche Thema gefunden wo ich den Pastebin-Link bereitgestellt habe (der nicht ablaufen sollte).

http://pastebin.com/kgLt1RrG

Ich habe das vor 8 Monaten geschrieben und es (seitdem) nicht mehr getestet. Lassen Sie mich also über Probleme wissen.

Ich hoffe, das hilft..

t31os
quelle
Cool, danke dafür - werde es später am Abend testen und dich wissen lassen, was passiert.
Artparks
1

Die einfachste Methode, wenn auch nicht die sauberste:

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

Dadurch erhalten Sie alle Ihre Galerien sortiert nach dem Metaschlüssel. Der nächste Schritt besteht darin, herauszufinden, ob die Galerien mit dem Wert 1 nach oder vor den anderen Posts stehen. Auf diese Weise können Sie entweder:

  • Verarbeiten Sie Elemente, bis Sie entweder 4 Galerieelemente verarbeitet oder einen Beitrag mit einem Metawert von 1 erreicht haben
  • Überspringen Sie die Beiträge mit einem Metawert von 1 und beginnen Sie mit der Verarbeitung, wenn Sie den ersten Wert ungleich 1 erreichen

Andere Methoden, für die keine benutzerdefinierte SQL-Anweisung erforderlich ist:

  • Führen Sie eine Abfrage aus, um die Galerien zu finden, die Sie nicht möchten, und füllen Sie damit ein Array von Post-IDs. Führen Sie dann eine zweite Abfrage durch, und übergeben Sie dieses Array als auszuschließende Posts
  • Verwenden einer Taxonomie anstelle von benutzerdefinierten Feldern (löst dies recht gut und bringt viele andere nette Verbesserungen kostenlos mit, sodass Sie auch Zeit sparen)
Tom J Nowell
quelle