diff --git a/inc/Engine/Common/PerformanceHints/Activation/ServiceProvider.php b/inc/Engine/Common/PerformanceHints/Activation/ServiceProvider.php index 03a2e10c4d..be31a91dba 100644 --- a/inc/Engine/Common/PerformanceHints/Activation/ServiceProvider.php +++ b/inc/Engine/Common/PerformanceHints/Activation/ServiceProvider.php @@ -9,6 +9,7 @@ use WP_Rocket\Engine\Media\AboveTheFold\Activation\ActivationFactory as ATFActivationFactory; use WP_Rocket\Engine\Optimization\LazyRenderContent\Activation\ActivationFactory as LRCActivationFactory; use WP_Rocket\Engine\Optimization\LazyRenderContent\Context\Context as LRCContext; +use WP_Rocket\Engine\Media\PreconnectExternalDomains\Context\Context as PreconnectContext; class ServiceProvider extends AbstractServiceProvider { /** @@ -30,6 +31,7 @@ class ServiceProvider extends AbstractServiceProvider { 'atf_activation_factory', 'lrc_context', 'lrc_activation_factory', + 'preconnect_external_domains_context', ]; /** @@ -68,6 +70,8 @@ public function register(): void { ] ); + $this->getContainer()->add( 'preconnect_external_domains_context', PreconnectContext::class ); + $factories = []; $atf_activation_factory = $this->getContainer()->get( 'atf_activation_factory' ); diff --git a/inc/Engine/Common/PerformanceHints/Cron/CronTrait.php b/inc/Engine/Common/PerformanceHints/Cron/CronTrait.php new file mode 100644 index 0000000000..7b65669070 --- /dev/null +++ b/inc/Engine/Common/PerformanceHints/Cron/CronTrait.php @@ -0,0 +1,28 @@ +queries; + } + + return $this->queries->set_cleanup_interval( $delete_interval ); + } +} diff --git a/inc/Engine/Common/PerformanceHints/ServiceProvider.php b/inc/Engine/Common/PerformanceHints/ServiceProvider.php index 0a74c07e63..dafa41f193 100644 --- a/inc/Engine/Common/PerformanceHints/ServiceProvider.php +++ b/inc/Engine/Common/PerformanceHints/ServiceProvider.php @@ -75,6 +75,7 @@ public function register(): void { $factory_array = [ $this->getContainer()->get( 'atf_factory' ), $this->getContainer()->get( 'lrc_factory' ), + $this->getContainer()->get( 'preconnect_external_domains_factory' ), ]; foreach ( $factory_array as $factory ) { diff --git a/inc/Engine/Media/PreconnectExternalDomains/Factory.php b/inc/Engine/Media/PreconnectExternalDomains/Factory.php new file mode 100644 index 0000000000..f76eeeceee --- /dev/null +++ b/inc/Engine/Media/PreconnectExternalDomains/Factory.php @@ -0,0 +1,120 @@ +context = $context; + $this->queries = $queries; + $this->table = $table; + $this->ajax_controller = $ajax_controller; + $this->frontend_controller = $frontend_controller; + } + + /** + * Provides an Ajax controller object. + * + * @return AjaxControllerInterface + */ + public function get_ajax_controller(): AjaxControllerInterface { + return $this->ajax_controller; + } + + /** + * Provides a Frontend controller object. + * + * @return FrontendControllerInterface + */ + public function get_frontend_controller(): FrontendControllerInterface { + return $this->frontend_controller; + } + + /** + * Provides a Table interface object. + * + * @return TableInterface + */ + public function table(): TableInterface { + return $this->table; + } + + /** + * Provides a Queries object. + * + * @return QueriesInterface + */ + public function queries(): QueriesInterface { + // Defines the interval for deletion and returns Queries object. + return $this->deletion_interval( 'rocket_preconnect_external_domains_cleanup_interval' ); + } + + /** + * Provides Context object. + * + * @return ContextInterface + */ + public function get_context(): ContextInterface { + return $this->context; + } +} diff --git a/inc/Engine/Media/PreconnectExternalDomains/Frontend/Controller.php b/inc/Engine/Media/PreconnectExternalDomains/Frontend/Controller.php new file mode 100644 index 0000000000..ef1fb71653 --- /dev/null +++ b/inc/Engine/Media/PreconnectExternalDomains/Frontend/Controller.php @@ -0,0 +1,71 @@ +options = $options; + $this->query = $query; + $this->context = $context; + } + + /** + * Applies preconnect domains optimization. + * + * @param string $html HTML content. + * @param object $row Database row. + * @return string + */ + public function optimize( string $html, $row ): string { + if ( ! $row->has_preconnect_external_domains() ) { + return $html; + } + + return $html; + } + + /** + * 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 { + return $data; + } +} diff --git a/inc/Engine/Media/PreconnectExternalDomains/ServiceProvider.php b/inc/Engine/Media/PreconnectExternalDomains/ServiceProvider.php index 5c017f72cd..d0c3f5e54b 100644 --- a/inc/Engine/Media/PreconnectExternalDomains/ServiceProvider.php +++ b/inc/Engine/Media/PreconnectExternalDomains/ServiceProvider.php @@ -8,7 +8,7 @@ use WP_Rocket\Engine\Media\PreconnectExternalDomains\Database\Queries\PreconnectExternalDomains as Query; use WP_Rocket\Engine\Media\PreconnectExternalDomains\AJAX\Controller as AJAXController; use WP_Rocket\Engine\Media\PreconnectExternalDomains\Database\Table\PreconnectExternalDomains as PreconnectTable; -use WP_Rocket\Engine\Media\PreconnectExternalDomains\Frontend\Subscriber as FrontendSubscriber; +use WP_Rocket\Engine\Media\PreconnectExternalDomains\Frontend\{Controller as FrontController, Subscriber as FrontendSubscriber}; class ServiceProvider extends AbstractServiceProvider { /** @@ -26,6 +26,8 @@ class ServiceProvider extends AbstractServiceProvider { 'preconnect_external_domains_ajax_controller', 'preconnect_frontend_subscriber', 'preconnect_external_domains_table', + 'preconnect_external_domains_factory', + 'preconnect_external_domains_controller', ]; /** @@ -65,5 +67,25 @@ public function register(): void { ); $this->getContainer()->addShared( 'preconnect_frontend_subscriber', FrontendSubscriber::class ); + + $this->getContainer()->add( 'preconnect_external_domains_controller', FrontController::class ) + ->addArguments( + [ + $this->getContainer()->get( 'options' ), + $this->getContainer()->get( 'preconnect_external_domains_query' ), + $this->getContainer()->get( 'preconnect_external_domains_context' ), + ] + ); + + $this->getContainer()->addShared( 'preconnect_external_domains_factory', Factory::class ) + ->addArguments( + [ + $this->getContainer()->get( 'preconnect_external_domains_query' ), + $this->getContainer()->get( 'preconnect_external_domains_context' ), + $this->getContainer()->get( 'preconnect_external_domains_ajax_controller' ), + $this->getContainer()->get( 'preconnect_external_domains_table' ), + $this->getContainer()->get( 'preconnect_external_domains_controller' ), + ] + ); } } diff --git a/tests/Fixtures/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php b/tests/Fixtures/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php index 05c71f65b5..beb2e2f9ac 100644 --- a/tests/Fixtures/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php +++ b/tests/Fixtures/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php @@ -33,6 +33,17 @@ ], ]; +$preconnect_external_domains = [ + 'row' => [ + 'status' => 'completed', + 'url' => 'http://example.org', + 'domains' => json_encode( [ + 'http://example-domain.org', + 'http://example-domain.com', + ] ), + ], +]; + return [ 'test_data' => [ 'shouldReturnOriginalWhenBypassAndRow' => [ @@ -56,6 +67,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => $html_input, ], @@ -69,6 +81,9 @@ 'lrc' => [ 'row' => null, ], + 'preload_external_domains' => [ + 'row' => null + ], ], 'expected' => $html_input, ], @@ -83,6 +98,9 @@ 'lrc' => [ 'row' => null, ], + 'preload_external_domains' => [ + 'row' => null + ], ], 'expected' => $html_input, ], @@ -97,6 +115,9 @@ 'lrc' => [ 'row' => null, ], + 'preload_external_domains' => [ + 'row' => null + ], ], 'expected' => $html_output_with_beacon, ], @@ -109,6 +130,9 @@ 'lrc' => [ 'row' => null, ], + 'preload_external_domains' => [ + 'row' => null + ], ], 'expected' => $html_output_with_beacon, ], @@ -122,6 +146,9 @@ 'lrc' => [ 'row' => null, ], + 'preload_external_domains' => [ + 'row' => null + ], ], 'expected' => $html_output_with_beacon, ], @@ -145,6 +172,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => $html_output_with_preload, ], @@ -153,6 +181,7 @@ 'html' => $html_input, 'atf' => [], 'lrc' => [], + 'preload_external_domains' => [], 'is_logged_in' => true, 'user_cache_enabled' => 1, ], @@ -170,6 +199,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => $html_output, ], @@ -191,6 +221,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_bg_responsive_imgset_template.php'), ], @@ -212,6 +243,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_bg_responsive_webkit_template.php'), ], @@ -233,6 +265,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_layered_bg.php'), ], @@ -253,6 +286,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_single_bg.php'), ], @@ -273,6 +307,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_responsive.php'), ], @@ -291,6 +326,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_with_relative_img_lcp.php'), ], @@ -309,6 +345,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_with_absolute_img_lcp.php'), ], @@ -327,6 +364,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_image.php'), ], @@ -345,6 +383,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_with_fetchpriority.html'), ], @@ -363,6 +402,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_with_markup_comment.html'), ], @@ -389,7 +429,8 @@ ] ), ], ], - 'lrc' =>$lrc, + 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => $html_output_with_bg_image_lcp, ], @@ -417,6 +458,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => $html_output_with_picture_img_lcp, ], @@ -444,6 +486,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => $html_output_with_img_lcp, ], @@ -460,6 +503,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => $html_output, ], @@ -492,6 +536,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_picture.php'), ], @@ -524,6 +569,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_picture_2.php'), ], @@ -556,6 +602,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_picture_3.php'), ], @@ -586,6 +633,7 @@ ], ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => file_get_contents(__DIR__ . '/HTML/output_lcp_picture_4.php'), ], @@ -606,6 +654,9 @@ 'lrc' => [ 'row' => null, ], + 'preload_external_domains' => [ + 'row' => null + ], ], 'expected' => $html_output_with_beacon_and_lcp_opt, ], @@ -616,6 +667,7 @@ 'row' => null, ], 'lrc' => $lrc, + 'preload_external_domains' => $preconnect_external_domains, ], 'expected' => $html_output_with_beacon_and_only_lrc_opt, ], @@ -640,6 +692,9 @@ 'lrc' => [ 'row' => null, ], + 'preload_external_domains' => [ + 'row' => null + ], ], 'expected' => $html_input_without_closing_body_tag_output, ], diff --git a/tests/Fixtures/inc/Engine/Media/PreconnectExternalDomains/Database/Rows/hasPreconnectExternalDomains.php b/tests/Fixtures/inc/Engine/Media/PreconnectExternalDomains/Database/Rows/hasPreconnectExternalDomains.php new file mode 100644 index 0000000000..861a2d04fb --- /dev/null +++ b/tests/Fixtures/inc/Engine/Media/PreconnectExternalDomains/Database/Rows/hasPreconnectExternalDomains.php @@ -0,0 +1,32 @@ + [ + 'config' => [ + 'status' => 'in-progress', + 'domains' => '["http://example.org", "http://example.com"]', + ], + 'expected' => false, + ], + 'shouldReturnFalseWhenDomainsIsEmpty' => [ + 'config' => [ + 'status' => 'completed', + 'domains' => '', + ], + 'expected' => false, + ], + 'shouldReturnFalseWhenDomainsIsEmptyArray' => [ + 'config' => [ + 'status' => 'completed', + 'domains' => '[]', + ], + 'expected' => false, + ], + 'shouldReturnTrueWhenStatusIsCompletedAndDomainsIsNotEmpty' => [ + 'config' => [ + 'status' => 'completed', + 'domains' => '["http://example.org", "http://example.com"]', + ], + 'expected' => true, + ], +]; diff --git a/tests/Integration/bootstrap.php b/tests/Integration/bootstrap.php index c0a5d5515e..baacca49e8 100644 --- a/tests/Integration/bootstrap.php +++ b/tests/Integration/bootstrap.php @@ -17,7 +17,7 @@ 'muplugins_loaded', function () { - // Disable ATF & LRC optimizations to prevent DB requests (unrelated to other tests). + // Disable ATF, LRC & Preconnect external domains optimizations to prevent DB requests (unrelated to other tests). add_filter( 'rocket_above_the_fold_optimization', '__return_false' ); add_filter( 'rocket_lrc_optimization', '__return_false' ); add_filter( 'rocket_preconnect_external_domains_optimization', '__return_false' ); diff --git a/tests/Integration/inc/Engine/Common/PerformanceHints/Admin/Controller/truncateFromAdmin.php b/tests/Integration/inc/Engine/Common/PerformanceHints/Admin/Controller/truncateFromAdmin.php index 4844d66e79..609a372060 100644 --- a/tests/Integration/inc/Engine/Common/PerformanceHints/Admin/Controller/truncateFromAdmin.php +++ b/tests/Integration/inc/Engine/Common/PerformanceHints/Admin/Controller/truncateFromAdmin.php @@ -22,11 +22,13 @@ public static function set_up_before_class() { // Install in set_up_before_class because of exists() requiring not temporary table. self::installAtfTable(); self::installLrcTable(); + self::installPreconnectExternalDomainsTable(); } public static function tear_down_after_class() { self::uninstallAtfTable(); self::uninstallLrcTable(); + self::uninstallPreconnectDomainsTable(); parent::tear_down_after_class(); } diff --git a/tests/Integration/inc/Engine/Common/PerformanceHints/Cron/Subscriber/cleanup.php b/tests/Integration/inc/Engine/Common/PerformanceHints/Cron/Subscriber/cleanup.php index 27b103d82a..7808761853 100644 --- a/tests/Integration/inc/Engine/Common/PerformanceHints/Cron/Subscriber/cleanup.php +++ b/tests/Integration/inc/Engine/Common/PerformanceHints/Cron/Subscriber/cleanup.php @@ -24,11 +24,13 @@ public static function set_up_before_class() { // Install in set_up_before_class because of exists(). self::installAtfTable(); self::installLrcTable(); + self::installPreconnectExternalDomainsTable(); } public static function tear_down_after_class() { self::uninstallAtfTable(); self::uninstallLrcTable(); + self::uninstallPreconnectDomainsTable(); parent::tear_down_after_class(); } diff --git a/tests/Integration/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php b/tests/Integration/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php index 882b5bb8ff..dca7bab07b 100644 --- a/tests/Integration/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php +++ b/tests/Integration/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php @@ -10,7 +10,7 @@ * * @group PerformanceHints */ -class Test_MaybeApplyOptimizations extends FilesystemTestCase { +class Test_Maybe_Apply_Optimizations extends FilesystemTestCase { protected $path_to_test_data = '/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php'; protected $config; private $cached_user = false; @@ -22,11 +22,13 @@ public static function set_up_before_class() { // Install in set_up_before_class because of exists(). self::installAtfTable(); self::installLrcTable(); + self::installPreconnectExternalDomainsTable(); } public static function tear_down_after_class() { self::uninstallAtfTable(); self::uninstallLrcTable(); + self::uninstallPreconnectDomainsTable(); parent::tear_down_after_class(); } @@ -76,6 +78,10 @@ public function testShouldReturnAsExpected( $config, $expected ) { self::addLrc( $config['lrc']['row'] ); } + if ( ! empty( $config['preload_external_domains']['row'] ) ) { + self::addPreconnectExternalDomains( $config['preload_external_domains']['row'] ); + } + if ( isset( $config['filter_delay'] ) ) { add_filter( 'rocket_performance_hints_optimization_delay', [ $this, 'add_delay' ] ); } diff --git a/tests/Integration/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/start_performance_hints_buffer.php b/tests/Integration/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/start_performance_hints_buffer.php index dd0f9c17c5..bdcae8839b 100644 --- a/tests/Integration/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/start_performance_hints_buffer.php +++ b/tests/Integration/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/start_performance_hints_buffer.php @@ -16,11 +16,13 @@ public static function set_up_before_class() { // Install in set_up_before_class because of exists(). self::installAtfTable(); self::installLrcTable(); + self::installPreconnectExternalDomainsTable(); } public static function tear_down_after_class() { self::uninstallAtfTable(); self::uninstallLrcTable(); + self::uninstallPreconnectDomainsTable(); parent::tear_down_after_class(); } diff --git a/tests/Integration/inc/Engine/Support/Data/getSupportData.php b/tests/Integration/inc/Engine/Support/Data/getSupportData.php index c97d505485..691ebe6295 100644 --- a/tests/Integration/inc/Engine/Support/Data/getSupportData.php +++ b/tests/Integration/inc/Engine/Support/Data/getSupportData.php @@ -21,6 +21,7 @@ public function set_up() { add_filter( 'rocket_above_the_fold_optimization', '__return_true' ); add_filter( 'rocket_lrc_optimization', '__return_true' ); + add_filter( 'rocket_preconnect_external_domains_optimization', '__return_true' ); $this->wp_version = $wp_version; } @@ -30,6 +31,7 @@ public function tear_down() { remove_filter( 'rocket_above_the_fold_optimization', '__return_true' ); remove_filter( 'rocket_lrc_optimization', '__return_true' ); + remove_filter( 'rocket_preconnect_external_domains_optimization', '__return_true' ); $wp_version = $this->wp_version; diff --git a/tests/Unit/inc/Engine/Media/PreconnectExternalDomains/Database/Rows/hasPreconnectExternalDomains.php b/tests/Unit/inc/Engine/Media/PreconnectExternalDomains/Database/Rows/hasPreconnectExternalDomains.php new file mode 100644 index 0000000000..1788907dcc --- /dev/null +++ b/tests/Unit/inc/Engine/Media/PreconnectExternalDomains/Database/Rows/hasPreconnectExternalDomains.php @@ -0,0 +1,22 @@ +assertSame( $expected, $preconnect_external_domains->has_preconnect_external_domains() ); + } +}