0

I'm using the starter theme Sage to create a custom Wordpress Theme. I made a very simple infinite scroll system to display every posts. On that point, everything seems to work fine.

Now, I have to display an advertisement block each N posts in the loop. At first sight, it seemed pretty easy, but unfortunately, it was not.

My system works this way :

  1. When the blog page is displayed, the firsts N posts are shown. In that template (Template 1), in the loop, I call a method to check if I have to display an advertisement.

  2. When the user starts to scroll, the next N posts are loaded with AJAX. So, JS calls a Wordpress action which loads the next posts and call the appropriate template (Template 2). In that template, I check again how many posts have passed and if I have to display an advertisement.

  3. Counting informations are stocked in session variables.

The problem is this one :

When the page is loaded, everything is fine. When the infinite scroll operates for the first time, it still fine. But, when the system is called once again, the counting informations stocked in variables session are not good. They take the previous values like if the session variables were not incremented.

At first time, I used some static attributes and a static method but it didn't work. So, I thought it was because the script was not call at once and I used global variables. But it didn't work either.

It seems that the counting works fine but every time the template called by AJAX is loaded, the session variables are reset to their previous values, like if they were late.

Here are the files that I use :

  • Template 1, it's the index.php of the theme

  • Template 2, the file called by AJAX

  • Ajax functions, which contains all the AJAX actions I need in Wordpress

  • Advertisement Controller, which contains every method relative to the advertisements blocks

  • A JS file with the different AJAX queries.

Can somebody tell what I am doing wrong? It will be much appreciated.

Template 1

/****************************************/
/********** TEMPLATE 1 - INDEX **********/
/****************************************/

use Roots\Sage\ThemeAdvertisementController;

$AdvertisementController = new ThemeAdvertisementController\AdvertisementController();

$_SESSION['globalCountAds'] = 0;
$_SESSION['globalArrayAds'] = '';
$_SESSION['globalCountPosts'] = 1;

get_template_part('templates/page', 'header');

while (have_posts()) {

    the_post();
    get_template_part('templates/content', get_post_type() != 'post' ? get_post_type() : get_post_format());

    $theLoopAd = $AdvertisementController->getTheLoopAds();

    if ( $theLoopAd ) {
        echo $theLoopAd;
    }

}

Template 2

/**************************************************/
/********** TEMPLATE 2 - CALLDED BY AJAX **********/
/**************************************************/

use Roots\Sage\ThemeAdvertisementController;

$AdvertisementController = new ThemeAdvertisementController\AdvertisementController();

while (have_posts()) {

    the_post();

    get_template_part( 'templates/content', get_post_type() != 'post' ? get_post_type() : get_post_format() );  

    $theLoopAd = $AdvertisementController->getTheLoopAds();

    if ( $theLoopAd ) {
        echo $theLoopAd;
    }

}

Advertisement Controller

/**********************************************/
/********** ADVERTISEMENT CONTROLLER **********/
/**********************************************/

namespace Roots\Sage\ThemeAdvertisementController;

use Roots\Sage\ThemeViewController;
use Roots\Sage\ThemePostController;

class AdvertisementController {

    public function __construct() {

    }

    private function getTheAds() {

        $PostController = new ThemePostController\PostController();

        $postType = 'advertisement';
        $nbPosts = -1;
        $status = 'publish';
        $orderBy = 'title';
        $order = 'ASC';
        $meta = '';
        $taxQuery = '';
        $metaQuery = array(
                          array(
                              'key' => 'advertisement_in_news',
                              'value' => true,
                              'compare' => '='
                          )
                        );

        return $PostController->getThePosts( $postType, $nbPosts, $status, $orderBy, $order, $meta, $taxQuery, $metaQuery );

    }

    private function displayTheAd() {

        $ViewController = new ThemeViewController\ViewController();

        $theAdsArray = $_SESSION['globalArrayAds'];
        $theGlobalCountAds = $_SESSION['globalCountAds'];

        $thePostID = $theAdsArray->posts[ $theGlobalCountAds ]->ID;

        if ( !empty( $thePostID ) ) {

            $_SESSION['globalCountAds']++;

            $ViewController->postID = $thePostID;
            $ViewController->postType = 'advertisement';
            $ViewController->nbPosts = 1;
            $ViewController->status = 'publish';
            $ViewController->orderBy = 'ID';
            $ViewController->order = 'ASC';
            $ViewController->meta = '';
            $ViewController->taxQuery = '';

            return $ViewController->displayAdvertisementBlock();

        } else {
            return false;   
        }

    }

    public function getTheLoopAds() {

        $arrayAds = $_SESSION['globalArrayAds'];
        $adsCount = $_SESSION['globalCountAds'];
        $postCount = $_SESSION['globalCountPosts'];

        $_SESSION['globalCountPosts']++;

        if ( empty( $arrayAds ) ) {

            $theAds = $this->getTheAds();
            $_SESSION['globalArrayAds'] = $theAds; 

        }

        if ( $postCount%2 == 0 && $postCount != 0 ) {

            $displayedAd = $this->displayTheAd();

            if ( $displayedAd ) {
                return $displayedAd;
            } else {
                return false;   
            }

        } else {
            return false;  
        }

    }

}

Ajax Functions

/************************************/
/********** AJAX FUNCTIONS **********/
/************************************/

function infinitePaginateAjax() {

    $paged = $_POST['paged'];
    $postsPerPage = get_option('posts_per_page');

    $args = array( 'paged' => $paged, 
                   'post_status' => 'publish', 
                   'order' => 'DESC',
                   'post_type' => 'post',
                   'posts_per_page' => $postsPerPage
            );

    query_posts( $args );
    get_template_part('templates/loop-news');

    exit;
}

