Errors when using negative ttl for hole punching

#1
We have a product site that has two possible states:

Logged In:

The product price is shown.

Not Logged In:

The price is not shown and you get a text saying that you need to login to see the price.

Problem:

Currently the "Not Logged In" state of the site is being cached and if the customer logs in, then the site gets served from the cache, and incorrectly showing the not logged in state instead of showing the "Logged In" state.
Only if the customer reloads the site again, then it shows the "Logged In" state.

So I added ttl="-1" to the block in the catalog_product_view.xml layout file, to make it private.


XML:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>  
        <referenceContainer name="product.info.form.content">
            <block class="Magento\Catalog\Block\Product\View"
                    name="product.info.addtocart"
                    as="addtocart"
                    template="Vendor_Module::product/view/addtocart.phtml"
                    ttl="-1"
            />
        </referenceContainer>
    </body>
</page>
But then if the site loads it outputs this error:

Error: Call to a member function isSaleable() on null in app/code/Vendor/Module/view/frontend/templates/product/view/addtocart.phtml:4
This is the code:

app/code/Vendor/Module/view/frontend/templates/product/view/addtocart.phtml

PHP:
<?php
$_product = $block->getProduct();
if ($_product->isSaleable()):
    echo "Some logic...";
endif;

I noticed even more problems, e.g. you can't check if a customer is logged in with \Magento\Customer\Model\Session if you are using a negative ttl.

Am I doing something wrong, or is it a bug in the litemage extension?
 
Last edited:

serpent_driver

Well-Known Member
#2
Currently the "Not Logged In" state of the site is being cached and if the customer logs in, then the site gets served from the cache, and incorrectly showing the not logged in state instead of showing the "Logged In" state.
Only if the customer reloads the site again, then it shows the "Logged In" state.
Do you use any custom login function that doesn't reload or redirect the page after login?

So I added ttl="-1" to the block in the catalog_product_view.xml layout file, to make it private.
LiteMage doesn't support private cache. Only LiteCache supports it.

https://www.cachecrawler.com/LiteCache:::39.html
https://www.cachecrawler.com/Download/LiteCache-for-Magento-2::118.html
 
#3
@serpent_driver Yes, I am using a custom login with JWT. I forgot to mention it.
We are checking if the user is sending a JWT with the request headers and if true evalute it and login the user in a observer if it is valid.
We are observing the event `controller_action_predispatch`.

This seems to be the problem. If I login normally, then there is no issue.

LiteMage doesn't support private cache. Only LiteCache supports it.
This is not correct. They updated the documentation a short time ago. They support private cache.
 
Last edited:

serpent_driver

Well-Known Member
#5
Yes, I am using a custom login with JWT. I forgot to mention it.
We are checking if the user is sending a JWT with the request headers and if true evalute it and login the user if it is valid.
I don't know what JWT is, but to make your changes work a page reload is always necessary to make your changes work. LiteSpeed LScache is a page cache that caches the output of the entire content of a requested URL. If you change partially content by AJAX without reload of the entire page LScache cannot take into account this changes in a different cache copy.
 
#6
@serpent_driver JWT is a token that holds the users credentials. If a user enters his credentials in the login form (a popup on the site where the customer stays at the moment) and submits, then a ajax request to our server is made where the JWT token is generated and sent back and the site gets reloaded. Then this JWT will be transmitted with each request the user makes.

So as I mentioned after the user got the JWT, the site will get reloaded and in this process an observer watching the event `controller_action_predispatch` gets triggerd. In this observer the JWT will be read out and decoded/decrypted in order to retrieve the username and password so we can check if these credentials are correct. If true the user will get logged in with the `loginById` method from the Magento\Customer\Model\Session class. So this happens during the site load.

I guess the solution is to reload the site again, after the login, like you have mentioned. Or maybe we could use another observer event...
We are using the JWT solution specifically for our App version of our shop.
On desktop customers are logging in normaly.
 
Top