0

I'm currently trying to unset a session variable in WordPress if the page get's reloaded. I've tried a lot but it's not working like I want it. This is my function:

/**
 * Unset filter session if page get's reloaded
 */
add_action( 'wp', 'unset_filter_session' );
function unset_filter_session() {
    //Reset sessions on refresh page
    unset( $_SESSION['expenditure_filter'] );
}

It's working but it's working too good. Because when I reload the content-area in WordPress via AJAX, the session get's unset too which should be avoided:

jQuery('#content-area').load(location.href + ' #content-area>*', '');

So how can I do the unset of the session just on page load and exclude AJAX reloads?

4
  • I'd keep in mind that sessions don't work on all hosts, and are incompatible with a lot of caching mechanisms, with an added server overhead, which is why WP uses cookies and user meta
    – Tom J Nowell
    Commented Dec 5, 2018 at 0:43
  • User meta is not possible for not registered users. Cookies might be a solution but what if the user disabled cookies?
    – Johnny97
    Commented Dec 5, 2018 at 0:46
  • I wouldn't expect any site to be able to track what I'm doing if I set cookies, which is kind of the point. At that point you could create table entries or posts and pass around a transaction ID, but then you would need the users consent to store data about them to comply with data protection legislation, else it could be illegal in some states/countries/continents, e.g. California, or the EU
    – Tom J Nowell
    Commented Dec 5, 2018 at 0:57
  • Additionally, you can use URLs, a filtered view can have a filter endpoint on the end so it remains unique, this also improves compatibility with fullpage caching
    – Tom J Nowell
    Commented Dec 5, 2018 at 0:58

2 Answers 2

2

Try using wp_doing_ajax() like so:

function unset_filter_session() {
    if ( ! wp_doing_ajax() ) {
        //Reset sessions on refresh page
        unset( $_SESSION['expenditure_filter'] );
    }
}

UPDATE

You can check the answer's revision for this update part..

UPDATE #2

Sorry, I didn't realize that you're loading a page fragment (#content-area) using the jQuery.load() method. Or that you're not using the admin-ajax.php to handle the AJAX request.

So if you're not using the wp_ajax_{action} or wp_ajax_nopriv_{action} action, or with the way you do the AJAX request, you can check whether the X-Requested-With header is set and that its value is XMLHttpRequest, and if so, you can cancel the session unsetting, like so:

function unset_filter_session() {
    if ( empty( $_SERVER['HTTP_X_REQUESTED_WITH'] ) ||
        'XMLHttpRequest' !== $_SERVER['HTTP_X_REQUESTED_WITH'] ) {
        //Reset sessions on refresh page, if not doing AJAX request
        unset( $_SESSION['expenditure_filter'] );
    }
}

That should work because jQuery always sets that header, unless you explicitly remove it — or change its value.

See the headers option on the jQuery.ajax() reference:

The header X-Requested-With: XMLHttpRequest is always added, but its default XMLHttpRequest value can be changed

Note: The header name is X-Requested-With, but in the superglobal $_SERVER, its key is HTTP_X_REQUESTED_WITH. I.e. Don't use $_SERVER['X-Requested-With'].

UPDATE #3

As suggested by Lawrence Johnson, you (ahem, we) should use filter_input():

function unset_filter_session() {
    if ( 'XMLHttpRequest' !== filter_input( INPUT_SERVER, 'HTTP_X_REQUESTED_WITH' ) ) {
        //Reset sessions on refresh page, if not doing AJAX request
        unset( $_SESSION['expenditure_filter'] );
    }
}

(but I kept the previous code for reference)

13
  • This is not working, sadly :(
    – Johnny97
    Commented Dec 5, 2018 at 0:47
  • I haven't actually tested the code, but I'll see if I can come up with another solution. However, as an aside, you could try localStorage or sessionStorage in JavaScript.. but yes, JS has to be enabled on the browser and that localStorage / sessionStorage is actually supported and again, enabled.
    – Sally CJ
    Commented Dec 5, 2018 at 1:02
  • 1
    Also, as for the AJAX calls going through wp_ajax_ methods, I agree with you, but this looks like its for a single page app. His approach for dynamically loading content using this method is not abnormal; still, I probably would've broken the content out into includes and create an ajax handler for retrieving them. Commented Dec 5, 2018 at 17:47
  • 1
    @SallyCJ, it sounds like our answers are in alignment now. I would recommend using filter_input over querying $_SERVER directly, though. It is a fundamentally safer way to retrieve values that could potentially be manipulated by a malicious user, and in your case you could reduce the condition since it will return null for not found or false for invalid. Commented Dec 6, 2018 at 17:03
  • 1
    Once again, +1 for that @LawrenceJohnson, and thanks a lot for helping :) (I've updated the answer)
    – Sally CJ
    Commented Dec 6, 2018 at 17:52
0

One thing you could consider doing is adding a header variable to your AJAX requests. Even a GET or POST param would likely to the trick. Perhaps something like this:

/**
 * Unset filter session if page get's reloaded
 */
add_action( 'wp', 'unset_filter_session' );
function unset_filter_session() {
    //Reset sessions on refresh page
    if (!filter_input(INPUT_POST, 'isContentLoader', FILTER_SANITIZE_NUMBER_INT)) {
        unset( $_SESSION['expenditure_filter'] );
    }
}

And then

jQuery('#content-area').load(location.href + ' #content-area>*', { isContentLoader: 1 });
1
  • I won't include it in the answer since it doesn't fit the question, but, if it were me, I wouldn't be storing something in session that is only supposed to live within the active page. It'd be much easier to maintain consistency by storing the variables in your JavaScript and posting as needed for server-side processing. Commented Dec 5, 2018 at 6:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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