PluginProbe
Elementor Website Builder – more than just a page builder / 4.2.4
Elementor Website Builder – more than just a page builder v4.2.4
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / includes / embed.php

embed.php in Elementor Website Builder – more than just a page builder 4.2.4, at includes/embed.php

326 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 /**
9 * Elementor embed.
10 *
11 * Elementor embed handler class is responsible for Elementor embed functionality.
12 * The class holds the supported providers with their embed patters, and handles
13 * their custom properties to create custom HTML with the embedded content.
14 *
15 * @since 1.5.0
16 */
17 class Embed {
18
19 /**
20 * Embeddable background video providers.
21 *
22 * Holds the list of providers whose background video is rendered as an embedded
23 * iframe player (.elementor-background-video-embed) rather than a hosted <video>
24 * element. This is intentionally a SUBSET of the providers recognized by
25 * get_video_properties() — the frontend background-video handler only mounts
26 * YouTube/Vimeo players, so other providers must fall through to hosted rendering.
27 *
28 * @access private
29 * @static
30 *
31 * @var array Embeddable background video provider slugs.
32 */
33 private static $video_embed_providers = [ 'youtube', 'vimeo' ];
34
35
36 /**
37 * Provider match masks.
38 *
39 * Holds a list of supported providers with their URL structure in a regex format.
40 *
41 * @since 1.5.0
42 * @access private
43 * @static
44 *
45 * @var array Provider URL structure regex.
46 */
47 private static $provider_match_masks = [
48 'youtube' => '/^.*(?:youtu\.be\/|youtube(?:-nocookie)?\.com\/(?:(?:watch)?\?(?:.*&)?vi?=|(?:embed|v|vi|user|shorts)\/))([^\?&\"\'>]+)/',
49 'vimeo' => '/^.*vimeo\.com\/(?:[a-z]*\/)*([‌​0-9]{6,11})[?]?.*/',
50 'dailymotion' => '/^.*dailymotion.com\/(?:video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/',
51 'videopress' => [
52 '/^(?:http(?:s)?:\/\/)?videos\.files\.wordpress\.com\/([a-zA-Z\d]{8,})\//i',
53 '/^(?:http(?:s)?:\/\/)?(?:www\.)?video(?:\.word)?press\.com\/(?:v|embed)\/([a-zA-Z\d]{8,})(.+)?/i',
54 ],
55 ];
56
57 /**
58 * Embed patterns.
59 *
60 * Holds a list of supported providers with their embed patters.
61 *
62 * @since 1.5.0
63 * @access private
64 * @static
65 *
66 * @var array Embed patters.
67 */
68 private static $embed_patterns = [
69 'youtube' => 'https://www.youtube{NO_COOKIE}.com/embed/{VIDEO_ID}?feature=oembed',
70 'vimeo' => 'https://player.vimeo.com/video/{VIDEO_ID}#t={TIME}',
71 'dailymotion' => 'https://dailymotion.com/embed/video/{VIDEO_ID}',
72 'videopress' => 'https://videopress.com/embed/{VIDEO_ID}',
73 ];
74
75 /**
76 * Get video properties.
77 *
78 * Retrieve the video properties for a given video URL.
79 *
80 * @since 1.5.0
81 * @access public
82 * @static
83 *
84 * @param string $video_url Video URL.
85 *
86 * @return null|array The video properties, or null.
87 */
88 public static function get_video_properties( $video_url ) {
89 foreach ( self::$provider_match_masks as $provider => $match_mask ) {
90 if ( ! is_array( $match_mask ) ) {
91 $match_mask = [ $match_mask ];
92 }
93
94 foreach ( $match_mask as $mask ) {
95 if ( preg_match( $mask, $video_url, $matches ) ) {
96 return [
97 'provider' => $provider,
98 'video_id' => $matches[1],
99 ];
100 }
101 }
102 }
103
104 return null;
105 }
106
107 /**
108 * Is embeddable background video.
109 *
110 * Whether a given video URL belongs to a provider that the frontend
111 * background-video handler renders as an embedded iframe player.
112 *
113 * @param string $video_url Video URL.
114 *
115 * @return bool
116 **/
117 public static function is_embed_video( $video_url ) {
118 $video_properties = self::get_video_properties( $video_url );
119
120 return null !== $video_properties && in_array( $video_properties['provider'], self::$video_embed_providers, true );
121 }
122
123 /**
124 * Get embed URL.
125 *
126 * Retrieve the embed URL for a given video.
127 *
128 * @since 1.5.0
129 * @access public
130 * @static
131 *
132 * @param string $video_url Video URL.
133 * @param array $embed_url_params Optional. Embed parameters. Default is an
134 * empty array.
135 * @param array $options Optional. Embed options. Default is an
136 * empty array.
137 *
138 * @return null|array The video properties, or null.
139 */
140 public static function get_embed_url( $video_url, array $embed_url_params = [], array $options = [] ) {
141 $video_properties = self::get_video_properties( $video_url );
142
143 if ( ! $video_properties ) {
144 return null;
145 }
146
147 $embed_pattern = self::$embed_patterns[ $video_properties['provider'] ];
148
149 $replacements = [
150 '{VIDEO_ID}' => $video_properties['video_id'],
151 ];
152
153 if ( 'youtube' === $video_properties['provider'] ) {
154 $replacements['{NO_COOKIE}'] = ! empty( $options['privacy'] ) ? '-nocookie' : '';
155 } elseif ( 'vimeo' === $video_properties['provider'] ) {
156 $time_text = '';
157
158 if ( ! empty( $options['start'] ) ) {
159 $time_text = date( 'H\hi\ms\s', $options['start'] ); // PHPCS:Ignore WordPress.DateTime.RestrictedFunctions.date_date
160 }
161
162 $replacements['{TIME}'] = $time_text;
163
164 /**
165 * Handle Vimeo private videos
166 *
167 * Vimeo requires an additional parameter when displaying private/unlisted videos. It has two ways of
168 * passing that parameter:
169 * * as an endpoint - vimeo.com/{video_id}/{privacy_token}
170 * OR
171 * * as a GET parameter named `h` - vimeo.com/{video_id}?h={privacy_token}
172 *
173 * The following regex match looks for either of these methods in the Vimeo URL, and if it finds a privacy
174 * token, it adds it to the embed params array as the `h` parameter (which is how Vimeo can receive it when
175 * using Oembed).
176 */
177 $h_param = [];
178 preg_match( '/(?|(?:[\?|\&]h={1})([\w]+)|\d\/([\w]+))/', $video_url, $h_param );
179
180 if ( ! empty( $h_param ) ) {
181 $embed_url_params['h'] = $h_param[1];
182 }
183 }
184
185 $embed_pattern = str_replace( array_keys( $replacements ), $replacements, $embed_pattern );
186
187 return add_query_arg( $embed_url_params, $embed_pattern );
188 }
189
190 /**
191 * Get embed HTML.
192 *
193 * Retrieve the final HTML of the embedded URL.
194 *
195 * @since 1.5.0
196 * @access public
197 * @static
198 *
199 * @param string $video_url Video URL.
200 * @param array $embed_url_params Optional. Embed parameters. Default is an
201 * empty array.
202 * @param array $options Optional. Embed options. Default is an
203 * empty array.
204 * @param array $frame_attributes Optional. IFrame attributes. Default is an
205 * empty array.
206 *
207 * @return string The embed HTML.
208 */
209 public static function get_embed_html( $video_url, array $embed_url_params = [], array $options = [], array $frame_attributes = [] ) {
210 $video_properties = self::get_video_properties( $video_url );
211
212 $default_frame_attributes = [
213 'class' => 'elementor-video-iframe',
214 'allowfullscreen',
215 'allow' => 'clipboard-write',
216 'title' => sprintf(
217 /* translators: %s: Video provider */
218 __( '%s Video Player', 'elementor' ),
219 $video_properties['provider']
220 ),
221 ];
222
223 $video_embed_url = self::get_embed_url( $video_url, $embed_url_params, $options );
224 if ( ! $video_embed_url ) {
225 return null;
226 }
227 if ( ! isset( $options['lazy_load'] ) || ! $options['lazy_load'] ) {
228 $default_frame_attributes['src'] = $video_embed_url;
229 } else {
230 $default_frame_attributes['data-lazy-load'] = $video_embed_url;
231 }
232
233 if ( isset( $embed_url_params['autoplay'] ) ) {
234 $default_frame_attributes['allow'] = 'autoplay';
235 }
236
237 $frame_attributes = array_merge( $default_frame_attributes, $frame_attributes );
238
239 $attributes_for_print = [];
240
241 foreach ( $frame_attributes as $attribute_key => $attribute_value ) {
242 $attribute_value = esc_attr( $attribute_value );
243
244 if ( is_numeric( $attribute_key ) ) {
245 $attributes_for_print[] = $attribute_value;
246 } else {
247 $attributes_for_print[] = sprintf( '%1$s="%2$s"', $attribute_key, $attribute_value );
248 }
249 }
250
251 $attributes_for_print = implode( ' ', $attributes_for_print );
252
253 $iframe_html = "<iframe $attributes_for_print></iframe>";
254
255 /** This filter is documented in wp-includes/class-oembed.php */
256 return apply_filters( 'oembed_result', $iframe_html, $video_url, $frame_attributes );
257 }
258
259 /**
260 * Get oembed data from the cache.
261 * if not exists in the cache it will fetch from provider and then save to the cache.
262 *
263 * @param string $oembed_url
264 * @param string $cached_post_id
265 *
266 * @return array|null
267 */
268 public static function get_oembed_data( $oembed_url, $cached_post_id ) {
269 $cached_oembed_data = json_decode( get_post_meta( $cached_post_id, '_elementor_oembed_cache', true ), true );
270
271 if ( isset( $cached_oembed_data[ $oembed_url ] ) ) {
272 return $cached_oembed_data[ $oembed_url ];
273 }
274
275 $normalize_oembed_data = self::fetch_oembed_data( $oembed_url );
276
277 if ( ! $cached_oembed_data ) {
278 $cached_oembed_data = [];
279 }
280
281 update_post_meta( $cached_post_id, '_elementor_oembed_cache', wp_json_encode( array_merge(
282 $cached_oembed_data,
283 [
284 $oembed_url => $normalize_oembed_data,
285 ]
286 ) ) );
287
288 return $normalize_oembed_data;
289 }
290
291 /**
292 * Fetch oembed data from oembed provider.
293 *
294 * @param string $oembed_url
295 * @return array|null
296 */
297 public static function fetch_oembed_data( $oembed_url ) {
298 $oembed_data = _wp_oembed_get_object()->get_data( $oembed_url );
299
300 if ( ! $oembed_data ) {
301 return null;
302 }
303
304 return [
305 'thumbnail_url' => $oembed_data->thumbnail_url,
306 'title' => $oembed_data->title,
307 ];
308 }
309
310 /**
311 * @param string $oembed_url
312 * @param null|string|int $cached_post_id
313 *
314 * @return string|null
315 */
316 public static function get_embed_thumbnail_html( $oembed_url, $cached_post_id = null ) {
317 $oembed_data = self::get_oembed_data( $oembed_url, $cached_post_id );
318
319 if ( ! $oembed_data ) {
320 return null;
321 }
322
323 return '<div class="elementor-image">' . sprintf( '<img src="%1$s" alt="%2$s" title="%2$s" width="%3$s" loading="lazy" />', $oembed_data['thumbnail_url'], esc_attr( $oembed_data['title'] ), '100%' ) . '</div>';
324 }
325 }
326