Completed
Branch master (e24efa)
by LA
01:53
created

do-functions.php ➔ imgix_apply_parameters_to_url()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 4
nop 3
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * @package imgix
5
 */
6
7
/**
8
 * Find all img tags with sources matching "imgix.net" without the parameter
9
 * "srcset" and add the "srcset" parameter to all those images, appending a new
10
 * source using the "dpr=2" modifier.
11
 *
12
 * @param $content
13
 * @return string Content with retina-enriched image tags.
14
 */
15
function imgix_add_retina( $content ) {
16
	$pattern = '/<img((?![^>]+srcset )([^>]*)';
17
	$pattern .= 'src=[\'"]([^\'"]*imgix.net[^\'"]*\?[^\'"]*w=[^\'"]*)[\'"]([^>]*)*?)>/i';
18
	$repl = '<img$2src="$3" srcset="${3}, ${3}&amp;dpr=2 2x, ${3}&amp;dpr=3 3x,"$4>';
19
	$content = preg_replace( $pattern, $repl, $content );
20
21
	return preg_replace( $pattern, $repl, $content );
22
}
23
24
/**
25
 * Extract all img tags from a given $content block into an array.
26
 *
27
 * @return array An array of matching arrays with two keys: 'url' and 'params'
28
 */
29
function imgix_extract_imgs( $content ) {
30
	preg_match_all( '/src=["\']http.+\/([^\s]+?)["\']/', $content, $matches );
31
	$results = array();
32
33
	if ( $matches ) {
34
		foreach ( $matches[1] as $url ) {
35
			array_push( $results, $url );
36
		}
37
	}
38
39
	return $results;
40
}
41
42
/**
43
 * Searches "$content" for all occurences of "$url" and add the given
44
 * querystring parameters to the URL, preserving existing querystring
45
 * parameters.
46
 *
47
 * @return string Content with matching URLs having the new querystrings.
48
 */
49
function imgix_apply_parameters_to_url( $url, $params, $content ) {
50
	$parts = explode( '?', $url . '?' );
51
52
	list( $base_url, $base_params ) = array( $parts[0], $parts[1] );
53
54
	$new_url = $old_url = $base_url;
55
	$new_url .= '?' . $params;
56
	$new_url .= $base_params ? '&amp;' . $base_params : '';
57
	$old_url .= $base_params ? '?' . $base_params : '';
58
59
	return str_replace( $old_url, $new_url, $content );
60
}
61
62
/**
63
 * Returns a string of global parameters to be applied in all images,
64
 * acording to plugin's settings.
65
 *
66
 * @return string Global parameters to be appened at the end of each img URL.
67
 */
68
function imgix_get_global_params_string() {
69
	global $imgix_options;
70
	$params = array();
71
	// For now, only "auto" is supported.
72
	$auto = array();
73
74
	if ( isset( $imgix_options['auto_format'] ) && $imgix_options['auto_format'] ) {
75
		array_push( $auto, 'format' );
76
	}
77
78
	if ( isset( $imgix_options['auto_enhance'] ) && $imgix_options['auto_enhance'] ) {
79
		array_push( $auto, 'enhance' );
80
	}
81
82
	if ( ! empty( $auto ) ) {
83
		array_push( $params, 'auto=' . implode( '%2C', $auto ) );
84
	}
85
86
	return implode( '&amp;', $params );
87
}
88
89
/**
90
 * Sanitize a given URL to make sure it has a scheme (or alternatively, '//' ),
91
 * host, path, and ends with a '/'.
92
 *
93
 * @return string A sanitized URL.
94
 */
95
function imgix_ensure_valid_url( $url ) {
96
	$slash = strpos( $url, '//' ) == 0 ? '//' : '';
97
98
	if ( $slash ) {
99
		$url = substr( $url, 2 );
100
	}
101
102
	$urlp = wp_parse_url( $url );
103
	$pref = array_key_exists( 'scheme', $urlp ) ? $urlp['scheme'] . '://' : $slash;
104
105
	if ( ! $slash && strpos( $pref, 'http' ) !== 0 ) {
106
		$pref = 'http://';
107
	}
108
109
	$result = $urlp['host'] ? $pref . $urlp['host'] : false;
110
111
	if ( false !== $result ) {
112
		return trailingslashit( $result );
113
	}
114
115
	return null;
116
}
117
118
/**
119
 * Parse through img element src attributes to extract height and width parameters
120
 * based on the structure of the src URL's path.
121
 *
122
 * For example, if we are giving an img src ending in "-400x300.png",
123
 * we return an array structured like so:
124
 *
125
 *    array(array(
126
 *      'raw' => '-400x300.png',
127
 *      'w' => '400',
128
 *      'h' => '300',
129
 *      'type' => 'png',
130
 *      'extra' => ''
131
 *    ))
132
 *
133
 * @return array An array of arrays that has extracted the URL's inferred w',
134
 * 'h', and 'type'
135
 */
