Skip to content

Commit

Permalink
Merge branch 'develop' into feature/plugin-check
Browse files Browse the repository at this point in the history
  • Loading branch information
tillkruss authored Oct 15, 2024
2 parents 5b9bcb9 + 0cfdb6d commit 2d870e1
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 107 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ jobs:
strategy:
fail-fast: false
matrix:
php: ['7.2', '7.4', '8.2']
relay: ['0.5.1']
php: ['7.4', '8.2']
relay: ['0.7.0']

steps:
- name: Checkout
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## 2.5.4

- Respect `WP_REDIS_SCHEME` for Cluster connections
- Fixed issue with Predis and `SentinelReplication` connection
- Fixed double-slash in `admin.css` URL

## 2.5.3

- Added `WP_REDIS_DISABLE_GROUP_FLUSH` constant
- Added `redis_cache_manager_capability` filter and `WP_REDIS_MANAGER_CAPABILITY` constant
- Added `WP_REDIS_SSL_CONTEXT` support for PhpRedis cluster connections
- Fixed several issues with Predis and cluster/replicated connection
- Fixed another rare fatal error in `show_error_and_die()`

## 2.5.2

- Respect `WP_REDIS_FLUSH_TIMEOUT` in Lua flush scripts
Expand Down
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,13 @@ The Redis Object Cache plugin comes with vast set of configuration options. If y
| `WP_REDIS_DISABLED` | `false` | Emergency switch to bypass the object cache without deleting the drop-in |
| `WP_REDIS_DISABLE_ADMINBAR` | `false` | Disables admin bar display |
| `WP_REDIS_DISABLE_METRICS` | `false` | Disables metrics collection and display |
| `WP_REDIS_DISABLE_BANNERS` | `false` | Disables promotional banners |
| `WP_REDIS_DISABLE_DROPIN_CHECK` | `false` | Disables the extended drop-in write test |
| `WP_REDIS_DISABLE_DROPIN_AUTOUPDATE` | `false` | Disables the drop-in auto-update |
| `WP_REDIS_DISABLE_GROUP_FLUSH` | `false` | Disables group flushing with Lua script and uses `flushdb` call instead |
| `WP_REDIS_DISABLE_BANNERS` | `false` | Disables promotional banners and notices |
| `WP_REDIS_DISABLE_COMMENT` | `false` | Disables HTML source comment |
| `WP_REDIS_SSL_CONTEXT` | `[]` | TLS connection options for `tls` or `rediss` scheme |
| `WP_REDIS_MANAGER_CAPABILITY` | | The capability a user must have to manage the plugin |

</details>

