[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