Completed
Push — add/geo-location-support ( 007f25...6296b5 )
by Brad
29:34 queued 17:46
created

functions.photon.php ➔ jetpack_photon_url()   F

Complexity

Conditions 26
Paths 319

Size

Total Lines 180
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 26
eloc 53
nc 319
nop 3
dl 0
loc 180
rs 3.5303
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Generates a Photon URL.
5
 *
6
 * @see http://developer.wordpress.com/docs/photon/
7
 *
8
 * @param string $image_url URL to the publicly accessible image you want to manipulate
9
 * @param array|string $args An array of arguments, i.e. array( 'w' => '300', 'resize' => array( 123, 456 ) ), or in string form (w=123&h=456)
10
 * @return string The raw final URL. You should run this through esc_url() before displaying it.
11
 */
12
function jetpack_photon_url( $image_url, $args = array(), $scheme = null ) {
13
	$image_url = trim( $image_url );
14
15
	if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
16
		/**
17
		 * Disables Photon URL processing for local development
18
		 *
19
		 * @module photon
20
		 *
21
		 * @since 4.1.0
22
		 *
23
		 * @param bool false Result of Jetpack::is_development_mode.
24
		 */
25
		if ( true === apply_filters( 'jetpack_photon_development_mode', Jetpack::is_development_mode() ) ) {
26
			return $image_url;
27
		}
28
	}
29
30
	/**
31
	 * Allow specific image URls to avoid going through Photon.
32
	 *
33
	 * @module photon
34
	 *
35
	 * @since 3.2.0
36
	 *
37
	 * @param bool false Should the image be returned as is, without going through Photon. Default to false.
38
	 * @param string $image_url Image URL.
39
	 * @param array|string $args Array of Photon arguments.
40
	 * @param string|null $scheme Image scheme. Default to null.
41
	 */
42
	if ( false !== apply_filters( 'jetpack_photon_skip_for_url', false, $image_url, $args, $scheme ) ) {
43
		return $image_url;
44
	}
45
46
	/**
47
	 * Filter the original image URL before it goes through Photon.
48
	 *
49
	 * @module photon
50
	 *
51
	 * @since 1.9.0
52
	 *
53
	 * @param string $image_url Image URL.
54
	 * @param array|string $args Array of Photon arguments.
55
	 * @param string|null $scheme Image scheme. Default to null.
56
	 */
57
	$image_url = apply_filters( 'jetpack_photon_pre_image_url', $image_url, $args, $scheme );
58
	/**
59
	 * Filter the original Photon image parameters before Photon is applied to an image.
60
	 *
61
	 * @module photon
62
	 *
63
	 * @since 1.9.0
64
	 *
65
	 * @param array|string $args Array of Photon arguments.
66
	 * @param string $image_url Image URL.
67
	 * @param string|null $scheme Image scheme. Default to null.
68
	 */
69
	$args = apply_filters( 'jetpack_photon_pre_args', $args, $image_url, $scheme );
70
71
	if ( empty( $image_url ) )
72
		return $image_url;
73
74
	$image_url_parts = @jetpack_photon_parse_url( $image_url );
75
76
	// Unable to parse
77
	if ( ! is_array( $image_url_parts ) || empty( $image_url_parts['host'] ) || empty( $image_url_parts['path'] ) )
78
		return $image_url;
79
80
	if ( is_array( $args ) ){
81
		// Convert values that are arrays into strings
82
		foreach ( $args as $arg => $value ) {
83
			if ( is_array( $value ) ) {
84
				$args[$arg] = implode( ',', $value );
85
			}
86
		}
87
88
		// Encode values
89
		// See http://core.trac.wordpress.org/ticket/17923
90
		$args = rawurlencode_deep( $args );
91
	}
92
93
	// Don't photon-ize WPCOM hosted images -- we can serve them up from wpcom directly.
94
	$is_wpcom_image = false;
95
	if ( wp_endswith( strtolower( $image_url_parts['host'] ), '.files.wordpress.com' ) ) {
96
		$is_wpcom_image = true;
97
		if ( isset( $args['ssl'] ) ) {
98
			// Do not send the ssl argument to prevent caching issues
99
			unset( $args['ssl'] );
100
		}
101
	}
102
103
	/** This filter is documented below. */
104
	$custom_photon_url = apply_filters( 'jetpack_photon_domain', '', $image_url );
105
	$custom_photon_url = esc_url( $custom_photon_url );
106
107
	// You can't run a Photon URL through Photon again because query strings are stripped.
