Commande par méta valeur ou date?


10

Vous avez un champ personnalisé appelé startDatemais ce n'est que sur quelques événements. Je me demandais s'il n'était pas défini pour un article que je pourrais utiliser post_datepour générer la liste des articles?

// if meta_key _postmeta.startDate isn't set get the rest by posts.post_date

query_posts(
    array(
        array(
            'posts_per_page' => 10,
            'meta_key' => 'startDate',
            'meta_value' => date('Y-m-d'),
            'meta_compare' => '<',
            'orderby' => 'meta_value',
            'order' => 'ASC'
        ), 
        array(
            'meta_key' => 'post_date',
            'meta_value' => date('Y-m-d'),
            'meta_compare' => '<'
        )
    )
);

post_date est-il un champ personnalisé?
Bainternet

i ws en supposant que c'est le champ publié par défaut de wordpress mais peut être faux? Quoi qu'il en soit,
j'aimerais

ok donc ce n'est pas un champ méta son dans le tableau des messages
Bainternet

Correction de vos arguments de requête, j'espère que cela n'a pas faussé ce que vous illustriez du tout, n'hésitez pas à revenir si nécessaire.
t31os

cheers t31os - l'avez de nouveau édité pour le rendre plus clair. Vous en avez besoin pour sélectionner un contenu plus ancien que MAINTENANT à l'aide de startDate, et si startDate n'a pas été défini, utilisez la date par défaut des messages post_date.
v3nt

Réponses:


11

Si vous pouvez l'expliquer en SQL, vous pouvez l'interroger! Il y a trois endroits où nous voulons changer la requête par défaut:

SELECT wp_posts.*
FROM wp_posts 
INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
WHERE 1=1
    AND wp_posts.post_type = 'post'
    AND (wp_posts.post_status = 'publish')
    AND wp_postmeta.meta_key = 'startDate'
    AND CAST(wp_postmeta.meta_value AS CHAR) < '2011-03-23'
GROUP BY wp_posts.ID
ORDER BY wp_postmeta.meta_value DESC
LIMIT 0, 10
  • La jointure doit être une jointure gauche
  • La clause where
  • L'ordre

La jointure et la clause where sont ajoutées via la _get_meta_sql()fonction . La sortie est filtrée, nous pouvons donc y accéder:

add_filter( 'get_meta_sql', 'wpse12814_get_meta_sql' );
function wpse12814_get_meta_sql( $meta_sql )
{
    // Move the `meta_key` comparison in the join so it can handle posts without this meta_key
    $meta_sql['join'] = " LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'startDate') ";
    $meta_sql['where'] = " AND (wp_postmeta.meta_value IS NULL OR wp_postmeta.meta_value < '" . date('Y-m-d') . "')";
    return $meta_sql;
}

La clause de commande est filtrée à travers posts_orderby:

add_filter( 'posts_orderby', 'wpse12814_posts_orderby' );
function wpse12814_posts_orderby( $orderby )
{
    $orderby = 'COALESCE(wp_postmeta.meta_value, wp_posts.post_date) ASC';
    return $orderby;
}

Cela nous donne la requête SQL suivante:

SELECT wp_posts.*
FROM wp_posts
LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'startDate')
WHERE 1=1
    AND wp_posts.post_type = 'post'
    AND (wp_posts.post_status = 'publish')
    AND (wp_postmeta.meta_value IS NULL OR wp_postmeta.meta_value < '2011-03-23')
GROUP BY wp_posts.ID
ORDER BY COALESCE(wp_postmeta.meta_value, wp_posts.post_date) ASC
LIMIT 0, 10

N'oubliez pas de décrocher les filtres après avoir effectué votre requête, sinon vous gâcheriez d'autres requêtes également. Et si possible, vous ne devez pas query_posts()vous appeler , mais modifier la requête de publication principale effectuée par WordPress lors de la configuration de la page.


2
Solution très élégante, je n'aurais pas pensé à utiliser COALESCE comme ça. Je conseillerais simplement de ne pas supposer le préfixe 'wp_' par défaut et d'utiliser {$ wpdb-> prefix} à la place ...
goldenapples

@goldenapples: Oui, vous pouvez le généraliser, mais il est déjà si spécifique pour cette requête (il gâchera d'autres requêtes avec une méta-partie), que je pensais que ce n'était pas nécessaire.
Jan Fabry

Merci Jan - c'est une révélation! Vous vous familiarisez toujours avec wordpress et vous vous demandez où cela s'appelle sur ma page? Et comment pourrais-je le décrocher? c'est-à-dire // $ theQuery ... then <? php if (have_posts ()): while (have_posts ()): the_post (); ?>?
v3nt

@daniel: Vous pouvez placer les fonctions dans le functions.phpfichier de votre thème . Ensuite, juste avant d'exécuter la requête, vous placez les deux add_filter()lignes. Après la requête, vous écrivez remove_filter( 'get_meta_sql', 'wpse12814_get_meta_sql' ); remove_filter( 'posts_orderby', 'wpse12814_posts_orderby' );pour les supprimer à nouveau.
Jan Fabry

ah - ça a du sens maintenant et ça marche aussi! Merci beaucoup Jan. Ça va être utile ...
v3nt

0

essayez quelque chose comme:

$postedtime = get_post_meta($post->ID, 'startDate');

if($postedtime != null){
$orderby = $postedtime;

}else{
$orderby = 'date';
}

thankx alex mais ne savez pas comment cela s'implique dans la boucle?
v3nt

doh! lorsque vous query_posts (array ('orderby' => $ orderby))
Alex Older

0

Un appel de messages de requête ne fait qu'une seule requête, pas deux. Donc non, vous ne pouvez pas lui demander de faire deux requêtes distinctes, puis de concaténer les résultats.

N'oubliez pas que vous sélectionnez un ensemble de publications ici, puis les affichez. Cet ensemble est sélectionné d'un seul coup. Si vous souhaitez obtenir deux ensembles distincts de publications, puis les fusionner, c'est quelque chose que vous devrez faire vous-même avec get_posts ou similaire.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.