diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 3634190663b67..5af0a4a6b32d1 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -5419,7 +5419,25 @@ function wp_widgets_add_menu() { function wp_ob_end_flush_all() { $levels = ob_get_level(); for ( $i = 0; $i < $levels; $i++ ) { - ob_end_flush(); + $ob_status = ob_get_status(); + + // can be not set in some installations + if ( ! isset( $ob_status['flags'] ) ) { + break; + } + + if ( ( $ob_status['flags'] & PHP_OUTPUT_HANDLER_REMOVABLE ) === PHP_OUTPUT_HANDLER_REMOVABLE ) { + ob_end_flush(); + continue; + } + + if ( ( $ob_status['flags'] & PHP_OUTPUT_HANDLER_FLUSHABLE ) === PHP_OUTPUT_HANDLER_FLUSHABLE ) { + // we can't end it, but at least flush it + ob_flush(); + } + + // can't end any parents either + break; } } diff --git a/tests/phpunit/tests/functions/wpObEndFlushAll.php b/tests/phpunit/tests/functions/wpObEndFlushAll.php new file mode 100644 index 0000000000000..dd0746a5ec32a --- /dev/null +++ b/tests/phpunit/tests/functions/wpObEndFlushAll.php @@ -0,0 +1,61 @@ +markTestSkipped( + 'Non-removable output buffers cannot be tested at the moment, see https://github.com/sebastianbergmann/phpunit/issues/5851.' + ); + + // Clear any previous errors that could lead to false failures. + error_clear_last(); + + ob_start( array( $this, 'my_ob_cb' ), 0, 0 ); + + wp_ob_end_flush_all(); + + $this->assertNull( error_get_last() ); + } + + public function test_wp_ob_end_flush_all() { + $this->expectOutputString( '' ); + + // Clear any previous errors that could lead to false failures. + error_clear_last(); + + ob_start( array( $this, 'my_ob_cb' ) ); + + // will not be in phpunit, since we end all buffers below + // phpunit's behavior will change once the issue above is fixed though, in which case we would expect "hello" instead of empty string + echo 'hello'; + + wp_ob_end_flush_all(); + + $this->assertNull( error_get_last() ); + + // restart phpunit's output buffer + ob_start(); + } +}