You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
316 lines
8.2 KiB
316 lines
8.2 KiB
<?php
|
|
/*
|
|
Plugin Name: Nginx Cache Custom
|
|
Plugin URI: http://wordpress.org/plugins/nginx-cache/
|
|
Description: Purge the Nginx cache (FastCGI, Proxy, uWSGI) automatically when content changes or manually within WordPress.
|
|
Version: 1.0.4
|
|
Text Domain: nginx-cache
|
|
Domain Path: /languages
|
|
Author: Till Krüss
|
|
Author URI: http://till.im/
|
|
License: GPLv3
|
|
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) exit;
|
|
|
|
class NginxCache {
|
|
|
|
private $screen = 'tools_page_nginx-cache';
|
|
private $capability = 'manage_options';
|
|
private $admin_page = 'tools.php?page=nginx-cache';
|
|
|
|
public function __construct() {
|
|
|
|
load_plugin_textdomain( 'nginx-cache', false, 'nginx-cache/languages' );
|
|
|
|
add_filter( 'option_nginx_cache_path', 'sanitize_text_field' );
|
|
add_filter( 'option_nginx_auto_purge', 'absint' );
|
|
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'add_plugin_actions_links' ) );
|
|
|
|
// if ( get_option( 'nginx_auto_purge' ) ) {
|
|
add_action( 'init', array( $this, 'register_purge_actions' ), 20 );
|
|
// }
|
|
|
|
add_action( 'admin_init', array( $this, 'register_settings' ) );
|
|
add_action( 'admin_menu', array( $this, 'add_admin_menu_page' ) );
|
|
add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_node' ), 100 );
|
|
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
|
|
add_action( 'load-' . $this->screen, array( $this, 'do_admin_actions' ) );
|
|
add_action( 'load-' . $this->screen, array( $this, 'add_settings_notices' ) );
|
|
}
|
|
|
|
public function register_purge_actions() {
|
|
|
|
// use `nginx_cache_purge_actions` filter to alter default purge actions
|
|
$purge_actions = (array) apply_filters(
|
|
'nginx_cache_purge_actions',
|
|
array(
|
|
'publish_phone', 'save_post', 'edit_post', 'delete_post', 'wp_trash_post', 'clean_post_cache',
|
|
'trackback_post', 'pingback_post', 'comment_post', 'edit_comment', 'delete_comment', 'wp_set_comment_status',
|
|
'switch_theme', 'wp_update_nav_menu', 'edit_user_profile_update'
|
|
)
|
|
);
|
|
|
|
foreach ( $purge_actions as $action ) {
|
|
if ( did_action( $action ) ) {
|
|
$this->purge_zone_once();
|
|
} else {
|
|
add_action( $action, array( $this, 'purge_zone_once' ) );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public function register_settings() {
|
|
|
|
register_setting( 'nginx-cache', 'nginx_cache_path', 'sanitize_text_field' );
|
|
register_setting( 'nginx-cache', 'nginx_auto_purge', 'absint' );
|
|
|
|
}
|
|
|
|
public function add_settings_notices() {
|
|
|
|
// $path_error = $this->is_valid_path();
|
|
|
|
if ( isset( $_GET[ 'message' ] ) && ! isset( $_GET[ 'settings-updated' ] ) ) {
|
|
|
|
// show cache purge success message
|
|
if ( $_GET[ 'message' ] === 'cache-purged' ) {
|
|
add_settings_error( '', 'nginx_cache_path', __( 'Cache purged.', 'nginx-cache' ), 'updated' );
|
|
}
|
|
|
|
// show cache purge failure message
|
|
if ( $_GET[ 'message' ] === 'purge-cache-failed' ) {
|
|
add_settings_error( '', 'nginx_cache_path', sprintf( __( 'Cache could not be purged. %s', 'nginx-cache' ), wptexturize( $path_error->get_error_message() ) ) );
|
|
}
|
|
|
|
} elseif ( is_wp_error( $path_error ) && $path_error->get_error_code() === 'fs' ) {
|
|
|
|
// show cache path problem message
|
|
add_settings_error( '', 'nginx_cache_path', wptexturize( $path_error->get_error_message( 'fs' ) ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public function do_admin_actions() {
|
|
|
|
// purge cache
|
|
if ( isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] === 'purge-cache' && wp_verify_nonce( $_GET[ '_wpnonce' ], 'purge-cache' ) ) {
|
|
|
|
$result = $this->purge_zone();
|
|
wp_safe_redirect( admin_url( add_query_arg( 'message', is_wp_error( $result ) ? 'purge-cache-failed' : 'cache-purged', $this->admin_page ) ) );
|
|
exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public function add_admin_bar_node( $wp_admin_bar ) {
|
|
|
|
// verify user capability
|
|
if ( ! current_user_can( $this->capability ) ) {
|
|
return;
|
|
}
|
|
|
|
// add "Nginx" node to admin-bar
|
|
$wp_admin_bar->add_node( array(
|
|
'id' => 'nginx-cache',
|
|
'title' => __( 'Nginx', 'nginx-cache' ),
|
|
'href' => admin_url( $this->admin_page )
|
|
) );
|
|
|
|
// add "Purge Cache" to "Nginx" node
|
|
$wp_admin_bar->add_node( array(
|
|
'parent' => 'nginx-cache',
|
|
'id' => 'purge-cache',
|
|
'title' => __( 'Purge Cache', 'nginx-cache' ),
|
|
'href' => wp_nonce_url( admin_url( add_query_arg( 'action', 'purge-cache', $this->admin_page ) ), 'purge-cache' )
|
|
) );
|
|
|
|
}
|
|
|
|
public function add_admin_menu_page() {
|
|
|
|
// add "Tools" sub-page
|
|
add_management_page(
|
|
__( 'Nginx Cache', 'nginx-cache' ),
|
|
__( 'Nginx Cache', 'nginx-cache' ),
|
|
$this->capability,
|
|
'nginx-cache',
|
|
array( $this, 'show_settings_page' )
|
|
);
|
|
|
|
}
|
|
|
|
public function show_settings_page() {
|
|
require_once plugin_dir_path( __FILE__ ) . '/includes/settings-page.php';
|
|
}
|
|
|
|
public function add_plugin_actions_links( $links ) {
|
|
|
|
// add settings link to plugin actions
|
|
return array_merge(
|
|
array( '<a href="' . admin_url( $this->admin_page ) . '">' . __( 'Settings', 'nginx-cache' ) . '</a>' ),
|
|
$links
|
|
);
|
|
|
|
}
|
|
|
|
public function enqueue_admin_styles( $hook_suffix ) {
|
|
|
|
if ( $hook_suffix === $this->screen ) {
|
|
$plugin = get_plugin_data( __FILE__ );
|
|
wp_enqueue_style( 'nginx-cache', plugin_dir_url( __FILE__ ) . 'includes/settings-page.css', null, $plugin[ 'Version' ] );
|
|
}
|
|
|
|
}
|
|
|
|
private function is_valid_path() {
|
|
|
|
global $wp_filesystem;
|
|
|
|
$path = get_option( 'nginx_cache_path' );
|
|
|
|
if ( empty( $path ) ) {
|
|
return new WP_Error( 'empty', __( '"Cache Zone Path" is not set.', 'nginx-cache' ) );
|
|
}
|
|
|
|
if ( $this->initialize_filesystem() ) {
|
|
|
|
if ( ! $wp_filesystem->exists( $path ) ) {
|
|
return new WP_Error( 'fs', __( '"Cache Zone Path" does not exist.', 'nginx-cache' ) );
|
|
}
|
|
|
|
if ( ! $wp_filesystem->is_dir( $path ) ) {
|
|
return new WP_Error( 'fs', __( '"Cache Zone Path" is not a directory.', 'nginx-cache' ) );
|
|
}
|
|
|
|
$list = $wp_filesystem->dirlist( $path, true, true );
|
|
|
|
if ( is_array( $list ) && ! $this->validate_dirlist( $list ) ) {
|
|
return new WP_Error( 'fs', __( '"Cache Zone Path" does not appear to be a Nginx cache zone directory.', 'nginx-cache' ) );
|
|
}
|
|
|
|
if ( ! $wp_filesystem->is_writable( $path ) ) {
|
|
return new WP_Error( 'fs', __( '"Cache Zone Path" is not writable.', 'nginx-cache' ) );
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return new WP_Error( 'fs', __( 'Filesystem API could not be initialized.', 'nginx-cache' ) );
|
|
|
|
}
|
|
|
|
private function validate_dirlist( $list ) {
|
|
|
|
foreach ( $list as $item ) {
|
|
|
|
// abort if file is not a MD5 hash
|
|
if ( $item[ 'type' ] === 'f' && ( strlen( $item[ 'name' ] ) !== 32 || ! ctype_xdigit( $item[ 'name' ] ) ) ) {
|
|
return false;
|
|
}
|
|
|
|
// validate subdirectories recursively
|
|
if ( $item[ 'type' ] === 'd' && ! $this->validate_dirlist( $item[ 'files' ] ) ) {
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
public function purge_zone_once() {
|
|
|
|
static $completed = false;
|
|
|
|
if ( ! $completed ) {
|
|
$this->purge_zone();
|
|
$completed = true;
|
|
}
|
|
|
|
}
|
|
|
|
private function purge_zone() {
|
|
|
|
global $wp_filesystem;
|
|
|
|
if ( ! $this->should_purge() ) {
|
|
return false;
|
|
}
|
|
|
|
// $path = get_option( 'nginx_cache_path' );
|
|
// $path_error = $this->is_valid_path();
|
|
|
|
// abort if cache zone path is not valid
|
|
// if ( is_wp_error( $path_error ) ) {
|
|
// return $path_error;
|
|
// }
|
|
|
|
// delete cache directory (recursively)
|
|
// $wp_filesystem->rmdir( $path, true );
|
|
|
|
// recreate empty cache directory
|
|
// $wp_filesystem->mkdir( $path );
|
|
|
|
system('sudo /bin/rm -r /var/run/nginx-cache/APP_NAME/*');
|
|
|
|
do_action( 'nginx_cache_zone_purged', $path );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
private function should_purge() {
|
|
|
|
$post_type = get_post_type();
|
|
|
|
if ( ! $post_type ) {
|
|
return true;
|
|
}
|
|
|
|
if ( ! in_array( $post_type, (array) apply_filters( 'nginx_cache_excluded_post_types', array() ) ) ) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private function initialize_filesystem() {
|
|
|
|
$path = get_option( 'nginx_cache_path' );
|
|
|
|
// if the cache directory doesn't exist, try to create it
|
|
if ( ! file_exists( $path ) ) {
|
|
mkdir( $path );
|
|
}
|
|
|
|
// load WordPress file API?
|
|
if ( ! function_exists( 'request_filesystem_credentials' ) ) {
|
|
require_once ABSPATH . 'wp-admin/includes/file.php';
|
|
}
|
|
|
|
ob_start();
|
|
$credentials = request_filesystem_credentials( '', '', false, $path, null, true );
|
|
ob_end_clean();
|
|
|
|
if ( $credentials === false ) {
|
|
return false;
|
|
}
|
|
|
|
if ( ! WP_Filesystem( $credentials, $path, true ) ) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new NginxCache;
|