Jump to content

Page Hit Counter – Simple Page View Tracking


David Karich

Recommended Posts

18 hours ago, adrian said:

I just noticed that if you uninstall and reinstall, you get an SQL error because it's trying to create a table that already exists, so either the uninstall didn't clean things up properly (if that is the intention), or the install process needs to check to see if it already exists.

Hi @adrian, unfortunately I can't reproduce the problem on any installation where I just tested it. The module does not handle the uninstall process manually either, it uses PW's native methods: https://github.com/FlipZoomMedia/PageHitCounter/blob/master/PageHitCounter.module#L1130 – There I'm confused unfortunately, why when uninstalling the field your MySQL table is not removed. Maybe local development environment with wrong rights? ?

Quote

Also, just wondering if the AJAX approach could be reserved for sites running ProCache? Is there a need otherwise for doing it this way, rather than hooking on page render? There's a good chance I am overlooking something, but just thought I'd ask.

Surely this would also work, but this makes it in the end, I think, unnecessarily inflated in the code. The current method does not block the rendering process because rights, templates, filters, cookies, etc. have to be checked first and then an SQL query has to be waited for before it continues (even if it is only milliseconds here). It is therefore asynchronous and does not block the frontend. It clears the way for self-created AJAX requests for tracking and it works as it is implemented, for all methods. Whether ProCache is in use or not. ? 

Quote

Another thought - have you considered a way for us to easily extend this to log click events to track users viewing PDFs etc? Maybe this really doesn't belong within this module and should be kept as something we implement on a case-by-case basis?

The module should never become a tracking or statistics module in its concept. There are simply enough better tools that you can use for that. It has always been and should remain so, a simple way to quickly sort by interests or get an overview without big bells and whistles. 

