Enable cache, and disable hits
When you enable caching in Joomla, article hits do not increase when cached pages are served. This is unfortunately a limitation of the caching system in Joomla, there is not “toggle switch” to enable this feature.
Hits not always accurate, but sometimes needed
For those users needing this feature, it’s usually recommended that they instead switch to a more accurate tracking system, like Google Analytics. This though is an alternative, and doesn’t actually present a solution to the problem at hand. Even though not 100% accurate, sometimes article hits are necessary, such as the scenario when you need to order articles based upon their popularity.
We created a solution
The article that you’re reading right now is within InMotion Hosting’s Support Center, and is served using Joomla. We have enabled caching in Joomla, and ourselves needed the hits on articles to increase. In this tutorial, we will outline the steps we’ve taken to have Joomla increase article hits event when a cached page is served.
- Disable article hits
I know it sounds funny, but the first step in this entire process is to disable article hits. The solution we are implementing will use ajax to increase article hits. We don’t want Joomla to increase hits at the same time our ajax call is increasing hits, this would result in double hits.
Edit the following file and add the code highlighted in red below:
components/com_content/models/article.php
public function hit($pk = 0) { return true; $input = JFactory::getApplication()->input; $hitcount = $input->getInt('hitcount', 1); if ($hitcount) { $pk = (!empty($pk)) ? $pk : (int) $this->getState('article.id'); $table = JTable::getInstance('Content', 'JTable'); $table->load($pk); $table->hit($pk); } return true; }
Core file change!
This step edits a core file, which is not recommended. You can skip this step, however this will result in hits increasing by 2 (instead of 1) when cache is not used to server a page. - Enclose your hit count within a span tag
After using ajax to make a call to increase article hits, we will update the current hit counter on the page so that it is accurate. We will use javascript for this, and javascript needs to know where on the page the hits are showing. We label the article hit counts by wrapping it within a span tag.
Create a language override and add the changes highlighted in red:
Language Constant: COM_CONTENT_ARTICLE_HITS Text Hits: <span id=”article_hits”>%s</span> - Add the ajax calls to your articles
Now it’s time to add the ajax calls to our articles. It’s this ajax call that makes a request to increase article hits, and will run regardless if the page is being served via cache or not. Edit the following file and add the code highlighted in red at the end of the file:
components/com_content/views/article/tmpl/default.php
<?php if (!empty($this->item->pagination) && $this->item->pagination && $this->item->paginationposition && $this->item->paginationrelative) : echo $this->item->pagination; ?> <?php endif; ?> <?php echo $this->item->event->afterDisplayContent; ?> </div> <script type='text/javascript'> jQuery.post( '<?php echo JURI::base(); ?>includes/increase_hits.php', {option:'com_content',view:'article',id:'<?php echo $this->item->id; ?>'}, function(data,status){jQuery('#article_hits').html(data);},'text' ); </script>
Core file change!
This step edits a core file, which is not recommended. You should instead add this code to an override. - Create increase_hits.php
Create the following file. This is the php script that our ajax call will interact with.
includes/increase_hits.php
<?php /** * Use this script to update article hits when caching is enabled * Setup guide can be found here: https://www.inmotionhosting.com/support/edu/joomla-3/increase-hits-cache */ if ( $_POST['option'] == "com_content" && $_POST['view'] == "article" && is_numeric($_POST['id'])) { // connect to the database include_once("../configuration.php"); $cg = new JConfig; $con = mysqli_connect($cg->host,$cg->user,$cg->password,$cg->db); if (mysqli_connect_errno()) die('n/a'); // increase hits $query = " UPDATE `" . $cg->dbprefix . "content` SET `hits` = `hits` + 1 WHERE `id` = " . $_POST['id'] . " LIMIT 1; "; mysqli_query($con,$query); // grab the new hit count $query = " SELECT `hits` FROM `" . $cg->dbprefix . "content` WHERE `id` = " . $_POST['id'] . " LIMIT 1; "; $new_hits = mysqli_fetch_assoc(mysqli_query($con,$query)); // close the connection to the database mysqli_close($con); echo $new_hits['hits']; } ?>
And that’s it! It’s the same approach we’ve used for our own Joomla site. If you have any problems getting this to work, feel free to post a comment below. Alternatively, post a comment too if you have another method users can implement to increase hits when cache is being used.
Thanks!
A special thanks to Pankaj with joomlart.com for the encouragement to write this article.
It’s not working for me on Joomla 3.4. Is there some parts you’re supposed to enter individual site details, or are you supposed to put the code as is?
Hello Sam,
sorry for the problems with Joomla 3.4. Yes, you are supposed to insert server relevant information where the code indicates a connection or server reference. For example, the database connection information would be required. Other than that, the code should be used as it is provided above.
I hope this helps to answer your question, please let us know if you require any further assistance.
Regards,
Arnel C.
I think I found the…guilty. I applied the code to templates/mytemplate/html/com_content/article/default.php
This file was allready there at my template. So I add the code there. It works now.Hope I didn’t make mistake.
Once again Thank you.
Best regards
Elias
In addition to my previous post I would kindly like to add a strange (for me) thing.
I did your method succesfully in my dev site. But in my live site this doesn’t work. Keep in mind that theese 2 sites are online.The dev site is in a subfolder and it’s the clone of my live one. In the dev site I do my…homework, testing this and that.
The strange part is that in dev site the method works ok. In the live it’s not! What do you think is cousing this? I miss somthing for sure. I checked every step and I everything is good. Something else is cousing this. What’s your opinion? Can you point me at the right direction (what to check, etc)?
Thank you once again
Elias,
1) I would back up all your files first, then go ahead with the overwrite. If anything happens after that, then you can always return to the backup point.
2) If you are finding that your numbers are correct, except for the first time, then it should be okay. There may be differences in Joomla installation versions, plugins, etc. that may affect how this is operating. The most important thing is that you are getting consistent results from your testing. If you continually have the correct number AFTER your run your test, then you should use what you have with no issue.
3)It shouldn’t really matter the languages, if you made the correction in the core files.
If you have any further questions or comments, please let us know.
Regards,
Arnel C.
Hello Elias,
I’m not sure why your code wouldn’t work in live versus the dev site. I would think that there has to be some difference in the code that you’re applying on the dev, that is not the same in the live. It may have to do with server references or it might have to do with support services being different from one server to another. It’s hard to say. I would recommend checking the error logs to see if anything has been captured that could account for the problem you’re seeing.
I hope this helps to answer your question, please let us know if you require any further assistance.
Regards,
Arnel C.
Thank you for your reply. I succesfully did your method and it works like a charm. However I have some questions if you don’t mind.
1. I didn’t use the first edit here (components/com_content/models/article.php) becouse I am afraid to edit core files. Can I use an override for this?
2. You say that I can skip that step but this will result in hits increasing by 2 (instead of 1). That’s true but only at the first time you read an article. The next time you read the same article, the counter increases normally by 1. That’s what I see when I test it. Am I wrong with that? My point is…Will I have problem becouse I skipped the first step?
3. I did the language overrides in both two languages that I use. Is this wrong?
Thank you
So it is safe to do what article says, or not. I am new at this, I am trying to learn and I am confused a bit, from Dmitry’s post 🙂
Hello Elias,
You should be fine for the most part. If you are worried about security you may read the following StackOverflow.com thread about sanitizing your sql code.
Best Regards,
TJ Edens
SQL Injection – welcome!
Did you ever heard about sanitising inputs?
Hello Dmitry,
Thanks for the input. Your point is well taken. I will request to have the article updated with that in mind. For anyone interested in the topic, check out this post.
If you have any further questions or comments, please let us know.
Regards,
Arnel C.
I know this has not yet been tested with 2.5, as mentioned by JeffMa, so I just wanted to verify his comment. No errors after implementing the hacks, but I read further on a Joomla Forum that the failure to update hits may very well be due to the delay in the caching time. So, I set the cache to 1 minute, as opposed to the default 15 minutes, and the page hits did update without any need to hack any files. So, my suggestion would be to wait for the site to cache and then check the page hits again. You may not need to do anything.
Tested this on Joomla 2.5.28 and it did not work. Any suggestions?
As this is in the Joomla 3 category, there may have been some changes since your version. Are you getting any errors when performing this?
Hi,
Thank you very much for sharing this article.
I tried it in our Joomla 3 site and it works fine. But I have one small problem.
In case there’s a pagebreak and the user navigates to other pages in the same article the hit count is increased.
So if there are 3 pages in a article, for every user visit to that article, count is increased by 3.
We have made the step 3 changes in the template overriden default.php and we are using Jooma shine’s JSN Boot template.
Can you please suggest some idea to fix this? Thanks in advance.
Thank you.
Great, thank you for the tips. Would this work for Joomla 2.5 and how to have the same for K2 items ?
It has not been tested but in theory it should work just fine in Joomla 2.5. Unfortunately, we are not familiar with K2.