web-dev-qa-db-fra.com

Essayer de réaliser une requête de champ personnalisée complexe avec order by défini sur la valeur du champ

J'ai deux champs personnalisés pour les publications d'événement: event-start et event-end. Lorsque je recherche des événements en cours, je souhaite afficher tout message où le event-start _ OR le event-end est supérieur ou égal à la date du jour et j'aimerais les commander par event-start (pas le post_date par défaut).

J'ai créé une requête avec les paramètres suivants:

$args = array(
  'post_type' => 'post',
  'posts_per_page' => $number,          
  'meta_query' => array(
    'relation' => 'OR',
    array(
      'key' => 'event-start',
      'value' => $today_is,
      'type' => 'NUMERIC',
      'compare' => '>='
    ),
    array(
      'key' => 'event-end',
      'value' => $today_is,
      'type' => 'NUMERIC',
      'compare' => '>='
    )
  ),
  'orderby' => 'meta_value',
  'order' => 'ASC',
);

La requête obtient les publications correctes, mais le problème est que je ne parviens pas à obtenir l'ordre au travail. Cet ensemble d'arguments exécute la requête suivante:

SELECT SQL_CALC_FOUND_ROWS wp_18_posts.ID FROM wp_18_posts INNER JOIN wp_18_postmeta ON (wp_18_posts.ID = wp_18_postmeta.post_id)
INNER JOIN wp_18_postmeta AS mt1 ON (wp_18_posts.ID = mt1.post_id) WHERE 1=1 AND wp_18_posts.post_type = 'post' AND (wp_18_posts.post_status = 'publish' OR wp_18_posts.post_status = 'private') AND ( (wp_18_postmeta.meta_key = 'event-start' AND CAST(wp_18_postmeta.meta_value AS SIGNED) >= '1344289896')
OR (mt1.meta_key = 'event-end' AND CAST(mt1.meta_value AS SIGNED) >= '1344289896') ) GROUP BY wp_18_posts.ID **ORDER BY wp_18_posts.post_date** ASC LIMIT 0, 3

Notez que la clause ORDER BY est toujours définie sur post_date. Si je change les arguments de la requête pour utiliser l'ancien style de meta_key ainsi que orderby meta_value avec le nouveau style meta_query comme ceci:

$args = array(
  'post_type' => 'post',
  'posts_per_page' => $number,      
  'meta_query' => array(
    'relation' => 'OR',
    array(
      'key' => 'event-start',
      'value' => $today_is,
      'type' => 'NUMERIC',
      'compare' => '>='
    ),
    array(
      'key' => 'event-end',
      'value' => $today_is,
      'type' => 'NUMERIC',
      'compare' => '>='
    )
  ),
  'orderby' => 'meta_value',
  'meta_key' => 'event-start',
  'order' => 'ASC',
);

Je me retrouve avec la requête suivante:

SELECT SQL_CALC_FOUND_ROWS wp_18_posts.ID FROM wp_18_posts INNER JOIN wp_18_postmeta ON (wp_18_posts.ID = wp_18_postmeta.post_id)
INNER JOIN wp_18_postmeta AS mt1 ON (wp_18_posts.ID = mt1.post_id)
INNER JOIN wp_18_postmeta AS mt2 ON (wp_18_posts.ID = mt2.post_id) WHERE 1=1 AND wp_18_posts.post_type = 'post' AND (wp_18_posts.post_status = 'publish' OR wp_18_posts.post_status = 'private') AND (wp_18_postmeta.meta_key = 'event-start'
OR (mt1.meta_key = 'event-start' AND CAST(mt1.meta_value AS SIGNED) >= '1344289518')
OR (mt2.meta_key = 'event-end' AND CAST(mt2.meta_value AS SIGNED) >= '1344289518') ) GROUP BY wp_18_posts.ID ORDER BY wp_18_postmeta.meta_value ASC LIMIT 0, 3

Ce qui extrait toutes les publications avec une clé méta event-start quelle que soit la date définie pour cette clé.

Toute idée sur la manière de configurer une requête de champ personnalisée complexe et de la commander à l'aide de la valeur event-start serait grandement appréciée.

3
DaveE

Voici la meilleure solution que j'ai trouvée:

$args = array(
    'post_type'      => 'post',
    'posts_per_page' => $number,
    'meta_key'       => 'event-start',
    'meta_value'     => $today_is,
    'meta_query'     => array(
        'relation' => 'OR',
        array(
            'key'     => 'event-start',
            'value'   => $today_is,
            'type'    => 'NUMERIC',
            'compare' => '>=',
        ),
        array(
            'key'     => 'event-end',
            'value'   => $today_is,
            'type'    => 'NUMERIC',
            'compare' => '>=',
        )
    ),
    'orderby' => 'meta_value',
    'order'   => 'ASC',
);

Il utilise le même complexe meta_query, mais j’ai ajouté un meta_key et un meta_value distincts afin de déclencher le meta_value orderby.

Si je me souviens bien, au moment où j'ai écrit ce billet, j'avais déjà essayé cette solution, mais cela n'a pas fonctionné. Je pense aussi que je suis tombé sur un ticket Trac dans WordPress Core lié à ce problème, mais je ne le trouve pas pour le moment.

Conclusion: au moment de la publication d'origine, je pense qu'il y avait un bug dans WordPress qui empêchait que cela fonctionne, mais cela fonctionne maintenant.

1
DaveE

Si la valeur de vos champs personnalisés est numérique, vous pouvez essayer de la commander avec meta_value_num. Notez également que meta_value et meta_value_num nécessitent meta_key dans la requête comme décrit ici .

$args = array(
  'post_type' => 'post',
  'posts_per_page' => $number,          
  'meta_query' => array(
    'relation' => 'OR',
    array(
      'meta_key' => 'event-start',
      'value' => $today_is,
      'type' => 'NUMERIC',
      'compare' => '>='
    ),
    array(
      'meta_key' => 'event-end',
      'value' => $today_is,
      'type' => 'NUMERIC',
      'compare' => '>='
    )
  ),
  'orderby' => 'meta_value_num',
  'order' => 'ASC',
);
1
unifiedac