PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 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 All 508 releases
← All changes | jetpack_vendor/automattic/jetpack-post-media/src/class-shortcodes.php +254 -0 16.2-beta → 16.3-beta View file →
@@ -1,0 +1,254 @@
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 +}