How to Drop Tables on Uninstall using WordPress? - mysql

On plugin activation, I have 4 tables that are created in the WordPress database.
On uninstall I'd like to have the tables deleted.
I've been able to write it out to delete the tables on deactivation. But from what I've read, it's better to keep the database tables information until the admin uninstalls rather than deactivates.
I've been looking for answers but all I seem to able to find is dropping them on deactivation. I do also have the version option I need to uninstall with it.

You should not make uninstall.php as bhuthecoder said.
Using an uninstall.php file to handle plugin uninstallation can be problematic because it relies on the plugin being properly installed and activated before it can be run. If the plugin was never activated, or if it was deactivated and then uninstalled, the uninstall.php file will not be run and any cleanup tasks that it was responsible for will not be performed. This can lead to plugin-specific data being left behind in the database, which can cause problems if the plugin is re-installed at a later time. A better approach is to use a WordPress uninstall hook.
You can name the file like you want or you can do that in single file without separate file for uninstallation.
register_uninstall_hook('uninstall.php', 'on_uninstall');
It means that WP will run uninstall.php and function on_uninstall in the uninstall.php when the plugin will be deleted. So, you can rename the file if you want, you can rename the function.
register_uninstall_hook(__FILE__, 'on_uninstall');
It means the same, but __FILE__ indicate current file which is working now and function on_uninstall should be in this file.
FILE php.net
The full path and filename of the file with symlinks resolved. If used
inside an include, the name of the included file is returned.
Simple example of functions for activation/deactivation/uninstallation.
function on_activation()
{
//Some stuff
}
function on_deactivation()
{
//Some stuff
}
function on_uninstall()
{
//Some stuff
}
register_activation_hook(__FILE__, 'on_activation');
register_deactivation_hook(__FILE__, 'on_deactivation');
register_uninstall_hook(__FILE__, 'on_uninstall');
If you added some options you can delete it when uninstall like this:
delete_option( 'some name' );
As bhuthecoder said, you should not drop tables when deactivation, it is redundant and not friendly for a user, who can lost his data after deactivation.
There are syntax mistake in your code:
$sql = 'DROP TABLE IF EXISTS $table_name;';
Should be like this:
$sql = "DROP TABLE IF EXISTS $table_name";
If you want to put some variable in the string you should use double quotes.
And require_once is redundant.
Better like this:
function e34s_db_clients_uninstall()
{
global $wpdb;
$table_name = $wpdb->prefix . 'e34s_clients';
$sql = "DROP TABLE IF EXISTS $table_name";
$wpdb->query($sql);
delete_option('e34s_time_card_version');
}
register_uninstall_hook(__FILE__, 'e34s_db_clients_uninstall');
Or like this:
register_uninstall_hook('uninstall.php', 'e34s_db_clients_uninstall');
With function e34s_db_clients_uninstall in the uninstall.php.

there are two ways to do this operation on plugin uninstall/delete.
the best way i learned is by using uninstall.php
uninstall.php only loads when a plugin is removed or deleted from the plugins you can put any code in it to run when user deletes or uninstalls a plugin.
<?php
/*
* Removing Plugin data using uninstall.php
* the below function clears the database table on uninstall
* only loads this file when uninstalling a plugin.
*/
/*
* exit uninstall if not called by WP
*/
if ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
exit();
}
/*
* Making WPDB as global
* to access database information.
*/
global $wpdb;
/*
* #var $table_name
* name of table to be dropped
* prefixed with $wpdb->prefix from the database
*/
$table_name = $wpdb->prefix . 'table_name_to_be_dropped';
// drop the table from the database.
$wpdb->query( "DROP TABLE IF EXISTS $table_name" );
change the "table_name_to_be_dropped" by your table name.

Well, I got many results when I googled this issue. Here is what I got:-
function mr_np_activate(){
// hook uninstall
if ( function_exists('register_uninstall_hook') )
register_uninstall_hook(__FILE__,'mr_np_uninstall');
}
register_activation_hook(__FILE__,'mr_np_activate');
function mr_np_uninstall() {
delete_option('my_plugins_options');
}
source: https://wordpress.stackexchange.com/questions/24600/how-can-i-delete-options-with-register-uninstall-hook
For more info: http://codex.wordpress.org/Function_Reference/register_uninstall_hook

Use, register_uninstall_hook.
It Registers the uninstall hook that will be called when the user clicks on the uninstall link that calls for the plugin to uninstall itself,
for details check http://codex.wordpress.org/Function_Reference/register_uninstall_hook

