public function create_lazy_inline_css( array $data ): array { if ( ! key_exists( 'html', $data ) || ! key_exists( 'css_inline', $data ) ) { $this->logger::debug( 'Create lazy css inline bailed out', $this->generate_log_context( [ 'data' => $data, ] ) ); return $data; } $html = $data['html']; if ( ! key_exists( 'lazyloaded_images', $data ) ) { $data['lazyloaded_images'] = []; } foreach ( $data['css_inline'] as $content ) { $output = $this->generate_content( $content ); $html = str_replace( $content, $output->get_content(), $html ); $data['lazyloaded_images'] = array_merge( $data['lazyloaded_images'], $output->get_urls() ); } $data['html'] = $html; return $data; } /** * Format a URL. * * @param string $url URL to format. * @return string */ protected function format_url( string $url ): string { return strtok( $url, '?' ); } /** * Check of the string is excluded. * * @param string $string String to check. * @return bool */ protected function is_excluded( string $string ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.stringFound $values = [ $string, ]; $parsed_url_host = wp_parse_url( $string, PHP_URL_HOST ); if ( ! $parsed_url_host ) { $values [] = rocket_get_home_url() . $string; } /** * Filters the src used to prevent lazy load from being applied. * * @param array $excluded_src An array of excluded src. */ $excluded_values = apply_filters( 'rocket_lazyload_excluded_src', [] ); if ( ! is_array( $excluded_values ) ) { $excluded_values = (array) $excluded_values; } if ( empty( $excluded_values ) ) { return false; } foreach ( $values as $value ) { foreach ( $excluded_values as $excluded_value ) { if ( strpos( $value, $excluded_value ) !== false ) { return true; } } } return false; } /** * Add the lazyload script to exclude js exclusions. * * @param array $js_files Exclusions. * @return array */ public function add_lazyload_script_exclude_js( array $js_files ) { if ( ! $this->is_activated() ) { return $js_files; } $js_files [] = '#rocket_lazyload_css-js-after'; return $js_files; } /** * Add the lazyload script to defer js exclusions. * * @param array $exclude_defer_js Exclusions. * @return array */ public function add_lazyload_script_rocket_exclude_defer_js( array $exclude_defer_js ) { if ( ! $this->is_activated() ) { return $exclude_defer_js; } $exclude_defer_js [] = '#rocket_lazyload_css-js-after'; return $exclude_defer_js; } /** * Add the lazyload script to delay js exclusions. * * @param array $js_files Exclusions. * @return array */ public function add_lazyload_script_rocket_delay_js_exclusions( array $js_files ) { if ( ! $this->is_activated() ) { return $js_files; } $js_files [] = '#rocket_lazyload_css-js-after'; return $js_files; } /** * Is the feature activated. * * @return bool */ protected function is_activated(): bool { return (bool) $this->options->get( 'lazyload_css_bg_img', false ); } /** * Add lazyload_excluded_src to excluded filters. * * @param array $excluded Excluded URLs. * @param array $urls List of Urls processed. * @return mixed */ public function exclude_rocket_lazyload_excluded_src( $excluded, $urls ) { /** * Filters the src used to prevent lazy load from being applied. * * @param array $excluded_src An array of excluded src. */ $excluded_values = apply_filters( 'rocket_lazyload_excluded_src', [] ); if ( ! is_array( $excluded_values ) ) { $excluded_values = (array) $excluded_values; } if ( empty( $excluded_values ) ) { return $excluded; } foreach ( $urls as $url ) { foreach ( $excluded_values as $excluded_value ) { if ( strpos( $url['selector'], $excluded_value ) !== false || strpos( $url['style'], $excluded_value ) !== false ) { $excluded[] = $url; break; } } } return $excluded; } /** * Add hashes. * * @param array $tags Tags. * @return array */ protected function add_hashes( array $tags ): array { return array_map( function ( $url_tag ) { /** * Lazyload CSS hash. * * @param string $hash Lazyload CSS hash. */ $url_tag['hash'] = apply_filters( 'rocket_lazyload_css_hash', wp_generate_uuid4(), $url_tag ); return $url_tag; }, $tags ); } /** * Return mapping file URL. * * @param string $url Resource URL. * @return string */ protected function get_mapping_file_url( string $url ): string { return $this->format_url( $url ) . '.json'; } /** * Add timestamp to URL. * * @param string $url Asset Url. * * @return string */ protected function generate_asset_url( string $url ): string { $parsed_query = wp_parse_url( $url, PHP_URL_QUERY ); $queries = []; if ( $parsed_query ) { parse_str( $parsed_query, $queries ); } $queries['wpr_t'] = current_time( 'timestamp' ); // phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested $cached_url = $this->cache->generate_url( $this->format_url( $url ) ); $this->logger::debug( "Generated url lazy css files $url", $this->generate_log_context( [ 'data' => $cached_url, ] ) ); return add_query_arg( $queries, $cached_url ); } /** * Generate the context for logs. * * @param array $data Data to pass to logs. * @return array */ protected function generate_log_context( array $data = [] ): array { return array_merge( $data, [ 'type' => 'lazyload_css_bg_images', ] ); } /** * Protect URL inside the content. * * @param string $content Content to protect. * @param array $css_files CSS files from the content. * @return ProtectedContent */ protected function protect_css_urls( string $content, array $css_files ): ProtectedContent { usort( $css_files, function ( $url1, $url2 ) { return strlen( $url1 ) < strlen( $url2 ) ? 1 : -1; } ); $css_files_mapping = []; foreach ( $css_files as $url ) { $placeholder = uniqid( 'url_bg_css_' ); $content = str_replace( $url, $placeholder, $content ); $css_files_mapping[ $url ] = $placeholder; } return $this->lazyloaded_content_factory->make_protected_content( $css_files_mapping, $content ); } /** * Exclude SVG from lazy loaded images. * * @param array $urls URLs to exclude. * @return array */ public function remove_svg_from_lazyload_css( array $urls ): array { $urls[] = 'data:image/svg+xml'; return $urls; } }