Completed
Push — update/editor-blocks-icon-colo... ( 093ab2...3cfb5e )
by
unknown
08:47
created

modules/shortcodes/getty.php (2 issues)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Getty shortcode
4
 *
5
 * [getty src="82278805" width="$width" height="$height"]
6
 * <div class="getty embed image" style="background-color:#fff;display:inline-block;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#a7a7a7;font-size:11px;width:100%;max-width:462px;"><div style="padding:0;margin:0;text-align:left;"><a href="http://www.gettyimages.com/detail/82278805" target="_blank" style="color:#a7a7a7;text-decoration:none;font-weight:normal !important;border:none;display:inline-block;">Embed from Getty Images</a></div><div style="overflow:hidden;position:relative;height:0;padding:80.086580% 0 0 0;width:100%;"><iframe src="//embed.gettyimages.com/embed/82278805?et=jGiu6FXXSpJDGf1SnwLV2g&sig=TFVNFtqghwNw5iJQ1MFWnI8f4Y40_sfogfZLhai6SfA=" width="462" height="370" scrolling="no" frameborder="0" style="display:inline-block;position:absolute;top:0;left:0;width:100%;height:100%;"></iframe></div><p style="margin:0;"></p></div>
7
 *
8
 * @package Jetpack
9
 */
10
11
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
12
	add_action( 'init', 'jetpack_getty_enable_embeds' );
13
} else {
14
	jetpack_getty_enable_embeds();
15
}
16
17
/**
18
 * Register Getty as oembed provider. Add filter to reverse iframes to shortcode. Register [getty] shortcode.
19
 *
20
 * @since 4.5.0
21
 * @since 5.8.0 removed string parameter.
22
 */
23
function jetpack_getty_enable_embeds() {
24
25
	// Support their oEmbed Endpoint.
26
	wp_oembed_add_provider( '#https?://www\.gettyimages\.com/detail/.*#i', 'https://embed.gettyimages.com/oembed/', true );
27
	wp_oembed_add_provider( '#https?://(www\.)?gty\.im/.*#i', 'https://embed.gettyimages.com/oembed/', true );
28
29
	// Allow iframes to be filtered to short code (so direct copy+paste can be done).
30
	add_filter( 'pre_kses', 'wpcom_shortcodereverse_getty' );
31
32
	// Actually display the Getty Embed.
33
	add_shortcode( 'getty', 'jetpack_getty_shortcode' );
34
}
35
36
/**
37
 * Filters the oEmbed provider URL for Getty URLs to include site URL host as
38
 * caller if available, falling back to "wordpress.com". Must be applied at
39
 * time of embed in case that `init` is too early (WP.com REST API).
40
 *
41
 * @module shortcodes
42
 *
43
 * @since 5.8.0
44
 *
45
 * @see WP_oEmbed::fetch
46
 *
47
 * @return string oEmbed provider URL
48
 */
49
add_filter( 'oembed_fetch_url', 'getty_add_oembed_endpoint_caller' );
50
51
/**
52
 * Filter the embeds to add a caller parameter.
53
 *
54
 * @param string $provider URL of the oEmbed provider.
55
 */
56
function getty_add_oembed_endpoint_caller( $provider ) {
57
	// By time filter is called, original provider URL has had url, maxwidth,
58
	// maxheight query parameters added.
59
	if ( 0 !== strpos( $provider, 'https://embed.gettyimages.com/oembed/' ) ) {
60
		return $provider;
61
	}
62
63
	// Set the caller argument to pass to Getty's oembed provider.
64
	if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
65
66
		// Only include caller for non-private sites.
67
		if ( ! function_exists( 'is_private_blog' ) || ! is_private_blog() ) {
68
			$host = wp_parse_url( get_bloginfo( 'url' ), PHP_URL_HOST );
0 ignored issues
show
The call to wp_parse_url() has too many arguments starting with PHP_URL_HOST.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
69
		}
70
71
		// Fall back to WordPress.com.
72
		if ( empty( $host ) ) {
73
			$host = 'wordpress.com';
74
		}
75
	} else {
76
		$host = wp_parse_url( get_home_url(), PHP_URL_HOST );
0 ignored issues
show
The call to wp_parse_url() has too many arguments starting with PHP_URL_HOST.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
77
	}
78
79
	return add_query_arg( 'caller', $host, $provider );
80
}
81
82
/**
83
 * Compose shortcode based on Getty iframes.
84
 *
85
 * @since 4.5.0
86
 *
87
 * @param string $content Post content.
88
 *
89
 * @return mixed
90
 */