Everything that is based on template, you can track with it but also. See the Custom API tracking methods. So if your downloads have a template in any form, you can also use it to map a download counter. For example, I have already mapped this with login counters. (https://github.com/FlipZoomMedia/PageHitCounter#example-tracking-a-page-hit-via-api-and-jquery)

For everything else there is Analytics or Matomo, or the many other tools. But ask @bernhard, I don't want to anticipate anything, but he builds something great on the basis of the PageHitCounter. ? 

  • Like 1
Link to comment
Share on other sites

10 hours ago, adrian said:

@David Karich - on the issue of the AJAX call from the js file - turns out if you have url segments enabled for a template, when you view a page, the entire page's html is included in the response and sent to the browser along with the "Page Hit Counter: Tracked".

I can workaround it by adding:


if($config->ajax && $input->urlSegment1 == 'phcv1') exit;

to _init.php, but I think there needs to be a more elegant solution ?

I have read your section about "Notice: Tracking with URL segments", but I don't think that is really the issue here. I haven't defined my urlsegments yet (I will before the site goes live), but I don't think that will prevent this issue, will it?

Any thoughts?

 

I think you have the PW debug mode on, right? The response is not returned when debug mode is off. Also, all non-AJAX based requests are not processed further. https://github.com/FlipZoomMedia/PageHitCounter/blob/master/PageHitCounter.module#L643 

Or have I misunderstood something?

  • Like 1
Link to comment
Share on other sites

Hi @David Karich - thanks for all the follow up. I tried uninstalling / reinstalling again here, this time on my local dev setup, rather than my production server and no errors this time - I'll put this down to a random PW glitch.

I see your point of view about the AJAX approach, although I still feel like it is less efficient than a direct call during page render, but I'm not too concerned about it.

Now, regarding the important stuff - you're correct that the page's HTML is not returned when debug mode is off, but I'd still consider this a bug - I am pretty sure that it being returned is not your intention ?  and it's annoying to deal with it when debug mode is on. Perhaps this module shouldn't be installed while a site is still in development (when debug mode is likely to be on), but I still think this should be fixed.

I don't really understand your point about non-AJAX based requests not being processed further. I think you'll need to setup urlsegments with a required trailing slash and you'll see my point about the unnecessary 301 redirect - could be easily fixed by appending a trailing slash (if required) to your call to the /phcv1 path.

Link to comment
Share on other sites

10 hours ago, adrian said:

Sorry, on a related note, if the template's urlsegment trailing slash is set to "yes" to force a trailing slash, you end up with two calls, so the module needs to check this setting and adjust the path accordingly.

681700061_ScreenShot2021-02-15at8_51_37PM.png.f39f12f20a7e415a241a9b6b9997d4c9.png

FYI - the reason I have that setting forcing the trailing slash is because I have urlsegments and pagination both turned on, and without it, URLs can end up broken.

 

10 hours ago, adrian said:

@David Karich - on the issue of the AJAX call from the js file - turns out if you have url segments enabled for a template, when you view a page, the entire page's html is included in the response and sent to the browser along with the "Page Hit Counter: Tracked".

I can workaround it by adding:


if($config->ajax && $input->urlSegment1 == 'phcv1') exit;

to _init.php, but I think there needs to be a more elegant solution ?

I have read your section about "Notice: Tracking with URL segments", but I don't think that is really the issue here. I haven't defined my urlsegments yet (I will before the site goes live), but I don't think that will prevent this issue, will it?

Any thoughts?

 

Yes, this is the problem described. Just tested it. Forget what I said before. This error occurs only when there are missing segment definitions with segments enabled. 

Edit 1: Just validated it again too, there is no other way. You need to define the URL segments or leave placeholders via regex so that an endpoint can be created and there is a possibility that a 404 will be triggered. And without a segment definition a 404 will never be triggered and so the script can't hook in at that point.

Edit 2: Consequently, the request is not going to the module, but simply to your page, which itself is the response in your console in debug mode. But the tracking endpoint can also not be placed uniformly on the root, because in cookie mode with differentiated URL segments the cookie must be stored only on this path. I will think about whether there should be an alternative way without AJAX. But I can't implement this adhoc, because I don't have the time for it and for this project no customer releases budgets anymore, because these use cases for which it was needed, work like this.

@adrian Please define the URL segments in your project and test it, it should work with that. ? 

  • Like 1
Link to comment
Share on other sites

@David Karich - defining URL segments does seem to fix all the issues. However, I am concerned about setups where the definition would allow matching "phcv1" - mine are specific enough at the moment, but I can see it being an issue, especially if you have a segment for catching incoming affiliate links, or something similar with one segment that allows any alphanumeric characters.

  • Like 1
Link to comment
Share on other sites

27 minutes ago, adrian said:

or something similar with one segment that allows any alphanumeric characters.

But this is not a problem, as long as you can define a segment in some way. I also have it in use, where segments can have any value. The segment definition via RegEx works, for example: 

regex:^affiliate/[a-zA-Z0-9-_]+$

For all other cases, even if I have not yet encountered one, where you can not define any segments and everything is wildcard (which you should also avoid from SEO point of view or also the potential for DDOS attacks), the module is then unfortunately not the right choice. ? 

Link to comment
Share on other sites

1 minute ago, David Karich said:

But this is not a problem, as long as you can define a segment in some way. I also have it in use, where segments can have any value. The segment definition via RegEx works, for example: 


regex:^affiliate/[a-zA-Z0-9-_]+$

 

Sure, that works, but I am talking about direct affiliate links - sites often have mysite.com/davidk without any preceding segment to define what it is. I kinda find this practice a bit weird, but it seems pretty common.

Link to comment
Share on other sites

8 minutes ago, adrian said:

Sure, that works, but I am talking about direct affiliate links - sites often have mysite.com/davidk without any preceding segment to define what it is. I kinda find this practice a bit weird, but it seems pretty common.

Yes, I understand. Unfortunately, this case cannot be mapped with the module, because the whole core concept is based on triggering a 404 via a non-existent endpoint and hooking in before it. I wanted to keep it simple and not have to install an additional page as API endpoint and a template for it. ? 

  • Like 2
Link to comment
Share on other sites

21 hours ago, David Karich said:

Yes, I understand. Unfortunately, this case cannot be mapped with the module, because the whole core concept is based on triggering a 404 via a non-existent endpoint and hooking in before it. I wanted to keep it simple and not have to install an additional page as API endpoint and a template for it. ? 

Yeah, I understand the reasons - it's a shame PW doesn't have a dedicated endpoint that is automatically available on all installs so we don't have to deal with hacking into 404. I have wished for something like this many times - I wonder if maybe it should be a feature request?

 

  • Like 1
Link to comment
Share on other sites

4 minutes ago, adrian said:

Yeah, I understand the reasons - it's a shame PW doesn't have a dedicated endpoint that is automatically available on all installs so we don't have to deal with hacking into 404. I haven't wished for something like this many times - I wonder if maybe it should be a feature request?

 

Now that you mention it, the first thing that strikes me is how often I have to build endpoints like this over and over again on every project. ?? I think that would be a really useful feature request, to have a fixed endpoint, which then each module can extend and have access to it.

  • Like 2
Link to comment
Share on other sites

11 minutes ago, David Karich said:

Now that you mention it, the first thing that strikes me is how often I have to build endpoints like this over and over again on every project. ?? I think that would be a really useful feature request, to have a fixed endpoint, which then each module can extend and have access to it.

Would you mind adding this to the Github requests repo? I'd do it, but I feel like I've added so many requests and issue lately that Ryan is starting to tune me out ?

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Hi thanks for the module,

Tried a fresh install of v2.0 with PW 3.0.168,

I works well when I am logged in and navigating the pages. But as soon as I browse not logged in, the pages hits are not recorded.

Any idea. Nothing fancy on my side : templates don't have url semgent activated, it is not a multilanguage install, the pages are not cached at present. The js plugin of the module seems to be loading properly.... No specific configuration as been made. I have not install the pagehit field type for now, rest of the module conf is standard (as it comes after install). I just have list edthe template I wanted to track and set the session life time to 0 for testing purpose.

On an other topic, just saw that you answered my question about multilingual install. Thanks you and sorry I missed your answer. This is why I didnt' react. I will surely test it again in my multilanguage set up.

Regards

Link to comment
Share on other sites

  • 2 months later...

Weird, this is not tracking anything for me. Is it supposed to update in real-time?

Right now I have it assigned to 3 different templates, I see the phits field is there, but it always stays at zero.

Templates are assigned on both auto-tracking and api tracking, tried cookieless tracking on and off, disabled the bot filter and IP validation. Nothing seems to work.

Link to comment
Share on other sites

36 minutes ago, matjazp said:

"data-phc" attribute is missing on body tag. Are you sure you have body at all?

Damn, what a noob. That was it. How does one make a full project, publish it, test it, and never see a broken pages or a piece of red text anywhere saying Hey, where's your <body> tag?

A mistery. Thank you sir, beer's on me ?

  • Like 2
  • Haha 1
Link to comment
Share on other sites

  • 4 months later...

Hey @David Karich

I wanted to install PHC + RHC today like this:

<?php

    // install page hit counter
    $phc = $rm->installModule("PageHitCounter", "https://github.com/FlipZoomMedia/PageHitCounter/archive/refs/heads/master.zip");
    if($phc) {
      $rm->setModuleConfig($phc, [
        'forTemplates' => [
          'home',
          'basic-page',

          // blog
          Item::tpl,
          Overview::tpl,

          // teams
          TeamPage::tpl,
          PersonPage::tpl,
        ],
        // exclude roles from tracking
        'forRoles' => [
          'superuser',
          'webmaster',
        ],
      ]);
      $rm->installModule("PagePaths");
      $rm->installModule("RockHitCounter");
    }
  }

