diff --git a/src/wp-includes/plugin.php b/src/wp-includes/plugin.php index 479990a653..6e3a21e0a3 100644 --- a/src/wp-includes/plugin.php +++ b/src/wp-includes/plugin.php @@ -1019,19 +1019,21 @@ function _wp_filter_build_unique_id($tag, $function, $priority) { * * @return array the staticvar from the first time it is set. */ -function _backup_plugin_globals(){ +function _backup_plugin_globals( $backup = true ) { global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; static $backup_globals = array(); - if ( empty( $backup_globals ) ) { + if ( $backup ) { $backup_globals = array( 'backup_wp_filter' => $wp_filter, 'backup_wp_actions' => $wp_actions, 'backup_merged_filters' => $merged_filters, 'backup_wp_current_filter' => $wp_current_filter, ); - }; + + $wp_filter = $wp_actions = array(); + } return $backup_globals; } @@ -1047,24 +1049,49 @@ function _backup_plugin_globals(){ * @global array $wp_current_filter Stores the list of current filters with the current one last. * @staticvar array $backup_globals Backed up globals. */ -function _restore_plugin_globals(){ +function _restore_plugin_globals() { global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; - $backup_globals = _backup_plugin_globals(); + $backup_globals = _backup_plugin_globals( false ); - if ( $wp_filter !== $backup_globals['backup_wp_filter'] ){ - $wp_filter = array_merge_recursive( $wp_filter, $backup_globals['backup_wp_filter'] ); + if ( empty( $wp_filter ) ) { + $wp_filter = $backup_globals['backup_wp_filter']; + } else { + $added_filters = $wp_filter; + $wp_filter = $backup_globals['backup_wp_filter']; + + foreach ( $added_filters as $tag => $callback_groups ) { + // Loop through callback groups. + foreach ( $callback_groups as $priority => $callbacks ) { + + // Loop through callbacks. + foreach ( $callbacks as $cb ) { + add_filter( $tag, $cb['function'], $priority, $cb['accepted_args'] ); + } + } + } } - if ( $wp_actions !== $backup_globals['backup_wp_actions'] ){ - $wp_actions = array_merge_recursive( $wp_actions, $backup_globals['backup_wp_actions'] ); + if ( empty ( $wp_actions ) ) { + $wp_actions = $backup_globals['backup_wp_actions']; + } else { + $run_actions = $wp_actions; + $wp_actions = $backup_globals['backup_wp_actions']; + + foreach( $run_actions as $action => $count ) { + if ( ! isset( $wp_actions[ $action ] ) ) { + $wp_actions[ $action ] = 0; + } + + $wp_actions[ $action ] += $count; + } } - if ( $merged_filters !== $backup_globals['backup_merged_filters'] ){ + if ( $merged_filters !== $backup_globals['backup_merged_filters'] ) { $merged_filters = array_merge_recursive( $merged_filters, $backup_globals['backup_merged_filters'] ); } - if ( $wp_current_filter !== $backup_globals['backup_wp_current_filter'] ){ + if ( $wp_current_filter !== $backup_globals['backup_wp_current_filter'] ) { $wp_current_filter = array_merge_recursive( $wp_current_filter, $backup_globals['backup_wp_current_filter'] ); } } diff --git a/src/wp-settings.php b/src/wp-settings.php index 37a31c2fe7..1a241fac05 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -83,7 +83,7 @@ wp_debug_mode(); */ if ( WP_CACHE && apply_filters( 'enable_loading_advanced_cache_dropin', true ) ) { // For an advanced caching plugin to use. Uses a static drop-in because you would only want one. - _backup_plugin_globals(); + _backup_plugin_globals( true ); WP_DEBUG ? include( WP_CONTENT_DIR . '/advanced-cache.php' ) : @include( WP_CONTENT_DIR . '/advanced-cache.php' ); _restore_plugin_globals(); } diff --git a/tests/phpunit/tests/actions.php b/tests/phpunit/tests/actions.php index b02e2adcc9..fd45ffd6af 100644 --- a/tests/phpunit/tests/actions.php +++ b/tests/phpunit/tests/actions.php @@ -332,7 +332,7 @@ class Tests_Actions extends WP_UnitTestCase { * @ticket 36819 */ function test_backup_plugin_globals_returns_filters() { - $backup = _backup_plugin_globals(); + $backup = _backup_plugin_globals( true ); $this->assertArrayHasKey( 'backup_wp_filter', $backup ); $this->assertArrayHasKey( 'backup_wp_actions', $backup ); $this->assertArrayHasKey( 'backup_wp_current_filter', $backup ); @@ -343,14 +343,14 @@ class Tests_Actions extends WP_UnitTestCase { * @ticket 36819 */ function test_backup_plugin_globals_returns_filters_from_first_time_called() { - $backup = _backup_plugin_globals(); + $backup = _backup_plugin_globals( true ); $a = new MockAction(); $tag = rand_str(); add_action($tag, array(&$a, 'action')); - $new_backup = _backup_plugin_globals(); + $new_backup = _backup_plugin_globals( false ); $this->assertEquals( $backup, $new_backup ); } @@ -361,7 +361,7 @@ class Tests_Actions extends WP_UnitTestCase { global $wp_actions; $original_actions = $wp_actions; - _backup_plugin_globals(); + _backup_plugin_globals( true ); $wp_actions = array(); @@ -378,7 +378,7 @@ class Tests_Actions extends WP_UnitTestCase { global $wp_filter; $original_filter = $wp_filter; - $backup = _backup_plugin_globals(); + $backup = _backup_plugin_globals( true ); $a = new MockAction(); $tag = rand_str(); @@ -391,6 +391,26 @@ class Tests_Actions extends WP_UnitTestCase { $this->assertNotEquals( $GLOBALS['wp_filter'], $original_filter ); } + /** + * @ticket 36819 + */ + function test_applied_actions_are_counted_after_restore() { + global $wp_actions; + + $action_name = 'this_is_a_fake_action_name'; + $this->assertArrayNotHasKey( $action_name, $wp_actions ); + + do_action( $action_name ); + + $this->assertEquals( 1, $wp_actions[ $action_name ] ); + + _backup_plugin_globals( true ); + do_action( $action_name ); + _restore_plugin_globals(); + + $this->assertEquals( 2, $wp_actions[ $action_name ] ); + } + function apply_testing_filter() { $this->apply_testing_filter = true;