. (int) round( $sizes[1] * $ratio ) . '"'; } return false; } /** * Assign width and height attributes to the img tag. * * @param string $image IMG tag. * @param string $width_height Width/Height attributes in ready state like [height="100" width="100"]. * * @return string IMG tag after adding attributes otherwise return the input img when error. */ private function assign_width_height( string $image, string $width_height ): string { // Remove old width and height attributes if found. $changed_image = preg_replace( '/\s(height|width)=(?:[\'"]?(?:[^\'\"\s]+)*[\'"]?)?/i', '', $image ); $changed_image = preg_replace( '/<\s*img/i', 'filesystem->exists( $image ); } $file_headers = get_headers( $image ); if ( ! $file_headers ) { return false; } return false !== strstr( $file_headers[0], '200' ); } /** * Check if we can specify image dimensions for all images. * * @return bool Can we or not. */ private function can_specify_dimensions_images(): bool { /** * Filter images dimensions attributes process. * * @since 2.2 * * @param bool $specify_dimensions Do the job or not. */ return apply_filters( 'rocket_specify_image_dimensions', false ) || $this->options->get( 'image_dimensions', false ); } /** * Check if we can specify image dimensions for one image. * * @param string $image Full img tag. * * @return false|string false if we can't specify for this image otherwise get img src attribute. */ private function can_specify_dimensions_one_image( string $image ) { // Don't touch lazy-load file (no conflict with Photon (Jetpack)). if ( false !== strpos( $image, 'data-lazy-original' ) || false !== strpos( $image, 'data-no-image-dimensions' ) || ! preg_match( '/\s+src\s*=\s*[\'"](?[^\'"]+)/i', $image, $src_match ) ) { return false; } return $src_match['url']; } /** * Get Image sizes. * * @param string $image_url Image url to get sizes for. * * @return array|false Get image sizes otherwise false. */ private function get_image_sizes( string $image_url ) { if ( $this->is_external_file( $image_url ) ) { $image_url = $this->normalize_url( $image_url ); if ( ! $this->can_specify_dimensions_external_images() ) { Logger::debug( 'Specify Image Dimensions failed because you/server disabled specifying dimensions for external images.', [ 'image_url' => $image_url ] ); return false; } if ( ! $this->image_exists( $image_url, true ) ) { Logger::debug( 'Specify Image Dimensions failed because external image not found.', [ 'image_url' => $image_url ] ); return false; } $sizes = $this->getimagesize( $image_url ); if ( ! $sizes ) { Logger::debug( 'Specify Image Dimensions failed because image is not valid.', [ 'image_url' => $image_url ] ); return false; } return $sizes; } $local_path = $this->get_local_path( $image_url ); if ( ! $this->image_exists( $local_path, false ) ) { Logger::debug( 'Specify Image Dimensions failed because internal image is not found.', [ 'image_url' => $image_url ] ); return false; } $sizes = $this->getimagesize( $local_path ); if ( ! $sizes ) { Logger::debug( 'Specify Image Dimensions failed because image is not valid.', [ 'image_url' => $image_url ] ); return false; } return $sizes; } /** * Gets image sizes for the given file * * @param string $filename File we want to retrieve information about. * * @return array|false */ private function getimagesize( string $filename ) { $file = new SplFileInfo( strtok( $filename, '?' ) ); if ( 'svg' === $file->getExtension() ) { return $this->svg_getimagesize( $filename ); } return getimagesize( $filename ); } /** * Gets image sizes for the given SVG file * * Uses the width/height attributes if present, or fallback to viewBox attribute * * @param string $filename File we want to retrieve information about. * * @return array|false */ private function svg_getimagesize( string $filename ) { $svgfile = simplexml_load_file( rawurlencode( $filename ), 'SimpleXMLElement', rocket_get_constant( 'LIBXML_NOERROR', 32 ) | rocket_get_constant( 'LIBXML_NOWARNING', 64 ) ); if ( ! $svgfile ) { return false; } $width = $this->format_svg_value( (string) $svgfile->attributes()->width ); $height = $this->format_svg_value( (string) $svgfile->attributes()->height ); $size = []; if ( ! empty( $width ) && ! empty( $height ) ) { $size[0] = $width; $size[1] = $height; $size[2] = 0; $size[3] = 'width="' . absint( $width ) . '" height="' . absint( $height ) . '"'; return $size; } $view_box = preg_split( '/[\s,]+/', (string) $svgfile->attributes()->viewBox ); if ( ! empty( $view_box ) ) { if ( ! empty( $view_box[2] ) && ! empty( $view_box[3] ) ) { $size[0] = $view_box[2]; $size[1] = $view_box[3]; $size[2] = 0; $size[3] = 'width="' . absint( $size[0] ) . '" height="' . absint( $size[1] ) . '"'; return $size; } return false; } return false; } /** * Formats the SVG width/height value in case of unusual units * * @since 3.10.8 * * @param string $value The value of the SVG width/height attribute. * * @return string */ private function format_svg_value( string $value ): string { // No unit, we can use the value directly. if ( is_numeric( $value ) ) { return $value; } if ( empty( $value ) ) { return $value; } $px_pattern = '/([0-9]+)\s*px/i'; // If pixel unit, remove the unit and return the numeric value. if ( preg_match( $px_pattern, $value ) ) { return preg_replace( $px_pattern, '$1', $value ); } // Return an empty string for other units. return ''; } /** * Normalize relative url to full url. * * @param string $url Url to be normalized. * * @return string Normalized url. */ private function normalize_url( string $url ): string { $url_host = wp_parse_url( $url, PHP_URL_HOST ); if ( empty( $url_host ) ) { $relative_url = ltrim( wp_make_link_relative( $url ), '/' ); $site_url_components = wp_parse_url( site_url( '/' ) ); return $site_url_components['scheme'] . '://' . $site_url_components['host'] . '/' . $relative_url; } return $url; } }