Drop tables only when admin uninstall/delete the plugin.
Don't drop tables when admin deactivates the plugin , as Users normally deactivates all plugins to troubleshoot the wordpress errors after fixing they will reactivate the plugins again,if you drop tables at that time they will loose all your plugin settings that configured by admin .Also while upgrading wordpress automatically deactivates all plugins and reactivates after successful upgrade.
Instructions to delete tables while unistalling:
1)First you need to create unistall.php in your plugin root folder.This file is automatically called by wordpress when user clicks delete button.You can include your code in this file.
2)Must read full documentation about this in http://codex.wordpress.org/Function_Reference/register_uninstall_hook

use register_deactivation_hook. thats work for me.
function on_deactivation() {
global $wpdb;
$table_name = $wpdb->prefix . 'school';
$sql = "DROP TABLE IF EXISTS $table_name";
$wpdb->query( $sql );
delete_option( 'wp_install_uninstall_config' );
}
register_deactivation_hook( __FILE__, 'on_deactivation' );

Related

How Do I Bulk Delete All Wordpress Posts in a Specific Category or Before a Specific Date?

I have some categories on a site with over 350,000 active posts some of which have as many as 50,000 posts. The volume makes using a bulk delete plugins not viable because they all timeout and delete nothing. The best feedback I've gotten from the Wordpress support forum is to use WP-CLI but beyond that all they've done is give me a link to the WP-CLI website which contains no example specific to my needs.
I have never used CLI before beyond a failed attempt to run Media Cleaner which resulted in a timeout at 999 seconds. That was months ago so I forget how I tried to do that. Could someone please post a code snippet that could basically be copied and pasted into CLI with the only change I need to make being swapping the category ID or date/ID number of the oldest post I want to keep?
Again, I want to be able to delete all posts from a specific category or before a specific date/ID.
Alternatively, could someone post a SQL statement so that I can do this using MySQL without installing CLI? The SQL would be better because I could apply it to any site without installing let alone learning CLI.
You don't have access to phpmyadmin?
You could avoid all of that just by deleting posts on load:
/**
* REMOVE EVIL POSTS IF AND WHEN LOADED
* add to functions.php
* works on regular posts and simple categories,
* check codex for details if custom post types, custom taxonomies, etc.
**/
add_action( 'template_redirect', 'delete_post_on_load' ) ;
function delete_post_on_load() {
global $post ;
//has term works more consistently if all variables are supplied
if ( has_term( array( 'Category to Go', 'Second Category to Go' ), 'category', $post->ID ) ) {
wp_delete_post( $post->ID, true ) ;
wp_safe_redirect( site_url() ) ; //redirect to home instead of 404 on deletion
exit() ;
}
}

Create a folder if it doesn't exist

Create a folder if it doesn't exist in Magento, I don't want to use mkdir(). Is there any way to do this ? May be core_file_uploader can work out, but its throwing error.
Magento has Varien_Io_File class for quite many filesystem works.
So instead of using PHP's vanilla mkdir() function, you can use the Magento's way:
$io = new Varien_Io_File();
$io->mkdir(your_path_to_dir);
Or you can also check if the directory does not exist right before creating it
$io = new Varien_Io_File();
if (!$io->fileExists(your_path_to_dir, false)) {
$io->mkdir(your_path_to_dir);
}

How to remove "CREATE DATABASE IF NOT EXISTS" statement from Export in phpMyAdmin 4?

