Jump to content

How to make a simple visitor counter for your page in PW


EyeDentify
 Share

Recommended Posts

Hello all PW fans. I wanted to contribute with a simple but short tutorial on how i created a simple visitor counter to have a rough estimate on what pages got visits on my website.

This tutorial assumes that you have setup a field on your page template that you want to monitor with a name of visit_counter of the field type integer.

I put this simple code together by reading some answers by the Excelent Ryan Cramer here on the forums and decided to make a few changes to his implementation.

This is because i did not want the code to count my visits to the site if i was logged in.

Instead the code shows the current pages visits if i am logged in, and hides it if i am not.

Enough talking. Here is the code:

 

<?PHP
/*
    simple code for recording current page visit count to its visit_counter field of "integer" type.
    But only if the visitor is not currently logged in.
*/

if($user->isLoggedin()) {
    
    /* if the user is logged in */ 
    echo("<p>Visits: {$page->visit_counter} st.</p>");
    
    
} else {
    
    /* if the user is NOT logged in */
    
    /* get current visit counts and save them plus one */
    
    /* turn of output formating so PW do not give an error when we change the value */
    $page->of(false);
    
    /* increment the current integer plus one */
    $page->visit_counter++;
    
    /* save the visitor_counter field */
    $page->save('visit_counter');
    
    /* turn on output formating so PW work as it should */
    $page->of(true);
    
}
?>

I also put this code in a PHP file by itself and named it _visit_counter.php so that i could easily include it in whatever page i want to monitor.

You could potentialy expand this and make it more advanced. i would look at the "roles" and "user" section of the:
http://cheatsheet.processwire.com

Bonus Tip, in the PW admin go to your template that you have the field setup in and on the "advanced" tab look for the "List of fields to display in the admin Pagelist" section and in that field put:

 

{title} - Visits: {visit_counter}

This again assumes the fields name is visit_counter .
Now in my page list in admin i can see the title followed by the number of visits. Handy :)
 

This is my first post to these forums. And i will try to help out where i feel my abilites come to the rescue.

Hope this helps anyone out there working with Processwire.

  • Like 9
Link to comment
Share on other sites

Welcome to the forums @magnusbonnevier :-)

Thanks for the tutorial

Thank you sir.

I must say that i fell in love with Processwire when i discovered it by chance.

My Autism makes it difficult for me to grasp concepts sometimes and with Wordpress i had a tough time. Put Processwire changed everything for me. It sounds silly byt its like a dream come true. Processwire totaly make sens to me and the way the API works and as a fan of jQuery i love the route Ryan Cramer took with it.

  • Like 10
Link to comment
Share on other sites

You could expand this even a little further - mix and match:

$page->setOutputFormatting(false);
$key = "visit_counter".$page->id; 
if(!$session->$key) { 
    $page->visit_counter++; 
    $page->save('visit_counter'); 
    $session->$key = 1; 
}

PS: i don't take credit for this, I found this here too

 

Have fun with PW!

  • Like 2
Link to comment
Share on other sites

You could expand this even a little further - mix and match:

$page->setOutputFormatting(false);
$key = "visit_counter".$page->id; 
if(!$session->$key) { 
    $page->visit_counter++; 
    $page->save('visit_counter'); 
    $session->$key = 1; 
}

PS: i don't take credit for this, I found this here too

 

Have fun with PW!

Hello Videokid. Thank you for your contribution. 

I would like however a little explanation how your version is different from mine so i could learn from it.

I see the use of the $session API variable, but what use has it in your code example ? what does it do ?

Thank you again.

Link to comment
Share on other sites

@EyeDentify, @Videokid is trying to make sure that there is only one count per visit (Your version counts pages refreshes, for instance), but I think his version also falls short because it prevents the following pages on the same session to be counted ;)

For @Videokid idea to work, you would have to check a combination of session and page, and not only the session. I don't have time to come up with it now, sorry for that,

EDIT: Oh, the solution already accounts for that ($key = "visit_counter".$page->id;). I have to look better at the code before talking :P

  • Like 2
Link to comment
Share on other sites

@EyeDentify, @Videokid is trying to make sure that there is only one count per visit (Your version counts pages refreshes, for instance), but I think his version also falls short because it prevents the following pages on the same session to be counted ;)

For @Videokid idea to work, you would have to check a combination of session and page, and not only the session. I don't have time to come up with it now, sorry for that,

EDIT: Oh, the solution already accounts for that ($key = "visit_counter".$page->id;). I have to look better at the code before talking :P

Aha. So your saying that if the Session var is set then there is no counting ?

And if there is no such Session var it is set and the count goes up one ?

Just so i understand.

  • Like 1
