Completed
Push — master ( e47ebd...1dc9c8 )
by LA
01:51
created

do-functions.php ➔ imgix_replace_non_wp_images()   C

Complexity

Conditions 8
Paths 2

Size

Total Lines 44
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 24
nc 2
nop 1
dl 0
loc 44
rs 5.3846
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * @package imgix
5
 */
6
7
/**
8
 * Find all img tags with sources matching "imgix.net" without the parameter
9
 * "srcset" and add the "srcset" parameter to all those images, appending a new
10
 * source using the "dpr=2" modifier.
11
 *
12
 * @param $content
13
 *
14
 * @return string Content with retina-enriched image tags.
15
 */
16
function imgix_add_retina( $content ) {
17
	$pattern = '/<img((?![^>]+srcset )([^>]*)';
18
	$pattern .= 'src=[\'"]([^\'"]*imgix.net[^\'"]*\?[^\'"]*w=[^\'"]*)[\'"]([^>]*)*?)>/i';
19
	$repl    = '<img$2src="$3" srcset="${3}, ${3}&amp;dpr=2 2x, ${3}&amp;dpr=3 3x,"$4>';
20
	$content = preg_replace( $pattern, $repl, $content );
21
22
	return preg_replace( $pattern, $repl, $content );
23
}
24
25
/**
26
 * Returns a array of global parameters to be applied in all images,
27
 * according to plugin's settings.
28
 *
29
 * @return array Global parameters to be appened at the end of each img URL.
30
 */
31
function imgix_get_global_params() {
32
	global $imgix_options;
33
34
	$params = [];
35
	// For now, only "auto" is supported.
36
37
	$auto = [];
38
	if ( ! empty( $imgix_options['auto_format'] ) ) {
39
		array_push( $auto, 'format' );
40
	}
41
42
	if ( ! empty( $imgix_options['auto_enhance'] ) ) {
43
		array_push( $auto, 'enhance' );
44
	}
45
46
	if ( ! empty( $auto ) ) {
47
		$params['auto'] = implode( ',', $auto );
48
	}
49
50
	return $params;
51
}
52
53
/**
54
 * Convert sizes in filename to parameters and returns origina filename without sizes.
55
 * If no size is found the original filename is returned.
56
 *
57
 * @param string $filename
58
 *
59
 * @return array with filename and size arguments.
60
 */
61
function convert_filename_to_size_args( $filename ) {
62
	$arguments = [];
63
64
	$filename = preg_replace_callback( '/-(?<width>\d+)x(?<height>\d+)(?<extension>\.\w{3,4}$)/', function ( $match ) use ( &$arguments ) {
65
		$arguments = [
66
			'w' => $match['width'],
67
			'h' => $match['height']
68
		];
69
70
		return $match['extension'];
71
	}, $filename );
72
73
	return [ $filename, $arguments ];
74
}
75
76
/**
77
 * Modify image urls for attachments to use imgix host.
78
 *
79
 * @param string $url
80
 *
81
 * @return string
82
 */
83
function imgix_file_url( $url ) {
84
85
	global $imgix_options;
86
87
	if ( empty ( $imgix_options['cdn_link'] ) ) {
88
		return $url;
89
	}
90
91
	$file = pathinfo( $url );
92
93
	if ( in_array( $file['extension'], [ 'jpg', 'gif', 'png', 'jpeg' ] ) ) {
94
		return str_replace( trailingslashit( home_url( '/' ) ), trailingslashit( $imgix_options['cdn_link'] ), $url );
95
	}
96
97
	return $url;
98
}
99
100
add_filter( 'wp_get_attachment_url', 'imgix_file_url' );
101
add_filter( 'imgix/add-image-url', 'imgix_file_url' );
102
103
/**
104
 * Modify image urls in srcset to use imgix host.
105
 *
106
 * @param array $sources
107
 *
108
 * @return array $sources
109
 */
110
function imgix_cdn_srcset( $sources ) {
111
	foreach ( $sources as $source ) {
112
		$sources[ $source['value'] ]['url'] = apply_filters( 'imgix/add-image-url', $sources[ $source['value'] ]['url'] );
113
	}
114
115
	return $sources;
116
}
117
118
add_filter( 'wp_calculate_image_srcset', 'imgix_cdn_srcset', 10 );
119
120
/**
121
 * Modify image urls in content to use imgix host.
122
 *
123
 * @param $content
124
 *
125
 * @return string
126
 */
127
function imgix_replace_non_wp_images( $content ) {
128
	global $imgix_options;
129
130
	if ( ! empty( $imgix_options['cdn_link'] ) ) {
131
132
		$content = preg_replace_callback( '/(?<=\shref="|\ssrc="|\shref=\'|\ssrc=\').*(?=\'|")/', function ( $match ) use ( $imgix_options ) {
133
			$url = $match[0];
134
135
			$pathinfo = pathinfo( $url );
136
137
			if ( in_array( $pathinfo['extension'], [ 'jpg', 'gif', 'png', 'jpeg' ], true ) ) {
138
				$file_url = parse_url( $url );
139
				if ( $file_url['host'] === parse_url( home_url( '/' ), PHP_URL_HOST ) ) {
140
					$cdn = parse_url( $imgix_options['cdn_link'] );
141
					foreach ( [ 'scheme', 'host', 'port' ] as $url_part ) {
142
						if ( isset( $cdn[ $url_part ] ) ) {
143
							$file_url[ $url_part ] = $cdn[ $url_part ];
144
						} else {
145
							unset( $file_url[ $url_part ] );
146
						}
147
					}
148
149
					list( $filename, $arguments ) = convert_filename_to_size_args( $pathinfo['basename'] );
150
151
					$arguments = array_merge( $arguments, imgix_get_global_params() );
152
153
					$file_url['path'] = trailingslashit( dirname( $file_url['path'] ) ) . $filename;
154
155
					if ( ! empty( $arguments ) ) {
156
						$file_url['query'] = empty( $file_url['query'] ) ? build_query( $arguments ) : $file_url['query'] . '&' . build_query( $arguments );
157
					}
158
159
					$url = http_build_url( $file_url );
0 ignored issues
show
Security Bug introduced by
It seems like $file_url defined by parse_url($url) on line 138 can also be of type false; however, http_build_url() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
160
				}
161
			}
162
163
164
			return esc_url_raw( $url );
165
		}, $content );
166
167
	}
168
169
	return $content;
170
}
171
172
add_filter( 'the_content', 'imgix_replace_non_wp_images' );
173
174
function imgix_wp_head() {
175
	global $imgix_options;
176
177
	if ( isset( $imgix_options['cdn_link'] ) && $imgix_options['cdn_link'] ) {
178
		printf( "<link rel='dns-prefetch' href='%s'/>",
179
			esc_url( preg_replace( '/^https?:/', '', untrailingslashit( $imgix_options['cdn_link'] ) ) )
180
		);
181
	}
182
}
183
184
add_action( 'wp_head', 'imgix_wp_head', 1 );
185
186
if ( isset( $imgix_options['add_dpi2_srcset'] ) && $imgix_options['add_dpi2_srcset'] ) {
187
	function imgix_buffer_start() {
188
		ob_start( 'imgix_add_retina' );
189
	}
190
191
	function imgix_buffer_end() {
192
		ob_end_flush();
193
	}
194
195
	add_action( 'after_setup_theme', 'imgix_buffer_start' );
196
	add_action( 'shutdown', 'imgix_buffer_end' );
197
	add_filter( 'the_content', 'imgix_add_retina' );
198
}
199