PluginProbe
Elementor Website Builder – more than just a page builder / 4.1.0-dev3
Elementor Website Builder – more than just a page builder v4.1.0-dev3
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.1.0-dev3, at includes/embed.php

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