Add feature to cache story cards
This commit is contained in:
parent
9e06156c9c
commit
8c77b23260
@ -1597,6 +1597,8 @@ define( 'CONSTANT_NAME', value );
|
||||
| FICTIONEER_QUERY_ID_ARRAY_LIMIT | integer | Maximum allowed IDs in 'post__{not}_in' query arguments. Default `100`.
|
||||
| FICTIONEER_PATREON_EXPIRATION_TIME | integer | Time until a user’s Patreon data expires in seconds. Default `WEEK_IN_SECONDS`.
|
||||
| FICTIONEER_PARTIAL_CACHE_EXPIRATION_TIME | integer | Time until a cached partial expires in seconds. Default `4 * HOUR_IN_SECONDS`.
|
||||
| FICTIONEER_CARD_CACHE_LIMIT | integer | Number of cards cached by the story card cache feature if enabled. Default `50`.
|
||||
| FICTIONEER_CARD_CACHE_EXPIRATION_TIME | integer | Time until the whole story card cache expires in seconds. Default `HOUR_IN_SECONDS`.
|
||||
| FICTIONEER_CACHE_PURGE_ASSIST | boolean | Whether to call the cache purge assist function on post updates. Default `true`.
|
||||
| FICTIONEER_RELATIONSHIP_PURGE_ASSIST | boolean | Whether to purge related post caches. Default `true`.
|
||||
| FICTIONEER_CHAPTER_LIST_TRANSIENTS | boolean | Whether to cache chapter lists on story pages as Transients. Default `true`.
|
||||
|
@ -288,6 +288,16 @@ if ( ! defined( 'FICTIONEER_PARTIAL_CACHE_EXPIRATION_TIME' ) ) {
|
||||
define( 'FICTIONEER_PARTIAL_CACHE_EXPIRATION_TIME', 4 * HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
// Integer: Maximum number of cards in card cache
|
||||
if ( ! defined( 'FICTIONEER_CARD_CACHE_LIMIT' ) ) {
|
||||
define( 'FICTIONEER_CARD_CACHE_LIMIT', 50 );
|
||||
}
|
||||
|
||||
// Integer: Time until the card cache expires
|
||||
if ( ! defined( 'FICTIONEER_CARD_CACHE_EXPIRATION_TIME' ) ) {
|
||||
define( 'FICTIONEER_CARD_CACHE_EXPIRATION_TIME', HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
/*
|
||||
* Booleans
|
||||
*/
|
||||
|
@ -83,6 +83,16 @@ if ( ! defined( 'FICTIONEER_ENABLE_PARTIAL_CACHING' ) ) {
|
||||
);
|
||||
}
|
||||
|
||||
// Boolean: Partial caching enabled?
|
||||
if ( ! defined( 'FICTIONEER_ENABLE_STORY_CARD_CACHING' ) ) {
|
||||
define(
|
||||
'FICTIONEER_ENABLE_STORY_CARD_CACHING',
|
||||
get_option( 'fictioneer_enable_story_card_caching' ) &&
|
||||
! is_customize_preview() &&
|
||||
! fictioneer_caching_active( 'story_card_caching' )
|
||||
);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// ENABLE SHORTCODE TRANSIENTS?
|
||||
// =============================================================================
|
||||
@ -192,6 +202,11 @@ if ( ! function_exists( 'fictioneer_purge_all_caches' ) ) {
|
||||
|
||||
// Cached HTML partials
|
||||
fictioneer_clear_all_cached_partials();
|
||||
|
||||
// Cached story cards
|
||||
if ( FICTIONEER_ENABLE_STORY_CARD_CACHING ) {
|
||||
fictioneer_purge_story_card_cache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,6 +296,11 @@ if ( ! function_exists( 'fictioneer_purge_post_cache' ) ) {
|
||||
if ( FICTIONEER_ENABLE_PARTIAL_CACHING ) {
|
||||
fictioneer_clear_cached_content( $post_id );
|
||||
}
|
||||
|
||||
// Cached story card
|
||||
if ( FICTIONEER_ENABLE_STORY_CARD_CACHING ) {
|
||||
fictioneer_delete_cached_story_card( $post_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1072,3 +1092,182 @@ if ( FICTIONEER_ENABLE_PARTIAL_CACHING ) {
|
||||
add_action( $hook, 'fictioneer_clear_cached_content' );
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// TRANSIENT CARD CACHE
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Returns the Transient array with all cached story cards
|
||||
*
|
||||
* @since 5.22.1
|
||||
*
|
||||
* @return array Array of cached story cards; empty array if disabled.
|
||||
*/
|
||||
|
||||
function fictioneer_get_story_card_cache() {
|
||||
// Abort if...
|
||||
if ( ! FICTIONEER_ENABLE_STORY_CARD_CACHING ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Initialize global cache variable
|
||||
global $fictioneer_story_card_cache;
|
||||
|
||||
if ( ! $fictioneer_story_card_cache ) {
|
||||
$fictioneer_story_card_cache = get_transient( 'fictioneer_card_cache' ) ?: [];
|
||||
}
|
||||
|
||||
return $fictioneer_story_card_cache;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function fictioneer_set_story_card_cache( $key, $card ) {
|
||||
// Abort if...
|
||||
if ( ! FICTIONEER_ENABLE_STORY_CARD_CACHING ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize global cache variable
|
||||
global $fictioneer_story_card_cache;
|
||||
|
||||
// Setup
|
||||
if ( ! $fictioneer_story_card_cache ) {
|
||||
$fictioneer_story_card_cache = fictioneer_get_story_card_cache();
|
||||
}
|
||||
|
||||
// Remove cached card...
|
||||
unset( $fictioneer_story_card_cache[ $key ] );
|
||||
|
||||
// ... and append at the end
|
||||
$fictioneer_story_card_cache[ $key ] = $card;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function fictioneer_save_story_card_cache() {
|
||||
// Abort if...
|
||||
if ( ! FICTIONEER_ENABLE_STORY_CARD_CACHING ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize global cache variable
|
||||
global $fictioneer_story_card_cache;
|
||||
|
||||
// Anything to save?
|
||||
if ( is_array( $fictioneer_story_card_cache ) ) {
|
||||
set_transient( 'fictioneer_card_cache', $fictioneer_story_card_cache, FICTIONEER_CARD_CACHE_EXPIRATION_TIME );
|
||||
}
|
||||
}
|
||||
add_action( 'shutdown', 'fictioneer_save_story_card_cache' );
|
||||
|
||||
|
||||
|
||||
|
||||
function fictioneer_purge_story_card_cache() {
|
||||
// Abort if...
|
||||
if ( ! FICTIONEER_ENABLE_STORY_CARD_CACHING ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $fictioneer_story_card_cache;
|
||||
|
||||
$fictioneer_story_card_cache = [];
|
||||
|
||||
delete_transient( 'fictioneer_card_cache' );
|
||||
}
|
||||
|
||||
|
||||
|
||||
function fictioneer_delete_cached_story_card( $post_id ) {
|
||||
// Abort if...
|
||||
if ( ! FICTIONEER_ENABLE_STORY_CARD_CACHING ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize global cache variable
|
||||
global $fictioneer_story_card_cache;
|
||||
|
||||
// Setup
|
||||
if ( ! $fictioneer_story_card_cache ) {
|
||||
$fictioneer_story_card_cache = fictioneer_get_story_card_cache();
|
||||
}
|
||||
|
||||
// Find matching keys
|
||||
foreach ( $fictioneer_story_card_cache as $key => $value ) {
|
||||
if ( strpos( $key, $post_id . '_' ) === 0 ) {
|
||||
unset( $fictioneer_story_card_cache[ $key ] );
|
||||
|
||||
// Update comment count in story meta cache (if story)
|
||||
if ( FICTIONEER_ENABLE_STORY_DATA_META_CACHE ) {
|
||||
$story_data = fictioneer_get_story_data( $post_id );
|
||||
|
||||
if ( $story_data ) {
|
||||
$story_data['comment_count'] = fictioneer_get_story_comment_count( $post_id );
|
||||
$story_data['comment_count_timestamp'] = time();
|
||||
|
||||
update_post_meta( $post_id, 'fictioneer_story_data_collection', $story_data );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function fictioneer_delete_cached_story_card_by_comment( $comment_id ) {
|
||||
// Setup
|
||||
$comment = get_comment( $comment_id );
|
||||
|
||||
if ( $comment ) {
|
||||
$story_id = get_post_meta( $comment->comment_post_ID, 'fictioneer_chapter_story', true );
|
||||
|
||||
if ( $story_id ) {
|
||||
fictioneer_delete_cached_story_card( $story_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'wp_insert_comment', 'fictioneer_delete_cached_story_card_by_comment' );
|
||||
add_action( 'delete_comment', 'fictioneer_delete_cached_story_card_by_comment' );
|
||||
|
||||
|
||||
|
||||
function fictioneer_get_cached_story_card( $key ) {
|
||||
// Abort if...
|
||||
if ( ! FICTIONEER_ENABLE_STORY_CARD_CACHING ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Initialize global cache variable
|
||||
global $fictioneer_story_card_cache;
|
||||
|
||||
// Setup
|
||||
if ( ! $fictioneer_story_card_cache ) {
|
||||
$fictioneer_story_card_cache = fictioneer_get_story_card_cache();
|
||||
}
|
||||
|
||||
// Look in currently cached cards...
|
||||
if ( $card = ( $fictioneer_story_card_cache[ $key ] ?? 0 ) ) {
|
||||
// Remove cached card...
|
||||
unset( $fictioneer_story_card_cache[ $key ] );
|
||||
|
||||
// ... and append at the end
|
||||
$fictioneer_story_card_cache[ $key ] = $card;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Limit cache to 50 latest cards
|
||||
if ( count( $fictioneer_story_card_cache ) > FICTIONEER_CARD_CACHE_LIMIT ) {
|
||||
$fictioneer_story_card_cache = array_slice(
|
||||
$fictioneer_story_card_cache,
|
||||
-1 * FICTIONEER_CARD_CACHE_LIMIT,
|
||||
FICTIONEER_CARD_CACHE_LIMIT,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Return cached card
|
||||
return $card;
|
||||
}
|
||||
|
@ -677,6 +677,12 @@ define( 'FICTIONEER_OPTIONS', array(
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'default' => 0
|
||||
),
|
||||
'fictioneer_enable_story_card_caching' => array(
|
||||
'name' => 'fictioneer_enable_story_card_caching',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'default' => 0
|
||||
)
|
||||
),
|
||||
'integers' => array(
|
||||
@ -1141,6 +1147,7 @@ function fictioneer_get_option_label( $option ) {
|
||||
'fictioneer_enable_custom_fields' => __( 'Enable custom fields', 'fictioneer' ),
|
||||
'fictioneer_disable_anti_flicker' => __( 'Disable anti-flicker script', 'fictioneer' ),
|
||||
'fictioneer_hide_categories' => __( 'Hide categories on posts', 'fictioneer' ),
|
||||
'fictioneer_enable_story_card_caching' => __( 'Enable caching of story cards', 'fictioneer' ),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -481,6 +481,9 @@ function fictioneer_purge_theme_caches() {
|
||||
|
||||
fictioneer_clear_all_cached_partials();
|
||||
|
||||
// Cached story cards
|
||||
fictioneer_purge_story_card_cache();
|
||||
|
||||
// Cache busting string
|
||||
fictioneer_regenerate_cache_bust();
|
||||
|
||||
|
@ -734,6 +734,20 @@
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_story_card_caching',
|
||||
__( 'Enable caching of story cards', 'fictioneer' ),
|
||||
sprintf(
|
||||
__( 'Caches the latest %d story cards in the database to speed up loading. Do not use this together with a cache plugin.', 'fictioneer' ),
|
||||
FICTIONEER_CARD_CACHE_LIMIT
|
||||
),
|
||||
__( '<p>Rendering story cards is resource-intensive due to multiple complex queries. The more cards you display at once, the slower the page will load. This feature mitigates the slowdown by caching the HTML of the last rendered cards in the database, which typically results in faster loading times for the most recent stories.</p><p>You can use the <code>FICTIONEER_CARD_CACHE_LIMIT</code> constant to change the number of cached cards (default is 50). Be aware that increasing this number will result in higher RAM consumption.</p>', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,19 @@
|
||||
// No direct access!
|
||||
defined( 'ABSPATH' ) OR exit;
|
||||
|
||||
// Card cache?
|
||||
$card_cache_active = get_option( 'fictioneer_enable_story_card_caching' );
|
||||
|
||||
if ( $card_cache_active ) {
|
||||
$cache_key = $post->ID . '_' . date( 'Y-m-d-H-i-s', strtotime( $post->post_modified_gmt ) ) .
|
||||
'_' . md5( json_encode( $args ) );
|
||||
|
||||
if ( $cache = fictioneer_get_cached_story_card( $cache_key ) ) {
|
||||
echo $cache;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup
|
||||
$post_id = $post->ID;
|
||||
$story = fictioneer_get_story_data( $post_id );
|
||||
@ -72,6 +85,11 @@ $thumbnail_args = array(
|
||||
'class' => 'no-auto-lightbox'
|
||||
);
|
||||
|
||||
// Buffer HTML for cache if active
|
||||
if ( $card_cache_active ) {
|
||||
ob_start();
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<li
|
||||
@ -253,3 +271,17 @@ $thumbnail_args = array(
|
||||
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<?php
|
||||
|
||||
// Capture, store, and output cache if active
|
||||
if ( $card_cache_active ) {
|
||||
// Get buffered HTML
|
||||
$cache = fictioneer_minify_html( ob_get_clean() );
|
||||
|
||||
// Save in cache
|
||||
fictioneer_set_story_card_cache( $cache_key, $cache );
|
||||
|
||||
// Render card
|
||||
echo $cache;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user