|
View:
New views
9 Messages
—
Rating Filter:
Alert me
|
|
|
Hook being called twice on activate, once on deactivateI 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@...> mark@...) _______________________________________________ wp-hackers mailing list wp-hackers@... http://lists.automattic.com/mailman/listinfo/wp-hackers |
|
|
Re: Hook being called twice on activate, once on deactivateA solution might be to summon wpdb, before defining the constant:
global $wpdb; I assume your problem is caused by the different scope that the plugin is activated in. -- http://scribu.net _______________________________________________ wp-hackers mailing list wp-hackers@... http://lists.automattic.com/mailman/listinfo/wp-hackers |
|
|
Re: Hook being called twice on activate, once on deactivate> -----Original Message-----
> Sent: Thursday, October 29, 2009 12:24 PM > To: wp-hackers@... > Subject: [wp-hackers] Hook being called twice on activate, once on > deactivate > > I was hoping somebody on here might be able to explain the following > strange behavior I stumbled across. > That's odd how it added extra line breaks. *kicks Outlook* -Mark _______________________________________________ wp-hackers mailing list wp-hackers@... http://lists.automattic.com/mailman/listinfo/wp-hackers |
|
|
Re: Hook being called twice on activate, once on deactivateI can't explain why you're having it run twice or whatever, but the
reason you lose the prefix is simple. Your $wpdb is not in scope at the initial activation point. When you first get activated, your plugin is included from inside the activate_plugin function, meaning that you're not in global scope for that one run, you're in the function scope. When you get included from then on, in the normal load-everything sequence, your plugin gets included from the main path, inside wp-settings.php. $wpdb won't be defined in the function scope, unless you global it first. Which just goes to show: If you want a global variable, then *always* say so. Never assume scope. -Otto _______________________________________________ wp-hackers mailing list wp-hackers@... http://lists.automattic.com/mailman/listinfo/wp-hackers |
|
|
Re: Hook being called twice on activate, once on deactivateOn Thu, Oct 29, 2009 at 2:24 PM, mark waterous <mark@...> wrote:
> 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. That's not how to use register_activation_hook. call_user_func() there is calling the wpdb_test_activate function when it's defined, which is when the file is read in, rather than when the activation hook fires. Should be something like register_activation_hook( __FILE__, 'wpdb_test_activate'); and then figure out another way to pass the $outside_data stuff. _______________________________________________ wp-hackers mailing list wp-hackers@... http://lists.automattic.com/mailman/listinfo/wp-hackers |
|
|
Re: Hook being called twice on activate, once on deactivateFrankly, 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@...> > mark@...) > > > > _______________________________________________ > wp-hackers mailing list > wp-hackers@... > http://lists.automattic.com/mailman/listinfo/wp-hackers > wp-hackers mailing list wp-hackers@... http://lists.automattic.com/mailman/listinfo/wp-hackers |
|
|
Re: Hook being called twice on activate, once on deactivateThat fixes the constant returning the proper string, but is the activation
hook supposed to be run twice like that? And again on deactivation if there is no deactivation hook? -- Mark (http://mark.watero.us/) > -----Original Message----- > Sent: Thursday, October 29, 2009 12:39 PM > To: wp-hackers@... > Subject: Re: [wp-hackers] Hook being called twice on activate, once on > deactivate > > A solution might be to summon wpdb, before defining the constant: > > global $wpdb; > > I assume your problem is caused by the different scope that the plugin > is activated in. > > -- > http://scribu.net _______________________________________________ wp-hackers mailing list wp-hackers@... http://lists.automattic.com/mailman/listinfo/wp-hackers |
|
|
Re: Hook being called twice on activate, once on deactivateOn Thu, Oct 29, 2009 at 2:58 PM, mark waterous <mark@...> wrote:
> That fixes the constant returning the proper string, but is the activation > hook supposed to be run twice like that? And again on deactivation if there > is no deactivation hook? The *activation hook* is not being called during those times; the *call_user_func()* call is. Each time: 1. Test include of plugin file to check for fatal errors, immediately prior to activation. 2. Actual include of plugin file because it's activated. 3. Include of plugin file just prior to deactivation. _______________________________________________ wp-hackers mailing list wp-hackers@... http://lists.automattic.com/mailman/listinfo/wp-hackers |
|
|
Re: Hook being called twice on activate, once on deactivateI appreciate the comments, but the plugin itself doesn't use
call_user_func(), I simply did that in the test as a way to pass an argument to the function. It was meant to be a quick and dirty test, I wasn't really priding myself on the coding style in that sample - the root of the problem was the scope during activation as Otto informed me. Thank you for also pointing out however that call_user_func is executing every time the file is accessed, it's not a function I've used very much in the past, and I will make sure the same mistake isn't made twice. - Mark > -----Original Message----- > Sent: Thursday, October 29, 2009 12:53 PM > To: wp-hackers@... > Subject: Re: [wp-hackers] Hook being called twice on activate, once on > deactivate > > Frankly, your code is a mess. _______________________________________________ wp-hackers mailing list wp-hackers@... http://lists.automattic.com/mailman/listinfo/wp-hackers |
| Free embeddable forum powered by Nabble | Forum Help |