Completed
Push — feature/assets-cdn ( 60c30e...562c45 )
by George
19:15 queued 09:11
created

Jetpack_Photon_Static_Assets_CDN   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 202
Duplicated Lines 21.78 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 44
loc 202
rs 9.44
c 0
b 0
f 0
wmc 37
lcom 1
cbo 1

7 Methods

Rating   Name   Duplication   Size   Complexity  
A go() 0 5 1
B cdnize_assets() 20 31 9
B cdnize_plugin_assets() 24 50 10
B get_core_assets() 0 44 6
B get_plugin_assets() 0 34 6
A is_js_or_css_file() 0 3 1
A is_public_version() 0 11 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Module Name: Photon CDN
4
 * Module Description: Serve static assets from our 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: photon, image, cdn, performance, speed, assets
13
 */
14
15
Jetpack::dns_prefetch( array(
16
	'//c0.wp.com',
17
) );
18
19
class Jetpack_Photon_Static_Assets_CDN {
20
	const CDN = 'https://c0.wp.com/';
21
22
	public static function go() {
23
		add_action( 'wp_print_scripts', array( __CLASS__, 'cdnize_assets' ) );
24
		add_action( 'wp_print_styles',  array( __CLASS__, 'cdnize_assets' ) );
25
		add_action( 'wp_footer',        array( __CLASS__, 'cdnize_assets' ) );
26
	}
27
28
	public static function cdnize_assets() {
29
		global $wp_scripts, $wp_styles, $wp_version;
30
31
		$known_core_files = self::get_core_assets();
32
33
		if ( ! empty( $known_core_files ) && is_array( $known_core_files ) ) {
34
			$site_url = trailingslashit( site_url() );
35 View Code Duplication
			foreach ( $wp_scripts->registered as $handle => $thing ) {
36
				if ( wp_startswith( $thing->src, self::CDN ) ) {
37
					continue;
38
				}
39
				$src = ltrim( str_replace( $site_url, '', $thing->src ), '/' );
40
				if ( in_array( $src, $known_core_files ) ) {
41
					$wp_scripts->registered[ $handle ]->src = sprintf(self::CDN . 'c/%1$s/%2$s', $wp_version, $src );
42
					$wp_scripts->registered[ $handle ]->ver = null;
43
				}
44
			}
45 View Code Duplication
			foreach ( $wp_styles->registered as $handle => $thing ) {
46
				if ( wp_startswith( $thing->src, self::CDN ) ) {
47
					continue;
48
				}
49
				$src = ltrim( str_replace( $site_url, '', $thing->src ), '/' );
50
				if ( in_array( $src, $known_core_files ) ) {
51
					$wp_styles->registered[ $handle ]->src = sprintf(self::CDN . 'c/%1$s/%2$s', $wp_version, $src );
52
					$wp_styles->registered[ $handle ]->ver = null;
53
				}
54
			}
55
		}
56
57
		self::cdnize_plugin_assets( 'jetpack', JETPACK__VERSION );
58
	}
59
60
	public static function cdnize_plugin_assets( $plugin_slug, $current_version ) {
61
		global $wp_scripts, $wp_styles;
62
63
		/**
64
		 * Filters Jetpack CDN's plugin slug and version number. Can be used to override the values
65
		 * that Jetpack uses to retrieve assets. For example, when testing a development version of Jetpack
66
		 * the assets are not yet published, so you may need to override the version value to either
67
		 * trunk, or the latest available version. Expects the values to be returned in an array.
68
		 *
69
		 * @since 6.6
70
		 *
71
		 * @param array $values array( $slug = the plugin repository slug, i.e. jetpack, $version = the plugin version, i.e. 6.6 )
72
		 */
73
		list( $plugin_slug, $current_version ) = apply_filters(
74
			'jetpack_cdn_plugin_slug_and_version',
75
			array( $plugin_slug, $current_version )
76
		);
77
78
		$assets = self::get_plugin_assets( $plugin_slug, $current_version );
79
		$plugin_directory_url = plugins_url() . '/' . $plugin_slug . '/';
80
81
		if ( is_wp_error( $assets ) ) {
82
			return false;
83
		}
84
85 View Code Duplication
		foreach ( $wp_scripts->registered as $handle => $thing ) {
86
			if ( wp_startswith( $thing->src, self::CDN ) ) {
87
				continue;
88
			}
89
			if ( wp_startswith( $thing->src, $plugin_directory_url ) ) {
90
				$local_path = substr( $thing->src, strlen( $plugin_directory_url ) );
91
				if ( in_array( $local_path, $assets ) ) {
92
					$wp_scripts->registered[ $handle ]->src = sprintf(self::CDN . 'p/%1$s/%2$s/%3$s', $plugin_slug, $current_version, $local_path );
93
					$wp_scripts->registered[ $handle ]->ver = null;
94
				}
95
			}
96
		}
97 View Code Duplication
		foreach ( $wp_styles->registered as $handle => $thing ) {
98
			if ( wp_startswith( $thing->src, self::CDN ) ) {
99
				continue;
100
			}
101
			if ( wp_startswith( $thing->src, $plugin_directory_url ) ) {
102
				$local_path = substr( $thing->src, strlen( $plugin_directory_url ) );
103
				if ( in_array( $local_path, $assets ) ) {
104
					$wp_styles->registered[ $handle ]->src = sprintf(self::CDN . 'p/%1$s/%2$s/%3$s', $plugin_slug, $current_version, $local_path );
105
					$wp_styles->registered[ $handle ]->ver = null;
106
				}
107
			}
108
		}
109
	}
110
111
	/**
112
	 * Returns cdn-able assets for core.
113
	 *
114
	 * @param null $version
115
	 * @param null $locale
116
	 * @return array|bool
117
	 */
118
	public static function get_core_assets( $version = null, $locale = null ) {
119
		if ( empty( $version ) ) {
120
			$version = $GLOBALS['wp_version'];
121
		}
122
		if ( empty( $locale ) ) {
123
			$locale = get_locale();
124
		}
125
126
		/**
127
		 * Filters Jetpack CDN's Core version number and locale. Can be used to override the values
128
		 * that Jetpack uses to retrieve assets. Expects the values to be returned in an array.
129
		 *
130
		 * @since 6.6
131
		 *
132
		 * @param array $values array( $version  = core assets version, i.e. 4.9.1, $locale = desired locale )
133
		 */
134
		list( $version, $locale ) = apply_filters(
135
			'jetpack_cdn_plugin_slug_and_version',
136
			array( $version, $locale )
137
		);
138
139
		$cache = Jetpack_Options::get_option( 'static_asset_cdn_files', array() );
140
		if ( isset( $cache['core'][ $version ][ $locale ] ) ) {
141
			return $cache['core'][ $version ][ $locale ];
142
		}
143
144
		require_once( ABSPATH . 'wp-admin/includes/update.php' );
145
		$checksums = get_core_checksums( $version, $locale );
146
147
		if ( empty( $checksums ) ) {
148
			return false;
149
		}
150
151
		$return = array_filter( array_keys( $checksums ), array( __CLASS__, 'is_js_or_css_file' ) );
152
153
		if ( ! isset( $cache['core'][ $version ] ) ) {
154
			$cache['core'] = array();
155
			$cache['core'][ $version ] = array();
156
		}
157
		$cache['core'][ $version ][ $locale ] = $return;
158
		Jetpack_Options::update_option( 'static_asset_cdn_files', $cache, true );
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
159
160
		return $return;
161
	}
162
163
	/**
164
	 * Returns cdn-able assets for a given plugin.
165
	 *
166
	 * @param string $plugin
167
	 * @param string $version
168
	 * @return array
169
	 */
170
	public static function get_plugin_assets( $plugin, $version ) {
171
		if ( 'jetpack' === $plugin && JETPACK__VERSION === $version ) {
172
			include( JETPACK__PLUGIN_DIR . 'modules/photon-cdn/jetpack-manifest.php' );
173
			return $assets;
0 ignored issues
show
Bug introduced by
The variable $assets does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
174
		}
175
176
		$cache = Jetpack_Options::get_option( 'static_asset_cdn_files', array() );
177
		if ( isset( $cache[ $plugin ][ $version ] ) ) {
178
			return $cache[ $plugin ][ $version ];
179
		}
180
181
		$url = sprintf( 'http://downloads.wordpress.org/plugin-checksums/%s/%s.json', $plugin, $version );
182
183
		if ( wp_http_supports( array( 'ssl' ) ) ) {
184
			$url = set_url_scheme( $url, 'https' );
185
		}
186
187
		$response = wp_remote_get( $url );
188
189
		$body = trim( wp_remote_retrieve_body( $response ) );
190
		$body = json_decode( $body, true );
191
192
		if( ! is_array( $body ) ) {
193
			return array();
194
		}
195
196
		$return = array_filter( array_keys( $body['files'] ), array( __CLASS__, 'is_js_or_css_file' ) );
197
198
		$cache[ $plugin ] = array();
199
		$cache[ $plugin ][ $version ] = $return;
200
		Jetpack_Options::update_option( 'static_asset_cdn_files', $cache, true );
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
201
202
		return $return;
203
	}
204
205
	public static function is_js_or_css_file( $path ) {
206
		return in_array( substr( $path, -3 ), array( 'css', '.js' ) );
207
	}
208
209
	public static function is_public_version( $version, $include_beta_and_rc = false ) {
210
		if ( preg_match( '/^\d+(\.\d+)+$/', $version ) ) {
211
			// matches `1` `1.2` `1.2.3`
212
			return true;
213
		} elseif ( $include_beta_and_rc && preg_match( '/^\d+(\.\d+)+(-(beta|rc)\d?)$/i', $version ) ) {
214
			// matches `1.2.3` `1.2.3-beta` `1.2.3-beta1` `1.2.3-rc` `1.2.3-rc2`
215
			return true;
216
		}
217
		// unrecognized version
218
		return false;
219
	}
220
}
221
Jetpack_Photon_Static_Assets_CDN::go();
222