Skip to content
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

PRESS10-42 Fix/transients filters #109

Merged
merged 11 commits into from
Dec 5, 2024
59 changes: 53 additions & 6 deletions includes/Helpers/Transient.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,32 @@ public static function get( string $key ) {
}

/**
* @var array{value:mixed, expires_at:int} $data The saved value and the Unix time it expires at.
* Implement the filters as used in {@see get_transient()}.
*/
$pre = apply_filters( "pre_transient_{$key}", false, $key );
if ( false !== $pre ) {
return $pre;
}

/**
* The saved value and the Unix time it expires at.
*
* @var array{value:mixed, expires_at:int} $data
*/
$data = \get_option( $key );
if ( is_array( $data ) && isset( $data['expires_at'], $data['value'] ) ) {
if ( $data['expires_at'] > time() ) {
return $data['value'];
$value = $data['value'];
} else {
\delete_option( $key );
$value = false;
}
}

return false;
/**
* Implement the filters as used in {@see get_transient()}.
*/
return apply_filters( "transient_{$key}", $value, $key );
}

/**
Expand All @@ -65,11 +79,25 @@ public static function set( string $key, $value, int $expires_in = 3600 ): bool
return \set_transient( $key, $value, $expires_in );
}

/**
* Implement the filters as used in {@see set_transient()}.
*/
$value = apply_filters( "pre_set_transient_{$key}", $value, $expires_in, $key );
$expires_in = apply_filters( "expiration_of_transient_{$key}", $expires_in, $value, $key );

$data = array(
'value' => $value,
'expires_at' => $expires_in + time(),
);
return \update_option( $key, $data, false );

$result = \update_option( $key, $data, false );

if ( $result ) {
do_action( "set_transient_{$key}", $value, $expires_in, $key );
do_action( 'setted_transient', $key, $value, $expires_in );
}

return $result;
}

/**
Expand All @@ -86,7 +114,26 @@ public static function delete( $key ): bool {
return \delete_transient( $key );
}

return \delete_option( $key );
/**
* Implement the filters as used in {@see set_transient()}.
*
* @param string $key Transient name.
*/
do_action( "delete_transient_{$key}", $key );

$result = \delete_option( $key );

if ( $result ) {

/**
* Implement the filters as used in {@see set_transient()}.
*
* @param string $transient Deleted transient name.
*/
do_action( 'deleted_transient', $key );
}

return $result;
}

/**
Expand All @@ -100,7 +147,7 @@ public static function delete( $key ): bool {
*/
public function __call( $name, $arguments ) {
if ( ! method_exists( __CLASS__, $name ) ) {
throw new \BadMethodCallException( "Method $name does not exist" );
throw new \BadMethodCallException( 'Method ' . esc_html( $name ) . ' does not exist' );
}
return self::$name( ...$arguments );
}
Expand Down
7 changes: 0 additions & 7 deletions tests/phpunit/bootstrap.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
<?php

/**
* I was having trouble with {@see WP_Mock::expectAction()} so mocked it here. Because we're using PHP 7.1, we're
* not on the latest version of WP_Mock, which requires 7.4.
*/
function do_action(...$args) {}
function apply_filters(...$args) { return $args[1]; }

/**
* Resets mocks between each test case so the mocks in one do not unintentionally help pass another test.
*/
Expand Down
117 changes: 111 additions & 6 deletions tests/phpunit/includes/Helpers/TransientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace NewfoldLabs\WP\Module\Helpers;

use NewfoldLabs\WP\Module\Data\Helpers\Transient;
use WP_Mock;
use WP_Mock\Tools\TestCase;

