drupal-7drupal-formsdrupal-commercedrupal-form-validation

Caching product display with Display Cache and still be able to add products


I'm building an eCommerce website using D7, mainly with Commerce and DS. To get a better perfomance I installed Display Cache which is a module that caches the rendered HTML of an entity for anonymous and authenticated users. In my particular case i'm caching the Product Display (a node which references a product and it's variations if any).

After a few hours of configuration I end up with a "good result" in performance. All my entities where cached by rol, in teaser and full mode... but then the problem arises when the user clicks "Add to cart" button because it's not adding products to the cart... nor it is showing an error.

One possible reason is the form token or some form processing function that is invalidating the action because the form is not generating everytime as expected. I read how to disable the form token in the "Add to cart form" (or any form) but it's not working. I set $form['#token'] to false, but still is not adding products to the cart.

Probably the solution is not easy, but I need clues of what I could do or where I could start tackling the problem.

So, thanks for you expertice.


Solution

  • A solution to this combination of modules, in order to have cached display for anonymous & authenticated users and add to cart forms is to disable cache programatically of the requested product in all it's displays... and disable the token of the "add to cart form".

    Here is the code for disabling the token:

    function YOUR_MODULE_form_alter(&$form, &$form_state, $form_id) {
        if (strstr($form_id, 'commerce_cart_add_to_cart_form') || strstr($form_id, 'views_form_commerce_cart_form_default')) {
            unset($form['#token']);
        }
    }
    

    And here is the code to remove caching when a an add to cart button is pressed:

    function YOUR_MODULE_init() {
        if (isset($_POST['product_id'])) {
            $id_product = intval($_POST['product_id']);
            $res = views_get_view_result('sys_search_product_display', 'default', $id_product);
            foreach ($res as $nid) {
                display_cache_flush_cache('node', $nid);
            }
        }
    }
    

    Note that "sys_search_product_display" is just a view which receives the ID of the product and returns the ID of the product display. This can be done in other ways.