PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.7.3
Jetpack – WP Security, Backup, Speed, & Growth v12.7.3
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 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 / modules / photon-cdn.php
jetpack / modules Last commit date
calypsoify 2 years ago carousel 2 years ago cloudflare-analytics 4 years ago comment-likes 5 years ago comments 2 years ago contact-form 1 year ago custom-css 2 years ago custom-post-types 2 years ago geo-location 4 years ago google-analytics 3 years ago gravatar 6 years ago infinite-scroll 3 years ago likes 3 years ago markdown 3 years ago masterbar 2 years ago memberships 2 years ago photon-cdn 2 years ago plugin-search 4 years ago post-by-email 3 years ago related-posts 2 years ago scan 3 years ago seo-tools 2 years ago sharedaddy 2 years ago shortcodes 2 years ago simple-payments 3 years ago site-icon 4 years ago sitemaps 2 years ago sso 2 years ago stats 2 years ago subscriptions 2 years ago theme-tools 2 years ago tiled-gallery 2 years ago verification-tools 4 years ago videopress 2 years ago widget-visibility 2 years ago widgets 2 years ago woocommerce-analytics 2 years ago wordads 2 years ago wpcom-block-editor 2 years ago wpcom-tos 5 years ago action-bar.php 3 years ago blaze.php 3 years ago carousel.php 4 years ago comment-likes.php 3 years ago comments.php 2 years ago contact-form.php 3 years ago copy-post.php 3 years ago custom-content-types.php 4 years ago custom-css.php 3 years ago enhanced-distribution.php 4 years ago geo-location.php 4 years ago google-analytics.php 4 years ago google-fonts.php 2 years ago gravatar-hovercards.php 2 years ago infinite-scroll.php 3 years ago json-api.php 5 years ago latex.php 4 years ago lazy-images.php 2 years ago likes.php 2 years ago markdown.php 4 years ago masterbar.php 4 years ago module-extras.php 4 years ago module-headings.php 2 years ago module-info.php 2 years ago monitor.php 2 years ago notes.php 2 years ago photon-cdn.php 3 years ago photon.php 3 years ago plugin-search.php 2 years ago post-by-email.php 5 years ago post-list.php 4 years ago protect.php 3 years ago publicize.php 2 years ago related-posts.php 2 years ago search.php 4 years ago seo-tools.php 4 years ago sharedaddy.php 2 years ago shortcodes.php 3 years ago shortlinks.php 4 years ago sitemaps.php 4 years ago sso.php 2 years ago stats.php 2 years ago subscriptions.php 2 years ago theme-tools.php 3 years ago tiled-gallery.php 4 years ago vaultpress.php 2 years ago verification-tools.php 5 years ago videopress.php 4 years ago waf.php 3 years ago widget-visibility.php 4 years ago widgets.php 3 years ago woocommerce-analytics.php 5 years ago wordads.php 5 years ago wpgroho.js 6 years ago
photon-cdn.php
337 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Module Name: Asset CDN
4 * Module Description: Jetpack’s Site Accelerator loads your site faster by optimizing your images and serving your images and static files from our global network of servers.
5 * Sort Order: 26
6 * Recommendation Order: 1
7 * First Introduced: 6.6
8 * Requires Connection: No
9 * Auto Activate: No
10 * Module Tags: Photos and Videos, Appearance, Recommended
11 * Feature: Recommended, Appearance
12 * Additional Search Queries: site accelerator, accelerate, static, assets, javascript, css, files, performance, cdn, bandwidth, content delivery network, pagespeed, combine js, optimize css
13 *
14 * @package automattic/jetpack
15 */
16
17 use Automattic\Jetpack\Assets;
18
19 $GLOBALS['concatenate_scripts'] = false; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
20
21 Assets::add_resource_hint( '//c0.wp.com', 'dns-prefetch' );
22
23 /**
24 * Asset CDN module main class file.
25 */
26 class Jetpack_Photon_Static_Assets_CDN {
27 const CDN = 'https://c0.wp.com/';
28
29 /**
30 * Sets up action handlers needed for Jetpack CDN.
31 */
32 public static function go() {
33 add_action( 'wp_print_scripts', array( __CLASS__, 'cdnize_assets' ) );
34 add_action( 'wp_print_styles', array( __CLASS__, 'cdnize_assets' ) );
35 add_action( 'admin_print_scripts', array( __CLASS__, 'cdnize_assets' ) );
36 add_action( 'admin_print_styles', array( __CLASS__, 'cdnize_assets' ) );
37 add_action( 'wp_footer', array( __CLASS__, 'cdnize_assets' ) );
38 add_filter( 'load_script_textdomain_relative_path', array( __CLASS__, 'fix_script_relative_path' ), 10, 2 );
39 add_filter( 'load_script_translation_file', array( __CLASS__, 'fix_local_script_translation_path' ), 10, 3 );
40 }
41
42 /**
43 * Sets up CDN URLs for assets that are enqueued by the WordPress Core.
44 */
45 public static function cdnize_assets() {
46 global $wp_scripts, $wp_styles, $wp_version;
47
48 /*
49 * Short-circuit if AMP since not relevant as custom JS is not allowed and CSS is inlined.
50 * Note that it is not suitable to use the jetpack_force_disable_site_accelerator filter for this
51 * because it will be applied before the wp action, which is the point at which the queried object
52 * is available and we know whether the response will be AMP or not. This is particularly important
53 * for AMP-first (native AMP) pages where there are no AMP-specific URLs.
54 */
55 if ( class_exists( Jetpack_AMP_Support::class ) && Jetpack_AMP_Support::is_amp_request() ) {
56 return;
57 }
58
59 /**
60 * Filters Jetpack CDN's Core version number and locale. Can be used to override the values
61 * that Jetpack uses to retrieve assets. Expects the values to be returned in an array.
62 *
63 * @module photon-cdn
64 *
65 * @since 6.6.0
66 *
67 * @param array $values array( $version = core assets version, i.e. 4.9.8, $locale = desired locale )
68 */
69 list( $version, $locale ) = apply_filters( // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
70 'jetpack_cdn_core_version_and_locale',
71 array( $wp_version, get_locale() )
72 );
73
74 if ( self::is_public_version( $version ) ) {
75 $site_url = trailingslashit( site_url() );
76 foreach ( $wp_scripts->registered as $handle => $thing ) {
77 if ( wp_startswith( $thing->src, self::CDN ) ) {
78 continue;
79 }
80 if ( ! is_string( $thing->src ) ) {
81 continue;
82 }
83 $src = ltrim( str_replace( $site_url, '', $thing->src ), '/' );
84 if ( self::is_js_or_css_file( $src ) && in_array( substr( $src, 0, 9 ), array( 'wp-admin/', 'wp-includ' ), true ) ) {
85 $wp_scripts->registered[ $handle ]->src = sprintf( self::CDN . 'c/%1$s/%2$s', $version, $src );
86 $wp_scripts->registered[ $handle ]->ver = null;
87 }
88 }
89 foreach ( $wp_styles->registered as $handle => $thing ) {
90 if ( wp_startswith( $thing->src, self::CDN ) ) {
91 continue;
92 }
93 if ( ! is_string( $thing->src ) ) {
94 continue;
95 }
96 $src = ltrim( str_replace( $site_url, '', $thing->src ), '/' );
97 if ( self::is_js_or_css_file( $src ) && in_array( substr( $src, 0, 9 ), array( 'wp-admin/', 'wp-includ' ), true ) ) {
98 $wp_styles->registered[ $handle ]->src = sprintf( self::CDN . 'c/%1$s/%2$s', $version, $src );
99 $wp_styles->registered[ $handle ]->ver = null;
100 }
101 }
102 }
103
104 self::cdnize_plugin_assets( 'jetpack', JETPACK__VERSION );
105 if ( class_exists( 'WooCommerce' ) ) {
106 self::cdnize_plugin_assets( 'woocommerce', WC_VERSION );
107 }
108 }
109
110 /**
111 * Ensure use of the correct relative path when determining the JavaScript file names.
112 *
113 * @param string $relative The relative path of the script. False if it could not be determined.
114 * @param string $src The full source url of the script.
115 * @return string The expected relative path for the CDN-ed URL.
116 */
117 public static function fix_script_relative_path( $relative, $src ) {
118
119 // Note relevant in AMP responses. See note above.
120 if ( class_exists( Jetpack_AMP_Support::class ) && Jetpack_AMP_Support::is_amp_request() ) {
121 return $relative;
122 }
123
124 $strpos = strpos( $src, '/wp-includes/' );
125
126 // We only treat URLs that have wp-includes in them. Cases like language textdomains
127 // can also use this filter, they don't need to be touched because they are local paths.
128 if ( false !== $strpos ) {
129 return substr( $src, 1 + $strpos );
130 }
131
132 // Get the local path from a URL which was CDN'ed by cdnize_plugin_assets().
133 if ( preg_match( '#^' . preg_quote( self::CDN, '#' ) . 'p/[^/]+/[^/]+/(.*)$#', $src, $m ) ) {
134 return $m[1];
135 }
136
137 return $relative;
138 }
139
140 /**
141 * Ensure use of the correct local path when loading the JavaScript translation file for a CDN'ed asset.
142 *
143 * @param string|false $file Path to the translation file to load. False if there isn't one.
144 * @param string $handle The script handle.
145 * @param string $domain The text domain.
146 *
147 * @return string The transformed local languages path.
148 */
149 public static function fix_local_script_translation_path( $file, $handle, $domain ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
150 global $wp_scripts;
151
152 // This is a rewritten plugin URL, so load the language file from the plugins path.
153 if ( $file && isset( $wp_scripts->registered[ $handle ] ) && wp_startswith( $wp_scripts->registered[ $handle ]->src, self::CDN . 'p' ) ) {
154 return WP_LANG_DIR . '/plugins/' . basename( $file );
155 }
156
157 return $file;
158 }
159
160 /**
161 * Sets up CDN URLs for supported plugin assets.
162 *
163 * @param String $plugin_slug plugin slug string.
164 * @param String $current_version plugin version string.
165 * @return null|bool
166 */
167 public static function cdnize_plugin_assets( $plugin_slug, $current_version ) {
168 global $wp_scripts, $wp_styles;
169
170 /**
171 * Filters Jetpack CDN's plugin slug and version number. Can be used to override the values
172 * that Jetpack uses to retrieve assets. For example, when testing a development version of Jetpack
173 * the assets are not yet published, so you may need to override the version value to either
174 * trunk, or the latest available version. Expects the values to be returned in an array.
175 *
176 * @module photon-cdn
177 *
178 * @since 6.6.0
179 *
180 * @param array $values array( $slug = the plugin repository slug, i.e. jetpack, $version = the plugin version, i.e. 6.6 )
181 */
182 list( $plugin_slug, $current_version ) = apply_filters(
183 'jetpack_cdn_plugin_slug_and_version',
184 array( $plugin_slug, $current_version )
185 );
186
187 $assets = self::get_plugin_assets( $plugin_slug, $current_version );
188 $plugin_directory_url = plugins_url() . '/' . $plugin_slug . '/';
189
190 if ( is_wp_error( $assets ) || ! is_array( $assets ) ) {
191 return false;
192 }
193
194 foreach ( $wp_scripts->registered as $handle => $thing ) {
195 if ( wp_startswith( $thing->src, self::CDN ) ) {
196 continue;
197 }
198 if ( wp_startswith( $thing->src, $plugin_directory_url ) ) {
199 $local_path = substr( $thing->src, strlen( $plugin_directory_url ) );
200 if ( in_array( $local_path, $assets, true ) ) {
201 $wp_scripts->registered[ $handle ]->src = sprintf( self::CDN . 'p/%1$s/%2$s/%3$s', $plugin_slug, $current_version, $local_path );
202 $wp_scripts->registered[ $handle ]->ver = null;
203 }
204 }
205 }
206 foreach ( $wp_styles->registered as $handle => $thing ) {
207 if ( wp_startswith( $thing->src, self::CDN ) ) {
208 continue;
209 }
210 if ( wp_startswith( $thing->src, $plugin_directory_url ) ) {
211 $local_path = substr( $thing->src, strlen( $plugin_directory_url ) );
212 if ( in_array( $local_path, $assets, true ) ) {
213 $wp_styles->registered[ $handle ]->src = sprintf( self::CDN . 'p/%1$s/%2$s/%3$s', $plugin_slug, $current_version, $local_path );
214 $wp_styles->registered[ $handle ]->ver = null;
215 }
216 }
217 }
218 }
219
220 /**
221 * Returns cdn-able assets for a given plugin.
222 *
223 * @param string $plugin plugin slug string.
224 * @param string $version plugin version number string.
225 * @return array|bool Will return false if not a public version.
226 */
227 public static function get_plugin_assets( $plugin, $version ) {
228 if ( 'jetpack' === $plugin && JETPACK__VERSION === $version ) {
229 if ( ! self::is_public_version( $version ) ) {
230 return false;
231 }
232
233 $assets = array(); // The variable will be redefined in the included file.
234
235 include JETPACK__PLUGIN_DIR . 'modules/photon-cdn/jetpack-manifest.php';
236 return $assets;
237 }
238
239 /**
240 * Used for other plugins to provide their bundled assets via filter to
241 * prevent the need of storing them in an option or an external api request
242 * to w.org.
243 *
244 * @module photon-cdn
245 *
246 * @since 6.6.0
247 *
248 * @param array $assets The assets array for the plugin.
249 * @param string $version The version of the plugin being requested.
250 */
251 $assets = apply_filters( "jetpack_cdn_plugin_assets-{$plugin}", null, $version ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
252 if ( is_array( $assets ) ) {
253 return $assets;
254 }
255
256 if ( ! self::is_public_version( $version ) ) {
257 return false;
258 }
259
260 $cache = Jetpack_Options::get_option( 'static_asset_cdn_files', array() );
261 if ( isset( $cache[ $plugin ][ $version ] ) ) {
262 if ( is_array( $cache[ $plugin ][ $version ] ) ) {
263 return $cache[ $plugin ][ $version ];
264 }
265 if ( is_numeric( $cache[ $plugin ][ $version ] ) ) {
266 // Cache an empty result for up to 24h.
267 if ( (int) $cache[ $plugin ][ $version ] + DAY_IN_SECONDS > time() ) {
268 return array();
269 }
270 }
271 }
272
273 $url = sprintf( 'http://downloads.wordpress.org/plugin-checksums/%s/%s.json', $plugin, $version );
274
275 if ( wp_http_supports( array( 'ssl' ) ) ) {
276 $url = set_url_scheme( $url, 'https' );
277 }
278
279 $response = wp_remote_get( $url );
280
281 $body = trim( wp_remote_retrieve_body( $response ) );
282 $body = json_decode( $body, true );
283
284 $return = time();
285 if ( is_array( $body ) ) {
286 $return = array_filter( array_keys( $body['files'] ), array( __CLASS__, 'is_js_or_css_file' ) );
287 }
288
289 $cache[ $plugin ] = array();
290 $cache[ $plugin ][ $version ] = $return;
291 Jetpack_Options::update_option( 'static_asset_cdn_files', $cache, true );
292
293 return $return;
294 }
295
296 /**
297 * Checks a path whether it is a JS or CSS file.
298 *
299 * @param String $path file path.
300 * @return Boolean whether the file is a JS or CSS.
301 */
302 public static function is_js_or_css_file( $path ) {
303 return ( false === strpos( $path, '?' ) ) && in_array( substr( $path, -3 ), array( 'css', '.js' ), true );
304 }
305
306 /**
307 * Checks whether the version string indicates a production version.
308 *
309 * @param String $version the version string.
310 * @param Boolean $include_beta_and_rc whether to count beta and RC versions as production.
311 * @return Boolean
312 */
313 public static function is_public_version( $version, $include_beta_and_rc = false ) {
314 if ( preg_match( '/^\d+(\.\d+)+$/', $version ) ) {
315 /** Example matches: `1`, `1.2`, `1.2.3`. */
316 return true;
317 } elseif ( $include_beta_and_rc && preg_match( '/^\d+(\.\d+)+(-(beta|rc|pressable)\d?)$/i', $version ) ) {
318 /** Example matches: `1.2.3`, `1.2.3-beta`, `1.2.3-pressable`, `1.2.3-beta1`, `1.2.3-rc`, `1.2.3-rc2`. */
319 return true;
320 }
321 // Unrecognized version.
322 return false;
323 }
324 }
325 /**
326 * Allow plugins to short-circuit the Asset CDN, even when the module is on.
327 *
328 * @module photon-cdn
329 *
330 * @since 6.7.0
331 *
332 * @param false bool Should the Asset CDN be blocked? False by default.
333 */
334 if ( true !== apply_filters( 'jetpack_force_disable_site_accelerator', false ) ) {
335 Jetpack_Photon_Static_Assets_CDN::go();
336 }
337