Completed
Push — v2/videopress-sideloading ( 341d44...ce2243 )
by
unknown
09:54
created

functions.photon.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
	/**
16
	 * Allow specific image URls to avoid going through Photon.
17
	 *
18
	 * @module photon
19
	 *
20
	 * @since 3.2.0
21
	 *
22
	 * @param bool false Should the image be returned as is, without going through Photon. Default to false.
23
	 * @param string $image_url Image URL.
24
	 * @param array|string $args Array of Photon arguments.
25
	 * @param string|null $scheme Image scheme. Default to null.
26
	 */
27
	if ( false !== apply_filters( 'jetpack_photon_skip_for_url', false, $image_url, $args, $scheme ) ) {
28
		return $image_url;
29
	}
30
31
	/**
32
	 * Filter the original image URL before it goes through Photon.
33
	 *
34
	 * @module photon
35
	 *
36
	 * @since 1.9.0
37
	 *
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
	$image_url = apply_filters( 'jetpack_photon_pre_image_url', $image_url, $args,      $scheme );
43
	/**
44
	 * Filter the original Photon image parameters before Photon is applied to an image.
45
	 *
46
	 * @module photon
47
	 *
48
	 * @since 1.9.0
49
	 *
50
	 * @param array|string $args Array of Photon arguments.
51
	 * @param string $image_url Image URL.
52
	 * @param string|null $scheme Image scheme. Default to null.
53
	 */
54
	$args      = apply_filters( 'jetpack_photon_pre_args',      $args,      $image_url, $scheme );
0 ignored issues
show
Equals sign not aligned correctly; expected 1 space but found 6 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
55
56
	if ( empty( $image_url ) )
57
		return $image_url;
58
59
	$image_url_parts = @parse_url( $image_url );
60
61
	// Unable to parse
62
	if ( ! is_array( $image_url_parts ) || empty( $image_url_parts['host'] ) || empty( $image_url_parts['path'] ) )
63
		return $image_url;
64
65
	if ( is_array( $args ) ){
66
		// Convert values that are arrays into strings
67
		foreach ( $args as $arg => $value ) {
68
			if ( is_array( $value ) ) {
69
				$args[$arg] = implode( ',', $value );
70
			}
71
		}
72
73
		// Encode values
74
		// See http://core.trac.wordpress.org/ticket/17923
75
		$args = rawurlencode_deep( $args );
76
	}
77
78
	/** This filter is documented below. */
79
	$custom_photon_url = apply_filters( 'jetpack_photon_domain', '', $image_url );
80
	$custom_photon_url = esc_url( $custom_photon_url );
81
82
	// You can't run a Photon URL through Photon again because query strings are stripped.
83
	// So if the image is already a Photon URL, append the new arguments to the existing URL.
84
	if (
85
		in_array( $image_url_parts['host'], array( 'i0.wp.com', 'i1.wp.com', 'i2.wp.com' ) )
86
		|| $image_url_parts['host'] === parse_url( $custom_photon_url, PHP_URL_HOST )
87
	) {
88
		$photon_url = add_query_arg( $args, $image_url );
89
		return jetpack_photon_url_scheme( $photon_url, $scheme );
90
	}
91
92
	/**
93
	 * Allow Photon to use query strings as well.
94
	 * By default, Photon doesn't support query strings so we ignore them and look only at the path.
95
	 * This setting is Photon Server dependent.
96
	 *
97
	 * @module photon
98
	 *
99
	 * @since 1.9.0
100
	 *
101
	 * @param bool false Should images using query strings go through Photon. Default is false.
102
	 * @param string $image_url_parts['host'] Image URL's host.
103
	 */
104
	if ( ! apply_filters( 'jetpack_photon_any_extension_for_domain', false, $image_url_parts['host'] ) ) {
105
		// Photon doesn't support query strings so we ignore them and look only at the path.
106
		// However some source images are served via PHP so check the no-query-string extension.
107
		// For future proofing, this is a blacklist of common issues rather than a whitelist.
108
		$extension = pathinfo( $image_url_parts['path'], PATHINFO_EXTENSION );
109
		if ( empty( $extension ) || in_array( $extension, array( 'php' ) ) )
110
			return $image_url;
111
	}
112
113
	$image_host_path = $image_url_parts['host'] . $image_url_parts['path'];
114
115
	// Figure out which CDN subdomain to use
116
	srand( crc32( $image_host_path ) );
117
	$subdomain = rand( 0, 2 );
118
	srand();
119
120
	/**
121
	 * Filters the domain used by the Photon module.
122
	 *
123
	 * @module photon
124
	 *
125
	 * @since 3.4.2
126
	 *
127
	 * @param string http://i{$subdomain}.wp.com Domain used by Photon. $subdomain is a random number between 0 and 2.
128
	 * @param string $image_url URL of the image to be photonized.
129
	 */
130
	$photon_domain = apply_filters( 'jetpack_photon_domain', "http://i{$subdomain}.wp.com", $image_url );
131
	$photon_domain = trailingslashit( esc_url( $photon_domain ) );
