PluginProbe
Elementor Website Builder – more than just a page builder / 3.17.1
Elementor Website Builder – more than just a page builder v3.17.1
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 3.17.1, at includes/embed.php

289 lines 8.3 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 embeded 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)\/))([^\?&\"\'>]+)/',
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 'title' => sprintf(
183 /* translators: %s: Video provider */
184 __( '%s Video Player', 'elementor' ),
185 $video_properties['provider']
186 ),
187 ];
188
189 $video_embed_url = self::get_embed_url( $video_url, $embed_url_params, $options );
190 if ( ! $video_embed_url ) {
191 return null;
192 }
193 if ( ! isset( $options['lazy_load'] ) || ! $options['lazy_load'] ) {
194 $default_frame_attributes['src'] = $video_embed_url;
195 } else {
196 $default_frame_attributes['data-lazy-load'] = $video_embed_url;
197 }
198
199 $frame_attributes = array_merge( $default_frame_attributes, $frame_attributes );
200
201 $attributes_for_print = [];
202
203 foreach ( $frame_attributes as $attribute_key => $attribute_value ) {
204 $attribute_value = esc_attr( $attribute_value );
205
206 if ( is_numeric( $attribute_key ) ) {
207 $attributes_for_print[] = $attribute_value;
208 } else {
209 $attributes_for_print[] = sprintf( '%1$s="%2$s"', $attribute_key, $attribute_value );
210 }
211 }
212
213 $attributes_for_print = implode( ' ', $attributes_for_print );
214
215 $iframe_html = "<iframe $attributes_for_print></iframe>";
216
217 /** This filter is documented in wp-includes/class-oembed.php */
218 return apply_filters( 'oembed_result', $iframe_html, $video_url, $frame_attributes );
219 }
220
221 /**
222 * Get oembed data from the cache.
223 * if not exists in the cache it will fetch from provider and then save to the cache.
224 *
225 * @param $oembed_url
226 * @param $cached_post_id
227 *
228 * @return array|null
229 */
230 public static function get_oembed_data( $oembed_url, $cached_post_id ) {
231 $cached_oembed_data = json_decode( get_post_meta( $cached_post_id, '_elementor_oembed_cache', true ), true );
232
233 if ( isset( $cached_oembed_data[ $oembed_url ] ) ) {
234 return $cached_oembed_data[ $oembed_url ];
235 }
236
237 $normalize_oembed_data = self::fetch_oembed_data( $oembed_url );
238
239 if ( ! $cached_oembed_data ) {
240 $cached_oembed_data = [];
241 }
242
243 update_post_meta( $cached_post_id, '_elementor_oembed_cache', wp_json_encode( array_merge(
244 $cached_oembed_data,
245 [
246 $oembed_url => $normalize_oembed_data,
247 ]
248 ) ) );
249
250 return $normalize_oembed_data;
251 }
252
253 /**
254 * Fetch oembed data from oembed provider.
255 *
256 * @param $oembed_url
257 *
258 * @return array|null
259 */
260 public static function fetch_oembed_data( $oembed_url ) {
261 $oembed_data = _wp_oembed_get_object()->get_data( $oembed_url );
262
263 if ( ! $oembed_data ) {
264 return null;
265 }
266
267 return [
268 'thumbnail_url' => $oembed_data->thumbnail_url,
269 'title' => $oembed_data->title,
270 ];
271 }
272
273 /**
274 * @param $oembed_url
275 * @param null|string|int $cached_post_id
276 *
277 * @return string|null
278 */
279 public static function get_embed_thumbnail_html( $oembed_url, $cached_post_id = null ) {
280 $oembed_data = self::get_oembed_data( $oembed_url, $cached_post_id );
281
282 if ( ! $oembed_data ) {
283 return null;
284 }
285
286 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>';
287 }
288 }
289