[wp-hackers] Hook being called twice on activate, once on deactivate

Chris Jean gaarai at gaarai.com
Thu Oct 29 19:52:49 UTC 2009


Frankly, your code is a mess.

Your register_activation_hook call is not passing the name of a function
that should be called; rather, it is directly calling the function.
That's what call_user_func does, it runs the function.

That means that when the register_activation_hook portion of the code is
encountered, it immediately executes the wpdb_test_activate function.

The reason why it is running three times when you activate and then
deactivate is because it does the following:

   1. Runs once when the activate link is clicked. WordPress basically
      tries to run it just to ensure that the code is valid and doesn't
      crash before actually activating it. This would also account for
      why $wpdb doesn't exist since it is more or less working in just a
      sandbox environment at this point.
   2. Runs again when the Plugins page reloads after having the plugin
      activated. It runs since it is now an active plugin and as all
      active plugins do, it executes.
   3. Runs again when you deactivate the plugin since a full run of the
      code executes before deactivating the plugin in order to give the
      plugin time to respond to deactivation actions.

I bet if you navigated through the site with the plugin activated, you
would see output each time as each time the code runs, the
call_user_func is executing wpdb_test_activate.

Personally, I think using a define for the table name is sloppy and
error-prone (this situation makes a case for it).

Getting back to the topic, your main issue is the call_user_func. It
should look like the following:

    register_activation_hook( __FILE__, 'wpdb_test_activate' );

Notice that you can't add any variables. All register_activation_hook
does is create an action, and you can't pass variable data to an
add_action. The idea is that variable data gets passed to the registered
function, but in this case, no parameters are passed to the registered
activation function.

Chris Jean
http://gaarai.com/
@chrisjean



mark waterous wrote:
> I was hoping somebody on here might be able to explain the following strange
> behavior I stumbled across.
>
>  
>
> I've been working on a plugin that during activation needs to create some
> tables. The table names are stored in constants for use in various locations
> around the plugins codebase, and are defined ala;
>
>  
>
> define( 'MYPLUGIN_TABLE_WHATEVER', $wpdb->prefix . 'table_whatever' );
>
>  
>
> Which works fine everywhere else in the code, returning the desired
> 'wp_#_table_whatever' string I need. Right up until the constant is used
> from inside an activation callback, at which point it drops the
> $wpdb->prefix, and I wind up with tables called only 'table_whatever' (no
> prefix). So I wrote a quick'n'dirty to try and discern what was occurring;
>
>  
>
> <?php /*
>
> Plugin Name: WPDB Object Test
>
> Description: If you only knew.
>
> Version: 0.1
>
> */
>
>  
>
> define( 'WPDB_TEST_TABLE', $wpdb->prefix . 'table_name' );
>
>  
>
> $outside_data = WPDB_TEST_TABLE;
>
>  
>
> function wpdb_test_activate( $outside_data ) {
>
>                 global $wpdb;
>
>  
>
>                 $file = dirname( __FILE__ ) . '/test.log';
>
>  
>
>                 $data = 'Outside: ' . $outside_data . "\n";
>
>                 $data .= 'Constant: ' .WPDB_TEST_TABLE . "\n";
>
>                 $data .= 'Inside: ' . $wpdb->prefix . "table_name\n\n";
>
>  
>
>                 $fp = @fopen( $file, 'a' );
>
>                 if ( $fp )
>
>                                 fwrite( $fp, $data );
>
>                 fclose( $fp );
>
> }
>
>  
>
> register_activation_hook( __FILE__, call_user_func( 'wpdb_test_activate',
> $outside_data ) );
>
> ?>
>
>  
>
> This resulted in behavior I wasn't expecting - it would appear that the hook
> runs twice on activation. The first run strips $wpdb->prefix, the second
> time it doesn't. It also runs the activation hook again on deactivation.
> Should it be doing that? The actual plugin has a deactivation hook of
> course, but I wasn't expecting it to run the activation hook in absence of
> this.
>
>  
>
> My test.log file looks like this, though you could run it for yourself to be
> sure (the first two groups are from activation, the third from
> deactivation):
>
>  
>
> <test.log>
>
> Outside: table_name
>
> Constant: table_name
>
> Inside: wp_3_table_name
>
>  
>
> Outside: wp_3_table_name
>
> Constant: wp_3_table_name
>
> Inside: wp_3_table_name
>
>  
>
> Outside: wp_3_table_name
>
> Constant: wp_3_table_name
>
> Inside: wp_3_table_name
>
> </test.log>
>
>  
>
> (sorry about the long post, and this apology that makes it even longer)
>
>  
>
> --
>
> Mark Waterous
>
>  <http://mark.watero.us/> http://mark.watero.us/ ( <mailto:mark at watero.us>
> mark at watero.us) 
>
>  
>
> _______________________________________________
> wp-hackers mailing list
> wp-hackers at lists.automattic.com
> http://lists.automattic.com/mailman/listinfo/wp-hackers
>   


More information about the wp-hackers mailing list