web-dev-qa-db-fra.com

Sélection de la catégorie complexe selon l'entrée de l'utilisateur

Cela va être une grande explication car je n'ai pas de raccourci pour expliquer tout le scénario.

Disons que j'ai la structure de catégories suivante. (les identifiants de catégories sont entre parenthèses devant chaque catégorie)

First Level 1 (100)
    Second Level 1 (104)
        Third Level 1 (108)
        Third Level 2 (109)
        Third Level 3 (110)
        Third Level 4 (111)
    Second Level 2 (105)
        Third Level 1 (112)
        Third Level 2 (113)
First Level 2 (101)
    Second Level 1 (106)
        Third Level 1 (114)
        Third Level 2 (115)
        Third Level 3 (116)
    Second Level 2 (107)
        Third Level 1 (117)
        Third Level 2 (118)
First Level 3 (102)
First Level 4 (103)

J'ai l'obligation de donner aux utilisateurs la liberté de choisir les catégories (que j'appelle des filtres) ce qu'ils doivent voir dans le blog. Donc, j'ai donné la même structure pour les utilisateurs en présélectionnant toutes les catégories. Si quelqu'un doit exclure une catégorie, l'utilisateur peut la désélectionner.

Mais j'ai une certaine logique d'afficher les messages en fonction des filtres ci-dessous.

Fonctionnement des filtres:

Second Level est un niveau interne qui n'a rien à voir avec la sélection de l'utilisateur, bien qu'il soit utile de conserver la hiérarchie. Les utilisateurs ne peuvent cocher les catégories Third Level qu'en cochant leur parent First Level. Si l'utilisateur désélectionne First Level, les enfants sont automatiquement verrouillés.

LOGIQUE: (je considérerai un post à des fins d'explication)

PREMIÈRE RÈGLE:

Si quelqu'un coche la catégorie First Level et s'il a des enfants, je devrais passer à la deuxième étape ci-dessous.

Le message ne sera affiché que si au moins un des membres de la catégorie Third Level du message est également coché dans les filtres de l'utilisateur. Mais ceci doit être vérifié sous chaque Second Level sections séparément.

Par exemple. Third Level 1 et Third Level 2 sont cochés dans post (sous le First Level 1 & Second Level 1)

L'utilisateur a décoché Third Level 1 mais a coché Third Level 2, alors il sera toujours affiché (feu vert)

Mais l'utilisateur n'a coché que Third Level 3 (sous le First Level 1 & Second Level 1) dans les filtres, la publication ne serait alors pas affichée. (lumière rouge)

Ainsi, une publication ne sera affichée que si TOUTES les sections Second Level sont allumées en vert. Dans l'exemple ci-dessus, Second Level 1 et Second Level 2 (sous le First Level 1) doivent remplir la logique ci-dessus pour afficher la publication.

Exemple: utilisateur intéressé par First Level 1 (à partir de filtres). La poste est également classée comme First Level 1

Ensuite, je devrais passer à la deuxième étape pour laquelle je dois vérifier toutes les sections Second Level remplissant la logique ci-dessus.

  • Second Level 1
  • Second Level 2

Si l'une des sections Second Level affiche un feu rouge, la transaction ne sera pas affichée.

SECONDE RÈGLE:

Si l’une des catégories First Level n’a pas d’enfants, elle est considérée comme remplissant les critères de filtrage.

TROISIEME REGLE:

Chaque fois qu'une publication remplit au moins une exigence First Level considérée comme la publication, elle sera affichée sur le blog.

C'est donc la logique d'afficher des messages sur le blog en fonction des entrées de filtre des utilisateurs. Maintenant, ce dont j'ai vraiment besoin, c'est de construire un WP_Query. Honnêtement, je ne sais même pas comment le démarrer car je n'ai pas beaucoup d'expérience avec Wordpress. Mais mon essai initial était avec category__in avec tous les identifiants de catégorie cochés, ce qui ne correspond pas à la nouvelle logique.

Toute aide sera hautement appréciée, car je suis coincée là-dessus depuis quelques jours maintenant.

Merci d'avance.

UPDATE 1:

si quelqu'un décoche 110 & 111 reste tout est considéré comme étant coché, alors le même algorithme avec tax_query sera comme ci-dessous. Mais en réalité, cela ne charge pas du tout.

$args = array(
    'post_type' => 'post',
    'tax_query' => array(
        'relation' => 'OR',
        array(
            'relation' => 'AND',
            array(
                'taxonomy' => 'category',
                'field'    => 'term_id',
                'terms'    => array( 108,109 ),
                'operator' => 'IN',
            ),
            array(
                'taxonomy' => 'category',
                'field'    => 'term_id',
                'terms'    => array( 112,113 ),
                'operator' => 'IN',
            )
        ),
        array(
            'relation' => 'AND',
            array(
                'taxonomy' => 'category',
                'field'    => 'term_id',
                'terms'    => array( 114,115,116 ),
                'operator' => 'IN',
            ),
            array(
                'taxonomy' => 'category',
                'field'    => 'term_id',
                'terms'    => array( 117,118 ),
                'operator' => 'IN',
            )
        ),
        array(
            'taxonomy' => 'category',
            'field'    => 'term_id',
            'terms'    => array( 102, 103 ),
            'operator' => 'IN',
        ),
    ),
);
1
Janith Chinthana

Après de longues recherches, le seul moyen que j’ai trouvé était de récupérer les résultats avec une requête SQL personnalisée.

SELECT SQL_CALC_FOUND_ROWS blog_posts.* FROM (
SELECT blog_posts.* FROM blog_posts 
INNER JOIN blog_term_relationships AS tt0 ON (blog_posts.ID = tt0.object_id AND tt0.term_taxonomy_id IN (108,109)) 
INNER JOIN blog_term_relationships AS tt1 ON (blog_posts.ID = tt1.object_id AND tt1.term_taxonomy_id IN (112,113)) 
WHERE blog_posts.post_type = 'post' AND (blog_posts.post_status = 'publish') 
UNION 
SELECT blog_posts.* FROM blog_posts 
INNER JOIN blog_term_relationships AS tt3 ON (blog_posts.ID = tt3.object_id AND tt3.term_taxonomy_id IN (114,115,116)) 
INNER JOIN blog_term_relationships AS tt4 ON (blog_posts.ID = tt4.object_id AND tt4.term_taxonomy_id IN (117,118)) 
WHERE blog_posts.post_type = 'post' AND (blog_posts.post_status = 'publish') ) blog_posts 
GROUP BY blog_posts.ID ORDER BY blog_posts.post_date DESC LIMIT 0, 12;

le code suivant a été utilisé pour extraire les résultats selon https://codex.wordpress.org/Displaying_Posts_Using_a_Custom_Select_Query

$pageposts = $wpdb->get_results($querystr, OBJECT);
0
Janith Chinthana

La requête que vous devez utiliser n’est pas si compliquée que celle que vous voulez obtenir pour obtenir des articles de certaines taxonomies seulement. Vous avez raison, vous devriez utiliser le tax_query.

La première chose à faire est de rassembler tous vos identifiants de catégorie dans un seul tableau car il n’est pas nécessaire d’en avoir plusieurs puisque vous n’utilisez que la condition IN (c’est-à-dire les publications qui appartiennent à au moins une catégorie de la liste). Cela rend le code sujette aux erreurs et lent à avoir plusieurs requêtes de taxe quand une seule suffirait.

Le problème de votre requête est que vous utilisez une relation AND qui n’est jamais vraie dans votre cas (c’est-à-dire que vous n’avez pas de publication qui est en même temps dans les catégories 108 ou 109, et dans les catégories 112 ou 113).

Je vous suggère donc d'utiliser les arguments WP_Query comme suit:

$args = array(
    'post_type' => 'post',
    'tax_query' => array(
        array(
            'taxonomy' => 'category',
            'field'    => 'term_id',
            'terms'    => array( 108, 109, 112, 113, 114, 115, 116, 117, 118, 102, 103 ),
            'operator' => 'IN',
        ),
    ),
);

Je comprends que vous avez une logique en plusieurs étapes pour sélectionner les messages à afficher dans certaines catégories. J'y ai réfléchi et il serait assez compliqué d'implémenter cette logique dans une requête fiscale via plusieurs relations AND/OR. Je pense que vous devriez faire toute la sélection de catégorie dans PHP et vous retrouver avec un tableau d'identifiants de catégorie que vous utiliseriez comme ci-dessus. Cela vous permettra de séparer votre logique de la sélection des publications.

1
Vlad Olaru