Completed
Push — feature/assets-cdn ( f636a6...717807 )
by George
07:10
created

Jetpack_Photon_Static_Assets_CDN::cdnize_assets()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 30

Duplication

Lines 22
Ratio 73.33 %

Importance

Changes 0
Metric Value
cc 7
nc 16
nop 0
dl 22
loc 30
rs 8.5066
c 0
b 0
f 0
1
<?php
2
/**
3
 * Module Name: Photon
4
 * Module Description: Serve images from our servers
5
 * Jumpstart Description: Mirrors and serves your images from our free and fast image CDN, improving your site’s performance with no additional load on your servers.
6
 * Sort Order: 25
7
 * Recommendation Order: 1
8
 * First Introduced: 2.0
9
 * Requires Connection: Yes
10
 * Auto Activate: No
11
 * Module Tags: Photos and Videos, Appearance, Recommended
12
 * Feature: Recommended, Jumpstart, Appearance
13
 * Additional Search Queries: photon, image, cdn, performance, speed
14
 */
15
16
Jetpack::dns_prefetch( array(
17
	'//i0.wp.com',
18
	'//i1.wp.com',
19
	'//i2.wp.com',
20
	'//c0.wp.com',
21
) );
22
23
Jetpack_Photon::instance();
24
25
class Jetpack_Photon_Static_Assets_CDN {
26
	public static function go() {
27
		add_action( 'wp_print_scripts', array( __CLASS__, 'cdnize_assets' ) );
28
		add_action( 'wp_print_styles',  array( __CLASS__, 'cdnize_assets' ) );
29
		add_action( 'wp_footer',        array( __CLASS__, 'cdnize_assets' ) );
30
	}
31
32
	public static function cdnize_assets() {
33
		global $wp_scripts, $wp_styles, $wp_version;
34
35
		$known_core_files = self::get_core_checksums();
36
		$site_url = trailingslashit( site_url() );
37 View Code Duplication
		foreach ( $wp_scripts->registered as $handle => $thing ) {
38
			if ( wp_startswith( $thing->src, 'https://c0.wp.com/' ) ) {
39
				continue;
40
			}
41
			$src = ltrim( str_replace( $site_url, '', $thing->src ), '/' );
42
			if ( isset( $known_core_files[ $src ] ) ) {
43
				$wp_scripts->registered[ $handle ]->src = sprintf('https://c0.wp.com/c/%1$s/%2$s', $wp_version, $src );
44
				$wp_scripts->registered[ $handle ]->ver = null;
45
				wp_script_add_data( $handle, 'integrity', 'md5-' . base64_encode( $known_core_files[ $src ] ) );
46
			}
47
		}
48 View Code Duplication
		foreach ( $wp_styles->registered as $handle => $thing ) {
49
			if ( wp_startswith( $thing->src, 'https://c0.wp.com/' ) ) {
50
				continue;
51
			}
52
			$src = ltrim( str_replace( $site_url, '', $thing->src ), '/' );
53
			if ( isset( $known_core_files[ $src ] ) ) {
54
				$wp_styles->registered[ $handle ]->src = sprintf('https://c0.wp.com/c/%1$s/%2$s', $wp_version, $src );
55
				$wp_styles->registered[ $handle ]->ver = null;
56
				wp_style_add_data( $handle, 'integrity', 'md5-' . base64_encode( $known_core_files[ $src ] ) );
57
			}
58
		}
59
60
		self::cdnize_plugin_assets( 'jetpack', JETPACK__VERSION );
61
	}
62
63
	public static function cdnize_plugin_assets( $plugin_slug, $current_version ) {
64
		global $wp_scripts, $wp_styles;
65
66
		$supported_versions = self::get_plugin_versions( $plugin_slug );
67
		if ( ! in_array( $current_version, $supported_versions ) ) {
68
			return false;
69
		}
70
71
		$asset_hashes = self::get_plugin_checksums( $current_version, $plugin_slug );
72
		$plugin_directory_url = plugins_url() . '/' . $plugin_slug . '/';
73
74 View Code Duplication
		foreach ( $wp_scripts->registered as $handle => $thing ) {
75
			if ( wp_startswith( $thing->src, 'https://c0.wp.com/' ) ) {
76
				continue;
77
			}
78
			if ( wp_startswith( $thing->src, $plugin_directory_url ) ) {
79
				$local_path = substr( $thing->src, strlen( $plugin_directory_url ) );
80
				if ( isset( $asset_hashes[ $local_path ] ) ) {
81
					$wp_scripts->registered[ $handle ]->src = sprintf('https://c0.wp.com/p/%1$s/%2$s/%3$s', $plugin_slug, $current_version, $local_path );
82
					$wp_scripts->registered[ $handle ]->ver = null;
83
					wp_script_add_data( $handle, 'integrity', 'sha256-' . base64_encode( $asset_hashes[ $local_path ] ) );
84
				}
85
			}
86
		}
87 View Code Duplication
		foreach ( $wp_styles->registered as $handle => $thing ) {
88
			if ( wp_startswith( $thing->src, 'https://c0.wp.com/' ) ) {
89
				continue;
90
			}
91
			if ( wp_startswith( $thing->src, $plugin_directory_url ) ) {
92
				$local_path = substr( $thing->src, strlen( $plugin_directory_url ) );
93
				if ( isset( $asset_hashes[ $local_path ] ) ) {
94
					$wp_styles->registered[ $handle ]->src = sprintf('https://c0.wp.com/p/%1$s/%2$s/%3$s', $plugin_slug, $current_version, $local_path );
95
					$wp_styles->registered[ $handle ]->ver = null;
96
					wp_style_add_data( $handle, 'integrity', 'sha256-' . base64_encode( $asset_hashes[ $local_path ] ) );
97
				}
98
			}
99
		}
100
	}
101
102
	/**
103
	 * Returns MD5 checksums (boo, hiss)
104
	 * @todo CACHING
105
	 *
106
	 * @param null $version
107
	 * @param null $locale
108
	 * @return array|bool
109
	 */
110
	public static function get_core_checksums( $version = null, $locale = null ) {
111
		if ( empty( $version ) ) {
112
			$version = $GLOBALS['wp_version'];
113
		}
114
		if ( empty( $locale ) ) {
115
			$locale = get_locale();
116
		}
117
		require_once( ABSPATH . 'wp-admin/includes/update.php' );
118
		return get_core_checksums( $version, $locale );
119
	}
120
121
	/**
122
	 * @todo CACHING
123
	 *
124
	 * @param string $plugin
125
	 * @return array
126
	 */
127
	public static function get_plugin_versions( $plugin = 'jetpack' ) {
128
		$response = wp_remote_get( sprintf( 'https://api.wordpress.org/plugins/info/1.0/%s.json', esc_url( $plugin ) ) );
129
		$body = trim( wp_remote_retrieve_body( $response ) );
130
		$body = json_decode( $body, true );
131
		return array_keys( $body['versions'] );
132
	}
133
134
	/**
135
	 * Returns SHA-256 checksums
136
	 * @todo CACHING
137
	 *
138
	 * @param null $version
139
	 * @param string $plugin
140
	 * @return array
141
	 */
142
	public static function get_plugin_checksums( $version = null, $plugin = 'jetpack' ) {
143
		if ( empty( $version ) ) {
144
			$version = JETPACK__VERSION;
145
		}
146
		$url = sprintf( 'http://downloads.wordpress.org/plugin-checksums/%s/%s.json', $plugin, $version );
147
148
		if ( wp_http_supports( array( 'ssl' ) ) ) {
149
			$url = set_url_scheme( $url, 'https' );
150
		}
151
152
		$response = wp_remote_get( $url );
153
154
		$body = trim( wp_remote_retrieve_body( $response ) );
155
		$body = json_decode( $body, true );
156
157
		$return = array();
158
159
		foreach ( $body['files'] as $file => $hashes ) {
160
			if ( in_array( substr( $file, -3 ), array( 'css', '.js' ) ) ) {
161
				$return[ $file ] = $hashes['sha256'];
162
			}
163
		}
164
165
		return $return;
166
	}
167
}
168
Jetpack_Photon_Static_Assets_CDN::go();
169
170