initial release

git-svn-id: http://plugins.svn.wordpress.org/wp-ffpc/trunk@505945 b8457f37-d9ea-0310-8a92-e5e31aec5664
This commit is contained in:
cadeyrn 2012-02-16 14:07:00 +00:00
parent 0c00c7edab
commit 6dd39641df
5 changed files with 1159 additions and 0 deletions

254
advanced-cache.php Normal file
View file

@ -0,0 +1,254 @@
<?php
/**
* part of WordPress plugin WP-FFPC
*/
/* check for WP cache enabled*/
if ( !WP_CACHE )
return false;
/* check for config */
if (!isset($wp_ffpc_config))
return false;
/* request uri */
$wp_ffpc_uri = $_SERVER['REQUEST_URI'];
/* query string */
$wp_ffpc_qs = strpos($wp_ffpc_uri, '?');
/* no cache for uri with query strings, things usually go bad that way */
if ($wp_ffpc_qs !== false)
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;
/* no cache for pages starting with /wp- like WP admin */
if (strpos($wp_ffpc_uri, '/wp-') !== false)
return false;
/* no cache for robots.txt */
if ( strpos($wp_ffpc_uri, 'robots.txt') )
return false;
/* multisite files can be too large for memcached */
if (function_exists('is_multisite') && is_multisite() && strpos($wp_ffpc_uri, '/files/') )
return false;
/* no cache for logged in users */
if (!$wp_ffpc_config['cache_loggedin']) {
foreach ($_COOKIE as $n=>$v) {
// test cookie makes to cache not work!!!
if ($n == 'wordpress_test_cookie') continue;
// wp 2.5 and wp 2.3 have different cookie prefix, skip cache if a post password cookie is present, also
if ( (substr($n, 0, 14) == 'wordpressuser_' || substr($n, 0, 10) == 'wordpress_' || substr($n, 0, 12) == 'wp-postpass_') && !$wp_ffpc_config['cache_loggedin'] ) {
return false;
}
}
}
global $wp_ffpc_backend_status;
$wp_ffpc_backend_status = wp_ffpc_init( );
/* check alive status of backend */
if ( !$wp_ffpc_backend_status )
return false;
/* use the full accessed URL string as key, same will be generated by nginx as well
we need a data and a meta key: data is string only with content, meta is not used in nginx */
global $wp_ffpc_data_key;
$wp_ffpc_data_key = $wp_ffpc_config['prefix_data'] . $_SERVER['HTTP_HOST'] . $wp_ffpc_uri;
global $wp_ffpc_meta_key;
$wp_ffpc_meta_key = $wp_ffpc_config['prefix_meta'] . $_SERVER['HTTP_HOST'] . $wp_ffpc_uri;
/* search for valid data entry */
global $wp_ffpc_data;
$wp_ffpc_data = wp_ffpc_get ( $wp_ffpc_data_key );
/* search for valid meta entry */
global $wp_ffpc_meta;
$wp_ffpc_meta = wp_ffpc_get ( $wp_ffpc_meta_key );
/* data is corrupted or empty */
if ( !$wp_ffpc_data || !$wp_ffpc_meta ) {
wp_ffpc_start();
return;
}
/* 404 status cache */
if ($wp_ffpc_meta['status'] == 404) {
header("HTTP/1.1 404 Not Found");
flush();
die();
}
/* server redirect cache */
if ($wp_ffpc_meta['redirect_location']) {
header('Location: ' . $wp_ffpc_meta['redirect_location']);
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_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_meta['lastmodified'] ) {
header("HTTP/1.0 304 Not Modified");
flush();
die();
}
}
/* data found & correct, serve it */
header('Content-Type: ' . $wp_ffpc_meta['mime']);
/* 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_meta['shortlink'] ) )
header('Link:<'. $wp_ffpc_meta['shortlink'] .'>; rel=shortlink');
/* if last modifications were set (for posts & pages) */
if ( !empty($wp_ffpc_meta['lastmodified']) )
header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $wp_ffpc_meta['lastmodified'] ). " GMT");
/* only set when not multisite, fallback to HTTP HOST */
$wp_ffpc_pingback_url = (empty( $wp_ffpc_config['url'] )) ? $_SERVER['HTTP_HOST'] : $wp_ffpc_config['url'];
/* pingback additional header */
if ($wp_ffpc_config['pingback_status'])
header('X-Pingback: ' . $wp_ffpc_pingback_url . '/xmlrpc.php' );
/* for debugging */
if ($wp_ffpc_config['debug'])
header('X-Cache-Engine: WP-FFPC with ' . $wp_ffpc_config['cache_type']);
/* HTML data */
echo $wp_ffpc_data;
flush();
die();
/**
* FUNCTIONS
*/
/**
* starts caching
*
*/
function wp_ffpc_start( ) {
ob_start('wp_ffpc_callback');
}
/**
* write cache function, called when page generation ended
*/
function wp_ffpc_callback($buffer) {
global $wp_ffpc_config;
global $wp_ffpc_data;
global $wp_ffpc_meta;
global $wp_ffpc_redirect;
global $wp_ffpc_meta_key;
global $wp_ffpc_data_key;
/* no is_home = error */
if (!function_exists('is_home'))
return $buffer;
/* no <body> close tag = not HTML, don't cache */
if (strpos($buffer, '</body>') === false)
return $buffer;
/* reset meta to solve conflicts */
$wp_ffpc_meta = array();
/* WP is sending a redirect */
if ($wp_ffpc_redirect) {
$wp_ffpc_meta['redirect_location'] = $wp_ffpc_redirect;
wp_ffpc_write();
return $buffer;
}
/* 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() )
$wp_ffpc_meta['type'] = 'home';
elseif (is_feed() )
$wp_ffpc_meta['type'] = 'feed';
elseif ( is_archive() )
$wp_ffpc_meta['type'] = 'archive';
elseif ( is_single() )
$wp_ffpc_meta['type'] = 'single';
else if ( is_page() )
$wp_ffpc_meta['type'] = 'page';
else
$wp_ffpc_meta['type'] = 'unknown';
/* check if caching is disabled for page type */
$nocache_key = 'nocache_'. $wp_ffpc_meta['type'];
if ( $wp_ffpc_config[$nocache_key] == 1 ) {
return $buffer;
}
if ( is_404() )
$wp_ffpc_meta['status'] = 404;
/* feed is xml, all others forced to be HTML */
if ( is_feed() )
$wp_ffpc_meta['mime'] = 'text/xml;charset=';
else
$wp_ffpc_meta['mime'] = 'text/html;charset=';
/* set mimetype */
$wp_ffpc_meta['mime'] = $wp_ffpc_meta['mime'] . $wp_ffpc_config['charset'];
/* get shortlink, if possible */
if (function_exists('wp_get_shortlink'))
{
$shortlink = wp_get_shortlink( );
if (!empty ( $shortlink ) )
$wp_ffpc_meta['shortlink'] = $shortlink;
}
/* try if post is available
if made with archieve, last listed post can make this go bad
*/
global $post;
if ( !empty($post) && ( $wp_ffpc_meta['type'] == 'single' || $wp_ffpc_meta['type'] == 'page' ) )
{
/* get last modification data */
if (!empty ( $post->post_modified_gmt ) )
$wp_ffpc_meta['lastmodified'] = strtotime ( $post->post_modified_gmt );
}
/* set meta */
wp_ffpc_set ( $wp_ffpc_meta_key, $wp_ffpc_meta );
/* set data */
wp_ffpc_set ( $wp_ffpc_data_key, $buffer );
/* vital for nginx version */
header("HTTP/1.1 200 OK");
/* echoes HTML out */
return $buffer;
}
?>

