precache cron; utilities, etc

This commit is contained in:
Peter Molnar 2013-06-07 17:56:56 +01:00
parent 8ec2ebf569
commit 0c368e2bb9
7 changed files with 275 additions and 219 deletions

View file

@ -1,10 +1,10 @@
=== WP-FFPC ===
Contributors: cadeyrn
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=XU3DG7LLA76WC
Tags: cache, page cache, full page cache, nginx, memcached, apc, speed, fast
Tags: cache, page cache, full page cache, nginx, memcached, apc, speed
Requires at least: 3.0
Tested up to: 3.5.1
Stable tag: 1.1.1
Stable tag: 1.2
License: GPLv3
License URI: http://www.gnu.org/licenses/gpl-3.0.html
@ -54,6 +54,7 @@ You have to remove the default yum package, named `php-pecl-memcache` and instal
From version 1.0, the plugin supports subdomain based WordPress Network with possible different per site cache settings. If the plugin is network active, obviously the network wide settings will be used for all of the sites. If it's activated only on some of the sites, the other will not be affected and even the cache storage backend can be different from site to site.
= What are the plugin's requirements? =
* WordPress >= 3.0
and **at least one** of the following for storage backend:
@ -74,7 +75,6 @@ In order to make contributions a lot easier, I've moved the plugin development t
I provide support for the plugin as best as I can, but it comes without guarantee.
Please post feature requests to [WP-FFPC feature request topic](http://wordpress.org/support/topic/feature-requests-14 "WP-FFPC feature request topic") and any questions on the forum.
== Screenshots ==
1. settings screen, cache type and basic settings
@ -85,6 +85,23 @@ Please post feature requests to [WP-FFPC feature request topic](http://wordpress
== Changelog ==
= 1.2 =
*TBA*
What's new:
* additional cookie patterns to exclude visitors from cache
* syslog dropped; using standard PHP log instead, combined with WP_DEBUG to change to info/notice level
* possibility to start pre-cache from wp-cron
What's fixed:
* WordPress has changed in cookie naming, plugin & nginx example has been updated
**Dropped functions**
* there's no info log on/off anymore, it's triggered when WP_DEBUG is active
= 1.1.1 =
*2013.04.25*

@ -1 +1 @@
Subproject commit 8ddaed268614d2826fb74d22033302c6df231ca3
Subproject commit c862af55f464e366dd6f44d20dcf709d0b5bbe51

View file

@ -52,25 +52,12 @@ elseif ( !empty ( $wp_ffpc_config[ $_SERVER['HTTP_HOST'] ] ) )
else
return false;
/* no cache for for logged in users normally, only if enabled */
if ( $wp_ffpc_config['cache_loggedin'] == 0 || $wp_ffpc_config['nocache_cookies'] ) {
if ( isset($wp_ffpc_config['nocache_cookies']) && !empty($wp_ffpc_config['nocache_cookies']) ) {
$nocache_cookies = array_map('trim',explode(",", $wp_ffpc_config['nocache_cookies'] ) );
$nocache_cookies = array();
if( $wp_ffpc_config['nocache_cookies'] ){
$nocache_cookies = array_map('trim',explode(",", $wp_ffpc_config['nocache_cookies'] ) );
}
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 ( $wp_ffpc_config['cache_loggedin'] == 0 ) {
if ( (substr($n, 0, 14) == 'wordpressuser_' || substr($n, 0, 10) == 'wordpress_' || substr($n, 0, 12) == 'wp-postpass_') && !$wp_ffpc_config['cache_loggedin'] ) {
return false;
}
}
/* check for any matches to user-added cookies to no-cache */
if ( ! empty( $nocache_cookies ) ){
if ( !empty( $nocache_cookies ) ) {
foreach ($_COOKIE as $n=>$v) {
/* check for any matches to user-added cookies to no-cache */
foreach ( $nocache_cookies as $nocache_cookie ) {
if( strpos( $n, $nocache_cookie ) === 0 ) {
return false;
@ -80,13 +67,27 @@ if ( $wp_ffpc_config['cache_loggedin'] == 0 || $wp_ffpc_config['nocache_cookie
}
}
/* canonical redirect storage */
$wp_ffpc_redirect = null;
/* fires up the backend storage array with current config */
$wp_ffpc_backend = new WP_FFPC_Backend( $wp_ffpc_config );
/* 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;
}
}
}
}
/* will store time of page generation */
$wp_ffpc_gentime = 0;
@ -244,7 +245,7 @@ function wp_ffpc_callback( $buffer ) {
/* check if caching is disabled for page type */
$nocache_key = 'nocache_'. $meta['type'];
/* don't cache if prevented by rule, also, log it */
/* don't cache if prevented by rule */
if ( $wp_ffpc_config[ $nocache_key ] == 1 ) {
return $buffer;
}

View file

@ -10,6 +10,11 @@
*/
if (!class_exists('WP_FFPC_Backend')) {
/* get the plugin abstract class*/
include_once ( 'wp-common/wp-plugin-utilities.php');
/* __ only availabe if we're running from the inside of wordpress, not in advanced-cache.php phase */
if ( function_exists ( '__' ) ) {
function __translate__ ( $text, $domain ) { return __($text, $domain); }
@ -18,7 +23,6 @@ if (!class_exists('WP_FFPC_Backend')) {
function __translate__ ( $text, $domain ) { return $text; }
}
/**
*
* @var mixed $connection Backend object storage variable
@ -29,16 +33,18 @@ if (!class_exists('WP_FFPC_Backend')) {
*/
class WP_FFPC_Backend {
const plugin_constant = 'wp-ffpc';
const network_key = 'network';
const host_separator = ',';
const port_separator = ':';
private $plugin_constant = 'wp-ffpc';
private $connection = NULL;
private $alive = false;
private $network = false;
private $options = array();
private $status = array();
public $cookies = array();
private $utilities;
/**
* constructor
@ -51,6 +57,10 @@ if (!class_exists('WP_FFPC_Backend')) {
$this->options = $config;
$this->network = $network;
$this->cookies = array ( 'comment_author_' , 'wordpressuser_' , 'wp-postpass_', 'wordpress_logged_in_' );
$this->utilities = WP_Plugins_Utilities::Utility();
/* no config, nothing is going to work */
if ( empty ( $this->options ) ) {
return false;
@ -62,7 +72,7 @@ if (!class_exists('WP_FFPC_Backend')) {
/* call backend initiator based on cache type */
$init = $this->proxy( 'init' );
$this->log ( __translate__('init starting', self::plugin_constant ));
$this->log ( __translate__('init starting', $this->plugin_constant ));
$this->$init();
}
@ -100,14 +110,14 @@ if (!class_exists('WP_FFPC_Backend')) {
return false;
/* log the current action */
$this->log ( __translate__('get ', self::plugin_constant ). $key );
$this->log ( __translate__('get ', $this->plugin_constant ). $key );
/* proxy to internal function */
$internal = $this->proxy( 'get' );
$result = $this->$internal( $key );
if ( $result === false )
$this->log ( __translate__( "failed to get entry: ", self::plugin_constant ) . $key );
$this->log ( __translate__( "failed to get entry: ", $this->plugin_constant ) . $key );
return $result;
}
@ -127,7 +137,7 @@ if (!class_exists('WP_FFPC_Backend')) {
return false;
/* log the current action */
$this->log( __translate__('set ', self::plugin_constant ) . $key . __translate__(' expiration time: ', self::plugin_constant ) . $this->options['expire']);
$this->log( __translate__('set ', $this->plugin_constant ) . $key . __translate__(' expiration time: ', $this->plugin_constant ) . $this->options['expire']);
/* proxy to internal function */
$internal = $this->options['cache_type'] . '_set';
@ -135,7 +145,7 @@ if (!class_exists('WP_FFPC_Backend')) {
/* check result validity */
if ( $result === false )
$this->log ( __translate__('failed to set entry: ', self::plugin_constant ) . $key, LOG_WARNING );
$this->log ( __translate__('failed to set entry: ', $this->plugin_constant ) . $key, LOG_WARNING );
return $result;
}
@ -153,21 +163,21 @@ if (!class_exists('WP_FFPC_Backend')) {
/* exit if no post_id is specified */
if ( empty ( $post_id ) && $force === false ) {
$this->log ( __translate__('not clearing unidentified post ', self::plugin_constant ), LOG_WARNING );
$this->log ( __translate__('not clearing unidentified post ', $this->plugin_constant ), LOG_WARNING );
return false;
}
/* if invalidation method is set to full, flush cache */
if ( $this->options['invalidation_method'] === 0 || $force === true ) {
/* log action */
$this->log ( __translate__('flushing cache', self::plugin_constant ) );
$this->log ( __translate__('flushing cache', $this->plugin_constant ) );
/* proxy to internal function */
$internal = $this->proxy ( 'flush' );
$result = $this->$internal();
if ( $result === false )
$this->log ( __translate__('failed to flush cache', self::plugin_constant ), LOG_WARNING );
$this->log ( __translate__('failed to flush cache', $this->plugin_constant ), LOG_WARNING );
return $result;
}
@ -193,7 +203,7 @@ if (!class_exists('WP_FFPC_Backend')) {
/* no path, don't do anything */
if ( empty( $path ) ) {
$this->log ( __translate__('unable to determine path from Post Permalink, post ID: ', self::plugin_constant ) . $post_id , LOG_WARNING );
$this->log ( __translate__('unable to determine path from Post Permalink, post ID: ', $this->plugin_constant ) . $post_id , LOG_WARNING );
return false;
}
@ -325,7 +335,7 @@ if (!class_exists('WP_FFPC_Backend')) {
*/
private function is_alive() {
if ( ! $this->alive ) {
$this->log ( __translate__("backend is not active, exiting function ", self::plugin_constant ) . __FUNCTION__, LOG_WARNING );
$this->log ( __translate__("backend is not active, exiting function ", $this->plugin_constant ) . __FUNCTION__, LOG_WARNING );
return false;
}
@ -371,36 +381,14 @@ if (!class_exists('WP_FFPC_Backend')) {
}
/**
* sends message to sysog
*
* @param mixed $message message to add besides basic info
* log wrapper to include options
*
*/
private function log ( $message, $log_level = LOG_WARNING ) {
if ( @is_array( $message ) || @is_object ( $message ) )
$message = serialize($message);
if ( !isset ( $this->options['log'] ) || $this->options['log'] != 1 )
return false;
switch ( $log_level ) {
case LOG_ERR :
if ( function_exists( 'syslog' ) && function_exists ( 'openlog' ) ) {
openlog('wordpress('.$_SERVER['HTTP_HOST'].')',LOG_NDELAY|LOG_PERROR,LOG_SYSLOG);
syslog( $log_level , self::plugin_constant . $message );
}
/* error level is real problem, needs to be displayed on the admin panel */
//throw new Exception ( $message );
break;
default:
if ( function_exists( 'syslog' ) && function_exists ( 'openlog' ) && isset( $this->options['log_info'] ) && $this->options['log_info'] == 1 ) {
openlog('wordpress(' .$_SERVER['HTTP_HOST']. ')', LOG_NDELAY,LOG_SYSLOG);
syslog( $log_level, self::plugin_constant . " " . $message );
}
break;
}
else
$this->utilities->log ( $this->plugin_constant , $message, $log_level );
}
/*********************** END PUBLIC FUNCTIONS ***********************/
@ -411,13 +399,13 @@ if (!class_exists('WP_FFPC_Backend')) {
private function apc_init () {
/* verify apc functions exist, apc extension is loaded */
if ( ! function_exists( 'apc_sma_info' ) ) {
$this->log ( __translate__('APC extension missing', self::plugin_constant ) );
$this->log ( __translate__('APC extension missing', $this->plugin_constant ) );
return false;
}
/* verify apc is working */
if ( apc_sma_info() ) {
$this->log ( __translate__('backend OK', self::plugin_constant ) );
$this->log ( __translate__('backend OK', $this->plugin_constant ) );
$this->alive = true;
}
}
@ -480,11 +468,11 @@ if (!class_exists('WP_FFPC_Backend')) {
foreach ( $keys as $key => $dummy ) {
if ( ! apc_delete ( $key ) ) {
$this->log ( __translate__('Failed to delete APC entry: ', self::plugin_constant ) . $key, LOG_ERR );
//throw new Exception ( __translate__('Deleting APC entry failed with key ', self::plugin_constant ) . $key );
$this->log ( __translate__('Failed to delete APC entry: ', $this->plugin_constant ) . $key, LOG_ERR );
//throw new Exception ( __translate__('Deleting APC entry failed with key ', $this->plugin_constant ) . $key );
}
else {
$this->log ( __translate__( 'APC entry delete: ', self::plugin_constant ) . $key );
$this->log ( __translate__( 'APC entry delete: ', $this->plugin_constant ) . $key );
}
}
}
@ -498,13 +486,13 @@ if (!class_exists('WP_FFPC_Backend')) {
private function memcached_init () {
/* Memcached class does not exist, Memcached extension is not available */
if (!class_exists('Memcached')) {
$this->log ( __translate__(' Memcached extension missing', self::plugin_constant ), LOG_ERR );
$this->log ( __translate__(' Memcached extension missing', $this->plugin_constant ), LOG_ERR );
return false;
}
/* check for existing server list, otherwise we cannot add backends */
if ( empty ( $this->options['servers'] ) && ! $this->alive ) {
$this->log ( __translate__("Memcached servers list is empty, init failed", self::plugin_constant ), LOG_WARNING );
$this->log ( __translate__("Memcached servers list is empty, init failed", $this->plugin_constant ), LOG_WARNING );
return false;
}
@ -512,7 +500,7 @@ if (!class_exists('WP_FFPC_Backend')) {
if ( $this->connection === NULL ) {
/* persistent backend needs an identifier */
if ( $this->options['persistent'] == '1' )
$this->connection = new Memcached( self::plugin_constant );
$this->connection = new Memcached( $this->plugin_constant );
else
$this->connection = new Memcached();
@ -523,7 +511,7 @@ if (!class_exists('WP_FFPC_Backend')) {
/* check if initialization was success or not */
if ( $this->connection === NULL ) {
$this->log ( __translate__( 'error initializing Memcached PHP extension, exiting', self::plugin_constant ) );
$this->log ( __translate__( 'error initializing Memcached PHP extension, exiting', $this->plugin_constant ) );
return false;
}
@ -548,7 +536,7 @@ if (!class_exists('WP_FFPC_Backend')) {
/* only add servers that does not exists already in connection pool */
if ( !@array_key_exists($server_id , $servers_alive ) ) {
$this->connection->addServer( $server['host'], $server['port'] );
$this->log ( $server_id . __translate__(" added, persistent mode: ", self::plugin_constant ) . $this->options['persistent'] );
$this->log ( $server_id . __translate__(" added, persistent mode: ", $this->plugin_constant ) . $this->options['persistent'] );
}
}
@ -563,7 +551,7 @@ if (!class_exists('WP_FFPC_Backend')) {
*/
private function memcached_status () {
/* server status will be calculated by getting server stats */
$this->log ( __translate__("checking server statuses", self::plugin_constant ));
$this->log ( __translate__("checking server statuses", $this->plugin_constant ));
/* get servers statistic from connection */
$report = $this->connection->getStats();
@ -572,7 +560,7 @@ if (!class_exists('WP_FFPC_Backend')) {
$this->status[$server_id] = 0;
/* if server uptime is not empty, it's most probably up & running */
if ( !empty($details['uptime']) ) {
$this->log ( $server_id . __translate__(" server is up & running", self::plugin_constant ));
$this->log ( $server_id . __translate__(" server is up & running", $this->plugin_constant ));
$this->status[$server_id] = 1;
}
}
@ -602,8 +590,8 @@ if (!class_exists('WP_FFPC_Backend')) {
/* if storing failed, log the error code */
if ( $result === false ) {
$code = $this->connection->getResultCode();
$this->log ( __translate__('unable to set entry ', self::plugin_constant ) . $key . __translate__( ', Memcached error code: ', self::plugin_constant ) . $code );
//throw new Exception ( __translate__('Unable to store Memcached entry ', self::plugin_constant ) . $key . __translate__( ', error code: ', self::plugin_constant ) . $code );
$this->log ( __translate__('unable to set entry ', $this->plugin_constant ) . $key . __translate__( ', Memcached error code: ', $this->plugin_constant ) . $code );
//throw new Exception ( __translate__('Unable to store Memcached entry ', $this->plugin_constant ) . $key . __translate__( ', error code: ', $this->plugin_constant ) . $code );
}
return $result;
@ -634,10 +622,10 @@ if (!class_exists('WP_FFPC_Backend')) {
if ( $kresult === false ) {
$code = $this->connection->getResultCode();
$this->log ( __translate__('unable to delete entry ', self::plugin_constant ) . $key . __translate__( ', Memcached error code: ', self::plugin_constant ) . $code );
$this->log ( __translate__('unable to delete entry ', $this->plugin_constant ) . $key . __translate__( ', Memcached error code: ', $this->plugin_constant ) . $code );
}
else {
$this->log ( __translate__( 'entry deleted: ', self::plugin_constant ) . $key );
$this->log ( __translate__( 'entry deleted: ', $this->plugin_constant ) . $key );
}
}
}
@ -650,13 +638,13 @@ if (!class_exists('WP_FFPC_Backend')) {
private function memcache_init () {
/* Memcached class does not exist, Memcache extension is not available */
if (!class_exists('Memcache')) {
$this->log ( __translate__('PHP Memcache extension missing', self::plugin_constant ), LOG_ERR );
$this->log ( __translate__('PHP Memcache extension missing', $this->plugin_constant ), LOG_ERR );
return false;
}
/* check for existing server list, otherwise we cannot add backends */
if ( empty ( $this->options['servers'] ) && ! $this->alive ) {
$this->log ( __translate__("servers list is empty, init failed", self::plugin_constant ), LOG_WARNING );
$this->log ( __translate__("servers list is empty, init failed", $this->plugin_constant ), LOG_WARNING );
return false;
}
@ -666,7 +654,7 @@ if (!class_exists('WP_FFPC_Backend')) {
/* check if initialization was success or not */
if ( $this->connection === NULL ) {
$this->log ( __translate__( 'error initializing Memcache PHP extension, exiting', self::plugin_constant ) );
$this->log ( __translate__( 'error initializing Memcache PHP extension, exiting', $this->plugin_constant ) );
return false;
}
@ -678,7 +666,7 @@ if (!class_exists('WP_FFPC_Backend')) {
else
$this->status[$server_id] = $this->connection->connect ( $server['host'] , $server['port'] );
$this->log ( $server_id . __translate__(" added, persistent mode: ", self::plugin_constant ) . $this->options['persistent'] );
$this->log ( $server_id . __translate__(" added, persistent mode: ", $this->plugin_constant ) . $this->options['persistent'] );
}
/* backend is now alive */
@ -692,14 +680,14 @@ if (!class_exists('WP_FFPC_Backend')) {
*/
private function memcache_status () {
/* server status will be calculated by getting server stats */
$this->log ( __translate__("checking server statuses", self::plugin_constant ));
$this->log ( __translate__("checking server statuses", $this->plugin_constant ));
/* get servers statistic from connection */
foreach ( $this->options['servers'] as $server_id => $server ) {
$this->status[$server_id] = $this->connection->getServerStatus( $server['host'], $server['port'] );
if ( $this->status[$server_id] == 0 )
$this->log ( $server_id . __translate__(" server is down", self::plugin_constant ));
$this->log ( $server_id . __translate__(" server is down", $this->plugin_constant ));
else
$this->log ( $server_id . __translate__(" server is up & running", self::plugin_constant ));
$this->log ( $server_id . __translate__(" server is up & running", $this->plugin_constant ));
}
}
@ -748,10 +736,10 @@ if (!class_exists('WP_FFPC_Backend')) {
$kresult = $this->connection->delete( $key );
if ( $kresult === false ) {
$this->log ( __translate__('unable to delete entry ', self::plugin_constant ) . $key );
$this->log ( __translate__('unable to delete entry ', $this->plugin_constant ) . $key );
}
else {
$this->log ( __translate__( 'entry deleted: ', self::plugin_constant ) . $key );
$this->log ( __translate__( 'entry deleted: ', $this->plugin_constant ) . $key );
}
}
}

View file

@ -12,9 +12,9 @@
if ( ! class_exists( 'WP_FFPC' ) ) {
/* get the plugin abstract class*/
include_once ( 'common/wp-plugin-abstract.phpp');
include_once ( 'wp-common/wp-plugin-abstract.php' );
/* get the common functions class*/
include_once ( 'wp-ffpc-backend.php');
include_once ( 'wp-ffpc-backend.php' );
/**
* main wp-ffpc class
@ -42,8 +42,13 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
const slug_precache = '&precached=true';
const key_precache_disabled = 'precache_disabled';
const slug_precache_disabled = '&precache_disabled=true';
const precache_log = 'wp-ffpc-precache.log';
const precache_log = 'wp-ffpc-precache-log';
const precache_timestamp = 'wp-ffpc-precache-timestamp';
const precache_php = 'wp-ffpc-precache.php';
const precache_id = 'wp-ffpc-precache-task';
private $precache_message = '';
private $precache_logfile = '';
private $precache_phpfile = '';
private $global_option = '';
private $global_config_key = '';
private $global_config = array();
@ -56,11 +61,13 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
private $button_precache;
protected $select_cache_type = array ();
protected $select_invalidation_method = array ();
protected $select_schedules = array();
protected $valid_cache_type = array ();
private $precache_logfile = '';
private $shell_function = false;
private $shell_possibilities = array ();
private $backend = NULL;
private $scheduled = false;
/**
* init hook function runs before admin panel hook, themeing and options read
@ -82,8 +89,11 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
$this->global_option = $this->plugin_constant . '-global';
/* precache log */
$this->precache_logfile = sys_get_temp_dir() . '/' . self::precache_log;
/* this is the precacher php worker file */
$this->precache_phpfile = sys_get_temp_dir() . '/' . self::precache_php;
/* search for a system function */
$this->shell_possibilities = array ( 'shell_exec', 'exec', 'system', 'passthru' );
//$this->shell_possibilities = array ( 'shell_exec' );
$disabled_functions = array_map('trim', explode(',', ini_get('disable_functions') ) );
foreach ( $this->shell_possibilities as $possible ) {
@ -120,6 +130,14 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
2 => __( 'modified post and all taxonomies' , $this->plugin_constant ),
);
$wp_schedules = wp_get_schedules();
$schedules['null'] = __( 'do not use timed precache' );
foreach ( $wp_schedules as $interval=>$details ) {
$schedules[ $interval ] = $details['display'];
}
$this->select_schedules = $schedules;
}
/**
@ -151,6 +169,16 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
/* add filter for catching canonical redirects */
add_filter('redirect_canonical', 'wp_ffpc_redirect_callback', 10, 2);
if ( !wp_next_scheduled( self::precache_id ) && $this->options['precache_schedule'] != 'null' && $this->scheduled === false ) {
$this->scheduled = wp_schedule_event( time(), $this->options['precache_schedule'] , self::precache_id );
}
else {
wp_clear_scheduled_hook ( self::precache_id );
}
/* add precache coldrun action */
add_action( self::precache_id , array( &$this, 'precache_coldrun' ) );
}
/**
@ -171,7 +199,7 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
/**
* uninstall hook function, to be extended
*/
public function plugin_uninstall( $delete_options = true ) {
static public function plugin_uninstall( $delete_options = true ) {
/* delete advanced-cache.php file */
unlink ( $this->acache );
@ -188,6 +216,16 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
public function plugin_hook_admin_init () {
/* save parameter updates, if there are any */
if ( isset( $_POST[ $this->button_flush ] ) ) {
update_option( self::precache_log , '' );
update_option( self::precache_timestamp , '' );
if ( @file_exists ( $this->precache_logfile ) )
unlink ( $this->precache_logfile );
if ( @file_exists ( $this->precache_phpfile ) )
unlink ( $this->precache_phpfile );
$this->backend->clear( false, true );
$this->status = 3;
header( "Location: ". $this->settings_link . self::slug_flush );
@ -201,7 +239,7 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
header( "Location: ". $this->settings_link . self::slug_precache_disabled );
}
else {
$this->precache_message = $this->precache();
$this->precache_message = $this->precache_coldrun();
$this->status = 4;
header( "Location: ". $this->settings_link . self::slug_precache );
}
@ -344,7 +382,7 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
<li><a href="#<?php echo $this->plugin_constant ?>-exceptions" class="wp-switch-editor"><?php _e( 'Cache exceptions', $this->plugin_constant ); ?></a></li>
<li><a href="#<?php echo $this->plugin_constant ?>-memcached" class="wp-switch-editor"><?php _e( 'Memcache(d)', $this->plugin_constant ); ?></a></li>
<li><a href="#<?php echo $this->plugin_constant ?>-nginx" class="wp-switch-editor"><?php _e( 'nginx', $this->plugin_constant ); ?></a></li>
<li><a href="#<?php echo $this->plugin_constant ?>-precachelog" class="wp-switch-editor"><?php _e( 'Precache log', $this->plugin_constant ); ?></a></li>
<li><a href="#<?php echo $this->plugin_constant ?>-precache" class="wp-switch-editor"><?php _e( 'Precache & precache log', $this->plugin_constant ); ?></a></li>
</ul>
<fieldset id="<?php echo $this->plugin_constant ?>-type">
@ -415,14 +453,6 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
<span class="description"><?php _e('Enables ERROR and WARNING level syslog messages. Requires PHP syslog function.', $this->plugin_constant); ?></span>
</dd>
<dt>
<label for="log_info"><?php _e("Enable information log", $this->plugin_constant); ?></label>
</dt>
<dd>
<input type="checkbox" name="log_info" id="log_info" value="1" <?php checked($this->options['log_info'],true); ?> />
<span class="description"><?php _e('Enables INFO level messages; careful, plugin is really talkative. Requires PHP syslog function.', $this->plugin_constant); ?></span>
</dd>
<dt>
<label for="response_header"><?php _e("Add X-Cache-Engine header", $this->plugin_constant); ?></label>
</dt>
@ -537,39 +567,59 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
<pre><?php echo $this->nginx_example(); ?></pre>
</fieldset>
<fieldset id="<?php echo $this->plugin_constant ?>-precachelog">
<legend><?php _e('Log from previous pre-cache generation', $this->plugin_constant); ?></legend>
<fieldset id="<?php echo $this->plugin_constant ?>-precache">
<legend><?php _e('Precache settings & log from previous pre-cache generation', $this->plugin_constant); ?></legend>
<dt>
<label for="precache_schedule"><?php _e('Precache schedule', $this->plugin_constant); ?></label>
</dt>
<dd>
<select name="precache_schedule" id="precache_schedule">
<?php $this->print_select_options ( $this->select_schedules, $this->options['precache_schedule'] ) ?>
</select>
<span class="description"><?php _e('Schedule autorun for precache with WP-Cron', $this->plugin_constant); ?></span>
</dd>
<?php
if ( @file_exists ( $this->precache_logfile ) ) :
$log = file ( $this->precache_logfile );
$head = explode( "\t", array_shift( $log ));
$gentime = filemtime ( $this->precache_logfile );
?>
<p><strong><?php _e( 'Time of run: ') ?><?php echo date('r', $gentime ); ?></strong></p>
<table style="width:100%; border: 1px solid #ccc;">
<thead><tr>
<th style="width:70%;"><?php echo $head[0]; ?></th>
<th style="width:15%;"><?php echo $head[1]; ?></th>
<th style="width:15%;"><?php echo $head[2]; ?></th>
</tr></thead>
<?php
foreach ( $log as $line ) :
$line = explode ( "\t", $line );
?>
<tr>
<td><?php echo $line[0]; ?></td>
<td><?php echo $line[1]; ?></td>
<td><?php echo $line[2]; ?></td>
</tr>
<?php
endforeach;
?>
</table>
<?php
else :
$gentime = $this->_get_option( self::precache_timestamp );
$log = $this->_get_option( self::precache_log );
if ( @file_exists ( $this->precache_logfile ) ) {
$logtime = filemtime ( $this->precache_logfile );
/* update precache log in DB if needed */
if ( $logtime > $gentime ) {
$log = file ( $this->precache_logfile );
$this->_update_option( self::precache_log , $log );
$this->_update_option( self::precache_timestamp , $logtime );
}
}
if ( empty ( $log ) ) {
_e('No precache log was found!', $this->plugin_constant);
endif;
?></pre>
}
else { ?>
<p><strong><?php _e( 'Time of run: ') ?><?php echo date('r', $gentime ); ?></strong></p>
<table style="width:100%; border: 1px solid #ccc;">
<thead><tr>
<?php $head = explode( " ", array_shift( $log ));
foreach ( $head as $column ) { ?>
<th><?php echo $column; ?></th>
<?php } ?>
</tr></thead>
<?php
foreach ( $log as $line ) { ?>
<tr>
<?php $line = explode ( " ", $line );
foreach ( $line as $column ) { ?>
<td><?php echo $column; ?></td>
<?php } ?>
</tr>
<?php } ?>
</table>
<?php } ?>
</fieldset>
<p class="clear">
@ -766,12 +816,6 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
/* read the sample file */
$nginx = file_get_contents ( $this->nginx_sample );
/* this part is not used when the cache is turned on for logged in users */
$loggedin = '# avoid cache for logged in users
if ($http_cookie ~* "comment_author_|wordpressuser_|wp-postpass_" ) {
set $memcached_request 0;
}';
/* replace the data prefix with the configured one */
$to_replace = array ( 'DATAPREFIX' , 'SERVERROOT', 'SERVERLOG' );
$replace_with = array ( $this->options['prefix_data'], ABSPATH, $_SERVER['SERVER_NAME'] );
@ -785,6 +829,13 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
}
$nginx = str_replace ( 'MEMCACHED_SERVERS' , $nginx_servers , $nginx );
$loggedincookies = join('|', $this->backend->cookies );
/* this part is not used when the cache is turned on for logged in users */
$loggedin = '
if ($http_cookie ~* "'. $loggedincookies .'" ) {
set $memcached_request 0;
}';
/* add logged in cache, if valid */
if ( ! $this->options['cache_loggedin'])
$nginx = str_replace ( 'LOGGEDIN_EXCEPTION' , $loggedin , $nginx );
@ -838,22 +889,89 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
update_site_option( $this->global_option , $this->global_config );
}
/**
* generate cache entry for every available permalink, might be very-very slow,
* therefore it starts a background process
*
*/
private function precache () {
private function precache ( &$links ) {
/* double check if we do have any links to pre-cache */
if ( !empty ( $links ) && !$this->precache_running() ) {
$out = '<?php
$links = ' . var_export ( $links , true ) . ';
echo "permalink\tgeneration time (s)\tsize ( kbyte )\n";
foreach ( $links as $permalink => $dummy ) {
$starttime = explode ( " ", microtime() );
$starttime = $starttime[1] + $starttime[0];
$page = file_get_contents( $permalink );
$size = round ( ( strlen ( $page ) / 1024 ), 3 );
$endtime = explode ( " ", microtime() );
$endtime = ( $endtime[1] + $endtime[0] ) - $starttime;
echo $permalink . "\t" . $endtime . "\t" . $size . "\n";
unset ( $page, $size, $starttime, $endtime );
sleep( 1 );
}
unlink ( "'. $this->precache_phpfile .'" );
?>';
file_put_contents ( $this->precache_phpfile, $out );
/* call the precache worker file in the background */
$shellfunction = $this->shell_function;
$shellfunction( 'php '. $this->precache_phpfile .' >'. $this->precache_logfile .' 2>&1 &' );
}
}
/**
* check is precache is still ongoing
*
*/
private function precache_running () {
$return = false;
/* if the precache file exists, it did not finish running as it should delete itself on finish */
if ( file_exists ( $this->precache_phpfile )) {
$return = true;
}
// TODO: cross-platform process check; this is *nix only
//else {
// /* otherwise try to check if precache is running; */
// $shellfunction = $this->shell_function;
// $running = $shellfunction( "ps aux | grep \"". $this->precache_phpfile ."\" | grep -v grep | awk '{print $2}'" );
// if ( is_int( $running ) && $running != 0 ) {
// $return = true;
// }
//}
return $return;
}
/**
* run full-site precache
*/
public function precache_coldrun () {
/* container for links to precache, well be accessed by reference */
$links = array();
/* when plugin is network wide active, we need to pre-cache for all link of all blogs */
if ( $this->network ) {
/* list all blogs */
$blog_list = get_blog_list( 0, 'all' );
global $wpdb;
$blog_list = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM wp_blogs ORDER BY blog_id", '' ) );
foreach ($blog_list as $blog) {
/* get permalinks for this blog */
$this->precache_list_permalinks ( $links, $blog['blog_id'] );
if ( $blog->archived != 1 && $blog->spam != 1 && $blog->deleted != 1) {
/* get permalinks for this blog */
$this->precache_list_permalinks ( $links, $blog->blog_id );
}
}
}
else {
@ -861,45 +979,12 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
$this->precache_list_permalinks ( $links, false );
}
/* temporary php file, will destroy itself after finish in order to clean up */
$tmpfile = tempnam(sys_get_temp_dir(), 'wp-ffpc');
/* double check if we do have any links to pre-cache */
if ( !empty ( $links ) ) :
/* this is the precacher php worker file: logs the links, their generation time and the generated content size
* writes the logfile and destroys itself afterwards
*/
$out .= '<?php
$links = ' . var_export ( $links , true ) . ';
echo "permalink\tgeneration time (s)\tsize ( kbyte )\n";
foreach ( $links as $permalink => $dummy ) {
$starttime = explode ( " ", microtime() );
$starttime = $starttime[1] + $starttime[0];
$page = file_get_contents( $permalink );
$size = round ( ( strlen ( $page ) / 1024 ), 3 );
$endtime = explode ( " ", microtime() );
$endtime = ( $endtime[1] + $endtime[0] ) - $starttime;
echo $permalink . "\t" . $endtime . "\t" . $size . "\n";
unset ( $page, $size, $starttime, $endtime );
sleep( 1 );
}
unlink ( "'. $tmpfile .'" );
?>';
file_put_contents ( $tmpfile, $out );
/* call the precache worker file in the background */
$shellfunction = $this->shell_function;
$shellfunction( 'php '. $tmpfile .' >'. $this->precache_logfile .' 2>&1 &' );
endif;
if ( !empty ( $links ) ) {
$this->precache ( $links );
}
}
/**
* gets all post-like entry permalinks for a site, returns values in passed-by-reference array
*
@ -921,7 +1006,6 @@ if ( ! class_exists( 'WP_FFPC' ) ) {
$links[ $url ] = true;
}
/* get all published posts */
$args = array (
'post_type' => 'any',

View file

@ -25,40 +25,6 @@ MEMCACHED_SERVERS
access_log /var/log/nginx/SERVERLOG.access.log;
error_log /var/log/nginx/SERVERLOG.error.log;
# a bit of security; uncomment if you're using any WAF
## Block SQL injections
location ~union.*select.*\( { deny all; }
location ~union.*all.*select.* { deny all; }
location ~concat.*\( { deny all; }
## Block common exploits
location ~ (<|%3C).*script.*(>|%3E) { deny all; }
location ~ base64_(en|de)code\(.*\) { deny all; }
location ~ (\[|\]|\(|\)|<|>|ê|"|\;) { deny all; }
location ~ (%24&x) { deny all; }
location ~ (%0|%A|%B|%C|%D|%E|%F|127\.0) { deny all; }
location ~ \.\.\/ { deny all; }
location ~ ~$ { deny all; }
location ~ proc/self/environ { deny all; }
location ~ /\.(htaccess|htpasswd) { log_not_found off; deny all; }
## Block file injections
location ~ [a-zA-Z0-9_]=http:// { deny all; }
location ~ [a-zA-Z0-9_]=(\.\.//?)+ { deny all; }
location ~ [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ { deny all; }
## wordpress security
location ~* wp-config.php { deny all; }
location ~* wp-admin/includes { deny all; }
location ~* wp-app\.log { deny all; }
location ~ (licence|readme|license)\.(html|txt) { deny all; }
location ~ \.(css|js|jpg|jpeg|png|gif)$ {
expires 7d;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
add_header "Vary" "Accept-Encoding";
}
## PHP5-FPM
location ~ (\.php) {
# these settings are usually in fastcgi_params
@ -138,14 +104,14 @@ MEMCACHED_SERVERS
}
if ( $memcached_request = 0) {
rewrite ^ /index.php?$args last;
rewrite ^ /index.php last;
}
}
## rewrite rules
location @rewrites {
add_header X-Cache-Engine "";
rewrite ^ /index.php?$args last;
rewrite ^ /index.php last;
}
}

View file

@ -3,7 +3,7 @@
Plugin Name: WP-FFPC
Plugin URI: http://petermolnar.eu/wordpress/wp-ffpc
Description: WordPress cache plugin for memcached & nginx - unbeatable speed
Version: 1.1.1
Version: 1.2
Author: Peter Molnar <hello@petermolnar.eu>
Author URI: http://petermolnar.eu/
License: GPLv3
@ -34,7 +34,6 @@ $wp_ffpc_defaults = array (
'prefix_meta' =>'meta-',
'prefix_data' =>'data-',
'charset' => 'utf-8',
'log_info' => false,
'log' => true,
'cache_type' => 'memcached',
'cache_loggedin' => false,
@ -48,9 +47,10 @@ $wp_ffpc_defaults = array (
'persistent' => false,
'response_header' => false,
'generate_time' => false,
'precache_schedule' => 'null'
);
$wp_ffpc = new WP_FFPC ( 'wp-ffpc', '1.1.1', 'WP-FFPC', $wp_ffpc_defaults, 'https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=XU3DG7LLA76WC' );
$wp_ffpc = new WP_FFPC ( 'wp-ffpc', '1.2', 'WP-FFPC', $wp_ffpc_defaults, 'https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=XU3DG7LLA76WC' );
?>