132
	$photon_url  = $photon_domain . $image_host_path;
133
134
	/**
135
	 * Add query strings to Photon URL.
136
	 * By default, Photon doesn't support query strings so we ignore them.
137
	 * This setting is Photon Server dependent.
138
	 *
139
	 * @module photon
140
	 *
141
	 * @since 1.9.0
142
	 *
143
	 * @param bool false Should query strings be added to the image URL. Default is false.
144
	 * @param string $image_url_parts['host'] Image URL's host.
145
	 */
146
	if ( isset( $image_url_parts['query'] ) && apply_filters( 'jetpack_photon_add_query_string_to_domain', false, $image_url_parts['host'] ) ) {
147
		$photon_url .= '?q=' . rawurlencode( $image_url_parts['query'] );
148
	}
149
150
	if ( $args ) {
151
		if ( is_array( $args ) ) {
152
			$photon_url = add_query_arg( $args, $photon_url );
153
		} else {
154
			// You can pass a query string for complicated requests but where you still want CDN subdomain help, etc.
155
			$photon_url .= '?' . $args;
156
		}
157
	}
158
159
	return jetpack_photon_url_scheme( $photon_url, $scheme );
160
}
161
add_filter( 'jetpack_photon_url', 'jetpack_photon_url', 10, 3 );
162
163
/**
164
 * WordPress.com
165
 *
166
 * If a cropped WP.com-hosted image is the source image, have Photon replicate the crop.
167
 */
168
add_filter( 'jetpack_photon_pre_args', 'jetpack_photon_parse_wpcom_query_args', 10, 2 );
169
170
function jetpack_photon_parse_wpcom_query_args( $args, $image_url ) {
171
	$parsed_url = @parse_url( $image_url );
172
173
	if ( ! $parsed_url )
174
		return $args;
175
176
	$image_url_parts = wp_parse_args( $parsed_url, array(
177
		'host'  => '',
178
		'query' => ''
179
	) );
180
181
	if ( '.files.wordpress.com' != substr( $image_url_parts['host'], -20 ) )
182
		return $args;
183
184
	if ( empty( $image_url_parts['query'] ) )
185
		return $args;
186
187
	$wpcom_args = wp_parse_args( $image_url_parts['query'] );
188
189
	if ( empty( $wpcom_args['w'] ) || empty( $wpcom_args['h'] ) )
190
		return $args;
191
192
	// Keep the crop by using "resize"
193
	if ( ! empty( $wpcom_args['crop'] ) ) {
194 View Code Duplication
		if ( is_array( $args ) ) {
195
			$args = array_merge( array( 'resize' => array( $wpcom_args['w'], $wpcom_args['h'] ) ), $args );
196
		} else {
197
			$args = 'resize=' . rawurlencode( absint( $wpcom_args['w'] ) . ',' . absint( $wpcom_args['h'] ) ) . '&' . $args;
198
		}
199 View Code Duplication
	} else {
200
		if ( is_array( $args ) ) {
201
			$args = array_merge( array( 'fit' => array( $wpcom_args['w'], $wpcom_args['h'] ) ), $args );
202
		} else {
203
			$args = 'fit=' . rawurlencode( absint( $wpcom_args['w'] ) . ',' . absint( $wpcom_args['h'] ) ) . '&' . $args;
204
		}
205
	}
206
207
	return $args;
208
}
209
210
211
/**
212
 * Facebook
213
 */
214
add_filter( 'jetpack_photon_add_query_string_to_domain', 'jetpack_photon_allow_facebook_graph_domain', 10, 2 );
215
add_filter( 'jetpack_photon_any_extension_for_domain',   'jetpack_photon_allow_facebook_graph_domain', 10, 2 );
216
217
function jetpack_photon_url_scheme( $url, $scheme ) {
218
	if ( ! in_array( $scheme, array( 'http', 'https', 'network_path' ) ) ) {
219
		$scheme = is_ssl() ? 'https' : 'http';
220
	}
221
222
	if ( 'network_path' == $scheme ) {
223
		$scheme_slashes = '//';
224
	} else {
225
		$scheme_slashes = "$scheme://";
226
	}
227
228
	return preg_replace( '#^[a-z:]+//#i', $scheme_slashes, $url );
229
}
230
231
function jetpack_photon_allow_facebook_graph_domain( $allow = false, $domain ) {
232
	switch ( $domain ) {
233
	case 'graph.facebook.com' :
234
		return true;
235
	}
236
237
	return $allow;
238
}
239
240
add_filter( 'jetpack_photon_skip_for_url', 'jetpack_photon_banned_domains', 9, 4 );
241
function jetpack_photon_banned_domains( $skip, $image_url, $args, $scheme ) {
242
	$banned_domains = array(
243
		'http://chart.googleapis.com/',
244
		'https://chart.googleapis.com/',
245
		'http://chart.apis.google.com/',
246
	);
247
248
	foreach ( $banned_domains as $banned_domain ) {
249
		if ( wp_startswith( $image_url, $banned_domain ) )
250
			return true;
251
	}
252
253
	return $skip;
254
}
255