2013-03-19 10:16:59 +00:00
< ? php
/**
* advanced cache worker of WordPress plugin WP - FFPC
*/
/* check for WP cache enabled*/
if ( ! WP_CACHE )
return false ;
/* no cache for post request (comments, plugins and so on) */
if ( $_SERVER [ " REQUEST_METHOD " ] == 'POST' )
return false ;
/**
* Try to avoid enabling the cache if sessions are managed
* with request parameters and a session is active
*/
if ( defined ( 'SID' ) && SID != '' )
return false ;
2015-01-31 10:24:04 +00:00
/* check for config */
if ( ! isset ( $wp_ffpc_config ))
return false ;
2013-03-19 10:16:59 +00:00
/* request uri */
$wp_ffpc_uri = $_SERVER [ 'REQUEST_URI' ];
/* no cache for robots.txt */
if ( stripos ( $wp_ffpc_uri , 'robots.txt' ) )
return false ;
/* multisite files can be too large for memcached */
2014-09-04 10:49:14 +01:00
if ( function_exists ( 'is_multisite' ) && stripos ( $wp_ffpc_uri , '/files/' ) && is_multisite () )
return false ;
2013-03-19 10:16:59 +00:00
/* check if config is network active: use network config */
if ( ! empty ( $wp_ffpc_config [ 'network' ] ) )
$wp_ffpc_config = $wp_ffpc_config [ 'network' ];
/* check if config is active for site : use site config */
elseif ( ! empty ( $wp_ffpc_config [ $_SERVER [ 'HTTP_HOST' ] ] ) )
$wp_ffpc_config = $wp_ffpc_config [ $_SERVER [ 'HTTP_HOST' ] ];
/* plugin config not found :( */
else
return false ;
2015-01-31 10:24:04 +00:00
/* no cache for uri with query strings, things usually go bad that way */
if ( isset ( $wp_ffpc_config [ 'nocache_dyn' ]) && ! empty ( $wp_ffpc_config [ 'nocache_dyn' ]) && stripos ( $wp_ffpc_uri , '?' ) !== false )
return false ;
2014-09-19 09:38:54 +01:00
/* check for cookies that will make us not cache the content, like logged in WordPress cookie */
2013-06-07 17:56:56 +01:00
if ( isset ( $wp_ffpc_config [ 'nocache_cookies' ]) && ! empty ( $wp_ffpc_config [ 'nocache_cookies' ]) ) {
$nocache_cookies = array_map ( 'trim' , explode ( " , " , $wp_ffpc_config [ 'nocache_cookies' ] ) );
2013-04-19 21:42:09 +01:00
2013-06-07 17:56:56 +01:00
if ( ! empty ( $nocache_cookies ) ) {
foreach ( $_COOKIE as $n => $v ) {
/* check for any matches to user-added cookies to no-cache */
2013-04-19 21:42:09 +01:00
foreach ( $nocache_cookies as $nocache_cookie ) {
if ( strpos ( $n , $nocache_cookie ) === 0 ) {
return false ;
}
}
2013-03-19 10:16:59 +00:00
}
}
}
2014-08-22 11:55:25 +01:00
/* no cache for excluded URL patterns */
if ( isset ( $wp_ffpc_config [ 'nocache_url' ]) && trim ( $wp_ffpc_config [ 'nocache_url' ]) ) {
$pattern = sprintf ( '#%s#' , trim ( $wp_ffpc_config [ 'nocache_url' ]));
if ( preg_match ( $pattern , $wp_ffpc_uri ) ) {
return false ;
}
}
2013-06-07 17:56:56 +01:00
/* no cache for for logged in users unless it ' s set
identifier cookies are listed in backend as var for easier usage
*/
if ( ! isset ( $wp_ffpc_config [ 'cache_loggedin' ]) || $wp_ffpc_config [ 'cache_loggedin' ] == 0 || empty ( $wp_ffpc_config [ 'cache_loggedin' ]) ) {
foreach ( $_COOKIE as $n => $v ) {
foreach ( $wp_ffpc_backend -> cookies as $nocache_cookie ) {
if ( strpos ( $n , $nocache_cookie ) === 0 ) {
return false ;
}
}
}
}
2015-05-07 14:22:33 +01:00
/* canonical redirect storage */
$wp_ffpc_redirect = null ;
/* fires up the backend storage array with current config */
include_once ( 'wp-ffpc-backend.php' );
$wp_ffpc_backend = new WP_FFPC_Backend ( $wp_ffpc_config );
2014-09-05 10:41:18 +01:00
2013-03-28 22:27:54 +00:00
/* will store time of page generation */
2013-03-25 13:11:49 +00:00
$wp_ffpc_gentime = 0 ;
2013-03-19 10:16:59 +00:00
2013-03-28 22:27:54 +00:00
/* backend connection failed, no caching :( */
2013-03-19 10:16:59 +00:00
if ( $wp_ffpc_backend -> status () === false )
return false ;
2013-03-28 22:27:54 +00:00
/* try to get data & meta keys for current page */
2013-03-31 22:22:02 +01:00
$wp_ffpc_keys = array ( 'meta' => $wp_ffpc_config [ 'prefix_meta' ], 'data' => $wp_ffpc_config [ 'prefix_data' ] );
2013-03-19 10:16:59 +00:00
$wp_ffpc_values = array ();
2013-03-31 22:22:02 +01:00
foreach ( $wp_ffpc_keys as $internal => $key ) {
2014-01-01 12:38:59 +00:00
$key = $wp_ffpc_backend -> key ( $key );
$value = $wp_ffpc_backend -> get ( $key );
2013-03-19 10:16:59 +00:00
2013-03-19 18:08:34 +00:00
if ( ! $value ) {
2013-03-28 22:27:54 +00:00
/* does not matter which is missing, we need both, if one fails, no caching */
2013-03-19 10:16:59 +00:00
wp_ffpc_start ();
return ;
}
2013-03-19 18:08:34 +00:00
else {
2013-03-28 22:27:54 +00:00
/* store results */
2013-03-31 22:22:02 +01:00
$wp_ffpc_values [ $internal ] = $value ;
2013-03-19 10:16:59 +00:00
}
}
/* serve cache 404 status */
2013-04-09 05:32:07 +01:00
if ( isset ( $wp_ffpc_values [ 'meta' ][ 'status' ] ) && $wp_ffpc_values [ 'meta' ][ 'status' ] == 404 ) {
2013-03-19 10:16:59 +00:00
header ( " HTTP/1.1 404 Not Found " );
2014-09-04 10:49:14 +01:00
/* if I kill the page serving here , the 404 page will not be showed at all , so we do not do that
* flush ();
* die ();
*/
2013-03-19 10:16:59 +00:00
}
/* server redirect cache */
2013-04-09 05:32:07 +01:00
if ( isset ( $wp_ffpc_values [ 'meta' ][ 'redirect' ] ) && $wp_ffpc_values [ 'meta' ][ 'redirect' ] ) {
2013-03-19 10:16:59 +00:00
header ( 'Location: ' . $wp_ffpc_values [ 'meta' ][ 'redirect' ] );
2014-09-04 10:49:14 +01:00
/* cut the connection as fast as possible */
2013-03-19 10:16:59 +00:00
flush ();
die ();
}
/* page is already cached on client side (chrome likes to do this, anyway, it's quite efficient) */
if ( array_key_exists ( " HTTP_IF_MODIFIED_SINCE " , $_SERVER ) && ! empty ( $wp_ffpc_values [ 'meta' ][ 'lastmodified' ] ) ) {
$if_modified_since = strtotime ( preg_replace ( '/;.*$/' , '' , $_SERVER [ " HTTP_IF_MODIFIED_SINCE " ]));
/* check is cache is still valid */
if ( $if_modified_since >= $wp_ffpc_values [ 'meta' ][ 'lastmodified' ] ) {
header ( " HTTP/1.0 304 Not Modified " );
2014-09-04 10:49:14 +01:00
/* connection cut for faster serving */
2013-03-19 10:16:59 +00:00
flush ();
die ();
}
}
2013-03-28 22:27:54 +00:00
/*** SERVING CACHED PAGE ***/
2013-03-19 10:16:59 +00:00
/* if we reach this point it means data was found & correct, serve it */
2013-06-18 10:57:31 +01:00
if ( ! empty ( $wp_ffpc_values [ 'meta' ][ 'mime' ] ) )
header ( 'Content-Type: ' . $wp_ffpc_values [ 'meta' ][ 'mime' ]);
2013-03-19 10:16:59 +00:00
/* don't allow browser caching of page */
header ( 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0' );
header ( 'Pragma: no-cache' );
/* expire at this very moment */
header ( 'Expires: ' . gmdate ( " D, d M Y H:i:s " , time () ) . " GMT " );
/* if shortlinks were set */
if ( ! empty ( $wp_ffpc_values [ 'meta' ][ 'shortlink' ] ) )
header ( 'Link:<' . $wp_ffpc_values [ 'meta' ][ 'shortlink' ] . '>; rel=shortlink' );
/* if last modifications were set (for posts & pages) */
if ( ! empty ( $wp_ffpc_values [ 'meta' ][ 'lastmodified' ]) )
header ( 'Last-Modified: ' . gmdate ( " D, d M Y H:i:s " , $wp_ffpc_values [ 'meta' ][ 'lastmodified' ] ) . " GMT " );
/* pingback urls, if existx */
2014-12-08 09:19:01 +00:00
if ( ! empty ( $wp_ffpc_values [ 'meta' ][ 'pingback' ] ) && $wp_ffpc_config [ 'pingback_header' ] )
2013-03-19 10:16:59 +00:00
header ( 'X-Pingback: ' . $wp_ffpc_values [ 'meta' ][ 'pingback' ] );
/* for debugging */
if ( $wp_ffpc_config [ 'response_header' ] )
2013-04-19 21:42:09 +01:00
header ( 'X-Cache-Engine: WP-FFPC with ' . $wp_ffpc_config [ 'cache_type' ] . ' via PHP' );
2013-03-19 10:16:59 +00:00
/* HTML data */
2015-05-07 14:22:33 +01:00
if ( $wp_ffpc_config [ 'generate_time' ] == '1' && stripos ( $wp_ffpc_values [ 'data' ], '</body>' ) ) {
$mtime = explode ( " " , microtime () );
$wp_ffpc_gentime = ( $mtime [ 1 ] + $mtime [ 0 ] ) - $wp_ffpc_gentime ;
$insertion = " \n <!-- \n WP-FFPC cache output stats \n \t cache engine: " . $wp_ffpc_config [ 'cache_type' ] . " \n \t UNIX timestamp: " . time () . " \n \t date: " . date ( 'c' ) . " \n \t from server: " . $_SERVER [ 'SERVER_ADDR' ] . " \n \t - if you see this, WP-FFPC used the cache to serve the page \n --> \n " ;
$index = stripos ( $wp_ffpc_values [ 'data' ] , '</body>' );
$wp_ffpc_values [ 'data' ] = substr_replace ( $wp_ffpc_values [ 'data' ], $insertion , $index , 0 );
}
2015-04-29 09:40:12 +01:00
echo trim ( $wp_ffpc_values [ 'data' ]);
2014-12-08 09:19:01 +00:00
2013-03-19 10:16:59 +00:00
flush ();
die ();
2013-03-28 22:27:54 +00:00
/*** END SERVING CACHED PAGE ***/
/*** GENERATING CACHE ENTRY ***/
2013-03-19 10:16:59 +00:00
/**
* starts caching function
*
*/
function wp_ffpc_start ( ) {
2013-03-28 22:27:54 +00:00
/* set start time */
2013-03-25 13:11:49 +00:00
global $wp_ffpc_gentime ;
$mtime = explode ( " " , microtime () );
$wp_ffpc_gentime = $mtime [ 1 ] + $mtime [ 0 ];
2013-03-19 10:16:59 +00:00
/* start object "colleting" and pass it the the actual storer function */
ob_start ( 'wp_ffpc_callback' );
}
/**
* callback function for WordPress redirect urls
*
*/
function wp_ffpc_redirect_callback ( $redirect_url , $requested_url ) {
global $wp_ffpc_redirect ;
$wp_ffpc_redirect = $redirect_url ;
return $redirect_url ;
}
/**
* write cache function , called when page generation ended
*/
function wp_ffpc_callback ( $buffer ) {
2013-03-28 22:27:54 +00:00
/* use global config */
2013-03-19 10:16:59 +00:00
global $wp_ffpc_config ;
2013-03-28 22:27:54 +00:00
/* backend was already set up, try to use it */
2013-03-19 10:16:59 +00:00
global $wp_ffpc_backend ;
2013-03-28 22:27:54 +00:00
/* check is it's a redirect */
2013-03-19 10:16:59 +00:00
global $wp_ffpc_redirect ;
2013-03-28 22:27:54 +00:00
/* no is_home = error, WordPress functions are not availabe */
2013-03-19 10:16:59 +00:00
if ( ! function_exists ( 'is_home' ))
return $buffer ;
2013-03-28 22:27:54 +00:00
/* no <body> close tag = not HTML, also no <rss>, not feed, don't cache */
if ( stripos ( $buffer , '</body>' ) === false && stripos ( $buffer , '</rss>' ) === false )
2013-03-19 10:16:59 +00:00
return $buffer ;
/* reset meta to solve conflicts */
$meta = array ();
/* trim unneeded whitespace from beginning / ending of buffer */
$buffer = trim ( $buffer );
/* Can be a trackback or other things without a body .
We do not cache them , WP needs to get those calls . */
if ( strlen ( $buffer ) == 0 )
return '' ;
if ( is_home () )
$meta [ 'type' ] = 'home' ;
elseif ( is_feed () )
$meta [ 'type' ] = 'feed' ;
elseif ( is_archive () )
$meta [ 'type' ] = 'archive' ;
elseif ( is_single () )
$meta [ 'type' ] = 'single' ;
elseif ( is_page () )
$meta [ 'type' ] = 'page' ;
else
$meta [ 'type' ] = 'unknown' ;
2013-06-25 17:27:23 +01:00
if ( $meta [ 'type' ] != 'unknown' ) {
/* check if caching is disabled for page type */
$nocache_key = 'nocache_' . $meta [ 'type' ];
2013-03-19 10:16:59 +00:00
2013-06-25 17:27:23 +01:00
/* don't cache if prevented by rule */
if ( $wp_ffpc_config [ $nocache_key ] == 1 ) {
return $buffer ;
}
2013-03-19 10:16:59 +00:00
}
2014-08-22 11:55:25 +01:00
if ( is_404 () )
2013-03-19 10:16:59 +00:00
$meta [ 'status' ] = 404 ;
/* redirect page */
if ( $wp_ffpc_redirect != null )
$meta [ 'redirect' ] = $wp_ffpc_redirect ;
/* feed is xml, all others forced to be HTML */
if ( is_feed () )
$meta [ 'mime' ] = 'text/xml;charset=' ;
else
$meta [ 'mime' ] = 'text/html;charset=' ;
/* set mimetype */
$meta [ 'mime' ] = $meta [ 'mime' ] . $wp_ffpc_config [ 'charset' ];
/* try if post is available
if made with archieve , last listed post can make this go bad
*/
global $post ;
2013-03-19 18:08:34 +00:00
if ( ! empty ( $post ) && ( $meta [ 'type' ] == 'single' || $meta [ 'type' ] == 'page' ) && ! empty ( $post -> post_modified_gmt ) ) {
2013-03-19 10:16:59 +00:00
/* get last modification data */
$meta [ 'lastmodified' ] = strtotime ( $post -> post_modified_gmt );
/* get shortlink, if possible */
2013-03-19 18:08:34 +00:00
if ( function_exists ( 'wp_get_shortlink' )) {
2013-03-19 10:16:59 +00:00
$shortlink = wp_get_shortlink ( );
if ( ! empty ( $shortlink ) )
$meta [ 'shortlink' ] = $shortlink ;
}
}
/* store pingback url if pingbacks are enabled */
if ( get_option ( 'default_ping_status' ) == 'open' )
$meta [ 'pingback' ] = get_bloginfo ( 'pingback_url' );
2013-03-28 22:27:54 +00:00
/* add generation info is option is set, but only to HTML */
if ( $wp_ffpc_config [ 'generate_time' ] == '1' && stripos ( $buffer , '</body>' ) ) {
2013-03-25 13:11:49 +00:00
global $wp_ffpc_gentime ;
$mtime = explode ( " " , microtime () );
$wp_ffpc_gentime = ( $mtime [ 1 ] + $mtime [ 0 ] ) - $wp_ffpc_gentime ;
2015-05-07 14:22:33 +01:00
$insertion = " \n <!-- \n WP-FFPC cache generation stats " . " \n \t generation time: " . round ( $wp_ffpc_gentime , 3 ) . " seconds \n \t generaton UNIX timestamp: " . time () . " \n \t generaton date: " . date ( 'c' ) . " \n \t generator server: " . $_SERVER [ 'SERVER_ADDR' ] . " \n \t - at this point the cache entry is only created by WP-FFPC but the page is not yet served from the cache \n --> \n " ;
2013-03-25 13:11:49 +00:00
$index = stripos ( $buffer , '</body>' );
$buffer = substr_replace ( $buffer , $insertion , $index , 0 );
}
2014-04-09 19:16:35 +01:00
$prefix_meta = $wp_ffpc_backend -> key ( $wp_ffpc_config [ 'prefix_meta' ] );
$wp_ffpc_backend -> set ( $prefix_meta , $meta );
$prefix_data = $wp_ffpc_backend -> key ( $wp_ffpc_config [ 'prefix_data' ] );
$wp_ffpc_backend -> set ( $prefix_data , $buffer );
2013-03-19 10:16:59 +00:00
2014-04-09 21:34:14 +01:00
if ( ! empty ( $meta [ 'status' ] ) && $meta [ 'status' ] == 404 ) {
2013-11-07 10:06:49 +00:00
header ( " HTTP/1.1 404 Not Found " );
}
else {
/* vital for nginx, make no problem at other places */
header ( " HTTP/1.1 200 OK " );
}
2013-03-19 10:16:59 +00:00
/* echoes HTML out */
2015-04-29 09:40:12 +01:00
return trim ( $buffer );
2013-03-19 10:16:59 +00:00
}
2013-03-28 22:27:54 +00:00
/*** END GENERATING CACHE ENTRY ***/