This does ALMOST work. The problem seems to be that the "addCounterField" method does not get triggered when using RockMigrations compared to a manual module save:

<?php

        // ------------------------------------------------------------------------
        // On save actions
        // ------------------------------------------------------------------------
        if($input->post->submit_save_module) {
            $forTemplates       = (array) $input->post->forTemplates;
            $forAPITemplates    = (array) $input->post->forAPITemplates;
            $thousandSeparator  = (string) $input->post->thousandSeparator;
            $cookielessTracking = (int) $input->post->cookielessTracking;
            $sessionLifetime    = (int) $input->post->sessionLifetime;
            $ignoreURLSegments  = (int) $input->post->ignoreURLSegments;
            $ipFilter           = (string) $input->post->ipFilter;
            $botFilter          = (int) $input->post->botFilter;
            $customAttributes   = (string) $input->post->customAttributes;
            $forRoles           = (array) $input->post->forRoles;
            $showForBackend     = (int) $input->post->showForBackend;
            $ipValidation       = (int) $input->post->ipValidation;
            $excludeTemplates   = (array) $input->post->excludeTemplates;

            // ------------------------------------------------------------------------
            // Perform counter reset
            // ------------------------------------------------------------------------
            if($input->post->resetSelector !== "") {
                $modules->get("PageHitCounter")->resetPageViews((string) $input->post->resetSelector, (int) $input->post->dryRun);
            }

            // ------------------------------------------------------------------------
            // Add phit field to selected templates
            // ------------------------------------------------------------------------
            $modules->get("PageHitCounter")->addCounterField(array_unique(array_merge($forTemplates, $forAPITemplates)));
        }

