-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ensure the entire template is passed to the output buffer callback for Optimization Detective to process #1317
Changes from 7 commits
b3ce59e
13e068d
523fc7a
3235f3b
15ca2f0
78967f5
f218dc8
0b4f2cd
2c6ec0c
35085e8
364fa43
1b62c1a
26e859d
21ebb97
8cbcbd6
85e9c2b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,8 +31,35 @@ | |
* @return string Unmodified value of $passthrough. | ||
*/ | ||
function od_buffer_output( string $passthrough ): string { | ||
/* | ||
* Instead of the default PHP_OUTPUT_HANDLER_STDFLAGS (cleanable, flushable, and removable) being used for flags, | ||
* we need to omit PHP_OUTPUT_HANDLER_FLUSHABLE. If the buffer were flushable, then each time that ob_flush() is | ||
* called, it would send a fragment of the output into the output buffer callback. When buffering the entire | ||
* response as an HTML document, this would result in broken HTML processing. | ||
* | ||
* If this ends up being problematic, then PHP_OUTPUT_HANDLER_FLUSHABLE could be added to the $flags and the | ||
* output buffer callback could check if the phase is PHP_OUTPUT_HANDLER_FLUSH and abort any subsequent | ||
* processing while also emitting a _doing_it_wrong(). | ||
*/ | ||
$flags = PHP_OUTPUT_HANDLER_CLEANABLE; | ||
|
||
// When running unit tests the output buffer must also be removable in order to obtain the buffered output. | ||
if ( php_sapi_name() === 'cli' ) { | ||
// TODO: Do any caching plugins need the output buffer to be removable? This is unlikely, as they would pass an output buffer callback to ob_start() instead of calling ob_get_clean() at shutdown. | ||
$flags |= PHP_OUTPUT_HANDLER_REMOVABLE; | ||
} | ||
|
||
ob_start( | ||
static function ( string $output ): string { | ||
static function ( string $output, ?int $phase ): string { | ||
// When the output is being cleaned (e.g. pending template is replaced with error page), do not send it through the filter. | ||
if ( ( $phase & PHP_OUTPUT_HANDLER_CLEAN ) !== 0 ) { | ||
return $output; | ||
} | ||
|
||
// Since ob_start() was called without PHP_OUTPUT_HANDLER_FLUSHABLE, at this point the phase should never be flush, and it should always be final. | ||
assert( ( $phase & ( PHP_OUTPUT_HANDLER_FLUSH ) ) === 0 ); | ||
assert( ( $phase & ( PHP_OUTPUT_HANDLER_FINAL ) ) !== 0 ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure about using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are sanity checks that should not ever return false given the flags. There are instances of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, but not in WordPress itself, and I don't know how relevant the presence of these flags is in said code, e.g. whether the code paths are even reached. If they should never return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. Removed in 364fa43. |
||
|
||
/** | ||
* Filters the template output buffer prior to sending to the client. | ||
* | ||
|
@@ -42,7 +69,9 @@ static function ( string $output ): string { | |
* @return string Filtered output buffer. | ||
*/ | ||
return (string) apply_filters( 'od_template_output_buffer', $output ); | ||
} | ||
}, | ||
0, // Unlimited buffer size. | ||
$flags | ||
); | ||
return $passthrough; | ||
} | ||
|
@@ -139,7 +168,7 @@ function od_is_response_html_content_type(): bool { | |
* @return string Filtered template output buffer. | ||
*/ | ||
function od_optimize_template_output_buffer( string $buffer ): string { | ||
if ( ! od_is_response_html_content_type() ) { | ||
if ( ! od_is_response_html_content_type() ) { // TODO: This should check to see if there is an HTML tag. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I'm opening a sub-PR for this. It's unrelated to output buffering. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #1442 |
||
return $buffer; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually does need to be removable because WordPress core calls
wp_ob_end_flush_all()
atshutdown
, and the lack ofPHP_OUTPUT_HANDLER_REMOVABLE
results in:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 0b4f2cd