2013-03-19 10:16:59 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* backend driver for WordPress plugin WP-FFPC
|
|
|
|
*
|
|
|
|
* supported storages:
|
|
|
|
* - APC
|
|
|
|
* - Memcached
|
|
|
|
* - Memcache
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (!class_exists('WP_FFPC_Backend')) {
|
2013-06-07 17:56:56 +01:00
|
|
|
|
|
|
|
/* get the plugin abstract class*/
|
|
|
|
include_once ( 'wp-common/wp-plugin-utilities.php');
|
|
|
|
|
|
|
|
|
2013-03-19 10:16:59 +00:00
|
|
|
/* __ 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); }
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
function __translate__ ( $text, $domain ) { return $text; }
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2013-06-18 10:57:31 +01:00
|
|
|
* @var string $plugin_constant Namespace of the plugin
|
2013-03-19 10:16:59 +00:00
|
|
|
* @var mixed $connection Backend object storage variable
|
2013-06-18 10:57:31 +01:00
|
|
|
* @var boolean $alive Alive flag of backend connection
|
|
|
|
* @var boolean $network WordPress Network flag
|
|
|
|
* @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
|
2013-03-19 10:16:59 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
class WP_FFPC_Backend {
|
|
|
|
|
|
|
|
const network_key = 'network';
|
|
|
|
const host_separator = ',';
|
|
|
|
const port_separator = ':';
|
|
|
|
|
2013-06-07 17:56:56 +01:00
|
|
|
private $plugin_constant = 'wp-ffpc';
|
2013-03-19 10:16:59 +00:00
|
|
|
private $connection = NULL;
|
|
|
|
private $alive = false;
|
2013-03-28 22:27:54 +00:00
|
|
|
private $network = false;
|
|
|
|
private $options = array();
|
|
|
|
private $status = array();
|
2013-06-07 17:56:56 +01:00
|
|
|
public $cookies = array();
|
2013-06-17 12:28:49 +01:00
|
|
|
private $urimap = array();
|
2013-06-07 17:56:56 +01:00
|
|
|
private $utilities;
|
2013-03-19 10:16:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* constructor
|
|
|
|
*
|
|
|
|
* @param mixed $config Configuration options
|
2013-06-18 10:57:31 +01:00
|
|
|
* @param boolean $network WordPress Network indicator flah
|
2013-03-19 10:16:59 +00:00
|
|
|
*
|
|
|
|
*/
|
2013-03-28 22:27:54 +00:00
|
|
|
public function __construct( $config, $network = false ) {
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2013-06-18 10:57:31 +01:00
|
|
|
/* no config, nothing is going to work */
|
2013-06-18 18:17:52 +01:00
|
|
|
if ( empty ( $config ) ) {
|
2013-06-18 10:57:31 +01:00
|
|
|
return false;
|
|
|
|
//die ( __translate__ ( 'WP-FFPC Backend class received empty configuration array, the plugin will not work this way', $this->plugin_constant ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set config */
|
2013-03-19 10:16:59 +00:00
|
|
|
$this->options = $config;
|
2013-06-18 10:57:31 +01:00
|
|
|
|
|
|
|
/* set network flag */
|
2013-03-28 22:27:54 +00:00
|
|
|
$this->network = $network;
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2013-06-18 10:57:31 +01:00
|
|
|
/* these are the list of the cookies to look for when looking for logged in user */
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->cookies = array ( 'comment_author_' , 'wordpressuser_' , 'wp-postpass_', 'wordpress_logged_in_' );
|
|
|
|
|
2013-06-18 10:57:31 +01:00
|
|
|
/* make utilities singleton */
|
2013-06-17 12:28:49 +01:00
|
|
|
$this->utilities = WP_Plugins_Utilities_v1::Utility();
|
|
|
|
|
2013-06-18 10:57:31 +01:00
|
|
|
/* map the key with the predefined schemes */
|
2013-06-17 14:22:46 +01:00
|
|
|
$ruser = isset ( $_SERVER['REMOTE_USER'] ) ? $_SERVER['REMOTE_USER'] : '';
|
|
|
|
$ruri = isset ( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '';
|
|
|
|
$rhost = isset ( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : '';
|
|
|
|
$scookie = isset ( $_COOKIE['PHPSESSID'] ) ? $_COOKIE['PHPSESSID'] : '';
|
|
|
|
|
2013-06-17 12:28:49 +01:00
|
|
|
$this->urimap = array(
|
|
|
|
'$scheme' => str_replace ( '://', '', $this->utilities->replace_if_ssl ( 'http://' ) ),
|
2013-06-17 14:22:46 +01:00
|
|
|
'$host' => $rhost,
|
|
|
|
'$request_uri' => $ruri,
|
|
|
|
'$remote_user' => $ruser,
|
|
|
|
'$cookie_PHPSESSID' => $scookie,
|
2013-06-17 12:28:49 +01:00
|
|
|
);
|
2013-06-07 17:56:56 +01:00
|
|
|
|
2013-03-19 10:16:59 +00:00
|
|
|
/* split hosts entry to servers */
|
|
|
|
$this->set_servers();
|
|
|
|
|
|
|
|
/* call backend initiator based on cache type */
|
|
|
|
$init = $this->proxy( 'init' );
|
|
|
|
|
2013-06-18 10:57:31 +01:00
|
|
|
/* info level */
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__('init starting', $this->plugin_constant ));
|
2013-03-19 10:16:59 +00:00
|
|
|
$this->$init();
|
2013-06-17 14:22:46 +01:00
|
|
|
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
|
2013-06-18 10:57:31 +01:00
|
|
|
/*********************** PUBLIC / PROXY FUNCTIONS ***********************/
|
2013-03-19 10:16:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* build key to make requests with
|
|
|
|
*
|
2013-03-28 22:27:54 +00:00
|
|
|
* @param string $prefix prefix to add to prefix
|
2013-03-19 10:16:59 +00:00
|
|
|
*
|
|
|
|
*/
|
2013-03-28 22:27:54 +00:00
|
|
|
public function key ( &$prefix ) {
|
2013-06-17 12:28:49 +01:00
|
|
|
/* data is string only with content, meta is not used in nginx */
|
2013-06-25 17:23:40 +01:00
|
|
|
$key = $prefix . str_replace ( array_keys( $this->urimap ), $this->urimap, $this->options['key'] );
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'original key configuration: %s', $this->plugin_constant ), $this->options['key'] ) );
|
|
|
|
$this->log ( sprintf( __translate__( 'setting key to: %s', $this->plugin_constant ), $key ) );
|
2013-06-17 12:28:49 +01:00
|
|
|
return $key;
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* public get function, transparent proxy to internal function based on backend
|
|
|
|
*
|
|
|
|
* @param string $key Cache key to get value for
|
|
|
|
*
|
|
|
|
* @return mixed False when entry not found or entry value on success
|
|
|
|
*/
|
|
|
|
public function get ( &$key ) {
|
|
|
|
|
|
|
|
/* look for backend aliveness, exit on inactive backend */
|
|
|
|
if ( ! $this->is_alive() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* log the current action */
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'get %s', $this->plugin_constant ), $key ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
|
|
|
|
/* proxy to internal function */
|
|
|
|
$internal = $this->proxy( 'get' );
|
|
|
|
$result = $this->$internal( $key );
|
|
|
|
|
|
|
|
if ( $result === false )
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'failed to get entry: %s', $this->plugin_constant ), $key ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* public set function, transparent proxy to internal function based on backend
|
|
|
|
*
|
|
|
|
* @param string $key Cache key to set with ( reference only, for speed )
|
|
|
|
* @param mixed $data Data to set ( reference only, for speed )
|
|
|
|
*
|
|
|
|
* @return mixed $result status of set function
|
|
|
|
*/
|
|
|
|
public function set ( &$key, &$data ) {
|
|
|
|
|
|
|
|
/* look for backend aliveness, exit on inactive backend */
|
|
|
|
if ( ! $this->is_alive() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* log the current action */
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'set %s expiration time: %s', $this->plugin_constant ), $key, $this->options['expire'] ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
|
|
|
|
/* proxy to internal function */
|
2014-05-30 11:22:21 +01:00
|
|
|
$internal = $this->proxy( 'set' );
|
2013-03-19 10:16:59 +00:00
|
|
|
$result = $this->$internal( $key, $data );
|
|
|
|
|
|
|
|
/* check result validity */
|
|
|
|
if ( $result === false )
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'failed to set entry: %s', $this->plugin_constant ), $key ), LOG_WARNING );
|
2013-03-19 10:16:59 +00:00
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* public get function, transparent proxy to internal function based on backend
|
|
|
|
*
|
2013-06-18 10:57:31 +01:00
|
|
|
* @param string $post_id ID of post to invalidate
|
|
|
|
* @param boolean $force Force flush cache
|
2014-05-12 15:48:22 +01:00
|
|
|
* @param boolean $comment Clear a single page based on comment trigger
|
2013-06-18 10:57:31 +01:00
|
|
|
*
|
2013-03-19 10:16:59 +00:00
|
|
|
*/
|
2013-03-28 22:27:54 +00:00
|
|
|
public function clear ( $post_id = false, $force = false ) {
|
2013-03-19 10:16:59 +00:00
|
|
|
|
|
|
|
/* look for backend aliveness, exit on inactive backend */
|
|
|
|
if ( ! $this->is_alive() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* exit if no post_id is specified */
|
2013-03-28 22:27:54 +00:00
|
|
|
if ( empty ( $post_id ) && $force === false ) {
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__('not clearing unidentified post ', $this->plugin_constant ), LOG_WARNING );
|
2013-03-19 10:16:59 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if invalidation method is set to full, flush cache */
|
2014-05-12 15:48:22 +01:00
|
|
|
if ( ( $this->options['invalidation_method'] === 0 || $force === true ) ) {
|
2013-03-19 10:16:59 +00:00
|
|
|
/* log action */
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__('flushing cache', $this->plugin_constant ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
|
|
|
|
/* proxy to internal function */
|
|
|
|
$internal = $this->proxy ( 'flush' );
|
|
|
|
$result = $this->$internal();
|
|
|
|
|
|
|
|
if ( $result === false )
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__('failed to flush cache', $this->plugin_constant ), LOG_WARNING );
|
2013-03-19 10:16:59 +00:00
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2013-03-28 22:27:54 +00:00
|
|
|
/* storage for entries to clear */
|
|
|
|
$to_clear = array();
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2013-03-28 22:27:54 +00:00
|
|
|
/* clear taxonomies if settings requires it */
|
|
|
|
if ( $this->options['invalidation_method'] == 2 ) {
|
|
|
|
/* this will only clear the current blog's entries */
|
|
|
|
$this->taxonomy_links( $to_clear );
|
|
|
|
}
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2013-03-28 22:27:54 +00:00
|
|
|
/* if there's a post id pushed, it needs to be invalidated in all cases */
|
|
|
|
if ( !empty ( $post_id ) ) {
|
|
|
|
|
|
|
|
/* need permalink functions */
|
|
|
|
if ( !function_exists('get_permalink') )
|
|
|
|
include_once ( ABSPATH . 'wp-includes/link-template.php' );
|
|
|
|
|
|
|
|
/* get path from permalink */
|
|
|
|
$path = substr ( get_permalink( $post_id ) , 7 );
|
|
|
|
|
|
|
|
/* no path, don't do anything */
|
|
|
|
if ( empty( $path ) ) {
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'unable to determine path from Post Permalink, post ID: %s', $this->plugin_constant ), $post_id ), LOG_WARNING );
|
2013-03-28 22:27:54 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( isset($_SERVER['HTTPS']) && ( ( strtolower($_SERVER['HTTPS']) == 'on' ) || ( $_SERVER['HTTPS'] == '1' ) ) )
|
|
|
|
$protocol = 'https://';
|
|
|
|
else
|
|
|
|
$protocol = 'http://';
|
|
|
|
|
|
|
|
/* elements to clear
|
|
|
|
values are keys, faster to process and eliminates duplicates
|
|
|
|
*/
|
|
|
|
$to_clear[ $protocol . $path ] = true;
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
|
2013-03-28 22:27:54 +00:00
|
|
|
foreach ( $to_clear as $link => $dummy ) {
|
|
|
|
/* clear all feeds as well */
|
|
|
|
$to_clear[ $link. 'feed' ] = true;
|
|
|
|
}
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2013-03-28 22:27:54 +00:00
|
|
|
/* add data & meta prefixes */
|
|
|
|
foreach ( $to_clear as $link => $dummy ) {
|
|
|
|
unset ( $to_clear [ $link ]);
|
|
|
|
$to_clear[ $this->options[ 'prefix_meta' ] . $link ] = true;
|
|
|
|
$to_clear[ $this->options[ 'prefix_data' ] . $link ] = true;
|
|
|
|
}
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2013-03-28 22:27:54 +00:00
|
|
|
/* run clear */
|
2013-03-19 10:16:59 +00:00
|
|
|
$internal = $this->proxy ( 'clear' );
|
|
|
|
$this->$internal ( $to_clear );
|
|
|
|
}
|
|
|
|
|
2014-05-12 15:48:22 +01:00
|
|
|
/**
|
|
|
|
* clear cache triggered by new comment
|
|
|
|
*
|
|
|
|
* @param $comment_id Comment ID
|
|
|
|
* @param $comment_object The whole comment object ?
|
|
|
|
*/
|
|
|
|
public function clear_by_comment ( $comment_id, $comment_object ) {
|
|
|
|
if ( empty( $comment_id ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
$comment = get_comment( $comment_id );
|
|
|
|
$post_id = $comment->comment_post_ID;
|
|
|
|
if ( !empty( $post_id ) )
|
|
|
|
$this->clear ( $post_id );
|
|
|
|
|
|
|
|
unset ( $comment );
|
|
|
|
unset ( $post_id );
|
|
|
|
}
|
|
|
|
|
2013-03-28 22:27:54 +00:00
|
|
|
/**
|
|
|
|
* to collect all permalinks of all taxonomy terms used in invalidation & precache
|
|
|
|
*
|
|
|
|
* @param array &$links Passed by reference array that has to be filled up with the links
|
|
|
|
* @param mixed $site Site ID or false; used in WordPress Network
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public function taxonomy_links ( &$links, $site = false ) {
|
|
|
|
|
|
|
|
if ( $site !== false ) {
|
|
|
|
$current_blog = get_current_blog_id();
|
|
|
|
switch_to_blog( $site );
|
|
|
|
|
|
|
|
$url = get_blog_option ( $site, 'siteurl' );
|
|
|
|
if ( substr( $url, -1) !== '/' )
|
|
|
|
$url = $url . '/';
|
|
|
|
|
|
|
|
$links[ $url ] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we're only interested in public taxonomies */
|
|
|
|
$args = array(
|
|
|
|
'public' => true,
|
|
|
|
);
|
|
|
|
|
|
|
|
/* get taxonomies as objects */
|
|
|
|
$taxonomies = get_taxonomies( $args, 'objects' );
|
|
|
|
|
|
|
|
if ( !empty( $taxonomies ) ) {
|
|
|
|
foreach ( $taxonomies as $taxonomy ) {
|
|
|
|
/* reset array, just in case */
|
|
|
|
$terms = array();
|
|
|
|
|
|
|
|
/* get all the terms for this taxonomy, only if not empty */
|
|
|
|
$sargs = array(
|
|
|
|
'hide_empty' => true,
|
|
|
|
'fields' => 'all',
|
|
|
|
'hierarchical' =>false,
|
|
|
|
);
|
|
|
|
$terms = get_terms ( $taxonomy->name , $sargs );
|
|
|
|
|
|
|
|
if ( !empty ( $terms ) ) {
|
|
|
|
foreach ( $terms as $term ) {
|
|
|
|
/* get the permalink for the term */
|
|
|
|
$link = get_term_link ( $term->slug, $taxonomy->name );
|
|
|
|
/* add to container */
|
|
|
|
$links[ $link ] = true;
|
|
|
|
/* remove the taxonomy name from the link, lots of plugins remove this for SEO, it's better to include them than leave them out
|
|
|
|
in worst case, we cache some 404 as well
|
|
|
|
*/
|
|
|
|
$link = str_replace ( '/'.$taxonomy->rewrite['slug'], '', $link );
|
|
|
|
/* add to container */
|
|
|
|
$links[ $link ] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* switch back to original site if we navigated away */
|
|
|
|
if ( $site !== false ) {
|
|
|
|
switch_to_blog( $current_blog );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-03-19 10:16:59 +00:00
|
|
|
/**
|
|
|
|
* get backend aliveness
|
|
|
|
*
|
|
|
|
* @return array Array of configured servers with aliveness value
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public function status () {
|
|
|
|
|
|
|
|
/* look for backend aliveness, exit on inactive backend */
|
|
|
|
if ( ! $this->is_alive() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
$internal = $this->proxy ( 'status' );
|
2013-03-25 12:38:25 +00:00
|
|
|
$this->$internal();
|
|
|
|
return $this->status;
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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() {
|
|
|
|
if ( ! $this->alive ) {
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__("backend is not active, exiting function ", $this->plugin_constant ) . __FUNCTION__, LOG_WARNING );
|
2013-03-19 10:16:59 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* split hosts string to backend servers
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
private function set_servers () {
|
|
|
|
/* replace servers array in config according to hosts field */
|
|
|
|
$servers = explode( self::host_separator , $this->options['hosts']);
|
|
|
|
|
|
|
|
$options['servers'] = array();
|
|
|
|
|
|
|
|
foreach ( $servers as $snum => $sstring ) {
|
|
|
|
|
|
|
|
$separator = strpos( $sstring , self::port_separator );
|
|
|
|
$host = substr( $sstring, 0, $separator );
|
|
|
|
$port = substr( $sstring, $separator + 1 );
|
2013-11-07 21:11:12 +00:00
|
|
|
// unix socket failsafe
|
|
|
|
if ( empty ($port) ) $port = 0;
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2013-11-07 21:11:12 +00:00
|
|
|
$this->options['servers'][$sstring] = array (
|
|
|
|
'host' => $host,
|
|
|
|
'port' => $port
|
|
|
|
);
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get current array of servers
|
|
|
|
*
|
|
|
|
* @return array Server list in current config
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public function get_servers () {
|
2013-06-18 18:17:52 +01:00
|
|
|
$r = isset ( $this->options['servers'] ) ? $this->options['servers'] : '';
|
|
|
|
return $r;
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2013-06-07 17:56:56 +01:00
|
|
|
* log wrapper to include options
|
2013-03-19 10:16:59 +00:00
|
|
|
*
|
2013-06-18 10:57:31 +01:00
|
|
|
* @var mixed $message Message to log
|
|
|
|
* @var int $log_level Log level
|
2013-03-19 10:16:59 +00:00
|
|
|
*/
|
2013-04-25 10:35:11 +01:00
|
|
|
private function log ( $message, $log_level = LOG_WARNING ) {
|
|
|
|
if ( !isset ( $this->options['log'] ) || $this->options['log'] != 1 )
|
2013-03-19 10:16:59 +00:00
|
|
|
return false;
|
2013-06-07 17:56:56 +01:00
|
|
|
else
|
|
|
|
$this->utilities->log ( $this->plugin_constant , $message, $log_level );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************** 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 */
|
2014-05-30 11:22:21 +01:00
|
|
|
if ( ! function_exists( 'apc_cache_info' ) ) {
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__('APC extension missing', $this->plugin_constant ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* verify apc is working */
|
2014-05-30 11:22:21 +01:00
|
|
|
if ( apc_cache_info("user",true) ) {
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__('backend OK', $this->plugin_constant ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
$this->alive = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* health checker for APC
|
|
|
|
*
|
|
|
|
* @return boolean Aliveness status
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
private function apc_status () {
|
2013-03-25 12:41:16 +00:00
|
|
|
$this->status = true;
|
2013-03-19 10:16:59 +00:00
|
|
|
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 ) {
|
|
|
|
return apc_store( $key , $data , $this->options['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
|
|
|
|
*/
|
2013-03-28 22:27:54 +00:00
|
|
|
private function apc_clear ( &$keys ) {
|
2013-03-19 10:16:59 +00:00
|
|
|
/* make an array if only one string is present, easier processing */
|
|
|
|
if ( !is_array ( $keys ) )
|
2013-03-28 22:27:54 +00:00
|
|
|
$keys = array ( $keys => true );
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2013-03-28 22:27:54 +00:00
|
|
|
foreach ( $keys as $key => $dummy ) {
|
2013-03-19 10:16:59 +00:00
|
|
|
if ( ! apc_delete ( $key ) ) {
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'Failed to delete APC entry: %s', $this->plugin_constant ), $key ), LOG_ERR );
|
2013-06-07 17:56:56 +01:00
|
|
|
//throw new Exception ( __translate__('Deleting APC entry failed with key ', $this->plugin_constant ) . $key );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
else {
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'APC entry delete: %s', $this->plugin_constant ), $key ) );
|
2014-05-30 11:22:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************** 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",true) ) {
|
|
|
|
$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 ) {
|
|
|
|
return apcu_store( $key , $data , $this->options['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_ERR );
|
|
|
|
//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 ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************** END APC FUNCTIONS ***********************/
|
|
|
|
|
2014-05-12 15:48:22 +01:00
|
|
|
/*********************** XCACHE FUNCTIONS ***********************/
|
|
|
|
/**
|
|
|
|
* init apc backend: test APC availability and set alive status
|
|
|
|
*/
|
|
|
|
private function xcache_init () {
|
|
|
|
/* verify apc functions exist, apc extension is loaded */
|
|
|
|
if ( ! function_exists( 'xcache_info' ) ) {
|
|
|
|
$this->log ( __translate__('XCACHE extension missing', $this->plugin_constant ) );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* verify apc is working */
|
|
|
|
$info = xcache_info();
|
|
|
|
if ( !empty( $info )) {
|
|
|
|
$this->log ( __translate__('backend OK', $this->plugin_constant ) );
|
|
|
|
$this->alive = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* health checker for Xcache
|
|
|
|
*
|
|
|
|
* @return boolean Aliveness status
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
private function xcache_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 xcache_get ( &$key ) {
|
|
|
|
if ( xcache_isset ( $key ) )
|
|
|
|
return xcache_get( $key );
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 xcache_set ( &$key, &$data ) {
|
|
|
|
return xcache_set( $key , $data , $this->options['expire'] );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Flushes APC user entry storage
|
|
|
|
*
|
|
|
|
* @return boolean APC flush outcome status
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
private function xcache_flush ( ) {
|
|
|
|
return xcache_clear_cache(XC_TYPE_VAR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes entry from APC or flushes APC user entry storage
|
|
|
|
*
|
|
|
|
* @param mixed $keys Keys to clear, string or array
|
|
|
|
*/
|
|
|
|
private function xcache_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 ( ! xcache_unset ( $key ) ) {
|
|
|
|
$this->log ( sprintf( __translate__( 'Failed to delete XCACHE entry: %s', $this->plugin_constant ), $key ), LOG_ERR );
|
|
|
|
//throw new Exception ( __translate__('Deleting APC entry failed with key ', $this->plugin_constant ) . $key );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$this->log ( sprintf( __translate__( 'XCACHE entry delete: %s', $this->plugin_constant ), $key ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************** END XCACHE FUNCTIONS ***********************/
|
|
|
|
|
|
|
|
|
2013-03-19 10:16:59 +00:00
|
|
|
/*********************** MEMCACHED FUNCTIONS ***********************/
|
|
|
|
/**
|
|
|
|
* init memcached backend
|
|
|
|
*/
|
|
|
|
private function memcached_init () {
|
|
|
|
/* Memcached class does not exist, Memcached extension is not available */
|
|
|
|
if (!class_exists('Memcached')) {
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__(' Memcached extension missing', $this->plugin_constant ), LOG_ERR );
|
2013-03-19 10:16:59 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check for existing server list, otherwise we cannot add backends */
|
|
|
|
if ( empty ( $this->options['servers'] ) && ! $this->alive ) {
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__("Memcached servers list is empty, init failed", $this->plugin_constant ), LOG_WARNING );
|
2013-03-19 10:16:59 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check is there's no backend connection yet */
|
|
|
|
if ( $this->connection === NULL ) {
|
|
|
|
/* persistent backend needs an identifier */
|
|
|
|
if ( $this->options['persistent'] == '1' )
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->connection = new Memcached( $this->plugin_constant );
|
2013-03-19 10:16:59 +00:00
|
|
|
else
|
|
|
|
$this->connection = new Memcached();
|
|
|
|
|
|
|
|
/* use binary and not compressed format, good for nginx and still fast */
|
|
|
|
$this->connection->setOption( Memcached::OPT_COMPRESSION , false );
|
2013-03-19 18:08:34 +00:00
|
|
|
$this->connection->setOption( Memcached::OPT_BINARY_PROTOCOL , true );
|
2014-06-02 16:02:13 +01:00
|
|
|
|
|
|
|
if ( version_compare( phpversion( 'memcached' ) , '2.0.0', '>=' ) && ini_get( 'memcached.use_sasl' ) == 1 ) {
|
|
|
|
$this->connection->setSaslAuthData ( $this->options['authuser'], $this->options['authpass']);
|
|
|
|
}
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check if initialization was success or not */
|
|
|
|
if ( $this->connection === NULL ) {
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__( 'error initializing Memcached PHP extension, exiting', $this->plugin_constant ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
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'] );
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( '%s added, persistent mode: %s', $this->plugin_constant ), $server_id, $this->options['persistent'] ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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 */
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__("checking server statuses", $this->plugin_constant ));
|
2013-03-19 10:16:59 +00:00
|
|
|
/* get servers statistic from connection */
|
|
|
|
$report = $this->connection->getStats();
|
|
|
|
|
|
|
|
foreach ( $report as $server_id => $details ) {
|
|
|
|
/* reset server status to offline */
|
|
|
|
$this->status[$server_id] = 0;
|
|
|
|
/* if server uptime is not empty, it's most probably up & running */
|
|
|
|
if ( !empty($details['uptime']) ) {
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( '%s server is up & running', $this->plugin_constant ), $server_id ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
$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 ) {
|
|
|
|
$result = $this->connection->set ( $key, $data , $this->options['expire'] );
|
|
|
|
|
|
|
|
/* if storing failed, log the error code */
|
|
|
|
if ( $result === false ) {
|
|
|
|
$code = $this->connection->getResultCode();
|
2014-04-29 15:58:50 +01:00
|
|
|
$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 ) );
|
2013-06-07 17:56:56 +01:00
|
|
|
//throw new Exception ( __translate__('Unable to store Memcached entry ', $this->plugin_constant ) . $key . __translate__( ', error code: ', $this->plugin_constant ) . $code );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
2013-03-28 22:27:54 +00:00
|
|
|
private function memcached_clear ( &$keys ) {
|
2013-03-19 10:16:59 +00:00
|
|
|
|
|
|
|
/* make an array if only one string is present, easier processing */
|
|
|
|
if ( !is_array ( $keys ) )
|
2013-03-28 22:27:54 +00:00
|
|
|
$keys = array ( $keys => true );
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2013-03-28 22:27:54 +00:00
|
|
|
foreach ( $keys as $key => $dummy ) {
|
2013-03-19 10:16:59 +00:00
|
|
|
$kresult = $this->connection->delete( $key );
|
|
|
|
|
|
|
|
if ( $kresult === false ) {
|
|
|
|
$code = $this->connection->getResultCode();
|
2014-04-29 15:58:50 +01:00
|
|
|
$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 ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
else {
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'entry deleted: %s', $this->plugin_constant ), $key ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*********************** 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')) {
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__('PHP Memcache extension missing', $this->plugin_constant ), LOG_ERR );
|
2013-03-19 10:16:59 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check for existing server list, otherwise we cannot add backends */
|
|
|
|
if ( empty ( $this->options['servers'] ) && ! $this->alive ) {
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__("servers list is empty, init failed", $this->plugin_constant ), LOG_WARNING );
|
2013-03-19 10:16:59 +00:00
|
|
|
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 ) {
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__( 'error initializing Memcache PHP extension, exiting', $this->plugin_constant ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* adding servers */
|
|
|
|
foreach ( $this->options['servers'] as $server_id => $server ) {
|
|
|
|
if ( $this->options['persistent'] == '1' )
|
2013-11-07 21:11:12 +00:00
|
|
|
$conn = 'pconnect';
|
|
|
|
else
|
|
|
|
$conn = 'connect';
|
|
|
|
|
|
|
|
/* in case of unix socket */
|
|
|
|
if ( $server['port'] === 0 )
|
|
|
|
$this->status[$server_id] = $this->connection->$conn ( 'unix:/' . $server['host'] );
|
2013-03-19 10:16:59 +00:00
|
|
|
else
|
2013-11-07 21:11:12 +00:00
|
|
|
$this->status[$server_id] = $this->connection->$conn ( $server['host'] , $server['port'] );
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( '%s added, persistent mode: %s', $this->plugin_constant ), $server_id, $this->options['persistent'] ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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 */
|
2013-06-07 17:56:56 +01:00
|
|
|
$this->log ( __translate__("checking server statuses", $this->plugin_constant ));
|
2013-03-19 10:16:59 +00:00
|
|
|
/* 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 )
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( '%s server is down', $this->plugin_constant ), $server_id ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
else
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( '%s server is up & running', $this->plugin_constant ), $server_id ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 ) {
|
|
|
|
$result = $this->connection->set ( $key, $data , 0 , $this->options['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
|
|
|
|
*/
|
2013-03-28 22:27:54 +00:00
|
|
|
private function memcache_clear ( &$keys ) {
|
2013-03-19 10:16:59 +00:00
|
|
|
/* make an array if only one string is present, easier processing */
|
|
|
|
if ( !is_array ( $keys ) )
|
2013-03-28 22:27:54 +00:00
|
|
|
$keys = array ( $keys => true );
|
2013-03-19 10:16:59 +00:00
|
|
|
|
2013-03-28 22:27:54 +00:00
|
|
|
foreach ( $keys as $key => $dummy ) {
|
2013-03-19 10:16:59 +00:00
|
|
|
$kresult = $this->connection->delete( $key );
|
|
|
|
|
2013-03-19 18:08:34 +00:00
|
|
|
if ( $kresult === false ) {
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'unable to delete entry: %s', $this->plugin_constant ), $key ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
2013-03-19 18:08:34 +00:00
|
|
|
else {
|
2014-04-29 15:58:50 +01:00
|
|
|
$this->log ( sprintf( __translate__( 'entry deleted: %s', $this->plugin_constant ), $key ) );
|
2013-03-19 10:16:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************** END MEMCACHE FUNCTIONS ***********************/
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-06-25 17:23:40 +01:00
|
|
|
?>
|