PluginProbe ʕ •ᴥ•ʔ
Smush – Image Optimization, Compression, Lazy Load, WebP & CDN / 3.23.4
Smush – Image Optimization, Compression, Lazy Load, WebP & CDN v3.23.4
4.1.0 4.0.3 4.0.2 2.8.1 2.9.1 3.0.0 3.0.1 3.0.2 3.1.1 3.10.1 3.10.2 3.10.3 3.11.1 3.12.3 3.12.4 3.12.5 3.12.6 3.13.0 3.13.1 3.13.2 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.2 3.16.4 3.16.5 3.16.6 3.17.0 3.17.1 3.18.0 3.18.1 3.2.0.1 3.2.1 3.2.2.1 3.2.4 3.20.0 3.21.1 3.22.1 3.22.3 3.23.0 3.23.1 3.23.2 3.23.3 3.23.4 3.24.0 3.24.0-beta.2 3.3.0 3.3.1 3.3.2 3.4.1 3.4.2 3.6.1 3.6.3 3.7.0 3.7.1 3.7.2 3.7.3 3.8.2 3.8.3 3.8.4 3.8.5 3.8.7 3.8.8 3.9.0 3.9.1 3.9.11 3.9.2 3.9.4 3.9.5 3.9.8 3.9.9 trunk 1.0.0 1.0.1 1.0.2 1.1 1.1.1 1.1.2 1.1.3 1.2 1.2.1 1.2.10 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.5.1 1.6.5.2 1.6.5.3 1.6.5.4 1.7 1.7.1 1.7.1.1 2.0 2.0.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.6.2 2.0.6.3 2.0.6.5 2.0.7 2.0.7.1 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2 2.2.1 2.2.2 2.3 2.3.1 2.4 2.4.2 2.4.3 2.4.4 2.4.5 2.5.2 2.5.3 2.6.1 2.6.2 2.6.3 2.7 2.7.1 2.7.4 2.7.4.1 2.7.5 2.7.6 2.7.8 2.7.8.1 2.7.9.1 2.8.0 2.8.0.1
wp-smushit / core / class-url-utils.php
wp-smushit / core Last commit date
api 3 months ago backups 3 months ago cache 3 months ago cli 3 months ago directory 3 months ago external 3 months ago integrations 3 months ago lazy-load 3 months ago media 3 months ago media-library 3 months ago membership 3 months ago modules 3 months ago parser 3 months ago photon 3 months ago resize 3 months ago security 3 months ago smush 3 months ago srcset 3 months ago stats 3 months ago threads 3 months ago transform 3 months ago class-animated-status-controller.php 3 months ago class-array-utils.php 3 months ago class-attachment-id-list.php 3 months ago class-backup-size.php 3 months ago class-configs.php 3 months ago class-controller.php 3 months ago class-core.php 3 months ago class-cron-controller.php 3 months ago class-deprecated-hooks.php 3 months ago class-error-handler.php 3 months ago class-file-system.php 3 months ago class-file-utils.php 3 months ago class-format-utils.php 3 months ago class-helper.php 3 months ago class-hub-connector.php 3 months ago class-installer.php 3 months ago class-keyword-exclusions.php 3 months ago class-modules.php 3 months ago class-optimization-controller.php 3 months ago class-plugin-settings-watcher.php 3 months ago class-product-analytics.php 3 months ago class-rest.php 3 months ago class-server-utils.php 3 months ago class-settings.php 3 months ago class-shim.php 3 months ago class-smush-file.php 3 months ago class-stats.php 3 months ago class-time-utils.php 3 months ago class-timer.php 3 months ago class-upload-dir.php 3 months ago class-url-utils.php 3 months ago class-wp-query-utils.php 3 months ago wp-compat.php 3 months ago
class-url-utils.php
285 lines
1 <?php
2
3 namespace Smush\Core;
4
5 use Smush\Core\CDN\CDN_Helper;
6 use Smush\Core\Transform\Transformation_Controller;
7
8 class Url_Utils {
9 /**
10 * @var Upload_Dir
11 */
12 private $upload_dir;
13
14 /**
15 * @var string
16 */
17 private $content_url;
18
19 public function __construct() {
20 $this->upload_dir = new Upload_Dir();
21 }
22
23 public function get_extension( $url ) {
24 $path = wp_parse_url( $url, PHP_URL_PATH );
25 if ( empty( $path ) ) {
26 return false;
27 }
28
29 return strtolower( pathinfo( $path, PATHINFO_EXTENSION ) );
30 }
31
32 public function get_url_scheme( $url ) {
33 $url_parts = wp_parse_url( $url );
34
35 return empty( $url_parts['scheme'] )
36 ? false
37 : $url_parts['scheme'];
38 }
39
40 /**
41 * @param $url
42 *
43 * @return string
44 * @see attachment_url_to_postid()
45 */
46 public function make_media_url_relative( $url ) {
47 $upload_url = $this->upload_dir->get_upload_url();
48 $path = $url;
49
50 $site_url = parse_url( $upload_url );
51 $image_path = parse_url( $path );
52
53 // Force the protocols to match if needed.
54 if ( isset( $image_path['scheme'] ) && ( $image_path['scheme'] !== $site_url['scheme'] ) ) {
55 $path = str_replace( $image_path['scheme'], $site_url['scheme'], $path );
56 }
57
58 if ( str_starts_with( $path, $upload_url . '/' ) ) {
59 $path = substr( $path, strlen( $upload_url . '/' ) );
60 }
61
62 return $path;
63 }
64
65 public function guess_dimensions_from_image_url( $url ) {
66 $width_height_string = array();
67
68 if ( preg_match( '#-(\d+)x(\d+)\.(?:jpe?g|png|gif|webp|svg)#i', $url, $width_height_string ) ) {
69 $width = (int) $width_height_string[1];
70 $height = (int) $width_height_string[2];
71
72 if ( $width && $height ) {
73 return array( $width, $height );
74 }
75 }
76
77 return array( false, false );
78 }
79
80 public function get_query_vars( $url ) {
81 // Decode HTML entities in the URL.
82 $url = html_entity_decode( $url );
83
84 $parse_url = wp_parse_url( $url );
85 $query_vars = array();
86 if ( ! empty( $parse_url['query'] ) ) {
87 wp_parse_str( $parse_url['query'], $query_vars );
88 }
89
90 return $query_vars;
91 }
92
93 public function get_image_dimensions( $image_url ) {
94 $dimensions = apply_filters( 'wp_smush_get_image_dimensions', false, $image_url );
95 if ( $dimensions ) {
96 return $dimensions;
97 }
98
99 $image_url = apply_filters( 'wp_smush_get_image_dimensions_url', $image_url );
100
101 return $this->_get_image_dimensions( $image_url );
102 }
103
104 private function _get_image_dimensions( $image_url ) {
105 $default = array( false, false );
106
107 if ( empty( $image_url ) ) {
108 return $default;
109 }
110
111 list( $width, $height ) = $this->guess_dimensions_from_image_url( $image_url );
112
113 if ( ! empty( $width ) && ! empty( $height ) && $width > Transformation_Controller::get_min_transformable_image_dimension() ) {
114 return array( $width, $height );
115 }
116
117 if ( $this->is_external_url( $image_url ) ) {
118 if ( ! $this->should_fetch_external_image_dimensions( $image_url ) ) {
119 return $default;
120 }
121
122 if ( ! $this->url_has_200_response( $image_url ) ) {
123 return $default;
124 }
125
126 return $this->getimagesize( $image_url );
127 }
128
129 $local_path = $this->url_to_path( $image_url );
130 if ( ! $local_path || ! file_exists( $local_path ) ) {
131 return $default;
132 }
133
134 return $this->getimagesize( $local_path );
135 }
136
137 public function get_url_content_type_header( $image_url ) {
138 // Use url headers to check content type
139 if ( $this->is_external_url( $image_url ) ) {
140 $headers = get_headers( $image_url, 1 );
141
142 if ( empty( $headers['content-type'] ) ) {
143 return false;
144 }
145
146 return $headers['content-type'];
147 } else {
148 return false;
149 }
150 }
151
152 private function should_fetch_external_image_dimensions( $image_url ) {
153 return ini_get( 'allow_url_fopen' ) && apply_filters( 'wp_smush_should_fetch_external_image_dimensions', false, $image_url );
154 }
155
156 private function getimagesize( $image_url ) {
157 $sizes = wp_getimagesize( $image_url );
158
159 if ( empty( $sizes ) ) {
160 return array( false, false );
161 }
162
163 return array( $sizes[0], $sizes[1] );
164 }
165
166 public function url_has_200_response( $url ) {
167 if ( ! $url || ! ini_get( 'allow_url_fopen' ) ) {
168 return false;
169 }
170
171 $file_headers = get_headers( $url );
172
173 if ( empty( $file_headers[0] ) ) {
174 return false;
175 }
176
177 return false !== strstr( $file_headers[0], '200' );
178 }
179
180 public function is_external_url( $absolute_url ) {
181 if ( str_starts_with( $absolute_url, $this->get_content_url() ) ) {
182 return false;
183 }
184
185 if ( str_starts_with( $absolute_url, $this->upload_dir->get_upload_url() ) ) {
186 return false;
187 }
188
189 return true;
190 }
191
192 public function url_to_path( $absolute_url ) {
193 if ( str_starts_with( $absolute_url, $this->get_content_url() ) ) {
194 return str_replace( $this->get_content_url(), WP_CONTENT_DIR, $absolute_url );
195 }
196
197 $upload_url = $this->upload_dir->get_upload_url();
198 $upload_dir = $this->upload_dir->get_upload_path();
199
200 if ( str_starts_with( $absolute_url, $upload_url ) ) {
201 return str_replace( $upload_url, $upload_dir, $absolute_url );
202 }
203
204 return false;
205 }
206
207 private function get_content_url() {
208 if ( ! $this->content_url ) {
209 $this->content_url = content_url();
210 }
211
212 return $this->content_url;
213 }
214
215 /**
216 * Get full size image url from resized one.
217 *
218 * @param string $src Image URL.
219 *
220 * @return string
221 * @since 3.0
222 *
223 */
224 public function get_url_without_dimensions( $src ) {
225 $extensions = array(
226 'gif',
227 'jpg',
228 'jpeg',
229 'png',
230 'webp',
231 );
232 if ( ! preg_match( '/(-\d+x\d+)\.(' . implode( '|', $extensions ) . ')(?:\?.+)?$/i', $src, $src_parts ) ) {
233 return $src;
234 }
235
236 // Remove WP's resize string to get the original image.
237 $original_src = str_replace( $src_parts[1], '', $src );
238
239 // Extracts the file path to the image minus the base url.
240 $file_path = substr( $original_src, strlen( $this->upload_dir->get_upload_url() ) );
241
242 // Continue only if the file exists.
243 if ( file_exists( $this->upload_dir->get_upload_path() . $file_path ) ) {
244 return $original_src;
245 }
246
247 // Revert to source if file does not exist.
248 return $src;
249 }
250
251 /**
252 * Convert original image URL to scaled image URL.
253 *
254 * @param string $src Original image URL.
255 *
256 * @return string|null
257 */
258 public function get_scaled_image_url( $original_src ) {
259 if ( strpos( $original_src, '-scaled' ) !== false ) {
260 return $original_src;
261 }
262
263 $path_info = pathinfo( $original_src );
264 $scaled_filename = $path_info['filename'] . '-scaled.' . $path_info['extension'];
265 $scaled_src = str_replace( $path_info['basename'], $scaled_filename, $original_src );
266
267 $scaled_path = $this->url_to_path( $scaled_src );
268 if ( $scaled_path && file_exists( $scaled_path ) ) {
269 return $scaled_src;
270 }
271
272 return null;
273 }
274
275 public function normalize_url( $url ) {
276 $url = str_replace( array( 'http://', 'https://', 'www.' ), '', $url );
277
278 return untrailingslashit( $url );
279 }
280
281 public function is_relative( $url ) {
282 return ! empty( preg_match( '/^\./', $url ) ) || empty( wp_parse_url( $url, PHP_URL_HOST ) );
283 }
284 }
285