web-dev-qa-db-fra.com

Deux postes sont chargés au lieu d'un?

J'essaie d'ajouter une fonction de lecture de messages à mon site Web Wordpress. Pour ce faire, je crée un cookie dans lequel je stocke tous les identifiants des messages lus. Chaque fois qu'un article est chargé, la fonction suivante est activée:

function readPosts() {
    if (is_single()){
        $postId = get_the_id() . "/";
        $cookie = empty($_COOKIE['readposts']) ? "/0/" : $_COOKIE['readposts'];
        if(strpos($cookie, ("/" . $postId)) === false){
            $val = $cookie . $postId;
            setcookie('readposts', $val, time() + 3141592, "/");
        }
    }
}
add_action('get_header', 'readposts');

J'ai essayé d'utiliser différents hooks, tels que wp, init ou template_redirect, mais tous donnent le même résultat. Au lieu d'ajouter uniquement l'ID de la publication en cours au cookie, deux ID sont ajoutés. L'ID de l'article en cours et l'ID de l'article publié juste après l'article en cours. Comme si je chargeais deux posts différents. Mais cela n’ajoute l’ID d’un message plus récent que s’il ne figure pas déjà dans le cookie et, bien entendu, s’il existe un message plus récent!

Voici à quoi ressemble le cookie avant de charger une page:/0/221/46/Et après:/0/221/46/292/82 /

Je ne sais pas pourquoi cela se passe. Cela ressemble à de la magie noire pour moi. Si vous avez une idée, je vous serais très reconnaissant de votre aide! Merci

1
FrelonGuepe

Je suis allé dans le sens JavaScript comme l'a suggéré @Mark Kaplun et cela fonctionne. Il n'y a plus de doublon. Voici mon JS pour ceux qui sont intéressés:

jQuery(document).ready(function($) {
    var name = "readposts=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');

    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            var cookie = c.substring(name.length, c.length);
        }
    }

    if(cookie == "")
        cookie = "/0/" + my_script_vars.postID + "/";
    else if(cookie.indexOf("/" + my_script_vars.postID + "/") === -1)
        cookie += my_script_vars.postID + "/";

    var d = new Date();
    d.setTime(d.getTime() + (30*24*60*60*1000));
    var expires = "expires="+ d.toUTCString();
    document.cookie = "readposts=" + cookie + ";" + expires + ";path=/";
});

Et voici comment je dis à WP de le charger et de rendre postID accessible à partir de JS:

function wpse268423_enqueue_cookie_script(){    
     if (is_single()){
          global $post;
          wp_enqueue_script('cookie_read_posts', get_template_directory_uri() 
                    . '/js/cookie_read_posts.js' );
          wp_localize_script('cookie_read_posts', 'my_script_vars', array(
                    'postID' => $post->ID)
          );
     }
}
add_action('get_header', 'wpse268423_enqueue_cookie_script');
2
FrelonGuepe

Le problème réside dans le fait que vous définissez des cookies lors de l’accès au contenu, et non lors de sa lecture. Les navigateurs peuvent essayer de pré-extraire du contenu, et votre description ressemble à celle du navigateur, car elle préfète le lien "suivant" situé dans l'en-tête.

Par expérience, évitez de définir des cookies sur le serveur et préférez les configurer côté client (ajoutez au code HTML un petit JS qui définira le cookie) ou mieux, si possible, utilisez plutôt le stockage local.

3
Mark Kaplun