index-wp-redis.php 8.6 KB
Newer Older
Benjamin Adams's avatar
Benjamin Adams committed
1
<?php
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/**
 * WP REDIS CACHE
 */

/**
 * GLOBAL CONFIGURATION
 */
$GLOBALS['wp_redis_cache_config'] = array(
	'debug'         => false,
	'cache'         => true,
	'server_ip'     => '127.0.0.1',
	'redis_server'  => '127.0.0.1',
	'redis_port'    => 6379,
	'redis_db'      => 0,
	'secret_string' => 'changeme',
);

19 20 21
// Uncomment either option below to fix the values here and disable the admin UI
// $GLOBALS['wp_redis_cache_config']['cache_duration'] = 43200;
// $GLOBALS['wp_redis_cache_config']['unlimited']      = false;
22

23 24 25 26 27
// Modify this function to introduce custom handling when exceptions occur
function wp_redis_cache_exception_handler( $exception ) {
	return;
}

28
/**
29 30
 * END GLOBAL CONFIGURATION
 *
31 32
 * DO NOT EDIT BELOW THIS LINE!
 */
Erick Hitter's avatar
Erick Hitter committed
33
$GLOBALS['wp_redis_cache_config']['current_url'] = wp_redis_cache_get_clean_url( $GLOBALS['wp_redis_cache_config']['secret_string'] );
34
$GLOBALS['wp_redis_cache_config']['redis_key']   = md5( $GLOBALS['wp_redis_cache_config']['current_url'] );
Benjamin Adams's avatar
Benjamin Adams committed
35

Ulrich Block's avatar
Ulrich Block committed
36 37 38
// Start the timer so we can track the page load time
$start = microtime();

39 40 41 42 43 44 45 46 47
/**
 * UTILITY FUNCTIONS
 */

/**
 * Compute microtime from a timestamp
 *
 * @return float
 */
Erick Hitter's avatar
Erick Hitter committed
48
function wp_redis_cache_get_micro_time( $time ) {
Erick Hitter's avatar
Erick Hitter committed
49 50
	list( $usec, $sec ) = explode( " ", $time );
	return ( (float) $usec + (float) $sec );
Ulrich Block's avatar
Ulrich Block committed
51 52
}

53 54 55 56 57
/**
 * Is the current request a refresh request with the correct secret key?
 *
 * @return bool
 */
Erick Hitter's avatar
Erick Hitter committed
58
function wp_redis_cache_refresh_has_secret( $secret ) {
Erick Hitter's avatar
Erick Hitter committed
59
	return isset( $_GET['refresh'] ) && $secret == $_GET['refresh'];
Benjamin Adams's avatar
merged  
Benjamin Adams committed
60
}
Ulrich Block's avatar
Ulrich Block committed
61

62 63 64 65 66
/**
 * Does current request include a refresh request?
 *
 * @return bool
 */
Erick Hitter's avatar
Erick Hitter committed
67
function wp_redis_cache_request_has_secret( $secret ) {
Erick Hitter's avatar
Erick Hitter committed
68
	return false !== strpos( $_SERVER['REQUEST_URI'], "refresh=${secret}" );
Benjamin Adams's avatar
merged  
Benjamin Adams committed
69
}
Hendrik Klemp's avatar
Hendrik Klemp committed
70

71 72 73 74 75
/**
 * Determine if request is from a server other than the one running this code
 *
 * @return bool
 */
Erick Hitter's avatar
Erick Hitter committed
76
function wp_redis_cache_is_remote_page_load( $current_url, $server_ip ) {
Erick Hitter's avatar
Erick Hitter committed
77
	return ( isset( $_SERVER['HTTP_REFERER'] )
78
			&& $_SERVER['HTTP_REFERER'] == $current_url
Erick Hitter's avatar
Erick Hitter committed
79
			&& $_SERVER['REQUEST_URI'] != '/'
80
			&& $_SERVER['REMOTE_ADDR'] != $server_ip );
Benjamin Adams's avatar
merged  
Benjamin Adams committed
81
}
Hendrik Klemp's avatar
Hendrik Klemp committed
82

