SponsoredHosinger Special Offer

WP+ WordPress Plugin Development

Build WordPress plugins from scratch: actions and filters, shortcodes, settings pages, custom post types, meta boxes, AJAX, REST endpoints, custom tables, cron and blocks.

Activation, Deactivation and Uninstall

WordPress Plugin Development Lesson 7 of 27 ~3 min read

Overview

WordPress gives plugins three lifecycle moments — activation, deactivation and uninstall — so you can create default settings when a plugin is switched on, pause scheduled work when it is switched off, and delete every trace of it when it is removed.

Activation

<?php
/**
 * Runs once, when the plugin is activated.
 */
function gdc_books_activate() {
    // Default settings, only if they don't exist yet (re-activation keeps old ones).
    add_option(
        'gdc_books_settings',
        array(
            'books_per_page' => 6,
            'show_isbn'      => true,
        )
    );

    // Register the post type now, then flush, so /books/ works immediately.
    gdc_books_register_post_type();
    flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'gdc_books_activate' );
  • register_activation_hook() must be called from the main plugin file with __FILE__.
  • add_option() does nothing if the option already exists — exactly what you want, so re-activating does not reset a user's settings.
  • flush_rewrite_rules() rebuilds the URL rules so your post type's pretty URLs work. It is expensive: call it only on activation and deactivation, never on init.

Deactivation

<?php
function gdc_books_deactivate() {
    // Stop scheduled events (lesson 21).
    wp_clear_scheduled_hook( 'gdc_books_daily_cleanup' );

    // Remove our rewrite rules.
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'gdc_books_deactivate' );
Watch out: Deactivation is not uninstall. People deactivate plugins temporarily to debug a problem. Never delete their data on deactivation — they would lose every book when they switch the plugin back on.

Uninstall

When someone clicks Delete on the Plugins screen, WordPress looks for uninstall.php in your plugin folder and runs it. Create gdc-books/uninstall.php:

<?php
/**
 * Removes all GDC Books data when the plugin is deleted.
 */

// Only run when WordPress itself is uninstalling the plugin.
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
    exit;
}

// Settings.
delete_option( 'gdc_books_settings' );
delete_option( 'gdc_books_db_version' );

// Transients (lesson 21).
delete_transient( 'gdc_books_stats' );

// All Book posts and their meta.
$book_ids = get_posts(
    array(
        'post_type'   => 'gdc_book',
        'post_status' => 'any',
        'numberposts' => -1,
        'fields'      => 'ids',
    )
);

foreach ( $book_ids as $book_id ) {
    wp_delete_post( $book_id, true ); // true: skip the trash.
}

// A custom table (lesson 20).
global $wpdb;
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}gdc_books_favourites" );

The WP_UNINSTALL_PLUGIN check is vital: without it, anyone requesting the file's URL directly could wipe your users' data.

Tip: Some users want to delete a plugin but keep its content — for example, to reinstall later. Respect that with a "Delete all data on uninstall" checkbox in your settings, and check it at the top of uninstall.php before deleting anything.

Multisite

On a multisite network, options and posts exist per site. A thorough uninstall.php loops through each site with get_sites() and switch_to_blog() / restore_current_blog() to clean up everywhere.

Practice

  • Add the activation hook and confirm the gdc_books_settings option appears in Settings → All Options (/wp-admin/options.php).
  • Deactivate and reactivate — the option keeps its value.
  • Add uninstall.php, delete the plugin, and confirm the option is gone.
Create a free account to save which lessons you've finished. Save my progress