Note:

This post is abondoned. I have stopped working on wordpress projects and as such I no longer keep track of wordpress related things.


UPDATE (3 August 2012) In version 3.3.0 wordpress core provided direct activation/deactivation hook for themes (see the new usage below). (thanks to jacobsnyder for telling me about it)
NOTE: The old approach will still work, so you don’t need to change your existing code if you were using the old approach.

Activation hook:

Code:

<?php  
function myactivationfunction($oldname, $oldtheme=false) {

}
add_action("after_switch_theme", "myactivationfunction", 10 ,  2);  

Explanation:
We write a function ‘myactivationfunction’ and attach it to “afterswitchtheme” hook. (This goes in your functions.php file)

Detailed Explanation (not necessary to use):
When theme is deactivated, wordpress core switches the theme in switch_theme function (wp-includes/theme.php @line 649). This function calls “switch_theme” hook (which we will use as deactivation hook), and adds an option “theme_switched”.

check_theme_switched() function is attached to “init” hook on every page request [add_action( 'init', 'check_theme_switched', 99 ); is attached at wp-includes/default-filters.php (@line 214)]. Its job is to check if “theme_switched” option exists and if it exists then it does “after_switch_theme” action. After performing that action it deletes that option “theme_switched”.

It’s similar to the approach we were taking.

Deactivation hook:

Code:

<?php  
function mydeactivationfunction($newname, $newtheme) {

}
add_action("switch_theme", "mydeactivationfunction", 10 , 2);  

Explanation:
We write a function ‘mydeactivationfunction’ and attach it to “switch_theme” hook. (This goes in your functions.php file)

Detailed Explanation (not necessary to use):
When admin activates a new theme, switch_theme function is called at wp-includes/theme.php (@line 23). This function calls switch_theme hook which we use as deactivation hook.

For wordpress version < 3.3.0

When you develop plugin you can use register_activation_hook and register_deactivation_hook functions to add your functions which will be called when plugin is being activated or deactivated. They are very useful functions as often plugin developer has to set the environment for plugin to work.

No such hooks exist for wordpress themes. If you are a theme developer and you need to run some code when theme gets activated then you have to rely on unreliable methods like this:

if ( is_admin() && isset($_GET['activated'] ) && $pagenow == 'themes.php' ) {  
// your code here
}

This method is pretty unreliable as after activating a theme admin can refresh that page and if that happens then your activation code will run twice.
And there is no method at all to run some code on theme deactivation. Now as themes are evolving rapidly this poses one serious limitation.

As wordpress 3.0.4 came out I once again thought of searching for any such method, but they haven’t provided any such hooks for themes yet.

I have developed theme activation/deactivation hooks and I think that it is 100% reliable.
Download and include this php file in your theme code. Register hooks and that’s all. File has usage example at top. Let me know what you guys think.

<?php  
/**
* Provides activation/deactivation hook for wordpress theme.
*
* Usage:
* ----------------------------------------------
* Include this file before this line.
* ----------------------------------------------
* function my_theme_activate() {
*    // code to execute on theme activation
* }
* wp_register_theme_activation_hook('mytheme', 'my_theme_activate');
*
* function my_theme_deactivate() {
*    // code to execute on theme deactivation
* }
* wp_register_theme_deactivation_hook('mytheme', 'my_theme_deactivate');
* ----------------------------------------------
*
* @author Krishna Kant Sharma (http://www.krishnakantsharma.com)
*/

/**
*
* @desc registers a theme activation hook
* @param string $code : Code of the theme. This can be the base folder of your theme. Eg if your theme is in folder 'mytheme' then code will be 'mytheme'
* @param callback $function : Function to call when theme gets activated.
*/
function wp_register_theme_activation_hook($code, $function) {  
$optionKey="theme_is_activated_" . $code;
  if(!get_option($optionKey)) {
      call_user_func($function);
      update_option($optionKey , 1);
  }
}

/**
* @desc registers deactivation hook
* @param string $code : Code of the theme. This must match the value you provided in wp_register_theme_activation_hook function as $code
* @param callback $function : Function to call when theme gets deactivated.
*/
function wp_register_theme_deactivation_hook($code, $function) {  
  // store function in code specific global
  $GLOBALS["wp_register_theme_deactivation_hook_function" . $code]=$function;

  // create a runtime function which will delete the option set while activation of this theme and will call deactivation function provided in $function
  $fn=create_function('$theme', ' call_user_func($GLOBALS["wp_register_theme_deactivation_hook_function' . $code . '"]); delete_option("theme_is_activated_' . $code. '");');

  // add above created function to switch_theme action hook. This hook gets called when admin changes the theme.
  // Due to wordpress core implementation this hook can only be received by currently active theme (which is going to be deactivated as admin has chosen another one.
  // Your theme can perceive this hook as a deactivation hook.)
  add_action("switch_theme", $fn);
}