BoldGrid / w3-total-cache

GNU General Public License v2.0
152 stars 85 forks source link

Cannot update content in w3tc_processed_content filter #758

Closed nkonstas closed 8 months ago

nkonstas commented 1 year ago

Hello,

This seems like a bug to me but I could be wrong.

I'm trying to modify the final html for all pages to optimise the css handling for lighthouse. Based on the code in Generic_Plugin:522 (below) my assumption is that I can modify the $buffer in my filter function (in functions.php) and that would be the 'final' cached page.

However, in practice although my handler is called and I correctly modify the $buffer (I trace it out in debug.log), what the browser gets is the unmodified copy.

This seems like a bug to me? Is there anything I can do (maybe force a cache invalidation?) to get the page to use my changes?

Thank you!

$buffer = Util_Bus::do_ob_callbacks(
array(
    'swarmify',
    'lazyload',
    'minify',
    'newrelic',
    'cdn',
    'browsercache',
    'pagecache',
),
$buffer
);

$buffer = apply_filters( 'w3tc_processed_content', $buffer );
nkonstas commented 1 year ago

For anyone interested, this will fix the issue although changing w3t code means an update will override it:

Generic_Plugin:522

$buffer = Util_Bus::do_ob_callbacks(
array(
    'swarmify',
    'lazyload',
    'minify',
    'newrelic',
    'cdn',
    'browsercache',
),
$buffer
);

$buffer = apply_filters( 'w3tc_processed_content', $buffer );

$buffer = Util_Bus::do_ob_callbacks(
array(
    'pagecache',
),
$buffer
);
superpoincare commented 11 months ago

Yeah, something should be done there by W3TC authors.

Meanwhile here is a trick I learned in a plugin which doesn't exist any longer named (Above The Fold Optimization):

class W3TC_Util_Bus_Modifier {
    private $pagecache_callback;

    public function __construct() {
        if ( isset( $GLOBALS['_w3tc_ob_callbacks']['pagecache'] ) ) {
            $this->pagecache_callback = $GLOBALS['_w3tc_ob_callbacks']['pagecache'];
        }

        $GLOBALS['_w3tc_ob_callbacks']['pagecache'] = [
            $this,
            'ob_callback',
        ];
    }

    public function ob_callback( $buffer ) {
        $buffer = apply_filters( 'w3tc_processed_content_pre', $buffer );

        if ( is_callable( $this->pagecache_callback ) ) {
            $buffer = call_user_func( $this->pagecache_callback, $buffer );
        }

        return $buffer;
    }
}

class_exists( 'W3TC\Util_Bus' ) && new W3TC_Util_Bus_Modifier;

What it does is intercepts the Util_Bus by redefining pagecache, adding additional code to a newly defined thing which also includes pagecache and then lets W3TC execute this newly defined thing instead.