add_action( 'wp_ajax_infinitePaginateAjax','infinitePaginateAjax' );
add_action( 'wp_ajax_nopriv_infinitePaginateAjax','infinitePaginateAjax' );

function getNbPostsPerPageAjax() {

    $value = array();

    $nbPostsPerPage = get_option('posts_per_page');

    if ( !empty( $nbPostsPerPage ) ) {
        $value['answer'] = 1;    
        $value['value'] = $nbPostsPerPage;
        $value['globalCountAds'] = $_SESSION['globalCountAds'];
        $value['globalCountPosts'] = $_SESSION['globalCountPosts'];
    } else {
        $value['answer'] = 0; 
        $value['value'] = 0;
    }

    $data = json_encode( $value );

    die( $data );

}

add_action( 'wp_ajax_getNbPostsPerPageAjax','getNbPostsPerPageAjax' );
add_action( 'wp_ajax_nopriv_getNbPostsPerPageAjax','getNbPostsPerPageAjax' );

function getTotalPostsAjax() {

    global $wp_query;
    $value = array();

    $nbPosts = wp_count_posts( 'post' );
    $nbPublishedPosts = $nbPosts->publish;

    if ( !empty( $nbPublishedPosts ) ) {
        $value['answer'] = 1;    
        $value['value'] = $nbPublishedPosts;
        $value['globalCountAds'] = $_SESSION['globalCountAds'];
        $value['globalCountPosts'] = $_SESSION['globalCountPosts'];
    } else {
        $value['answer'] = 0; 
        $value['value'] = 0;
    }

    $data = json_encode( $value );

    die( $data );

}

add_action( 'wp_ajax_getTotalPostsAjax','getTotalPostsAjax' );
add_action( 'wp_ajax_nopriv_getTotalPostsAjax','getTotalPostsAjax' );

JS

/************************/
/********** JS **********/
/************************/

jQuery(document).ready(function() {


    var pageInfinite = '.infinite-page';
    var loaderInfinite = '.infinite-loader';
    var contentInfinite = '.main-content';

    var getTotalPosts = function() {

        var totalPosts = '';

        jQuery.ajax({
            type : "POST",
            contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
            async: false,
            url : data_sage_js.ajaxurl,
            data: { 
                action: 'getTotalPostsAjax'
            },
            success: function( data ) {

                data = jQuery.parseJSON( data );

                if ( data.answer !== 0 ) {
                    totalPosts = data.value;    

                }  else {
                    totalPosts = 0;
                }

            },
            error: function () {

                console.log( 'error: cannot get nb posts' );
                totalPosts = 0;

            }

        }); 

        return totalPosts;

    };

    var getNbPostsPerPage = function() {

        var postsPerPage = '';

        jQuery.ajax({
            type : "POST",
            contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
            async: false,
            url : data_sage_js.ajaxurl,
            data: { 
                action: 'getNbPostsPerPageAjax'
            },
            success: function( data ) {

                data = jQuery.parseJSON( data );

                if ( data.answer !== 0 ) {
                    postsPerPage = data.value;

                }  else {
                    postsPerPage = 0;
                }

            },
            error: function () {

                console.log( 'error: cannot get max posts page' );
                postsPerPage = 0;

            }

        }); 

        return postsPerPage;

    };

    var infiniteLoadArticle = function( pageNumber ) { 

        jQuery( loaderInfinite ).show( 'fast' );

        setTimeout(function(){

            jQuery.ajax({
                type:'POST',
                contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
                async: false,
                url: data_sage_js.ajaxurl,
                data: { 
                    action: 'infinitePaginateAjax',
                    paged: pageNumber
                },
                success: function( html ) {
                    jQuery( loaderInfinite ).hide( 'fast' );
                    jQuery( contentInfinite ).append( html);
                }
            });

        }, 1000);

        return false;

    };

    if ( jQuery( pageInfinite ).length > 0 ) {


        var postsTotal = parseInt( getTotalPosts() );
        var incPost = parseInt( getNbPostsPerPage() );
        var postsCount = parseInt( incPost );
        var nbPage = parseInt( 1 );
        var nbTotalPage = parseInt( Math.ceil( postsTotal / incPost ) );

        jQuery(window).scroll(function() {

            if ( jQuery(window).scrollTop() === jQuery(document).height() - jQuery(window).height() ) {

                if ( nbTotalPage > nbPage ) {

                    nbPage++;

                    infiniteLoadArticle( nbPage );

                    postsCount = postsCount + incPost;

                } else if ( nbTotalPage <= nbPage ) {

                    return false;

                }

            }

        });
    }

});

EDIT/SOLVE

So, after hours of searching, I decided to do it another way : I decided to use the "posts_per_page" attribute to count posts and to know when I have to display an advertisement. I just had to refactor a few functions and methods.

  • why do you need to store anything in sessions? just pass everything via javascript. – Milo Jul 21 '15 at 19:48
  • You are right. Maybe I should do it in another way. But I am using session to store the counting informations. Each template calls N posts at once and I need to know, during each loop, how many posts have passed and if I have to display an advertisement block and in that case, which advertisement I have to display. – Lancelot Jul 22 '15 at 5:46
  • Maybe this will help: developer.mozilla.org/en/docs/Web/API/Window/localStorage – Rodrigo Mar 4 '16 at 17:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.