PageRenderTime 30ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/so-widgets-bundle/widgets/video/video.php

https://bitbucket.org/Netbog/mormirkam
PHP | 346 lines | 260 code | 36 blank | 50 comment | 38 complexity | 5c61bb6b3bbb876ba494eaf8d79e1417 MD5 | raw file
Possible License(s): GPL-2.0, MIT
  1. <?php
  2. /*
  3. Widget Name: Video Player
  4. Description: Play all your self or externally hosted videos in a customizable video player.
  5. Author: SiteOrigin
  6. Author URI: https://siteorigin.com
  7. */
  8. class SiteOrigin_Widget_Video_Widget extends SiteOrigin_Widget {
  9. function __construct() {
  10. parent::__construct(
  11. 'sow-video',
  12. __( 'SiteOrigin Video Player', 'so-widgets-bundle' ),
  13. array(
  14. 'description' => __( 'A video player widget.', 'so-widgets-bundle' ),
  15. 'help' => 'http://siteorigin.com/widgets-bundle/video-widget-documentation/'
  16. ),
  17. array(),
  18. false,
  19. plugin_dir_path( __FILE__ )
  20. );
  21. }
  22. function get_widget_form() {
  23. return array(
  24. 'title' => array(
  25. 'type' => 'text',
  26. 'label' => __( 'Title', 'so-widgets-bundle' )
  27. ),
  28. 'host_type' => array(
  29. 'type' => 'radio',
  30. 'label' => __( 'Video location', 'so-widgets-bundle' ),
  31. 'default' => 'self',
  32. 'options' => array(
  33. 'self' => __( 'Self hosted', 'so-widgets-bundle' ),
  34. 'external' => __( 'Externally hosted', 'so-widgets-bundle' ),
  35. ),
  36. // This field should be a video type state emitter
  37. 'state_emitter' => array(
  38. 'callback' => 'select',
  39. 'args' => array( 'video_type' )
  40. )
  41. ),
  42. 'video' => array(
  43. 'type' => 'section',
  44. 'label' => __( 'Video File', 'so-widgets-bundle' ),
  45. 'fields' => array(
  46. 'self_sources' => array(
  47. 'type' => 'repeater',
  48. 'label' => __( 'Sources', 'so-widgets-bundle' ),
  49. 'fields' => array(
  50. 'self_video' => array(
  51. 'type' => 'media',
  52. 'fallback' => true,
  53. 'label' => __( 'Select video', 'so-widgets-bundle' ),
  54. 'default' => '',
  55. 'library' => 'video',
  56. ),
  57. ),
  58. 'state_handler' => array(
  59. 'video_type[self]' => array( 'show' ),
  60. 'video_type[external]' => array( 'hide' ),
  61. ),
  62. ),
  63. 'self_poster' => array(
  64. 'type' => 'media',
  65. 'label' => __( 'Select cover image', 'so-widgets-bundle' ),
  66. 'default' => '',
  67. 'library' => 'image',
  68. 'state_handler' => array(
  69. 'video_type[self]' => array( 'show' ),
  70. 'video_type[external]' => array( 'hide' ),
  71. ),
  72. ),
  73. 'external_video' => array(
  74. 'type' => 'text',
  75. 'sanitize' => 'url',
  76. 'label' => __( 'Video URL', 'so-widgets-bundle' ),
  77. 'state_handler' => array(
  78. 'video_type[external]' => array( 'show' ),
  79. 'video_type[self]' => array( 'hide' ),
  80. ),
  81. ),
  82. ),
  83. ),
  84. 'playback' => array(
  85. 'type' => 'section',
  86. 'label' => __( 'Video Playback', 'so-widgets-bundle' ),
  87. 'fields' => array(
  88. 'autoplay' => array(
  89. 'type' => 'checkbox',
  90. 'default' => false,
  91. 'label' => __( 'Autoplay', 'so-widgets-bundle' )
  92. ),
  93. 'oembed' => array(
  94. 'type' => 'checkbox',
  95. 'default' => true,
  96. 'label' => __( 'Use oEmbed', 'so-widgets-bundle' ),
  97. 'description' => __( 'Always use the embedded video rather than the MediaElement player.', 'so-widgets-bundle' ),
  98. 'state_handler' => array(
  99. 'video_type[external]' => array( 'show' ),
  100. 'video_type[self]' => array( 'hide' ),
  101. )
  102. ),
  103. 'related_videos' => array(
  104. 'type' => 'checkbox',
  105. 'default' => true,
  106. 'label' => __( 'Show related videos.', 'so-widgets-bundle' ),
  107. 'description' => __( 'If the external host supports it.', 'so-widgets-bundle' ),
  108. 'state_handler' => array(
  109. 'video_type[external]' => array( 'show' ),
  110. 'video_type[self]' => array( 'hide' ),
  111. )
  112. ),
  113. ),
  114. ),
  115. );
  116. }
  117. function enqueue_frontend_scripts( $instance ) {
  118. $video_host = empty( $instance['host_type'] ) ? '' : $instance['host_type'];
  119. if ( $video_host == 'external' ) {
  120. $video_host = ! empty( $instance['video']['external_video'] ) ? $this->get_host_from_url( $instance['video']['external_video'] ) : '';
  121. }
  122. if ( $this->is_skinnable_video_host( $video_host ) ) {
  123. if ( $video_host == 'vimeo' && ! wp_script_is( 'froogaloop' ) ) {
  124. wp_enqueue_script( 'froogaloop' );
  125. }
  126. if ( ! wp_style_is( 'sow-html-player-responsive' ) ) {
  127. wp_enqueue_style(
  128. 'html-player-responsive',
  129. plugin_dir_url( __FILE__ ) . 'css/html-player-responsive.css',
  130. array(),
  131. SOW_BUNDLE_VERSION
  132. );
  133. }
  134. if ( ! wp_style_is( 'wp-mediaelement' ) ) {
  135. wp_enqueue_style( 'wp-mediaelement' );
  136. }
  137. if ( ! wp_script_is( 'so-video-widget' ) ) {
  138. wp_enqueue_script(
  139. 'so-video-widget',
  140. plugin_dir_url( __FILE__ ) . 'js/so-video-widget' . SOW_BUNDLE_JS_SUFFIX . '.js',
  141. array( 'jquery', 'mediaelement' ),
  142. SOW_BUNDLE_VERSION
  143. );
  144. }
  145. }
  146. parent::enqueue_frontend_scripts( $instance );
  147. }
  148. function get_template_name( $instance ) {
  149. return 'default';
  150. }
  151. function get_template_variables( $instance, $args ) {
  152. static $player_id = 1;
  153. $self_sources = array();
  154. $external_src = '';
  155. $external_video_type = '';
  156. $poster = '';
  157. $video_host = $instance['host_type'];
  158. if ( $video_host == 'self' ) {
  159. if ( isset( $instance['video']['self_sources'] ) ) {
  160. foreach ( $instance['video']['self_sources'] as $source ) {
  161. $src = '';
  162. $video_type = '';
  163. if ( ! empty( $source['self_video'] ) ) {
  164. // Handle an attachment video
  165. $src = wp_get_attachment_url( $source['self_video'] );
  166. $video_type = get_post_mime_type( $source['self_video'] );
  167. } else if ( ! empty( $source['self_video_fallback'] ) ) {
  168. // Handle an external URL video
  169. $src = $source['self_video_fallback'];
  170. $vid_info = wp_check_filetype( basename( $source['self_video_fallback'] ) );
  171. $video_type = $vid_info['type'];
  172. }
  173. if ( ! empty( $src ) ) {
  174. $self_sources[] = array( 'src' => $src, 'video_type' => $video_type );
  175. }
  176. }
  177. }
  178. $poster = ! empty( $instance['video']['self_poster'] ) ? wp_get_attachment_url( $instance['video']['self_poster'] ) : '';
  179. } else {
  180. $video_host = $this->get_host_from_url( $instance['video']['external_video'] );
  181. $external_video_type = 'video/' . $video_host;
  182. $external_src = ! empty( $instance['video']['external_video'] ) ? $instance['video']['external_video'] : '';
  183. }
  184. $return = array(
  185. 'player_id' => 'sow-player-' . ( $player_id ++ ),
  186. 'host_type' => $instance['host_type'],
  187. 'src' => $external_src,
  188. 'sources' => $self_sources,
  189. 'video_type' => $external_video_type,
  190. 'is_skinnable_video_host' => $this->is_skinnable_video_host( $video_host ),
  191. 'poster' => $poster,
  192. 'autoplay' => ! empty( $instance['playback']['autoplay'] ),
  193. 'related_videos' => ! empty( $instance['playback']['related_videos'] ),
  194. 'skin_class' => 'default'
  195. );
  196. // Force oEmbed for this video
  197. if ( $instance['host_type'] == 'external' && $instance['playback']['oembed'] ) {
  198. $return['is_skinnable_video_host'] = false;
  199. }
  200. return $return;
  201. }
  202. function get_style_name( $instance ) {
  203. // For now, we'll only use the default style
  204. return '';
  205. }
  206. /**
  207. * Gets a video source embed
  208. */
  209. function get_video_oembed( $src, $autoplay = false, $related_videos = true ) {
  210. if ( empty( $src ) ) {
  211. return '';
  212. }
  213. global $content_width;
  214. $video_width = ! empty( $content_width ) ? $content_width : 640;
  215. $hash = md5( serialize( array(
  216. 'src' => $src,
  217. 'width' => $video_width,
  218. 'autoplay' => $autoplay,
  219. ) ) );
  220. $html = get_transient( 'sow-vid-embed[' . $hash . ']' );
  221. if ( empty( $html ) ) {
  222. $html = wp_oembed_get( $src, array( 'width' => $video_width ) );
  223. if ( $autoplay ) {
  224. $html = preg_replace_callback( '/src=["\'](http[^"\']*)["\']/', array(
  225. $this,
  226. 'autoplay_callback'
  227. ), $html );
  228. }
  229. if ( empty( $related_videos ) ) {
  230. $html = preg_replace_callback( '/src=["\'](http[^"\']*)["\']/', array(
  231. $this,
  232. 'remove_related_videos'
  233. ), $html );
  234. }
  235. if ( ! empty( $html ) ) {
  236. set_transient( 'sow-vid-embed[' . $hash . ']', $html, 30 * 86400 );
  237. }
  238. }
  239. return $html;
  240. }
  241. /**
  242. * The preg_replace callback that adds autoplay.
  243. *
  244. * @param $match
  245. *
  246. * @return mixed
  247. */
  248. function autoplay_callback( $match ) {
  249. return str_replace( $match[1], add_query_arg( 'autoplay', 1, $match[1] ), $match[0] );
  250. }
  251. /**
  252. * The preg_replace callback that adds the rel param for YouTube videos.
  253. *
  254. * @param $match
  255. *
  256. * @return mixed
  257. */
  258. function remove_related_videos( $match ) {
  259. return str_replace( $match[1], add_query_arg( 'rel', 0, $match[1] ), $match[0] );
  260. }
  261. /**
  262. * Get the video host from the URL
  263. *
  264. * @param $video_url
  265. *
  266. * @return string
  267. */
  268. private function get_host_from_url( $video_url ) {
  269. preg_match( '/https?:\/\/(www.)?([A-Za-z0-9\-]+)\./', $video_url, $matches );
  270. return ( ! empty( $matches ) && count( $matches ) > 2 ) ? $matches[2] : '';
  271. }
  272. /**
  273. * Check if the current host is skinnable
  274. *
  275. * @param $video_host
  276. *
  277. * @return bool
  278. */
  279. private function is_skinnable_video_host( $video_host ) {
  280. global $wp_version;
  281. return $video_host == 'self' || ( ( $video_host == 'youtube' || $video_host == 'vimeo' ) && $wp_version >= 4.2 );
  282. }
  283. /**
  284. *
  285. * Update older versions of widget to use multiple sources.
  286. *
  287. * @param $instance
  288. *
  289. * @return mixed
  290. */
  291. function modify_instance( $instance ) {
  292. $video_src = array();
  293. if ( isset( $instance['video']['self_video'] ) && ! empty( $instance['video']['self_video'] ) ) {
  294. $video_src['self_video'] = $instance['video']['self_video'];
  295. unset( $instance['video']['self_video'] );
  296. }
  297. if ( isset( $instance['video']['self_video_fallback'] ) && ! empty( $instance['video']['self_video_fallback'] ) ) {
  298. $video_src['self_video_fallback'] = $instance['video']['self_video_fallback'];
  299. unset( $instance['video']['self_video_fallback'] );
  300. }
  301. if ( ! empty( $video_src ) ) {
  302. if ( ! isset( $instance['video']['self_sources'] ) ) {
  303. $instance['video']['self_sources'] = array();
  304. }
  305. $instance['video']['self_sources'][] = $video_src;
  306. }
  307. return $instance;
  308. }
  309. }
  310. siteorigin_widget_register( 'video', __FILE__, 'SiteOrigin_Widget_Video_Widget' );