diff --git a/inc/Engine/Media/PreloadFonts/AJAX/Controller.php b/inc/Engine/Media/PreloadFonts/AJAX/Controller.php new file mode 100644 index 0000000000..2eeeda7aff --- /dev/null +++ b/inc/Engine/Media/PreloadFonts/AJAX/Controller.php @@ -0,0 +1,161 @@ +query = $query; + $this->context = $context; + } + + + /** + * Add Preload fonts data to the database + * + * @return array + */ + public function add_data(): array { + check_ajax_referer( 'rocket_beacon', 'rocket_beacon_nonce' ); + $payload = []; + + if ( ! $this->context->is_allowed() ) { + $payload['preload_fonts'] = 'not allowed'; + + return $payload; + } + + $url = isset( $_POST['url'] ) ? untrailingslashit( esc_url_raw( wp_unslash( $_POST['url'] ) ) ) : ''; + $is_mobile = isset( $_POST['is_mobile'] ) ? filter_var( wp_unslash( $_POST['is_mobile'] ), FILTER_VALIDATE_BOOLEAN ) : false; + $results = isset( $_POST['results'] ) ? json_decode( wp_unslash( $_POST['results'] ) ) : (object) [ 'preload_fonts' => [] ]; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $fonts = $results->preload_fonts ?? []; + + $preload_fonts = []; + + /** + * Filters the maximum number of fonts being saved into the database. + * + * @param int $max_number Maximum number to allow. + * @param string $url Current page url. + * @param string[]|array $hashes Current list of preload fonts. + */ + $max_preload_fonts_number = wpm_apply_filters_typed( 'integer', 'rocket_preload_fonts_number', 20, $url, $fonts ); + if ( 0 >= $max_preload_fonts_number ) { + $max_preload_fonts_number = 1; + } + + foreach ( (array) $fonts as $index => $font ) { + $preload_fonts[ $index ] = sanitize_text_field( wp_unslash( $font ) ); + --$max_preload_fonts_number; + } + + $row = $this->query->get_row( $url, $is_mobile ); + if ( ! empty( $row ) ) { + $payload['preload_fonts'] = 'item already in the database'; + + return $payload; + } + + $status = isset( $_POST['status'] ) ? sanitize_text_field( wp_unslash( $_POST['status'] ) ) : ''; + list( $status_code, $status_message ) = $this->get_status_code_message( $status ); + + $item = [ + 'url' => $url, + 'is_mobile' => $is_mobile, + 'status' => $status_code, + 'error_message' => $status_message, + 'fonts' => wp_json_encode( $preload_fonts ), + 'created_at' => current_time( 'mysql', true ), + 'last_accessed' => current_time( 'mysql', true ), + ]; + + $result = $this->query->add_item( $item ); + + if ( ! $result ) { + $payload['preload_fonts'] = 'error when adding the entry to the database'; + + return $payload; + } + + $payload['preload_fonts'] = $item; + + return $payload; + } + + /** + * Checks if there is existing data for the current URL and device type from the beacon script. + * + * This method is called via AJAX. It checks if there is existing fonts data for the current URL and device type. + * If the data exists, it returns a JSON success response with true. If the data does not exist, it returns a JSON success response with false. + * If the context is not allowed, it returns a JSON error response with false. + * + * @return array + */ + public function check_data(): array { + $payload = [ + 'preload_fonts' => false, + ]; + + check_ajax_referer( 'rocket_beacon', 'rocket_beacon_nonce' ); + + if ( ! $this->context->is_allowed() ) { + $payload['preload_fonts'] = true; + + return $payload; + } + + $is_mobile = isset( $_POST['is_mobile'] ) ? filter_var( wp_unslash( $_POST['is_mobile'] ), FILTER_VALIDATE_BOOLEAN ) : false; + $url = isset( $_POST['url'] ) ? untrailingslashit( esc_url_raw( wp_unslash( $_POST['url'] ) ) ) : ''; + + $row = $this->query->get_row( $url, $is_mobile ); + + if ( ! empty( $row ) ) { + $payload['preload_fonts'] = true; + } + + return $payload; + } + + /** + * Preload Fonts Deletion interval filter. + * + * @return int + */ + public static function deletion_interval(): int { + /** + * Filters the interval (in months) to determine when a Preload Fonts entry is considered 'old'. + * Old PLF entries are eligible for deletion. By default, a PLF entry is considered old if it hasn't been accessed in the last month. + * + * @param int $delete_interval The interval in months after which a preload fonts entry is considered old. Default is 1 month. + */ + return wpm_apply_filters_typed( 'integer', 'rocket_preload_fonts_cleanup_interval', 1 ); + } +} diff --git a/inc/Engine/Media/PreloadFonts/Context/Context.php b/inc/Engine/Media/PreloadFonts/Context/Context.php new file mode 100644 index 0000000000..951c013119 --- /dev/null +++ b/inc/Engine/Media/PreloadFonts/Context/Context.php @@ -0,0 +1,44 @@ +options = $options; + } + + /** + * Determine if the action is allowed. + * + * @param array $data Data to pass to the context. + * @return bool + */ + public function is_allowed( array $data = [] ): bool { + if ( $this->options->get( 'wp_rocket_no_licence' ) ) { + return false; + } + + /** + * Filters to manage preload fonts + * + * @param bool $allow True to allow, false otherwise. + */ + return wpm_apply_filters_typed( 'boolean', 'rocket_preload_fonts', true ); + } +} diff --git a/inc/Engine/Media/PreloadFonts/Database/Queries/PreloadFonts.php b/inc/Engine/Media/PreloadFonts/Database/Queries/PreloadFonts.php new file mode 100644 index 0000000000..72638eb27c --- /dev/null +++ b/inc/Engine/Media/PreloadFonts/Database/Queries/PreloadFonts.php @@ -0,0 +1,96 @@ +get_db(); + + // Early bailout if no database interface is available. + if ( ! $db ) { + return false; + } + + $delete_interval = Controller::deletion_interval(); + + if ( $delete_interval <= 0 ) { + return false; + } + + $prefixed_table_name = $db->prefix . $this->table_name; + $query = "DELETE FROM `$prefixed_table_name` WHERE status = 'failed' OR `last_accessed` <= date_sub(now(), interval $delete_interval month)"; + + return $db->query( $query ); + } +} diff --git a/inc/Engine/Media/PreloadFonts/Database/Rows/PreloadFonts.php b/inc/Engine/Media/PreloadFonts/Database/Rows/PreloadFonts.php new file mode 100644 index 0000000000..dd552abe5f --- /dev/null +++ b/inc/Engine/Media/PreloadFonts/Database/Rows/PreloadFonts.php @@ -0,0 +1,111 @@ +id = (int) $this->id; + $this->url = (string) $this->url; + $this->is_mobile = (bool) $this->is_mobile; + $this->fonts = (string) $this->fonts; + $this->status = (string) $this->status; + $this->error_message = (string) $this->error_message; + $this->modified = empty( $this->modified ) ? 0 : strtotime( (string) $this->modified ); + $this->last_accessed = empty( $this->last_accessed ) ? 0 : strtotime( (string) $this->last_accessed ); + $this->created_at = empty( $this->created_at ) ? 0 : strtotime( (string) $this->created_at ); + } + + /** + * Checks if the object has a valid Preload Fonts value. + * + * @return bool Returns true if the object's status is 'completed' and the fonts value is not empty or '[]', false otherwise. + */ + public function has_preload_fonts() { + if ( 'completed' !== $this->status ) { + return false; + } + + if ( empty( $this->fonts ) ) { + return false; + } + + if ( '[]' === $this->fonts ) { + return false; + } + + return true; + } +} diff --git a/inc/Engine/Media/PreloadFonts/Database/Schema/PreloadFonts.php b/inc/Engine/Media/PreloadFonts/Database/Schema/PreloadFonts.php new file mode 100644 index 0000000000..a8eef190b2 --- /dev/null +++ b/inc/Engine/Media/PreloadFonts/Database/Schema/PreloadFonts.php @@ -0,0 +1,110 @@ + 'id', + 'type' => 'bigint', + 'length' => '20', + 'unsigned' => true, + 'extra' => 'auto_increment', + 'primary' => true, + 'sortable' => true, + ], + + // URL column. + [ + 'name' => 'url', + 'type' => 'varchar', + 'length' => '2000', + 'default' => '', + 'cache_key' => true, + 'searchable' => true, + 'sortable' => true, + ], + + // IS_MOBILE column. + [ + 'name' => 'is_mobile', + 'type' => 'tinyint', + 'length' => '1', + 'default' => 0, + 'cache_key' => true, + 'searchable' => true, + 'sortable' => true, + ], + + // Below the fold column. + [ + 'name' => 'fonts', + 'type' => 'longtext', + 'default' => '', + 'cache_key' => false, + 'searchable' => true, + 'sortable' => true, + ], + + // error_message column. + [ + 'name' => 'error_message', + 'type' => 'longtext', + 'default' => null, + 'cache_key' => false, + 'searchable' => true, + 'sortable' => true, + ], + + // STATUS column. + [ + 'name' => 'status', + 'type' => 'varchar', + 'length' => '255', + 'default' => null, + 'cache_key' => true, + 'searchable' => true, + 'sortable' => false, + ], + + // MODIFIED column. + [ + 'name' => 'modified', + 'type' => 'timestamp', + 'default' => '0000-00-00 00:00:00', + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ], + + // LAST_ACCESSED column. + [ + 'name' => 'last_accessed', + 'type' => 'timestamp', + 'default' => '0000-00-00 00:00:00', + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ], + + // CREATED_AT column. + [ + 'name' => 'created_at', + 'type' => 'timestamp', + 'default' => null, + 'created' => true, + 'date_query' => true, + 'sortable' => true, + ], + ]; +} diff --git a/inc/Engine/Media/PreloadFonts/Database/Table/PreloadFonts.php b/inc/Engine/Media/PreloadFonts/Database/Table/PreloadFonts.php new file mode 100644 index 0000000000..417b97e2ee --- /dev/null +++ b/inc/Engine/Media/PreloadFonts/Database/Table/PreloadFonts.php @@ -0,0 +1,57 @@ + value array of versions => methods. + * + * @var array + */ + protected $upgrades = []; + + /** + * Table schema data. + * + * @var string + */ + protected $schema_data = " + id bigint(20) unsigned NOT NULL AUTO_INCREMENT, + url varchar(2000) NOT NULL default '', + is_mobile tinyint(1) NOT NULL default 0, + fonts longtext default '', + error_message longtext default '', + status varchar(255) NOT NULL default '', + modified timestamp NOT NULL default '0000-00-00 00:00:00', + last_accessed timestamp NOT NULL default '0000-00-00 00:00:00', + created_at timestamp NULL, + PRIMARY KEY (id), + KEY url (url(150), is_mobile), + KEY modified (modified), + KEY last_accessed (last_accessed), + INDEX `status_index` (`status`(191))"; +} diff --git a/inc/Engine/Media/PreloadFonts/Frontend/Subscriber.php b/inc/Engine/Media/PreloadFonts/Frontend/Subscriber.php new file mode 100644 index 0000000000..6062f7c859 --- /dev/null +++ b/inc/Engine/Media/PreloadFonts/Frontend/Subscriber.php @@ -0,0 +1,20 @@ +provides, true ); + } + + /** + * Registers the classes in the container + * + * @return void + */ + public function register(): void { + $this->getContainer()->addShared( 'preload_fonts_table', PreloadFontsTable::class ); + + $this->getContainer()->get( 'preload_fonts_table' ); + $options = $this->getContainer()->get( 'options' ); + + $this->getContainer()->add( 'preload_fonts_query', PreloadFontsQuery::class ); + $this->getContainer()->add( 'preload_fonts_context', Context::class ) + ->addArgument( $options ); + + $this->getContainer()->add( 'preload_fonts_ajax_controller', AJAXController::class ) + ->addArguments( + [ + $this->getContainer()->get( 'preload_fonts_query' ), + $this->getContainer()->get( 'preload_fonts_context' ), + ] + ); + + $this->getContainer()->addShared( 'preload_fonts_frontend_subscriber', FrontendSubscriber::class ); + } +} diff --git a/inc/Engine/WPRocketUninstall.php b/inc/Engine/WPRocketUninstall.php index 23d17995e9..b45b6b1bf3 100644 --- a/inc/Engine/WPRocketUninstall.php +++ b/inc/Engine/WPRocketUninstall.php @@ -5,6 +5,7 @@ use WP_Rocket\Engine\Preload\Database\Tables\Cache; use WP_Rocket\Engine\Media\AboveTheFold\Database\Tables\AboveTheFold; use WP_Rocket\Engine\Optimization\LazyRenderContent\Database\Table\LazyRenderContent; +use WP_Rocket\Engine\Media\PreloadFonts\Database\Table\PreloadFonts; /** * Manages the deletion of WP Rocket data and files on uninstall. @@ -152,6 +153,7 @@ class WPRocketUninstall { * @param Cache $rocket_cache Preload rocket_cache table. * @param AboveTheFold $atf_table Above the fold table. * @param LazyRenderContent $lrc_table Lazy Render content table. + * @param PreloadFonts $preload_fonts_table Preload fonts table. */ public function __construct( $cache_path, @@ -159,7 +161,8 @@ public function __construct( $rucss_usedcss_table, $rocket_cache, $atf_table, - $lrc_table + $lrc_table, + $preload_fonts_table ) { $this->cache_path = trailingslashit( $cache_path ); $this->config_path = $config_path; @@ -168,6 +171,7 @@ public function __construct( $rocket_cache, $atf_table, $lrc_table, + $preload_fonts_table, ]; } diff --git a/inc/Plugin.php b/inc/Plugin.php index 1300cbc134..d93c7569df 100644 --- a/inc/Plugin.php +++ b/inc/Plugin.php @@ -54,7 +54,7 @@ use WP_Rocket\Engine\Common\PerformanceHints\ServiceProvider as PerformanceHintsServiceProvider; use WP_Rocket\Engine\Optimization\LazyRenderContent\ServiceProvider as LRCServiceProvider; use WP_Rocket\Engine\Media\Fonts\ServiceProvider as MediaFontsServiceProvider; - +use WP_Rocket\Engine\Media\PreloadFonts\ServiceProvider as PreloadFontsServiceProvider; /** * Plugin Manager. @@ -311,6 +311,7 @@ private function init_common_subscribers() { $this->container->addServiceProvider( new PerformanceHintsServiceProvider() ); $this->container->addServiceProvider( new LRCServiceProvider() ); $this->container->addServiceProvider( new MediaFontsServiceProvider() ); + $this->container->addServiceProvider( new PreloadFontsServiceProvider() ); $common_subscribers = [ 'license_subscriber', @@ -408,6 +409,7 @@ private function init_common_subscribers() { 'media_fonts_frontend_subscriber', 'media_fonts_admin_subscriber', 'media_fonts_clean_subscriber', + 'preload_fonts_frontend_subscriber', ]; $host_type = HostResolver::get_host_service(); diff --git a/tests/Fixtures/inc/Engine/Media/PreloadFonts/AJAX/Controller/addData.php b/tests/Fixtures/inc/Engine/Media/PreloadFonts/AJAX/Controller/addData.php new file mode 100644 index 0000000000..df539fd184 --- /dev/null +++ b/tests/Fixtures/inc/Engine/Media/PreloadFonts/AJAX/Controller/addData.php @@ -0,0 +1,276 @@ + [ + 'config' => [ + 'filter' => true, + 'url' => 'http://example.org', + 'is_mobile' => false, + 'results' => json_encode([ + 'preload_fonts' => [ + 'Raleway' => [ + 'variations' => [ + [ + 'weight' => '300', + 'style' => 'normal', + 'url' => 'https://fonts.gstatic.com/s/raleway/v34/1Ptug8zYS_SKggPNyC0IT4ttDfA.woff2', + ], + [ + 'weight' => '400', + "style" => 'normal', + "url" => 'https://fonts.googleapis.com/css?family=Roboto', + ], + ], + ], + ] + ]), + ], + 'expected' => [ + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'fonts' => json_encode( + [ + "Raleway" => (object) [ + 'variations' => [ + [ + 'weight' => "300", + "style" => "normal", + 'url' => 'https://fonts.gstatic.com/s/raleway/v34/1Ptug8zYS_SKggPNyC0IT4ttDfA.woff2', + ], + [ + 'weight' => "400", + "style" => "normal", + "url" => "https://fonts.googleapis.com/css?family=Roboto", + ], + ], + ] + ], + ), + 'last_accessed' => '2025-02-02 00:00:00', + 'created_at' => '2025-02-02 00:00:00', + 'error_message' => '' + ], + 'result' => true, + 'message' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'error_message' => '', + 'fonts' => json_encode( + [ + "Raleway" => (object) [ + 'variations' => [ + [ + 'weight' => "300", + "style" => "normal", + 'url' => 'https://fonts.gstatic.com/s/raleway/v34/1Ptug8zYS_SKggPNyC0IT4ttDfA.woff2', + ], + [ + 'weight' => "400", + "style" => "normal", + "url" => "https://fonts.googleapis.com/css?family=Roboto", + ], + ], + ] + ], + ), + 'created_at' => '2025-02-02 00:00:00', + 'last_accessed' => '2025-02-02 00:00:00', + ], + ], + ], + 'testShouldBailWhenNotAllowed' => [ + 'config' => [ + 'filter' => false, + 'url' => 'http://example.org', + 'is_mobile' => false, + 'results' => json_encode( + [ + 'preload_fonts' => [] + ], + ), + ], + 'expected' => [ + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'fonts' => [], + 'created_at' => '2025-02-02 00:00:00', + 'last_accessed' => '2025-02-02 00:00:00', + ], + 'result' => false, + 'message' => 'not allowed', + ], + ], + 'testShouldBailoutWhenDBError' => [ + 'config' => [ + 'filter' => true, + 'url' => 'http://example.org', + 'is_mobile' => false, + 'results' => json_encode([ + 'preload_fonts' => [ + 'Raleway' => [ + 'variations' => [ + [ + 'weight' => '300', + 'style' => 'normal', + 'url' => 'https://fonts.gstatic.com/s/raleway/v34/1Ptug8zYS_SKggPNyC0IT4ttDfA.woff2', + ], + [ + 'weight' => '400', + "style" => 'normal', + "url" => 'https://fonts.googleapis.com/css?family=Roboto', + ], + ], + ], + ] + ]), + ], + 'expected' => [ + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'fonts' => json_encode( + [ + "Raleway" => (object) [ + 'variations' => [ + [ + 'weight' => "300", + "style" => "normal", + 'url' => 'https://fonts.gstatic.com/s/raleway/v34/1Ptug8zYS_SKggPNyC0IT4ttDfA.woff2', + ], + [ + 'weight' => "400", + "style" => "normal", + "url" => "https://fonts.googleapis.com/css?family=Roboto", + ], + ], + ] + ], + ), + 'last_accessed' => '2025-02-02 00:00:00', + 'created_at' => '2025-02-02 00:00:00', + 'error_message' => '' + ], + 'result' => false, + 'message' => 'error when adding the entry to the database', + ], + ], + 'testShouldAddItemToDBWhenMobile' => [ + 'config' => [ + 'filter' => true, + 'url' => 'http://example.org', + 'is_mobile' => true, + 'results' => json_encode([ + 'preload_fonts' => [ + 'Raleway' => [ + 'variations' => [ + [ + 'weight' => '300', + 'style' => 'normal', + 'url' => 'https://fonts.gstatic.com/s/raleway/v34/1Ptug8zYS_SKggPNyC0IT4ttDfA.woff2', + ], + [ + 'weight' => '400', + "style" => 'normal', + "url" => 'https://fonts.googleapis.com/css?family=Roboto', + ], + ], + ], + ] + ]), + ], + 'expected' => [ + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => true, + 'status' => 'completed', + 'fonts' => json_encode( + [ + "Raleway" => (object) [ + 'variations' => [ + [ + 'weight' => "300", + "style" => "normal", + 'url' => 'https://fonts.gstatic.com/s/raleway/v34/1Ptug8zYS_SKggPNyC0IT4ttDfA.woff2', + ], + [ + 'weight' => "400", + "style" => "normal", + "url" => "https://fonts.googleapis.com/css?family=Roboto", + ], + ], + ] + ], + ), + 'last_accessed' => '2025-02-02 00:00:00', + 'created_at' => '2025-02-02 00:00:00', + 'error_message' => '' + ], + 'result' => true, + 'message' => [ + 'url' => 'http://example.org', + 'is_mobile' => true, + 'status' => 'completed', + 'error_message' => '', + 'fonts' => json_encode( + [ + "Raleway" => (object) [ + 'variations' => [ + [ + 'weight' => "300", + "style" => "normal", + 'url' => 'https://fonts.gstatic.com/s/raleway/v34/1Ptug8zYS_SKggPNyC0IT4ttDfA.woff2', + ], + [ + 'weight' => "400", + "style" => "normal", + "url" => "https://fonts.googleapis.com/css?family=Roboto", + ], + ], + ] + ], + ), + 'created_at' => '2025-02-02 00:00:00', + 'last_accessed' => '2025-02-02 00:00:00', + ], + ], + ], + 'testShouldNotAddItemToDBWhenNoData' => [ + 'config' => [ + 'filter' => true, + 'url' => 'http://example.org', + 'is_mobile' => false, + 'results' => json_encode( + [ + 'preload_fonts' => [] + ], + ), + ], + 'expected' => [ + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'fonts' => '[]', + 'last_accessed' => '2025-01-01 00:00:00', + 'error_message' => '', + 'created_at' => '2025-01-01 00:00:00', + ], + 'result' => true, + 'message' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'error_message' => '', + 'fonts' => '[]', + 'created_at' => '2025-01-01 00:00:00', + 'last_accessed' => '2025-01-01 00:00:00', + ], + ], + ] +]; diff --git a/tests/Integration/inc/Engine/WPRocketUninstall/uninstall.php b/tests/Integration/inc/Engine/WPRocketUninstall/uninstall.php index a98a466013..31eed9783c 100644 --- a/tests/Integration/inc/Engine/WPRocketUninstall/uninstall.php +++ b/tests/Integration/inc/Engine/WPRocketUninstall/uninstall.php @@ -144,8 +144,17 @@ public function testShouldDeleteAll() { $preload_table = $container->get( 'preload_caches_table' ); $atf_table = $container->get( 'atf_table' ); $lrc_table = $container->get( 'lrc_table' ); - - $uninstall = new WPRocketUninstall( $cache_path, $config_path, $rucss_usedcss_table, $preload_table, $atf_table, $lrc_table ); + $preload_fonts_table = $container->get( 'preload_fonts_table' ); + + $uninstall = new WPRocketUninstall( + $cache_path, + $config_path, + $rucss_usedcss_table, + $preload_table, + $atf_table, + $lrc_table, + $preload_fonts_table + ); $uninstall->uninstall(); diff --git a/tests/Unit/inc/Engine/Media/PreloadFonts/AJAX/Controller/addData.php b/tests/Unit/inc/Engine/Media/PreloadFonts/AJAX/Controller/addData.php new file mode 100644 index 0000000000..a13f64bab8 --- /dev/null +++ b/tests/Unit/inc/Engine/Media/PreloadFonts/AJAX/Controller/addData.php @@ -0,0 +1,107 @@ +query = $this->createPartialMock( PreloadFonts::class, [ 'add_item' ] ); + $this->context = Mockery::mock( Context::class ); + $this->controller = new Controller( $this->query, $this->context ); + $this->temp_post = $_POST; + + + $this->stubEscapeFunctions(); + } + + protected function tearDown(): void { + unset( $_POST ); + $_POST = $this->temp_post; + + parent::tearDown(); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $expected ) { + $this->stubEscapeFunctions(); + $this->stubTranslationFunctions(); + + $_POST = [ + 'url' => addslashes( $config['url'] ), + 'is_mobile' => addslashes( $config['is_mobile'] ), + 'results' => addslashes( $config['results'] ), + 'status' => addslashes( $config['status'] ?? 'success' ), + ]; + + Functions\expect( 'check_ajax_referer' ) + ->once() + ->with( 'rocket_beacon', 'rocket_beacon_nonce' ) + ->andReturn( true ); + + $this->context->shouldReceive( 'is_allowed' ) + ->atMost() + ->once() + ->andReturn( $config['filter'] ); + + $valid_source = $expected['valid_source'] ?? []; + + if(empty($valid_source)) { + Functions\when( 'sanitize_text_field' )->alias( + function ( $value ) { + return is_string( $value ) ? strip_tags( $value ) : $value; + } + ); + } else{ + Functions\when('sanitize_text_field')->alias( + function ($value) use ($valid_source) { + $arr_value = []; + if (!is_string($value)) { + foreach ($valid_source as $key => $replacement) { + $arr_value[] = strip_tags($replacement); + } + return (object) $arr_value; + } + + return strip_tags($value); + } + ); + } + + Functions\when( 'current_time' ) + ->justReturn( $expected['item']['last_accessed'] ); + + $this->query->method( 'add_item' ) + ->with( $expected['item'] ) + ->willReturn( $expected['result'] ); + + Functions\when( 'wp_unslash' )->alias( + function ( $value ) { + return is_string( $value ) ? stripslashes( $value ) : $value; + } + ); + + $this->stubWpParseUrl(); + + $this->assertSame( [ 'preload_fonts' => $expected['message'] ], $this->controller->add_data() ); + } +} diff --git a/uninstall.php b/uninstall.php index 55e48390f5..5fd62b9b9e 100755 --- a/uninstall.php +++ b/uninstall.php @@ -35,13 +35,15 @@ $rocket_cache_table = new WP_Rocket\Engine\Preload\Database\Tables\Cache(); $rocket_atf_table = new WP_Rocket\Engine\Media\AboveTheFold\Database\Tables\AboveTheFold(); $rocket_lrc_table = new WP_Rocket\Engine\Optimization\LazyRenderContent\Database\Table\LazyRenderContent(); +$rocket_preload_fonts_table = new WP_Rocket\Engine\Media\PreloadFonts\Database\Table\PreloadFonts(); $rocket_uninstall = new WPRocketUninstall( WP_ROCKET_CACHE_ROOT_PATH, WP_ROCKET_CONFIG_PATH, $rocket_rucss_usedcss_table, $rocket_cache_table, $rocket_atf_table, - $rocket_lrc_table + $rocket_lrc_table, + $rocket_preload_fonts_table ); $rocket_uninstall->uninstall();