get_styles( $html );
if ( empty( $styles ) ) {
return $html;
}
foreach ( $styles as $style ) {
if ( $this->is_minify_excluded_file( $style ) ) {
Logger::debug(
'Style is excluded.',
[
'css minification process',
'tag' => $style[0],
]
);
continue;
}
$integrity_validated = $this->local_cache->validate_integrity( $style );
if ( false === $integrity_validated ) {
Logger::debug(
'Style integrity attribute not valid.',
[
'css minification process',
'tag' => $style[0],
]
);
continue;
}
$style['final'] = $integrity_validated;
$minify_url = $this->replace_url( strtok( $style['url'], '?' ) );
if ( ! $minify_url ) {
Logger::error(
'Style minification failed.',
[
'css minification process',
'tag' => $style[0],
]
);
continue;
}
$html = $this->replace_style( $style, $minify_url, $html );
}
return $html;
}
/**
* Get all style tags from HTML.
*
* @param string $html HTML content.
*
* @return array Array with style tags, empty array if no style tags found.
*/
protected function get_styles( $html ) {
$html_nocomments = $this->hide_comments( $html );
$styles = $this->find( ']+[\s"\'])?href\s*=\s*[\'"]\s*?(?[^\'"]+\.css(?:\?[^\'"]*)?)\s*?[\'"]([^>]+)?\/?>', $html_nocomments );
if ( ! $styles ) {
Logger::debug( 'No `` tags found.', [ 'css minification process' ] );
return [];
}
Logger::debug(
'Found ' . count( $styles ) . ' `` tags.',
[
'css minification process',
'tags' => $styles,
]
);
return $styles;
}
/**
* Creates the minify URL if the minification is successful
*
* @since 2.11
*
* @param string $url Original file URL.
*
* @return string|bool The minify URL if successful, false otherwise
*/
private function replace_url( $url ) {
if ( empty( $url ) ) {
return false;
}
// This filter is documented in /inc/classes/optimization/class-abstract-optimization.php.
$url = apply_filters( 'rocket_asset_url', $url, $this->get_zones() );
$parsed_url = wp_parse_url( $url );
if ( empty( $parsed_url['path'] ) ) {
return false;
}
if ( ! empty( $parsed_url['host'] ) ) {
$url = rocket_add_url_protocol( $url );
}
$filename = ltrim( rocket_realpath( $parsed_url['path'] ), '/' );
$minified_file = rawurldecode( $this->minify_base_path . $filename );
if ( rocket_direct_filesystem()->exists( $minified_file ) ) {
Logger::debug(
'Minified CSS file already exists.',
[
'css minification process',
'path' => $minified_file,
]
);
return $this->get_full_minified_url( $minified_file, $this->get_minify_url( $filename, $url ) );
}
$external_url = $this->is_external_file( $url );
$file_path = $external_url ? $this->local_cache->get_filepath( $url ) : $this->get_file_path( $url );
if ( empty( $file_path ) ) {
Logger::error(
'Couldn’t get the file path from the URL.',
[
'css minification process',
'url' => $url,
]
);
return false;
}
$file_content = $external_url ? $this->local_cache->get_content( $url ) : $this->get_file_content( $file_path );
if ( ! $file_content ) {
Logger::error(
'No file content.',
[
'css minification process',
'path' => $file_path,
]
);
return false;
}
$minified_content = $external_url ? $this->minify( $url, $minified_file, $file_content ) : $this->minify( $file_path, $minified_file, $file_content );
if ( empty( $minified_content ) ) {
return false;
}
$minified_content = $this->font_display_swap( $url, $minified_file, $minified_content );
if ( empty( $minified_content ) ) {
return false;
}
$save_minify_file = $this->save_minify_file( $minified_file, $minified_content );
if ( ! $save_minify_file ) {
return false;
}
return $this->get_full_minified_url( $minified_file, $this->get_minify_url( $filename, $url ) );
}
/**
* Replace old style tag with the minified tag.
*
* @param array $style Style matched data.
* @param string $minify_url Minified URL.
* @param string $html HTML content.
*
* @return string
*/
protected function replace_style( $style, $minify_url, $html ) {
$replace_style = str_replace( $style['url'], $minify_url, $style['final'] );
$replace_style = str_replace( ' $minify_url,
]
);
return $html;
}
/**
* Save minified CSS file.
*
* @since 3.7
*
* @param string $minified_file Minified file path.
* @param string $minified_content Minified HTML content.
*
* @return bool
*/
protected function save_minify_file( $minified_file, $minified_content ) {
$save_minify_file = $this->write_file( $minified_content, $minified_file );
if ( ! $save_minify_file ) {
Logger::error(
'Minified CSS file could not be created.',
[
'css minification process',
'path' => $minified_file,
]
);
return false;
}
Logger::debug(
'Minified CSS file successfully created.',
[
'css minification process',
'path' => $minified_file,
]
);
return true;
}
/**
* Applies font display swap if the file contains @font-face.
*
* @since 3.7
*
* @param string $url File Url.
* @param string $minified_file Minified file path.
* @param string $content CSS file content.
*
* @return string
*/
protected function font_display_swap( $url, $minified_file, $content ) {
if (
preg_match( '/(?:-|\.)min.css/iU', $url )
&&
false === stripos( $content, '@font-face' )
) {
Logger::error(
'Do not apply font display swap on min.css files without font-face.',
[
'css minification process',
'path' => $minified_file,
]
);
if ( ! $this->is_external_file( $url ) ) {
return '';
}
return $content;
}
return $this->apply_font_display_swap( $content );
}
/**
* Minifies the content
*
* @since 2.11
*
* @param string $file_path Source filepath.
* @param string $minified_file Target filepath.
* @param string $file_content Content to minify.
*
* @return string
*/
protected function minify( $file_path, $minified_file, $file_content ) {
$file_content = $this->rewrite_paths( $file_path, $minified_file, $file_content );
$minifier = $this->get_minifier( $file_content );
$minified_content = $minifier->minify();
if ( empty( $minified_content ) ) {
Logger::error(
'No minified content.',
[
'css minification process',
'path' => $minified_file,
]
);
return '';
}
return $minified_content;
}
/**
* Returns a new minifier instance
*
* @since 3.1
*
* @param string $file_content Content to minify.
*
* @return Minifier\CSS
*/
protected function get_minifier( $file_content ) {
return new Minifier\CSS( $file_content );
}
}