diff --git a/README.md b/README.md index fb83095..8cab033 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Transient Cleaner -Remove expired transients from your options table. The original and best! +Remove expired transients from your options table. The original and best! **This plugin is designed only for WordPress 5.8 or below, as transient cleaning is part of core functionality after that point.** diff --git a/artiss-transient-cleaner.php b/artiss-transient-cleaner.php index d426a0b..c772cfb 100755 --- a/artiss-transient-cleaner.php +++ b/artiss-transient-cleaner.php @@ -2,14 +2,14 @@ /** * Transient Cleaner * - * @package Artiss-Transient-Cleaner + * @package artiss-transient-cleaner * @author David Artiss * @license GPL-2.0-or-later * * Plugin Name: Transient Cleaner * Plugin URI: https://wordpress.org/plugins/artiss-transient-cleaner/ - * Description: 🧼 Clear expired transients from your options table. - * Version: 1.6 + * Description: Clear expired transients from your options table. + * Version: 1.7 * Requires at least: 4.4 * Requires PHP: 7.4 * Author: David Artiss @@ -26,22 +26,26 @@ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ +// Exit if accessed directly. + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + // Define global to hold the plugin base file name. if ( ! defined( 'TRANSIENT_CLEANER_PLUGIN_BASE' ) ) { define( 'TRANSIENT_CLEANER_PLUGIN_BASE', plugin_basename( __FILE__ ) ); } -$functions_dir = plugin_dir_path( __FILE__ ) . 'includes/'; +$functions_dir = plugin_dir_path( __FILE__ ) . 'inc/'; // Include all the various functions. -require_once $functions_dir . 'clean-transients.php'; // General configuration set-up. +require_once plugin_dir_path( __FILE__ ) . 'inc/scheduler.php'; -require_once $functions_dir . 'shared-functions.php'; // Assorted shared functions. +require_once plugin_dir_path( __FILE__ ) . 'inc/clean-transients.php'; -if ( is_admin() ) { +require_once plugin_dir_path( __FILE__ ) . 'inc/settings.php'; - include_once $functions_dir . 'set-admin-config.php'; // Administration configuration. - -} +require_once plugin_dir_path( __FILE__ ) . 'inc/shared.php'; diff --git a/assets/blueprints/blueprint.json b/assets/blueprints/blueprint.json new file mode 100644 index 0000000..90e039b --- /dev/null +++ b/assets/blueprints/blueprint.json @@ -0,0 +1,30 @@ +{ + "landingPage": "\/wp-admin\/tools.php?page=transient-options", + "preferredVersions": { + "php": "8.0", + "wp": "latest" + }, + "phpExtensionBundles": [ + "kitchen-sink" + ], + "features": { + "networking": true + }, + "steps": [ + { + "step": "installPlugin", + "pluginZipFile": { + "resource": "url", + "url": "https:\/\/downloads.wordpress.org\/plugin\/artiss-transient-cleaner.zip" + }, + "options": { + "activate": true + } + }, + { + "step": "login", + "username": "admin", + "password": "password" + } + ] +} \ No newline at end of file diff --git a/assets/icon-128x128.png b/assets/icon-128x128.png index a07bb4a..2059297 100644 Binary files a/assets/icon-128x128.png and b/assets/icon-128x128.png differ diff --git a/assets/icon-256x256.png b/assets/icon-256x256.png index 1837f46..48aedce 100644 Binary files a/assets/icon-256x256.png and b/assets/icon-256x256.png differ diff --git a/assets/icon.svg b/assets/icon.svg new file mode 100644 index 0000000..08a35f8 --- /dev/null +++ b/assets/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/screenshot-1.jpg b/assets/screenshot-1.jpg new file mode 100644 index 0000000..2675a42 Binary files /dev/null and b/assets/screenshot-1.jpg differ diff --git a/assets/screenshot-1.png b/assets/screenshot-1.png deleted file mode 100755 index 5ca6a74..0000000 Binary files a/assets/screenshot-1.png and /dev/null differ diff --git a/inc/clean-transients.php b/inc/clean-transients.php new file mode 100755 index 0000000..2816405 --- /dev/null +++ b/inc/clean-transients.php @@ -0,0 +1,128 @@ +query( + $wpdb->prepare( + "DELETE FROM $wpdb->options + WHERE option_name LIKE %s", + $wpdb->esc_like( '_transient_' ) . '%' + ) + ); + $records .= $clean; + + // If multisite, and the main network, also clear the sitemeta table. + + if ( is_multisite() && is_main_network() ) { + $clean = $wpdb->query( + $wpdb->prepare( + "DELETE FROM $wpdb->sitemeta + WHERE meta_key LIKE %s", + $wpdb->esc_like( '_site_transient_' ) . '%' + ) + ); + $records .= $clean; + } + } else { + + // Delete transients from options table. + + $clean = $wpdb->query( + $wpdb->prepare( + "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b + WHERE a.option_name LIKE %s + AND a.option_name NOT LIKE %s + AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, CHAR_LENGTH('_transient_') + 1 ) ) + AND b.option_value < %d", + $wpdb->esc_like( '_transient_' ) . '%', + $wpdb->esc_like( '_transient_timeout_' ) . '%', + time() + ) + ); + $records .= $clean; + + // Delete transients from multisite, if configured as such. + + if ( is_multisite() && is_main_network() ) { + + $clean = $wpdb->query( + $wpdb->prepare( + "DELETE a, b FROM {$wpdb->sitemeta} a, {$wpdb->sitemeta} b + WHERE a.meta_key LIKE %s + AND a.meta_key NOT LIKE %s + AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, CHAR_LENGTH('_site_transient_') + 1 ) ) + AND b.meta_value < %d", + $wpdb->esc_like( '_site_transient_' ) . '%', + $wpdb->esc_like( '_site_transient_timeout_' ) . '%', + time() + ) + ); + $records .= $clean; + } + } + + // Save options field with number & timestamp. + + $results = array(); + + $results['timestamp'] = time() + ( get_option( 'gmt_offset' ) * 3600 ); + $results['records'] = $records; + + $option_name = 'transient_clean_'; + if ( $clear_all ) { + $option_name .= 'all'; + } else { + $option_name .= 'expired'; + } + update_option( $option_name, $results ); + + // Optimize the table after the deletions. + + if ( ( ( $options['upgrade_optimize'] ) && ( $clear_all ) ) || ( ( $options['clean_optimize'] ) && ( ! $clear_all ) ) ) { + $wpdb->query( "OPTIMIZE TABLE $wpdb->options" ); + if ( is_multisite() && is_main_network() ) { + $wpdb->query( "OPTIMIZE TABLE $wpdb->sitemeta" ); + } + } + } + + return $cleaned; +} diff --git a/inc/scheduler.php b/inc/scheduler.php new file mode 100755 index 0000000..e33fce7 --- /dev/null +++ b/inc/scheduler.php @@ -0,0 +1,119 @@ + +
' . esc_html( $text ) . '
' . __( 'This screen allows you to specify the default options for the Transient Cleaner plugin.', 'artiss-transient-cleaner' ) . '
'; + $help_text .= '' . __( "In addition, details of recent transient cleans are shown. Tick the 'Run Now' options to perform a clean, whether a full removal of transients or just the removal of expired transients.", 'artiss-transient-cleaner' ) . '
'; + $help_text .= '' . __( 'Remember to click the Save Changes button at the bottom of the screen for new settings to take effect.', 'artiss-transient-cleaner' ) . '
'; + + return $help_text; +} + +/** + * Options Help Sidebar + * + * Add a links sidebar to the options help. + * + * @return string Help Text + */ +function transient_cleaner_options_sidebar() { + + $help_text = '' . __( 'For more information:', 'artiss-transient-cleaner' ) . '
'; + $help_text .= '' . __( 'Instructions', 'artiss-transient-cleaner' ) . '
'; + $help_text .= '' . __( 'Support Forum', 'artiss-transient-cleaner' ) . '
'; + + return $help_text; +} + +/** + * Get options + * + * Fetch options and, if any are missing, complete the data + * + * @return string Array of options + */ +function transient_cleaner_get_options() { + + if ( defined( 'transient_cleaner_LITE' ) && transient_cleaner_LITE ) { + $lite = true; + } else { + $lite = false; + } + + if ( ! $lite ) { + $options = get_option( 'transient_clean_options' ); + } + + // If options don't exist, create an empty array. + + if ( ! is_array( $options ) ) { + $options = array(); + } + + // Because of upgrading, check each option - if not set, apply default. + + $default_array = array( + 'clean_enable' => true, + 'clean_optimize' => false, + 'upgrade_enable' => true, + 'upgrade_optimize' => true, + 'schedule' => '00', + ); + + // Merge existing and default options - any missing from existing will take the default settings. + + $new_options = array_merge( $default_array, $options ); + + // Update the options, if changed, and return the result. + + if ( $options !== $new_options && ! $lite ) { + update_option( 'transient_clean_options', $new_options ); + } + + return $new_options; +} diff --git a/inc/shared.php b/inc/shared.php new file mode 100755 index 0000000..4a945be --- /dev/null +++ b/inc/shared.php @@ -0,0 +1,127 @@ +' . __( 'Github', 'artiss-transient-cleaner' ) . '' ), + array( '' . __( 'Support', 'artiss-transient-cleaner' ) . '' ), + array( '' . __( 'Donate', 'artiss-transient-cleaner' ) . '' ), + array( '' . str_repeat( '', 5 ) . '' ), + ); + } + + return $links; +} + +add_filter( 'plugin_row_meta', 'transient_cleaner_plugin_meta', 10, 2 ); + +/** + * Modify actions links. + * + * Add or remove links for the actions listed against this plugin + * + * @version 1.1 + * @param string $actions Current actions. + * @param string $plugin_file The plugin. + * @return string Actions, now with deactivation removed! + */ +function transient_cleaner_action_links( $actions, $plugin_file ) { + + // Make sure we only perform actions for this specific plugin! + if ( strpos( $plugin_file, 'artiss-transient-cleaner.php' ) !== false ) { + + // Add link to the settings page. + if ( current_user_can( 'manage_options' ) ) { + array_unshift( $actions, '' . __( 'Settings', 'artiss-transient-cleaner' ) . '' ); + } + } + + return $actions; +} + +add_filter( 'plugin_action_links', 'transient_cleaner_action_links', 10, 2 ); + +/** + * WordPress Requirements Check + * + * Deactivate the plugin if certain requirements are not met. + * + * @version 1.1 + */ +function transient_cleaner_requirements_check() { + + $reason = ''; + + // Grab the plugin details. + + $plugins = get_plugins(); + $name = $plugins[ TRANSIENT_CLEANER_PLUGIN_BASE ]['Name']; + + // Check for an object cache. + + global $_wp_using_ext_object_cache; + + if ( $_wp_using_ext_object_cache ) { + $reason .= '' . sprintf( __( '%1$s has been deactivated', 'artiss-transient-cleaner' ), $name ) . '
' . __( 'Reason:', 'artiss-transient-cleaner' ) . '
' . $text . '
' . sprintf( __( '%1$s has been deactivated', 'artiss-transient-cleaner' ), $name ) . '
' . __( 'Reason:', 'artiss-transient-cleaner' ) . '
'; - $message .= '' . __( 'This screen allows you to specify the default options for the Transient Cleaner plugin.', 'artiss-transient-cleaner' ) . '
'; - $help_text .= '' . __( "In addition, details of recent transient cleans are shown. Tick the 'Run Now' options to perform a clean, whether a full removal of transients or just the removal of expired transients.", 'artiss-transient-cleaner' ) . '
'; - $help_text .= '' . __( 'Remember to click the Save Changes button at the bottom of the screen for new settings to take effect.', 'artiss-transient-cleaner' ) . '
'; - - return $help_text; -} - -/** - * Options Help Sidebar - * - * Add a links sidebar to the options help. - * - * @return string Help Text - */ -function tc_options_sidebar() { - - $help_text = '' . __( 'For more information:', 'artiss-transient-cleaner' ) . '
'; - $help_text .= ''; - $help_text .= ''; - - return $help_text; -} diff --git a/includes/shared-functions.php b/includes/shared-functions.php deleted file mode 100755 index 78e669a..0000000 --- a/includes/shared-functions.php +++ /dev/null @@ -1,82 +0,0 @@ - true, - 'clean_optimize' => false, - 'upgrade_enable' => true, - 'upgrade_optimize' => true, - 'schedule' => '00', - ); - - // Merge existing and default options - any missing from existing will take the default settings. - - $new_options = array_merge( $default_array, $options ); - - // Update the options, if changed, and return the result. - - if ( $options !== $new_options && ! $lite ) { - update_option( 'transient_clean_options', $new_options ); - } - - return $new_options; -} - -/** - * Set scheduler - * - * Set up scheduler. Set up seperately as this is done from 2 difference places - * and wanted to keep a consistent process. - * - * @param string $hour The hour to be scheduled. - * @return string The hour parameter that was used - */ -function tc_set_schedule( $hour ) { - - // If the hour to be set is before now, setting it will cause the schedule to run immediately - // Therefore, in this case it's set to that time for tomorrow. - - $hour .= ':00'; - if ( $hour <= gmdate( 'H' ) ) { - $hour .= ' tomorrow'; - } - - // Now create the scheduled event. - - wp_schedule_event( strtotime( $hour ), 'daily', 'housekeep_transients' ); - - return $hour; -} diff --git a/readme.txt b/readme.txt index 9e510ad..218c3f3 100755 --- a/readme.txt +++ b/readme.txt @@ -1,20 +1,27 @@ === Transient Cleaner === -Contributors: dartiss +Contributors: dartiss +Donate link: https://artiss.blog/donate Tags: cache, clean, database, options, transient Requires at least: 4.4 -Tested up to: 5.8 +Tested up to: 6.5 Requires PHP: 7.4 -Stable tag: 1.6 +Stable tag: 1.7 License: GPLv2 or later -License URI: http://www.gnu.org/licenses/gpl-2.0.html +License URI: http://www.gnu.org/licenses/gpl-2.0.html +README revision: 1.0 -🧼 Clean expired transients from your options table. The original and best! +Clean expired transients from your options table. The original and best! == Description == Clean expired transients from your options table. The original and best! -**This plugin is designed only for WordPress 5.8 or below, as transient cleaning is part of core functionality after that point.** +**Transient housekeeping was added to the core of WordPress after version 5.8. However, I have decided to open up this plugin to all versions to allow for manual transient cleaning. Longer term I am working on a new version of the plugin, designed specifically for all WordPress releases.** + +* Tested up to PHP 8.2 +* Fully complies with WordPress coding standards +* Compliant with the stronger [WordPress VIP](https://wpvip.com/) coding standards, as well as compatibility with their platform +* Community plugin - visit the [Github page](https://github.com/dartiss/[repo link] "Github") to get involved with the latest code development, request enhancements and report issues "Transients are a simple and standardized way of storing cached data in the WordPress database temporarily by giving it a custom name and a timeframe after which it will expire and be deleted." @@ -24,10 +31,6 @@ Why is this a problem? Transients are often used by plugins to "cache" data (my Meantime, this plugin is the hero that you've been waiting for. Simply activate the plugin, sit back and enjoy a much cleaner, smaller options table. It also adds the additional recommendation that after a database upgrade all transients will be cleared down. -I'd like to thank WordPress Developer Andrew Nacin for his early discussion on this. Also, I'd like to acknowledge [the useful article at Everybody Staze](http://www.staze.org/wordpress-_transient-buildup/ "WordPress _transient buildup") for ensuring the proposed solution made sense, and [W-Shadow.com](http://w-shadow.com/blog/2012/04/17/delete-stale-transients/ "Cleaning Up Stale Transients") for the cleaning code. - -Iconography is courtesy of the very talented [Janki Rathod](https://www.fiverr.com/jankirathore) ♥️ - == The Settings Screen == Within `Administration` -> `Tools` -> `Transients` an options screen exists allowing you to tweak when you'd like cleaning to happen, including the ability to perform an ad-hoc run, and when you'd like the to be automatically scheduled. @@ -49,16 +52,20 @@ This should be added to your `wp-config.php` file. If you're the type of odd person who likes to code for WordPress (really?) then I've added a couple of hooks so you can call our rather neat cleaning functions... * `housekeep_transients` - this will clear down any expired transients -* `clear_all_transients` - this will remove any and all transients, expired or otherwise +* `clear_all_transients` - this will remove any and all transients, expired or otherwise + +== Acknowledgements == + +I'd like to thank WordPress Developer Andrew Nacin for his early discussion on this. Also, I'd like to acknowledge [the useful article at Everybody Staze](http://www.staze.org/wordpress-_transient-buildup/ "WordPress _transient buildup") for ensuring the proposed solution made sense, and [W-Shadow.com](http://w-shadow.com/blog/2012/04/17/delete-stale-transients/ "Cleaning Up Stale Transients") for the cleaning code. + +Iconography is courtesy of the very talented [Janki Rathod](https://www.fiverr.com/jankirathore). == Installation == -Transient Cleaner can be found and installed via the Plugin menu within WordPress administration (Plugins -> Add New). Alternatively, it can be downloaded from WordPress.org and installed manually... - -1. Upload the entire `artiss-transient-cleaner` folder to your `wp-content/plugins/` directory. -2. Activate the plugin through the 'Plugins' menu in WordPress administration. +This plugin can be found and installed via the Plugin menu within WP Admin (Plugins -> Add New). Alternatively, it can be downloaded from WordPress.org and installed manually... -Voila! It's ready to go. +1. Upload the entire unzipped plugin folder to your `wp-content/plugins/` directory, either from WP Admin (Plugins -> Add New), your favorite FTP client or any other file manager +2. Activate the plugin through the 'Plugins' menu in WP Admin (Plugins -> Installed Plugins) == Frequently Asked Questions == @@ -84,6 +91,17 @@ A transient may consist of one or more records (normally a timed transient - the I use semantic versioning, with the first release being 1.0. += 1.7 = +* Enhancement: Code quality improvements - major code changes to make sure all code guidelines are met +* Enhancement: Using new cross-plugin shared functions +* Enhancement: Tidy up of this README + += 1.6.2 = +* Bug: Fixed a bug in the settings screen. Remember kids - listen to your teachers when they tell you that spelling is important! Especially function names + += 1.6.1 = +* Maintenance: Removed the WordPress version check so that the plugin will remain active on all versions + = 1.6 = * Enhancement: Added new error screens to prevent activation after WordPress 5.8 * Enhancement: Code quality improved @@ -191,5 +209,5 @@ I use semantic versioning, with the first release being 1.0. == Upgrade Notice == -= 1.6 = -* New version detection screen and code quality improvements. \ No newline at end of file += 1.7 = +* Code quality improvements \ No newline at end of file