web-dev-qa-db-de.com

Vergleichen von Arrays mit meta_query in pre_get_posts

Ich arbeite an einem Formular zum Filtern einer Liste von Posts mit benutzerdefinierten Feldern, die mit dem Plug-in "Erweiterte benutzerdefinierte Felder" erstellt wurden. Aufgrund des Formulars verwende ich die Aktion pre_get_posts, um die Abfrage über GET-Anforderungen zu ändern. (Die folgenden Codereferenzen sind entweder PHP oder werden von print_r() ausgegeben.)

Ich habe die meta_query so eingestellt:

$query->set('meta_query',$filter);

und $filter sieht so aus:

Array
(
    [0] => Array
        (
            [key] => delivery_method
            [value] => Array
                (
                    [0] => Online
                    [1] => Scheduled

                )

            [compare] => IN
        )
)

Das benutzerdefinierte Feld, das ich abfrage, ist folgendermaßen aufgebaut:

Array (
    [delivery_method] => Array (
        [0] => Online
        [1] => Scheduled
    )
)

Wenn ich nach Beiträgen mit [compare] => IN (wie oben) suche, werden keine Beiträge zurückgegeben. Wenn ich nach Beiträgen mit [compare] => NOT IN suche, werden alle Beiträge zurückgegeben.

Ich versuche nur die Beiträge zurückzugeben, die eine bestimmte "Zustellmethode" haben. Gibt es eine Möglichkeit, die beiden fehlenden Arrays zu vergleichen? Oder muss ich eines der Arrays irgendwie auflösen und einzelne Werte mit einem Array vergleichen?

2
camara_tech

In der ACF-Dokumentation wird empfohlen, die Werte einzeln und nicht gleichzeitig mithilfe eines Arrays zu überprüfen.

Der folgende Code stammt aus der ACF-Dokumentation für den Feldtyp "Kontrollkästchen":

http://www.advancedcustomfields.com/resources/field-types/checkbox/

/*
*  Query posts for a checkbox value.
*  This method uses the meta_query LIKE to match the string "red" to the database value a:2:{i:0;s:3:"red";i:1;s:4:"blue";} (serialized array)
*  The above value suggests that the user selected "red" and "blue" from the checkbox choices
*/

$posts = get_posts(array(
    'meta_query' => array(
        array(
            'key' => 'field_name', // name of custom field
            'value' => '"red"', // matches exaclty "red", not just red. This prevents a match for "acquired"
            'compare' => 'LIKE'
        )
    )
));

Daher sollte die Abfrage in pre_get_posts folgendermaßen aussehen:

$filter = array(
    array(
        'key' => 'delivery_method'
        'value' => '"Online"'
        'compare' => 'LIKE'
    ),
    array(
        'key' => 'delivery_method'
        'value' => '"Scheduled"'
        'compare' => 'LIKE'
    )
)

$query->set('meta_query',$filter);
2
camara_tech

Wenn ich richtig liege, haben Sie ein Feld, das ein Array enthält, um genau zu sein, etwas, das Sie speichern können, indem Sie Folgendes verwenden:

add_post_meta( $postid, 'delivery_method', array('Online', 'Scheduled') );

Dann wollen Sie Posts abfragen, bei denen das Feld 'delivery_method' = array( 'Online', 'Scheduled') ist.

Das Problem ist, dass eine Meta-Abfrage wie die Ihre:

$meta_query = array(
  array(
    'key' => 'delivery_method',
    'value' => array( 'Online', 'Scheduled' ),
    'compare' => 'IN'
  )
);

gibt Posts mit dem Schlüssel 'deliver_method' zurück, der auf 'Online' (Zeichenfolge) oder 'Scheduled' (Zeichenfolge) oder beides gesetzt ist, aber in Ihrem Post ist der Schlüssel 'deliver_method' als Array gespeichert Daher lautet sein Wert serialisiert von WordPress, bevor er in der Datenbank gespeichert wird, und Sie können mit einem unserialisierten Array keinen serialisierten Wert abfragen ...

Wenn Sie also verschiedene Übermittlungsmethoden speichern möchten, ist es besser, mehrere Werte für denselben Schlüssel zu verwenden, als einen Schlüssel mit mehreren Werten, z.

add_post_meta( $postid, 'delivery_method', 'Online' );
add_post_meta( $postid, 'delivery_method', 'Scheduled' );

Auf diese Weise können Sie mit den richtigen Argumenten Beiträge mit einer der Methoden oder beiden erhalten, je nach Ihren Anforderungen.

Ich weiß aufrichtig nicht, wie ich das mit ACF implementieren soll, und der Plugin-spezifische Weg ist für diese Site nicht thematisch, aber ich denke, das Konzept ist einfach und Sie können es einfach auf dieses Plugin anwenden.

Ein unsauberer Hack für den speziellen Fall ist die Abfrage mit dem serialisierten Wert als Wert

$meta_query = array(
  array(
    'key' => 'delivery_method',
    'value' => serialize ( array( 'Online', 'Scheduled' ) )
  )
);

Diese Meta-Abfrage gibt die Posts zurück, bei denen beide Methoden als Array gespeichert sind.

1
gmazzap