Completed
Push — merge/functions-photon ( 908584...10fdaa )
by
unknown
60:05 queued 48:11
created

functions.photon.php ➔ jetpack_photon_url()   F

Complexity

Conditions 26
Paths 343

Size

Total Lines 180
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 26
eloc 53
nc 343
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 ( isset( $image_url_parts['scheme'] ) && 'https' == $image_url_parts['scheme'] ) {
81
		$args['ssl'] = '1';
82
	}
83
84
	if ( is_array( $args ) ){
85
		// Convert values that are arrays into strings
86
		foreach ( $args as $arg => $value ) {
87
			if ( is_array( $value ) ) {
88
				$args[$arg] = implode( ',', $value );
89
			}
90
		}
91
92
		// Encode values
93
		// See http://core.trac.wordpress.org/ticket/17923
94
		$args = rawurlencode_deep( $args );
95
	}
96
97
	// Don't photon-ize WPCOM hosted images -- we can serve them up from wpcom directly.
98
	$is_wpcom_image = false;
99
	if ( wp_endswith( strtolower( $image_url_parts['host'] ), '.files.wordpress.com' ) ) {
100
		$is_wpcom_image = true;
101
		if ( isset( $args['ssl'] ) ) {
102
			// Do not send the ssl argument to prevent caching issues
103
			unset( $args['ssl'] );
104
		}
105
	}
106
107
	/** This filter is documented below. */
108
	$custom_photon_url = apply_filters( 'jetpack_photon_domain', '', $image_url );
109
	$custom_photon_url = esc_url( $custom_photon_url );
110
111
	// You can't run a Photon URL through Photon again because query strings are stripped.
112
	// So if the image is already a Photon URL, append the new arguments to the existing URL.
113
	// Alternately, if it's a *.files.wordpress.com url, then keep the domain as is.
114
	if (
115
		in_array( $image_url_parts['host'], array( 'i0.wp.com', 'i1.wp.com', 'i2.wp.com' ) )
116
		|| $image_url_parts['host'] === jetpack_photon_parse_url( $custom_photon_url, PHP_URL_HOST )
117
		|| $is_wpcom_image
118
	) {
119
		$photon_url = add_query_arg( $args, $image_url );
120
		return jetpack_photon_url_scheme( $photon_url, $scheme );
121
	}
122
123
	/**
124
	 * Allow Photon to use query strings as well.
125
	 * By default, Photon doesn't support query strings so we ignore them and look only at the path.
126
	 * This setting is Photon Server dependent.
127
	 *
128
	 * @module photon
129
	 *
130
	 * @since 1.9.0
131
	 *
132
	 * @param bool false Should images using query strings go through Photon. Default is false.
133
	 * @param string $image_url_parts['host'] Image URL's host.
134
	 */
135
	if ( ! apply_filters( 'jetpack_photon_any_extension_for_domain', false, $image_url_parts['host'] ) ) {
136
		// Photon doesn't support query strings so we ignore them and look only at the path.
137
		// However some source images are served via PHP so check the no-query-string extension.
138
		// For future proofing, this is a blacklist of common issues rather than a whitelist.
139
		$extension = pathinfo( $image_url_parts['path'], PATHINFO_EXTENSION );
140
		if ( empty( $extension ) || in_array( $extension, array( 'php', 'ashx' ) ) )
141
			return $image_url;
142
	}
143
144
	$image_host_path = $image_url_parts['host'] . $image_url_parts['path'];
145
146
	// Figure out which CDN subdomain to use
147
	srand( crc32( $image_host_path ) );
148
	$subdomain = rand( 0, 2 );
149
	srand();
150
151
	/**
152
	 * Filters the domain used by the Photon module.
153
	 *
154
	 * @module photon
155
	 *
156
	 * @since 3.4.2
157
	 *
158
	 * @param string https://i{$subdomain}.wp.com Domain used by Photon. $subdomain is a random number between 0 and 2.
159
	 * @param string $image_url URL of the image to be photonized.
160
	 */