Expand Down Expand Up @@ -228,11 +231,12 @@ Redis Object Cache has various WP CLI commands, for more information run `wp hel

Redis Object Cache has various hooks and the commonly used ones are listed below.

| Filter / Action | Description |
| --------------------------------------- | ------------------------------------------------- |
| `redis_cache_expiration` | Filters the cache expiration for individual keys |
| `redis_cache_validate_dropin` | Filters whether the drop-in is valid |
| Filter / Action | Description |
| --------------------------------------- | ----------- |
| `redis_cache_expiration` | Filters the cache expiration for individual keys |
| `redis_cache_validate_dropin` | Filters whether the drop-in is valid |
| `redis_cache_add_non_persistent_groups` | Filters the groups to be marked as non persistent |
| `redis_cache_manager_capability` | Filters the capability a user needs to manage the plugin |

## Footnotes

Expand Down
21 changes: 19 additions & 2 deletions includes/class-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,12 @@ public function enqueue_admin_styles() {
return;
}

wp_enqueue_style( 'redis-cache', WP_REDIS_PLUGIN_DIR . '/assets/css/admin.css', [], WP_REDIS_VERSION );
wp_enqueue_style(
'redis-cache',
trailingslashit( WP_REDIS_PLUGIN_DIR ) . 'assets/css/admin.css',
[],
WP_REDIS_VERSION
);
}

/**
Expand Down Expand Up @@ -1565,7 +1570,19 @@ public function obscure_url_secrets( $url ) {
* @return string
*/
public function manage_redis_capability() {
return is_multisite() ? 'manage_network_options' : 'manage_options';
if ( defined( 'WP_REDIS_MANAGER_CAPABILITY' ) && WP_REDIS_MANAGER_CAPABILITY ) {
return WP_REDIS_MANAGER_CAPABILITY;
}

$capability = is_multisite() ? 'manage_network_options' : 'manage_options';

/**
* Filters the capability used to determine if a user can manage Redis.
*
* @since 2.6.0
* @param string $capability The default capability to determine if the user can manage cache.
*/
return apply_filters( 'redis_cache_manager_capability', $capability );
}

/**
Expand Down
46 changes: 31 additions & 15 deletions includes/class-predis.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,10 @@ public function connect( $read_timeout = null ) {
* @return bool
*/
public function flush( $throw_exception = false ) {
$flush_timeout = defined( 'WP_REDIS_FLUSH_TIMEOUT' )
? intval( WP_REDIS_FLUSH_TIMEOUT )
: 5;

if ( is_null( $this->redis ) ) {
$flush_timeout = defined( 'WP_REDIS_FLUSH_TIMEOUT' )
? intval( WP_REDIS_FLUSH_TIMEOUT )
: 5;
try {
$this->connect( $flush_timeout );
} catch ( Exception $exception ) {
Expand All @@ -153,16 +152,16 @@ public function flush( $throw_exception = false ) {

return false;
}
}

if ( is_null( $this->redis ) ) {
return false;
if ( is_null( $this->redis ) ) {
return false;
}
}

if ( defined( 'WP_REDIS_CLUSTER' ) ) {
try {
foreach ( $this->redis->_masters() as $master ) {
$this->redis->flushdb( $master );
foreach ( $this->redis->getIterator() as $master ) {
$master->flushdb();
}
} catch ( Exception $exception ) {
if ( $throw_exception ) {
Expand Down Expand Up @@ -207,13 +206,30 @@ protected function build_cluster_connection_array() {
$cluster = array_values( WP_REDIS_CLUSTER );

foreach ( $cluster as $key => $server ) {
$connection_string = parse_url( $server );
$components = parse_url( $server );

if ( ! empty( $components['scheme'] ) ) {
$scheme = $components['scheme'];
} elseif ( defined( 'WP_REDIS_SCHEME' ) ) {
$scheme = WP_REDIS_SCHEME;
} else {
$scheme = null;
}

$cluster[ $key ] = sprintf(
"%s:%s",
$connection_string['host'],
$connection_string['port']
);
if ( isset( $scheme ) ) {
$cluster[ $key ] = sprintf(
'%s://%s:%d',
$scheme,
$components['host'],
$components['port']
);
} else {
$cluster[ $key ] = sprintf(
'%s:%d',
$components['host'],
$components['port']
);
}
}

return $cluster;
Expand Down
78 changes: 57 additions & 21 deletions includes/object-cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: Redis Object Cache Drop-In
* Plugin URI: https://wordpress.org/plugins/redis-cache/
* Description: A persistent object cache backend powered by Redis. Supports Predis, PhpRedis, Relay, replication, sentinels, clustering and WP-CLI.
* Version: 2.5.2
* Version: 2.5.4
* Author: Till Krüss
* Author URI: https://objectcache.pro
* License: GPLv3
Expand Down Expand Up @@ -690,6 +690,14 @@ protected function connect_using_phpredis( $parameters ) {
$args['password'] = $parameters['password'];
}

if ( version_compare( $version, '5.3.0', '>=' ) && defined( 'WP_REDIS_SSL_CONTEXT' ) && ! empty( WP_REDIS_SSL_CONTEXT ) ) {
if ( ! array_key_exists( 'password', $args ) ) {
$args['password'] = null;
}

$args['ssl'] = WP_REDIS_SSL_CONTEXT;
}

$this->redis = new RedisCluster( null, ...array_values( $args ) );
$this->diagnostics += $args;
}
Expand Down Expand Up @@ -1131,23 +1139,22 @@ protected function connect_using_hhvm( $parameters ) {
* @return void
*/
public function fetch_info() {
$options = method_exists( $this->redis, 'getOptions' )
? $this->redis->getOptions()
: new stdClass();

if ( isset( $options->replication ) && $options->replication ) {
return;
}

if ( defined( 'WP_REDIS_CLUSTER' ) ) {
$connectionId = is_string( WP_REDIS_CLUSTER )
? 'SERVER'
: current( $this->build_cluster_connection_array() );

$info = $this->determine_client() === 'predis'
$info = $this->is_predis()
? $this->redis->getClientBy( 'id', $connectionId )->info()
: $this->redis->info( $connectionId );
} else {
if ( $this->is_predis() ) {
$connection = $this->redis->getConnection();
if ( $connection instanceof Predis\Connection\Replication\ReplicationInterface ) {
$connection->switchToMaster();
}
}

$info = $this->redis->info();
}

Expand Down Expand Up @@ -1604,8 +1611,14 @@ protected function execute_lua_script( $script ) {
$flushTimeout = defined( 'WP_REDIS_FLUSH_TIMEOUT' ) ? WP_REDIS_FLUSH_TIMEOUT : 5;

if ( $this->is_predis() ) {
$timeout = $this->redis->getConnection()->getParameters()->read_write_timeout ?? ini_get( 'default_socket_timeout' );
stream_set_timeout( $this->redis->getConnection()->getResource(), $flushTimeout );
$connection = $this->redis->getConnection();

if ($connection instanceof Predis\Connection\Replication\ReplicationInterface) {
$connection = $connection->getMaster();
}

$timeout = $connection->getParameters()->read_write_timeout ?? ini_get( 'default_socket_timeout' );
stream_set_timeout( $connection->getResource(), $flushTimeout );
} else {
$timeout = $this->redis->getOption( Redis::OPT_READ_TIMEOUT );
$this->redis->setOption( Redis::OPT_READ_TIMEOUT, $flushTimeout );
Expand All @@ -1619,7 +1632,7 @@ protected function execute_lua_script( $script ) {
}

if ( $this->is_predis() ) {
stream_set_timeout( $this->redis->getConnection()->getResource(), $timeout );
stream_set_timeout( $connection->getResource(), $timeout ); // @phpstan-ignore variable.undefined
} else {
$this->redis->setOption( Redis::OPT_READ_TIMEOUT, $timeout );
}
Expand Down Expand Up @@ -1756,6 +1769,10 @@ public function flush() {
* @return bool Returns TRUE on success or FALSE on failure.
*/
public function flush_group( $group ) {
if ( defined( 'WP_REDIS_DISABLE_GROUP_FLUSH' ) && WP_REDIS_DISABLE_GROUP_FLUSH ) {
return $this->flush();
}

$san_group = $this->sanitize_key_part( $group );

if ( is_multisite() && ! $this->is_global_group( $san_group ) ) {
Expand Down Expand Up @@ -1872,7 +1889,7 @@ protected function lua_flush_closure( $salt, $escape = true ) {
return i
LUA;

if ( version_compare( $this->redis_version(), '5', '<' ) && version_compare( $this->redis_version(), '3.2', '>=' ) ) {
if ( isset($this->redis_version) && version_compare( $this->redis_version, '5', '<' ) && version_compare( $this->redis_version, '3.2', '>=' ) ) {
$script = 'redis.replicate_commands()' . "\n" . $script;
}

Expand Down Expand Up @@ -1924,7 +1941,7 @@ function ( $group ) {
until 0 == cur
return i
LUA;
if ( version_compare( $this->redis_version(), '5', '<' ) && version_compare( $this->redis_version(), '3.2', '>=' ) ) {
if ( isset($this->redis_version) && version_compare( $this->redis_version, '5', '<' ) && version_compare( $this->redis_version, '3.2', '>=' ) ) {
$script = 'redis.replicate_commands()' . "\n" . $script;
}

Expand Down Expand Up @@ -2959,6 +2976,8 @@ protected function show_error_and_die( Exception $exception ) {
add_filter( 'pre_determine_locale', function () {
return defined( 'WPLANG' ) ? WPLANG : 'en_US';
} );

add_filter( 'pre_get_language_files_from_path', '__return_empty_array' );
}

// Load custom Redis error template, if present.
Expand Down Expand Up @@ -3013,13 +3032,30 @@ protected function build_cluster_connection_array() {
$cluster = array_values( WP_REDIS_CLUSTER );

foreach ( $cluster as $key => $server ) {
$connection_string = parse_url( $server );
$components = parse_url( $server );

$cluster[ $key ] = sprintf(
"%s:%s",
$connection_string['host'],
$connection_string['port']
);
if ( ! empty( $components['scheme'] ) ) {
$scheme = $components['scheme'];
} elseif ( defined( 'WP_REDIS_SCHEME' ) ) {
$scheme = WP_REDIS_SCHEME;
} else {
$scheme = null;
}

if ( isset( $scheme ) ) {
$cluster[ $key ] = sprintf(
'%s://%s:%d',
$scheme,
$components['host'],
$components['port']
);
} else {
$cluster[ $key ] = sprintf(
'%s:%d',
$components['host'],
$components['port']
);
}
}

return $cluster;
Expand Down
Loading

0 comments on commit 2d870e1

Please sign in to comment.