Any ideas how we could make your module work with RockMigrations without having to do a manual module config save?

Thx ? 

Link to comment
Share on other sites

  • 1 month later...

@David Karich could you please modify the js script a little so that we can set the page id of the tracked page manually as function parameter?

LZ0oSZN.png

The example of the docs can then be simplified a lot from this:

$(function(){
    if($('a.news_tag').length > 0) {
        $('a.news_tag').each(function(){
            var tPID = $(this).data("pid");
            if(tPID) {
                $(this).on("click", function(){
                    $.post(location.pathname.replace(/\/?$/, '/') + 'phcv1', {pid: tPID});
                });
            }
        });
    }
});

To something like that (untested):

$(document).on('click', 'a[data-pid]', function(e) {
  let pid = $(e.target).data('pid');
  if(pid) PHC.track(pid);
});

PS: The reason why I need this is I'm using barba.js for page transitions so I need to send page tracking manually after each transition and the <body> tag is not updated from one page to the other meaning that automatic tracking via body[data-phc] does not work...

Link to comment
Share on other sites

On 11/21/2021 at 6:20 PM, bernhard said:

@David Karich could you please modify the js script a little so that we can set the page id of the tracked page manually as function parameter?

LZ0oSZN.png

The example of the docs can then be simplified a lot from this:

$(function(){
    if($('a.news_tag').length > 0) {
        $('a.news_tag').each(function(){
            var tPID = $(this).data("pid");
            if(tPID) {
                $(this).on("click", function(){
                    $.post(location.pathname.replace(/\/?$/, '/') + 'phcv1', {pid: tPID});
                });
            }
        });
    }
});

To something like that (untested):

$(document).on('click', 'a[data-pid]', function(e) {
  let pid = $(e.target).data('pid');
  if(pid) PHC.track(pid);
});

PS: The reason why I need this is I'm using barba.js for page transitions so I need to send page tracking manually after each transition and the <body> tag is not updated from one page to the other meaning that automatic tracking via body[data-phc] does not work...

@bernhard, I think that shouldn't be a problem. I also have other updates on the to-do list. I'll try to push it this year during my Christmas holiday. Unfortunately, I really don't have time at the moment to roll that out sooner.

  • Like 1
Link to comment
Share on other sites

  • 3 months later...

Hi @David Karich, first thanks for the module I learnt to love on many sites. Today I installed version 2.0 on a new site and even if I see the script and the tag in the body tag nothing is beeing count. Any idea what I am doing wrong? (I accessed the site from five different devices). 

 

Link to comment
Share on other sites

@cpx3 this note might help and might even be the issue:

Quote

Upgrade note for 2.0.0 from previous versions!

Version 2.0.0 requires an update in the database schema, so that additionally the date of the last access / hit on the page can be displayed ($page->lastPageHit). To make this possible, you have to do the update via the upgrade module, upload the ZIP itself and do an update directly via the backend AND DO A MODULE REFRESH DIRECTLY AFTER UPLOAD/UPDATE. If you do not do this, you will get an error that a column is missing in the database table.

>>>> All information about the changelog and bug fixings in the first post.

 

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
×
×
  • Create New...