108
	// So if the image is already a Photon URL, append the new arguments to the existing URL.
109
	// Alternately, if it's a *.files.wordpress.com url, then keep the domain as is.
110
	if (
111
		in_array( $image_url_parts['host'], array( 'i0.wp.com', 'i1.wp.com', 'i2.wp.com' ) )
112
		|| $image_url_parts['host'] === jetpack_photon_parse_url( $custom_photon_url, PHP_URL_HOST )
113
		|| $is_wpcom_image
114
	) {
115
		$photon_url = add_query_arg( $args, $image_url );
116
		return jetpack_photon_url_scheme( $photon_url, $scheme );
117
	}
118
119
	/**
120
	 * Allow Photon to use query strings as well.
121
	 * By default, Photon doesn't support query strings so we ignore them and look only at the path.
122
	 * This setting is Photon Server dependent.
123
	 *
124
	 * @module photon
125
	 *
126
	 * @since 1.9.0
127
	 *
128
	 * @param bool false Should images using query strings go through Photon. Default is false.
129
	 * @param string $image_url_parts['host'] Image URL's host.
130
	 */
131
	if ( ! apply_filters( 'jetpack_photon_any_extension_for_domain', false, $image_url_parts['host'] ) ) {
132
		// Photon doesn't support query strings so we ignore them and look only at the path.
133
		// However some source images are served via PHP so check the no-query-string extension.
134
		// For future proofing, this is a blacklist of common issues rather than a whitelist.
135
		$extension = pathinfo( $image_url_parts['path'], PATHINFO_EXTENSION );
136
		if ( empty( $extension ) || in_array( $extension, array( 'php', 'ashx' ) ) )
137
			return $image_url;
138
	}
139
140
	$image_host_path = $image_url_parts['host'] . $image_url_parts['path'];
141
142
	// Figure out which CDN subdomain to use
143
	srand( crc32( $image_host_path ) );
144
	$subdomain = rand( 0, 2 );
145
	srand();
146
147
	/**
148
	 * Filters the domain used by the Photon module.
149
	 *
150
	 * @module photon
151
	 *
152
	 * @since 3.4.2
153
	 *
154
	 * @param string https://i{$subdomain}.wp.com Domain used by Photon. $subdomain is a random number between 0 and 2.
155
	 * @param string $image_url URL of the image to be photonized.
156
	 */
157
	$photon_domain = apply_filters( 'jetpack_photon_domain', "https://i{$subdomain}.wp.com", $image_url );
158
	$photon_domain = trailingslashit( esc_url( $photon_domain ) );
159
	$photon_url  = $photon_domain . $image_host_path;
160
161
	/**
162
	 * Add query strings to Photon URL.
163
	 * By default, Photon doesn't support query strings so we ignore them.
164
	 * This setting is Photon Server dependent.
165
	 *
166
	 * @module photon
167
	 *
168
	 * @since 1.9.0
169
	 *
170
	 * @param bool false Should query strings be added to the image URL. Default is false.
171
	 * @param string $image_url_parts['host'] Image URL's host.
172
	 */
173
	if ( isset( $image_url_parts['query'] ) && apply_filters( 'jetpack_photon_add_query_string_to_domain', false, $image_url_parts['host'] ) ) {
174
		$photon_url .= '?q=' . rawurlencode( $image_url_parts['query'] );
175
	}
176
177
	if ( $args ) {
178
		if ( is_array( $args ) ) {
179
			$photon_url = add_query_arg( $args, $photon_url );
180
		} else {
181
			// You can pass a query string for complicated requests but where you still want CDN subdomain help, etc.
182
			$photon_url .= '?' . $args;
183
		}
184
	}
185
186
	if ( isset( $image_url_parts['scheme'] ) && 'https' == $image_url_parts['scheme'] ) {
187
		$photon_url = add_query_arg( array( 'ssl' => 1 ), $photon_url );
188
	}
189
190
	return jetpack_photon_url_scheme( $photon_url, $scheme );
191
}
192
add_filter( 'jetpack_photon_url', 'jetpack_photon_url', 10, 3 );
193
194
/**
195
 * WordPress.com
196
 *
197
 * If a cropped WP.com-hosted image is the source image, have Photon replicate the crop.
198
 */
