Support » Plugin: WP REST Cache » How to Clear Custom Endpoint Cache

  • Resolved geochanto

    (@geochanto)


    First of all, thanks for the awesome plugin.

    I have a custom endpoint at /custom/v2/all-products. I was able to cache this with the wp_rest_cache/allowed_endpoints hook, which I added to /wp-content/mu-plugins/wp-rest-cache.php.

    I’m not able to clear this cache. Looks like it’s not able to detect the relation with the product post type. But moreover, it does not clear even when manually clearing rest cache from the WP admin.

    Is there any way to create another hook for this? i.e. if a post type product is saved, then clear cache for this endpoint?

Viewing 14 replies - 1 through 14 (of 14 total)
  • Plugin Author Richard Korthuis

    (@rockfire)

    Hi @geochanto

    Thank you for using our plugin!

    First of all: you should not add your hooks to the /wp-content/mu-plugin/wp-rest-cache.php file. This file might be changed by a future version of our plugin and then your changes will disappear. You should add your hooks to code that isn’t changed with an update, most often your (child) theme’s function.php.

    The plugin will try to detect the object types of entries in your endpoint, but this detection is not flawless. It will check for the existence of the fields id and type and use the type as the object type (or check for id and taxonomy in the case of a taxonomy). If those fields aren’t present it will not be able to detect the object type.

    You can however ‘help’ the plugin to detect the correct object type by using the wp_rest_cache/determine_object_type filter (see the FAQ).

    But even if the plugin doesn’t know the object type of the items in your endpoint, the caches should still be cleared whenever you click the Clear REST cache button.

    geochanto

    (@geochanto)

    @rockfire thanks for the tips. However in my case I don’t even see any caches in the admin area, but cache does seem to be working. I’m not sure that “unkown” object type that others have complained about is my problem.

    I found in other posts that you have this method: \WP_Rest_Cache_Plugin\Includes\Caching\Caching::get_instance()->delete_cache_by_endpoint( '/api/endpoint/here' ); . My guess is that if I call this on save_post, then I could clear the cache manually. I’m just not sure about the PHP syntax how to do so, as I’m mostly a javascript guy. Any pointers would be appreciated.

    I’m also wondering how/where is the cache stored? I could not find any static files, so my guess is that this is a db-level cache?

    Plugin Author Richard Korthuis

    (@rockfire)

    Hi @geochanto

    Are you sure the cache is working? Because I find it strange it would be working but not showing any caches in the admin area. You can check by looking at the response headers from the REST API, it should contain a x-wp-cached-call: served-cache header if the cache is working.

    Calling the delete_cache_by_endpoint(...) function will probably not work, since that is using the same data as is used to display the caches in the admin area. So before trying to implement that we should try and investigate if the cache is indeed working and if so, why the data isn’t saved correctly to display in the admin area.

    Where the caches are stored depends on whether or not you are using external object caching. The caches are stored using the transients API, which are stored by default in the wp_options table (search: SELECT * FROM wp_options WHERE option_name LIKE '%transient%wp_rest_cache%'). If however you are using an external object cache (like Redis or Memcached) it is stored in that object cache.
    No matter if you use external object cache or not the plugin also stores some extra information in the wp_wrc_caches and wp_wrc_relations tables. There is a really small chance that the caches are stored but the extra information is not stored in those tables.
    So could you check your wp_options table and the wp_wrc_caches table to see if there is anything saved? Hopefully from there we can investigate what is going wrong.

    geochanto

    (@geochanto)

    the x-wp-cached-call: served-cache header is there. I restarted the server and now I see caches in the admin area as well. I see that the object type is wrong – it says hardwood instead of product.

    So if I help it determine the right object type it would clear the cache?

    Below does not work. What’s the correct implementation of this?

    function wprc_determine_object_type( $object_type, $cache_key, $data, $uri ) {
        if ( $object_type !== 'unknown' || strpos( $uri, $this->namespace . '/' . $this->rest_base ) === false ) {
            return $object_type;
        }
        // Do your magic here
        if ($object_type == 'hardwood') {
            $object_type = 'product';
        }
        // Do your magic here
        return $object_type;
    }
    Nurgiel

    (@nurgiel)

    Hey =)

    I’m using a custom controller that deletes cashe on save_post using Plugin’s delete_cache_by_endpoint method.

    I’ve edited/simplified it a bit to match your endpoints, hope it helps!
    https://gist.github.com/Nurgiel/7b379aba37542981680af285ac19fa6b

    • This reply was modified 1 year ago by Nurgiel.
    Plugin Author Richard Korthuis

    (@rockfire)

    Hi @geochanto

    Strange that you had to restart the server to see the caches in the admin area, but great it works now šŸ™‚

    This is probably the correct implementation for you:

    function wprc_determine_object_type( $object_type, $cache_key, $data, $uri ) {
        if ('hardwood' === $object_type) {
            $object_type = 'product';
        }
        return $object_type;
    }
    add_filter( 'wp_rest_cache/determine_object_type', 'wprc_determine_object_type', 10, 4 );
    geochanto

    (@geochanto)

    @rockfire with that, it did not update the object_type in the admin area, so I tried to delete that cache record, then hit the API again.

    I’m getting the x-wp-cached-call: served-cache header, and an updated response. But, the endpoint is not re-cached in the admin area. So, I suspect it may be a false positive and cache is actually not served.

    *EDIT:* confirmed cache does not work, after checking the wp_options table as suggested.

    I think calling delete_cache_by_endpoint may be a simpler approach.

    • This reply was modified 1 year ago by geochanto.
    geochanto

    (@geochanto)

    @nurgiel thanks for taking the time. I see you have a lot of stuff going on in there. I think I probably don’t need to do all that. My need is simple, something like this pseudocode called from functions.php. I just don’t know the correct syntax for to call that method from another file, because delete_cache_by_endpoint is in /wp-content/plugins/wp-rest-cache/includes/class-caching.php:

    
    on_save_post {
      if(post->type === 'product) {
      delete_cache_by_endpoint('/custom/v2/all-products');
      }
    }
    

    Can I do this?

    geochanto

    (@geochanto)

    @nurgiel FYI I did try to use your entire controller, but with that caching no longer works šŸ™

    geochanto

    (@geochanto)

    after playing around for a while, I think I got it šŸ™‚ cache seems to be clearing for the right post type, and caching seems to be working – can verify with the response header, and also cache hit incrementing in the admin area.

    Here’s my code:

    <?php
    
    require_once ABSPATH . 'wp-admin/includes/plugin.php';
    if ( is_plugin_active( 'wp-rest-cache/wp-rest-cache.php' ) ) {
        include_once WP_PLUGIN_DIR . '/wp-rest-cache/wp-rest-cache.php';
    
        $wp_rest_cache_api = new \WP_Rest_Cache_Plugin\Includes\API\Endpoint_Api();
        $wp_rest_cache_api->get_api_cache();
    
        function wprc_add_acf_posts_endpoint( $allowed_endpoints ) {
            if ( ! isset( $allowed_endpoints[ 'custom/v2' ] ) || ! in_array( 'all-products', $allowed_endpoints[ 'custom/v2' ] ) ) {
                $allowed_endpoints[ 'custom/v2' ][] = 'all-products';
            }
    
            if ( ! isset( $allowed_endpoints[ 'custom/v2' ] ) || ! in_array( 'all-posts', $allowed_endpoints[ 'custom/v2' ] ) ) {
                $allowed_endpoints[ 'custom/v2' ][] = 'all-posts';
            }
    
            return $allowed_endpoints;
        }
        add_filter( 'wp_rest_cache/allowed_endpoints', 'wprc_add_acf_posts_endpoint', 10, 1);
    
        function refreshCache($postId)
        {
            // If this is just a post revision, do nothing.
            if (wp_is_post_revision($postId) || wp_is_post_autosave($postId)) {
                return;
            }
            
            // Verify if this isn't an auto-save routine.
            // If it is that our form has not been submitted then we dont want to do anything.
            if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
                return;
            }
            
            // Return if it's a post revision.
            if (wp_is_post_revision($postId) !== false) {
                return;
            }
    
            $post_type = get_post_type($postId);
    
            $caching = \WP_Rest_Cache_Plugin\Includes\Caching\Caching::get_instance();
            if ($post_type === 'post') {
                $caching->delete_cache_by_endpoint("/wp-json/custom/v2/all-posts");
            }
            else if ($post_type === 'product') {
                $caching->delete_cache_by_endpoint("/wp-json/custom/v2/all-products");
            }
            
        }
        add_action('save_post', 'refreshCache', 1);
    }
    Plugin Author Richard Korthuis

    (@rockfire)

    Hi @geochanto

    It would probably have worked with the wp_rest_cache/determine_object_type if you first deleted the old caches. Not flushed/cleared, but actually deleted them (via Settings > WP REST Cache > Tab: Endpoint API Cache > Delete cache record). It is something we should probably reconsider, but at this point we do not update the object type once a cache has been stored.

    Now about your code: great you have got it working for you. I do however have some remarks:

    It seems like you either have added your filters to the mu-plugins/wp-rest-cache.php, which I must recommend you to not do that (see my first comment). Or you have made a copy of it. In this case I must recommend you to (at least) delete the lines:

    $wp_rest_cache_api = new \WP_Rest_Cache_Plugin\Includes\API\Endpoint_Api();
    $wp_rest_cache_api->get_api_cache();

    Also in the refreshCache function you are checking twice for wp_is_post_revision($postId), in the first if-clause and in the third if-clause. So the third can be removed.

    Nurgiel

    (@nurgiel)

    Also in the refreshCache function you are checking twice for wp_is_post_revision($postId), in the first if-clause and in the third if-clause. So the third can be removed.

    Whoopsie =] my bad.

    @geochanto

    Are you still there ??

    can you help me , i need to flush cache for a specific object type ( from function.php) every time a specific endpoint is called

    @sawasblog If I were you, I’d try to open a new ticket and reference any info in this one. I have limited knowledge of PHP so chances are I can’t provide you with the answers you need beyond what’s already described in this ticket.

Viewing 14 replies - 1 through 14 (of 14 total)
  • The topic ‘How to Clear Custom Endpoint Cache’ is closed to new replies.