53
css/wp-ffpc.admin.css Normal file
View file

@ -0,0 +1,53 @@
dt {
margin-top: 2em;
font-weight:bold;
}
dd {
}
fieldset {
display:block;
margin:0 1% 0 1%;
clear:none;
}
legend {
font-weight:bold;
padding:0;
margin:0;
font-size:130%;
padding-top:3em;
}
.default {
display:block;
padding-left: 1em;
font-size:90%;
color:#666;
}
.description {
display:block;
}
.grid50 {
float:left;
display:block;
text-align:left;
margin:0 1% 0 1%;
width:48%;
overflow:auto;
}
.clearcolumns {
clear:both;
}
.error-msg {
color: #990000;
}
.ok-msg {
color: #009900;
}

45
readme.txt Normal file
View file

@ -0,0 +1,45 @@
=== WP-FFPC ===
Contributors: cadeyrn
Tags: cache, APC, memcached, full page cache
Requires at least: 2.7
Tested up to: 3.3
Stable tag: 0.1
Fast Full Page Cache, backend can be memcached or APC
== Description ==
WP-FFPC is a full page cache plugin for WordPress. It can use APC or a memcached server as backend.
PHP has two extension for communication with a memcached server, named Memcache and Memcached. The plugin can utilize both.
A special function is that when used with the Memcache extension it produces memcached entries that can be read and served directly from nginx, making the cache insanely fast.
The naming stands for Fast Full Page Cache.
If used in WordPress Network, the configuration will only be available for network admins at the network admin panel, and will be system-wide and will be applied for every blog.
Some parts were based on Hyper Cache plugin by Satollo (info@satollo.net).
= Usage =
Configure the plugin at the admin section
== Installation ==
1. Upload contents of `wp-ffpc.zip` to the `/wp-content/plugins/` directory
2. Activate the plugin through the `Plugins` menu in WordPress (please use network wide activation if used in a WordPress Network)
3. Fine tune the settings in `Settings` -> `wp-ffpc` menu in WordPress. For WordPress Network, please visit the Network Admin panel, the options will be available at WP-FFPC menu entry.
== Frequently Asked Questions ==
== Screenshots ==
== Upgrade Notice ==
== Changelog ==
= 0.1 =
2012.02.16
* first public release

