PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 14.8.1
Jetpack – WP Security, Backup, Speed, & Growth v14.8.1
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / modules / shortcodes / gist.php
jetpack / modules / shortcodes Last commit date
css 1 year ago images 2 years ago img 2 years ago js 1 year ago archiveorg-book.php 5 years ago archiveorg.php 5 years ago archives.php 5 years ago bandcamp.php 3 years ago brightcove.php 5 years ago cartodb.php 5 years ago class.filter-embedded-html-objects.php 2 years ago codepen.php 5 years ago crowdsignal.php 1 year ago dailymotion.php 3 years ago descript.php 4 years ago facebook.php 1 year ago flatio.php 5 years ago flickr.php 1 year ago getty.php 2 years ago gist.php 1 year ago googleapps.php 2 years ago googlemaps.php 2 years ago googleplus.php 5 years ago gravatar.php 2 years ago houzz.php 5 years ago inline-pdfs.php 4 years ago instagram.php 1 year ago kickstarter.php 3 years ago mailchimp.php 3 years ago medium.php 3 years ago mixcloud.php 2 years ago others.php 1 year ago pinterest.php 2 years ago presentations.php 2 years ago quiz.php 4 years ago recipe.php 1 year ago scribd.php 5 years ago sitemap.php 5 years ago slideshare.php 5 years ago slideshow.php 1 year ago smartframe.php 3 years ago soundcloud.php 3 years ago spotify.php 2 years ago ted.php 5 years ago tweet.php 2 years ago twitchtv.php 5 years ago twitter-timeline.php 5 years ago twitter.php 1 year ago unavailable.php 3 years ago untappd-menu.php 3 years ago upcoming-events.php 1 year ago ustream.php 5 years ago videopress.php 4 years ago vimeo.php 2 years ago vine.php 5 years ago vr.php 2 years ago wufoo.php 3 years ago youtube.php 1 year ago
gist.php
264 lines
1 <?php
2 /**
3 * GitHub's Gist site supports oEmbed but their oembed provider only
4 * returns raw HTML (no styling) and the first little bit of the code.
5 *
6 * Their JavaScript-based embed method is a lot better, so that's what we're using.
7 *
8 * Supported formats:
9 * Full URL: https://gist.github.com/57cc50246aab776e110060926a2face2
10 * Full URL with username: https://gist.github.com/jeherve/57cc50246aab776e110060926a2face2
11 * Full URL linking to specific file: https://gist.github.com/jeherve/57cc50246aab776e110060926a2face2#file-wp-config-php
12 * Full URL, no username, linking to specific file: https://gist.github.com/57cc50246aab776e110060926a2face2#file-wp-config-php
13 * Gist ID: [gist]57cc50246aab776e110060926a2face2[/gist]
14 * Gist ID within tag: [gist 57cc50246aab776e110060926a2face2]
15 * Gist ID with username: [gist jeherve/57cc50246aab776e110060926a2face2]
16 * Gist private ID with username: [gist xknown/fc5891af153e2cf365c9]
17 *
18 * @package automattic/jetpack
19 */
20
21 wp_embed_register_handler( 'github-gist', '#https?://gist\.github\.com/([a-zA-Z0-9/]+)(\#file\-[a-zA-Z0-9\_\-]+)?#', 'github_gist_embed_handler' );
22 add_shortcode( 'gist', 'github_gist_shortcode' );
23
24 /**
25 * Handle gist embeds.
26 *
27 * @since 2.8.0
28 *
29 * @global WP_Embed $wp_embed
30 *
31 * @param array $matches Results after parsing the URL using the regex in wp_embed_register_handler().
32 * @param array $attr Embed attributes.
33 * @param string $url The original URL that was matched by the regex.
34 * @param array $rawattr The original unmodified attributes.
35 * @return string The embed HTML.
36 */
37 function github_gist_embed_handler( $matches, $attr, $url, $rawattr ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
38 // Let the shortcode callback do all the work.
39 return github_gist_shortcode( $matches, $url );
40 }
41
42 /**
43 * Extract an ID from a Gist shortcode or a full Gist URL.
44 *
45 * @since 7.3.0
46 *
47 * @param string $gist Gist shortcode or full Gist URL.
48 *
49 * @return array $gist_info {
50 * Array of information about our gist.
51 * @type string $id Unique identifier for the gist.
52 * @type string $file File name if the gist links to a specific file.
53 * }
54 */
55 function jetpack_gist_get_shortcode_id( $gist = '' ) {
56 $gist_info = array(
57 'id' => '',
58 'file' => '',
59 'ts' => 8,
60 );
61 // Simple shortcode, with just an ID.
62 if ( ctype_alnum( $gist ) ) {
63 $gist_info['id'] = $gist;
64 }
65
66 // Full URL? Only keep the relevant parts.
67 $parsed_url = wp_parse_url( $gist );
68 if (
69 ! empty( $parsed_url )
70 && is_array( $parsed_url )
71 && isset( $parsed_url['scheme'] ) && isset( $parsed_url['host'] ) && isset( $parsed_url['path'] )
72 ) {
73 // Not a Gist URL? Bail.
74 if ( 'gist.github.com' !== $parsed_url['host'] ) {
75 return array(
76 'id' => '',
77 'file' => '',
78 'ts' => 8,
79 );
80 }
81
82 // Keep the file name if there was one.
83 if ( ! empty( $parsed_url['fragment'] ) ) {
84 $gist_info['file'] = preg_replace( '/(?:file-)(.+)/', '$1', $parsed_url['fragment'] );
85 }
86
87 // Validate the path structure - should be either username/gistid or just gistid
88 $path = trim( $parsed_url['path'], '/' );
89 if ( ! preg_match( '#^([a-zA-Z0-9_-]+/)?([a-f0-9]+)$#', $path ) ) {
90 return array(
91 'id' => '',
92 'file' => '',
93 'ts' => 8,
94 );
95 }
96
97 $gist_info['id'] = $path;
98 // Reassign $gist with the identifier to clean it up below.
99 $gist = $path;
100
101 // Parse the query args to obtain the tab spacing.
102 if ( ! empty( $parsed_url['query'] ) ) {
103 $query_args = array();
104 wp_parse_str( $parsed_url['query'], $query_args );
105 if ( ! empty( $query_args['ts'] ) ) {
106 $gist_info['ts'] = absint( $query_args['ts'] );
107 }
108 }
109 }
110
111 // Not a URL nor an ID? Look for "username/id", "/username/id", or "id", and only keep the ID.
112 if ( preg_match( '#^/?(([a-z0-9_-]+/)?([a-z0-9]+))$#i', $gist, $matches ) ) {
113 $gist_info['id'] = $matches[3];
114 }
115
116 return $gist_info;
117 }
118
119 /**
120 * Callback for gist shortcode.
121 *
122 * @since 2.8.0
123 *
124 * @param array $atts Attributes found in the shortcode.
125 * @param string $content Content enclosed by the shortcode.
126 *
127 * @return string The gist HTML.
128 */
129 function github_gist_shortcode( $atts, $content = '' ) {
130
131 if ( empty( $atts[0] ) && empty( $content ) ) {
132 if ( current_user_can( 'edit_posts' ) ) {
133 return esc_html__( 'Please specify a Gist URL or ID.', 'jetpack' );
134 } else {
135 return '<!-- Missing Gist ID -->';
136 }
137 }
138
139 $id = ( ! empty( $content ) ) ? $content : $atts[0];
140
141 // Parse a URL to get an ID we can use.
142 $gist_info = jetpack_gist_get_shortcode_id( $id );
143 if ( empty( $gist_info['id'] ) ) {
144 if ( current_user_can( 'edit_posts' ) ) {
145 return esc_html__( 'The Gist ID you provided is not valid. Please try a different one.', 'jetpack' );
146 } else {
147 return '<!-- Invalid Gist ID -->';
148 }
149 } else {
150 // Add trailing .json to all unique gist identifiers.
151 $id = $gist_info['id'] . '.json';
152 }
153
154 // The file name can come from the URL passed, or from a shortcode attribute.
155 if ( ! empty( $gist_info['file'] ) ) {
156 $file = $gist_info['file'];
157 } elseif ( ! empty( $atts['file'] ) ) {
158 $file = $atts['file'];
159 } else {
160 $file = '';
161 }
162
163 // Replace - by . to get a real file name from slug.
164 if ( ! empty( $file ) ) {
165 // Find the last -.
166 $dash_position = strrpos( $file, '-' );
167 if ( false !== $dash_position ) {
168 // Replace the - by a period.
169 $file = substr_replace( $file, '.', $dash_position, 1 );
170 }
171
172 $file = rawurlencode( $file );
173 }
174
175 // Set the tab size, allowing attributes to override the query string.
176 $tab_size = $gist_info['ts'];
177 if ( ! empty( $atts['ts'] ) ) {
178 $tab_size = absint( $atts['ts'] );
179 }
180
181 if (
182 class_exists( 'Jetpack_AMP_Support' )
183 && Jetpack_AMP_Support::is_amp_request()
184 ) {
185 /*
186 * According to <https://www.ampproject.org/docs/reference/components/amp-gist#height-(required)>:
187 *
188 * > Note: You must find the height of the gist by inspecting it with your browser (e.g., Chrome Developer Tools).
189 *
190 * However, this does not seem to be the case any longer. The actual height of the content does get set in the
191 * page after loading. So this is just the initial height.
192 * See <https://github.com/ampproject/amphtml/pull/17738>.
193 */
194 $height = 240;
195
196 $amp_tag = sprintf(
197 '<amp-gist layout="fixed-height" data-gistid="%s" height="%s"',
198 esc_attr( basename( $id, '.json' ) ),
199 esc_attr( $height )
200 );
201 if ( ! empty( $file ) ) {
202 $amp_tag .= sprintf( ' data-file="%s"', esc_attr( $file ) );
203 }
204 $amp_tag .= '></amp-gist>';
205 return $amp_tag;
206 }
207
208 // URL points to the entire gist, including the file name if there was one.
209 $id = ( ! empty( $file ) ? $id . '?file=' . $file : $id );
210 $return = false;
211
212 $request = wp_remote_get( esc_url_raw( 'https://gist.github.com/' . esc_attr( $id ) ) );
213 $request_code = wp_remote_retrieve_response_code( $request );
214
215 if ( 200 === $request_code ) {
216 $request_body = wp_remote_retrieve_body( $request );
217 $request_data = json_decode( $request_body );
218
219 wp_enqueue_style( 'jetpack-gist-styling', esc_url( $request_data->stylesheet ), array(), JETPACK__VERSION );
220
221 $gist = substr_replace( $request_data->div, sprintf( 'style="tab-size: %1$s" ', absint( $tab_size ) ), 5, 0 );
222
223 // Add inline styles for the tab style in the opening div of the gist.
224 $gist = preg_replace(
225 '#(\<div\s)+(id=\"gist[0-9]+\")+(\sclass=\"gist\"\>)?#',
226 sprintf( '$1style="tab-size: %1$s" $2$3', absint( $tab_size ) ),
227 $request_data->div,
228 1
229 );
230
231 // Add inline style to prevent the bottom margin to the embed that themes like TwentyTen, et al., add to tables.
232 $return = sprintf( '<style>.gist table { margin-bottom: 0; }</style>%1$s', $gist );
233 }
234
235 if (
236 // No need to check for a nonce here, that's already handled by Core further up.
237 // phpcs:disable WordPress.Security.NonceVerification.Missing
238 isset( $_POST['type'] )
239 && 'embed' === $_POST['type']
240 && isset( $_POST['action'] )
241 && 'parse-embed' === $_POST['action']
242 // phpcs:enable WordPress.Security.NonceVerification.Missing
243 ) {
244 return github_gist_simple_embed( $id, $tab_size );
245 }
246
247 return $return;
248 }
249
250 /**
251 * Use script tag to load shortcode in editor.
252 * Can't use wp_enqueue_script here.
253 *
254 * @since 3.9.0
255 *
256 * @param string $id The ID of the gist.
257 * @param int $tab_size The tab size of the gist.
258 * @return string The script tag of the gist.
259 */
260 function github_gist_simple_embed( $id, $tab_size = 8 ) {
261 $id = str_replace( 'json', 'js', $id );
262 return '<script src="' . esc_url( "https://gist.github.com/$id?ts=$tab_size" ) . '"></script>'; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
263 }
264