Skip to content

Adding option to store cache either in disk or in transients #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 128 additions & 19 deletions class-wp-rest-cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ private static function hooks() {
add_filter( 'rest_pre_dispatch', array( __CLASS__, 'pre_dispatch' ), 10, 3 );
}

public static function pre_dispatch( $result, $server, $request ) {
public static function pre_dispatch( $result, WP_REST_Server $server, WP_REST_Request $request ) {
$request_uri = esc_url( $_SERVER['REQUEST_URI'] );

if ( method_exists( $server, 'send_headers' ) ) {
Expand All @@ -48,35 +48,144 @@ public static function pre_dispatch( $result, $server, $request ) {
return $result;
}

$timeout = WP_REST_Cache_Admin::get_options( 'timeout' );
$timeout = apply_filters( 'rest_cache_timeout', $timeout['length'] * $timeout['period'], $timeout['length'], $timeout['period'] );

$skip = apply_filters( 'rest_cache_skip', WP_DEBUG, $request_uri, $server, $request );
if ( ! $skip ) {
$key = 'rest_cache_' . apply_filters( 'rest_cache_key', $request_uri, $server, $request );
if ( false === ( $result = get_transient( $key ) ) ) {
if ( is_null( self::$refresh ) ) {
self::$refresh = true;
}

$result = $server->dispatch( $request );
$timeout = WP_REST_Cache_Admin::get_options( 'timeout' );
$timeout = apply_filters( 'rest_cache_timeout', $timeout['length'] * $timeout['period'], $timeout['length'], $timeout['period'] );

set_transient( $key, $result, $timeout );
}
$key = 'rest_cache_' . apply_filters('rest_cache_key', $request_uri, $server, $request);

switch (WP_REST_Cache_Admin::get_options('cache_type')) {
case WP_REST_Cache_Admin::CACHE_TYPE_DISK:
$result = self::deal_with_disk_cache($key, $request, $server, $timeout);
break;

case WP_REST_Cache_Admin::CACHE_TYPE_TRANSIENT:
default:
$result = self::deal_with_transient_cache($key, $request, $server, $timeout);

break;
}

}

return $result;
}

private static function deal_with_transient_cache($key, $request, $server, $timeout) {
$result = get_transient( $key );

if ( false === $result ) {
if ( is_null( self::$refresh ) ) {
self::$refresh = true;
}

$result = $server->dispatch( $request );
set_transient( $key, $result, $timeout );
}

return $result;
}

/**
* Retrieves cache from disk (if available and not expired).
* Otherwise process the request as normal, but stores it
* serialized in Disk.
*
* @param string $key
* @param WP_REST_Request $request
* @param WP_REST_Server $server
* @param integer $timeout
*
* @return mixed
*/
private static function deal_with_disk_cache($key, $request, $server, $timeout) {
$cache_folder = rtrim(WP_REST_Cache_Admin::get_options( 'disk_cache_path' ), '/') .
DIRECTORY_SEPARATOR .
trim($key, '/');

$cached_file = $cache_folder . '/cache';

if( !is_dir($cache_folder) ) {
mkdir($cache_folder, 0744, true);
}

$result = false;

if ( file_exists($cached_file) ) {
if ( $timeout > 0 && ( filemtime( $cached_file ) + $timeout ) > time() ) {
$result = unserialize(file_get_contents($cached_file));
}
}

if ( false === $result ) {
if ( is_null( self::$refresh ) ) {
self::$refresh = true;
}

$response = $server->dispatch( $request );

$result = $response->get_data();
$file = fopen($cached_file, "w");
fwrite($file, serialize($result));
fclose($file);
}

return $result;
}

public static function empty_cache() {
global $wpdb;

return $wpdb->query( $wpdb->prepare(
"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s",
'_transient_rest_cache_%',
'_transient_timeout_rest_cache_%'
) );
switch (WP_REST_Cache_Admin::get_options('cache_type')) {
case WP_REST_Cache_Admin::CACHE_TYPE_DISK:
$return = self::delete_dir_and_files(WP_REST_Cache_Admin::get_options('disk_cache_path'));
break;


case WP_REST_Cache_Admin::CACHE_TYPE_TRANSIENT:
default:
global $wpdb;

$return = $wpdb->query( $wpdb->prepare(
"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s",
'_transient_rest_cache_%',
'_transient_timeout_rest_cache_%'
) );

break;
}

return $return;

}

public static function delete_dir_and_files($dir_path) {
$return = false;
if ( !empty($dir_path) && is_dir($dir_path) ) {
try{
if (substr($dir_path, strlen($dir_path) - 1, 1) != '/') {
$dir_path .= '/';
}
$files = glob($dir_path . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
self::delete_dir_and_files($file);
} else {
unlink($file);
}
}
rmdir($dir_path);
$return = true;

}catch (Exception $e) {
$return = false;
}

}
return $return;
}


}

add_action( 'init', array( 'WP_REST_Cache', 'init' ) );
Expand Down
4 changes: 4 additions & 0 deletions includes/admin/classes/class-wp-rest-cache-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
if ( ! class_exists( 'WP_REST_Cache_Admin' ) ) {

class WP_REST_Cache_Admin {
const CACHE_TYPE_TRANSIENT = 1;
const CACHE_TYPE_DISK = 2;

private static $default = array(
'timeout' => array(
'length' => 1,
'period' => WEEK_IN_SECONDS,
),
'cache_type' => WP_REST_Cache_Admin::CACHE_TYPE_TRANSIENT,
'disk_cache_path' => '/tmp/wp-rest-api-cache'
);

public static function init() {
Expand Down
16 changes: 16 additions & 0 deletions includes/admin/views/html-options.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@
</select>
</td>
</tr>
<tr>
<th scope="row"><?php _e( 'Type of cache', 'wp-rest-api-cache' ); ?></th>
<td>
<?php $cache_type = absint($options['cache_type']); ?>
<select name="rest_cache_options[cache_type]">
<option value="<?php echo WP_REST_Cache_Admin::CACHE_TYPE_TRANSIENT; ?>"<?php selected( $cache_type, WP_REST_Cache_Admin::CACHE_TYPE_TRANSIENT ); ?>><?php _e( 'Transient', 'wp-rest-api-cache' ); ?></option>
<option value="<?php echo WP_REST_Cache_Admin::CACHE_TYPE_DISK; ?>"<?php selected( $cache_type, WP_REST_Cache_Admin::CACHE_TYPE_DISK ); ?>><?php _e( 'Disk', 'wp-rest-api-cache' ); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row"><?php _e( 'Path to cache (if using Disk)', 'wp-rest-api-cache' ); ?></th>
<td>
<input type="text" id="fld-cache-path" style="width: 210px;" name="rest_cache_options[disk_cache_path]" value="<?php echo esc_attr($options['disk_cache_path']); ?>">
</td>
</tr>
<tr>
<th scope="row">&nbsp;</th>
<td><input type="submit" class="button button-primary" value="<?php _e( 'save changes', 'wp-rest-api-cache' ); ?>"></td>
Expand Down