180
wp-ffpc-common.php Normal file
View file

@ -0,0 +1,180 @@
<?php
/**
* part of WordPress plugin WP-FFPC
*/
/**
* function to test if selected backend is available & alive
*/
global $wp_ffpc_backend;
global $wp_nmc_redirect;
/**
* init and backend alive check function
*
* @param $type [optional] if set, alive will be tested against this
* if false, backend will be globally initiated
* when set, backend will not become global, just tested if alive
*/
function wp_ffpc_init( $type = false ) {
global $wp_ffpc_config;
$wp_ffpc_backend_status = false;
$reg_backend = $type;
// $type is to test an exact backend */
if ( !$type )
$type = $wp_ffpc_config['cache_type'];
/* verify selected storage is available */
switch ($type)
{
/* in case of apc */
case 'apc':
/* verify apc functions exist, apc ext is loaded */
if (!function_exists('apc_cache_info'))
return false;
/* verify apc is working */
if ( !apc_cache_info() )
return false;
$wp_ffpc_backend_status = true;
break;
/* in case of Memcache */
case 'memcache':
/* Memcache class does not exist, Memcache extension is not available */
if (!class_exists('Memcache'))
return false;
if ($reg_backend)
global $wp_ffpc_backend;
$wp_ffpc_backend = new Memcache();
$wp_ffpc_backend->addServer( $wp_ffpc_config['host'] , $wp_ffpc_config['port'] );
$wp_ffpc_backend_status = $wp_ffpc_backend->getServerStatus( $wp_ffpc_config['host'] , $wp_ffpc_config['port'] );
break;
/* in case of Memcached */
case 'memcached':
/* Memcached class does not exist, Memcached extension is not available */
if (!class_exists('Memcached'))
return false;
if ($reg_backend)
global $wp_ffpc_backend;
$wp_ffpc_backend = new Memcached();
$wp_ffpc_backend->addServer( $wp_ffpc_config['host'] , $wp_ffpc_config['port'] );
$wp_ffpc_backend_status = array_key_exists( $wp_ffpc_config['host'] . ':' . $wp_ffpc_config['port'] , $wp_ffpc_backend->getStats() );
break;
/* cache type is invalid */
default:
return false;
}
return $wp_ffpc_backend_status;
}
/**
* clear cache element or flush cache
*
* @param $post_id [optional] : if registered with invalidation hook, post_id will be passed
*/
function wp_ffpc_clear ( $post_id = false ) {
global $wp_ffpc_config;
global $post;
/* post invalidation enabled */
if ( $wp_ffpc_config['invalidation_method'] )
{
$path = substr ( get_permalink($post_id) , 7 );
if (empty($path))
return false;
$meta = $wp_ffpc_config['prefix-meta'] . $path;
$data = $wp_ffpc_config['prefix-data'] . $path;
}
switch ($wp_ffpc_config['cache_type'])
{
/* in case of apc */
case 'apc':
if ( $wp_ffpc_config['invalidation_method'] )
{
apc_delete ( $meta );
apc_delete ( $data );
}
else
{
apc_clear_cache('user');
apc_clear_cache('system');
}
break;
/* in case of Memcache */
case 'memcache':
case 'memcached':
global $wp_ffpc_backend;
if ( $wp_ffpc_config['invalidation_method'] )
{
$wp_ffpc_backend->delete( $meta );
$wp_ffpc_backend->delete( $data );
}
else
{
$wp_ffpc_backend->flush();
}
break;
/* cache type is invalid */
default:
return false;
}
return true;
}
/**
* sets a key-value pair in backend
*
* @param &$key store key, passed by reference for speed
* @param &$data store value, passed by reference for speed
*
*/
function wp_ffpc_set ( &$key, &$data ) {
global $wp_ffpc_config;
switch ($wp_ffpc_config['cache_type'])
{
case 'apc':
/* use apc_store to overwrite data is existed */
apc_store( $key , $data , $wp_ffpc_config['expire']);
break;
case 'memcache':
global $wp_ffpc_backend;
/* false to disable compression, vital for nginx */
$wp_ffpc_backend->set ( $key, $data , false, $wp_ffpc_config['expire'] );
break;
case 'memcached':
global $wp_ffpc_backend;
$wp_ffpc_backend->set ( $key, $data , $wp_ffpc_config['expire'] );
break;
}
}
/**
* gets cached element by key
*
* @param &$key: key of needed cache element
*
*/
function wp_ffpc_get( &$key ) {
global $wp_ffpc_config;
switch ($wp_ffpc_config['cache_type'])
{
case 'apc':
return apc_fetch($key);
case 'memcache':
case 'memcached':
global $wp_ffpc_backend;
return $wp_ffpc_backend->get($key);
default:
return false;
}
}
?>

