PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 11.1.1
Jetpack – WP Security, Backup, Speed, & Growth v11.1.1
15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / functions.photon.php
jetpack Last commit date
3rd-party 4 years ago _inc 3 years ago css 3 years ago extensions 3 years ago images 3 years ago jetpack_vendor 3 years ago json-endpoints 3 years ago modules 3 years ago sal 4 years ago src 4 years ago vendor 3 years ago views 4 years ago CHANGELOG.md 3 years ago LICENSE.txt 5 years ago SECURITY.md 5 years ago class-jetpack-connection-status.php 5 years ago class-jetpack-gallery-settings.php 4 years ago class-jetpack-pre-connection-jitms.php 4 years ago class-jetpack-recommendations-banner.php 3 years ago class-jetpack-stats-dashboard-widget.php 4 years ago class-jetpack-wizard-banner.php 5 years ago class-jetpack-xmlrpc-methods.php 4 years ago class.frame-nonce-preview.php 4 years ago class.jetpack-admin.php 3 years ago class.jetpack-affiliate.php 4 years ago class.jetpack-autoupdate.php 4 years ago class.jetpack-bbpress-json-api.compat.php 5 years ago class.jetpack-cli.php 3 years ago class.jetpack-client-server.php 4 years ago class.jetpack-connection-banner.php 3 years ago class.jetpack-data.php 5 years ago class.jetpack-gutenberg.php 3 years ago class.jetpack-heartbeat.php 4 years ago class.jetpack-idc.php 4 years ago class.jetpack-modules-list-table.php 4 years ago class.jetpack-network-sites-list-table.php 4 years ago class.jetpack-network.php 4 years ago class.jetpack-plan.php 3 years ago class.jetpack-post-images.php 3 years ago class.jetpack-twitter-cards.php 4 years ago class.jetpack-user-agent.php 4 years ago class.jetpack.php 3 years ago class.json-api-endpoints.php 4 years ago class.json-api.php 3 years ago class.photon.php 3 years ago composer.json 3 years ago enhanced-open-graph.php 4 years ago functions.compat.php 4 years ago functions.cookies.php 5 years ago functions.global.php 4 years ago functions.opengraph.php 4 years ago functions.photon.php 4 years ago jetpack.php 3 years ago json-api-config.php 5 years ago json-endpoints.php 4 years ago load-jetpack.php 4 years ago locales.php 4 years ago readme.txt 3 years ago require-lib.php 4 years ago uninstall.php 5 years ago wpml-config.xml 3 years ago
functions.photon.php
343 lines
1 <?php
2 /**
3 * Generic functions using the Photon service.
4 *
5 * Some are used outside of the Photon module being active, so intentionally not within the module.
6 *
7 * @package automattic/jetpack
8 */
9
10 use Automattic\Jetpack\Status;
11
12 /**
13 * Generates a Photon URL.
14 *
15 * @see https://developer.wordpress.com/docs/photon/
16 *
17 * @param string $image_url URL to the publicly accessible image you want to manipulate.
18 * @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).
19 * @param string|null $scheme URL protocol.
20 * @return string The raw final URL. You should run this through esc_url() before displaying it.
21 */
22 function jetpack_photon_url( $image_url, $args = array(), $scheme = null ) {
23 $image_url = trim( $image_url );
24
25 if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
26 /**
27 * Disables Photon URL processing for local development
28 *
29 * @module photon
30 *
31 * @since 4.1.0
32 *
33 * @param bool false Result of Automattic\Jetpack\Status->is_offline_mode().
34 */
35 if ( true === apply_filters( 'jetpack_photon_development_mode', ( new Status() )->is_offline_mode() ) ) {
36 return $image_url;
37 }
38 }
39
40 /**
41 * Allow specific image URls to avoid going through Photon.
42 *
43 * @module photon
44 *
45 * @since 3.2.0
46 *
47 * @param bool false Should the image be returned as is, without going through Photon. Default to false.
48 * @param string $image_url Image URL.
49 * @param array|string $args Array of Photon arguments.
50 * @param string|null $scheme Image scheme. Default to null.
51 */
52 if ( false !== apply_filters( 'jetpack_photon_skip_for_url', false, $image_url, $args, $scheme ) ) {
53 return $image_url;
54 }
55
56 /**
57 * Filter the original image URL before it goes through Photon.
58 *
59 * @module photon
60 *
61 * @since 1.9.0
62 *
63 * @param string $image_url Image URL.
64 * @param array|string $args Array of Photon arguments.
65 * @param string|null $scheme Image scheme. Default to null.
66 */
67 $image_url = apply_filters( 'jetpack_photon_pre_image_url', $image_url, $args, $scheme );
68 /**
69 * Filter the original Photon image parameters before Photon is applied to an image.
70 *
71 * @module photon
72 *
73 * @since 1.9.0
74 *
75 * @param array|string $args Array of Photon arguments.
76 * @param string $image_url Image URL.
77 * @param string|null $scheme Image scheme. Default to null.
78 */
79 $args = apply_filters( 'jetpack_photon_pre_args', $args, $image_url, $scheme );
80
81 if ( empty( $image_url ) ) {
82 return $image_url;
83 }
84
85 $image_url_parts = wp_parse_url( $image_url );
86
87 // Unable to parse.
88 if ( ! is_array( $image_url_parts ) || empty( $image_url_parts['host'] ) || empty( $image_url_parts['path'] ) ) {
89 return $image_url;
90 }
91
92 if ( is_array( $args ) ) {
93 // Convert values that are arrays into strings.
94 foreach ( $args as $arg => $value ) {
95 if ( is_array( $value ) ) {
96 $args[ $arg ] = implode( ',', $value );
97 }
98 }
99
100 // Encode values.
101 // See https://core.trac.wordpress.org/ticket/17923 .
102 $args = rawurlencode_deep( $args );
103 }
104
105 // Don't photon-ize WPCOM hosted images -- we can serve them up from wpcom directly.
106 $is_wpcom_image = false;
107 if ( wp_endswith( strtolower( $image_url_parts['host'] ), '.files.wordpress.com' ) ) {
108 $is_wpcom_image = true;
109 if ( isset( $args['ssl'] ) ) {
110 // Do not send the ssl argument to prevent caching issues.
111 unset( $args['ssl'] );
112 }
113 }
114
115 /** This filter is documented below. */
116 $custom_photon_url = apply_filters( 'jetpack_photon_domain', '', $image_url );
117 $custom_photon_url = esc_url( $custom_photon_url );
118
119 // You can't run a Photon URL through Photon again because query strings are stripped.
120 // So if the image is already a Photon URL, append the new arguments to the existing URL.
121 // Alternately, if it's a *.files.wordpress.com url, then keep the domain as is.
122 if (
123 in_array( $image_url_parts['host'], array( 'i0.wp.com', 'i1.wp.com', 'i2.wp.com' ), true )
124 || wp_parse_url( $custom_photon_url, PHP_URL_HOST ) === $image_url_parts['host']
125 || $is_wpcom_image
126 ) {
127 $photon_url = add_query_arg( $args, $image_url );
128 return jetpack_photon_url_scheme( $photon_url, $scheme );
129 }
130
131 /**
132 * Allow Photon to use query strings as well.
133 * By default, Photon doesn't support query strings so we ignore them and look only at the path.
134 * This setting is Photon Server dependent.
135 *
136 * @module photon
137 *
138 * @since 1.9.0
139 *
140 * @param bool false Should images using query strings go through Photon. Default is false.
141 * @param string $image_url_parts['host'] Image URL's host.
142 */
143 if ( ! apply_filters( 'jetpack_photon_any_extension_for_domain', false, $image_url_parts['host'] ) ) {
144 // Photon doesn't support query strings so we ignore them and look only at the path.
145 // However some source images are served via PHP so check the no-query-string extension.
146 // For future proofing, this is an excluded list of common issues rather than an allow list.
147 $extension = pathinfo( $image_url_parts['path'], PATHINFO_EXTENSION );
148 if ( empty( $extension ) || in_array( $extension, array( 'php', 'ashx' ), true ) ) {
149 return $image_url;
150 }
151 }
152
153 $image_host_path = $image_url_parts['host'] . $image_url_parts['path'];
154
155 /**
156 * Filters the domain used by the Photon module.
157 *
158 * @module photon
159 *
160 * @since 3.4.2
161 *
162 * @param string https://i0.wp.com Domain used by Photon.
163 * @param string $image_url URL of the image to be photonized.
164 */
165 $photon_domain = apply_filters( 'jetpack_photon_domain', 'https://i0.wp.com', $image_url );
166 $photon_domain = trailingslashit( esc_url( $photon_domain ) );
167 $photon_url = $photon_domain . $image_host_path;
168
169 /**
170 * Add query strings to Photon URL.
171 * By default, Photon doesn't support query strings so we ignore them.
172 * This setting is Photon Server dependent.
173 *
174 * @module photon
175 *
176 * @since 1.9.0
177 *
178 * @param bool false Should query strings be added to the image URL. Default is false.
179 * @param string $image_url_parts['host'] Image URL's host.
180 */
181 if ( isset( $image_url_parts['query'] ) && apply_filters( 'jetpack_photon_add_query_string_to_domain', false, $image_url_parts['host'] ) ) {
182 $photon_url .= '?q=' . rawurlencode( $image_url_parts['query'] );
183 }
184
185 if ( $args ) {
186 if ( is_array( $args ) ) {
187 $photon_url = add_query_arg( $args, $photon_url );
188 } else {
189 // You can pass a query string for complicated requests but where you still want CDN subdomain help, etc.
190 $photon_url .= '?' . $args;
191 }
192 }
193
194 if ( isset( $image_url_parts['scheme'] ) && 'https' === $image_url_parts['scheme'] ) {
195 $photon_url = add_query_arg( array( 'ssl' => 1 ), $photon_url );
196 }
197
198 return jetpack_photon_url_scheme( $photon_url, $scheme );
199 }
200
201 /**
202 * Add an easy way to photon-ize a URL that is safe to call even if Jetpack isn't active.
203 *
204 * See: https://jetpack.com/2013/07/11/photon-and-themes/
205 */
206 add_filter( 'jetpack_photon_url', 'jetpack_photon_url', 10, 3 );
207
208 /**
209 * WordPress.com
210 *
211 * If a cropped WP.com-hosted image is the source image, have Photon replicate the crop.
212 */
213 add_filter( 'jetpack_photon_pre_args', 'jetpack_photon_parse_wpcom_query_args', 10, 2 );
214
215 /**
216 * Parses WP.com-hosted image args to replicate the crop.
217 *
218 * @param mixed $args Args set during Photon's processing.
219 * @param string $image_url URL of the image.
220 * @return array|string Args for Photon to use for the URL.
221 */
222 function jetpack_photon_parse_wpcom_query_args( $args, $image_url ) {
223 $parsed_url = wp_parse_url( $image_url );
224
225 if ( ! $parsed_url ) {
226 return $args;
227 }
228
229 $image_url_parts = wp_parse_args(
230 $parsed_url,
231 array(
232 'host' => '',
233 'query' => '',
234 )
235 );
236
237 if ( '.files.wordpress.com' !== substr( $image_url_parts['host'], -20 ) ) {
238 return $args;
239 }
240
241 if ( empty( $image_url_parts['query'] ) ) {
242 return $args;
243 }
244
245 $wpcom_args = wp_parse_args( $image_url_parts['query'] );
246
247 if ( empty( $wpcom_args['w'] ) || empty( $wpcom_args['h'] ) ) {
248 return $args;
249 }
250
251 // Keep the crop by using "resize".
252 if ( ! empty( $wpcom_args['crop'] ) ) {
253 if ( is_array( $args ) ) {
254 $args = array_merge( array( 'resize' => array( $wpcom_args['w'], $wpcom_args['h'] ) ), $args );
255 } else {
256 $args = 'resize=' . rawurlencode( absint( $wpcom_args['w'] ) . ',' . absint( $wpcom_args['h'] ) ) . '&' . $args;
257 }
258 } else {
259 if ( is_array( $args ) ) {
260 $args = array_merge( array( 'fit' => array( $wpcom_args['w'], $wpcom_args['h'] ) ), $args );
261 } else {
262 $args = 'fit=' . rawurlencode( absint( $wpcom_args['w'] ) . ',' . absint( $wpcom_args['h'] ) ) . '&' . $args;
263 }
264 }
265
266 return $args;
267 }
268
269 /**
270 * Sets the scheme for a URL
271 *
272 * @param string $url URL to set scheme.
273 * @param string $scheme Scheme to use. Accepts http, https, network_path.
274 *
275 * @return string URL.
276 */
277 function jetpack_photon_url_scheme( $url, $scheme ) {
278 if ( ! in_array( $scheme, array( 'http', 'https', 'network_path' ), true ) ) {
279 if ( preg_match( '#^(https?:)?//#', $url ) ) {
280 return $url;
281 }
282
283 $scheme = 'http';
284 }
285
286 if ( 'network_path' === $scheme ) {
287 $scheme_slashes = '//';
288 } else {
289 $scheme_slashes = "$scheme://";
290 }
291
292 return preg_replace( '#^([a-z:]+)?//#i', $scheme_slashes, $url );
293 }
294
295 add_filter( 'jetpack_photon_skip_for_url', 'jetpack_photon_banned_domains', 9, 2 );
296
297 /**
298 * Check to skip Photon for a known domain that shouldn't be Photonized.
299 *
300 * @param bool $skip If the image should be skipped by Photon.
301 * @param string $image_url URL of the image.
302 *
303 * @return bool Should the image be skipped by Photon.
304 */
305 function jetpack_photon_banned_domains( $skip, $image_url ) {
306 $banned_host_patterns = array(
307 '/^chart\.googleapis\.com$/',
308 '/^chart\.apis\.google\.com$/',
309 '/^graph\.facebook\.com$/',
310 '/\.fbcdn\.net$/',
311 '/\.paypalobjects\.com$/',
312 '/\.dropbox\.com$/',
313 '/\.cdninstagram\.com$/',
314 '/^(commons|upload)\.wikimedia\.org$/',
315 '/\.wikipedia\.org$/',
316 );
317
318 $host = wp_parse_url( $image_url, PHP_URL_HOST );
319
320 foreach ( $banned_host_patterns as $banned_host_pattern ) {
321 if ( 1 === preg_match( $banned_host_pattern, $host ) ) {
322 return true;
323 }
324 }
325
326 return $skip;
327 }
328
329 /**
330 * Jetpack Photon - Support Text Widgets.
331 *
332 * @access public
333 * @param string $content Content from text widget.
334 * @return string
335 */
336 function jetpack_photon_support_text_widgets( $content ) {
337 if ( class_exists( 'Jetpack_Photon' ) && Jetpack::is_module_active( 'photon' ) ) {
338 return Jetpack_Photon::filter_the_content( $content );
339 }
340 return $content;
341 }
342 add_filter( 'widget_text', 'jetpack_photon_support_text_widgets' );
343