web-dev-qa-db-fra.com

Custom Post Type Interrogez plusieurs termes de taxonomie

Ainsi, sur cette page de liste Type de message personnalisé, vous trouverez une liste de propriétés.

J'ai une fonction de recherche personnalisée dans laquelle ils peuvent rechercher des propriétés avec certains termes de taxonomie, mais ils peuvent également rechercher plusieurs termes de taxonomie.

Question : Si quelqu'un sélectionne 2 termes, les seules propriétés à afficher dans la liste sont des propriétés avec term_oneANDterm_two

J'ai donc essayé ceci ci-dessous:

$required_features_slugs = array();
if( isset ( $_GET['features'] ) ) {
    $features_slugs = $_GET['features'];
}

$feature = get_terms('features');

$tmp_required = $required_features_slugs;

$property = array(
    'post_type'     => 'properties',
    'paged'         => $paged,
    'tax_query'         => array(
        array(
            'taxonomy'  => 'features',
            'field'     => 'slug',
            'terms'     => $tmp_required,
            'operator'  => 'AND',
        )
    ),
);

L'URL ressemble à ceci:

features%5B%5D=accredited-landlord&features%5B%5D=cellarbasement

Maintenant, étant donné que ces deux entités sont sélectionnées, une seule propriété doit être renvoyée car il n'y a qu'une seule propriété avec term_oneANDterm_two ensemble.

Cependant, je n'obtiens pas ce résultat, mais 4 propriétés, car il y en a 4. 3 avec term_one et 1 avec term_two.

Ce que je veux, c’est que 1 propriété soit renvoyée car il n’ya qu’une propriété avec term_onceANDterm_two ensemble.

Y at-il quelque chose de mal que je fais dans la requête?

Éditer : Fichier PHP mis à jour

$required_features_slugs = array();
if( isset ( $_GET['features'] ) ) {
    $required_features_slugs = $_GET['features'];
}

$all_features = get_terms('features');

if( ! empty( $required_features_slugs ) ) {
    foreach ( $all_features as $feature ) {
        $tmp_required = $required_features_slugs;

        if( ! in_array($feature->slug, $required_features_slugs) ) {
            array_Push( $tmp_required, $feature->slug );
        }

        $property = array(
            'post_type'     => 'properties',
            'paged'         => $paged,
            'tax_query'         => array(
                'taxonomy'  => 'features',
                'field'     => 'slug',
                'terms'     => $tmp_required,
                'operator'  => 'AND',
            ),
        );
    }
}

Edit # 2 : Voici donc le var_dump à la requête:

array(3) { ["post_type"]=> string(10) "properties" ["paged"]=> int(1) ["tax_query"]=> array(4) { ["taxonomy"]=> string(8) "features" ["field"]=> string(4) "slug" ["terms"]=> array(2) { [0]=> string(19) "accredited-landlord" [1]=> string(14) "cellarbasement" } ["operator"]=> string(3) "AND" } }

Et voici le var_dump aux termes:

array(2) { [0]=> string(19) "accredited-landlord" [1]=> string(14) "cellarbasement" }
2
Stephen

Arguments de la requête:

Si $input_terms est le tableau d'entrée des slugs à terme, vous devriez pouvoir utiliser (si je comprends bien la question):

$property = [
    'post_type'         => 'properties',
    'paged'             => $paged,
    'tax_query'         => [
        [
            'taxonomy'  => 'features',
            'field'     => 'slug',
            'terms'     => $input_terms,
            'operator'  => 'AND',
        ]
    ],
];

où nous avons ajouté un tableau manquant dans la requête de taxe.

Validation:

Nous devrions valider les termes d’entrée en premier.

Voici quelques exemples:

  • Vérifiez le nombre maximum de termes autorisés:

    $valid_input_terms_max_count = count( $input_terms ) <= 4;
    
  • Vérifiez le nombre minimum de termes autorisés:

    $valid_input_terms_min_count = count( $input_terms ) >= 1;
    
  • Vérifiez si les termes d’entrée slugs existent (en supposant que le tableau d’entrée non vide):

    $valid_input_terms_slugs = array_reduce( 
        (array) $input_terms, 
        function( $carry, $item ) { 
            return $carry && null !== term_exists( $item, 'features' ); 
        }, 
        true 
    );
    

    où nous recueillons term_exists() pour tous les termes en une seule valeur booléenne.

  • Nous pourrions également faire correspondre les slugs d'entrée à un tableau prédéfini de slugs

SQL généré:

Voici une requête SQL générée pour deux slugs de termes existants dans $input_terms:

SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID 
FROM wp_posts  
WHERE 1=1  AND ( 
  (
        SELECT COUNT(1)
        FROM wp_term_relationships
        WHERE term_taxonomy_id IN (160,161)
        AND object_id = wp_posts.ID
    ) = 2
) 
AND wp_posts.post_type = 'properties' 
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC 
LIMIT 0, 10

J'espère que vous pourrez adapter cela à vos besoins.

3
birgire

Essayez de changer d'opérateur en 'operator' => 'IN', ou essayez d'utiliser un code similaire à ceci:

$required_features_slugs = array();
if( isset ( $_GET['features'] ) ) {
    $required_features_slugs = $_GET['features'];
}

 if( ! empty( $required_features_slugs ) ) {

 $property = array(
        'post_type'     => 'properties',
        'paged'         => $paged,
        'tax_query'         => array(
        'relation' => 'AND',
        ),
  );


foreach ( $required_features_slugs as $feature ) {
        $property['tax_query'][] = array(
            'taxonomy'  => 'features',
            'field'     => 'slug',
            'terms'     => $feature,
        );
    }


}
}
2
Nefro

Peut-être que ça va marcher:

$property = array(
    'post_type'     => 'properties',
    'paged'         => $paged,
    'tax_query'     => array(
        'relation' => 'AND',    
    ),
);

$features = $_GET['features'];

foreach ($features as $feature) {
    $property['tax_query'][] = array(
        'taxonomy'  => 'features',
        'field'     => 'slug',
        'terms'     => $feature,   
    );
}
0
Krzysztof Grabania