199
add_filter( 'jetpack_photon_pre_args', 'jetpack_photon_parse_wpcom_query_args', 10, 2 );
200
201
function jetpack_photon_parse_wpcom_query_args( $args, $image_url ) {
202
	$parsed_url = @parse_url( $image_url );
203
204
	if ( ! $parsed_url )
205
		return $args;
206
207
	$image_url_parts = wp_parse_args( $parsed_url, array(
208
		'host'  => '',
209
		'query' => ''
210
	) );
211
212
	if ( '.files.wordpress.com' != substr( $image_url_parts['host'], -20 ) )
213
		return $args;
214
215
	if ( empty( $image_url_parts['query'] ) )
216
		return $args;
217
218
	$wpcom_args = wp_parse_args( $image_url_parts['query'] );
219
220
	if ( empty( $wpcom_args['w'] ) || empty( $wpcom_args['h'] ) )
221
		return $args;
222
223
	// Keep the crop by using "resize"
224
	if ( ! empty( $wpcom_args['crop'] ) ) {
225 View Code Duplication
		if ( is_array( $args ) ) {
226
			$args = array_merge( array( 'resize' => array( $wpcom_args['w'], $wpcom_args['h'] ) ), $args );
227
		} else {
228
			$args = 'resize=' . rawurlencode( absint( $wpcom_args['w'] ) . ',' . absint( $wpcom_args['h'] ) ) . '&' . $args;
229
		}
230 View Code Duplication
	} else {
231
		if ( is_array( $args ) ) {
232
			$args = array_merge( array( 'fit' => array( $wpcom_args['w'], $wpcom_args['h'] ) ), $args );
233
		} else {
234
			$args = 'fit=' . rawurlencode( absint( $wpcom_args['w'] ) . ',' . absint( $wpcom_args['h'] ) ) . '&' . $args;
235
		}
236
	}
237
238
	return $args;
239
}
240
241
function jetpack_photon_url_scheme( $url, $scheme ) {
242
	if ( ! in_array( $scheme, array( 'http', 'https', 'network_path' ) ) ) {
243
		if ( preg_match( '#^(https?:)?//#', $url ) ) {
244
			return $url;
245
		}
246
247
		$scheme = 'http';
248
	}
249
250
	if ( 'network_path' == $scheme ) {
251
		$scheme_slashes = '//';
252
	} else {
253
		$scheme_slashes = "$scheme://";
254
	}
255
256
	return preg_replace( '#^([a-z:]+)?//#i', $scheme_slashes, $url );
257
}
258
259
/**
260
 * A wrapper for PHP's parse_url, prepending assumed scheme for network path
261
 * URLs. PHP versions 5.4.6 and earlier do not correctly parse without scheme.
262
 *
263
 * @see http://php.net/manual/en/function.parse-url.php#refsect1-function.parse-url-changelog
264
 *
265
 * @param string $url The URL to parse
266
 * @param integer $component Retrieve specific URL component
267
 * @return mixed Result of parse_url
268
 */
269
function jetpack_photon_parse_url( $url, $component = -1 ) {
270
	if ( 0 === strpos( $url, '//' ) ) {
271
		$url = ( is_ssl() ? 'https:' : 'http:' ) . $url;
272
	}
273
274
	return parse_url( $url, $component );
275
}
276
277
add_filter( 'jetpack_photon_skip_for_url', 'jetpack_photon_banned_domains', 9, 2 );
278
function jetpack_photon_banned_domains( $skip, $image_url ) {
279
	$banned_host_patterns = array(
280
		'/^chart\.googleapis\.com$/',
281
		'/^chart\.apis\.google\.com$/',
282
		'/^graph\.facebook\.com$/',
283
		'/\.fbcdn\.net$/'
284
	);
285
286
	$host = jetpack_photon_parse_url( $image_url, PHP_URL_HOST );
287
288
	foreach ( $banned_host_patterns as $banned_host_pattern ) {
289
		if ( 1 === preg_match( $banned_host_pattern, $host ) ) {
290
			return true;
291
		}
292
	}
293
294
	return $skip;
295
}
296
297
298
/**
299
 * Jetpack Photon - Support Text Widgets.
300
 *
301
 * @access public
302
 * @param string $content Content from text widget.
303
 * @return string
304
 */
305
function jetpack_photon_support_text_widgets( $content ) {
306
	if ( class_exists( 'Jetpack_Photon' ) && Jetpack::is_module_active( 'photon' ) ) {
307
		return Jetpack_Photon::filter_the_content( $content );
308
	}
309
	return $content;
310
}
311
add_filter( 'widget_text', 'jetpack_photon_support_text_widgets' );
312