I'm using phpMyAdmin 4.0.2 and seems when doing an export over a whole DB, by default it adds the statement "CREATE DATABASE IF NOT EXISTS" in the beginning of the export SQL.
I wasn't able to find a config option or any option to disable that... So is there a way to disable that and not have that statement in my exports by default?
This behavior did not happen by default in version 3. A quick fix, actually a hack and thus not the desirable solution, is to edit the export class file located in libraries/plugins/export/ExportSql.class.php and force the CREATE and USE statements to be commented out by adding "-- " before them, as such:
Line 709
$create_query = '-- CREATE DATABASE IF NOT EXISTS '
Line 734
'-- USE ' . PMA_Util::backquoteCompat($db, $compat)
Edit: There's a drawback, and that is if you export one or more entire databases (not just some or all the tables inside a database), then the CREATE and USE statements appear commented also.
A better idea as opposed to Hermes's answer would be to edit the file ./export.php ( Mind you: not db_export.php ).
On line 724 ( in phpMyAdmin 4.0.4 ) you'll find the lines:
if (! $export_plugin->exportDBCreate($db)) {
break;
}
You can comment or remove them to skip the creation of the create database statements ( Which in my opinion is also neater then having 2 commented lines in the export ).
Like so:
/*
if (! $export_plugin->exportDBCreate($db)) {
break;
}
*/
The rows above only apply to exporting a single database ( On line 720, you'll find: } elseif ($export_type == 'database') { ). So you won't break full server exports.
What I do is I first select the database on the left sidebar, and then click the Export option. The dump file doesn't contain the CREATE DATABASE statement.
One quick warning, this works for me, but I haven't analyzed if there are any other differences in the SQL export file that you might want to take into consideration

Override WP_SITEURL and WP_HOME for WordPress Multisite

For doing local development on a WordPress site (http://www.example.com), I was previously overriding the WP_SITEURL and WP_HOME values in wp-config.php like so:
define('WP_SITEURL', 'http://local-example/');
define('WP_HOME', 'http://local-example/');
This would allow me to copy the database and site files to a local server, and make modifications as necessary, testing on the local install.
It was then necessary to convert the install to a WordPress Multisite so that users, authentication, plugins, etc. could be shared between the main site and a secondary site, hosted on a subdomain (http://second.example.com).
The method above to override the values in the wp_options table no longer works, but I am unsure the proper way to set a value for the entries in wp_blogs as well as the wp_2_options table for the primary and subdomain.
Updating my HOSTS file is somewhat of a workaround, but it not ideal (I am not able to compare to the live site, etc). Running a script to change the database values is another option I have tried, but is slightly more cumbersome, so my questions is whether or not there is an option in MultiSite to override these values in a settings file, such as wp-config.php, and if so what it would look like.
Update: full updated plugin code with additional description can be found here: http://justinsilver.com/technology/wordpress/wordpress-plugins/wordpress-plugin-wp-server-migration/
I was able to come up with a solution with the help of #user916011. I needed to be able to copy the wp_options table(s) to my development environment as they contain configurations that are needed. To overcome the issue of not being able to set the WP_SITEURL and WP_HOME values in MultiSite, I wrote a custom filter to replace the _config_wp_siteurl() and _config_wp_home() functions that are available for non-multisite installs that is included in a plugin that is available network-wide and is configured in wp-config.php. I am then able to copy all of the database tables except wp_site and wp_blogs to a local database.
I highly recommend the URL Token Replacement Techniques for WordPress 3.0 article by Chris Murphy to help handle URLs in your content.
This example assumes a subdomain multisite install, with a domain of example.com and two subdomains, www.example.com and second.example.com. The local development URLs will be www.example.local and second.example.local respectively.
Database Changes:
Update the domain value in wp_site:
UPDATE wp_site SET domain = 'example.local' WHERE domain = 'example.com';
Update the domain value(s) in wp_blogs:
UPDATE wp_blogs SET domain = 'www.example.local' WHERE domain = 'www.example.com';
UPDATE wp_blogs SET domain = 'second.example.local' WHERE domain = 'second.example.com';
Plugin Code:
The following plugin should be installed network-wide.
<?php
/*
Plugin Name: MultiSite WP_HOME and WP_SITEURL
Plugin URI: http://doublesharp.com/
Description: Allows wp_options values to be overwritten in wp-config.php for MultiSite
Author: Justin Silver
Version: 1.0
Author URI: http://doublesharp.com
License: GPL2
*/
function _ms_config_wp_siteurl( $url = '' ) {
if (is_multisite()):
global $blog_id, $current_site;
$cur_blog_id = defined('BLOG_ID_CURRENT_SITE')? BLOG_ID_CURRENT_SITE : 1;
$key = ($blog_id!=$cur_blog_id)? $blog_id.'_' : '';
$constant = 'WP_'.$key.'SITEURL';
if ( defined( $constant ) )
return untrailingslashit( constant($constant) );
endif;
return $url;
}
add_filter( 'option_siteurl', '_ms_config_wp_siteurl' );
function _ms_config_wp_home( $url = '' ) {
if (is_multisite()):
global $blog_id;
$cur_blog_id = defined('BLOG_ID_CURRENT_SITE')? BLOG_ID_CURRENT_SITE : 1;
$key = ($blog_id!=$cur_blog_id)? $blog_id.'_' : '';
$constant = 'WP_'.$key.'HOME';
if ( defined( $constant ) )
return untrailingslashit( constant($constant) );
endif;
return $url;
}
add_filter( 'option_home', '_ms_config_wp_home' );
?>
Configure wp-config.php:
Add new constants to wp-config.php. The primary site should use the standard WP_HOME and WP_SITEURL and the tertiary URLs should use WP_{$blog_id}_HOME and WP_{$blog_id}_SITEURL
define('WP_HOME', 'http://www.example.local');
define('WP_SITEURL', 'http://www.example.local');
define('WP_2_HOME', 'http://secondary.example.local');
define('WP_2_SITEURL', 'http://secondary.example.local');
You could use the update_option in functions.php
update_option("siteurl","http://example.com");
update_option("home","http://example.com");
There's a similar question being asked here: Team Development of a Wordpress Site which I provided a possible solution for. In your case, you may not want to go to that extent (though it would be very flexible); however, you could always look at the portion of the answer that mentions a domain-replacement technique.
I've outlined that solution here: URL Token Replacement Techniques...
I had the same issue and wanted a solution as similar to defining WP_HOME & WP_SITEURL in wp-config.php as possible.
I can't use a plugin, because I am syncing with GIT and don't want to have that plugin in my repo and I would have to add the plugin everytime... I suppose it could be activated network wide through the wp_sitemeta table... but it wasn't ideal for me.
I came up with this solution.
Be sure to not sync wp_blogs, wp_site, wp_sitemeta. And then add this code to your local wp-config.php somewhere below $table_prefix:
/* Update local database */
mysql_connect( DB_HOST, DB_USER, DB_PASSWORD ) or die( mysql_error() );
mysql_select_db( DB_NAME );
$result = mysql_query("SELECT * FROM `". $table_prefix ."blogs`") or die( mysql_error() );
while( $row = mysql_fetch_array( $result ) )
{
$id = (1 == $row['blog_id']) ? '' : $row['blog_id'] .'_';
mysql_query( "UPDATE `". $table_prefix . $id ."options` SET `option_value`='http://". $row['domain'] ."/' WHERE (`option_name`='siteurl' OR `option_name`='home')" ) or die( mysql_error() );
}
This will make sure your sites are synced up to your local wp_blogs table.
The only drawback is that when you add a new site, you do manually need to copy it into your wp_blogs table and update its local url.
This question is too old to answer, but recently I faced a similar situation where I have to migrate my wp site from staging to production and it was painful as it is having 5 subsite.
After scratching my head for all day, I found a simple and useful solution.
Of course one have to make changes in wp-config.php.
Other then that you have to follow below steps.
Generate database dump using following command.
mysqldump -u [user name] –p [password] [options] [database_name] [tablename] > [FileName]
After that open that file in any editor.
Find and replace your old domain with new domain.
Now restore the database with dump you created.
mysql -u [user name] -p [password] [database name] < [file anme]

Need a MySQL query to delete Wordpress comments

My wordpress site was recently hacked so I had to reinstall everything. Wordpress resinstalled, database backups imported, everything fine and dandy. Then I installed the Disqus plugin and synced (Disqus was previously used before the site was hacked). Big no-no apparantly. Now I have a duplicate of every single comment on my site! Even worse, the duplicate comments have been synced BACK to Disqus!
So, I know this is a simple query in PHPMyAdmin but I don't know it! Please help!
Keep in mind that there is a WordPress Stack Exchange website ;)
I would use PHP unless you know the wpdb name off the top of your head. Be sure to back up the DB first! Like so:
global $wpdb;
$comments = $wpdb->get_results("SELECT * FROM ".$wpdb->prefix."_comments"
." ORDER BY comment_post_ID, comment_content");
$prev = NULL;
foreach($comments as $comment) {
if ($prev && $prev->comment_content == $comment->comment_content
&& $prev->comment_post_ID == $comment->comment_post_ID ) { // add maybe other rules here
$wpdb->query("DELETE FROM ".$wpdb->prefix."_comments" WHERE comment_ID == $comment- >comment_ID");
}
else
$prev = $comment;
}
If he doesn't know how use mysql, I think re editing the wp interface is great, because usually wp creating there build function for queries. And it may lead again to destruction of it.
The only reason why it doesn't work maybe its because of the plug in they use.! I think so.!
The query for deleting in mysql is
Delete from (tablename) where (primarykey)
But I think wordpress has its build in database queries for select delete and update.
Here's another if you use the plugin Disqus
If you're logged into your Disqus account you can also choose to delete a comment at your dashboard. This will remove it from your profile and remove all identifying information from the comment on the original page. Once a comment has been anonymized it cannot be claimed again.