autoload-optimizer
Last commit date
autoload-optimizer.php
1 year ago
autoload-script.js
1 year ago
autoload-style.css
1 year ago
readme.txt
1 year ago
autoload-optimizer.php
277 lines
| 1 | <?php |
| 2 | /* |
| 3 | Plugin Name: Autoload Optimizer |
| 4 | Version: 1.0 |
| 5 | Description: Checks the autoloaded data size and lists the top autoloaded data entries sorted by size. |
| 6 | Author: WP Fix Experts |
| 7 | Author URI: https://wpfixexperts.com |
| 8 | License: GPLv2 or later |
| 9 | License URI: https://www.gnu.org/licenses/gpl-2.0.html |
| 10 | Text Domain: autoload-optimizer |
| 11 | */ |
| 12 | |
| 13 | // Prevent direct access |
| 14 | if (!defined('ABSPATH')) { |
| 15 | exit; |
| 16 | } |
| 17 | |
| 18 | // Add menu under Tools |
| 19 | add_action('admin_menu', 'autoload_optimizer_menu'); |
| 20 | function autoload_optimizer_menu() { |
| 21 | add_submenu_page( |
| 22 | 'tools.php', // Parent menu slug |
| 23 | 'Autoload Optimizer', // Page title |
| 24 | 'Autoload Optimizer', // Menu title |
| 25 | 'manage_options', // Capability |
| 26 | 'autoload-optimizer', // Menu slug |
| 27 | 'autoload_optimizer_page' // Callback function |
| 28 | ); |
| 29 | } |
| 30 | |
| 31 | // Enqueue styles and scripts |
| 32 | add_action('admin_enqueue_scripts', 'autoload_optimizer_scripts'); |
| 33 | function autoload_optimizer_scripts($hook) { |
| 34 | if ($hook !== 'tools_page_autoload-optimizer') { |
| 35 | return; |
| 36 | } |
| 37 | wp_enqueue_style( |
| 38 | 'autoload-optimizer-style', |
| 39 | plugins_url('autoload-style.css', __FILE__), |
| 40 | array(), // Dependencies |
| 41 | filemtime(plugin_dir_path(__FILE__) . 'autoload-style.css') // Dynamic version |
| 42 | ); |
| 43 | |
| 44 | wp_enqueue_script( |
| 45 | 'autoload-optimizer-script', |
| 46 | plugins_url('autoload-script.js', __FILE__), |
| 47 | array('jquery'), // Dependencies |
| 48 | filemtime(plugin_dir_path(__FILE__) . 'autoload-script.js'), // Dynamic version |
| 49 | true // Load in footer |
| 50 | ); |
| 51 | |
| 52 | // Localize script for AJAX nonce |
| 53 | wp_localize_script( |
| 54 | 'autoload-optimizer-script', |
| 55 | 'autoload_optimizer_ajax', |
| 56 | array( |
| 57 | 'ajax_url' => admin_url('admin-ajax.php'), |
| 58 | 'nonce' => wp_create_nonce('autoload_optimizer_nonce'), |
| 59 | ) |
| 60 | ); |
| 61 | } |
| 62 | |
| 63 | // Plugin page content |
| 64 | function autoload_optimizer_page() { |
| 65 | ?> |
| 66 | <div class="wrap"> |
| 67 | |
| 68 | |
| 69 | <!-- Welcome Screen --> |
| 70 | <div class="welcome-screen"> |
| 71 | <h3 style="color: blue;">Welcome to the Autoload Optimizer ! 🚀</h3> |
| 72 | <p>This powerful tool helps you optimize and manage autoloaded data in your WordPress database, improving site performance and speed. With just a few clicks, you can identify and clean up unnecessary autoloaded entries, reducing database bloat and enhancing website efficiency. <br> <br> <strong> Warning Note: |
| 73 | |
| 74 | ⚠ Proceed with Caution! ⚠</strong> |
| 75 | <br> |
| 76 | The Autoload Optimizer Plugin makes direct modifications to your WordPress database. Deleting essential autoloaded data may cause unexpected issues, including broken functionality or site errors. |
| 77 | <br><br> |
| 78 | <strong>📌 Before making changes, please:<br></strong> |
| 79 | ✔ Create a full database backup<br> |
| 80 | ✔ Review the list of autoloaded options carefully<br> |
| 81 | ✔ Test changes on a staging site if possible<br><br> |
| 82 | |
| 83 | Use this tool responsibly to avoid any disruptions. If you're unsure, consult a developer or seek professional support. |
| 84 | <br><br> |
| 85 | Your website's stability is our priority! 🚀 </p> |
| 86 | </div> |
| 87 | |
| 88 | <!-- Database Size and Autoload Data Size --> |
| 89 | <?php |
| 90 | $database_size = autoload_optimizer_get_database_size(); |
| 91 | $autoload_size = autoload_optimizer_get_autoload_size(); |
| 92 | ?> |
| 93 | <div class="database-info"> |
| 94 | <p><strong>Total Database Size:</strong> <?php echo esc_html(size_format($database_size)); ?></p> |
| 95 | <p><strong>Total Autoload Data Size:</strong> <?php echo esc_html(size_format($autoload_size)); ?></p> |
| 96 | </div> |
| 97 | |
| 98 | <!-- Tabs --> |
| 99 | <h2 class="nav-tab-wrapper"> |
| 100 | <a href="#tab1" class="nav-tab nav-tab-active">Autoload Options</a> |
| 101 | <a href="#tab2" class="nav-tab">Disabled Options</a> |
| 102 | </h2> |
| 103 | |
| 104 | <!-- Tab 1: Autoload Options --> |
| 105 | <div id="tab1" class="tab-content active"> |
| 106 | <?php |
| 107 | $autoload_options = autoload_optimizer_get_autoload_options(); |
| 108 | if ($autoload_options) { |
| 109 | echo '<table class="wp-list-table widefat fixed striped">'; |
| 110 | echo '<thead><tr><th>Option Name</th><th>Option Size</th><th>Action</th></tr></thead>'; |
| 111 | echo '<tbody>'; |
| 112 | foreach ($autoload_options as $option_name => $option_value) { |
| 113 | $option_size = strlen(maybe_serialize($option_value)); |
| 114 | echo '<tr>'; |
| 115 | echo '<td>' . esc_html($option_name) . '</td>'; |
| 116 | echo '<td>' . esc_html(size_format($option_size)) . '</td>'; |
| 117 | echo '<td> |
| 118 | <button class="button view-value" data-value="' . esc_attr(maybe_serialize($option_value)) . '">View Value</button> |
| 119 | <button class="button button-danger disable-option" data-option="' . esc_attr($option_name) . '">Disable</button> |
| 120 | </td>'; |
| 121 | echo '</tr>'; |
| 122 | } |
| 123 | echo '</tbody></table>'; |
| 124 | } else { |
| 125 | echo '<p>No autoload options found.</p>'; |
| 126 | } |
| 127 | ?> |
| 128 | </div> |
| 129 | |
| 130 | <!-- Tab 2: Disabled Options --> |
| 131 | <div id="tab2" class="tab-content"> |
| 132 | <?php |
| 133 | $disabled_options = get_option('autoload_optimizer_disabled_options', array()); |
| 134 | if ($disabled_options) { |
| 135 | echo '<table class="wp-list-table widefat fixed striped">'; |
| 136 | echo '<thead><tr><th>Option Name</th><th>Action</th></tr></thead>'; |
| 137 | echo '<tbody>'; |
| 138 | foreach ($disabled_options as $option_name) { |
| 139 | echo '<tr>'; |
| 140 | echo '<td>' . esc_html($option_name) . '</td>'; |
| 141 | echo '<td><button class="button button-primary restore-option" data-option="' . esc_attr($option_name) . '">Restore</button></td>'; |
| 142 | echo '</tr>'; |
| 143 | } |
| 144 | echo '</tbody></table>'; |
| 145 | } else { |
| 146 | echo '<p>No disabled options found.</p>'; |
| 147 | } |
| 148 | ?> |
| 149 | </div> |
| 150 | </div> |
| 151 | |
| 152 | <!-- Popup for viewing option value --> |
| 153 | <div id="value-popup" class="popup-modal"> |
| 154 | <div class="popup-content"> |
| 155 | <h3>Option Value</h3> |
| 156 | <pre id="popup-value"></pre> |
| 157 | <button id="close-popup" class="button button-primary">Close</button> |
| 158 | </div> |
| 159 | </div> |
| 160 | <?php |
| 161 | } |
| 162 | |
| 163 | // Helper function to get database size with caching |
| 164 | function autoload_optimizer_get_database_size() { |
| 165 | // Check if the database size is cached |
| 166 | $database_size = wp_cache_get('autoload_optimizer_database_size', 'autoload_optimizer'); |
| 167 | |
| 168 | if (false === $database_size) { |
| 169 | global $wpdb; |
| 170 | // Get the database size from the database |
| 171 | $database_size = $wpdb->get_var("SELECT SUM(data_length + index_length) FROM information_schema.TABLES WHERE table_schema = DATABASE()"); |
| 172 | $database_size = $database_size ? $database_size : 0; |
| 173 | |
| 174 | // Cache the database size for 12 hours |
| 175 | wp_cache_set('autoload_optimizer_database_size', $database_size, 'autoload_optimizer', 12 * HOUR_IN_SECONDS); |
| 176 | } |
| 177 | |
| 178 | return $database_size; |
| 179 | } |
| 180 | |
| 181 | // Helper function to get autoload size with caching |
| 182 | function autoload_optimizer_get_autoload_size() { |
| 183 | // Check if the autoload size is cached |
| 184 | $autoload_size = wp_cache_get('autoload_optimizer_autoload_size', 'autoload_optimizer'); |
| 185 | |
| 186 | if (false === $autoload_size) { |
| 187 | $autoload_options = autoload_optimizer_get_autoload_options(); |
| 188 | $autoload_size = 0; |
| 189 | |
| 190 | // Calculate the total size of autoloaded options |
| 191 | foreach ($autoload_options as $option_value) { |
| 192 | $autoload_size += strlen(maybe_serialize($option_value)); |
| 193 | } |
| 194 | |
| 195 | // Cache the autoload size for 12 hours |
| 196 | wp_cache_set('autoload_optimizer_autoload_size', $autoload_size, 'autoload_optimizer', 12 * HOUR_IN_SECONDS); |
| 197 | } |
| 198 | |
| 199 | return $autoload_size; |
| 200 | } |
| 201 | |
| 202 | // Helper function to get autoload options (top 20 by size) |
| 203 | function autoload_optimizer_get_autoload_options() { |
| 204 | $all_options = wp_load_alloptions(); |
| 205 | $options_with_size = array(); |
| 206 | |
| 207 | // Calculate size for each option |
| 208 | foreach ($all_options as $option_name => $option_value) { |
| 209 | $options_with_size[$option_name] = strlen(maybe_serialize($option_value)); |
| 210 | } |
| 211 | |
| 212 | // Sort options by size in descending order |
| 213 | arsort($options_with_size); |
| 214 | |
| 215 | // Get the top 20 options |
| 216 | $top_options = array_slice($options_with_size, 0, 20, true); |
| 217 | |
| 218 | // Fetch the full option data for the top 20 |
| 219 | $autoload_options = array(); |
| 220 | foreach ($top_options as $option_name => $size) { |
| 221 | $autoload_options[$option_name] = get_option($option_name); |
| 222 | } |
| 223 | |
| 224 | return $autoload_options; |
| 225 | } |
| 226 | |
| 227 | // AJAX handler to disable autoload option |
| 228 | add_action('wp_ajax_disable_autoload_option', 'autoload_optimizer_disable_option'); |
| 229 | function autoload_optimizer_disable_option() { |
| 230 | // Verify nonce |
| 231 | // Validate the nonce |
| 232 | if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field($_POST['nonce']), 'autoload_optimizer_nonce')) { |
| 233 | // Sanitize and escape the error message before sending it |
| 234 | $error_message = esc_html__('Invalid nonce.', 'your-text-domain'); |
| 235 | wp_send_json_error($error_message); |
| 236 | } |
| 237 | |
| 238 | if (!isset($_POST['option_name'])) { |
| 239 | wp_send_json_error('Option name is required.'); |
| 240 | } |
| 241 | $option_name = sanitize_text_field($_POST['option_name']); |
| 242 | update_option($option_name, get_option($option_name), 'no'); // Set autoload to 'no' |
| 243 | $disabled_options = get_option('autoload_optimizer_disabled_options', array()); |
| 244 | $disabled_options[] = $option_name; |
| 245 | update_option('autoload_optimizer_disabled_options', $disabled_options); |
| 246 | |
| 247 | // Clear the autoload size cache after disabling an option |
| 248 | wp_cache_delete('autoload_optimizer_autoload_size', 'autoload_optimizer'); |
| 249 | |
| 250 | wp_send_json_success('Option disabled successfully.'); |
| 251 | } |
| 252 | |
| 253 | // AJAX handler to restore autoload option |
| 254 | add_action('wp_ajax_restore_autoload_option', 'autoload_optimizer_restore_option'); |
| 255 | function autoload_optimizer_restore_option() { |
| 256 | // Verify nonce |
| 257 | if ( |
| 258 | !isset($_POST['nonce']) || |
| 259 | !wp_verify_nonce(sanitize_text_field($_POST['nonce']), 'autoload_optimizer_nonce') |
| 260 | ) { |
| 261 | wp_send_json_error('Invalid nonce.'); |
| 262 | } |
| 263 | |
| 264 | if (!isset($_POST['option_name'])) { |
| 265 | wp_send_json_error('Option name is required.'); |
| 266 | } |
| 267 | $option_name = sanitize_text_field($_POST['option_name']); |
| 268 | update_option($option_name, get_option($option_name), 'yes'); // Set autoload to 'yes' |
| 269 | $disabled_options = get_option('autoload_optimizer_disabled_options', array()); |
| 270 | $disabled_options = array_diff($disabled_options, array($option_name)); |
| 271 | update_option('autoload_optimizer_disabled_options', $disabled_options); |
| 272 | |
| 273 | // Clear the autoload size cache after restoring an option |
| 274 | wp_cache_delete('autoload_optimizer_autoload_size', 'autoload_optimizer'); |
| 275 | |
| 276 | wp_send_json_success('Option restored successfully.'); |
| 277 | } |