Support

Account

Home Forums Bug Reports ACF Fields not caching with W3-Total-Cache

Solving

ACF Fields not caching with W3-Total-Cache

  • I recently ran into a bug where I discovered that when W3-Total-Cache is installed, results returned from the function acf_get_field() in api/api-field.php on line 797 are not cached.

    This is because of the code on line 832 which attempts to get the cache:

        // get cache
        if( !$db_only ) {
         
            $found = false;
            $cache = wp_cache_get( $cache_key, 'acf', false, $found );
         
            if( $found ) return $cache;
         
        }  

    This calls wp_cache_get(), which is defined in W3 Total Cache as:

         function wp_cache_get($id, $group = 'default') {
             global $wp_object_cache;
     
             return $wp_object_cache->get($id, $group);
         }

    Notice that it’s missing the 3rd and 4th parameters, and the ACF code uses the 4th parameter ($found) to check if any entries were found. Since that variable is never set by W3 Total Cache, it always returns false, meaning that ACF never thinks it has cached results.

    I noticed this bug because I switched from W3 Total Cache to Redis and started running into issues where my acf/load_field filters were never being called in certain cases (because Redis was properly caching the results, and returning before those filters ran).

    However, if this does get patched, I would also like a way to bypass the cache (perhaps using $db_only), but still allow filters to run. Currently, the apply_filters() calls take place AFTER the check for $db_only–this means the filters will only ever run if no cached entry was found and if db only is false.

  • Hi @jsavage37

    I believe this is an issue with W3 Total Cache. ACF uses WordPress wp_cache_get() function which has four parameters, not two. There are several topics regarding this issue on W3 Total Cache’s forum, but I don’t know why they didn’t answer it. Here are the examples: https://wordpress.org/support/topic/w3-total-cache-does-not-correctly-implement-wp_cache_get, https://wordpress.org/support/topic/w3tcs-wp_cache_get-implementation. Could you please ask W3 Total Cache’s support instead?

    Thanks 🙂

  • Hi @james,

    Thanks for the response! I’m actually planning on moving away from W3 Total Cache to using Redis (which has a properly implemented cache function), so that piece shouldn’t be too much of an issue for me.

    However, there is the problem I’ve been running into with cache. In my code, I’m attempting to dynamically populate ACF Dropdown fields in the admin area, based on other post content. This is done using the filter ‘acf/load_field/name=field_name’. When caching isn’t working with W3 Total Cache, this runs fine. But when using a working cache it will run correctly once, cache those results, and then give me those same cached results for every post.

    This also won’t work with the argument $db_only = true, because it returns before the filters run.

    This problem could be solved by moving the filter calls above line 872 in api/api-field.php, and also moving them into line 848 in the same file. With the way it currently is, it will only ever run once, which is nice for most use cases, but doesn’t allow the same field to have different values on different posts with caching.

    Is there a way around this?

    Thanks!

  • Hi @jsavage37

    Could you please exclude the backend from Redis? I believe the backend (admin page) or any pages that change too much are not supposed to be cached.

    I hope this makes sense 🙂

Viewing 4 posts - 1 through 4 (of 4 total)

The topic ‘ACF Fields not caching with W3-Total-Cache’ is closed to new replies.