Jump to content

pro cache and counter solution


sakkoulas
 Share

Recommended Posts

hi guys i have a problem and idea it will be a great help. 

I know that this topic it has been discussed sometimes, but i can't find a solution

i use pro cache for my website, but i have to update a counter field any time someone read the specific article.

i have use wanze suggestion here but the problem is that every time the field is updated and the page is saved the pro cache delete the cache for the specific article and  the homepage. 

and this is happen about 5000 times a day .... 

so if the article (page) is cached and i read it, the next user that it will read the article or the homepage it will be uncached... 

so probably the problem will be resolved if i save the counter field of each article  (page ) with page id as a separate page child

but then it will create  a child for each article and until now i have about 28000 articles... 

is there any idea what i can do? thanks

Link to comment
Share on other sites

If you've got a page that is being saved 5000 times a day, then presumably that's because it is displaying some dynamic data. That page would be inappropriate for ProCache, since it caches the entire page output. Though if the page is being displayed more than 10k times a day, then it might still be worthwhile to use ProCache. But keep in mind that there is a small amount of overhead associated each time ProCache saves a cache of your page. So you have to factor that in to the equation. With a page focused on displaying dynamic data, you might be better off doing selective caching with MarkupCache, or just not using the cache. Another technique I'll often use is to handle the dynamic data with javascript, perhaps sending an ajax request back to the server and displaying the result after the cached page has already rendered. But if you are literally saving the page 5k times per day, that's just a lot of cache saving and clearing either way. Isn't there some way you could queue those changes to be committed once per hour or per day or something, so that you can still benefit from a cache?

Link to comment
Share on other sites

@Sakkoulas: as far as I understood, every article page has a counterfield that needs to be counted up one and also needs to be displayed into the article page?

If so, you can set up a new branch in your page tree, lets say you call it counter and assign a new created template, also called counter, to it. This branch will hold all article pages by its ids. And it has only one additional filed, the counter field. Now you can exclude this from ProCache.

With your (cached) article pages you use an AJAX - request to a bootstrapped script (we call it countMeUp.php and it resides in your webroot where we guessing pw's index.php also). Just send the article id to it and get back the current countvalue to display it.

// JS in the article pages template

$.ajax({
    url: '/countMeUp.php',           // here is your Ajax-URL
    type: 'POST',
    data: {
        action: 'articleCounter',    // only needed if you use this script for more than only the counter
        articleId: '<?php echo $page->id;?>',
    },
    success: function(data) {
        // here you have to validate that you have got an integer and nothing else
        ... 
        // if you have an integer you can assign it to your DOM-node to display it
        $('span#idOfTheArticleCounterDisplay').html(data);
    }
});

The countMeUp.php may look like

<?php

// bootstrap PW
	require_once(dirname(__FILE__).'/index.php');

// validation of untrusted user input
	if(!isset($input->post->action) || !in_array($input->post->action, array('articleCounter'))) {
		echo "INVALID1";
		return;
	}
	if(!isset($input->post->articleId) || !is_numeric($input->post->articleId)) {
		echo "INVALID2";
		return;
	}

// now check if it is a valid page id, we use find to respect hidden and unpublished pages, otherwise we could use ->get()
	$p = wire('page')->find('id=' . intval($input->post->articleId));
	if(0==$p->id) {
		echo "INVALID3";
		return;
	}

// is the found page an article page? you should validate template or something other to be sure
	if('article-template' != $p->template) {
		echo "INVALID4";
		return;
	}

// uff! - we have a valid id - lets get its counter
	$parent = wire('pages')->get('template=counter,name=counter');
	if(0==$parent->id) {  // uhm, someone must have messed up our Page Tree, damn! Where is the Counters Parent?
		echo "INVALID5";
		return;
	}

	$cp = wire('pages')->find("parent=$parent,title=" . $p->id);
	if(0==$cp->id) {
		// assuming the first call of a new page from the frontend
		$cp = new Page();
		$cp->of(false);
		$cp->template     = 'counterChild'; // or what ever you have set up for it
		$cp->parent       = $parent;
		$cp->title        = $p->id;
		$cp->counterField = 1;
		$cp->save();
	}
	else {
		// we have the counter, lets count it up
		$cp->of(false);
		$cp->counterField = intval($cp->counterField) + 1;
		$cp->save();
	}

// finally we return the current countValue
	echo intval($cp->counterField);

This is not tested! And yes it could be done more shortened. If you have got it work, you highly want to add some security to it, (sending a hash together with the AJAX that resolves to something what is unique to the article page and not public) otherwise people can mess up your counter by just sending integers to it.

EDIT: and everything what you are allready doing to avoid counter manipulation you also have to add into the countMeUp.php.

Edited by horst
  • Like 2
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...