Ticket #5625: 5625.r6603.diff
File 5625.r6603.diff, 11.1 KB (added by , 17 years ago) |
---|
-
wp-admin/includes/plugin.php
190 190 return 0; 191 191 } 192 192 193 /** 194 * get_plugin_assets() retrieves the plugin's registered assets from the option 195 * 196 * Part of the uninstall process. 197 * This function checks whether the plugin author has registered any assets 198 * that can be uninstalled and if so returns a named array with those options. 199 * 200 * @link http://trac.wordpress.org/ticket/5625 201 * 202 * @param string $plugin_file the path to the plugin file, usually given by __FILE__ 203 * @return array|bool the plugin's uninstallable assets, or false if there are none 204 * 205 */ 206 function get_plugin_assets( $plugin_file ) { 207 $plugin_assets = get_option( 'plugin_assets' ); 208 $plugin = plugin_basename( $plugin_file ); 209 if ( !is_array( $plugin_assets ) ) 210 return false; 211 if ( isset( $plugin_assets[$plugin] ) ) { 212 return $plugin_assets[$plugin]; 213 } else { 214 return false; 215 } 216 } 217 218 /** 219 * is_plugin_uninstallable() checks if a plugin has registered any uninstallable assets 220 * 221 * Part of the uninstall process. 222 * This function checks whether the plugin author has registered any assets 223 * that can be uninstalled. 224 * 225 * @link http://trac.wordpress.org/ticket/5625 226 * 227 * @param string $plugin_file the path to the plugin file, usually given by __FILE__ 228 * @return bool true if the plugin has assets that can be uninstalled 229 * 230 */ 231 function is_plugin_uninstallable( $plugin_file ){ 232 $uninstallable_plugins = get_option( 'plugin_assets' ); 233 $plugin = plugin_basename( $plugin_file ); 234 if ( isset( $uninstallable_plugins[$plugin] ) ) { 235 return true; 236 } else { 237 return false; 238 } 239 } 240 241 242 /** 243 * delete_plugin_assets() - Delete the database tables and options created by a plugin 244 * 245 * Part of the uninstall process. 246 * This function retrieves the list of assets the plugin author registered, using 247 * register_plugin_assets and removes the database tables and options specified. 248 * 249 * @link http://trac.wordpress.org/ticket/5625 250 * 251 * @param string $plugin_file the path to the plugin 252 * @return bool returns true if the tables and options are no longer present 253 */ 254 function delete_plugin_assets( $plugin_file ){ 255 global $wpdb; 256 $deletion_complete = true; 257 $uninstallable_plugins = get_option( 'plugin_assets' ); 258 $plugin = plugin_basename( $plugin_file ); 259 if ( isset( $uninstallable_plugins[$plugin] ) ) { 260 $plugin_assets = $uninstallable_plugins[$plugin]; 261 //remove tables 262 $remove_table_sql = 'DROP TABLE IF EXISTS `%s`'; 263 $check_table_sql = 'SELECT 1 FROM `%s` LIMIT 0'; 264 foreach( $plugin_assets['tables'] as $table ){ 265 //filter 266 $table = str_replace( '`' , '' , $table); 267 $table = str_replace( ';' , '' , $table); 268 $table = str_replace( '*' , '' , $table); 269 270 //check against core tables 271 if ( !in_array( str_replace( $wpdb->prefix , '' , $table ) , $wpdb->tables ) ) { 272 $sql = sprintf( $remove_table_sql , $table ); 273 $wpdb->query( $sql ); 274 //check if table is now gone 275 if ( $wpdb->query( sprintf( $check_table_sql , $table ) ) ) { 276 $deletion_complete = false; 277 } 278 } 279 } 280 //remove options 281 foreach( $plugin_assets['options'] as $option ){ 282 delete_option( $option ); 283 if ( get_option( $option ) ) { 284 $deletion_complete = false; 285 }; 286 } 287 //remove assets from asset list 288 if ( $deletion_complete ) { 289 unregister_plugin_assets( $plugin_file ); 290 } 291 } 292 return $deletion_complete; 293 } 294 295 193 296 // 194 297 // Menu 195 298 // -
wp-admin/plugins.php
27 27 check_admin_referer('reactivate-all'); 28 28 reactivate_all_plugins('plugins.php?errors=true'); 29 29 wp_redirect('plugins.php?reactivate-all=true'); // overrides the ?error=true one above 30 } elseif ( 'uninstall' == $_GET['action'] ) { 31 check_admin_referer('uninstall-plugin_' . $_GET['plugin']); 32 $current = get_option('active_plugins'); 33 $plugin = trim($_GET['plugin']); 34 if ( validate_file($plugin) ) 35 wp_die(__('Invalid plugin.')); 36 if ( ! file_exists(ABSPATH . PLUGINDIR . '/' . $plugin) ) 37 wp_die(__('Plugin file does not exist.')); 38 if ( !in_array($plugin, $current ) && is_plugin_uninstallable( $plugin ) ) { 39 $plugin_assets = get_plugin_assets( $plugin ); 40 //check for a callback function 41 if ( $plugin_assets['callback'] != NULL ) { 42 //include the plugin file 43 include_once( ABSPATH . PLUGINDIR . '/' . $plugin ); 44 //create and call the action 45 add_action( 'uninstall_plugin_' . $plugin , $plugin_assets['callback'] ); 46 do_action( 'uninstall_plugin_' . $plugin ); 47 } 48 if ( !delete_plugin_assets( $plugin ) ) { 49 wp_redirect('plugins.php?uninstalled=false'); 50 } 51 } 52 wp_redirect('plugins.php?uninstalled=true'); 30 53 } 31 54 32 55 exit; … … 59 82 <div id="message" class="updated fade"><p><?php _e('All plugins <strong>deactivated</strong>.'); ?></p></div> 60 83 <?php elseif (isset($_GET['reactivate-all'])) : ?> 61 84 <div id="message" class="updated fade"><p><?php _e('All plugins <strong>reactivated</strong>.'); ?></p></div> 85 <?php elseif (isset($_GET['uninstalled']) && $_GET['uninstalled'] == 'true') : ?> 86 <div id="message" class="updated fade"><p><?php _e('Plugin <strong>uninstalled</strong>.'); ?></p></div> 87 <?php elseif (isset($_GET['uninstalled']) && $_GET['uninstalled'] != 'true') : ?> 88 <div id="message" class="updated fade"> 89 <p><?php _e('The plugin could not be completely uninstalled. Some database tables, options or files may still exist.'); ?></p> 90 </div> 62 91 <?php endif; ?> 63 92 64 93 <div class="wrap"> … … 128 157 <td>$edit</td>"; 129 158 echo" 130 159 </tr>"; 160 161 if ( is_plugin_uninstallable( $plugin_file ) && (empty( $current_plugins ) || !in_array($plugin_file, $current_plugins) ) ) { 162 $plugin_data = get_plugin_data( ABSPATH . PLUGINDIR . '/' . $plugin_file ); 163 $toggle = "<a href='" . wp_nonce_url("plugins.php?action=uninstall&plugin=$plugin_file", 'uninstall-plugin_' . $plugin_file) . "' title='".__('Uninstall this plugin')."' class='delete'><strong>".__("Uninstall all the options and settings (including database tables ) relating to ").$plugin_data['Name']."</strong></a>"; 164 ?> 165 <tr> 166 <td colspan="5" style="border-top:1px solid #ccc; border-bottom:1px solid #ccc; background-color:#F9B7E0"><?php echo $toggle; ?></td> 167 </tr> 168 <?php 169 } 170 171 172 131 173 do_action( 'after_plugin_row', $plugin_file ); 132 174 } 133 175 ?> -
wp-includes/plugin.php
593 593 return $function[0].$function[1]; 594 594 } 595 595 596 /** 597 * register_plugin_assets() - Add the plugin's database tables and option names as assets so they can be removed later. 598 * 599 * Part of the uninstall process. 600 * When a plugin activates, and creates the database tables, and WordPress options it needs to run the plugin author 601 * can register those database tables and WordPress options so that they will be removed when the plugin is uninstalled. 602 * A callback can also be registered to handle more complex uninstall requirements. 603 * 604 * Note: This does not allow files to be registered as there is danger of getting paths wrong and removing 605 * similarly named files in different paths. 606 * 607 * @link http://trac.wordpress.org/ticket/5625 608 * 609 * @param string $plugin_file the path to the plugin file, usually given by __FILE__ 610 * @param callback $callback function name of the plugin's uninstaller, can be NULL 611 * @param array $tables array of table names that should be dropped when the plugin is uninstalled 612 * @param array $options array of option names that should be deleted when the plugin is uninstalled 613 * 614 */ 615 function register_plugin_assets( $plugin_file , $callback , $tables = array() , $options = array() ) { 616 $plugin_assets = get_option( 'plugin_assets' ); 617 $plugin = plugin_basename( $plugin_file ); 618 619 if ( !is_array( $plugin_assets ) ) 620 $plugin_assets = array(); 621 622 if( !isset($plugin_assets[$plugin]) ) 623 $plugin_assets[$plugin] = array( 'callback' => null, 'tables' => array(), 'options' => array() ); 624 625 if( !is_null( $callback ) ) { 626 $plugin_assets[$plugin]['callback'] = $callback; 627 } 628 629 if( is_array($options) && !empty($options) ) 630 $plugin_assets[$plugin]['options'] = array_merge( $options, $plugin_assets[$plugin]['options']); 631 632 if( is_array($tables) && !empty($tables) ) 633 $plugin_assets[$plugin]['tables'] = array_merge( $tables, $plugin_assets[$plugin]['tables']); 634 635 update_option( 'plugin_assets' , $plugin_assets ); 636 } 637 638 /** 639 * register_uninstall_hook() - Registers an uninstall callback that will be run when uninstalling the plugin. 640 * 641 * @param string $plugin_file Plugin file path 642 * @param callback $callback The hook that will be called during the plugin's uninstall process 643 */ 644 function register_uninstall_hook($plugin_file, $callback) { 645 register_plugin_assets($plugin_file, $callback); 646 } 647 648 /** 649 * register_plugin_option_asset() - Registers option(s) that will be uninstalled. 650 * 651 * If there are already options available that will be uninstalled, then the $options 652 * will be added to the list. If there are no options already, then the options will 653 * just be set. 654 * 655 * This function is useful for dynamically adding options that should be uninstalled 656 * during the uninstall process and the plugin won't be used any longer. 657 * 658 * The options should be given as a list without any keys. 659 * 660 * @param string $plugin_file Plugin file path 661 * @param string|array $options Single option or list of options to uninstall 662 */ 663 function register_plugin_option_asset($plugin_file, $options) { 664 if( !is_array($options) ) 665 $options = array( $options ); 666 667 register_plugin_assets($plugin_file, null, null, $options); 668 } 669 670 /** 671 * register_plugin_table_asset() - Registers table(s) that will be uninstalled. 672 * 673 * The table(s) should only be the ones that were added by your plugin and should 674 * not include the core plugins that WordPress installs. If you need to remove 675 * options then do so using the register_plugin_option_asset() or 676 * register_plugin_asset() function. 677 * 678 * The tables should be given as a list without any keys. 679 * 680 * @param string $plugin_file The path to the plugin file, usually given by __FILE__ 681 * @param string|array $tables Table or tables to uninstall 682 */ 683 function register_plugin_table_asset($plugin_file, $tables) { 684 if( !is_array($tables) ) 685 $tables = array( $tables ); 686 687 register_plugin_assets($plugin_file, null, $tables); 688 } 689 690 /** 691 * unregister_plugin_assets() - Unregisters the plugins uninstallable assets from the option 692 * 693 * @link http://trac.wordpress.org/ticket/5625 694 * 695 * @param string $plugin_file The path to the plugin file, usually given by __FILE__ 696 * 697 */ 698 function unregister_plugin_assets( $plugin_file ){ 699 $plugin_assets = get_option( 'plugin_assets' ); 700 $plugin = plugin_basename( $plugin_file ); 701 if ( isset( $plugin_assets[$plugin] ) ) { 702 unset($plugin_assets[$plugin]); 703 update_option( 'plugin_assets' , $plugin_assets ); 704 } 705 } 706 596 707 ?>