Jump to content

Recommended Posts

Posted

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
Posted

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
Posted

I would like to thank all the Nice people giving me likes for this post. It realy gives me encuragement to come up with future tutorials when i have something usefull to share.

  • Like 5
Posted

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
Posted

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.

Posted

@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
Posted

@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
Posted

Yes. it will count each page only once per session. So, if the user refreshes the page or use the back button, it will count only once.

  • Like 1
  • 8 months later...
Posted

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);
        //}

    }

 

Posted

I found this post 

 

So I tried using 

            $stats->save($field);

and it works.

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

 

Posted
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.

Posted

So wouldn't retrieving a page from a $page->get() call, manipulating a value of a field on the page, and then saving the page down by calling the Save() work?

If this isn't the work flow, what would it be?

Posted

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
Posted
11 hours ago, fbg13 said:

@FrancisChung you have 


$stats->save;

instead of 


$stats->save();

in your code.

I saw that this morning when I reviewed it and looks like you beat me to the punch :):-[

I really need to familiarise myself with PHPStorm's colour schematics, as it doesn't highlight it as an error (red).

Posted

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
Posted
6 hours ago, FrancisChung said:

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

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

Posted
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

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
  • Recently Browsing   0 members

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