PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 15.9-a.7
Jetpack – WP Security, Backup, Speed, & Growth v15.9-a.7
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 2 weeks ago images 1 year ago img 4 weeks ago js 6 months ago archiveorg-book.php 6 months ago archiveorg.php 6 months ago archives.php 2 weeks ago bandcamp.php 6 months ago brightcove.php 5 months ago cartodb.php 6 months ago class.filter-embedded-html-objects.php 6 months ago codepen.php 6 months ago crowdsignal.php 5 months ago dailymotion.php 6 months ago descript.php 6 months ago facebook.php 6 months ago flatio.php 6 months ago flickr.php 5 months ago getty.php 6 months ago gist.php 6 months ago googleapps.php 6 months ago googlemaps.php 3 weeks ago googleplus.php 6 months ago gravatar.php 6 months ago houzz.php 6 months ago inline-pdfs.php 6 months ago instagram.php 6 months ago kickstarter.php 6 months ago mailchimp.php 5 months ago medium.php 6 months ago mixcloud.php 6 months ago others.php 6 months ago pinterest.php 6 months ago presentations.php 6 months ago quiz.php 6 months ago recipe.php 6 months ago scribd.php 6 months ago shortcode-utils.php 6 months ago sitemap.php 6 months ago slideshare.php 6 months ago slideshow.php 4 weeks ago smartframe.php 6 months ago soundcloud.php 6 months ago spotify.php 6 months ago ted.php 6 months ago tweet.php 6 months ago twitchtv.php 6 months ago twitter-timeline.php 6 months ago twitter.php 6 months ago unavailable.php 6 months ago untappd-menu.php 6 months ago upcoming-events.php 6 months ago ustream.php 6 months ago videopress.php 6 months ago vimeo.php 1 week ago vine.php 6 months ago vr.php 1 week ago wufoo.php 6 months ago youtube.php 3 months ago
gist.php
268 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 if ( ! defined( 'ABSPATH' ) ) {
22 exit( 0 );
23 }
24
25 wp_embed_register_handler( 'github-gist', '#https?://gist\.github\.com/([a-zA-Z0-9/]+)(\#file\-[a-zA-Z0-9\_\-]+)?#', 'github_gist_embed_handler' );
26 add_shortcode( 'gist', 'github_gist_shortcode' );
27
28 /**
29 * Handle gist embeds.
30 *
31 * @since 2.8.0
32 *
33 * @global WP_Embed $wp_embed
34 *
35 * @param array $matches Results after parsing the URL using the regex in wp_embed_register_handler().
36 * @param array $attr Embed attributes.
37 * @param string $url The original URL that was matched by the regex.
38 * @param array $rawattr The original unmodified attributes.
39 * @return string The embed HTML.
40 */
41 function github_gist_embed_handler( $matches, $attr, $url, $rawattr ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
42 // Let the shortcode callback do all the work.
43 return github_gist_shortcode( $matches, $url );
44 }
45
46 /**
47 * Extract an ID from a Gist shortcode or a full Gist URL.
48 *
49 * @since 7.3.0
50 *
51 * @param string $gist Gist shortcode or full Gist URL.
52 *
53 * @return array $gist_info {
54 * Array of information about our gist.
55 * @type string $id Unique identifier for the gist.
56 * @type string $file File name if the gist links to a specific file.
57 * }
58 */
59 function jetpack_gist_get_shortcode_id( $gist = '' ) {
60 $gist_info = array(
61 'id' => '',
62 'file' => '',
63 'ts' => 8,
64 );
65 // Simple shortcode, with just an ID.
66 if ( ctype_alnum( $gist ) ) {
67 $gist_info['id'] = $gist;
68 }
69
70 // Full URL? Only keep the relevant parts.
71 $parsed_url = wp_parse_url( $gist );
72 if (
73 ! empty( $parsed_url )
74 && is_array( $parsed_url )
75 && isset( $parsed_url['scheme'] ) && isset( $parsed_url['host'] ) && isset( $parsed_url['path'] )
76 ) {
77 // Not a Gist URL? Bail.
78 if ( 'gist.github.com' !== $parsed_url['host'] ) {
79 return array(
80 'id' => '',
81 'file' => '',
82 'ts' => 8,
83 );
84 }
85
86 // Keep the file name if there was one.
87 if ( ! empty( $parsed_url['fragment'] ) ) {
88 $gist_info['file'] = preg_replace( '/(?:file-)(.+)/', '$1', $parsed_url['fragment'] );
89 }
90
91 // Validate the path structure - should be either username/gistid or just gistid
92 $path = trim( $parsed_url['path'], '/' );
93 if ( ! preg_match( '#^([a-zA-Z0-9_-]+/)?([a-f0-9]+)$#', $path ) ) {
94 return array(
95 'id' => '',
96 'file' => '',
97 'ts' => 8,
98 );
99 }
100
101 $gist_info['id'] = $path;
102 // Reassign $gist with the identifier to clean it up below.
103 $gist = $path;
104
105 // Parse the query args to obtain the tab spacing.
106 if ( ! empty( $parsed_url['query'] ) ) {
107 $query_args = array();
108 wp_parse_str( $parsed_url['query'], $query_args );
109 if ( ! empty( $query_args['ts'] ) ) {
110 $gist_info['ts'] = absint( $query_args['ts'] );
111 }
112 }
113 }
114
115 // Not a URL nor an ID? Look for "username/id", "/username/id", or "id", and only keep the ID.
116 if ( preg_match( '#^/?(([a-z0-9_-]+/)?([a-z0-9]+))$#i', $gist, $matches ) ) {
117 $gist_info['id'] = $matches[3];
118 }
119
120 return $gist_info;
121 }
122
123 /**
124 * Callback for gist shortcode.
125 *
126 * @since 2.8.0
127 *
128 * @param array $atts Attributes found in the shortcode.
129 * @param string $content Content enclosed by the shortcode.
130 *
131 * @return string The gist HTML.
132 */
133 function github_gist_shortcode( $atts, $content = '' ) {
134
135 if ( empty( $atts[0] ) && empty( $content ) ) {
136 if ( current_user_can( 'edit_posts' ) ) {
137 return esc_html__( 'Please specify a Gist URL or ID.', 'jetpack' );
138 } else {
139 return '<!-- Missing Gist ID -->';
140 }
141 }
142
143 $id = ( ! empty( $content ) ) ? $content : $atts[0];
144
145 // Parse a URL to get an ID we can use.
146 $gist_info = jetpack_gist_get_shortcode_id( $id );
147 if ( empty( $gist_info['id'] ) ) {
148 if ( current_user_can( 'edit_posts' ) ) {
149 return esc_html__( 'The Gist ID you provided is not valid. Please try a different one.', 'jetpack' );
150 } else {
151 return '<!-- Invalid Gist ID -->';
152 }
153 } else {
154 // Add trailing .json to all unique gist identifiers.
155 $id = $gist_info['id'] . '.json';
156 }
157
158 // The file name can come from the URL passed, or from a shortcode attribute.
159 if ( ! empty( $gist_info['file'] ) ) {
160 $file = $gist_info['file'];
161 } elseif ( ! empty( $atts['file'] ) ) {
162 $file = $atts['file'];
163 } else {
164 $file = '';
165 }
166
167 // Replace - by . to get a real file name from slug.
168 if ( ! empty( $file ) ) {
169 // Find the last -.
170 $dash_position = strrpos( $file, '-' );
171 if ( false !== $dash_position ) {
172 // Replace the - by a period.
173 $file = substr_replace( $file, '.', $dash_position, 1 );
174 }
175
176 $file = rawurlencode( $file );
177 }
178
179 // Set the tab size, allowing attributes to override the query string.
180 $tab_size = $gist_info['ts'];
181 if ( ! empty( $atts['ts'] ) ) {
182 $tab_size = absint( $atts['ts'] );
183 }
184
185 if (
186 class_exists( 'Jetpack_AMP_Support' )
187 && Jetpack_AMP_Support::is_amp_request()
188 ) {
189 /*
190 * According to <https://www.ampproject.org/docs/reference/components/amp-gist#height-(required)>:
191 *
192 * > Note: You must find the height of the gist by inspecting it with your browser (e.g., Chrome Developer Tools).
193 *
194 * However, this does not seem to be the case any longer. The actual height of the content does get set in the
195 * page after loading. So this is just the initial height.
196 * See <https://github.com/ampproject/amphtml/pull/17738>.
197 */
198 $height = 240;
199
200 $amp_tag = sprintf(
201 '<amp-gist layout="fixed-height" data-gistid="%s" height="%s"',
202 esc_attr( basename( $id, '.json' ) ),
203 esc_attr( $height )
204 );
205 if ( ! empty( $file ) ) {
206 $amp_tag .= sprintf( ' data-file="%s"', esc_attr( $file ) );
207 }
208 $amp_tag .= '></amp-gist>';
209 return $amp_tag;
210 }
211
212 // URL points to the entire gist, including the file name if there was one.
213 $id = ( ! empty( $file ) ? $id . '?file=' . $file : $id );
214 $return = false;
215
216 $request = wp_remote_get( esc_url_raw( 'https://gist.github.com/' . esc_attr( $id ) ) );
217 $request_code = wp_remote_retrieve_response_code( $request );
218
219 if ( 200 === $request_code ) {
220 $request_body = wp_remote_retrieve_body( $request );
221 $request_data = json_decode( $request_body );
222
223 wp_enqueue_style( 'jetpack-gist-styling', esc_url( $request_data->stylesheet ), array(), JETPACK__VERSION );
224
225 $gist = substr_replace( $request_data->div, sprintf( 'style="tab-size: %1$s" ', absint( $tab_size ) ), 5, 0 );
226
227 // Add inline styles for the tab style in the opening div of the gist.
228 $gist = preg_replace(
229 '#(\<div\s)+(id=\"gist[0-9]+\")+(\sclass=\"gist\"\>)?#',
230 sprintf( '$1style="tab-size: %1$s" $2$3', absint( $tab_size ) ),
231 $request_data->div,
232 1
233 );
234
235 // Add inline style to prevent the bottom margin to the embed that themes like TwentyTen, et al., add to tables.
236 $return = sprintf( '<style>.gist table { margin-bottom: 0; }</style>%1$s', $gist );
237 }
238
239 if (
240 // No need to check for a nonce here, that's already handled by Core further up.
241 // phpcs:disable WordPress.Security.NonceVerification.Missing
242 isset( $_POST['type'] )
243 && 'embed' === $_POST['type']
244 && isset( $_POST['action'] )
245 && 'parse-embed' === $_POST['action']
246 // phpcs:enable WordPress.Security.NonceVerification.Missing
247 ) {
248 return github_gist_simple_embed( $id, $tab_size );
249 }
250
251 return $return;
252 }
253
254 /**
255 * Use script tag to load shortcode in editor.
256 * Can't use wp_enqueue_script here.
257 *
258 * @since 3.9.0
259 *
260 * @param string $id The ID of the gist.
261 * @param int $tab_size The tab size of the gist.
262 * @return string The script tag of the gist.
263 */
264 function github_gist_simple_embed( $id, $tab_size = 8 ) {
265 $id = str_replace( 'json', 'js', $id );
266 return '<script src="' . esc_url( "https://gist.github.com/$id?ts=$tab_size" ) . '"></script>'; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
267 }
268