#WordPress Un Comparateur FIND_IN_SET pour les meta_queries

J'adore les WP_Meta_Queries. Elles me rendent énormément de services. Toutefois dans un cas bien précis, les comparateurs natifs ne suffisent pas. Voici deux techniques (celle de Mike et la mienne) pour simuler un comparateur FIND_IN_SET.

Depuis un bout de temps, j'ai démarré la "fabrication" d'un prototype d'une application Web qui utilise WordPress comme cadre de développement. Ce prototype est donc un plugin qui pour profiter de toutes les fonctions liées aux "posts" de WordPress crée des post types et entretient des liaisons entre ces derniers.

Tant que cette liaison est du type 11, no problĂ©mo : il suffit de stocker l'ID de l'un dans un post_meta de l'autre. A partir du moment oĂč cette liaison est du type 1N, ça se complique !

En effet, lorsque la valeur est unique, il est simple de lister les post_type_b attachés au post_type_a ou à une liste potentielle de post_type_a. Exemple :

En revanche, lorsqu'on doit stocker une liste de valeurs dans le post_meta d'un post_type_b correspondant aux diffĂ©rents ID de post_type_a qui lui sont attachĂ©s, les comparateurs classiques des meta_queries de WordPress ne sont plus d'aucune utilitĂ© :(. Or, si on s'amuse Ă  jouer des requĂȘtes MySQL, l'opĂ©rateur FIND_IN_SET nous permet d'atteindre l'objectif recherchĂ©. Une rapide recherche "meta_query find_in_set" vous dirigera vers ce gist proposĂ© par Mike Schinkel et qui vise Ă  ajouter prĂ©cisĂ©ment un comparateur FIND_IN_SET aux meta_queries de WordPress.

De mon cÎté, j'utilise une technique équivalente : passer un comparateur inexistant dans la liste proposée par WordPress pour ensuite modifier la meta_query que WordPress conçoit dans WP_Meta_Query->get_sql(). Exemple :

Ma différence par rapport à Mike, c'est que je ne souhaite pas que chacune des WP_Query de WordPress emprunte mon inspection d'un éventuel comparateur FIND_IN_SET. Cette inspection n'intervient que si et seulement si cette WP_Query contient une meta_query. Pour cela je filtre get_meta_sql, comme illustré ci-dessous.

VoiliVoilou, j'ai pensĂ© que ça pourrait intĂ©resser certains d'entre vous. N'hĂ©sitez pas Ă  me proposer des amĂ©liorations 🙂

PS : je n'ai découvert la technique de Mike qu'aprÚs avoir conçu la mienne. J'avais pensé un temps suggérer à WordPress un enhancement, mais ma découverte tardive du script de Mike m'aura permis de constater que ce n'était pas une voie dans laquelle souhaitait se diriger WordPress comme vous pourrez le constater dans sa discussion avec Otto.

5 commentaires sur “#WordPress Un Comparateur FIND_IN_SET pour les meta_queries

  1. Waw, ta méthode est trÚs intéressante !
    Elle m’aurait Ă©tĂ© vraiment utile Ă  une Ă©poque oĂč j’ai eu le mĂȘme « souci » de code. Mais en fait il y a un moyen de contourner le problĂšme, enfin dans mon cas : stocker les ids des posts en relations dans plusieurs metas ayant la mĂȘme clĂ©. Un ID = une meta, et il n’est pas interdit pour un post d’avoir plusieurs metas du mĂȘme nom. À partir de lĂ  les WP_Query de WordPress redeviennent facilement exploitable 🙂

    Une autre limite que je rencontre souvent, par contre, et Ă  laquelle je n’ai pas trouvĂ© de solution : faire une tax_query appellant les posts qui appartiennent Ă  un terme A et excluant ceux appartenant Ă  un terme B… Connais-tu une mĂ©thode pour ça ? (Ă  part utiliser post__not_in)

    1. Merci @BenHen75 et @Willy

      J’avais pas pensĂ© Ă  mettre plusieurs meta du mĂȘme nom !! Thanks 🙂
      Sinon, pour la tax_query, je viens de remarquer qu’il n’y avait pas de filtre disponible pour la mĂ©thode WP_Tax_Query->get_sql(). Etrange d’en avoir un pour les metas et pas pour les taxos.. Je viens d’essayer cette WP_Query et ça semble fonctionner :

      $args = array(
        'post_type' => 'post',
        'tax_query' => array(
          'relation' => 'AND',
          array(
            'taxonomy' => 'category',
            'field' => 'slug',
            'terms' => array( 'test' )
          ),
          array(
            'taxonomy' => 'category',
            'field' => 'slug',
            'terms' => array( 'uncategorized' ),
            'operator' => 'NOT IN'
          )
        )
      );

      $query = new WP_Query( $args );

      1. Ah oui effectivement… Il semble que j’ai « craqué »… en plus je viens de voir que ce code est dans la doc 😐

        Merci ^^

        Et effectivement, un petit filtre sur get_tax_query ne serait pas mal ; bizarre qu’il n’y en ai pas…

  2. Hello,

    Je ne remets pas en cause l’expĂ©rimentation que tu rĂ©alises avec les meta_query, ni mĂȘme la pertinence de la mĂ©thode « find_in_set ». C’est toujours intĂ©ressant de faire par soi-mĂȘme.

    Mais en ce qui concerne la mise en relation entre les types de contenus, il existe 2 solutions pertinentes, industrialisables et maintenables Ă  mes yeux.

    La plus simple (et le plus limitĂ© fonctionnellement), c’est le plugin que j’ai dĂ©veloppĂ© Ă  ce sujet Relation Post Types (RPT) et qui permet de crĂ©er des relations entre le type de contenu. (N – N)

    Pour aller encore plus loin, il existe Ă©galement Posts 2 Posts (P2P) dĂ©veloppĂ© par scribu et qui permet de faire des tas de choses (1 – N / N – N / N – 1 ), bref une tuerie pour les dĂ©veloppeurs.

    P2P : http://wordpress.org/plugins/posts-to-posts/
    RPT : http://wordpress.org/plugins/relation-post-types/

Les commentaires sont fermés.