How to Clear Custom Endpoint Cache
-
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 thewp_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?
-
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
andtype
and use thetype
as the object type (or check forid
andtaxonomy
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.@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?
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 thewp_wrc_caches
andwp_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 yourwp_options
table and thewp_wrc_caches
table to see if there is anything saved? Hopefully from there we can investigate what is going wrong.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 sayshardwood
instead ofproduct
.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; }
Hey =)
I’m using a custom controller that deletes cashe on
save_post
using Plugin’sdelete_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 5 years, 4 months ago by
Nurgiel.
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 );
-
This reply was modified 5 years, 4 months ago by
Richard Korthuis.
@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 5 years, 4 months ago by
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?
@nurgiel FYI I did try to use your entire controller, but with that caching no longer works ??
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); }
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 forwp_is_post_revision($postId)
, in the first if-clause and in the third if-clause. So the third can be removed.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.
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.
-
This reply was modified 5 years, 4 months ago by
- The topic ‘How to Clear Custom Endpoint Cache’ is closed to new replies.