136
function imgix_extract_img_details( $content ) {
137
	preg_match_all( '/-([0-9]+)x([0-9]+)\.([^"\']+)/', $content, $matches );
138
139
	$lookup = array( 'raw', 'w', 'h', 'type' );
140
	$data = array();
141
142
	if ( ! is_array($matches) ) {
143
		return $data;
144
	}
145
146
	foreach ( $matches as $k => $v ) {
147
		foreach ( $v as $index => $value ) {
148
			if ( ! array_key_exists( $index, $data ) ) {
149
				$data[ $index ] = array();
150
			}
151
152
			$key = $lookup[ $k ];
153
154
			if ( $key === 'type' ) {
155
				if ( strpos( $value, '?' ) !== false ) {
156
					$parts = explode( '?', $value );
157
					$data[ $index ]['type'] = $parts[0];
158
					$data[ $index ]['extra'] = $parts[1];
159
				} else {
160
					$data[ $index ]['type'] = $value;
161
					$data[ $index ]['extra'] = '';
162
				}
163
			} else {
164
				$data[ $index ][ $key ] = $value;
165
			}
166
		}
167
	}
168
169
	return $data;
170
}
171
172
/**
173
 * Finds references to the wordpress site URL in the given string,
174
 * (optionally prefixed by "src"), and changes them to the imgix URL.
175
 *
176
 * @return array An array countaining the final string, and a boolean value
177
 * indicating if it's different from the given input string.
178
 */
179
function imgix_replace_host( $str, $require_prefix = false ) {
180
	global $imgix_options;
181
182
	if ( ! isset( $imgix_options['cdn_link'] ) || ! $imgix_options['cdn_link'] ) {
183
		return array( $str, false );
184
	}
185
186
	$new_host = imgix_ensure_valid_url( $imgix_options['cdn_link'] );
187
	if ( ! $new_host ) {
188
		return array( $str, false );
189
	}
190
191
	// As soon as srcset is supported…
192
	// $prefix = $require_prefix? 'srcs?e?t?=[\'"]|,[\S+\n\r\s]*': '';
193
	$prefix = $require_prefix ? 'src=[\'"]' : '';
194
	$src = '(' . preg_quote( home_url( '/' ), '/' ) . '|\/\/)';
195
	$patt = '/(' . $prefix . ' )' . $src . '/i';
196
	$str = preg_replace( $patt, '$1' . $new_host, $str, -1, $count );
197
198
	return array( $str, (boolean) $count );
199
}
200
201
function imgix_file_url( $url ) {
202
203
	global $imgix_options;
204
205
	$imgix_url = $imgix_options['cdn_link'];
206
	$file = pathinfo( $url );
207
208
	if ( ! $imgix_url ) {
209
		return $url;
210
	}
211
212
	if ( in_array( $file['extension'], array( 'jpg', 'gif', 'png', 'jpeg' ) ) ) {
213
		return str_replace( get_bloginfo( 'wpurl' ), $imgix_url, $url );
214
	}
215
216
	return $url;
217
}
218
add_filter( 'wp_get_attachment_url', 'imgix_file_url' );
219
add_filter( 'imgix/add-image-url', 'imgix_file_url' );
220
221
/**
222
 *
223
 * @param array         $sources
224
 * @param array         $size_array
225
 * @param string        $image_src
226
 * @param array         $image_meta
227
 * @param $attachment_id
228
 *
229
 * @return array $sources
230
 */
231
function imgix_cdn_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ) {
0 ignored issues
show
Unused Code introduced by
The parameter $size_array is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $image_src is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $image_meta is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $attachment_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
232
233
	foreach ( $sources as $source ) {
234
235
		$sources[ $source['value'] ]['url'] = apply_filters( 'imgix/add-image-url', $sources[ $source['value'] ]['url'] );
236
237
	}
238
239
	return $sources;
240
}
241
add_filter( 'wp_calculate_image_srcset', 'imgix_cdn_srcset', 10, 5 );
242
243
function imgix_replace_non_wp_images( $content ) {
244
	list( $content, $match ) = imgix_replace_host( $content, true );
245
246
	if ( $match ) {
247
		// Apply image-tag-encoded params for every image in $content.
248
		foreach ( imgix_extract_img_details( $content ) as $img ) {
249
			$to_replace = $img['raw'];
250
			$extra_params = $img['extra'] ? '&amp;' . $img['extra'] : '';
251
			$new_url = '.' . $img['type'] . '?h=' . $img['h'] . '&amp;w=' . $img['w'] . $extra_params;
252
			$content = str_replace( $to_replace, $new_url, $content );
253
		}
254
255
		// Apply global parameters.
256
		$g_params = imgix_get_global_params_string();
257
		foreach ( imgix_extract_imgs( $content ) as $img_url ) {
258
			$content = imgix_apply_parameters_to_url( $img_url, $g_params, $content );
259
		}
260
	}
261
	return $content;
262
}
263
264
add_filter( 'the_content', 'imgix_replace_non_wp_images' );
265
266
function imgix_wp_head() {
267
	global $imgix_options;
268
269
	if ( isset( $imgix_options['cdn_link'] ) && $imgix_options['cdn_link'] ) {
270
		printf( "<link rel='dns-prefetch' href='%s'/>",
271
			esc_url( preg_replace( '/^https?:/', '', untrailingslashit( $imgix_options['cdn_link'] ) ) )
272
		);
273
	}
274
}
275
276
add_action( 'wp_head', 'imgix_wp_head', 1 );
277
278
if ( isset( $imgix_options['add_dpi2_srcset'] ) && $imgix_options['add_dpi2_srcset'] ) {
279
	function imgix_buffer_start() {
280
		ob_start( 'imgix_add_retina' );
281
	}
282
283
	function imgix_buffer_end() {
284
		ob_end_flush();
285
	}
286
287
	add_action( 'after_setup_theme', 'imgix_buffer_start' );
288
	add_action( 'shutdown', 'imgix_buffer_end' );
289
	add_filter( 'the_content', 'imgix_add_retina' );
290
}
291