diff --git a/backends/apc.php b/backends/apc.php new file mode 100644 index 0000000..26f3aab --- /dev/null +++ b/backends/apc.php @@ -0,0 +1,92 @@ +log ( __translate__('APC extension missing', $this->plugin_constant ) ); + return false; + } + + /* verify apc is working */ + if ( apc_cache_info("user",true) ) { + $this->log ( __translate__('backend OK', $this->plugin_constant ) ); + $this->alive = true; + } + } + + /** + * health checker for APC + * + * @return boolean Aliveness status + * + */ + protected function _status () { + $this->status = true; + return $this->alive; + } + + /** + * get function for APC backend + * + * @param string $key Key to get values for + * + * @return mixed Fetched data based on key + * + */ + protected function _get ( &$key ) { + return apc_fetch( $key ); + } + + /** + * Set function for APC backend + * + * @param string $key Key to set with + * @param mixed $data Data to set + * + * @return boolean APC store outcome + */ + protected function _set ( &$key, &$data, &$expire ) { + return apc_store( $key , $data , $expire ); + } + + + /** + * Flushes APC user entry storage + * + * @return boolean APC flush outcome status + * + */ + protected function _flush ( ) { + return apc_clear_cache('user'); + } + + /** + * Removes entry from APC or flushes APC user entry storage + * + * @param mixed $keys Keys to clear, string or array + */ + protected function _clear ( &$keys ) { + /* make an array if only one string is present, easier processing */ + if ( !is_array ( $keys ) ) + $keys = array ( $keys => true ); + + foreach ( $keys as $key => $dummy ) { + if ( ! apc_delete ( $key ) ) { + $this->log ( sprintf( __translate__( 'Failed to delete APC entry: %s', $this->plugin_constant ), $key ), LOG_WARNING ); + //throw new Exception ( __translate__('Deleting APC entry failed with key ', $this->plugin_constant ) . $key ); + } + else { + $this->log ( sprintf( __translate__( 'APC entry delete: %s', $this->plugin_constant ), $key ) ); + } + } + } +} + +endif; diff --git a/backends/apcu.php b/backends/apcu.php new file mode 100644 index 0000000..289fdde --- /dev/null +++ b/backends/apcu.php @@ -0,0 +1,92 @@ +log ( __translate__('APCu extension missing', $this->plugin_constant ) ); + return false; + } + + /* verify apcu is working */ + if ( @apcu_cache_info("user") != false ) { + $this->log ( __translate__('backend OK', $this->plugin_constant ) ); + $this->alive = true; + } + } + + /** + * health checker for APC + * + * @return boolean Aliveness status + * + */ + protected function _status () { + $this->status = true; + return $this->alive; + } + + /** + * get function for APC backend + * + * @param string $key Key to get values for + * + * @return mixed Fetched data based on key + * + */ + protected function _get ( &$key ) { + return apcu_fetch( $key ); + } + + /** + * Set function for APC backend + * + * @param string $key Key to set with + * @param mixed $data Data to set + * + * @return boolean APC store outcome + */ + protected function _set ( &$key, &$data, &$expire ) { + return apcu_store( $key , $data , $expire ); + } + + + /** + * Flushes APC user entry storage + * + * @return boolean APC flush outcome status + * + */ + protected function _flush ( ) { + return apcu_clear_cache(); + } + + /** + * Removes entry from APC or flushes APC user entry storage + * + * @param mixed $keys Keys to clear, string or array + */ + protected function _clear ( &$keys ) { + /* make an array if only one string is present, easier processing */ + if ( !is_array ( $keys ) ) + $keys = array ( $keys => true ); + + foreach ( $keys as $key => $dummy ) { + if ( ! apcu_delete ( $key ) ) { + $this->log ( sprintf( __translate__( 'Failed to delete APC entry: %s', $this->plugin_constant ), $key ), LOG_WARNING ); + //throw new Exception ( __translate__('Deleting APC entry failed with key ', $this->plugin_constant ) . $key ); + } + else { + $this->log ( sprintf( __translate__( 'APC entry delete: %s', $this->plugin_constant ), $key ) ); + } + } + } +} + +endif; diff --git a/backends/memcache.php b/backends/memcache.php new file mode 100644 index 0000000..5ee1553 --- /dev/null +++ b/backends/memcache.php @@ -0,0 +1,122 @@ +log ( __translate__('PHP Memcache extension missing', $this->plugin_constant ), LOG_WARNING ); + 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", $this->plugin_constant ), LOG_WARNING ); + return false; + } + + /* check is there's no backend connection yet */ + if ( $this->connection === NULL ) + $this->connection = new Memcache(); + + /* check if initialization was success or not */ + if ( $this->connection === NULL ) { + $this->log ( __translate__( 'error initializing Memcache PHP extension, exiting', $this->plugin_constant ) ); + return false; + } + + /* adding servers */ + foreach ( $this->options['servers'] as $server_id => $server ) { + /* in case of unix socket */ + if ( $server['port'] === 0 ) + $this->status[$server_id] = $this->connection->connect ( 'unix:/' . $server['host'] ); + else + $this->status[$server_id] = $this->connection->connect ( $server['host'] , $server['port'] ); + + $this->log ( sprintf( __translate__( '%s added', $this->plugin_constant ), $server_id ) ); + } + + /* backend is now alive */ + $this->alive = true; + $this->_status(); + } + + /** + * check current backend alive status for Memcached + * + */ + protected function _status () { + /* server status will be calculated by getting server stats */ + $this->log ( __translate__("checking server statuses", $this->plugin_constant )); + /* get servers statistic from connection */ + foreach ( $this->options['servers'] as $server_id => $server ) { + if ( $server['port'] === 0 ) + $this->status[$server_id] = $this->connection->getServerStatus( $server['host'], 11211 ); + else + $this->status[$server_id] = $this->connection->getServerStatus( $server['host'], $server['port'] ); + if ( $this->status[$server_id] == 0 ) + $this->log ( sprintf( __translate__( '%s server is down', $this->plugin_constant ), $server_id ) ); + else + $this->log ( sprintf( __translate__( '%s server is up & running', $this->plugin_constant ), $server_id ) ); + } + } + + /** + * get function for Memcached backend + * + * @param string $key Key to get values for + * + */ + protected function _get ( &$key ) { + return $this->connection->get($key); + } + + /** + * Set function for Memcached backend + * + * @param string $key Key to set with + * @param mixed $data Data to set + * + */ + protected function _set ( &$key, &$data, &$expire ) { + $result = $this->connection->set ( $key, $data , 0 , $expire ); + return $result; + } + + /** + * + * Flush memcached entries + */ + protected function _flush ( ) { + return $this->connection->flush(); + } + + + /** + * Removes entry from Memcached or flushes Memcached storage + * + * @param mixed $keys String / array of string of keys to delete entries with + */ + protected function _clear ( &$keys ) { + /* make an array if only one string is present, easier processing */ + if ( !is_array ( $keys ) ) + $keys = array ( $keys => true ); + + foreach ( $keys as $key => $dummy ) { + $kresult = $this->connection->delete( $key ); + + if ( $kresult === false ) { + $this->log ( sprintf( __translate__( 'unable to delete entry: %s', $this->plugin_constant ), $key ) ); + } + else { + $this->log ( sprintf( __translate__( 'entry deleted: %s', $this->plugin_constant ), $key ) ); + } + } + } +} + +endif; diff --git a/backends/memcached.php b/backends/memcached.php new file mode 100644 index 0000000..a80a319 --- /dev/null +++ b/backends/memcached.php @@ -0,0 +1,159 @@ +log ( __translate__(' Memcached extension missing, wp-ffpc will not be able to function correctly!', $this->plugin_constant ), LOG_WARNING ); + 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", $this->plugin_constant ), LOG_WARNING ); + return false; + } + + /* check is there's no backend connection yet */ + if ( $this->connection === NULL ) { + $this->connection = new Memcached(); + + /* use binary and not compressed format, good for nginx and still fast */ + $this->connection->setOption( Memcached::OPT_COMPRESSION , false ); + if ($this->options['memcached_binary']){ + $this->connection->setOption( Memcached::OPT_BINARY_PROTOCOL , true ); + } + + if ( version_compare( phpversion( 'memcached' ) , '2.0.0', '>=' ) && ini_get( 'memcached.use_sasl' ) == 1 && isset($this->options['authpass']) && !empty($this->options['authpass']) && isset($this->options['authuser']) && !empty($this->options['authuser']) ) { + $this->connection->setSaslAuthData ( $this->options['authuser'], $this->options['authpass']); + } + } + + /* check if initialization was success or not */ + if ( $this->connection === NULL ) { + $this->log ( __translate__( 'error initializing Memcached PHP extension, exiting', $this->plugin_constant ) ); + return false; + } + + /* check if we already have list of servers, only add server(s) if it's not already connected */ + $servers_alive = array(); + if ( !empty ( $this->status ) ) { + $servers_alive = $this->connection->getServerList(); + /* create check array if backend servers are already connected */ + if ( !empty ( $servers ) ) { + foreach ( $servers_alive as $skey => $server ) { + $skey = $server['host'] . ":" . $server['port']; + $servers_alive[ $skey ] = true; + } + } + } + + /* adding servers */ + foreach ( $this->options['servers'] as $server_id => $server ) { + /* reset server status to unknown */ + //$this->status[$server_id] = -1; + + /* 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 ( sprintf( __translate__( '%s added', $this->plugin_constant ), $server_id ) ); + } + } + + /* backend is now alive */ + $this->alive = true; + $this->_status(); + } + + /** + * sets current backend alive status for Memcached servers + * + */ + protected function _status () { + /* server status will be calculated by getting server stats */ + $this->log ( __translate__("checking server statuses", $this->plugin_constant )); + /* get server list from connection */ + $servers = $this->connection->getServerList(); + + foreach ( $servers as $server ) { + $server_id = $server['host'] . self::port_separator . $server['port']; + /* reset server status to offline */ + $this->status[$server_id] = 0; + if ($this->connection->set($this->plugin_constant, time())) { + $this->log ( sprintf( __translate__( '%s server is up & running', $this->plugin_constant ), $server_id ) ); + $this->status[$server_id] = 1; + } + } + + } + + /** + * get function for Memcached backend + * + * @param string $key Key to get values for + * + */ + protected function _get ( &$key ) { + return $this->connection->get($key); + } + + /** + * Set function for Memcached backend + * + * @param string $key Key to set with + * @param mixed $data Data to set + * + */ + protected function _set ( &$key, &$data, &$expire ) { + $result = $this->connection->set ( $key, $data , $expire ); + + /* if storing failed, log the error code */ + if ( $result === false ) { + $code = $this->connection->getResultCode(); + $this->log ( sprintf( __translate__( 'unable to set entry: %s', $this->plugin_constant ), $key ) ); + $this->log ( sprintf( __translate__( 'Memcached error code: %s', $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; + } + + /** + * + * Flush memcached entries + */ + protected function _flush ( ) { + return $this->connection->flush(); + } + + + /** + * Removes entry from Memcached or flushes Memcached storage + * + * @param mixed $keys String / array of string of keys to delete entries with + */ + protected function _clear ( &$keys ) { + + /* make an array if only one string is present, easier processing */ + if ( !is_array ( $keys ) ) + $keys = array ( $keys => true ); + + foreach ( $keys as $key => $dummy ) { + $kresult = $this->connection->delete( $key ); + + if ( $kresult === false ) { + $code = $this->connection->getResultCode(); + $this->log ( sprintf( __translate__( 'unable to delete entry: %s', $this->plugin_constant ), $key ) ); + $this->log ( sprintf( __translate__( 'Memcached error code: %s', $this->plugin_constant ), $code ) ); + } + else { + $this->log ( sprintf( __translate__( 'entry deleted: %s', $this->plugin_constant ), $key ) ); + } + } + } +} + +endif; diff --git a/backends/redis.php b/backends/redis.php new file mode 100644 index 0000000..e6379dc --- /dev/null +++ b/backends/redis.php @@ -0,0 +1,156 @@ +log ( __translate__('Redis extension missing, wp-ffpc will not be able to function correctly!', $this->plugin_constant ), LOG_WARNING ); + return false; + } + + /* check for existing server list, otherwise we cannot add backends */ + if ( empty ( $this->options['servers'] ) && ! $this->alive ) { + $this->log ( __translate__("Redis servers list is empty, init failed", $this->plugin_constant ), LOG_WARNING ); + return false; + } + + /* check is there's no backend connection yet */ + if ( $this->connection === NULL ) { + $this->connection = new Redis(); + } + + /* check if initialization was success or not */ + if ( $this->connection === NULL ) { + $this->log ( __translate__( 'error initializing Redis PHP extension, exiting', $this->plugin_constant ) ); + return false; + } + + /* check if we already have list of servers, only add server(s) if it's not already connected * + $servers_alive = array(); + if ( !empty ( $this->status ) ) { + $servers_alive = $this->connection->getServerList(); + /* create check array if backend servers are already connected * + if ( !empty ( $servers ) ) { + foreach ( $servers_alive as $skey => $server ) { + $skey = $server['host'] . ":" . $server['port']; + $servers_alive[ $skey ] = true; + } + } + } + + /* adding servers */ + foreach ( $this->options['servers'] as $server_id => $server ) { + /* only add servers that does not exists already in connection pool */ + if ( !@array_key_exists($server_id , $servers_alive ) ) { + + if ( $server['port'] != 0) + $this->connection->connect($server['host'], $server['port'] ); + else + $this->connection->connect($server['host'] ); + + if ( isset($this->options['authpass']) && !empty($this->options['authpass']) ) + $this->connection->auth ( $this->options['authpass'] ); + + $this->log ( sprintf( __translate__( '%s added', $this->plugin_constant ), $server_id ) ); + } + } + + /* backend is now alive */ + $this->alive = true; + $this->_status(); + } + + /** + * sets current backend alive status for Memcached servers + * + */ + protected function _status () { + /* server status will be calculated by getting server stats */ + + $this->log ( __translate__("checking server status", $this->plugin_constant )); + + try { + $info = $this->connection->ping(); + } catch ( Exception $e ) { + $this->log ( __translate__("Exception occured: " . json_encode($e), $this->plugin_constant )); + } + + $status = empty( $info ) ? 0 : 1; + + foreach ( $this->options['servers'] as $server_id => $server ) { + /* reset server status to offline */ + $this->status[$server_id] = $status; + } + + } + + /** + * get function for Memcached backend + * + * @param string $key Key to get values for + * + */ + protected function _get ( &$key ) { + return $this->connection->get($key); + } + + /** + * Set function for Memcached backend + * + * @param string $key Key to set with + * @param mixed $data Data to set + * + */ + protected function _set ( &$key, &$data, &$expire ) { + $result = $this->connection->set ( $key, $data, $expire ); + + /* if storing failed, log the error code */ + //if ( $result === false ) { + $this->log ( sprintf( __translate__( 'set entry returned: %s', $this->plugin_constant ), $result ) ); + //} + + return $result; + } + + /** + * + * Flush memcached entries + */ + protected function _flush ( ) { + try { + $r = $this->connection->flushDB(); + } catch ( Exception $e ) { + $this->log ( sprintf( __translate__( 'unable to flush, error: %s', $this->plugin_constant ), json_encode($r) ) ); + } + return $r; + } + + + /** + * Removes entry from Memcached or flushes Memcached storage + * + * @param mixed $keys String / array of string of keys to delete entries with + */ + protected function _clear ( &$keys ) { + + /* make an array if only one string is present, easier processing */ + if ( !is_array ( $keys ) ) + $keys = array ( $keys => true ); + + try { + $kresult = $this->connection->delete( $keys ); + } catch ( Exception $e ) { + $this->log ( sprintf( __translate__( 'unable to delete entry(s): %s', $this->plugin_constant ), json_encode($key) ) ); + $this->log ( sprintf( __translate__( 'Redis error: %s', $this->plugin_constant ), json_encode($e) ) ); + } + finally { + $this->log ( sprintf( __translate__( 'entry(s) deleted: %s', $this->plugin_constant ), json_encode($keys) ) ); + } + + } +} + +endif; diff --git a/readme.txt b/readme.txt index 4d67f69..c8c8fb5 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: cadeyrn, ameir, haroldkyle, plescheff, dkcwd, IgorCode 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 Requires at least: 3.0 -Tested up to: 4.2.1 +Tested up to: 4.3.1 Stable tag: 1.8.4 License: GPLv3 License URI: http://www.gnu.org/licenses/gpl-3.0.html @@ -78,6 +78,7 @@ Many thanks for donations, contributors, supporters, testers & bug reporters: * Meint Post * Knut Sparhell * Christian Kernbeis +* Gausden Barry == Installation == @@ -128,9 +129,11 @@ Version numbering logic: * every ..C indicates bugfixes for A.B version. = 1.8.4 = -*2015-* +*2015-10-13* * changes in HTML debug comment: instead of the former, single comment, now 2 comments are added. The first is added when the cache entry is generated; the second only appears if the page was served from the cached entry. Please note that this last bit will - should - change with every single refresh. +* backend code is now split into separate files +* more debug code = 1.8.3 = *2015-05-07* diff --git a/wp-ffpc-acache.php b/wp-ffpc-acache.php index 131ba8b..7fe7657 100644 --- a/wp-ffpc-acache.php +++ b/wp-ffpc-acache.php @@ -3,6 +3,15 @@ * advanced cache worker of WordPress plugin WP-FFPC */ +if ( !function_exists ('__debug__') ) { + /* __ only availabe if we're running from the inside of wordpress, not in advanced-cache.php phase */ + function __debug__ ( $text ) { + if ( defined('WP_FFPC__DEBUG_MODE') && WP_FFPC__DEBUG_MODE == true) + error_log ( __FILE__ . ': ' . $text ); + } +} + + /* check for WP cache enabled*/ if ( !WP_CACHE ) return false; @@ -26,12 +35,16 @@ if (!isset($wp_ffpc_config)) $wp_ffpc_uri = $_SERVER['REQUEST_URI']; /* no cache for robots.txt */ -if ( stripos($wp_ffpc_uri, 'robots.txt') ) +if ( stripos($wp_ffpc_uri, 'robots.txt') ) { + __debug__ ( 'Skippings robots.txt hit'); return false; +} /* multisite files can be too large for memcached */ -if ( function_exists('is_multisite') && stripos($wp_ffpc_uri, '/files/') && is_multisite() ) +if ( function_exists('is_multisite') && stripos($wp_ffpc_uri, '/files/') && is_multisite() ) { + __debug__ ( 'Skippings multisite /files/ hit'); return false; +} /* check if config is network active: use network config */ if (!empty ( $wp_ffpc_config['network'] ) ) @@ -44,8 +57,10 @@ else return false; /* 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 ) +if ( isset($wp_ffpc_config['nocache_dyn']) && !empty($wp_ffpc_config['nocache_dyn']) && stripos($wp_ffpc_uri, '?') !== false ) { + __debug__ ( 'Dynamic url cache is disabled ( url with "?" ), skipping'); return false; +} /* check for cookies that will make us not cache the content, like logged in WordPress cookie */ if ( isset($wp_ffpc_config['nocache_cookies']) && !empty($wp_ffpc_config['nocache_cookies']) ) { @@ -56,6 +71,7 @@ if ( isset($wp_ffpc_config['nocache_cookies']) && !empty($wp_ffpc_config['nocach /* check for any matches to user-added cookies to no-cache */ foreach ( $nocache_cookies as $nocache_cookie ) { if( strpos( $n, $nocache_cookie ) === 0 ) { + __debug__ ( "Cookie exception matched: $n, skipping"); return false; } } @@ -67,6 +83,7 @@ if ( isset($wp_ffpc_config['nocache_cookies']) && !empty($wp_ffpc_config['nocach 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) ) { + __debug__ ( "Cache exceptions matched, skipping"); return false; } } @@ -75,7 +92,10 @@ if ( isset($wp_ffpc_config['nocache_url']) && trim($wp_ffpc_config['nocache_url' $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 ); +$backend_class = 'WP_FFPC_Backend_' . $wp_ffpc_config['cache_type']; +$wp_ffpc_backend = new $backend_class ( $wp_ffpc_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 @@ -85,6 +105,7 @@ if ( !isset($wp_ffpc_config['cache_loggedin']) || $wp_ffpc_config['cache_loggedi foreach ($_COOKIE as $n=>$v) { foreach ( $wp_ffpc_backend->cookies as $nocache_cookie ) { if( strpos( $n, $nocache_cookie ) === 0 ) { + __debug__ ( "No cache for cookie: $n, skipping"); return false; } } @@ -95,13 +116,17 @@ if ( !isset($wp_ffpc_config['cache_loggedin']) || $wp_ffpc_config['cache_loggedi $wp_ffpc_gentime = 0; /* backend connection failed, no caching :( */ -if ( $wp_ffpc_backend->status() === false ) +if ( $wp_ffpc_backend->status() === false ) { + __debug__ ( "Backend offline, skipping"); return false; +} /* try to get data & meta keys for current page */ $wp_ffpc_keys = array ( 'meta' => $wp_ffpc_config['prefix_meta'], 'data' => $wp_ffpc_config['prefix_data'] ); $wp_ffpc_values = array(); +__debug__ ( "Trying to fetch entries"); + foreach ( $wp_ffpc_keys as $internal => $key ) { $key = $wp_ffpc_backend->key ( $key ); $value = $wp_ffpc_backend->get ( $key ); @@ -309,6 +334,8 @@ function wp_ffpc_callback( $buffer ) { if ( get_option ( 'default_ping_status' ) == 'open' ) $meta['pingback'] = get_bloginfo('pingback_url'); + $to_store = $buffer; + /* add generation info is option is set, but only to HTML */ if ( $wp_ffpc_config['generate_time'] == '1' && stripos($buffer, '') ) { global $wp_ffpc_gentime; diff --git a/wp-ffpc-backend.php b/wp-ffpc-backend.php index 9e34e53..f9dc4d4 100644 --- a/wp-ffpc-backend.php +++ b/wp-ffpc-backend.php @@ -11,39 +11,29 @@ if ( !function_exists ('__translate__') ) { } } +/* this is the base class for all backends; the actual workers + * are included at the end of the file from backends/ directory */ + if (!class_exists('WP_FFPC_Backend')) : -//include_once ( 'wp-common/plugin_utils.php'); -/** - * - * @var string $plugin_constant Namespace of the plugin - * @var mixed $connection Backend object storage variable - * @var boolean $alive Alive flag of backend connection - * @var array $options Configuration settings array - * @var array $status Backends status storage - * @var array $cookies Logged in cookies to search for - * @var array $urimap Map to render key with - * @var object $utilities Utilities singleton - * - */ -class WP_FFPC_Backend { + +abstract class WP_FFPC_Backend { const host_separator = ','; const port_separator = ':'; - private $plugin_constant = 'wp-ffpc'; - private $connection = NULL; - private $alive = false; - private $options = array(); - private $status = array(); + protected $plugin_constant = 'wp-ffpc'; + protected $connection = NULL; + protected $alive = false; + protected $options = array(); + protected $status = array(); public $cookies = array(); - private $urimap = array(); + protected $urimap = array(); /** * constructor * * @param mixed $config Configuration options - * @param boolean $network WordPress Network indicator flah * */ public function __construct( $config ) { @@ -54,7 +44,6 @@ class WP_FFPC_Backend { //die ( __translate__ ( 'WP-FFPC Backend class received empty configuration array, the plugin will not work this way', $this->plugin_constant ) ); } - /* set config */ $this->options = $config; /* these are the list of the cookies to look for when looking for logged in user */ @@ -79,16 +68,14 @@ class WP_FFPC_Backend { '$cookie_PHPSESSID' => $scookie, ); - /* split hosts entry to servers */ + /* split single line hosts entry */ $this->set_servers(); - /* call backend initiator based on cache type */ - $init = $this->proxy( 'init' ); - /* info level */ $this->log ( __translate__('init starting', $this->plugin_constant )); - $this->$init(); + /* call backend initiator based on cache type */ + $init = $this->_init(); if (is_admin() && function_exists('add_filter')) { add_filter('wp_ffpc_clear_keys_array', function($to_clear, $options) { @@ -105,7 +92,10 @@ class WP_FFPC_Backend { } } - + /* + * @param string $uri + * @param mixed $default_urimap + */ public static function parse_urimap($uri, $default_urimap=null) { $uri_parts = parse_url( $uri ); @@ -122,11 +112,14 @@ class WP_FFPC_Backend { return $uri_map; } + /** + * @param array $urimap + * @param string $subject + */ public static function map_urimap($urimap, $subject) { return str_replace(array_keys($urimap), $urimap, $subject); } - /*********************** PUBLIC / PROXY FUNCTIONS ***********************/ /** * build key to make requests with @@ -140,7 +133,7 @@ class WP_FFPC_Backend { $key_base = self::map_urimap($urimap, $this->options['key']); - if ( isset($this->options['hashkey']) && $this->options['hashkey'] == true) + if (( isset($this->options['hashkey']) && $this->options['hashkey'] == true) || $this->options['cache_type'] == 'redis' ) $key_base = sha1($key_base); $key = $prefix . $key_base; @@ -161,17 +154,17 @@ class WP_FFPC_Backend { */ public function get ( &$key ) { /* look for backend aliveness, exit on inactive backend */ - if ( ! $this->is_alive() ) + if ( ! $this->is_alive() ) { + $this->log ('WARNING: Backend offline'); return false; + } /* log the current action */ - $this->log ( sprintf( __translate__( 'get %s', $this->plugin_constant ), $key ) ); + $this->log ( sprintf( __translate__( 'GET %s', $this->plugin_constant ), $key ) ); - /* proxy to internal function */ - $internal = $this->proxy( 'get' ); - $result = $this->$internal( $key ); + $result = $this->_get( $key ); - if ( $result === false ) + if ( $result === false || $result === null ) $this->log ( sprintf( __translate__( 'failed to get entry: %s', $this->plugin_constant ), $key ) ); return $result; @@ -203,18 +196,23 @@ class WP_FFPC_Backend { elseif (( is_tax() || is_category() || is_tag() || is_archive() ) && isset($this->options['expire_taxonomy'])) $expire = (int) $this->options['expire_taxonomy']; + /* log the current action */ + $this->log ( sprintf( __translate__( 'SET %s', $this->plugin_constant ), $key ) ); /* proxy to internal function */ - $internal = $this->proxy( 'set' ); - $result = $this->$internal( $key, $data, $expire ); + $result = $this->_set( $key, $data, $expire ); /* check result validity */ - if ( $result === false ) + if ( $result === false || $result === null ) $this->log ( sprintf( __translate__( 'failed to set entry: %s', $this->plugin_constant ), $key ), LOG_WARNING ); return $result; } - + /* + * next generation clean + * + * + */ public function clear_ng ( $new_status, $old_status, $post ) { $this->clear ( $post->ID ); } @@ -224,7 +222,6 @@ class WP_FFPC_Backend { * * @param string $post_id ID of post to invalidate * @param boolean $force Force flush cache - * @param boolean $comment Clear a single page based on comment trigger * */ public function clear ( $post_id = false, $force = false ) { @@ -245,8 +242,7 @@ class WP_FFPC_Backend { $this->log ( __translate__('flushing cache', $this->plugin_constant ) ); /* proxy to internal function */ - $internal = $this->proxy ( 'flush' ); - $result = $this->$internal(); + $internal = $this->_flush(); if ( $result === false ) $this->log ( __translate__('failed to flush cache', $this->plugin_constant ), LOG_WARNING ); @@ -320,10 +316,13 @@ class WP_FFPC_Backend { $this->clear_keys( $to_clear ); } + /* + * unset entries by key + * @param array $keys + */ public function clear_keys( $keys ) { $to_clear = apply_filters('wp_ffpc_clear_keys_array', $keys, $this->options); - $internal = $this->proxy ( 'clear' ); - $this->$internal ( $to_clear ); + $this->_clear ( $to_clear ); } /** @@ -422,28 +421,17 @@ class WP_FFPC_Backend { if ( ! $this->is_alive() ) return false; - $internal = $this->proxy ( 'status' ); - $this->$internal(); + $internal = $this->_status(); return $this->status; } - /** - * backend proxy function name generator - * - * @return string Name of internal function based on cache_type - * - */ - private function proxy ( $method ) { - return $this->options['cache_type'] . '_' . $method; - } - /** * function to check backend aliveness * * @return boolean true if backend is alive, false if not * */ - private function is_alive() { + protected function is_alive() { if ( ! $this->alive ) { $this->log ( __translate__("backend is not active, exiting function ", $this->plugin_constant ) . __FUNCTION__, LOG_WARNING ); return false; @@ -457,7 +445,10 @@ class WP_FFPC_Backend { * * */ - private function set_servers () { + protected function set_servers () { + if ( empty ($this->options['hosts']) ) + return false; + /* replace servers array in config according to hosts field */ $servers = explode( self::host_separator , $this->options['hosts']); @@ -465,11 +456,15 @@ class WP_FFPC_Backend { foreach ( $servers as $snum => $sstring ) { - $separator = strpos( $sstring , self::port_separator ); - $host = substr( $sstring, 0, $separator ); - $port = substr( $sstring, $separator + 1 ); - // unix socket failsafe - if ( empty ($port) ) $port = 0; + if ( stristr($sstring, 'unix://' ) ) { + $host = str_replace('unix:/','',$sstring); + $port = 0; + } + else { + $separator = strpos( $sstring , self::port_separator ); + $host = substr( $sstring, 0, $separator ); + $port = substr( $sstring, $separator + 1 ); + } $this->options['servers'][$sstring] = array ( 'host' => $host, @@ -496,7 +491,7 @@ class WP_FFPC_Backend { * @var mixed $message Message to log * @var int $log_level Log level */ - private function log ( $message, $level = LOG_NOTICE ) { + protected function log ( $message, $level = LOG_NOTICE ) { if ( @is_array( $message ) || @is_object ( $message ) ) $message = json_encode($message); @@ -514,601 +509,19 @@ class WP_FFPC_Backend { error_log( __CLASS__ . ": " . $message ); } - /*********************** END PUBLIC FUNCTIONS ***********************/ - /*********************** APC FUNCTIONS ***********************/ - /** - * init apc backend: test APC availability and set alive status - */ - private function apc_init () { - /* verify apc functions exist, apc extension is loaded */ - if ( ! function_exists( 'apc_cache_info' ) ) { - $this->log ( __translate__('APC extension missing', $this->plugin_constant ) ); - return false; - } - - /* verify apc is working */ - if ( apc_cache_info("user",true) ) { - $this->log ( __translate__('backend OK', $this->plugin_constant ) ); - $this->alive = true; - } - } - - /** - * health checker for APC - * - * @return boolean Aliveness status - * - */ - private function apc_status () { - $this->status = true; - return $this->alive; - } - - /** - * get function for APC backend - * - * @param string $key Key to get values for - * - * @return mixed Fetched data based on key - * - */ - private function apc_get ( &$key ) { - return apc_fetch( $key ); - } - - /** - * Set function for APC backend - * - * @param string $key Key to set with - * @param mixed $data Data to set - * - * @return boolean APC store outcome - */ - private function apc_set ( &$key, &$data, &$expire ) { - return apc_store( $key , $data , $expire ); - } - - - /** - * Flushes APC user entry storage - * - * @return boolean APC flush outcome status - * - */ - private function apc_flush ( ) { - return apc_clear_cache('user'); - } - - /** - * Removes entry from APC or flushes APC user entry storage - * - * @param mixed $keys Keys to clear, string or array - */ - private function apc_clear ( &$keys ) { - /* make an array if only one string is present, easier processing */ - if ( !is_array ( $keys ) ) - $keys = array ( $keys => true ); - - foreach ( $keys as $key => $dummy ) { - if ( ! apc_delete ( $key ) ) { - $this->log ( sprintf( __translate__( 'Failed to delete APC entry: %s', $this->plugin_constant ), $key ), LOG_WARNING ); - //throw new Exception ( __translate__('Deleting APC entry failed with key ', $this->plugin_constant ) . $key ); - } - else { - $this->log ( sprintf( __translate__( 'APC entry delete: %s', $this->plugin_constant ), $key ) ); - } - } - } - - /*********************** END APC FUNCTIONS ***********************/ - /*********************** APCu FUNCTIONS ***********************/ - /** - * init apcu backend: test APCu availability and set alive status - */ - private function apcu_init () { - /* verify apcu functions exist, apcu extension is loaded */ - if ( ! function_exists( 'apcu_cache_info' ) ) { - $this->log ( __translate__('APCu extension missing', $this->plugin_constant ) ); - return false; - } - - /* verify apcu is working */ - if ( apcu_cache_info("user") ) { - $this->log ( __translate__('backend OK', $this->plugin_constant ) ); - $this->alive = true; - } - } - - /** - * health checker for APC - * - * @return boolean Aliveness status - * - */ - private function apcu_status () { - $this->status = true; - return $this->alive; - } - - /** - * get function for APC backend - * - * @param string $key Key to get values for - * - * @return mixed Fetched data based on key - * - */ - private function apcu_get ( &$key ) { - return apcu_fetch( $key ); - } - - /** - * Set function for APC backend - * - * @param string $key Key to set with - * @param mixed $data Data to set - * - * @return boolean APC store outcome - */ - private function apcu_set ( &$key, &$data, &$expire ) { - return apcu_store( $key , $data , $expire ); - } - - - /** - * Flushes APC user entry storage - * - * @return boolean APC flush outcome status - * - */ - private function apcu_flush ( ) { - return apcu_clear_cache(); - } - - /** - * Removes entry from APC or flushes APC user entry storage - * - * @param mixed $keys Keys to clear, string or array - */ - private function apcu_clear ( &$keys ) { - /* make an array if only one string is present, easier processing */ - if ( !is_array ( $keys ) ) - $keys = array ( $keys => true ); - - foreach ( $keys as $key => $dummy ) { - if ( ! apcu_delete ( $key ) ) { - $this->log ( sprintf( __translate__( 'Failed to delete APC entry: %s', $this->plugin_constant ), $key ), LOG_WARNING ); - //throw new Exception ( __translate__('Deleting APC entry failed with key ', $this->plugin_constant ) . $key ); - } - else { - $this->log ( sprintf( __translate__( 'APC entry delete: %s', $this->plugin_constant ), $key ) ); - } - } - } - - /*********************** END APC FUNCTIONS ***********************/ - - /*********************** MEMCACHED FUNCTIONS ***********************/ - /** - * init memcached 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, wp-ffpc will not be able to function correctly!', $this->plugin_constant ), LOG_WARNING ); - 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", $this->plugin_constant ), LOG_WARNING ); - return false; - } - - /* check is there's no backend connection yet */ - if ( $this->connection === NULL ) { - $this->connection = new Memcached(); - - /* use binary and not compressed format, good for nginx and still fast */ - $this->connection->setOption( Memcached::OPT_COMPRESSION , false ); - if ($this->options['memcached_binary']){ - $this->connection->setOption( Memcached::OPT_BINARY_PROTOCOL , true ); - } - - if ( version_compare( phpversion( 'memcached' ) , '2.0.0', '>=' ) && ini_get( 'memcached.use_sasl' ) == 1 && isset($this->options['authpass']) && !empty($this->options['authpass']) && isset($this->options['authuser']) && !empty($this->options['authuser']) ) { - $this->connection->setSaslAuthData ( $this->options['authuser'], $this->options['authpass']); - } - } - - /* check if initialization was success or not */ - if ( $this->connection === NULL ) { - $this->log ( __translate__( 'error initializing Memcached PHP extension, exiting', $this->plugin_constant ) ); - return false; - } - - /* check if we already have list of servers, only add server(s) if it's not already connected */ - $servers_alive = array(); - if ( !empty ( $this->status ) ) { - $servers_alive = $this->connection->getServerList(); - /* create check array if backend servers are already connected */ - if ( !empty ( $servers ) ) { - foreach ( $servers_alive as $skey => $server ) { - $skey = $server['host'] . ":" . $server['port']; - $servers_alive[ $skey ] = true; - } - } - } - - /* adding servers */ - foreach ( $this->options['servers'] as $server_id => $server ) { - /* reset server status to unknown */ - $this->status[$server_id] = -1; - - /* 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 ( sprintf( __translate__( '%s added', $this->plugin_constant ), $server_id ) ); - } - } - - /* backend is now alive */ - $this->alive = true; - $this->memcached_status(); - } - - /** - * sets current backend alive status for Memcached servers - * - */ - private function memcached_status () { - /* server status will be calculated by getting server stats */ - $this->log ( __translate__("checking server statuses", $this->plugin_constant )); - /* get server list from connection */ - $servers = $this->connection->getServerList(); - - foreach ( $servers as $server ) { - $server_id = $server['host'] . self::port_separator . $server['port']; - /* reset server status to offline */ - $this->status[$server_id] = 0; - if ($this->connection->set($this->plugin_constant, time())) { - $this->log ( sprintf( __translate__( '%s server is up & running', $this->plugin_constant ), $server_id ) ); - $this->status[$server_id] = 1; - } - } - - } - - /** - * get function for Memcached backend - * - * @param string $key Key to get values for - * - */ - private function memcached_get ( &$key ) { - return $this->connection->get($key); - } - - /** - * Set function for Memcached backend - * - * @param string $key Key to set with - * @param mixed $data Data to set - * - */ - private function memcached_set ( &$key, &$data, &$expire ) { - $result = $this->connection->set ( $key, $data , $expire ); - - /* if storing failed, log the error code */ - if ( $result === false ) { - $code = $this->connection->getResultCode(); - $this->log ( sprintf( __translate__( 'unable to set entry: %s', $this->plugin_constant ), $key ) ); - $this->log ( sprintf( __translate__( 'Memcached error code: %s', $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; - } - - /** - * - * Flush memcached entries - */ - private function memcached_flush ( ) { - return $this->connection->flush(); - } - - - /** - * Removes entry from Memcached or flushes Memcached storage - * - * @param mixed $keys String / array of string of keys to delete entries with - */ - private function memcached_clear ( &$keys ) { - - /* make an array if only one string is present, easier processing */ - if ( !is_array ( $keys ) ) - $keys = array ( $keys => true ); - - foreach ( $keys as $key => $dummy ) { - $kresult = $this->connection->delete( $key ); - - if ( $kresult === false ) { - $code = $this->connection->getResultCode(); - $this->log ( sprintf( __translate__( 'unable to delete entry: %s', $this->plugin_constant ), $key ) ); - $this->log ( sprintf( __translate__( 'Memcached error code: %s', $this->plugin_constant ), $code ) ); - } - else { - $this->log ( sprintf( __translate__( 'entry deleted: %s', $this->plugin_constant ), $key ) ); - } - } - } - /*********************** END MEMCACHED FUNCTIONS ***********************/ - - /*********************** MEMCACHE FUNCTIONS ***********************/ - /** - * init memcache 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', $this->plugin_constant ), LOG_WARNING ); - 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", $this->plugin_constant ), LOG_WARNING ); - return false; - } - - /* check is there's no backend connection yet */ - if ( $this->connection === NULL ) - $this->connection = new Memcache(); - - /* check if initialization was success or not */ - if ( $this->connection === NULL ) { - $this->log ( __translate__( 'error initializing Memcache PHP extension, exiting', $this->plugin_constant ) ); - return false; - } - - /* adding servers */ - foreach ( $this->options['servers'] as $server_id => $server ) { - /* in case of unix socket */ - if ( $server['port'] === 0 ) - $this->status[$server_id] = $this->connection->connect ( 'unix:/' . $server['host'] ); - else - $this->status[$server_id] = $this->connection->connect ( $server['host'] , $server['port'] ); - - $this->log ( sprintf( __translate__( '%s added', $this->plugin_constant ), $server_id ) ); - } - - /* backend is now alive */ - $this->alive = true; - $this->memcache_status(); - } - - /** - * check current backend alive status for Memcached - * - */ - private function memcache_status () { - /* server status will be calculated by getting server stats */ - $this->log ( __translate__("checking server statuses", $this->plugin_constant )); - /* get servers statistic from connection */ - foreach ( $this->options['servers'] as $server_id => $server ) { - if ( $server['port'] === 0 ) - $this->status[$server_id] = $this->connection->getServerStatus( $server['host'], 11211 ); - else - $this->status[$server_id] = $this->connection->getServerStatus( $server['host'], $server['port'] ); - if ( $this->status[$server_id] == 0 ) - $this->log ( sprintf( __translate__( '%s server is down', $this->plugin_constant ), $server_id ) ); - else - $this->log ( sprintf( __translate__( '%s server is up & running', $this->plugin_constant ), $server_id ) ); - } - } - - /** - * get function for Memcached backend - * - * @param string $key Key to get values for - * - */ - private function memcache_get ( &$key ) { - return $this->connection->get($key); - } - - /** - * Set function for Memcached backend - * - * @param string $key Key to set with - * @param mixed $data Data to set - * - */ - private function memcache_set ( &$key, &$data, &$expire ) { - $result = $this->connection->set ( $key, $data , 0 , $expire ); - return $result; - } - - /** - * - * Flush memcached entries - */ - private function memcache_flush ( ) { - return $this->connection->flush(); - } - - - /** - * Removes entry from Memcached or flushes Memcached storage - * - * @param mixed $keys String / array of string of keys to delete entries with - */ - private function memcache_clear ( &$keys ) { - /* make an array if only one string is present, easier processing */ - if ( !is_array ( $keys ) ) - $keys = array ( $keys => true ); - - foreach ( $keys as $key => $dummy ) { - $kresult = $this->connection->delete( $key ); - - if ( $kresult === false ) { - $this->log ( sprintf( __translate__( 'unable to delete entry: %s', $this->plugin_constant ), $key ) ); - } - else { - $this->log ( sprintf( __translate__( 'entry deleted: %s', $this->plugin_constant ), $key ) ); - } - } - } - - /*********************** END MEMCACHE FUNCTIONS ***********************/ - - /*********************** REDIS FUNCTIONS ***********************/ - /** - * init memcache backend - */ - private function redis_init () { - if (!class_exists('Redis')) { - $this->log ( __translate__('PHP Redis extension missing', $this->plugin_constant ), LOG_WARNING ); - 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", $this->plugin_constant ), LOG_WARNING ); - return false; - } - - /* check is there's no backend connection yet */ - if ( $this->connection === NULL ) - $this->connection = new Redis(); - - /* check if initialization was success or not */ - if ( $this->connection === NULL ) { - $this->log ( __translate__( 'error initializing Redis extension, exiting', $this->plugin_constant ) ); - return false; - } - - //$this->connection->setOption(Redis::OPT_PREFIX, $this->plugin_constant ); - - /* adding server * - foreach ( $this->options['servers'] as $server_id => $server ) { - /* in case of unix socket * - if ( $server['port'] === 0 ) { - try { - $this->status[$server_id] = $this->connection->connect ( $server['host'] ); - } catch ( RedisException $e ) { - $this->log ( sprintf( __translate__( 'adding %s to the Redis pool failed, error: %s', $this->plugin_constant ), $server['host'], $e ) ); - } - } - else { - try { - $this->status[$server_id] = $this->connection->connect ( $server['host'] , $server['port'] ); - } catch ( RedisException $e ) { - $this->log ( sprintf( __translate__( 'adding %s:%s to the Redis pool failed, error: %s', $this->plugin_constant ), $server['host'] , $server['port'], $e ) ); - } - } - - - $this->log ( sprintf( __translate__( 'server #%s added', $this->plugin_constant ), $server_id ) ); - }*/ - - /* adding server */ - $key = array_unshift ( array_keys ( $this->options['servers'] )); - $server = array_unshift( $this->options['servers'] ); - - try { - if ( $server['port'] === 0 ) - $this->status[$key] = $this->connection->connect ( $server['host'] ); - else - $this->status[$key] = $this->connection->connect ( $server['host'], $server['port'] ); - } catch ( RedisException $e ) { - $this->log ( sprintf( __translate__( 'adding %s to the Redis pool failed, error: %s', $this->plugin_constant ), $server['host'], $e ) ); - } - - $this->log ( sprintf( __translate__( 'server #%s added', $this->plugin_constant ), $server_id ) ); - - if ( !empty( $this->options['authpass'])) { - $auth = $this->connection->auth( $this->options['authpass'] ); - if ( $auth == false ) { - $this->log ( __translate__( 'Redis authentication failed, exiting', $this->plugin_constant ), LOG_WARNING ); - return false; - } - } - - /* backend is now alive */ - $this->alive = true; - $this->redis_status(); - } - - /** - * check current backend alive status for Memcached - * - */ - private function redis_status () { - /* server status will be calculated by getting server stats */ - $this->log ( __translate__("checking server statuses", $this->plugin_constant )); - - /* get servers statistic from connection */ - try { - $this->connection->ping(); - } catch ( RedisException $e ) { - $this->log ( sprintf( __translate__( 'Redis status check failed, error: %s', $this->plugin_constant ), $e ) ); - } - - $this->log ( sprintf( __translate__( 'Redis is up', $this->plugin_constant ), $server_id ) ); - } - - /** - * get function for Memcached backend - * - * @param string $key Key to get values for - * - */ - private function redis_get ( &$key ) { - return $this->connection->get($key); - } - - /** - * Set function for Memcached backend - * - * @param string $key Key to set with - * @param mixed $data Data to set - * - */ - private function redis_set ( &$key, &$data, &$expire ) { - $result = $this->connection->set ( $key, $data , Array('nx', 'ex' => $expire) ); - return $result; - } - - /** - * - * Flush memcached entries - */ - private function redis_flush ( ) { - return $this->connection->flushDB(); - } - - - /** - * Removes entry from Memcached or flushes Memcached storage - * - * @param mixed $keys String / array of string of keys to delete entries with - */ - private function redis_clear ( &$keys ) { - /* make an array if only one string is present, easier processing */ - if ( !is_array ( $keys ) ) - $keys = array ( $keys => true ); - - $kresults = $this->connection->delete( $keys ); - - foreach ( $kresults as $key => $value ) { - $this->log ( sprintf( __translate__( 'entry deleted: %s', $this->plugin_constant ), $value ) ); - } - } - - /*********************** END REDIS FUNCTIONS ***********************/ - + abstract protected function _init (); + abstract protected function _status (); + abstract protected function _get ( &$key ); + abstract protected function _set ( &$key, &$data, &$expire ); + abstract protected function _flush (); + abstract protected function _clear ( &$keys ); } endif; + + +$wp_ffpc_backends = glob( dirname( __FILE__ ) . "/backends/*.php" ); +foreach ( $wp_ffpc_backends as $backend ) + include_once $backend; +unset( $wp_ffpc_backends, $backend ); diff --git a/wp-ffpc-class.php b/wp-ffpc-class.php index 6cc9a98..d6d9c0c 100644 --- a/wp-ffpc-class.php +++ b/wp-ffpc-class.php @@ -85,7 +85,7 @@ class WP_FFPC extends WP_FFPC_ABSTRACT { /* nginx sample config file */ $this->nginx_sample = $this->plugin_dir . $this->plugin_constant . '-nginx-sample.conf'; /* backend driver file */ - $this->acache_backend = $this->plugin_dir . $this->plugin_constant . '-backend.php'; + $this->acache_backend = $this->plugin_dir . $this->plugin_constant . '-engine.php'; /* flush button identifier */ $this->button_flush = $this->plugin_constant . '-flush'; /* precache button identifier */ @@ -181,7 +181,8 @@ class WP_FFPC extends WP_FFPC_ABSTRACT { public function plugin_post_init () { /* initiate backend */ - $this->backend = new WP_FFPC_Backend ( $this->options ); + $backend_class = 'WP_FFPC_Backend_' . $this->options['cache_type']; + $this->backend = new $backend_class ( $this->options ); /* re-save settings after update */ add_action( 'upgrader_process_complete', array ( &$this->plugin_upgrade ), 10, 2 ); @@ -439,6 +440,7 @@ class WP_FFPC extends WP_FFPC_ABSTRACT { /* we need to go through all servers */ $servers = $this->backend->status(); + error_log(__CLASS__ . ':' .json_encode($servers)); if ( is_array( $servers ) && !empty ( $servers ) ) { foreach ( $servers as $server_string => $status ) { echo $server_string ." => "; @@ -705,19 +707,10 @@ class WP_FFPC extends WP_FFPC_ABSTRACT {
- - in case of TCP based connections, list the servers as host1:port1,host2:port2,... . Do not add trailing , and always separate host and port with : .
- in2.0.0b1 case using unix sockets with the Memcache driver: unix:// ', $this->plugin_constant); ?>
+ - in case of TCP based connections, list the servers as host1:port1,host2:port2,... . Do not add trailing , and always separate host and port with : .
- for a unix socket enter: unix://[socket_path]', $this->plugin_constant); ?>
-
- -
-
- options['memcached_binary'],true); ?> /> - plugin_constant); ?> -
- - options['cache_type'], 'memcached') && extension_loaded ( 'memcached' ) && version_compare( phpversion( 'memcached' ) , '2.0.0', '>=' ) || ( $this->options['cache_type'] == 'redis' ) ) { ?> +

options['authuser'] ) || !empty( $this->options['authpass'] ) ) ) { ?>

plugin_constant ) ?>

@@ -728,7 +721,7 @@ class WP_FFPC extends WP_FFPC_ABSTRACT {
- plugin_constant); ?> + plugin_constant); ?>
@@ -737,9 +730,19 @@ class WP_FFPC extends WP_FFPC_ABSTRACT {
- plugin_constant); ?> + plugin_constant); ?>
- + +

+
+ +
+
+ options['memcached_binary'],true); ?> /> + plugin_constant); ?> +
+ + @@ -988,12 +991,16 @@ class WP_FFPC extends WP_FFPC_ABSTRACT { */ private function deploy_advanced_cache( ) { - if ( @is_writable( $this->acache )) + if ( !is_writable( $this->acache )) { + error_log('Generating advanced-cache.php failed: '.$this->acache.' is not writable'); return false; + } /* if no active site left no need for advanced cache :( */ - if ( empty ( $this->global_config ) ) + if ( empty ( $this->global_config ) ) { + error_log('Generating advanced-cache.php failed: Global config is empty'); return false; + } /* add the required includes and generate the needed code */ $string[] = "acache, join( "\n" , $string ) ); + } /**