Skip to content

Commit

Permalink
Merge branch 'feature/261' into 000000-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
raamdev committed Aug 6, 2014
2 parents 58debdf + be6a67f commit f012c36
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 18 deletions.
16 changes: 8 additions & 8 deletions quick-cache/includes/menu-pages.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,17 @@ public function options()

echo '<div class="plugin-menu-page-panel">'."\n";

echo ' <a href="#" class="plugin-menu-page-panel-heading">'."\n";
echo ' <i class="fa fa-shield"></i> '.__('Deactivation Safeguards', $this->plugin->text_domain)."\n";
echo ' </a>'."\n";
echo ' <div class="plugin-menu-page-panel-heading">'."\n";
echo ' <i class="fa fa-shield"></i> '.__('Plugin Deletion Safeguards', $this->plugin->text_domain)."\n";
echo ' </div>'."\n";

echo ' <div class="plugin-menu-page-panel-body clearfix">'."\n";
echo ' <i class="fa fa-shield fa-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
echo ' <h3>'.__('Uninstall on Deactivation; or Safeguard Options?', $this->plugin->text_domain).'</h3>'."\n";
echo ' <p>'.__('<strong>Tip:</strong> By default, if you deactivate Quick Cache from the plugins menu in WordPress; nothing is lost. However, if you want to uninstall Quick Cache you should set this to <code>Yes</code> and <strong>THEN</strong> deactivate it from the plugins menu in WordPress. This way Quick Cache will erase your options for the plugin, clear the cache, remove the <code>advanced-cache.php</code> file, terminate CRON jobs, etc. It erases itself from existence completely.', $this->plugin->text_domain).'</p>'."\n";
echo ' <p><select name="'.esc_attr(__NAMESPACE__).'[save_options][uninstall_on_deactivation]">'."\n";
echo ' <option value="0"'.selected($this->plugin->options['uninstall_on_deactivation'], '0', FALSE).'>'.__('If I deactivate Quick Cache please safeguard my options and the cache (recommended).', $this->plugin->text_domain).'</option>'."\n";
echo ' <option value="1"'.selected($this->plugin->options['uninstall_on_deactivation'], '1', FALSE).'>'.__('Yes, uninstall (completely erase) Quick Cache on deactivation.', $this->plugin->text_domain).'</option>'."\n";
echo ' <h3>'.__('Uninstall on Plugin Deletion; or Safeguard Options?', $this->plugin->text_domain).'</h3>'."\n";
echo ' <p>'.__('<strong>Tip:</strong> By default, if you delete Quick Cache using the plugins menu in WordPress, nothing is lost. However, if you want to completely uninstall Quick Cache you should set this to <code>Yes</code> and <strong>THEN</strong> deactivate &amp; delete Quick Cache from the plugins menu in WordPress. This way Quick Cache will erase your options for the plugin, erase directories/files created by the plugin, remove the <code>advanced-cache.php</code> file, terminate CRON jobs, etc. It erases itself from existence completely.', $this->plugin->text_domain).'</p>'."\n";
echo ' <p><select name="'.esc_attr(__NAMESPACE__).'[save_options][uninstall_on_deletion]">'."\n";
echo ' <option value="0"'.selected($this->plugin->options['uninstall_on_deletion'], '0', FALSE).'>'.__('Safeguard my options and the cache (recommended).', $this->plugin->text_domain).'</option>'."\n";
echo ' <option value="1"'.selected($this->plugin->options['uninstall_on_deletion'], '1', FALSE).'>'.__('Yes, uninstall (completely erase) Quick Cache on plugin deletion.', $this->plugin->text_domain).'</option>'."\n";
echo ' </select></p>'."\n";
echo ' </div>'."\n";

Expand Down
111 changes: 101 additions & 10 deletions quick-cache/quick-cache.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ class plugin extends share
*/
public $network_cap = '';

/**
* Uninstall capability requirement.
*
* @since 14xxxx Adding uninstall handler.
*
* @var string WordPress capability required to
* completely uninstall/delete QC.
*/
public $uninstall_cap = '';

