From fbb2e1dc89ebf31089e34c79c38b700d8f051096 Mon Sep 17 00:00:00 2001 From: Andrew Nacin Date: Tue, 25 Mar 2014 18:22:49 +0000 Subject: [PATCH] Transients: Allow a non-expiring transient to be updated with an expiry. props shahpranaf, sandyr. fixes #22807. git-svn-id: https://develop.svn.wordpress.org/trunk@27719 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/option.php | 19 +++++++++-- tests/phpunit/tests/option/transient.php | 43 ++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/option.php b/src/wp-includes/option.php index e1ad731d70..0091c128c8 100644 --- a/src/wp-includes/option.php +++ b/src/wp-includes/option.php @@ -642,9 +642,22 @@ function set_transient( $transient, $value, $expiration = 0 ) { } $result = add_option( $transient, $value, '', $autoload ); } else { - if ( $expiration ) - update_option( $transient_timeout, time() + $expiration ); - $result = update_option( $transient, $value ); + // If expiration is requested, but the transient has no timeout option, + // delete, then re-create transient rather than update. + $update = true; + if ( $expiration ) { + if ( false === get_option( $transient_timeout ) ) { + delete_option( $transient ); + add_option( $transient_timeout, time() + $expiration, '', 'no' ); + $result = add_option( $transient, $value, '', 'no' ); + $update = false; + } else { + update_option( $transient_timeout, time() + $expiration ); + } + } + if ( $update ) { + $result = update_option( $transient, $value ); + } } } diff --git a/tests/phpunit/tests/option/transient.php b/tests/phpunit/tests/option/transient.php index 1d9c64fb6d..a8fe07fe6e 100644 --- a/tests/phpunit/tests/option/transient.php +++ b/tests/phpunit/tests/option/transient.php @@ -33,4 +33,47 @@ class Tests_Option_Transient extends WP_UnitTestCase { $this->assertEquals( $value, get_transient( $key ) ); $this->assertTrue( delete_transient( $key ) ); } + + /** + * @ticket 22807 + */ + function test_transient_data_with_timeout() { + $key = rand_str(); + $value = rand_str(); + $value2 = rand_str(); + + $this->assertFalse( get_option( '_transient_timeout_' . $key ) ); + $now = time(); + + $this->assertTrue( set_transient( $key, $value, 100 ) ); + + // Ensure the transient timeout is set for 100-101 seconds in the future. + $this->assertGreaterThanOrEqual( $now + 100, get_option( '_transient_timeout_' . $key ) ); + $this->assertLessThanOrEqual( $now + 101, get_option( '_transient_timeout_' . $key ) ); + + // Update the timeout to a second in the past and watch the transient be invalidated. + update_option( '_transient_timeout_' . $key, $now - 1 ); + $this->assertFalse( get_transient( $key ) ); + } + + /** + * @ticket 22807 + */ + function test_transient_add_timeout() { + $key = rand_str(); + $value = rand_str(); + $value2 = rand_str(); + $this->assertTrue( set_transient( $key, $value ) ); + $this->assertEquals( $value, get_transient( $key ) ); + + $this->assertFalse( get_option( '_transient_timeout_' . $key ) ); + + $now = time(); + // Add timeout to existing timeout-less transient. + $this->assertTrue( set_transient( $key, $value2, 1 ) ); + $this->assertGreaterThanOrEqual( $now, get_option( '_transient_timeout_' . $key ) ); + + update_option( '_transient_timeout_' . $key, $now - 1 ); + $this->assertFalse( get_transient( $key ) ); + } }