[wp-trac] [WordPress Trac] #52345: Transient with expiration never expires
WordPress Trac
noreply at wordpress.org
Fri Jan 22 18:09:58 UTC 2021
#52345: Transient with expiration never expires
--------------------------+-----------------------------
Reporter: mennoll | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Cache API | Version: 5.6
Severity: normal | Keywords: needs-patch
Focuses: |
--------------------------+-----------------------------
When storing a transient that has a timeout with the `set_transient()`
function, there is a possibility that storing the transient timeout will
fail. When you then try to get the transient with the `get_transient()`
function, WordPress just returns it, which basically makes it behave like
a transient with no expiration.
You can simulate the behaviour using this code:
{{{#!php
<?php
// First store the transient
$transient_name = 'testname';
$transient_value = 'testvalue';
$transient_expiration = 30;
set_transient( $transient_name, $transient_value, $transient_expiration );
// Now delete the transient timeout, simulating the timeout option save
failed
delete_option( '_transient_timeout_' . $transient_name );
// Now get the transient value
var_dump( get_transient( $transient_name ) ); // Returns 'testvalue'
}}}
To solve this issue, we need to modify the part in the `get_transient()`
function, that checks if a transient is expired.
The new code of the `get_transient()` should become this: (see `// <===
This is the changed line` for what's changed.)
{{{#!php
<?php
function get_transient( $transient ) {
/**
* Filters the value of an existing transient before it is retrieved.
*
* The dynamic portion of the hook name, `$transient`, refers to the
transient name.
*
* Returning a truthy value from the filter will effectively short-
circuit retrieval
* and return the passed value instead.
*
* @since 2.8.0
* @since 4.4.0 The `$transient` parameter was added
*
* @param mixed $pre_transient The default value to return if the
transient does not exist.
* Any value other than false will short-
circuit the retrieval
* of the transient, and return that
value.
* @param string $transient Transient name.
*/
$pre = apply_filters( "pre_transient_{$transient}", false, $transient
);
if ( false !== $pre ) {
return $pre;
}
if ( wp_using_ext_object_cache() ) {
$value = wp_cache_get( $transient, 'transient' );
} else {
$transient_option = '_transient_' . $transient;
if ( ! wp_installing() ) {
// If option is not in alloptions, it is not autoloaded and
thus has a timeout.
$alloptions = wp_load_alloptions();
if ( ! isset( $alloptions[ $transient_option ] ) ) {
$transient_timeout = '_transient_timeout_' . $transient;
$timeout = get_option( $transient_timeout );
if ( false === $timeout || ( false !== $timeout &&
$timeout < time() ) ) { // <=== This is the changed line
delete_option( $transient_option );
delete_option( $transient_timeout );
$value = false;
}
}
}
if ( ! isset( $value ) ) {
$value = get_option( $transient_option );
}
}
/**
* Filters an existing transient's value.
*
* The dynamic portion of the hook name, `$transient`, refers to the
transient name.
*
* @since 2.8.0
* @since 4.4.0 The `$transient` parameter was added
*
* @param mixed $value Value of transient.
* @param string $transient Transient name.
*/
return apply_filters( "transient_{$transient}", $value, $transient );
}
}}}
--
Ticket URL: <https://core.trac.wordpress.org/ticket/52345>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list