/**
Expand Down Expand Up @@ -72,6 +73,20 @@ public function test_set_transient_use_options(): void {
\WP_Mock::userFunction( 'set_transient' )
->never();

WP_Mock::expectFilter(
"pre_set_transient_{$test_transient_name}",
'value',
999,
$test_transient_name
);

WP_Mock::expectFilter(
"expiration_of_transient_{$test_transient_name}",
999,
'value',
$test_transient_name,
);

\WP_Mock::userFunction( 'update_option' )
->once()
->with(
Expand All @@ -81,6 +96,20 @@ public function test_set_transient_use_options(): void {
)
->andReturnTrue();

WP_Mock::expectAction(
"set_transient_{$test_transient_name}",
'value',
999,
$test_transient_name
);

WP_Mock::expectAction(
'setted_transient',
$test_transient_name,
'value',
999
);

Transient::set( $test_transient_name, 'value', 999 );

$this->assertConditionsMet();
Expand Down Expand Up @@ -124,6 +153,12 @@ public function test_get_transient_use_options(): void {
\WP_Mock::userFunction( 'get_transient' )
->never();

WP_Mock::expectFilter(
"pre_transient_{$test_transient_name}",
false,
$test_transient_name
);

\WP_Mock::userFunction( 'get_option' )
->once()
->with( $test_transient_name, )
Expand All @@ -134,6 +169,12 @@ public function test_get_transient_use_options(): void {
)
);

WP_Mock::expectFilter(
"transient_{$test_transient_name}",
'value',
$test_transient_name
);

$result = Transient::get( $test_transient_name );

$this->assertEquals( 'value', $result );
Expand All @@ -153,6 +194,12 @@ public function test_get_transient_use_options_expired(): void {
\WP_Mock::userFunction( 'get_transient' )
->never();

WP_Mock::expectFilter(
"pre_transient_{$test_transient_name}",
false,
$test_transient_name
);

\WP_Mock::userFunction( 'get_option' )
->once()
->with( $test_transient_name, )
Expand All @@ -168,6 +215,12 @@ public function test_get_transient_use_options_expired(): void {
->with( $test_transient_name )
->andReturnTrue();

WP_Mock::expectFilter(
"transient_{$test_transient_name}",
false,
$test_transient_name
);

$result = Transient::get( $test_transient_name );

$this->assertFalse( $result );
Expand Down Expand Up @@ -205,22 +258,74 @@ public function test_should_use_transients_bluehost_cloud(): void {
$test_transient_name = uniqid( __FUNCTION__ );

\WP_Mock::userFunction( 'get_dropins' )
->once()
->andReturn( array( 'object-cache.php' => array() ) );
->once()
->andReturn( array( 'object-cache.php' => array() ) );

\WP_Mock::userFunction( 'set_transient' )
->once()
->with( $test_transient_name, 'value', 999 )
->andReturnTrue();
->once()
->with( $test_transient_name, 'value', 999 )
->andReturnTrue();

\WP_Mock::userFunction( 'update_option' )
->never();
->never();

\NewfoldLabs\WP\Context\setContext( 'platform', 'atomic' );

Transient::set( $test_transient_name, 'value', 999 );

$this->assertConditionsMet();
}

/**
* {@see \WP_Mock\Functions::$wp_mocked_fuctions} array is not being reset between tests. The code seems to
* have been refactored in WP_Mock's newer versions but we are stuck using PHP 7.3 for now.
*
* @runInSeparateProcess
*
* @covers ::set
*/
public function test_set_transient_filters_are_called(): void {

$test_transient_name = uniqid( __FUNCTION__ );

WP_Mock::userFunction( 'get_dropins' )
->once()
->andReturn( array( 'object-cache.php' => array() ) );

WP_Mock::expectFilter(
"pre_set_transient_{$test_transient_name}",
'value',
999,
$test_transient_name
);

WP_Mock::expectFilter(
"expiration_of_transient_{$test_transient_name}",
999,
'value',
$test_transient_name,
);

\WP_Mock::userFunction( 'update_option' )
->once()
->andReturn( true );

WP_Mock::expectAction(
"set_transient_{$test_transient_name}",
'value',
999,
$test_transient_name
);

WP_Mock::expectAction(
'setted_transient',
$test_transient_name,
'value',
999
);

Transient::set( $test_transient_name, 'value', 999 );

$this->assertConditionsMet();
}
}
Loading
Loading