23

I've come up with a provisional solution for a not exactly common, but far from unprecedented problem with the interaction of popular WP caching solutions with cookies, in this case the standard WP comment cookies. My solution also bears on the rarely well-defined "known users" exception to serving cached files. Whether it's usable or not, I figure that explaining it and possibly learning why it's a bad idea might be generally instructive.

I've tested my method with WP Super Cache, W3 Total Cache, and Comet Cache. The one that I broke down for myself in detail while studying this problem was WP Super Cache ("WPSC" hereafter), so I'll use it as my main example.

BACKGROUND

When a WP standard comment thread is set to allow visitors to comment, comments cookies are set for any commenter who is not a registered user and logged in, with actual commenting privileges subjected to further checks. In what I believe is the most common configuration, a commenter needs to supply only a name and an email address. These are stored within two browser cookies, usually comment_author_ . COOKIEHASH, and comment_author_email_ . COOKIEHASH. COOKIEHASH is defined according to user options.

If set to deliver freshly generated files to "known users," WPSC determines whether or not to serve a cached file on the basis of several checks: Logged-in users get fresh files, and so do visitors "who can comment." The latter are chiefly identified by the presence in their browsers of comment_author_ cookies which are not specifically or uniquely identified for the particular user by the COOKIEHASH (usually but not always an MD5-encoded version of the "siteurl" recorded in site options).

What appears to be the key part of the WPSC code, from wp-cache-phase1.php LL371-383, uses a RegEx pattern to get a string, cycling through the cookies:

$regex = "/^wp-postpass|^comment_author_";
if ( defined( 'LOGGED_IN_COOKIE' ) )
    $regex .= "|^" . preg_quote( constant( 'LOGGED_IN_COOKIE' ) );
else
    $regex .= "|^wordpress_logged_in_";
$regex .= "/";
while ($key = key($_COOKIE)) {
    if ( preg_match( $regex, $key ) ) {
        wp_cache_debug( "wp_cache_get_cookies_values: $regex Cookie detected: $key", 5 );
        $string .= $_COOKIE[ $key ] . ",";
    }
    next($_COOKIE);
}

Now, if I were working strictly in PHP, I could re-produce or hook into WP core functions, and get the normal comment_author_ . COOKIEHASH set by the comment template, but I am working in jQuery using the jQuery Cookie plug-in. However, as you can see if you look at the RegEx, the WPSC function doesn't care about the COOKIEHASH: It's satisfied if it encounters comment_author_.

MY TENTATIVE SOLUTION

$.cookie( 'comment_author_proxyhash', 'proxy_author', { path: '/' } );

For those unfamiliar with jQuery Cookie: The above sets a simple session cookie with key = comment_author_proxyhash and value = proxy_author, good for the entire site. (Also, for those who use jQuery Cookie and WP, in addition to pre-substituting the familiar jQuery $ for the WP jQuery, I've also already set $.cookie.raw = true;.)

I added the line to my jQuery script, and, voila!, WPSC, W3 Total Cache, and Comet Cache are all acting like I want them to. After I use the script, and reload, I get fresh pages. If I happen to place a real comment, the normal comment_author_ and comment_author_email_ cookies are set, and there doesn't seem to be any problem with co-existence.

Perhaps one defect would be that the "proxyhash" cookie will travel with the user as long as he or she keeps the session open, but that doesn't strike me as likely a major problem - or even worth a warning. I've certainly never heard of someone complaining about such a thing happening with one of the regular cookies.

But maybe there's something I'm missing, and about to discover much to my woe, if potentially to my edification as well. Or maybe there's a relatively simple best-practicey way for me to replicate the COOKIEHASH in jQuery, also covering alternative use cases... or to achieve the same end effect by other means - other ways of tricking the caching plug-ins into treating the visitor as a commenter...

If not, is there any good reason NOT to push this or something close to it out to the universe in a plug-in?

  • 3
    Props for a well researched and documented question. However, I feel the nature of the question might open this to more of a discussion as opposed to a definitive answer (off-topic: primarily opinion based). FWIW in my opinion I see nothing wrong here - ultimately you're just setting a single, generic cookie with no personal data. – TheDeadMedic Nov 30 '16 at 9:57
  • Thanks much for the input. I'd be grateful for such a discussion, and I'd mark as good answers any that a) pointed out a problem with this "generic cookie" method, b) provided alternative means for achieving the same effect, or c) provided useful insight into underlying technical questions relating to "known users." – CK MacLeod Nov 30 '16 at 16:57
  • Just to note, you could use wp_localize_script to pass the cookie hash to your Javascript so that you could use the "native" cookie instead of the proxyhash. Otherwise, this is a very interesting issue and your solution seems solid, although cookies + cache are always so complex it's hard to say if it's "the right" solution or if there's something being missed. Great research! – phatskat Aug 25 '17 at 15:38
  • Interesting question - I can't think of anything about this that would get you into trouble, but can I ask why you want to bypass the cache in this way? Giving users this ability kind of defeats the purpose of having the full page cache to begin with. Further, an extra cookie adds to the request size (albeit minimally), when the same result can be achieved with common cache configurations by simply appending any query params to the URL, e.g. mysite.com?a. Just my $0.02... – ssnepenthe Oct 15 '17 at 7:24
  • ssnepenthe: Maybe I should have explained: A plugin I was developing when I wrote the question - wordpress.org/plugins/commenter-ignore-button - uses jQuery to allow visitors to put selected commenters "on ignore." The initial action applies CSS formatting to the comment thread, and then relies on a cookie to store the designation and its presence to duplicate the effect (via PHP) over subsequent refreshes until cookie expiration. In a cached version of the page, the effect wouldn't be registered. So, yes, it's a form of intentional localized cache-busting. – CK MacLeod Oct 15 '17 at 7:40
1

Your solution with comment_author_proxyhash cookie will of course technically work - all caching plugins I know doesn't analyze hash value and will just stop delivery of cached content based on comment_author_* cookie presense.

Problem here is that page caching functionality is something websites really need and often page caching is configured exactly because naked WordPress performance is not enough and able to even crash server at peak times. It depends on website content nature, but site owners sometimes just not able to pay for hardware required to handle everything via PHP/WP code. In other words as much as possible traffic has to be served from page cache whenever possible. From practice I may tell that we often have to identify and disable plugins doing cache exceptions.

Of course it's not always possible, but try to work with cached page whenever possible. For example you may hide div tags with comments you want to ignore via javascript, or ajax-ify whole comments block.

In any case you don't need to mark visitor as a commenter, but stop caching because of your custom logic reasons. So it's better to use unique cookie and make it a cache exception signal. W3 Total Cache has "Reject cookies" option for that, but not other plugins from your list so you'll need a hack like one you have suggested.

  • Thanks! You raise a number of valid issues, but I'll say that what this code does, essentially, is treat any visitor who is participating in the comment threads enough to put someone "on ignore" or "mute" as a "known user/commenter." If a site can't handle such participation, then it probably can't handle a standard WordPress comment template (and commenting community) either! – CK MacLeod Jan 28 '18 at 2:21
  • Think you are right here, while of course can't know for sure how your users use it. Btw many high traffic websites offload their comments processing to a separate requests or even third-party service exactly for the purpose of displaying article content fast and lazy load dynamic comments content later. Take it as an offtopic idea for maybe further versions of your plugin :) – WowPress.host Jan 29 '18 at 14:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.