PluginProbe
ezCache / 1.3
ezCache v1.3
2.6.5 2.6.4 2.6.2 2.6.3 2.6.1 2.6.0 2.5.6 2.5.5 2.5.4 2.5.3 2.5.2 2.5.1 2.5 2.2.1 2.2.2 trunk 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.3 1.3.1 1.3.10 1.3.11 All 49 releases
ezcache / includes / FileOptimizer / WebpConverter.php

WebpConverter.php in ezCache 1.3, at includes/FileOptimizer/WebpConverter.php

129 lines 4.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Upress\EzCache\FileOptimizer;
3
4 use Upress\EzCache\BackgroundProcesses\ConvertWebpProcess;
5 use wpdb;
6
7 class WebpConverter extends BaseFileOptimizer {
8 /** @var string $cache_dir */
9 protected $cache_dir;
10 /** @var string $cache_file */
11 protected $cache_file;
12 /** @var ConvertWebpProcess $webp_processor */
13 protected $webp_processor;
14 /** @var wpdb $wpdb */
15 protected $wpdb;
16
17 function __construct( $cache_dir, $cache_file, $webp_processor, $wpdb ) {
18 $this->cache_dir = $cache_dir;
19 $this->cache_file = $cache_file;
20 $this->webp_processor = $webp_processor;
21 $this->wpdb = $wpdb;
22 }
23
24 /**
25 * Minifies CSS files
26 *
27 * @param string $html HTML content.
28 *
29 * @return string
30 */
31 public function optimize( $html ) {
32 /*
33 * we need to make sure to handle multiple formats
34 * <img src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
35 * <img srcset="elva-fairy-320w.jpg 320w, elva-fairy-480w.jpg 480w, elva-fairy-800w.jpg 800w" sizes="(max-width: 320px) 280px, (max-width: 480px) 440px, 800px" src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
36 * <picture><source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg"><img srv="elva-480w-close-portrait.jpg" alt="Elva dressed as a fairy"></picture>
37 * <div style="background: url(elva-480w-close-portrait.jpg);">
38 * <div style="background-image: url(elva-480w-close-portrait.jpg);">
39 */
40 $images = $this->find( '<img\s+([^>]+[\s"\'])?src\s*=\s*[\'"]\s*?([^\'"]+(?:\?[^\'"]*)?)\s*?[\'"]([^>]+)?\/?>', $html );
41
42 if ( ! $images ) {
43 return $html;
44 }
45
46 $need_to_process = false;
47 foreach ( $images as $image ) {
48 $image_url = $image[2];
49 $image_path = $this->get_file_path( $image[2] );
50
51 // we don't process external files or files that don't exist
52 if( ! file_exists( $image_path ) || $this->is_external_file( $image_url ) ) {
53 continue;
54 }
55
56 $ext = pathinfo( $image_path, PATHINFO_EXTENSION );
57 $mime = mime_content_type( $image_path );
58
59 $image_webp_url = preg_replace( '/^(.+)\.' . preg_quote( $ext, '/' ) . '$/u', '$1.webp', $image_url );
60 $image_webp_path = preg_replace( '/^(.+)\.' . preg_quote( $ext, '/' ) . '$/u', '$1.webp', $image_path );
61
62 // and skip non-images or images already in webp format
63 if ( 'webp' == $ext || ! preg_match( '/image\/.+/i', $mime ) || preg_match( '/image\/(svg.*|ico|gif|webp)/i', $mime ) ) {
64 continue;
65 }
66
67 // check if the image has a webp version and if it has then just replace it in the html
68 $image = $this->wpdb->get_row(
69 $this->wpdb->prepare(
70 "SELECT * FROM `{$this->wpdb->prefix}ezcache_webp_images` WHERE `uid` = %s LIMIT 1",
71 [ sha1( $image_path ) ]
72 )
73 );
74
75 if ( $image && 'completed' == $image->status ) {
76 $html = preg_replace( '/\b' . preg_quote( $image_url, '/' ) . '\b/u', $image->webp_url, $html );
77 continue;
78 }
79
80 if ( $image && 'pending' == $image->status ) {
81 // image is being processed in background
82 continue;
83 }
84
85 if ( $image && 'failed' == $image->status ) {
86 // if the image has failed we need to requeue it
87 $this->wpdb->query(
88 $this->wpdb->prepare(
89 "DELETE FROM `{$this->wpdb->prefix}ezcache_webp_images` WHERE `id` = %d",
90 [ $image->id ]
91 )
92 );
93 }
94
95 // otherwise send the image to process
96 // this should parse the images and set a callback to update the cache file
97 $this->wpdb->query(
98 $this->wpdb->prepare(
99 "INSERT INTO `{$this->wpdb->prefix}ezcache_webp_images` (`uid`, `url`, `webp_url`, `path`, `webp_path`, `status`, `created_at`, `updated_at`) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
100 [ sha1( $image_path ), $image_url, $image_webp_url, $image_path, $image_webp_path, 'pending', date( 'Y-m-d H:i:s' ), date( 'Y-m-d H:i:s' ) ]
101 )
102 );
103
104 if ( empty( $this->wpdb->last_error ) ) {
105 $need_to_process = true;
106 $this->webp_processor->push_to_queue( [
107 'row_id' => $this->wpdb->insert_id,
108 'image_url' => $image_url,
109 'image_path' => $image_path,
110 'image_webp_url' => $image_webp_url,
111 'image_webp_path' => $image_webp_path,
112 'cache_file' => $this->cache_file,
113 ] );
114 } else {
115 error_log( $this->wpdb->last_error );
116 }
117 }
118
119 if ( $need_to_process ) {
120 add_filter( 'http_headers_useragent', function () {
121 return 'webp background processor';
122 }, 9999 );
123 $this->webp_processor->save();
124 }
125
126 return $html;
127 }
128 }
129