Activation and Deactivation hooks, a piece of cake!
Webprogramo > Blog > Wordpress > Activation and Deactivation Hooks, a piece of cake!

Activation and Deactivation Hooks, a piece of cake!

How to use activate and deactivate plugin hooks on WordPress!

Alejandro Lopez

12 julio, 2017

Webprogramo > Blog > Wordpress > Activation and Deactivation Hooks, a piece of cake!
SHARE! and the author will get a Yummy Cookie :
Share this...
Share on Facebook
Tweet about this on Twitter

Once upon a time (a couple of days ago to be more accurate), I was talking about How to create a painless WordPress Plugin, and I spoke a little bit about «Activation and Deactivation hooks.» Now, we are doing an example to learn more about these two important WordPress actions.

Activation and deactivation hooks example!

Let’s say we have a sweet cake store. Our WordPress website has everything set up to sell those delicious pieces of strawberry cake. But, for some supernatural reason, we want to register and count every click in our «Add to Cart» button, either our user buys it or not.

So, to accomplish this goal, we are going to create a table named «wp_addtocart_click» to save, post_id, IP, and timestamp, when our plugin is activated, and we are going to remove this table when the user deactivates it.

Then, this is the code to create the plugin we are talking about; it is a commented code for better understanding.

Plugin Name: Add To Cart Counter
Plugin URI: https:/
Description: This is a Piece Of Cake Add To Cart button click counter to explain the Activation and Deactivation Hooks
Version: 1.0
Author: Alejandro Lopez
Author URI:
License: GPL2

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {

// Plugin constants, (Just to look a little smarter)
define( 'POC_VERSION', '1.0.0' );
define( 'POC_MAIN_FILE', __FILE__ );
define( 'ADD_TO_CART_CLICK', 'addtocart_click' );

class Piece_Of_Cake_Counter {

    public function __construct(){
        // Here is the activation hook function where we register our function "add_to_cart_counter_create_table" 
        // to be executed one time when the plugin is activated
        register_activation_hook( POC_MAIN_FILE, array( $this, 'add_to_cart_counter_create_table' ) );
        // Here is the deactivation hook function where we register our function "add_to_cart_counter_remove_table" 
        // to be executed one time when the plugin is deactivated
        register_deactivation_hook( POC_MAIN_FILE, array( $this, 'add_to_cart_counter_remove_table' ) );
        // Let's say we are going to execute the counter function with AJAX, then, this is the way.
        // WordPress executes this addtocart_click function for logged-in users and not logged-in users
        add_action( 'wp_ajax_addtocart_click', array( $this, 'addtocart_click' ) );
        add_action( 'wp_ajax_nopriv_addtocart_click', array( $this, 'addtocart_click' ) );
     * This function creates the Add To Cart table to save every click on "Add To Cart Button"
     * This is going to be executed only when the plugin is activated.

    public function add_to_cart_counter_create_table(){
        // Get database helper
        global $wpdb;
        // Get Database Charset (To be consistent with our current database configuration)
        $charset_collate = $wpdb->get_charset_collate();
        // Create the table name using the WordPress prefix to be consistent with our database configuration
        $table = $wpdb->prefix . ADD_TO_CART_CLICK;
        // This is the SQL string to create the addtochart_click table
        $sql = "CREATE TABLE $table (
            id int(11) NOT NULL AUTO_INCREMENT,
            post_id int(11) NOT NULL,
            ip varchar(39) NOT NULL,
            timestamp timestamp DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY  (id)
        ) $charset_collate;";
        // The dbDelta function requires the upgrade.php file to be loaded first and as WordPress Says:
        // The dbDelta function examines the current table structure, compares it to the desired table structure, and either adds or modifies the table as necessary.
        // Then, it is the most recommended way to update / create our database table.
        require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
        dbDelta( $sql );
        // Here we add an option with the plugin version, it is very handy when we need to upgrade our plugin.
        add_option( 'add_to_cart_counter', POC_VERSION );

        // This option is explained in the deactivation function.
        add_option( 'remove_add_to_cart_counter', 1 );

     * This function removes the Add To Cart table when the plugin is deactivated

    public function add_to_cart_counter_remove_table() {

        // This option must be created in a configuration section of our plugin.
        // I am not going to explain how to do it now, but, basically, it adds an option for the user to check 
        // if they are sure to remove all the plugin data when the plugin is deactivated, with this, 
        // the user doesn't lose all the registered clicks when they temporary disables the plugin.
        if( ! get_option( 'remove_add_to_cart_counter' ) ) return;
        // Get database helper
        global $wpdb;
        $table = $wpdb->prefix . ADD_TO_CART_CLICK;
        // We execute our DROP TABLE query to remove the addtochart_click table
        $wpdb->query( "DROP TABLE IF EXISTS $table" );
        // We remove the plugin version and remove data validator options
        delete_option( "add_to_cart_counter" );
        delete_option( "remove_add_to_cart_counter" );
     * This is the add to cart AJAX function

    public function addtocart_click() {
        // We validate the post_id sent by AJAX, and check if the post (cake) is "published."
        if( isset( $_POST['post_id'] ) && 'publish' === get_post_status( $_POST['post_id'] ) ) {
            // Get database helper
            global $wpdb;
            // Save the click event on Database.
            $table = $wpdb->prefix . ADD_TO_CART_CLICK;
                    'post_id' => $_POST['post_id'],
                    'ip' => $this->getIP()

            echo 'Done';
        } else {
            echo 'Not done';
        // End of the AJAX
    // getIP function.
    function getIP()
        // populate a local variable to avoid extra function calls.
        // NOTE: use of getenv is not as common as use of $_SERVER.
        //       because of this use of $_SERVER is recommended, but 
        //       for consistency, I'll use getenv below
        $tmp = getenv("HTTP_CLIENT_IP");
        // you DON'T want the HTTP_CLIENT_ID to equal unknown. That said, I don't
        // believe it ever will (same for all below)
        if ( $tmp && !strcasecmp( $tmp, "unknown"))
            return $tmp;

        $tmp = getenv("HTTP_X_FORWARDED_FOR");
        if( $tmp && !strcasecmp( $tmp, "unknown"))
            return $tmp;

        // no sense in testing SERVER after this. 
        // $_SERVER[ 'REMOTE_ADDR' ] == gentenv( 'REMOTE_ADDR' );
        $tmp = getenv("REMOTE_ADDR");
        if($tmp && !strcasecmp($tmp, "unknown"))
            return $tmp;



// Last, we just initialize the class, and the piece of cake add to cart button counter is done!
new Piece_Of_Cake_Counter();

And, that’s it, now you have a clue about how to use the activation and deactivation hooks for plugins on WordPress =), if you want to know the basics to create a plugin in WordPress go to WordPress Plugin (Incredible easy and painless).

The getIP() function is was taken from here, thanks to cwallenpoole.