91
function wpcom_shortcodereverse_getty( $content ) {
92
	if ( ! is_string( $content ) || false === stripos( $content, '.gettyimages.com/' ) ) {
93
		return $content;
94
	}
95
96
	$regexp     = '!<iframe\s+src=[\'"](https?:)?//embed\.gettyimages\.com/embed(/|/?\?assets=)([a-z0-9_-]+(,[a-z0-9_-]+)*)[^\'"]*?[\'"]((?:\s+\w+=[\'"][^\'"]*[\'"])*)((?:[\s\w]*))></iframe>!i';
97
	$regexp_ent = str_replace( '&amp;#0*58;', '&amp;#0*58;|&#0*58;', htmlspecialchars( $regexp, ENT_NOQUOTES ) );
98
99
	// Markup pattern for 2017 embed syntax with significant differences from the prior pattern.
100
	$regexp_2017     = '!<a.+?class=\'gie-(single|slideshow)\'.+?gie\.widgets\.load\({([^}]+)}\).+?embed-cdn\.gettyimages\.com/widgets\.js.+?</script>!';
101
	$regexp_2017_ent = str_replace( '&amp;#0*58;', '&amp;#0*58;|&#0*58;', htmlspecialchars( $regexp_2017, ENT_NOQUOTES ) );
102
103
	foreach ( compact( 'regexp_2017', 'regexp_2017_ent', 'regexp', 'regexp_ent' ) as $reg => $regexp ) {
104
		if ( ! preg_match_all( $regexp, $content, $matches, PREG_SET_ORDER ) ) {
105
			continue;
106
		}
107
108
		foreach ( $matches as $match ) {
109
			if ( 'regexp_2017' === $reg || 'regexp_2017_ent' === $reg ) {
110
				// Extract individual keys from the matched JavaScript object.
111
				$params = $match[2];
112
				if ( ! preg_match_all( '!(?P<key>\w+)\s*:\s*([\'"](?P<value>[^\'"]*?)(px)?[\'"])!', $params, $key_matches, PREG_SET_ORDER ) ) {
113
					continue;
114
				}
115
116
				foreach ( $key_matches as $key_match ) {
117
					switch ( $key_match['key'] ) {
118
						case 'items':
119
							$ids = $key_match['value'];
120
							break;
121
						case 'w':
122
							$width = (int) $key_match['value'];
123
							break;
124
						case 'h':
125
							$height = (int) $key_match['value'];
126
							break;
127
						case 'tld':
128
							$tld = $key_match['value'];
129
							break;
130
					}
131
				}
132
			} else {
133
				$params = $match[5];
134
				if ( 'regexp_ent' === $reg ) {
135
					$params = html_entity_decode( $params );
136
				}
137
				$params = wp_kses_hair( $params, array( 'http' ) );
138
139
				$ids    = esc_html( $match[3] );
140
				$width  = isset( $params['width'] ) ? (int) $params['width']['value'] : 0;
141
				$height = isset( $params['height'] ) ? (int) $params['height']['value'] : 0;
142
			}
143
144
			if ( empty( $ids ) ) {
145
				continue;
146
			}
147
148
			$shortcode = '[getty src="' . esc_attr( $ids ) . '"';
149
			if ( ! empty( $width ) ) {
150
				$shortcode .= ' width="' . esc_attr( $width ) . '"';
151
			}
152
			if ( ! empty( $height ) ) {
153
				$shortcode .= ' height="' . esc_attr( $height ) . '"';
154
			}
155
156
			/*
157
			 * While it does not appear to have any practical impact, Getty has
158
			 * requested that we include TLD in the embed request
159
			 */
160
			if ( ! empty( $tld ) ) {
161
				$shortcode .= ' tld="' . esc_attr( $tld ) . '"';
162
			}
163
			$shortcode .= ']';
164
165
			$content = str_replace( $match[0], $shortcode, $content );
166
		}
167
	}
168
169
	// strip out enclosing div and any other markup.
170
	$regexp     = '%<div class="getty\s[^>]*+>.*?<div[^>]*+>(\[getty[^\]]*+\])\s*</div>.*?</div>%is';
171
	$regexp_ent = str_replace( array( '&amp;#0*58;', '[^&gt;]' ), array( '&amp;#0*58;|&#0*58;', '[^&]' ), htmlspecialchars( $regexp, ENT_NOQUOTES ) );
172
173
	foreach ( compact( 'regexp', 'regexp_ent' ) as $reg => $regexp ) {
174
		if ( ! preg_match_all( $regexp, $content, $matches, PREG_SET_ORDER ) ) {
175
			continue;
176
		}
177
178
		foreach ( $matches as $match ) {
179
			$content = str_replace( $match[0], $match[1], $content );
180
		}
181
	}
182
183
	/** This action is documented in modules/widgets/social-media-icons.php */
184
	do_action( 'jetpack_bump_stats_extras', 'html_to_shortcode', 'getty' );
185
186
	return $content;
187
}
188
189
/**
190
 * Parse shortcode arguments and render its output.
191
 *
192
 * @since 4.5.0
193
 *
194
 * @param array  $atts    Shortcode parameters.
195
 * @param string $content Content enclosed by shortcode tags.
196
 *
197
 * @return string
198
 */
199
function jetpack_getty_shortcode( $atts, $content = '' ) {
200
201 View Code Duplication
	if ( ! empty( $content ) ) {
202
		$src = $content;
203
	} elseif ( ! empty( $atts['src'] ) ) {
204
		$src = $atts['src'];
205
	} elseif ( ! empty( $atts[0] ) ) {
206
		$src = $atts[0];
207
	} else {
208
		return '<!-- Missing Getty Source ID -->';
209
	}
210
211
	$src = preg_replace( '/^([\da-z-]+(,[\da-z-]+)*).*$/', '$1', $src );
212
213
	$params = array(
214
		'width'  => isset( $atts['width'] ) ? (int) $atts['width'] : null,
215
		'height' => isset( $atts['height'] ) ? (int) $atts['height'] : null,
216
	);
217
218
	if ( ! empty( $atts['tld'] ) ) {
219
		$params['tld'] = $atts['tld'];
220
	}
221
222
	return wp_oembed_get( 'https://gty.im/' . $src, array_filter( $params ) );
223
}
224