Completed
Push — feature/assets-cdn ( 36c9f8...c0fc5e )
by George
07:07
created

get_plugin_assets()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 6
nop 2
dl 0
loc 34
rs 8.7537
c 0
b 0
f 0
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: Yes
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
		$assets = self::get_plugin_assets( $plugin_slug, $current_version );
64
		$plugin_directory_url = plugins_url() . '/' . $plugin_slug . '/';
65
66
		if ( is_wp_error( $assets ) ) {
67
			return false;
68
		}
69
70 View Code Duplication
		foreach ( $wp_scripts->registered as $handle => $thing ) {
71
			if ( wp_startswith( $thing->src, self::CDN ) ) {
72
				continue;
73
			}
74
			if ( wp_startswith( $thing->src, $plugin_directory_url ) ) {
75
				$local_path = substr( $thing->src, strlen( $plugin_directory_url ) );
76
				if ( in_array( $local_path, $assets ) ) {
77
					$wp_scripts->registered[ $handle ]->src = sprintf(self::CDN . 'p/%1$s/%2$s/%3$s', $plugin_slug, $current_version, $local_path );
78
					$wp_scripts->registered[ $handle ]->ver = null;
79
				}
80
			}
81
		}
82 View Code Duplication
		foreach ( $wp_styles->registered as $handle => $thing ) {
83
			if ( wp_startswith( $thing->src, self::CDN ) ) {
84
				continue;
85
			}
86
			if ( wp_startswith( $thing->src, $plugin_directory_url ) ) {
87
				$local_path = substr( $thing->src, strlen( $plugin_directory_url ) );
88
				if ( in_array( $local_path, $assets ) ) {
89
					$wp_styles->registered[ $handle ]->src = sprintf(self::CDN . 'p/%1$s/%2$s/%3$s', $plugin_slug, $current_version, $local_path );
90
					$wp_styles->registered[ $handle ]->ver = null;
91
				}
92
			}
93
		}
94
	}
95
96
	/**
97
	 * Returns cdn-able assets for core.
98
	 *
99
	 * @param null $version
100
	 * @param null $locale
101
	 * @return array|bool
102
	 */
103
	public static function get_core_assets( $version = null, $locale = null ) {
104
		if ( empty( $version ) ) {
105
			$version = $GLOBALS['wp_version'];
106
		}
107
		if ( empty( $locale ) ) {
108
			$locale = get_locale();
109
		}
110
111
		$cache = Jetpack_Options::get_option( 'static_asset_cdn_files', array() );
112
		if ( isset( $cache['core'][ $version ][ $locale ] ) ) {
113
			return $cache['core'][ $version ][ $locale ];
114
		}
115
116
		require_once( ABSPATH . 'wp-admin/includes/update.php' );
117
		$checksums = get_core_checksums( $version, $locale );
118
119
		if ( empty( $checksums ) ) {
120
		    return false;
121
        }
122
123
		$return = array_filter( array_keys( $checksums ), array( __CLASS__, 'is_js_or_css_file' ) );
124
125
		if ( ! isset( $cache['core'][ $version ] ) ) {
126
			$cache['core'] = array();
127
			$cache['core'][ $version ] = array();
128
		}
129
		$cache['core'][ $version ][ $locale ] = $return;
130
		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...
131
132
		return $return;
133
	}
134
135
	/**
136
	 * Returns cdn-able assets for a given plugin.
137
	 *
138
	 * @param string $plugin
139
	 * @param string $version
140
	 * @return array
141
	 */
142
	public static function get_plugin_assets( $plugin, $version ) {
143
	    if ( 'jetpack' === $plugin && JETPACK__VERSION === $version ) {
144
	        include( JETPACK__PLUGIN_DIR . 'modules/photon-cdn/jetpack-manifest.php' );
145
	        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...
146
        }
147
148
		$cache = Jetpack_Options::get_option( 'static_asset_cdn_files', array() );
149
		if ( isset( $cache[ $plugin ][ $version ] ) ) {
150
			return $cache[ $plugin ][ $version ];
151
		}
152
153
		$url = sprintf( 'http://downloads.wordpress.org/plugin-checksums/%s/%s.json', $plugin, $version );
154
155
		if ( wp_http_supports( array( 'ssl' ) ) ) {
156
			$url = set_url_scheme( $url, 'https' );
157
		}
158
159
		$response = wp_remote_get( $url );
160
161
		$body = trim( wp_remote_retrieve_body( $response ) );
162
		$body = json_decode( $body, true );
163
164
		if( ! is_array( $body ) ) {
165
			return array();
166
		}
167
168
		$return = array_filter( array_keys( $body['files'] ), array( __CLASS__, 'is_js_or_css_file' ) );
169
170
		$cache[ $plugin ] = array();
171
		$cache[ $plugin ][ $version ] = $return;
172
		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...
173
174
		return $return;
175
	}
176
177
	public static function is_js_or_css_file( $path ) {
178
		return in_array( substr( $path, -3 ), array( 'css', '.js' ) );
179
	}
180
}
181
Jetpack_Photon_Static_Assets_CDN::go();
182
183