Completed
Push — add/asset-cdn ( c81376 )
by
unknown
09:18 queued 59s
created

Asset_CDN::render_concatenated_styles()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Plugin Name: Asset CDN
4
 * Description: Speed up Javascript and CSS
5
 * Plugin URI: https://github.com/automattic/jetpack
6
 * Author: Automattic
7
 * Author URI: https://automattic.com
8
 * Version: 0.1.0
9
 * Text Domain: asset-cdn
10
 * Domain Path: /languages/
11
 * License: GPLv2 or later
12
 */
13
14
/**
15
 * TODO
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
16
 * - versioning (combine ver hashes) and cachebusting
17
 * - concat/minify/serve JS too
18
 * - asset inlining for smaller styles?
19
 * - critical CSS support?
20
 * - non-enqueued assets?
21
 */
22
23
class Asset_CDN {
24
	private static $__instance = null;
25
26
	private $cdn_server;
27
	private $concat_style_groups = array();
28
29
	/**
30
	 * Singleton implementation
31
	 *
32
	 * @return object
33
	 */
34
	public static function instance() {
35
		if ( ! is_a( self::$__instance, 'Asset_CDN' ) ) {
36
			self::$__instance = new Asset_CDN();
37
		}
38
39
		return self::$__instance;
40
	}
41
42
	private function __construct() {
43
		$this->cdn_server = 'https://cdn.wpvm.io';
44
45
		// allow smaller CSS by only minifying assets on the page
46
		add_filter( 'jetpack_implode_frontend_css', '__return_false' );
47
48
		// rewrite CSS tags
49
		add_filter( 'style_loader_tag', array( $this, 'print_inline_styles' ), -100, 4 );
50
51
		add_action( 'wp_head', array( $this, 'render_concatenated_styles_head' ), PHP_INT_MAX );
52
		add_action( 'wp_footer', array( $this, 'render_concatenated_styles_footer' ), PHP_INT_MAX );
53
	}
54
55
	/**
56
	 * Render functions
57
	 */
58
59
	function render_concatenated_styles_head() {
60
		if ( isset( $this->concat_style_groups[0] ) ) {
61
			$this->render_concatenated_styles( $this->concat_style_groups[0] );
62
		}
63
	}
64
	function render_concatenated_styles_footer() {
65
		if ( isset( $this->concat_style_groups[1] ) ) {
66
			$this->render_concatenated_styles( $this->concat_style_groups[1] );
67
		}
68
	}
69
	private function render_concatenated_styles( $styles ) {
70
		// special URL to concatenation service
71
		foreach( $styles as $media => $urls ) {
72
			$cdn_url = $this->cdn_server . '/css?b=' . urlencode( site_url() ) . '&' . http_build_query( array( 'f' => $urls ) );
73
			// if we are injecting critical CSS, load the full CSS async
74
			if ( $this->inject_critical_css ) {
0 ignored issues
show
Bug introduced by
The property inject_critical_css does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
75
				echo '<!-- jetpack concat --><link rel="preload" onload="this.rel=\'stylesheet\'" as="style" type="text/css" media="' . $media . '" href="' . esc_attr( $cdn_url ) . '"/>';
76
			} else {
77
				echo '<!-- jetpack concat --><link rel="stylesheet" type="text/css" media="' . $media . '" href="' . esc_attr( $cdn_url ) . '"/>';
78
			}
79
		}
80
	}
81
82
	/**
83
	 * Asset modification functions
84
	 */
85
86
	public function print_inline_styles( $tag, $handle, $href, $media ) {
87
		global $wp_styles;
88
89
		// don't do admin for now
90
		if ( is_admin() || ! isset( $wp_styles->registered[$handle] ) ) {
91
			return $tag;
92
		}
93
94
		$style = $wp_styles->registered[$handle];
95
96
		if ( $this->should_concat_style( $style ) ) {
97
			$this->buffer_style( $style );
98
			return '';
99
		}
100
101
		return $tag;
102
	}
103
104
	private function buffer_style( $style ) {
105
		$group = isset( $style->extra['group'] ) ? $style->extra['group'] : 0;
106
		$media = $style->args;
107
		if ( ! $media ) {
108
			$media = 'all';
109
		}
110
		if ( ! isset( $this->concat_style_groups[$group] ) ) {
111
			$this->concat_style_groups[$group] = array();
112
		}
113
		if ( ! isset( $this->concat_style_groups[$group][$media] ) ) {
114
			$this->concat_style_groups[$group][$media] = array();
115
		}
116
		$local_url = str_replace( untrailingslashit( site_url() ), '', $style->src );
117
		$this->concat_style_groups[$group][$media][] = $local_url;
118
	}
119
120
	private function should_concat_style( $style ) {
121
		// only concat local styles
122
		$is_local       = $this->is_local_url( $style->src );
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 7 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
123
		// don't concat conditional styles
124
		$is_conditional = isset( $style->extra['conditional'] );
125
		return apply_filters( 'jetpack_perf_concat_style', $is_local && ! $is_conditional, $style->handle, $style->src );
126
	}
127
128
	private function is_local_url( $url ) {
129
		$site_url = site_url();
130
		return ( strncmp( $url, '/', 1 ) === 0 && strncmp( $url, '//', 2 ) !== 0 )
131
			|| strpos( $url, $site_url ) === 0;
132
	}
133
}