83 84 85 86 87
/**
 * Set proper IP address for proxied requests
 *
 * @return null
 */
Erick Hitter's avatar
Erick Hitter committed
88
function wp_redis_cache_handle_cdn_remote_addressing() {
Erick Hitter's avatar
Erick Hitter committed
89
	// so we don't confuse the cloudflare server
Erick Hitter's avatar
Erick Hitter committed
90
	if ( isset( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
Erick Hitter's avatar
Erick Hitter committed
91 92
		$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
	}
Benjamin Adams's avatar
merged  
Benjamin Adams committed
93
}
94

95 96 97 98 99 100 101 102
/**
 * Prepare a URL for use as a cache key
 *
 * Strips secret key from URL
 *
 * @param string
 * @return string
 */
Erick Hitter's avatar
Erick Hitter committed
103
function wp_redis_cache_get_clean_url( $secret ) {
104
	$replace_keys = array( "?refresh=${secret}","&refresh=${secret}" );
105 106
	$url          = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
	return str_replace( $replace_keys, '', $url );
Benjamin Adams's avatar
Benjamin Adams committed
107
}
Benjamin Adams's avatar
merged  
Benjamin Adams committed
108

109 110 111 112 113
/**
 * BEGIN CACHING LOGIC
 */

// Set proper IP for proxied requests
Erick Hitter's avatar
Erick Hitter committed
114
wp_redis_cache_handle_cdn_remote_addressing();
Hendrik Klemp's avatar
Hendrik Klemp committed
115

116
// Ensure WP uses a theme (this is normally set in index.php)
Erick Hitter's avatar
Erick Hitter committed
117 118
if ( ! defined( 'WP_USE_THEMES' ) ) {
	define( 'WP_USE_THEMES', true );
Vasili Pascal's avatar
Vasili Pascal committed
119
}
Benjamin Adams's avatar
Benjamin Adams committed
120

Ulrich Block's avatar
Ulrich Block committed
121
try {
Erick Hitter's avatar
Erick Hitter committed
122
	// check if PECL Extension is available
Erick Hitter's avatar
Erick Hitter committed
123
	if ( class_exists( 'Redis' ) ) {
124
		if ( $GLOBALS['wp_redis_cache_config']['debug'] ) {
Erick Hitter's avatar
Erick Hitter committed
125 126
			echo "<!-- Redis PECL module found -->\n";
		}
Erick Hitter's avatar
Erick Hitter committed
127

Erick Hitter's avatar
Erick Hitter committed
128 129 130
		$redis = new Redis();

		// Sockets can be used as well. Documentation @ https://github.com/nicolasff/phpredis/#connection
131 132
		$redis->connect( $GLOBALS['wp_redis_cache_config']['redis_server'], $GLOBALS['wp_redis_cache_config']['redis_port'] );
		$redis->select( $GLOBALS['wp_redis_cache_config']['redis_db'] );
Erick Hitter's avatar
Erick Hitter committed
133
	} else { // Fallback to predis5.2.php
134
		if ( $GLOBALS['wp_redis_cache_config']['debug'] ) {
Erick Hitter's avatar
Erick Hitter committed
135 136
			echo "<!-- using predis as a backup -->\n";
		}
Erick Hitter's avatar
Erick Hitter committed
137

138
		include_once dirname( __FILE__ ) . '/wp-content/plugins/wp-redis-cache/predis5.2.php'; //we need this to use Redis inside of PHP
139
		$redis = new Predis_Client( array(
140 141 142
			'host'     => $GLOBALS['wp_redis_cache_config']['redis_server'],
			'port'     => $GLOBALS['wp_redis_cache_config']['redis_port'],
			'database' => $GLOBALS['wp_redis_cache_config']['redis_db'],
143
		) );
Erick Hitter's avatar
Erick Hitter committed
144 145 146
	}

	//Either manual refresh cache by adding ?refresh=secret_string after the URL or somebody posting a comment
Erick Hitter's avatar
Erick Hitter committed
147
	if ( wp_redis_cache_refresh_has_secret( $GLOBALS['wp_redis_cache_config']['secret_string'] ) || wp_redis_cache_request_has_secret( $GLOBALS['wp_redis_cache_config']['secret_string'] ) || wp_redis_cache_is_remote_page_load( $GLOBALS['wp_redis_cache_config']['current_url'], $GLOBALS['wp_redis_cache_config']['server_ip'] ) ) {
148
		if ( $GLOBALS['wp_redis_cache_config']['debug'] ) {
Erick Hitter's avatar
Erick Hitter committed
149 150
			echo "<!-- manual refresh was required -->\n";
		}
Erick Hitter's avatar
Erick Hitter committed
151

152
		$redis->del( $GLOBALS['wp_redis_cache_config']['redis_key'] );
Erick Hitter's avatar
Erick Hitter committed
153

154
		require dirname( __FILE__ ) . '/wp-blog-header.php';
Erick Hitter's avatar
Erick Hitter committed
155
	// If the cache does not exist lets display the user the normal page without cache, and then fetch a new cache page
156 157
	} elseif ( $_SERVER['REMOTE_ADDR'] != $GLOBALS['wp_redis_cache_config']['server_ip'] && false === strstr( $GLOBALS['wp_redis_cache_config']['current_url'], 'preview=true' ) ) {
		if ( $GLOBALS['wp_redis_cache_config']['debug'] ) {
Erick Hitter's avatar
Erick Hitter committed
158 159 160
			echo "<!-- displaying page without cache -->\n";
		}

161 162
		$is_post   = (bool) 'POST' === $_SERVER['REQUEST_METHOD'];
		$logged_in = (bool) preg_match( "#(wordpress_(logged|sec)|comment_author)#", var_export( $_COOKIE, true ) );
Erick Hitter's avatar
Erick Hitter committed
163

164 165 166 167 168
		if ( $GLOBALS['wp_redis_cache_config']['debug'] ) {
			echo "<!-- POST request: . " . ( $is_post ? 'yes' : 'no' ) . "-->\n";
			echo "<!-- Logged in: . " . ( $logged_in ? 'yes' : 'no' ) . "-->\n";
		}

169
		if ( ! $is_post && ! $logged_in ) {
Erick Hitter's avatar
Erick Hitter committed
170
			ob_start();
171
			require dirname( __FILE__ ) . '/wp-blog-header.php';
172
			$html_of_page = trim( ob_get_clean() );
Erick Hitter's avatar
Erick Hitter committed
173 174 175 176
			echo $html_of_page;

			// When a page displays after an "HTTP 404: Not Found" error occurs, do not cache
			// When the search was used, do not cache
177
			if ( ! is_404() && ! is_search() ) {
178 179 180 181 182 183 184 185
				if ( isset( $GLOBALS['wp_redis_cache_config']['unlimited'] ) ) {
					$unlimited = $GLOBALS['wp_redis_cache_config']['unlimited'];
				} else {
					$unlimited = (bool) get_option( 'wp-redis-cache-debug', false );
					$GLOBALS['wp_redis_cache_config']['unlimited'] = $unlimited;
				}

				// Determine how long to cache the page for and set the cache
Erick Hitter's avatar
Erick Hitter committed
186
				if ( $unlimited ) {
187
					$redis->set( $GLOBALS['wp_redis_cache_config']['redis_key'], $html_of_page );
Erick Hitter's avatar
Erick Hitter committed
188
				} else {
189 190 191 192 193 194 195 196 197 198 199 200
					if ( isset( $GLOBALS['wp_redis_cache_config']['cache_duration'] ) ) {
						$cache_duration = $GLOBALS['wp_redis_cache_config']['cache_duration'];
					} else {
						$cache_duration = (int) get_option( 'wp-redis-cache-seconds', 43200 );
						$GLOBALS['wp_redis_cache_config']['cache_duration'] = $cache_duration;
					}

					if ( ! is_numeric( $cache_duration ) ) {
						$cache_duration = $GLOBALS['wp_redis_cache_config']['cache_duration'] = 43200;
					}

					$redis->setex( $GLOBALS['wp_redis_cache_config']['redis_key'], $cache_duration, $html_of_page );
Erick Hitter's avatar
Erick Hitter committed
201 202 203
				}
			}
		} else { //either the user is logged in, or is posting a comment, show them uncached
204
			require dirname( __FILE__ ) . '/wp-blog-header.php';
Erick Hitter's avatar
Erick Hitter committed
205
		}
206
	} elseif ( $_SERVER['REMOTE_ADDR'] != $GLOBALS['wp_redis_cache_config']['server_ip'] && true === strstr( $GLOBALS['wp_redis_cache_config']['current_url'], 'preview=true' ) ) {
207
		require dirname( __FILE__ ) . '/wp-blog-header.php';
208
	// This page is cached, lets display it
209 210 211
	} elseif ( $redis->exists( $GLOBALS['wp_redis_cache_config']['redis_key'] ) ) {
		if ( $GLOBALS['wp_redis_cache_config']['debug'] ) {
			echo "<!-- serving page from cache: key: " . $GLOBALS['wp_redis_cache_config']['redis_key'] . " -->\n";
212 213
		}

Erick Hitter's avatar
Erick Hitter committed
214
		$GLOBALS['wp_redis_cache_config']['cache'] = true;
215

216
		$html_of_page = trim( $redis->get( $GLOBALS['wp_redis_cache_config']['redis_key'] ) );
217 218
		echo $html_of_page;

219 220
	} else {
		require dirname( __FILE__ ) . '/wp-blog-header.php';
Erick Hitter's avatar
Erick Hitter committed
221
	}
Erick Hitter's avatar
Erick Hitter committed
222
} catch ( Exception $e ) {
223
	require dirname( __FILE__ ) . '/wp-blog-header.php';
224
	wp_redis_cache_exception_handler( $e );
Benjamin Adams's avatar
Benjamin Adams committed
225 226
}

Hendrik Klemp's avatar
Hendrik Klemp committed
227
$end  = microtime();
Erick Hitter's avatar
Erick Hitter committed
228
$time = @wp_redis_cache_get_micro_time( $end ) - @wp_redis_cache_get_micro_time( $start );
229
if ( $GLOBALS['wp_redis_cache_config']['debug'] ) {
Erick Hitter's avatar
Erick Hitter committed
230
	echo "<!-- Cache system by Benjamin Adams. Page generated in " . round($time, 5) . " seconds. -->\n";
Erick Hitter's avatar
Erick Hitter committed
231
	echo "<!-- Site was cached = " . $GLOBALS['wp_redis_cache_config']['cache'] . " -->\n";
232
	if ( isset( $GLOBALS['wp_redis_cache_config']['cache_duration'] ) ) {
Erick Hitter's avatar
Erick Hitter committed
233
		echo "<!-- wp-redis-cache-seconds = " . $GLOBALS['wp_redis_cache_config']['cache_duration'] . " -->\n";
Erick Hitter's avatar
Erick Hitter committed
234
	}
Erick Hitter's avatar
Erick Hitter committed
235
	echo "<!-- wp-redis-cache-ip = " . $GLOBALS['wp_redis_cache_config']['server_ip'] . "-->\n";
236 237
	if ( isset( $GLOBALS['wp_redis_cache_config']['unlimited'] ) ) {
		echo "<!-- wp-redis-cache-unlimited = " . $GLOBALS['wp_redis_cache_config']['unlimited'] . "-->\n";
Erick Hitter's avatar
Erick Hitter committed
238
	}
Erick Hitter's avatar
Erick Hitter committed
239
	echo "<!-- wp-redis-cache-debug = " . $GLOBALS['wp_redis_cache_config']['debug'] . "-->\n";
Benjamin Adams's avatar
Benjamin Adams committed
240
}