627
wp-ffpc.php Normal file
View file

@ -0,0 +1,627 @@
<?php
/*
Plugin Name: WP-FFPC
Version: 0.1
Plugin URI: http://petermolnar.eu/wordpress/wp-ffpc
Description: Fast Full Page Cache, backend can be memcached or APC
Author: Peter Molnar
Author URI: http://petermolnar.eu/
License: GPL2
*/
/* Copyright 2010-2011 Peter Molnar (email : hello@petermolnar.eu )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* fix */
if ( ! defined( 'WP_PLUGIN_URL' ) )
define( 'WP_PLUGIN_URL', get_option( 'siteurl' ) . '/wp-content/plugins' );
if ( ! defined( 'WP_PLUGIN_DIR' ) )
define( 'WP_PLUGIN_DIR', ABSPATH . 'wp-content/plugins' );
/* constants */
define ( 'WP_FFPC_PARAM' , 'wp-ffpc' );
define ( 'WP_FFPC_OPTION_GROUP' , 'wp-ffpcparams' );
define ( 'WP_FFPC_OPTIONS_PAGE' , 'wp-ffpcoptions' );
define ( 'WP_FFPC_URL' , WP_PLUGIN_URL . '/' . WP_FFPC_PARAM );
define ( 'WP_FFPC_DIR' , WP_PLUGIN_DIR . '/' . WP_FFPC_PARAM );
define ( 'WP_FFPC_CONF_DIR' , WP_PLUGIN_DIR . '/' . WP_FFPC_PARAM .'/config' );
define ( 'WP_FFPC_ACACHE_MAIN_FILE' , ABSPATH . 'wp-content/advanced-cache.php' );
define ( 'WP_FFPC_ACACHE_INC_FILE' , WP_FFPC_DIR. '/advanced-cache.php' );
define ( 'WP_FFPC_ACACHE_COMMON_FILE' , WP_FFPC_DIR. '/wp-ffpc-common.php' );
define ( 'WP_FFPC_CONFIG_VAR' , '$wp_ffpc_config' );
include (WP_FFPC_DIR .'/wp-ffpc-common.php');
if (!class_exists('WPFFPC')) {
/**
* main class
*
*/
class WPFFPC {
/* for options array */
var $options = array();
/* for default options array */
var $defaults = array();
/* memcached server object */
var $memcached = NULL;
var $memcached_string = '';
/* status, 0 = nothing happened*/
var $status = 0;
/**
* constructor
*
*/
function __construct() {
/* register options */
$this->get_options();
/* check is backend is available */
$alive = wp_ffpc_init( $this->options['cache_type'] );
/* don't register hooks if backend is dead */
if ($alive)
{
/* init inactivation hooks */
add_action('switch_theme', array( $this , 'invalidate'), 0);
add_action('edit_post', array( $this , 'invalidate'), 0);
add_action('publish_post', array( $this , 'invalidate'), 0);
add_action('delete_post', array( $this , 'invalidate'), 0);
/* Capture and register if a redirect is sent back from WP, so the cache
can cache (or ignore) it. Redirects were source of problems for blogs
with more than one host name (eg. domain.com and www.domain.com) comined
with the use of Hyper Cache.*/
add_filter('redirect_canonical', array( $this , 'redirect_canonical') , 10, 2);
}
/* add admin styling */
if( is_admin() )
{
wp_enqueue_style( WP_FFPC_PARAM . '.admin.css' , WP_FFPC_URL . '/css/'. WP_FFPC_PARAM .'.admin.css', false, '0.1');
}
/* on activation */
register_activation_hook(__FILE__ , array( $this , 'activate') );
/* on deactivation */
register_deactivation_hook(__FILE__ , array( $this , 'deactivate') );
/* on uninstall */
register_uninstall_hook(__FILE__ , array( $this , 'uninstall') );
/* init plugin in the admin section */
/* if multisite, admin page will be on network admin section */
if ( MULTISITE )
add_action('network_admin_menu', array( $this , 'admin_init') );
/* not network, will be in simple admin menu */
else
add_action('admin_menu', array( $this , 'admin_init') );
}
/**
* activation hook: save default settings in order to eliminate bugs.
*
*/
function activate ( ) {
$this->save_settings( true );
}
/**
* init function for admin section
*
*/
function admin_init () {
/* register options */
add_site_option( WP_FFPC_PARAM, $this->options , '' , 'no');
/* save parameter updates, if there are any */
if ( isset($_POST[WP_FFPC_PARAM . '-save']) )
{
$this->save_settings ();
$this->status = 1;
header("Location: admin.php?page=" . WP_FFPC_OPTIONS_PAGE . "&saved=true");
}
add_menu_page('Edit WP-FFPC options', __('WP-FFPC', WP_FFPC_PARAM ), 10, WP_FFPC_OPTIONS_PAGE , array ( $this , 'admin_panel' ) );
}
/**
* settings panel at admin section
*
*/
function admin_panel ( ) {
/**
* security
*/
if( ! function_exists( 'current_user_can' ) || ! current_user_can( 'manage_options' ) ){
die( );
}
/**
* if options were saved
*/
if ($_GET['saved']=='true' || $this->status == 1) : ?>
<div id='setting-error-settings_updated' class='updated settings-error'><p><strong>Settings saved.</strong></p></div>
<?php endif;
/**
* the admin panel itself
*/
?>
<?php if ( !WP_CACHE ) : ?>
<div class="updated settings-error"><p><strong>WARNING: WP_CACHE is disabled, plugin will not work that way. Please add define( 'WP_CACHE', true ); into the beginning of wp-config.php</strong></p></div>
<?php endif; ?>
<div class="wrap">
<h2><?php _e( 'NMC settings', WP_FFPC_PARAM ) ; ?></h2>
<form method="post" action="#">
<fieldset>
<legend><?php _e( 'Global settings', WP_FFPC_PARAM ); ?></legend>
<dl>
<div class="grid50">
<dt>
<label for="cache_type"><?php _e('Cache invalidation method', WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<select name="cache_type" id="cache_type">
<?php $this->cache_type ( $this->options['cache_type'] ) ?>
</select>
<span class="description"><?php _e('Select cache invalidation method.', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php $this->cache_type( $this->defaults['cache_type'] , true ) ; ?></span>
</dd>
<dt>
<label for="expire"><?php _e('Entry invalidation time', WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="number" name="expire" id="expire" value="<?php echo $this->options['expire']; ?>" />
<span class="description"><?php _e('How long will an entry be valid', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php echo $this->defaults['expire']; ?></span>
</dd>
<dt>
<label for="charset"><?php _e('Charset to send data with.', WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="text" name="charset" id="charset" value="<?php echo $this->options['charset']; ?>" />
<span class="description"><?php _e('Charset of HTML and XML (pages and feeds) data.', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php echo $this->defaults['charset']; ?></span>
</dd>
<dt>
<label for="invalidation_method"><?php _e('Cache invalidation method', WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<select name="invalidation_method" id="invalidation_method">
<?php $this->invalidation_method ( $this->options['invalidation_method'] ) ?>
</select>
<span class="description"><?php _e('Select cache invalidation method. <p><strong>WARNING! When selection "all", the cache will be fully flushed, including elements that were set by other applications.</strong></p>', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php $this->invalidation_method( $this->defaults['invalidation_method'] , true ) ; ?></span>
</dd>
<dt>
<label for="prefix_data"><?php _e('Data prefix', WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="text" name="prefix_data" id="prefix_data" value="<?php echo $this->options['prefix_data']; ?>" />
<span class="description"><?php _e('Prefix for HTML content keys, can be used in nginx.', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php echo $this->defaults['prefix_data']; ?></span>
</dd>
<dt>
<label for="prefix_meta"><?php _e('Meta prefix', WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="text" name="prefix_meta" id="prefix_meta" value="<?php echo $this->options['prefix_meta']; ?>" />
<span class="description"><?php _e('Prefix for meta content keys, used only with PHP processing.', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php echo $this->defaults['prefix_meta']; ?></span>
</dd>
<dt>
<label for="debug"><?php _e("Enable debug mode", WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="checkbox" name="debug" id="debug" value="1" <?php checked($this->options['debug'],true); ?> />
<span class="description"><?php _e('An additional header, "X-Cache-Engine" will be added when pages are served through WP-FFPC.', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php $this->print_bool( $this->defaults['debug']); ?></span>
</dd>
<dt>
<label for="pingback_status"><?php _e("Enable pingback links", WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="checkbox" name="pingback_status" id="pingback_status" value="1" <?php checked($this->options['pingback_status'],true); ?> />
<span class="description"><?php _e('Enable "X-Pingback" headers in cached pages; will always use accessed hostname as host!', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php $this->print_bool( $this->defaults['pingback_status']); ?></span>
</dd>
</div>
<div class="grid50">
<dt>
<label for="cache_loggedin"><?php _e('Enable cache for logged in users', WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="checkbox" name="cache_loggedin" id="cache_loggedin" value="1" <?php checked($this->options['cache_loggedin'],true); ?> />
<span class="description"><?php _e('Cache pages even if user is logged in.', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php $this->print_bool( $this->defaults['cache_loggedin']); ?></span>
</dd>
<dt>
<label for="nocache_home"><?php _e("Don't cache home", WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="checkbox" name="nocache_home" id="nocache_home" value="1" <?php checked($this->options['nocache_home'],true); ?> />
<span class="description"><?php _e('Exclude home page from caching', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php $this->print_bool( $this->defaults['nocache_home']); ?></span>
</dd>
<dt>
<label for="nocache_feed"><?php _e("Don't cache feeds", WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="checkbox" name="nocache_feed" id="nocache_feed" value="1" <?php checked($this->options['nocache_feed'],true); ?> />
<span class="description"><?php _e('Exclude feeds from caching.', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php $this->print_bool( $this->defaults['nocache_feed']); ?></span>
</dd>
<dt>
<label for="nocache_archive"><?php _e("Don't cache archives", WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="checkbox" name="nocache_archive" id="nocache_archive" value="1" <?php checked($this->options['nocache_archive'],true); ?> />
<span class="description"><?php _e('Exclude archives from caching.', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php $this->print_bool( $this->defaults['nocache_archive']); ?></span>
</dd>
<dt>
<label for="nocache_single"><?php _e("Don't cache posts (and single-type entries)", WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="checkbox" name="nocache_single" id="nocache_single" value="1" <?php checked($this->options['nocache_single'],true); ?> />
<span class="description"><?php _e('Exclude singles from caching.', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php $this->print_bool( $this->defaults['nocache_single']); ?></span>
</dd>
<dt>
<label for="nocache_page"><?php _e("Don't cache pages", WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="checkbox" name="nocache_page" id="nocache_page" value="1" <?php checked($this->options['nocache_page'],true); ?> />
<span class="description"><?php _e('Exclude pages from caching.', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php $this->print_bool( $this->defaults['nocache_page']); ?></span>
</dd>
</div>
</dl>
</fieldset>
<fieldset class="grid50">
<legend><?php _e('Settings for memcached backend', WP_FFPC_PARAM); ?></legend>
<?php if ( !class_exists('Memcache') && !class_exists('Memcached') ): ?>
<h1 class="error">No PHP memcached extension was found. To use memcached, you need PHP Memcache or PHP Memcached extension.</h1>
<?php endif; ?>
<div>
<strong><?php _e( 'Memcached server status: ', WP_FFPC_PARAM ) ; ?>
<?php
if (class_exists('Memcache'))
$server_status = wp_ffpc_init('memcache');
elseif (class_exists('Memcached'))
$server_status = wp_ffpc_init('memcached');
$server_status = ( $server_status ) ? '<span class="error-msg">down</span>' : '<span class="ok-msg">up & running</span>' ;
echo $server_status;
?>
</strong>
</div>
<dl>
<dt>
<label for="host"><?php _e('Host', WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="text" name="host" id="host" value="<?php echo $this->options['host']; ?>" />
<span class="description"><?php _e('Hostname for memcached server', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php echo $this->defaults['host']; ?></span>
</dd>
<dt>
<label for="port"><?php _e('Host', WP_FFPC_PARAM); ?></label>
</dt>
<dd>
<input type="number" name="port" id="port" value="<?php echo $this->options['port']; ?>" />
<span class="description"><?php _e('Port for memcached server', WP_FFPC_PARAM); ?></span>
<span class="default"><?php _e('Default ', WP_FFPC_PARAM); ?>: <?php echo $this->defaults['port']; ?></span>
</dd>
</dl>
</fieldset>
<?php if ( $this->options['cache_type'] == 'memcache' ) : ?>
<fieldset class="grid50">
<legend><?php _e('Sample config for nginx to utilize the data entries', WP_FFPC_PARAM); ?></legend>
<pre>location / {
try_files $uri $uri/ @memcached;
}
location @memcached {
default_type text/html;
set $memcached_key <?php echo $this->options['prefix_data'];?>$host$request_uri;
memcached_pass <?php echo $this->options['host'];?>:<?php echo $this->options['port'];?>;
error_page 404 = @rewrites;
}
location @rewrites {
rewrite ^(.*)$ /index.php?q=$1 last;
}</pre>
</fieldset>
<? endif; ?>
<p class="clearcolumns"><input class="button-primary" type="submit" name="<?php echo WP_FFPC_PARAM; ?>-save" id="<?php echo WP_FFPC_PARAM; ?>-save" value="Save Changes" /></p>
</form>
<?php
}
/**
* generates cache type select box
*
* @param $current
* the active or required size's identifier
*
* @param $returntext
* boolean: is true, the description will be returned of $current size
*
* @return
* prints either description of $current
* or option list for a <select> input field with $current set as active
*
*/
function cache_type ( $current , $returntext = false ) {
$e = array (
'apc' => 'use APC as store',
'memcache' => 'use memcached server with Memcache extension',
'memcached' => 'use memcached server with Memcached extension',
);
$this->print_select_options ( $e , $current , $returntext );
}
/**
* deactivation hook: clear advanced-cache config file
*
*/
function deactivate ( ) {
if (@file_exists (WP_FFPC_ACACHE_MAIN_FILE))
@unlink (WP_FFPC_ACACHE_MAIN_FILE);
}
/**
* invalidate cache
*/
function invalidate ( $post_id ) {
wp_ffpc_clear ( $post_id );
}
/**
* generates invalidation method select box
*
* @param $current
* the active or required size's identifier
*
* @param $returntext
* boolean: is true, the description will be returned of $current size
*
* @return
* prints either description of $current
* or option list for a <select> input field with $current set as active
*
*/
function invalidation_method ( $current , $returntext = false ) {
$e = array (
0 => 'all cached pages (WARNING! Flushes _all_ cached entrys! )',
1 => 'only modified post',
);
$this->print_select_options ( $e , $current , $returntext );
}
/**
* generates main advanced-cache system-wide config file
*
*/
function generate_config() {
$acache = WP_FFPC_ACACHE_MAIN_FILE;
/* is file currently exists, delete it*/
if ( @file_exists( $acache ))
unlink ($acache);
/* is deletion was unsuccessful, die, we have no rights to do that */
if ( @file_exists( $acache ))
return false;
$string = '<?php'. "\n" .
'global '. WP_FFPC_CONFIG_VAR .' ;' . "\n";
foreach($this->options as $key => $val) {
if (is_string($val))
$val = "'" . $val . "'";
$string .= WP_FFPC_CONFIG_VAR . '[\'' . $key . '\']=' . $val . ";\n";
}
$string .= "\n\ninclude_once ('" . WP_FFPC_ACACHE_COMMON_FILE . "');\ninclude_once ('" . WP_FFPC_ACACHE_INC_FILE . "');\n";
file_put_contents($acache, $string);
return true;
}
/**
* parameters array with default values;
*
*/
function get_options ( ) {
$defaults = array (
'port'=>11211,
'host'=>'127.0.0.1',
'expire'=>300,
'invalidation_method'=>0,
'prefix_meta' =>'meta-',
'prefix_data' =>'data-',
'charset' => 'utf-8',
'pingback_status'=> false,
'debug' => 1,
'cache_type' => 'memcache',
'cache_loggedin' => false,
'nocache_home' => false,
'nocache_feed' => false,
'nocache_archive' => false,
'nocache_single' => false,
'nocache_page' => false,
);
$this->defaults = $defaults;
$this->options = get_site_option( WP_FFPC_PARAM , $defaults, false );
}
/**
* prints `true` or `false` depending on a bool variable.
*
* @param $val
* The boolen variable to print status of.
*
*/
function print_bool ( $val ) {
$bool = $val? 'true' : 'false';
echo $bool;
}
/**
* select field processor
*
* @param sizes
* array to build <option> values of
*
* @param $current
* the current resize type
*
* @param $returntext
* boolean: is true, the description will be returned of $current type
*
* @return
* prints either description of $current
* or option list for a <select> input field with $current set as active
*
*/
function print_select_options ( $sizes, $current, $returntext=false ) {
if ( $returntext )
{
_e( $sizes[ $current ] , WP_FFPC_PARAM);
return;
}
foreach ($sizes as $ext=>$name)
{
?>
<option value="<?php echo $ext ?>" <?php selected( $ext , $current ); ?>>
<?php _e( $name , WP_FFPC_PARAM); ?>
</option>
<?php
}
}
/**
* function to be able to store redirects
*/
function redirect_canonical($redirect_url, $requested_url) {
global $wp_nmc_redirect;
$wp_nmc_redirect = $redirect_url;
return $redirect_url;
}
/**
* save settings function
*
*/
function save_settings ( $firstrun = false ) {
/**
* update params from $_POST
*/
foreach ($this->options as $name=>$optionvalue)
{
if (!empty($_POST[$name]))
{
$update = $_POST[$name];
if (strlen($update)!=0 && !is_numeric($update))
$update = stripslashes($update);
}
elseif ( ( empty($_POST[$name]) && is_bool ($this->defaults[$name]) ) || is_numeric( $update ) )
{
$update = 0;
}
else
{
$update = $this->defaults[$name];
}
$this->options[$name] = $update;
}
update_site_option( WP_FFPC_PARAM , $this->options );
if ( ! $firstrun )
$this->generate_config();
}
/**
* clean up at uninstall
*
*/
function uninstall ( ) {
delete_site_option( WP_FFPC_PARAM );
}
}
}
/**
* instantiate the class
*/
$wp_nmc = new WPFFPC();
?>