/**
* Cache directory.
*
Expand All @@ -91,16 +101,31 @@ class plugin extends share
*/
public $cache = array();

/**
* Used by the plugin's uninstall handler.
*
* @since 14xxxx Adding uninstall handler.
*
* @var boolean If FALSE, run without any hooks.
*/
public $enable_hooks = TRUE;

/**
* Quick Cache plugin constructor.
*
* @param boolean $enable_hooks Defaults to a TRUE value.
* If FALSE, setup runs but without adding any hooks.
*
* @since 140422 First documented version.
*/
public function __construct()
public function __construct($enable_hooks = TRUE)
{
parent::__construct(); // Shared constructor.

$this->file = preg_replace('/\.inc\.php$/', '.php', __FILE__);
$this->enable_hooks = (boolean)$enable_hooks;
$this->file = preg_replace('/\.inc\.php$/', '.php', __FILE__);

if(!$this->enable_hooks) return; // All done in this case.

add_action('after_setup_theme', array($this, 'setup'));
register_activation_hook($this->file, array($this, 'activate'));
Expand All @@ -114,7 +139,8 @@ public function __construct()
*/
public function setup()
{
do_action('before__'.__METHOD__, get_defined_vars());
if($this->enable_hooks) // Hooks enabled?
do_action('before__'.__METHOD__, get_defined_vars());

load_plugin_textdomain($this->text_domain);

Expand All @@ -140,7 +166,7 @@ public function setup()
'feeds_enable' => '0', // `0|1`.
'cache_404_requests' => '0', // `0|1`.

'uninstall_on_deactivation' => '0' // `0|1`.
'uninstall_on_deletion' => '0' // `0|1`.
); // Default options are merged with those defined by the site owner.
$options = (is_array($options = get_option(__NAMESPACE__.'_options'))) ? $options : array();
if(is_multisite() && is_array($site_options = get_site_option(__NAMESPACE__.'_options')))
Expand Down Expand Up @@ -187,8 +213,11 @@ public function setup()
if(!$this->options['base_dir']) // Security enhancement; NEVER allow this to be empty.
$this->options['base_dir'] = $this->default_options['base_dir'];

$this->cap = apply_filters(__METHOD__.'__cap', 'activate_plugins');
$this->network_cap = apply_filters(__METHOD__.'__network_cap', 'manage_network_plugins');
$this->cap = apply_filters(__METHOD__.'__cap', 'activate_plugins');
$this->network_cap = apply_filters(__METHOD__.'__network_cap', 'manage_network_plugins');
$this->uninstall_cap = apply_filters(__METHOD__.'__uninstall_cap', 'delete_plugins');

if(!$this->enable_hooks) return; // Stop here; setup without hooks.

add_action('init', array($this, 'check_advanced_cache'));
add_action('init', array($this, 'check_blog_paths'));
Expand Down Expand Up @@ -327,11 +356,35 @@ public function deactivate()
$this->remove_wp_cache_from_wp_config();
$this->remove_advanced_cache();
$this->clear_cache();
}

/**
* Plugin uninstall hook.
*
* @since 14xxxx Adding uninstall handler.
*
* @attaches-to {@link \register_uninstall_hook()} ~ via {@link uninstall()}
*/
public function uninstall()
{
if(!current_user_can($this->uninstall_cap))
return; // Extra layer of security.

if(!$this->options['uninstall_on_deactivation'])
if(!class_exists('\\'.__NAMESPACE__.'\\uninstall'))
return; // Expecting the uninstall class.

if(!defined('WP_UNINSTALL_PLUGIN'))
return; // Disallow.

$this->remove_wp_cache_from_wp_config();
$this->remove_advanced_cache();
$this->wipe_cache();

if(!$this->options['uninstall_on_deletion'])
return; // Nothing to do here.

$this->delete_advanced_cache();
$this->remove_base_dir();

delete_option(__NAMESPACE__.'_options');
if(is_multisite()) // Delete network options too.
Expand Down Expand Up @@ -1988,6 +2041,44 @@ public function update_blog_paths($enable_live_network_counts = NULL)
}
return $value; // Pass through untouched (always).
}

