Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
WpRestApiCache Controller
<?php
/**
* WpRestApiCache Controller.
* This file extend the wp-rest-api-cache plugin that allows filtering of
* cache depending on conditions met.
*
* @package BeachbodyOnDemand\WpRestApiCache
*/
namespace BeachbodyOnDemand\WpRestApiCache;
use Inpsyde\Wonolog\Channels;
use Inpsyde\Wonolog\Data\Log;
use Monolog\Logger;
/**
* Remove the admin menu is a user doesn't have the cap `delete_users`.
*
* @return bool
*/
add_filter( 'rest_cache_show_admin_menu', function() : bool {
return current_user_can( 'delete_users' ) ?: false;
} );
/**
* Remove the admin bar menu item.
*
* @return bool
*/
add_filter( 'rest_cache_show_admin_bar_menu', '__return_false' );
/**
* Add headers to our REST response.
* The filter is called during the `rest_pre_dispatch` hook.
*
* @param array $headers Array of headers.
* @param string $request_uri global server REQUEST_URI.
* @param \WP_REST_Server $server Server instance.
* @param null|\WP_REST_Request $request Request used to generate the response.
* @return array
*/
add_filter( 'rest_cache_headers', function(
array $headers,
string $request_uri,
\WP_REST_Server $server,
\WP_REST_Request $request,
$response
) : array {
$headers['Cache-Control'] = 'public, max-age=3600';
/*
* If the response is a WP_REST_Response, we've got our data.
* This is were we should carefully comb through each object to determine what we should pass to
* out headers. If it's a big data set, find the newest 'modified_gmt' and compare it to the clients
* 'if_modified_since'.
*/
if ( $response instanceof \WP_REST_Response && ! $response->is_error() ) {
if ( is_array( $response->get_data() ) ) {
$posts = [];
foreach ( $response->get_data() as $post ) {
if ( ! isset( $post['modified_gmt'] ) ) {
continue;
}
$posts[] = $post['modified_gmt'];
}
if ( ! empty( $posts ) ) {
$newest = max( array_map( 'strtotime', $posts ) );
if ( is_int( $newest ) ) {
$headers['Last-Modified'] = ( new \DateTime( '@' . $newest ) )->format( DATE_RFC7231 );
}
}
}
$headers['Expires'] = ( new \DateTime() )->modify( '+1 hour' )->format( DATE_RFC7231 );
}
return $headers;
}, 10, 5 );
/**
* Don't skip object cache unless we don't have any Memcached servers in our pool or the
* `disable_object_cache` REQUEST is set.
*
* @param bool $skip Incoming value. Defaults to the value of `WP_DEBUG`.
* @param string $request_uri Server REQUEST_URI.
* @return bool
*/
add_filter( 'rest_cache_skip', function( bool $skip, string $request_uri ) : bool {
return empty( get_bod_memcached_servers() ) || (
isset( $_REQUEST['disable_object_cache'] ) &&
1 === filter_var( $_REQUEST['disable_object_cache'], FILTER_VALIDATE_INT ) ||
( ( is_user_logged_in() && is_admin() ) || is_customize_preview() )
);
}, 10, 2 );
/**
* Log the result of the skipped rest_cache.
*
* @param mixed $result The outgoing REST results.
* @param \WP_REST_Server $server Server instance.
* @param \WP_REST_Request $request Request used to generate the response.
*/
add_action( 'wp_rest_cache_skipped', function( $result, \WP_REST_Server $server, \WP_REST_Request $request ) {
do_action( 'wonolog.log', new Log(
sprintf( 'The `%s` REST route cache was skipped.', $request->get_route() ),
Logger::NOTICE,
Channels::DEBUG,
[
$result,
$server,
$request,
]
) );
}, 10, 3 );
/**
* Log the result of the skipped rest_cache.
*
* @param string $message The setting error message.
* @param string $type The setting error type code.
* @param \WP_User $user The current WordPres user performing the action.
*/
add_action( 'rest_cache_request_flush_cache', function( string $message, string $type, \WP_User $user ) {
do_action( 'wonolog.log', new Log(
sprintf( 'The `%s` user just flushed the object cache.', $user->user_login ),
Logger::NOTICE,
Channels::DEBUG,
[
$message,
$type,
$user->ID,
$user->user_email
]
) );
}, 10, 3 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.