<?php
declare(strict_types=1);
namespace WP_Rocket\Engine\Optimization\LazyRenderContent\Frontend;
use WP_Rocket\Engine\Common\Context\ContextInterface;
use WP_Rocket\Engine\Common\PerformanceHints\Frontend\ControllerInterface;
use WP_Rocket\Engine\Optimization\LazyRenderContent\Frontend\Processor\Processor;
use WP_Rocket\Engine\Support\CommentTrait;
class Controller implements ControllerInterface {
use CommentTrait;
/**
* Processor instance
*
* @var Processor
*/
private $processor;
/**
* Context instance
*
* @var ContextInterface
*/
private $context;
/**
* Constructor
*
* @param Processor $processor Processor instance.
* @param ContextInterface $context Context instance.
*/
public function __construct( Processor $processor, ContextInterface $context ) {
$this->processor = $processor;
$this->context = $context;
}
/**
* Applies optimization.
*
* @param string $html HTML content.
* @param object $row Database Row.
*
* @return string
*/
public function optimize( string $html, $row ): string {
if ( rocket_bypass() && $row->has_lrc() ) {
return $this->remove_hashes( $html );
}
if ( ! $row->has_lrc() ) {
return $this->remove_hashes( $html );
}
$hashes = json_decode( $row->below_the_fold );
if ( ! is_array( $hashes ) ) {
return $this->remove_hashes( $html );
}
$result = preg_replace( '/data-rocket-location-hash="(?:' . implode( '|', $hashes ) . ')"/i', 'data-wpr-lazyrender="1"', $html, -1, $count );
if (
null === $result
||
0 === $count
) {
return $this->remove_hashes( $html );
}
$html = $result;
$html = $this->remove_hashes( $html );
$html = $this->add_css( $html );
return $this->add_meta_comment( 'automatic_lazy_rendering', $html );
}
/**
* Remove hashes from the HTML content.
*
* @param string $html The HTML content.
*
* @return string
*/
private function remove_hashes( $html ) {
$result = preg_replace( '/data-rocket-location-hash="[^"]*"/i', '', $html );
if ( null === $result ) {
return $html;
}
return $result;
}
/**
* Add CSS to the HTML content.
*
* @param string $html The HTML content.
*
* @return string
*/
private function add_css( $html ) {
$css = '<style id="rocket-lazyrender-inline-css">[data-wpr-lazyrender] {content-visibility: auto;}</style>';
$result = preg_replace( '/<\/head>/i', $css . '</head>', $html, 1 );
if ( null === $result ) {
return $html;
}
return $result;
}
/**
* Add hashes to the HTML elements if allowed
*
* @param string $html The HTML content.
*
* @return string
*/
public function add_hashes_when_allowed( $html ) {
if ( ! $this->context->is_allowed() ) {
return $html;
}
return $this->add_hashes( $html );
}
/**
* Add hashes to the HTML elements
*
* @param string $html The HTML content.
*
* @return string
*/
public function add_hashes( $html ) {
if ( empty( $html ) ) {
return $html;
}
/**
* Filters the Lazy Render Content processor to use.
*
* @since 3.17
*
* @param string $processor The processor to use.
*/
$processor = wpm_apply_filters_typed( 'string', 'rocket_lrc_processor', extension_loaded( 'dom' ) ? 'dom' : 'regex' );
$this->processor->set_processor( $processor );
$this->processor->get_processor()->set_exclusions( $this->get_exclusions() );
return $this->processor->get_processor()->add_hashes( $html );
}
/**
* Get the list of patterns to exclude from hash injection.
*
* @return string[]
*/
private function get_exclusions(): array {
/**
* Filters the list of patterns to exclude from hash injection.
*
* @since 3.17.0.2
*
* @param string[] $exclusions The list of patterns to exclude from hash injection.
*/
$exclusions = wpm_apply_filters_typed( 'string[]', 'rocket_lrc_exclusions', [] );
return $exclusions;
}
/**
* Add custom data like the List of elements to be considered for optimization.
*
* @param array $data Array of data passed in beacon.
*
* @return array
*/
public function add_custom_data( array $data ): array {
$data['status']['lrc'] = $this->context->is_allowed();
/**
* Filters the LRC threshold
*
* @since 3.17
*
* @param int $threshold The LRC threshold value.
*/
$data['lrc_threshold'] = wpm_apply_filters_typed( 'integer', 'rocket_lrc_threshold', 1800 );
return $data;
}
}