161
	$photon_domain = apply_filters( 'jetpack_photon_domain', "https://i{$subdomain}.wp.com", $image_url );
162
	$photon_domain = trailingslashit( esc_url( $photon_domain ) );
163
	$photon_url  = $photon_domain . $image_host_path;
164
165
	/**
166
	 * Add query strings to Photon URL.
167
	 * By default, Photon doesn't support query strings so we ignore them.
168
	 * This setting is Photon Server dependent.
169
	 *
170
	 * @module photon
171
	 *
172
	 * @since 1.9.0
173
	 *
174
	 * @param bool false Should query strings be added to the image URL. Default is false.
175
	 * @param string $image_url_parts['host'] Image URL's host.
176
	 */
177
	if ( isset( $image_url_parts['query'] ) && apply_filters( 'jetpack_photon_add_query_string_to_domain', false, $image_url_parts['host'] ) ) {
178
		$photon_url .= '?q=' . rawurlencode( $image_url_parts['query'] );
179
	}
180
181
	if ( $args ) {
182
		if ( is_array( $args ) ) {
183
			$photon_url = add_query_arg( $args, $photon_url );
184
		} else {
185
			// You can pass a query string for complicated requests but where you still want CDN subdomain help, etc.
186
			$photon_url .= '?' . $args;
187
		}
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
		$scheme = is_ssl() ? 'https' : 'http';
244
	}
245
246
	if ( 'network_path' == $scheme ) {
247
		$scheme_slashes = '//';
248
	} else {
249
		$scheme_slashes = "$scheme://";
250
	}
251
252
	return preg_replace( '#^[a-z:]+//#i', $scheme_slashes, $url );
253
}
254
255
/**
256
 * A wrapper for PHP's parse_url, prepending assumed scheme for network path
257
 * URLs. PHP versions 5.4.6 and earlier do not correctly parse without scheme.
258
 *
259
 * @see http://php.net/manual/en/function.parse-url.php#refsect1-function.parse-url-changelog
260
 *
261
 * @param string $url The URL to parse
262
 * @param integer $component Retrieve specific URL component
263
 * @return mixed Result of parse_url
264
 */
265
function jetpack_photon_parse_url( $url, $component = -1 ) {
266
	if ( 0 === strpos( $url, '//' ) ) {
267
		$url = ( is_ssl() ? 'https:' : 'http:' ) . $url;
268
	}
269
270
	return parse_url( $url, $component );
271
}
272
273
add_filter( 'jetpack_photon_skip_for_url', 'jetpack_photon_banned_domains', 9, 2 );
274
function jetpack_photon_banned_domains( $skip, $image_url ) {
275
	$banned_host_patterns = array(
276
		'/^chart\.googleapis\.com$/',
277
		'/^chart\.apis\.google\.com$/',
278
		'/^graph\.facebook\.com$/',
279
		'/\.fbcdn\.net$/'
280
	);
281
282
	$host = jetpack_photon_parse_url( $image_url, PHP_URL_HOST );
283
284
	foreach ( $banned_host_patterns as $banned_host_pattern ) {
285
		if ( 1 === preg_match( $banned_host_pattern, $host ) ) {
286
			return true;
287
		}
288
	}
289
290
	return $skip;
291
}
292
293
294
/**
295
 * Jetpack Photon - Support Text Widgets.
296
 *
297
 * @access public
298
 * @param string $content Content from text widget.
299
 * @return string
300
 */
301
function jetpack_photon_support_text_widgets( $content ) {
302
	if ( class_exists( 'Jetpack_Photon' ) && Jetpack::is_module_active( 'photon' ) ) {
303
		return Jetpack_Photon::filter_the_content( $content );
304
	}
305
	return $content;
306
}
307
add_filter( 'widget_text', 'jetpack_photon_support_text_widgets' );
308