Make WordPress Core

Changeset 61111


Ignore:
Timestamp:
11/01/2025 04:44:21 AM (11 months ago)
Author:
westonruter
Message:

General: Rename wp_send_late_headers action to wp_finalized_template_enhancement_output_buffer.

Also update docs for wp_finalized_template_enhancement_output_buffer action and wp_template_enhancement_output_buffer filter to warn against attempting to open an output buffer in callbacks or else a PHP fatal error will occur.

Developed in ​https://github.com/WordPress/wordpress-develop/pull/10443

Follow-up to [61088], [60936].

Props westonruter, dmsnell.
See #43258.
Fixes #64126.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp.php

    r61088 r61111  
    589589                 * Fires once the requested HTTP headers for caching, content type, etc. have been sent.
    590590                 *
    591                  * The {@see 'wp_send_late_headers'} action may be used to send headers after rendering the template into an
    592                  * output buffer.
     591                 * The {@see 'wp_finalized_template_enhancement_output_buffer'} action may be used to send
     592                 * headers after rendering the template into an output buffer.
    593593                 *
    594594                 * @since 2.1.0
  • trunk/src/wp-includes/default-filters.php

    r61089 r61111  
    424424add_action( 'do_robots', 'do_robots' );
    425425add_action( 'do_favicon', 'do_favicon' );
    426 add_action( 'wp_before_include_template', 'wp_start_template_enhancement_output_buffer', 1000 ); // Late priority to let `wp_template_enhancement_output_buffer` filters and `wp_send_late_headers` actions be registered.
     426add_action( 'wp_before_include_template', 'wp_start_template_enhancement_output_buffer', 1000 ); // Late priority to let `wp_template_enhancement_output_buffer` filters and `wp_finalized_template_enhancement_output_buffer` actions be registered.
    427427add_action( 'set_comment_cookies', 'wp_set_comment_cookies', 10, 3 );
    428428add_action( 'sanitize_comment_cookies', 'sanitize_comment_cookies' );
  • trunk/src/wp-includes/template.php

    r61088 r61111  
    845845         *
    846846         * By default, an output buffer is only started if a {@see 'wp_template_enhancement_output_buffer'} filter has been
    847          * added or if a plugin has added a {@see 'wp_send_late_headers'} action. For this default to apply, either of the
    848          * hooks must be added by the time the template is included at the {@see 'wp_before_include_template'} action. This
    849          * allows template responses to be streamed unless the there is code which depends on an output buffer being opened.
    850          * This filter allows a site to opt in to adding such template enhancement filters later during the rendering of the
    851          * template.
     847         * added or if a plugin has added a {@see 'wp_finalized_template_enhancement_output_buffer'} action. For this
     848         * default to apply, either of the hooks must be added by the time the template is included at the
     849         * {@see 'wp_before_include_template'} action. This allows template responses to be streamed unless the there is
     850         * code which depends on an output buffer being opened. This filter allows a site to opt in to adding such template
     851         * enhancement filters later during the rendering of the template.
    852852         *
    853853         * @since 6.9.0
    … …  
    855855         * @param bool $use_output_buffer Whether an output buffer is started.
    856856         */
    857         return (bool) apply_filters( 'wp_should_output_buffer_template_for_enhancement', has_filter( 'wp_template_enhancement_output_buffer' ) || has_action( 'wp_send_late_headers' ) );
     857        return (bool) apply_filters( 'wp_should_output_buffer_template_for_enhancement', has_filter( 'wp_template_enhancement_output_buffer' ) || has_action( 'wp_finalized_template_enhancement_output_buffer' ) );
    858858}
    859859
    … …  
    960960        if ( ! $is_html_content_type ) {
    961961                /** This action is documented in wp-includes/template.php */
    962                 do_action( 'wp_send_late_headers', $output );
     962                do_action( 'wp_finalized_template_enhancement_output_buffer', $output );
    963963                return $output;
    964964        }
    … …  
    976976         * fully supports HTML5.
    977977         *
     978         * Important: Because this filter is applied inside an output buffer callback (i.e. display handler), any callbacks
     979         * added to the filter must not attempt to start their own output buffers. Otherwise, PHP will raise a fatal error:
     980         * "Cannot use output buffering in output buffering display handlers."
     981         *
    978982         * @since 6.9.0
    979983         *
    … …  
    984988
    985989        /**
    986          * Fires at the last moment HTTP headers may be sent.
    987          *
    988          * This happens immediately before the template enhancement output buffer is flushed. This is in contrast with
    989          * the {@see 'send_headers'} action which fires after the initial headers have been sent before the template
    990          * has begun rendering, and thus does not depend on output buffering. This action does not fire if the "template
    991          * enhancement output buffer" was not started. This output buffer is automatically started if this action is added
    992          * before {@see wp_start_template_enhancement_output_buffer()} runs at the {@see 'wp_before_include_template'}
    993          * action with priority 1000. Before this point, the output buffer will also be started automatically if there was a
     990         * Fires after the template enhancement output buffer has been finalized.
     991         *
     992         * This happens immediately before the template enhancement output buffer is flushed. No output may be printed at
     993         * this action. However, HTTP headers may be sent, which makes this action complimentary to the
     994         * {@see 'send_headers'} action, in which headers may be sent before the template has started rendering. In
     995         * contrast, this `wp_finalized_template_enhancement_output_buffer` action is the possible point at which HTTP
     996         * headers can be sent. This action does not fire if the "template enhancement output buffer" was not started. This
     997         * output buffer is automatically started if this action is added before
     998         * {@see wp_start_template_enhancement_output_buffer()} runs at the {@see 'wp_before_include_template'} action with
     999         * priority 1000. Before this point, the output buffer will also be started automatically if there was a
    9941000         * {@see 'wp_template_enhancement_output_buffer'} filter added, or if the
    9951001         * {@see 'wp_should_output_buffer_template_for_enhancement'} filter is made to return `true`.
    9961002         *
     1003         * Important: Because this action fires inside an output buffer callback (i.e. display handler), any callbacks added
     1004         * to the action must not attempt to start their own output buffers. Otherwise, PHP will raise a fatal error:
     1005         * "Cannot use output buffering in output buffering display handlers."
     1006         *
    9971007         * @since 6.9.0
    9981008         *
    999          * @param string $output Output buffer.
     1009         * @param string $output Finalized output buffer.
    10001010         */
    1001         do_action( 'wp_send_late_headers', $filtered_output );
     1011        do_action( 'wp_finalized_template_enhancement_output_buffer', $filtered_output );
    10021012
    10031013        return $filtered_output;
  • trunk/tests/phpunit/tests/template.php

    r61088 r61111  
    647647                $mock_action_callback = new MockAction();
    648648                add_filter(
    649                         'wp_send_late_headers',
     649                        'wp_finalized_template_enhancement_output_buffer',
    650650                        array( $mock_action_callback, 'action' ),
    651651                        10,
    … …  
    734734                $this->assertStringContainsString( '</html>', $processed_output, 'Expected processed output to contain string.' );
    735735
    736                 $this->assertSame( 1, did_action( 'wp_send_late_headers' ), 'Expected the wp_send_late_headers action to have fired.' );
    737                 $this->assertSame( 1, $mock_action_callback->get_call_count(), 'Expected wp_send_late_headers action callback to have been called once.' );
     736                $this->assertSame( 1, did_action( 'wp_finalized_template_enhancement_output_buffer' ), 'Expected the wp_finalized_template_enhancement_output_buffer action to have fired.' );
     737                $this->assertSame( 1, $mock_action_callback->get_call_count(), 'Expected wp_finalized_template_enhancement_output_buffer action callback to have been called once.' );
    738738                $action_args = $mock_action_callback->get_args()[0];
    739                 $this->assertCount( 1, $action_args, 'Expected the wp_send_late_headers action to have been passed only one argument.' );
    740                 $this->assertSame( $processed_output, $action_args[0], 'Expected the arg passed to wp_send_late_headers to be the same as the processed output buffer.' );
     739                $this->assertCount( 1, $action_args, 'Expected the wp_finalized_template_enhancement_output_buffer action to have been passed only one argument.' );
     740                $this->assertSame( $processed_output, $action_args[0], 'Expected the arg passed to wp_finalized_template_enhancement_output_buffer to be the same as the processed output buffer.' );
    741741        }
    742742
    … …  
    773773                $mock_action_callback = new MockAction();
    774774                add_filter(
    775                         'wp_send_late_headers',
     775                        'wp_finalized_template_enhancement_output_buffer',
    776776                        array( $mock_action_callback, 'action' ),
    777777                        10,
    … …  
    819819                $this->assertStringContainsString( '<title>Output Buffer Not Processed</title>', $output, 'Expected output buffer to have string since the output buffer was ended with cleaning.' );
    820820
    821                 $this->assertSame( 0, did_action( 'wp_send_late_headers' ), 'Expected the wp_send_late_headers action to not have fired.' );
    822                 $this->assertSame( 0, $mock_action_callback->get_call_count(), 'Expected wp_send_late_headers action callback to have been called once.' );
     821                $this->assertSame( 0, did_action( 'wp_finalized_template_enhancement_output_buffer' ), 'Expected the wp_finalized_template_enhancement_output_buffer action to not have fired.' );
     822                $this->assertSame( 0, $mock_action_callback->get_call_count(), 'Expected wp_finalized_template_enhancement_output_buffer action callback to have been called once.' );
    823823        }
    824824
    … …  
    855855                $mock_action_callback = new MockAction();
    856856                add_filter(
    857                         'wp_send_late_headers',
     857                        'wp_finalized_template_enhancement_output_buffer',
    858858                        array( $mock_action_callback, 'action' ),
    859859                        10,
    … …  
    906906                $this->assertStringContainsString( '<h1>Template Replaced</h1>', $output, 'Expected output buffer to have string due to replaced template.' );
    907907
    908                 $this->assertSame( 1, did_action( 'wp_send_late_headers' ), 'Expected the wp_send_late_headers action to have fired.' );
    909                 $this->assertSame( 1, $mock_action_callback->get_call_count(), 'Expected wp_send_late_headers action callback to have been called once.' );
     908                $this->assertSame( 1, did_action( 'wp_finalized_template_enhancement_output_buffer' ), 'Expected the wp_finalized_template_enhancement_output_buffer action to have fired.' );
     909                $this->assertSame( 1, $mock_action_callback->get_call_count(), 'Expected wp_finalized_template_enhancement_output_buffer action callback to have been called once.' );
    910910                $action_args = $mock_action_callback->get_args()[0];
    911                 $this->assertCount( 1, $action_args, 'Expected the wp_send_late_headers action to have been passed only one argument.' );
    912                 $this->assertSame( $output, $action_args[0], 'Expected the arg passed to wp_send_late_headers to be the same as the processed output buffer.' );
     911                $this->assertCount( 1, $action_args, 'Expected the wp_finalized_template_enhancement_output_buffer action to have been passed only one argument.' );
     912                $this->assertSame( $output, $action_args[0], 'Expected the arg passed to wp_finalized_template_enhancement_output_buffer to be the same as the processed output buffer.' );
    913913        }
    914914
    … …  
    931931                $mock_action_callback = new MockAction();
    932932                add_filter(
    933                         'wp_send_late_headers',
     933                        'wp_finalized_template_enhancement_output_buffer',
    934934                        array( $mock_action_callback, 'action' ),
    935935                        10,
    … …  
    971971                $this->assertSame( $json, $output, 'Expected output to not be processed.' );
    972972
    973                 $this->assertSame( 1, did_action( 'wp_send_late_headers' ), 'Expected the wp_send_late_headers action to have fired even though the wp_template_enhancement_output_buffer filter did not apply.' );
    974                 $this->assertSame( 1, $mock_action_callback->get_call_count(), 'Expected wp_send_late_headers action callback to have been called once.' );
     973                $this->assertSame( 1, did_action( 'wp_finalized_template_enhancement_output_buffer' ), 'Expected the wp_finalized_template_enhancement_output_buffer action to have fired even though the wp_template_enhancement_output_buffer filter did not apply.' );
     974                $this->assertSame( 1, $mock_action_callback->get_call_count(), 'Expected wp_finalized_template_enhancement_output_buffer action callback to have been called once.' );
    975975                $action_args = $mock_action_callback->get_args()[0];
    976                 $this->assertCount( 1, $action_args, 'Expected the wp_send_late_headers action to have been passed only one argument.' );
    977                 $this->assertSame( $output, $action_args[0], 'Expected the arg passed to wp_send_late_headers to be the same as the processed output buffer.' );
     976                $this->assertCount( 1, $action_args, 'Expected the wp_finalized_template_enhancement_output_buffer action to have been passed only one argument.' );
     977                $this->assertSame( $output, $action_args[0], 'Expected the arg passed to wp_finalized_template_enhancement_output_buffer to be the same as the processed output buffer.' );
    978978        }
    979979
Note: See TracChangeset for help on using the changeset viewer.