PluginProbe
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score / 1.2.4
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score v1.2.4
trunk 1.0 1.0.1 1.1 1.1.1 1.1.2 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1 2.1.1 2.1.2 2.2 2.2.1 All 69 releases
powered-cache / includes / class-powered-cache-cdn.php

class-powered-cache-cdn.php in Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score 1.2.4, at includes/class-powered-cache-cdn.php

247 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 class Powered_Cache_CDN {
8
9 /**
10 * Return an instance of the current class
11 *
12 * @since 1.0
13 * @return Powered_Cache_CDN
14 */
15 public static function factory() {
16 static $instance = false;
17
18 if ( ! $instance ) {
19 $instance = new self();
20 $instance->setup();
21 }
22
23 return $instance;
24 }
25
26 /**
27 * Setup hooks
28 *
29 * @since 1.0
30 */
31 public function setup() {
32
33 add_filter( 'wp_get_attachment_url', array( $this, 'cdn_url' ), PHP_INT_MAX );
34 add_filter( 'stylesheet_uri', array( $this, 'cdn_url' ), PHP_INT_MAX );
35 add_filter( 'smilies_src', array( $this, 'cdn_url' ), PHP_INT_MAX );
36 add_filter( 'bp_core_fetch_avatar_url', array( $this, 'cdn_url' ), PHP_INT_MAX );
37 add_filter( 'style_loader_src', array( $this, 'cdn_url' ), PHP_INT_MAX );
38 add_filter( 'script_loader_src', array( $this, 'cdn_url' ), PHP_INT_MAX );
39 add_filter( 'wp_calculate_image_srcset', array( $this, 'srcset_url' ), PHP_INT_MAX );
40 add_filter( 'wp_get_attachment_image_src', array( $this, 'attachment_image_src' ), PHP_INT_MAX );
41
42
43 add_filter( 'the_content', array( $this, 'cdn_images' ), PHP_INT_MAX );
44 add_filter( 'post_thumbnail_html', array( $this, 'cdn_images' ), PHP_INT_MAX );
45 add_filter( 'get_avatar', array( $this, 'cdn_images' ), PHP_INT_MAX );
46 add_filter( 'bp_core_fetch_avatar', array( $this, 'cdn_images' ), PHP_INT_MAX );
47 add_filter( 'widget_text', array( $this, 'cdn_images' ), PHP_INT_MAX );
48 add_filter( 'media_image', array( $this, 'cdn_images' ), PHP_INT_MAX );
49 add_filter( 'powered_cache_page_caching_buffer', array( $this, 'cdn_images' ), PHP_INT_MAX );
50
51
52 do_action( 'powered_cache_cdn_setup' );
53 }
54
55
56 /**
57 * Replace CDN url for srcset
58 *
59 * @param $sources array source files
60 *
61 * @since 1.2
62 * @return mixed
63 */
64 public function srcset_url( $sources ) {
65 foreach ( $sources as $key => $source ) {
66 $sources[ $key ]['url'] = $this->cdn_url( $source['url'] );
67 }
68
69 return $sources;
70 }
71
72 public function cdn_url( $url ) {
73 if ( is_admin() || is_preview() ) {
74 return $url;
75 }
76
77 return $this->maybe_cdn_replace( $url );
78 }
79
80
81 /**
82 * Replace URL for wp_get_attachment_image_src function
83 *
84 * @param array|false $image Either array with src, width & height, icon src, or false
85 *
86 * @since 1.2.4
87 * @return array $image
88 */
89 public function attachment_image_src( $image ) {
90 if ( is_admin() || is_preview() ) {
91 return $image;
92 }
93
94 if ( ! (bool) $image ) {
95 return $image;
96 }
97
98 $cdn_url = self::get_best_possible_cdn_host( 'image' );
99 // no host found
100 if ( false === $cdn_url ) {
101 return $image;
102 }
103
104 $image[0] = str_replace( home_url(), $cdn_url, $image[0] );
105
106 return $image;
107 }
108
109
110 public function cdn_images( $content ) {
111 if ( is_admin() || is_preview() || empty( $content ) ) {
112 return $content;
113 }
114
115 if ( ! class_exists( 'DOMDocument' ) ) {
116 return $content;
117 }
118
119 $document = new DOMDocument();
120 @$document->loadHTML($content);
121 $images = $document->getElementsByTagName('img');
122
123 $img_url = array();
124 foreach ( $images as $img ) {
125 if ( $img->hasAttribute( 'src' ) ) {
126 $img_url[] = $img->getAttribute( 'src' );
127 }
128
129 if ( $img->hasAttribute( 'srcset' ) ) {
130 $imgset = explode( ',', $img->getAttribute( 'srcset' ) );
131 foreach ( $imgset as $src_item ) {
132 $imgsrc = explode( ' ', trim( $src_item ) );
133 // first item is url, second width
134 $img_url[] = $imgsrc[0];
135 }
136 }
137 }
138
139 $img_url = array_unique($img_url);
140 $cdn_url = array();
141
142 foreach ( $img_url as $replace_url ) {
143 $cdn_url[] = $this->maybe_cdn_replace( $replace_url );
144 }
145
146
147 return str_replace( $img_url, $cdn_url, $content );
148 }
149
150
151 /**
152 * this method decide to url replacement.
153 * rejected files & external resources will be ignored
154 *
155 * @since 1.0
156 *
157 * @param string $url
158 * @return string cdn url
159 */
160 public static function maybe_cdn_replace( $url ) {
161 global $powered_cache_options;
162
163 $raw_url = $url;
164
165 // rejected file
166 if ( ! empty( $powered_cache_options['cdn_rejected_files'] ) ) {
167 $cdn_rejected_files = preg_split( '#(\r\n|\r|\n)#', $powered_cache_options['cdn_rejected_files'] );
168 $cdn_rejected_files = implode( '|', $cdn_rejected_files );
169
170 if ( preg_match( '#(' . $cdn_rejected_files . ')#', $url ) ) {
171 return $url;
172 }
173 }
174
175 // external resource
176 if ( false === strpos( $url, home_url() ) ) {
177 return $url;
178 }
179
180 // don't replace for base64 encoded images
181 if ( false !== strpos( $url, 'data:image' ) ) {
182 return $url;
183 }
184
185 // clean version string
186 if ( strpos( $url, '?ver=' ) ) {
187 $raw_url = remove_query_arg( 'ver', $url );
188 }
189
190 $raw_url = untrailingslashit( $raw_url );
191 $ext = explode( '.', $raw_url );
192 $ext = strtolower( end( $ext ) );
193
194 $zone = 'all';
195 $image_extensions = apply_filters( 'powered_cache_cdn_image_extensions', array( 'jpg', 'jpeg', 'gif', 'png', 'bmp', 'ico', 'webp' ) );
196
197 if ( in_array( $ext, $image_extensions ) ) {
198 $zone = 'image';
199 } elseif ( 'css' == $ext ) {
200 $zone = 'css';
201 } elseif ( 'js' == $ext ) {
202 $zone = 'js';
203 }
204
205 $cdn_url = self::get_best_possible_cdn_host( $zone );
206
207 // no host found
208 if ( false === $cdn_url ) {
209 return $url;
210 }
211
212 return str_replace( home_url(), $cdn_url, $url );
213 }
214
215 /**
216 * try to catch best cdn address to given zone
217 * @param string $zone keys of Powered_Cache_Admin_Helper::cdn_zones
218 *
219 * @return mixed string | false
220 */
221 public static function get_best_possible_cdn_host( $zone = 'all' ) {
222 global $powered_cache_cdn_addresses;
223
224 if ( ! isset( $powered_cache_cdn_addresses ) ) {
225 $powered_cache_cdn_addresses = powered_cache_cdn_addresses();
226 }
227
228 if ( isset( $powered_cache_cdn_addresses[ $zone ] ) && is_array( $powered_cache_cdn_addresses[ $zone ] ) ) {
229 // if we have multiple host for the same resource get randomly
230 $random_key = array_rand( $powered_cache_cdn_addresses[ $zone ] );
231
232 return $powered_cache_cdn_addresses[ $zone ][ $random_key ];
233 }
234
235 // fallback to primary host
236 if ( isset( $powered_cache_cdn_addresses['all'] ) && is_array( $powered_cache_cdn_addresses['all'] ) ) {
237 $random_key = array_rand( $powered_cache_cdn_addresses['all'] );
238
239 return $powered_cache_cdn_addresses['all'][ $random_key ];
240 }
241
242 return false;
243 }
244
245 }
246
247