web-dev-qa-db-fra.com

Comparaison de tableaux avec meta_query dans pre_get_posts

Je travaille sur un formulaire pour filtrer une liste de publications à l'aide de champs personnalisés créés avec le plugin Advanced Custom Fields. À cause du formulaire, j'utilise l'action pre_get_posts pour modifier la requête via des requêtes GET. (Les références de code suivantes sont soit PHP, soit extraites de print_r())

Je règle la meta_query comme ceci:

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

et $filter ressemble à ceci:

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

                )

            [compare] => IN
        )
)

Le champ personnalisé que j'interroge est structuré comme suit:

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

Lorsque je recherche des publications avec [compare] => IN (comme ci-dessus), aucune publication n'est renvoyée. Lorsque je recherche des publications avec [compare] => NOT IN, toutes les publications sont renvoyées.

J'essaie de ne renvoyer que les messages qui ont un "mode de livraison" spécifique. Existe-t-il un moyen de comparer les deux tableaux que j'ai manqués? ou dois-je en quelque sorte exploser l'un des tableaux et comparer des valeurs individuelles à un tableau?

2
camara_tech

La documentation d'ACF recommande de vérifier les valeurs individuellement plutôt que d'utiliser simultanément un tableau.

Le code suivant provient de la documentation ACF pour le type de champ Case à cocher:

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'
        )
    )
));

Par conséquent, la requête dans pre_get_posts devrait ressembler à ceci:

$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

Si je suis correct, vous avez un champ qui contient un tableau, pour que ce soit clair, quelque chose que vous pouvez enregistrer en utilisant:

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

Ensuite, vous voulez interroger les publications où le champ 'delivery_method' = array( 'Online', 'Scheduled').

Le problème est qu’une méta-requête comme la votre:

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

retourne les publications ayant la clé 'deliver_method' définie sur 'En ligne' (chaîne) ou 'Planifiées' (chaîne) ou les deux, mais votre publication a la clé 'deliver_method' enregistrée sous forme de tableau , donc sa valeur est serialized by WordPress avant d'être enregistré dans la base de données, et vous ne pouvez pas rechercher une valeur sérialisée à l'aide d'un tableau non sérialisé ...

Par conséquent, si vous souhaitez stocker différentes méthodes de livraison, il est préférable d'utiliser plusieurs valeurs pour la même clé, plutôt qu'une clé avec plusieurs valeurs, par exemple.

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

De cette manière, en utilisant les arguments appropriés, vous pourrez obtenir des publications ayant l'une des méthodes, ou les deux, en fonction de vos besoins.

Je ne sais sincèrement pas comment implémenter cela à l'aide d'ACF, mais le moyen spécifique au plug-in est hors sujet pour ce site, mais je pense que le concept est simple et que vous pouvez simplement l'appliquer sur ce plugin.

Un hack sale pour le cas spécifique est une requête utilisant comme valeur la valeur sérialisée

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

Cette méta-requête renvoie les publications ayant les deux méthodes enregistrées en tant que tableau.

1
gmazzap