Link to comment
Share on other sites

  • 8 months later...

Hi,

I'm having the same issues here but I can't get it to work on any of the browsers I've tried (Chrome, Safari, Firefox) 

Perhaps it's an issue with my code :-X  but if i step through the code and look in the error logs, there's no error being generated.

 

    public function Record() {

        //https://processwire.com/talk/topic/12158-how-to-make-a-simple-visitor-counter-for-your-page-in-pw/

        $stats = wire(pages)->get("/stats/, include=all");
        $field = 'stats_click_PDF';
        $key = $field.$this->page->id;
	//Temporary disable Session check  whilst debugging save issue
        //if(!wire(session)->$key) {
            $stats->of(false);

            $stats->$field++;
            $stats->save;
            wire(session)->set($key,1);

            $stats->of(true);
        //}

    }

 

Link to comment
Share on other sites

16 minutes ago, FrancisChung said:

Does anyone know why the above would work? The Stats page only has 1 field at the moment anyways.

 

 

Saving a field on a page is different than saving the whole page itself. That's why. :) The field lives on its own table, and has a pages_id column pointing to the page.

Link to comment
Share on other sites

Yes, that's it. This is a fully functional code example:

//pageviews.php receives a ajax get passing $page->name as querystring
//Ex: example.com/pageviews.php?path=/videos/title-of-video/

//First, check if there is a querystring and find the page with it 
if(($path = (string) $input->get->path)) {
   $path = $sanitizer->selectorValue($path);
   $p = $pages->getByPath($path);
   if($p->id && $p->fields->has('page_views')) {
       // page was found and it has a 'page_views' field
		
       $key = "pageview" . $p->id;
       if(!$session->$key) {
           // pageview not yet recorded for this page for this user session
           $p->setOutputFormatting(false);
           $p->page_views++;
           $p->save('page_views');
           $log->save("pageviews", $p->id); //optional, just if you want see it in the logs on Admin
           $session->$key = "pageview" . $p->id; //register in session so a reload will not trigger a pageview for the same user
       }
   }
} else { //no querystring on url, so lets avoid any problems
  throw new Wire404Exception();
}

 

  • Like 1
Link to comment
Share on other sites

I ended up using Ajax, Javascript and the above PHP Code so it's not so simple any more :)

Ajax + passing parameters to PHP was a real pain in the proverbial ... trying to figure out all the idiosyncracies.

 

If anyone is interested, I can post it up for your scrutiny :)

  • Like 1
Link to comment
Share on other sites

On 10/28/2016 at 8:20 AM, szabesz said:

Yes please! You never know whose life you are going to save by posting it :) 

Not sure about someone's life but certainly a few human follicles lol.

----

Javascript :

function RecordStats(id, field) {
   //alert("id="+id);
   // alert("field="+field);
    $.ajax({
        url: '/site/<insert your PHP file path here>',
        type: 'POST',
        dataType: 'json',
        ///data: JSON.stringify({id: id, field:  field}),
        data: {id: id, field:  field},
        cache: false,
        success: function(result) {
            //alePerSrt("Fire up Modal");
            //alert(notice);
            //alert(result);
            //alert("Ajax call made");

        },
        error: function (xhr, ajaxOptions, thrownError) {
            alert(xhr.status + ' ' + thrownError);
        }
    });

Notes : 

1) DataType is json, type is 'POST'.

2) Notice I have a blank function call (Explained in bold later)

3) Not sure if cache:false is needed.

4) In my URL I was pointing to recordstats.php which is listed below.

PHP: 

recordstats :
 

$id = $_POST["id"];
$field= $_POST["field"];

if (!IsNullOrEmptyString($id) && !IsNullOrEmptyString($field))
    Stats::Record($id, $field);

echo json_encode("{ok: 1}");

 

Notes : 

1) Note I'm using $_POST to retrieve parameters

2) You HAVE TO RETURN a JSON object if I'm using JSON to receive parameters as per AJAX Specification. This is the part where I pulled a few follicles out. 
 

Stats : 

    static function Record($id, $field)
    {
        //https://processwire.com/talk/topic/12158-how-to-make-a-simple-visitor-counter-for-your-page-in-pw/

        $stats = wire(pages)->get("/stats/, include=all");

        $key = $field.$id;
        if(!wire(session)->$key) {
            $stats->of(false);

            $stats->$field++;
            //$stats->save($field);
            $stats->save();
            wire(session)->set($key,1);

            $stats->of(true);
        }
    }

 

IsNullOrEmptyString :

Quote

function IsNullOrEmptyString($text){ return (!isset($text) || is_null($text) || trim($text)===''); }

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...