web-dev-qa-db-fra.com

Pagination avec requête SQL personnalisée

J'ai ma propre chaîne SQL pour sélectionner les publications de type de publication personnalisée avec une clause WHERE spécifique. J'ai utilisé le décalage et la limite pour renvoyer les publications appropriées en fonction de l'affichage d'une page. Cela fonctionne bien.

Maintenant, j'aimerais que les fonctions previous_posts_link() et next_posts_link() fonctionnent. Ils sont tous deux appelés à partir de get_posts_nav_link qui utilise global $wp_query.

Est-il possible de réaffecter global $wp_query avec ma chaîne SQL ou mes résultats $wpdb->get_results ou autre chose? Ainsi, les fonctions natives previous_posts_link() et next_posts_link() WP fonctionneraient.

Si non, comment puis-je reproduire les fonctions de lien précédent et suivant?

J'apprécierais vraiment toute aide et conseil! Je suis totalement coincé avec ça.
Merci :)

NOTE: Je viens de remarquer que previous_posts_link() fonctionne correctement sur toutes les pages, mais no idea why et dans ce cas, pourquoi next_posts_link ne fonctionne pas: S

Voici le code:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$post_per_page = intval(get_query_var('posts_per_page'));
$offset = ($paged - 1)*$post_per_page;

$sql = "
SELECT SQL_CALC_FOUND_ROWS  wp_posts.*, wp_postmeta.* 
FROM wp_posts 
INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) 
WHERE 1=1  
    AND wp_posts.post_type = 'movie' 
    AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
    AND ((wp_postmeta.meta_key = '_expiry_date' AND CAST(wp_postmeta.meta_value AS DATE) >= '".$current_date."') 
        OR (mt1.meta_key = '_expiry_date' AND CAST(mt1.meta_value AS CHAR) = ''))
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC
LIMIT ".$offset.", ".$post_per_page;

$movies_all_current = $wpdb->get_results( $sql, OBJECT);

if($movies_all_current) {
global $post;

//loop
foreach( $movies_all_current as $key=>$post ) {
    setup_postdata($post);
    //display each post
    //...
} //end foreach ?>

    //navigation
<div class="navigation">
    <div class="previous panel"><?php previous_posts_link('&laquo; newer') ?></div>
    <div class="next panel"><?php next_posts_link('older &raquo;') ?></div>
</div>
}
8
dashaluna

Ok, je suis arrivé à la fin. Je ne pouvais pas utiliser la classe WP_Query car j'avais vraiment besoin de mon propre SQL assez gros et complexe. Voici ce que j'ai fini par avoir:

Dans functions.php, j'ai mon code SQL personnalisé et ma logique pour compter les valeurs nécessaires à la logique de pagination WP:

function vacancies_current( ){
    global $wpdb, $paged, $max_num_pages, $current_date;

    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $post_per_page = intval(get_query_var('posts_per_page'));
    $offset = ($paged - 1)*$post_per_page;

    /* Custom sql here. I left out the important bits and deleted the body 
     as it will be specific when you have your own. */
    $sql = "
        SELECT SQL_CALC_FOUND_ROWS  {$wpdb->posts}.*
        FROM {$wpdb->posts}
        ....
        GROUP BY {$wpdb->posts}.ID 
        ORDER BY {$wpdb->posts}.post_date DESC
        LIMIT ".$offset.", ".$post_per_page."; ";   

    $sql_result = $wpdb->get_results( $sql, OBJECT);

    /* Determine the total of results found to calculate the max_num_pages
     for next_posts_link navigation */
    $sql_posts_total = $wpdb->get_var( "SELECT FOUND_ROWS();" );
    $max_num_pages = ceil($sql_posts_total / $post_per_page);

    return $sql_result;
}

Ensuite, dans mon fichier de modèle, j'aurais:

<?php 
    $vacancies_current = vacancies_current();
    /*followed by a standart loop to display your results */ 
 ?>
<div class="navigation">
    <div class="previous panel"><?php previous_posts_link('&laquo; previous vacancies',$max_num_pages) ?></div>
    <div class="next panel"><?php next_posts_link('more vacancies &raquo;',$max_num_pages) ?></div>
</div>

L'astuce consistait à fournir previous_posts_link() et next_posts_link la valeur $max_num_pages et évidemment à la calculer correctement.

Cela fonctionne très bien. J'espère que ça va aider quelqu'un :)

Dasha

16
dashaluna

Jetez un coup d'œil à Requêtes personnalisées - qui vous permettent de modifier l'appel wp_query de nombreuses façons intéressantes et utiles, puis transférez les résultats dans votre objet de requête global.

1
anu

Développer la réponse d'Anu. Au lieu de vous fier à votre requête SQL personnalisée, vous pouvez utiliser la classe WP_Query et laisser WordPress gérer l’ensemble des tâches lourdes de SQL. Cela résoudrait sûrement votre problème de navigation.

Exemple de requête pour le type de message de film dans votre méta_key _expiry_date:

$today = getdate();
$args = array(
    'post_type' => 'movie',
    'meta_query' => array(
            'meta_key' => '_expiry_date',
            'meta_value' => $today,
            'meta_compare' => '< '
                    ),
    'posts_per_page' => -1,
     'order'    => 'DESC'
    );

    $movie_query = new WP_Query( $args );

    while ( $movie_query->have_posts() ) : $movie_query->the_post(); 
    // Do stuff
   endwhile; ?>

 <div class="navigation">
<div class="previous panel"><?php previous_posts_link('&laquo; newer') ?></div>
<div class="next panel"><?php next_posts_link('older &raquo;') ?></div>
</div>
1
Chris_O