PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
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 / jetpack_vendor / automattic / jetpack-post-media / src / class-shortcodes.php
jetpack / jetpack_vendor / automattic / jetpack-post-media / src Last commit date
class-images.php 2 months ago class-post-media.php 1 month ago class-shortcodes.php 6 months ago class-twitter-cards.php 5 months ago
class-shortcodes.php
255 lines
1 <?php
2 /**
3 * Shortcode ID extraction methods.
4 *
5 * Provides static methods to extract identifiers from shortcode attributes
6 * for various media types (YouTube, Vimeo, TED, VideoPress, etc.).
7 *
8 * @package automattic/jetpack-post-media
9 */
10
11 namespace Automattic\Jetpack;
12
13 /**
14 * Extracts media identifiers from shortcode attributes.
15 *
16 * @since 0.1.0
17 */
18 class Shortcodes {
19
20 /**
21 * Get an ID from a shortcode attribute by key.
22 *
23 * Used for shortcodes that store their identifier in a single attribute,
24 * e.g. ted and hulu use a named 'id' attribute, while wpvideo and
25 * videopress use the first positional attribute.
26 *
27 * @since 0.1.0
28 *
29 * @param array $atts Shortcode attributes.
30 * @param string|int $key The attribute key to look up. Defaults to 0 (first positional attribute).
31 * @return string|int The attribute value, or 0 if not found.
32 */
33 public static function get_attribute_id( $atts, $key = 0 ) {
34 return ! empty( $atts[ $key ] ) ? $atts[ $key ] : 0;
35 }
36
37 /**
38 * Normalizes a YouTube URL to include a v= parameter and a query string free of encoded ampersands.
39 *
40 * Handles youtu.be short links, /v/ paths, /shorts/ paths, playlist URLs, and encoded ampersands.
41 *
42 * @since 0.1.0
43 *
44 * @param string|array $url YouTube URL, or an array with a 'url' key.
45 * @return string|false The normalized URL, or false if input is invalid.
46 */
47 public static function sanitize_youtube_url( $url ) {
48 if ( is_array( $url ) && isset( $url['url'] ) ) {
49 $url = $url['url'];
50 }
51 if ( ! is_string( $url ) ) {
52 return false;
53 }
54
55 $url = trim( $url, ' "' );
56 $url = trim( $url );
57 $url = str_replace(
58 array( 'youtu.be/', '/v/', '/shorts/', '#!v=', '&amp;', '&#038;', 'playlist' ),
59 array( 'youtu.be/?v=', '/?v=', '/watch?v=', '?v=', '&', '&', 'videoseries' ),
60 $url
61 );
62
63 // Replace any extra question marks with ampersands - the result of a URL like
64 // "https://www.youtube.com/v/dQw4w9WgXcQ?fs=1&hl=en_US" being passed in.
65 $query_string_start = strpos( $url, '?' );
66
67 if ( false !== $query_string_start ) {
68 $url = substr( $url, 0, $query_string_start + 1 ) . str_replace( '?', '&', substr( $url, $query_string_start + 1 ) );
69 }
70
71 return $url;
72 }
73
74 /**
75 * Extract a YouTube video or playlist ID from shortcode attributes.
76 *
77 * @since 0.1.0
78 *
79 * @param string|array $atts Shortcode attributes. Can be just the URL string or the full $atts array.
80 * @return string|false The YouTube video or playlist ID, or false on failure.
81 */
82 public static function get_youtube_id( $atts ) {
83 // Do we have an $atts array? Get first att.
84 if ( is_array( $atts ) ) {
85 $atts = reset( $atts );
86 }
87
88 $url = self::sanitize_youtube_url( $atts );
89
90 if ( ! is_string( $url ) || '' === $url ) {
91 return false;
92 }
93
94 $parsed = parse_url( $url ); // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url
95
96 if ( ! is_array( $parsed ) || ! isset( $parsed['query'] ) ) {
97 return false;
98 }
99
100 parse_str( $parsed['query'], $qargs );
101
102 if ( ! isset( $qargs['v'] ) && ! isset( $qargs['list'] ) ) {
103 return false;
104 }
105
106 $id = '';
107
108 if ( isset( $qargs['list'] ) ) {
109 $id = preg_replace( '|[^_a-z0-9-]|i', '', $qargs['list'] );
110 }
111
112 if ( empty( $id ) && isset( $qargs['v'] ) ) {
113 $id = preg_replace( '|[^_a-z0-9-]|i', '', $qargs['v'] );
114 }
115
116 return empty( $id ) ? false : $id;
117 }
118
119 /**
120 * Extract a Vimeo video ID from shortcode attributes.
121 *
122 * Supports numeric IDs and various Vimeo URL formats including
123 * groups, albums, channels, and player URLs.
124 *
125 * @since 0.1.0
126 *
127 * @param array $atts Shortcode attributes.
128 * @return int The Vimeo video ID, or 0 if not found.
129 */
130 public static function get_vimeo_id( $atts ) {
131 if ( isset( $atts[0] ) ) {
132 $atts[0] = trim( $atts[0], '=' );
133 if ( is_numeric( $atts[0] ) ) {
134 return (int) $atts[0];
135 }
136
137 /**
138 * Extract Vimeo ID from the URL. For examples:
139 * https://vimeo.com/12345
140 * https://vimeo.com/289091934/cd1f466bcc
141 * https://vimeo.com/album/2838732/video/6342264
142 * https://vimeo.com/groups/758728/videos/897094040
143 * https://vimeo.com/channels/staffpicks/videos/123456789
144 * https://vimeo.com/album/1234567/video/7654321
145 * https://player.vimeo.com/video/18427511
146 */
147 $pattern = '/(?:https?:\/\/)?vimeo\.com\/(?:groups\/[^\/]+\/videos\/|album\/\d+\/video\/|video\/|channels\/[^\/]+\/videos\/|[^\/]+\/)?([0-9]+)(?:[^\'\"0-9<]|$)/i';
148 $match = array();
149 if ( preg_match( $pattern, $atts[0], $match ) ) {
150 return (int) $match[1];
151 }
152 }
153
154 return 0;
155 }
156
157 /**
158 * Get the unique ID of a TED video from shortcode attributes.
159 *
160 * @since 0.1.0
161 *
162 * @param array $atts Shortcode attributes.
163 * @return string|int The TED video ID, or 0 if not found.
164 */
165 public static function get_ted_id( $atts ) {
166 return self::get_attribute_id( $atts, 'id' );
167 }
168
169 /**
170 * Get a VideoPress ID from wpvideo shortcode attributes.
171 *
172 * @since 0.1.0
173 *
174 * @param array $atts Shortcode attributes.
175 * @return string|int The VideoPress ID, or 0 if not found.
176 */
177 public static function get_wpvideo_id( $atts ) {
178 return self::get_attribute_id( $atts );
179 }
180
181 /**
182 * Get a VideoPress ID from videopress shortcode attributes.
183 *
184 * @since 0.1.0
185 *
186 * @param array $atts Shortcode attributes.
187 * @return string|int The VideoPress ID, or 0 if not found.
188 */
189 public static function get_videopress_id( $atts ) {
190 return self::get_attribute_id( $atts );
191 }
192
193 /**
194 * Get a Hulu video ID from shortcode attributes.
195 *
196 * @since 0.1.0
197 *
198 * @param array $atts Shortcode attributes.
199 * @return string|int The Hulu video ID, or 0 if not found.
200 */
201 public static function get_hulu_id( $atts ) {
202 return self::get_attribute_id( $atts, 'id' );
203 }
204
205 /**
206 * Get an Archive.org embed ID from shortcode attributes.
207 *
208 * Extracts the identifier from an Archive.org details or embed URL,
209 * or uses the raw attribute value if it is not a URL.
210 *
211 * @since 0.1.0
212 *
213 * @param array $atts Shortcode attributes.
214 * @return string|int The Archive.org identifier, the raw attribute value
215 * (which may be empty), or 0 if the attribute is not set.
216 */
217 public static function get_archiveorg_id( $atts ) {
218 if ( isset( $atts[0] ) ) {
219 $atts[0] = trim( $atts[0], '=' );
220 if ( preg_match( '~archive\.org/(details|embed)/([^/?#]+)~i', $atts[0], $match ) ) {
221 $id = $match[2];
222 } else {
223 $id = $atts[0];
224 }
225 return $id;
226 }
227 return 0;
228 }
229
230 /**
231 * Get an Archive.org book embed ID from shortcode attributes.
232 *
233 * Extracts the identifier from an Archive.org stream URL,
234 * or uses the raw attribute value if it is not a URL.
235 *
236 * @since 0.1.0
237 *
238 * @param array $atts Shortcode attributes.
239 * @return string|int The Archive.org book identifier, the raw attribute value
240 * (which may be empty), or 0 if the attribute is not set.
241 */
242 public static function get_archiveorg_book_id( $atts ) {
243 if ( isset( $atts[0] ) ) {
244 $atts[0] = trim( $atts[0], '=' );
245 if ( preg_match( '~archive\.org/stream/([^/?#]+)~i', $atts[0], $match ) ) {
246 $id = $match[1];
247 } else {
248 $id = $atts[0];
249 }
250 return $id;
251 }
252 return 0;
253 }
254 }
255