Skip to content

Instantly share code, notes, and snippets.

@AubreyHewes
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AubreyHewes/bd1f978d2bf7ba2bfa05 to your computer and use it in GitHub Desktop.
Save AubreyHewes/bd1f978d2bf7ba2bfa05 to your computer and use it in GitHub Desktop.
Wordpress Redis plugin (dokku/dokku-alt redis plugin spec compatible)
<?php
/*
* Plugin Name: WP_Redis
* Description: Exposes Redis to Wordpress as WP_Redis class. Requires ENV variable REDIS_URL (i.e. redis://localhost:port; dokku / dokku-alt compatible )
* Author: Aubrey Hewes<aubrey@hewes.org.uk>
* Version: 1.0
* License: MIT
*/
/**
* Class WP_Redis
*
* Simple Redis wrapper uses requested theme/plugin name as extra prefix on "wp_".
*
* The extra prefixing is only due to usage within a non-containerised environment/development environment; so the
* value is not possibly broken by other apps.
*
* i.e. "wp_[theme]key"
* i.e. "wp_[plugin]key"
*
* @todo hash the prefix based on runtime environment (host); makes sure non-containerised envs can not influence each other.
*
*/
class WP_Redis {
/**
* @var Redis
*/
private $instance;
/**
* @var string
*/
private $prefix;
/**
* Create a WordPress Redis Manager
*
* @param string $host
* @param int $port defaults to 6379
* @param int $timeout defaults to 0
* @param string $prefix defaults to 'wp_'
*
* @throws \Exception If the Redis module is not available
*/
public function __construct($host, $port = 6379, $timeout = 0, $prefix = 'wp_') {
$this->prefix = $prefix;
if (!class_exists('Redis')) {
throw new \Exception('Redis module is not available'); // @todo trigger_error / wp error
}
try {
$this->instance = new Redis();
$this->instance->connect($host, $port, $timeout);
} catch (\Exception $ex) {
// log_error
// dev: trigger_error
$this->instance = null;
}
}
/**
* Returns a cache key localised to site/theme/plugin
*
* @TODO test for plugin usage and use plugin as prefix
*
* @return string
*/
private function getKey($key) {
$prefix = $this->prefix;
/* @var WP_Theme $theme */
$theme = wp_get_theme();
if (!empty($theme->template)) {
$prefix .= $theme->template;
}
return $prefix.$key;
}
/**
* If Redis is unavailable will return false else the result of the Redis get call (false/mixed)
*
* @param string $key
*
* @return bool|mixed
*/
public function get($key) {
if ($this->instance === null) {
return false;
}
return $this->instance->get($this->getKey($key));
}
/**
* Set a Redis key/value.
*
* If Redis is unavailable will return false else the result of the Redis set (true/false)
*
* @param string $key
* @param mixed $value
*
* @return bool
*/
public function set($key, $value) {
if ($this->instance === null) {
return false;
}
return $this->instance->set($this->getKey($key), $value);
}
/**
* Deletes a Redis key/value
*
* @param string $key
*/
public function delete($key) {
/*return */$this->instance->delete($this->getKey($key));
}
}
/**
* Initialises Redis using the environment variable REDIS_URL (dokku / dokku-alt compatible).
*
* REDIS_URL is in the format <code>redis://host:port[/prefix]</code> you can set this in wp-config.php
*
* If environment variable REDIS_URL is empty then Redis is not available.
*/
function redis_init() {
global $redis;
$REDIS_URL = getenv('REDIS_URL'); // dokku/dokku-alt spec
if (empty($REDIS_URL)) { // not via dokku/dokku-alt or app not setup for spec
return;
}
$REDIS_URL = parse_url($REDIS_URL); // parse the url parts
if (empty($REDIS_URL)) { // url is malformed; http://php.net/manual/en/function.parse-url.php
return;
}
// create wp redis wrapper using optional default port
$redis = new WP_Redis($REDIS_URL['host'], !empty($REDIS_URL['port']) ? $REDIS_URL['port'] : 6379);
}
/**
* Set a Redis key/value.
*
* If Redis is unavailable will return false else the result of the Redis set (true/false)
*
* @note Global method for bc/seu usage
*
* @param string $key
* @param mixed $value
*
* @return bool If Redis is unavailable will return false else the result of the Redis set call (true/false)
*/
function redis_set($key, $value) {
global $redis;
return $redis->set($key, $value);
}
/**
* Get a Redis value by key.
*
* @note Global method for bc/seu usage
*
* @param string $key
*
* @return bool|mixed If Redis is unavailable will return false else the result of the Redis get call (false/mixed)
*/
function redis_get($key) {
global $redis;
return $redis->get($key);
}
/**
* Delete a Redis value by key
*
* @param string $key
*
* @return bool If Redis is unavailable will return false else the result of the Redis unset call (true/false)
*/
function redis_del($key) {
global $redis;
/*return */$redis->delete($key);
}
// HOOK IT UP TO WORDPRESS
add_action( 'init', 'redis_init' );
// available within wordpress:
// - redis_set(key, value)
// - redis_get(key)
// - redis_del(key)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment