Commit 8487a3d9 authored by Benjamin Adams's avatar Benjamin Adams
Browse files

Plugin and index page

parent 71667cd6
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
```
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index-wp-redis\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index-wp-redis\.php [L]
</IfModule>
# END WordPress
```
\ No newline at end of file
<?php
$seconds_cache_redis = 60*60*12; // 12 hours by default
$ip_of_your_website = '64.90.38.145'; //You must set this to the IP of your website
$secret_string = "changeme"; /*This must be the same as in the wp-admin section if you want to manually refresh the cache
ex: http://example.com/sample-post?refresh=changeme */
// so we don't confuse the cloudflare server
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
define('WP_USE_THEMES', true);
// Start the timer so we can track the page load time
$start = microtime();
include("wp-content/plugins/wp-redis-cache/predis5.2.php"); //we need this to use Redis inside of PHP
$redis = new Predis_Client();
$current_url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$current_url = str_replace("?refresh=$secret_string", '', $current_url); //clean up the URL
$current_url = str_replace("&refresh=$secret_string", '', $current_url);
$redis_key = md5($current_url);
//Either manual refresh cache by adding ?refresh=secret_string after the URL or somebody posting a comment
if (isset($_GET['refresh']) || $_GET['refresh']==$secret_string || ($_SERVER['HTTP_REFERER'] == $current_url && $_SERVER['REQUEST_URI'] != '/' && $_SERVER['REMOTE_ADDR'] != $ip_of_your_website)) {
$redis->del($redis_key);
require('./wp-blog-header.php');
// This page is cached, lets display it
} else if ($redis->exists($redis_key)) {
$html_of_page = $redis->get($redis_key);
echo $html_of_page;
// If the cache does not exist lets display the user the normal page without cache, and then fetch a new cache page
} else if ($_SERVER['REMOTE_ADDR'] != $ip_of_your_website && strstr($current_url, 'preview=true') == false) {
require('./wp-blog-header.php');
$html_of_page = @file_get_contents($current_url);
$usr_seconds=get_option('wp-redis-cache-seconds'); //if the user has the seconds defined in the admin section use it
if(isset($usr_seconds) && is_numeric($usr_seconds))
{
$seconds_cache_redis=$usr_seconds;
}
if(strlen($html_of_page) > 5000)
{
$redis->setex($redis_key, $seconds_cache_redis, $html_of_page);
}
// This is what your server should get if no cache exists
} else {
require('./wp-blog-header.php');
}
if ($_SERVER['REMOTE_ADDR'] != $ip_of_your_website) {
// How long did it take to load the page? (CloudFlare may strip out comments)
$end = microtime();
$time = (@getMicroTime($end) - @getMicroTime($start));
echo "<!-- Cache system by Benjamin Adams. Page generated in ".round($time,5)." seconds. -->";
}
function getMicroTime($t) {
list($usec, $sec) = explode(" ",$t);
return ((float)$usec + (float)$sec);
}
?>
\ No newline at end of file
<?php
add_action('transition_post_status', 'refresh_wp_redis_cache',10,3);
//clears the cache after you update a post
function refresh_wp_redis_cache( $new, $old, $post )
{
if($new == "publish")
{
$permalink = get_permalink( $post->ID );
include("predis5.2.php"); //we need this to use Redis inside of PHP
$redis = new Predis_Client();
$redis_key = md5($permalink);
$redis->del($redis_key);
}
}
\ No newline at end of file
<?php
class wctest{
public function __construct(){
if(is_admin()){
add_action('admin_menu', array($this, 'add_plugin_page'));
add_action('admin_init', array($this, 'page_init'));
}
}
public function add_plugin_page(){
// This page will be under "Settings"
add_options_page('Settings Admin', 'Settings', 'manage_options', 'test-setting-admin', array($this, 'create_admin_page'));
}
public function create_admin_page(){
?>
<div class="wrap">
<?php screen_icon(); ?>
<h2>Settings</h2>
<form method="post" action="options.php">
<?php
// This prints out all hidden setting fields
settings_fields('test_option_group');
do_settings_sections('test-setting-admin');
?>
<?php submit_button(); ?>
</form>
</div>
<?php
}
public function page_init(){
register_setting('test_option_group', 'array_key', array($this, 'check_ID'));
add_settings_section(
'setting_section_id',
'Setting',
array($this, 'print_section_info'),
'test-setting-admin'
);
add_settings_field(
'some_id',
'Some ID(Title)',
array($this, 'create_an_id_field'),
'test-setting-admin',
'setting_section_id'
);
}
public function check_ID($input){
if(is_numeric($input['some_id'])){
$mid = $input['some_id'];
if(get_option('test_some_id') === FALSE){
add_option('test_some_id', $mid);
}else{
update_option('test_some_id', $mid);
}
}else{
$mid = '';
}
return $mid;
}
public function print_section_info(){
print 'Enter your setting below:';
}
public function create_an_id_field(){
?><input type="text" id="input_whatever_unique_id_I_want" name="array_key[some_id]" value="<?=get_option('test_some_id');?>" /><?php
}
}
$wctest = new wctest();
\ No newline at end of file
<?php
/*
Plugin Name: Wp Redis Cache
Plugin URI: https://github.com/BenjaminAdams/wp-redis-cache
Description: Cache Wordpress with redis
Version: 1.0
Author: Benjamin Adams
Author URI: http://dudelol.com
/* Copyright 2013 Benjamin Adams (email : ben@dudelol.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//Custom Theme Settings
add_action('admin_menu', 'add_redis_interface');
function add_redis_interface() {
add_options_page('Wp Redis', 'Wp Redis', '8', 'functions', 'edit_redis_options');
}
function edit_redis_options() {
?>
<div class='wrap'>
<h2>Wp-Redis Options</h2>
<form method="post" action="options.php">
<?php wp_nonce_field('update-options') ?>
<p><strong>Seconds of Caching:</strong><br />
How many seconds would you like to cache? *Recommended 12 hours or 43200 seconds <br />
<input type="text" name="wp-redis-cache-seconds" size="45" value="<?php echo get_option('wp-redis-cache-seconds'); ?>" /></p>
<p><strong>Secret String:</strong><br />
To refresh the cache of your post manually you will need to set a secret string so do can refresh manually like so:
<br /> http://example.com/post_name?refresh=secret_string. <br />
<br />Important! You must change this in the index-wp-redis.php file<br />
<input type="text" name="wp-redis-secret" size="45" value="<?php echo get_option('wp-redis-secret'); ?>" /></p>
<p><input type="submit" name="Submit" value="Update Options" /></p>
<input type="hidden" name="action" value="update" />
<input type="hidden" name="page_options" value="wp-redis-cache-seconds,wp-redis-secret" />
</form>
</div>
<?php
}
include('cache.php');
\ No newline at end of file
<?php
class PredisException extends Exception { }
// Client-side errors
class Predis_ClientException extends PredisException { }
// Aborted multi/exec
class Predis_AbortedMultiExec extends PredisException { }
// Server-side errors
class Predis_ServerException extends PredisException {
public function toResponseError() {
return new Predis_ResponseError($this->getMessage());
}
}
// Communication errors
class Predis_CommunicationException extends PredisException {
private $_connection;
public function __construct(Predis_Connection $connection, $message = null, $code = null) {
$this->_connection = $connection;
parent::__construct($message, $code);
}
public function getConnection() { return $this->_connection; }
public function shouldResetConnection() { return true; }
}
// Unexpected responses
class Predis_MalformedServerResponse extends Predis_CommunicationException { }
/* ------------------------------------------------------------------------- */
class Predis_Client {
const VERSION = '0.6.6';
private $_options, $_connection, $_serverProfile, $_responseReader;
public function __construct($parameters = null, $clientOptions = null) {
$this->setupClient($clientOptions !== null ? $clientOptions : new Predis_ClientOptions());
$this->setupConnection($parameters);
}
public static function create(/* arguments */) {
$argv = func_get_args();
$argc = func_num_args();
$options = null;
$lastArg = $argv[$argc-1];
if ($argc > 0 && !is_string($lastArg) && ($lastArg instanceof Predis_ClientOptions ||
is_subclass_of($lastArg, 'Predis_RedisServerProfile'))) {
$options = array_pop($argv);
$argc--;
}
if ($argc === 0) {
throw new Predis_ClientException('Missing connection parameters');
}
return new Predis_Client($argc === 1 ? $argv[0] : $argv, $options);
}
private static function filterClientOptions($options) {
if ($options instanceof Predis_ClientOptions) {
return $options;
}
if (is_array($options)) {
return new Predis_ClientOptions($options);
}
if ($options instanceof Predis_RedisServerProfile) {
return new Predis_ClientOptions(array(
'profile' => $options
));
}
if (is_string($options)) {
return new Predis_ClientOptions(array(
'profile' => Predis_RedisServerProfile::get($options)
));
}
throw new InvalidArgumentException("Invalid type for client options");
}
private function setupClient($options) {
$options = self::filterClientOptions($options);
$this->setProfile($options->profile);
$reader = $options->reader;
$reader->setOption('iterable_multibulk', $options->iterable_multibulk);
$reader->setOption('throw_on_error', $options->throw_on_error);
$this->_options = $options;
$this->_responseReader = $reader;
}
private function setupConnection($parameters) {
if ($parameters !== null && !(is_array($parameters) || is_string($parameters))) {
throw new Predis_ClientException('Invalid parameters type (array or string expected)');
}
if (is_array($parameters) && isset($parameters[0])) {
$cluster = new Predis_ConnectionCluster($this->_options->key_distribution);
foreach ($parameters as $shardParams) {
$cluster->add($this->createConnection($shardParams));
}
$this->setConnection($cluster);
}
else {
$this->setConnection($this->createConnection($parameters));
}
}
private function createConnection($parameters) {
if (!$parameters instanceof Predis_ConnectionParameters) {
$parameters = new Predis_ConnectionParameters($parameters);
}
$connection = new Predis_Connection($parameters, $this->_responseReader);
if ($parameters->password !== null) {
$connection->pushInitCommand($this->createCommand(
'auth', array($parameters->password)
));
}
if ($parameters->database !== null) {
$connection->pushInitCommand($this->createCommand(
'select', array($parameters->database)
));
}
return $connection;
}
private function setConnection(Predis_IConnection $connection) {
$this->_connection = $connection;
}
public function setProfile($serverProfile) {
if ($serverProfile instanceof Predis_RedisServerProfile) {
$this->_serverProfile = $serverProfile;
}
else if (is_string($serverProfile)) {
$this->_serverProfile = Predis_RedisServerProfile::get($serverProfile);
}
else {
throw new InvalidArgumentException(
"Invalid type for server profile, Predis_RedisServerProfile or string expected"
);
}
}
public function getProfile() {
return $this->_serverProfile;
}
public function getResponseReader() {
return $this->_responseReader;
}
public function getClientFor($connectionAlias) {
if (!Predis_Shared_Utils::isCluster($this->_connection)) {
throw new Predis_ClientException(
'This method is supported only when the client is connected to a cluster of connections'
);
}
$connection = $this->_connection->getConnectionById($connectionAlias);
if ($connection === null) {
throw new InvalidArgumentException(
"Invalid connection alias: '$connectionAlias'"
);
}
$newClient = new Predis_Client();
$newClient->setupClient($this->_options);
$newClient->setConnection($connection);
return $newClient;
}
public function connect() {
$this->_connection->connect();
}
public function disconnect() {
$this->_connection->disconnect();
}
public function isConnected() {
return $this->_connection->isConnected();
}
public function getConnection($id = null) {
if (!isset($id)) {
return $this->_connection;
}
else {
return Predis_Shared_Utils::isCluster($this->_connection)
? $this->_connection->getConnectionById($id)
: $this->_connection;
}
}
public function __call($method, $arguments) {
$command = $this->_serverProfile->createCommand($method, $arguments);
return $this->_connection->executeCommand($command);
}
public function createCommand($method, $arguments = array()) {
return $this->_serverProfile->createCommand($method, $arguments);
}
public function executeCommand(Predis_Command $command) {
return $this->_connection->executeCommand($command);
}
public function executeCommandOnShards(Predis_Command $command) {
$replies = array();
if (Predis_Shared_Utils::isCluster($this->_connection)) {
foreach($this->_connection as $connection) {
$replies[] = $connection->executeCommand($command);
}
}
else {
$replies[] = $this->_connection->executeCommand($command);
}
return $replies;
}
public function rawCommand($rawCommandData, $closesConnection = false) {
if (Predis_Shared_Utils::isCluster($this->_connection)) {
throw new Predis_ClientException('Cannot send raw commands when connected to a cluster of Redis servers');
}
return $this->_connection->rawCommand($rawCommandData, $closesConnection);
}
private function sharedInitializer($argv, $initializer) {
$argc = count($argv);
if ($argc === 0) {
return $this->$initializer();
}
else if ($argc === 1) {
list($arg0) = $argv;
return is_array($arg0) ? $this->$initializer($arg0) : $this->$initializer(null, $arg0);
}
else if ($argc === 2) {
list($arg0, $arg1) = $argv;
return $this->$initializer($arg0, $arg1);
}
return $this->$initializer($this, $arguments);
}
public function pipeline(/* arguments */) {
$args = func_get_args();
return $this->sharedInitializer($args, 'initPipeline');
}
public function pipelineSafe($pipelineBlock = null) {
return $this->initPipeline(array('safe' => true), $pipelineBlock);
}
private function initPipeline(Array $options = null, $pipelineBlock = null) {
$pipeline = null;
if (isset($options)) {
if (isset($options['safe']) && $options['safe'] == true) {
$connection = $this->getConnection();
$pipeline = new Predis_CommandPipeline($this, $connection instanceof Predis_Connection
? new Predis_Pipeline_SafeExecutor($connection)
: new Predis_Pipeline_SafeClusterExecutor($connection)
);
}
else {
$pipeline = new Predis_CommandPipeline($this);
}
}
else {
$pipeline = new Predis_CommandPipeline($this);
}
return $this->pipelineExecute($pipeline, $pipelineBlock);
}
private function pipelineExecute(Predis_CommandPipeline $pipeline, $block) {
return $block !== null ? $pipeline->execute($block) : $pipeline;
}
public function multiExec(/* arguments */) {
$args = func_get_args();
return $this->sharedInitializer($args, 'initMultiExec');
}
private function initMultiExec(Array $options = null, $transBlock = null) {
$multi = isset($options) ? new Predis_MultiExecBlock($this, $options) : new Predis_MultiExecBlock($this);
return $transBlock !== null ? $multi->execute($transBlock) : $multi;
}
public function pubSubContext(Array $options = null) {
return new Predis_PubSubContext($this, $options);
}
}
/* ------------------------------------------------------------------------- */
interface Predis_IClientOptionsHandler {
public function validate($option, $value);
public function getDefault();
}
class Predis_ClientOptionsProfile implements Predis_IClientOptionsHandler {
public function validate($option, $value) {
if ($value instanceof Predis_RedisServerProfile) {
return $value;
}
if (is_string($value)) {
return Predis_RedisServerProfile::get($value);
}
throw new InvalidArgumentException("Invalid value for option $option");
}
public function getDefault() {
return Predis_RedisServerProfile::getDefault();
}
}
class Predis_ClientOptionsKeyDistribution implements Predis_IClientOptionsHandler {
public function validate($option, $value) {
if ($value instanceof Predis_Distribution_IDistributionStrategy) {
return $value;
}
if (is_string($value)) {
$valueReflection = new ReflectionClass($value);
if ($valueReflection->isSubclassOf('Predis_Distribution_IDistributionStrategy')) {
return new $value;
}
}
throw new InvalidArgumentException("Invalid value for option $option");
}
public function getDefault() {
return new Predis_Distribution_HashRing();
}
}
class Predis_ClientOptionsIterableMultiBulk implements Predis_IClientOptionsHandler {
public function validate($option, $value) {
return (bool) $value;
}
public function getDefault() {
return false;
}
}
class Predis_ClientOptionsThrowOnError implements Predis_IClientOptionsHandler {
public function validate($option, $value) {