The object cache is not connected to Redis.
',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_connection',
];
}
return [
'label' => 'Object cache is connected to Redis',
'description' => 'The object cache is connected to Redis.
',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'blue'],
'status' => 'good',
'test' => 'objectcache_connection',
];
}
/**
* Test whether Redis uses the noeviction policy.
*
* @param \RedisCachePro\Diagnostics\Diagnostics $diagnostics
* @return array
*/
protected function healthTestEvictionPolicy(Diagnostics $diagnostics)
{
$policy = $diagnostics->maxMemoryPolicy();
if ($policy !== 'noeviction') {
return [
'label' => "Redis uses the {$policy} policy",
'description' => "Redis is configured to use the {$policy} policy.",
'badge' => ['label' => 'Object Cache Pro', 'color' => 'blue'],
'status' => 'good',
'test' => 'objectcache_eviction_policy',
];
}
return [
'label' => 'Redis uses the noeviction policy',
'description' => sprintf(
'%s
',
implode(' ', [
'Redis is configured to use the noeviction policy, which might crash your site when Redis runs out of memory.',
'Setting a reasonable MaxTTL (maximum time-to-live) helps to reduce that risk.',
])
),
'badge' => ['label' => 'Object Cache Pro', 'color' => 'orange'],
'status' => 'recommended',
'test' => 'objectcache_eviction_policy',
'actions' => sprintf(
'%s
',
'https://objectcache.pro/docs/diagnostics/#eviction-policy',
'Learn more about the eviction policy.'
),
];
}
/**
* Test whether Redis supports Relay and asynchronous commands.
*
* @param \RedisCachePro\Diagnostics\Diagnostics $diagnostics
* @return array
*/
protected function healthTestRedisVersion(Diagnostics $diagnostics)
{
$redisVersion = (string) $diagnostics->redisVersion()->value;
if ($diagnostics->usingRelayCache() && version_compare($redisVersion, '6.2.7', '<')) {
return [
'label' => 'Relay requires 6.2.7 or newer',
'description' => sprintf(
'%s
',
implode(' ', [
"Object Cache Pro is using Relay, but the connected Redis Server ({$redisVersion}) is too old and the object cache may go stale.",
'Upgrade Redis to version 6.2.7 or newer.',
])
),
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_redis_version',
];
}
if ($this->config->async_flush && version_compare($redisVersion, '4.0', '<')) {
return [
'label' => 'Redis does not support asynchronous commands',
'description' => sprintf(
'%s
',
implode(' ', [
'Object Cache Pro is configured to use asynchronous commands,',
"but the connected Redis Server ({$redisVersion}) is too old and does not support them.",
'Upgrade Redis to version 4.0 or newer, or disable asynchronous flushing.',
])
),
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_redis_version',
'actions' => sprintf(
'%s
',
'https://objectcache.pro/docs/configuration-options/#asynchronous-flushing',
'Learn more.'
),
];
}
return [
'label' => 'Redis version supported',
'description' => 'The Redis Server version is supported.
',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'blue'],
'status' => 'good',
'test' => 'objectcache_redis_version',
];
}
/**
* Test whether the configuration is optimized for Relay.
* This check only runs when Relay is set as the client.
*
* @return array
*/
protected function healthTestRelayConfig()
{
$results = [
'label' => 'Configuration is not optimized for Relay',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'orange'],
'status' => 'recommended',
'test' => 'objectcache_relay_config',
'actions' => sprintf(
'%s
',
'https://objectcache.pro/docs/relay/',
'Learn more about using Relay.'
),
];
$config = $this->config();
$db = $config->database;
if ($config->shared === null) {
return $results + [
'description' => sprintf(
'
%s
',
'When using Relay, it’s strongly recommended to set the shared configuration option to indicate whether the Redis is used by multiple apps, or not.'
),
];
}
if ($config->shared && ! preg_match("/^db{$db}:?$/", $config->prefix ?? '')) {
return $results + [
'description' => sprintf(
'%s
',
sprintf(
'When using Relay in shared Redis environments, it’s strongly recommended to include the database index in the prefix configuration option to avoid unnecessary flushing. Consider setting the prefix to: %s',
"db{$db}:"
)
),
];
}
if ($config->prefetch) {
return $results + [
'description' => sprintf(
'%s
',
'When using Relay, it’s strongly recommended to disable the prefetch configuration option, it may slowed down Relay.'
),
];
}
if (! $config->split_alloptions) {
return $results + [
'description' => sprintf(
'%s
',
'When using Relay, it’s strongly recommended to enable the split_alloptions configuration option to avoid unnecessary writes.'
),
];
}
if ($config->compression === Configuration::COMPRESSION_NONE) {
return $results + [
'description' => sprintf(
'%s
',
'When using Relay, it’s strongly recommended to use any of the compression configuration options to reduce memory usage.'
),
];
}
if ($config->serializer === Configuration::SERIALIZER_PHP) {
return $results + [
'description' => sprintf(
'%s
',
'When using Relay, it’s strongly recommended to use the igbinary as the serializer configuration options. This will greatly reduce memory usage.'
),
];
}
return array_merge($results, [
'label' => 'Configuration is optimized for Relay',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'blue'],
'status' => 'good',
'description' => sprintf(
'%s
',
'The Object Cache Pro configuration is optimized for Relay.'
),
]);
}
/**
* Callback for `wp_ajax_health-check-objectcache-license` hook.
*
* @return void
*/
public function healthTestLicense()
{
check_ajax_referer('health-check-site-status');
add_filter('http_request_timeout', function () {
return 15;
});
if (! $this->token()) {
wp_send_json_success([
'label' => 'No license token set',
'description' => 'No Object Cache Pro license token was set and plugin updates are disabled.
',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_license',
'actions' => sprintf(
'%s
',
'https://objectcache.pro/docs/configuration-options/#token',
'Learn more about setting the license token.'
),
]);
}
$storedLicense = License::load();
if ($storedLicense instanceof License && $storedLicense->isValid()) {
$license = $this->license();
} else {
$response = $this->fetchLicense();
if (is_wp_error($response)) {
$license = License::fromError($response);
} else {
$license = License::fromResponse($response);
}
}
if ($license->isValid()) {
wp_send_json_success([
'label' => 'License token is set and license is valid',
'description' => 'The Object Cache Pro license token is set and the license is valid.
',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'blue'],
'status' => 'good',
'test' => 'objectcache_license',
]);
}
if (! $license->state()) {
wp_send_json_success([
'label' => 'Unable to verify license token',
'description' => sprintf(
'The license token ••••••••%s could not be verified.
',
substr($license->token(), -4)
),
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_license',
]);
}
$this->disableDropin();
if ($license->isInvalid()) {
wp_send_json_success([
'label' => 'Invalid license token',
'description' => sprintf(
'The license token ••••••••%s appears to be invalid.
',
substr($license->token(), -4)
),
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_license',
]);
}
wp_send_json_success([
'label' => "License is {$license->state()}",
'description' => "Your Object Cache Pro license is {$license->state()}.
",
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_license',
'actions' => implode('', [
sprintf(
'%s
',
'https://objectcache.pro/account',
'Manage your billing information'
),
sprintf(
'
%s
',
'https://objectcache.pro/support',
'Contact customer service'
),
]),
]);
}
/**
* Callback for `wp_ajax_health-check-objectcache-api` hook.
*
* @return void
*/
public function healthTestApi()
{
check_ajax_referer('health-check-site-status');
$response = $this->request('test');
if (is_wp_error($response) && strpos((string) $response->get_error_code(), 'objectcache_', 0) === false) {
wp_send_json_success([
'label' => 'Licensing API is unreachable',
'description' => sprintf(
'
WordPress is unable to communicate with Object Cache Pro’s licensing API.
%s
',
esc_html($response->get_error_message())
),
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_api',
'actions' => sprintf(
'%s
',
'https://status.objectcache.pro',
'Visit status page'
),
]);
}
$url = static::normalizeUrl(home_url());
if (! is_string($url)) {
$url = json_encode($url, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
wp_send_json_success([
'label' => 'Unable to determine site URL',
'description' => sprintf(
'
WordPress is able to communicate with Object Cache Pro’s licensing API, but the plugin is unable to determine the site URL: %s
',
esc_html(trim((string) $url, '"'))
),
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_api',
]);
}
if (isset($response->url->valid, $response->url->value) && ! $response->url->valid) {
wp_send_json_success([
'label' => 'Unable to validate site URL',
'description' => sprintf(
'WordPress is able to communicate with Object Cache Pro’s licensing API, but the plugin is unable to validate the site URL: %s
',
esc_html($response->url->value)
),
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_api',
]);
}
wp_send_json_success([
'label' => 'Licensing API is reachable',
'description' => 'The Object Cache Pro licensing API is reachable.
',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'blue'],
'status' => 'good',
'test' => 'objectcache_api',
'actions' => sprintf(
'%s
',
'https://status.objectcache.pro',
'Visit status page'
),
]);
}
/**
* Callback for `wp_ajax_health-check-objectcache-analytics` hook.
*
* @return array|void
*/
public function healthTestAnalytics()
{
if (wp_doing_ajax()) {
check_ajax_referer('health-check-site-status');
}
$results = [
'label' => 'Object cache analytics are enabled',
'description' => 'Object Cache Pro’ experimental cache analytics are enabled and accessible via WP CLI.
',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'blue'],
'status' => 'good',
'test' => 'objectcache_analytics',
];
if (! $this->analyticsEnabled()) {
$results = [
'label' => 'Object cache analytics are disabled',
'description' => 'Object Cache Pro’ experimental cache analytics are disabled.
',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'blue'],
'status' => 'good',
'test' => 'objectcache_analytics',
];
}
$this->healthDebugInfo();
if (wp_doing_ajax()) {
wp_send_json_success($results);
}
return $results;
}
/**
* Callback for `wp_ajax_health-check-objectcache-filesystem` hook.
*
* @return void
*/
public function healthTestFilesystem()
{
check_ajax_referer('health-check-site-status');
$fs = $this->diagnostics()->filesystemAccess();
if (is_wp_error($fs)) {
wp_send_json_success([
'label' => 'Unable to manage object cache drop-in',
'description' => sprintf(
'Object Cache Pro is unable to access the local filesystem and cannot manage the object cache drop-in.
%s
',
esc_html($fs->get_error_message())
),
'badge' => ['label' => 'Object Cache Pro', 'color' => 'red'],
'status' => 'critical',
'test' => 'objectcache_filesystem',
]);
}
wp_send_json_success([
'label' => 'Object cache drop-in can be managed',
'description' => 'Object Cache Pro can access the local filesystem and is able manage the object cache drop-in.
',
'badge' => ['label' => 'Object Cache Pro', 'color' => 'blue'],
'status' => 'good',
'test' => 'objectcache_filesystem',
]);
}
}