/**
* Removes the entire base directory.
*
* @since 14xxx First documented version.
*
* @return integer Total files removed by this routine (if any).
*
* @throws \exception If a wipe failure occurs.
*/
public function remove_base_dir()
{
$counter = 0; // Initialize.

// @TODO When set_time_limit() is disabled by PHP configuration, display a warning message to users upon plugin activation.
@set_time_limit(1800); // In case of HUGE sites w/ a very large directory. Errors are ignored in case `set_time_limit()` is disabled.

$base_dir = $this->wp_content_dir_to(''); // Simply the base directory.

/** @var $_dir_file \RecursiveDirectoryIterator For IDEs. */
if($base_dir && is_dir($base_dir)) foreach($this->dir_regex_iteration($base_dir, '/.+/') as $_dir_file)
{
if(($_dir_file->isFile() || $_dir_file->isLink()))
if(!unlink($_dir_file->getPathname())) // Throw exception if unable to delete.
throw new \exception(sprintf(__('Unable to remove file: `%1$s`.', $this->text_domain), $_dir_file->getPathname()));
else $counter++; // Increment counter for each file we wipe.

else if($_dir_file->isDir())
if(!rmdir($_dir_file->getPathname())) // Throw exception if unable to delete.
throw new \exception(sprintf(__('Unable to remove dir: `%1$s`.', $this->text_domain), $_dir_file->getPathname()));
}
unset($_dir_file); // Just a little housekeeping.

if(is_dir($base_dir) && !rmdir($base_dir)) // Throw exception if unable to delete.
throw new \exception(sprintf(__('Unable to remove base dir: `%1$s`.', $this->text_domain), $base_dir));

return $counter; // Total removals.
}
}

/**
Expand All @@ -2008,15 +2099,15 @@ function plugin() // Easy reference.
*
* @since 140422 First documented version.
*
* @var plugin $GLOBALS [__NAMESPACE__]
* @var plugin Main plugin class.
*/
$GLOBALS[__NAMESPACE__] = new plugin(); // New plugin instance.
$GLOBALS[__NAMESPACE__] = new plugin(!class_exists('\\'.__NAMESPACE__.'\\uninstall'));
/*
* API class inclusion; depends on {@link $GLOBALS[__NAMESPACE__]}.
*/
require_once dirname(__FILE__).'/includes/api-class.php';
}
else add_action('all_admin_notices', function () // Do NOT load in this case.
else if(!class_exists('\\'.__NAMESPACE__.'\\uninstall')) add_action('all_admin_notices', function ()
{
echo '<div class="error"><p>'. // Running multiple versions of this plugin at same time.
__('Please disable the LITE version of Quick Cache before you activate the PRO version.',
Expand Down
43 changes: 43 additions & 0 deletions quick-cache/uninstall.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Quick Cache Uninstaller
*
* @package quick_cache\uninstall
* @since 14xxxx Adding plugin uninstaller.
* @copyright WebSharks, Inc. <http://www.websharks-inc.com>
* @license GNU General Public License, version 2
*/
namespace quick_cache
{
if(!defined('WPINC')) // MUST have WordPress.
exit('Do NOT access this file directly: '.basename(__FILE__));

require_once dirname(__FILE__).'/quick-cache-pro.inc.php';

if(!class_exists('\\'.__NAMESPACE__.'\\uninstall'))
{
class uninstall // Uninstall handler.
{
/**
* @since 14xxxx Adding uninstaller.
*
* @var plugin Primary plugin class instance.
*/
protected $plugin; // Set by constructor.

/**
* Uninstall constructor.
*
* @since 14xxxx Adding uninstall handler.
*/
public function __construct()
{
$this->plugin = plugin( /* Without hooks. */);
$this->plugin->setup( /* Without hooks. */);
$this->plugin->uninstall();
}
}

new uninstall(); // Run the uninstaller.
}
}

0 comments on commit f012c36

Please sign in to comment.