embed.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. namespace Elementor;
  3. if ( ! defined( 'ABSPATH' ) ) {
  4. exit; // Exit if accessed directly.
  5. }
  6. /**
  7. * Elementor embed.
  8. *
  9. * Elementor embed handler class is responsible for Elementor embed functionality.
  10. * The class holds the supported providers with their embed patters, and handles
  11. * their custom properties to create custom HTML with the embeded content.
  12. *
  13. * @since 1.5.0
  14. */
  15. class Embed {
  16. /**
  17. * Provider match masks.
  18. *
  19. * Holds a list of supported providers with their URL structure in a regex format.
  20. *
  21. * @since 1.5.0
  22. * @access private
  23. * @static
  24. *
  25. * @var array Provider URL structure regex.
  26. */
  27. private static $provider_match_masks = [
  28. 'youtube' => '/^.*(?:youtu\.be\/|youtube(?:-nocookie)?\.com\/(?:(?:watch)?\?(?:.*&)?vi?=|(?:embed|v|vi|user)\/))([^\?&\"\'>]+)/',
  29. 'vimeo' => '/^.*vimeo\.com\/(?:[a-z]*\/)*([‌​0-9]{6,11})[?]?.*/',
  30. 'dailymotion' => '/^.*dailymotion.com\/(?:video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/',
  31. ];
  32. /**
  33. * Embed patterns.
  34. *
  35. * Holds a list of supported providers with their embed patters.
  36. *
  37. * @since 1.5.0
  38. * @access private
  39. * @static
  40. *
  41. * @var array Embed patters.
  42. */
  43. private static $embed_patterns = [
  44. 'youtube' => 'https://www.youtube{NO_COOKIE}.com/embed/{VIDEO_ID}?feature=oembed',
  45. 'vimeo' => 'https://player.vimeo.com/video/{VIDEO_ID}#t={TIME}',
  46. 'dailymotion' => 'https://dailymotion.com/embed/video/{VIDEO_ID}',
  47. ];
  48. /**
  49. * Get video properties.
  50. *
  51. * Retrieve the video properties for a given video URL.
  52. *
  53. * @since 1.5.0
  54. * @access public
  55. * @static
  56. *
  57. * @param string $video_url Video URL.
  58. *
  59. * @return null|array The video properties, or null.
  60. */
  61. public static function get_video_properties( $video_url ) {
  62. foreach ( self::$provider_match_masks as $provider => $match_mask ) {
  63. preg_match( $match_mask, $video_url, $matches );
  64. if ( $matches ) {
  65. return [
  66. 'provider' => $provider,
  67. 'video_id' => $matches[1],
  68. ];
  69. }
  70. }
  71. return null;
  72. }
  73. /**
  74. * Get embed URL.
  75. *
  76. * Retrieve the embed URL for a given video.
  77. *
  78. * @since 1.5.0
  79. * @access public
  80. * @static
  81. *
  82. * @param string $video_url Video URL.
  83. * @param array $embed_url_params Optional. Embed parameters. Default is an
  84. * empty array.
  85. * @param array $options Optional. Embed options. Default is an
  86. * empty array.
  87. *
  88. * @return null|array The video properties, or null.
  89. */
  90. public static function get_embed_url( $video_url, array $embed_url_params = [], array $options = [] ) {
  91. $video_properties = self::get_video_properties( $video_url );
  92. if ( ! $video_properties ) {
  93. return null;
  94. }
  95. $embed_pattern = self::$embed_patterns[ $video_properties['provider'] ];
  96. $replacements = [
  97. '{VIDEO_ID}' => $video_properties['video_id'],
  98. ];
  99. if ( 'youtube' === $video_properties['provider'] ) {
  100. $replacements['{NO_COOKIE}'] = ! empty( $options['privacy'] ) ? '-nocookie' : '';
  101. } elseif ( 'vimeo' === $video_properties['provider'] ) {
  102. $time_text = '';
  103. if ( ! empty( $options['start'] ) ) {
  104. $time_text = date( 'H\hi\ms\s', $options['start'] );
  105. }
  106. $replacements['{TIME}'] = $time_text;
  107. }
  108. $embed_pattern = str_replace( array_keys( $replacements ), $replacements, $embed_pattern );
  109. return add_query_arg( $embed_url_params, $embed_pattern );
  110. }
  111. /**
  112. * Get embed HTML.
  113. *
  114. * Retrieve the final HTML of the embedded URL.
  115. *
  116. * @since 1.5.0
  117. * @access public
  118. * @static
  119. *
  120. * @param string $video_url Video URL.
  121. * @param array $embed_url_params Optional. Embed parameters. Default is an
  122. * empty array.
  123. * @param array $options Optional. Embed options. Default is an
  124. * empty array.
  125. * @param array $frame_attributes Optional. IFrame attributes. Default is an
  126. * empty array.
  127. *
  128. * @return string The embed HTML.
  129. */
  130. public static function get_embed_html( $video_url, array $embed_url_params = [], array $options = [], array $frame_attributes = [] ) {
  131. $default_frame_attributes = [
  132. 'class' => 'elementor-video-iframe',
  133. 'allowfullscreen',
  134. ];
  135. $video_embed_url = self::get_embed_url( $video_url, $embed_url_params, $options );
  136. if ( ! $video_embed_url ) {
  137. return null;
  138. }
  139. if ( ! $options['lazy_load'] ) {
  140. $default_frame_attributes['src'] = $video_embed_url;
  141. } else {
  142. $default_frame_attributes['data-lazy-load'] = $video_embed_url;
  143. }
  144. $frame_attributes = array_merge( $default_frame_attributes, $frame_attributes );
  145. $attributes_for_print = [];
  146. foreach ( $frame_attributes as $attribute_key => $attribute_value ) {
  147. $attribute_value = esc_attr( $attribute_value );
  148. if ( is_numeric( $attribute_key ) ) {
  149. $attributes_for_print[] = $attribute_value;
  150. } else {
  151. $attributes_for_print[] = sprintf( '%1$s="%2$s"', $attribute_key, $attribute_value );
  152. }
  153. }
  154. $attributes_for_print = implode( ' ', $attributes_for_print );
  155. $iframe_html = "<iframe $attributes_for_print></iframe>";
  156. /** This filter is documented in wp-includes/class-oembed.php */
  157. return apply_filters( 'oembed_result', $iframe_html, $video_url, $frame_attributes );
  158. }
  159. }