editor-media-view.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. /**
  3. * WordPress Shortcode Editor View JS Code
  4. */
  5. function videopress_handle_editor_view_js() {
  6. global $content_width;
  7. $current_screen = get_current_screen();
  8. if ( ! isset( $current_screen->id ) || $current_screen->base !== 'post' ) {
  9. return;
  10. }
  11. add_action( 'admin_print_footer_scripts', 'videopress_editor_view_js_templates' );
  12. wp_enqueue_style( 'videopress-editor-ui', plugins_url( 'css/editor.css', __FILE__ ) );
  13. wp_enqueue_script(
  14. 'videopress-editor-view',
  15. Jetpack::get_file_url_for_environment(
  16. '_inc/build/videopress/js/editor-view.min.js',
  17. 'modules/videopress/js/editor-view.js'
  18. ),
  19. array( 'wp-util', 'jquery' ),
  20. false,
  21. true
  22. );
  23. wp_localize_script( 'videopress-editor-view', 'vpEditorView', array(
  24. 'home_url_host' => parse_url( home_url(), PHP_URL_HOST ),
  25. 'min_content_width' => VIDEOPRESS_MIN_WIDTH,
  26. 'content_width' => $content_width,
  27. 'modal_labels' => array(
  28. 'title' => esc_html__( 'VideoPress Shortcode', 'jetpack' ),
  29. 'guid' => esc_html__( 'Video ID', 'jetpack' ),
  30. 'w' => esc_html__( 'Video Width', 'jetpack' ),
  31. 'w_unit' => esc_html__( 'pixels', 'jetpack' ),
  32. /* Translators: example of usage of this is "Start Video After 10 seconds" */
  33. 'at' => esc_html__( 'Start Video After', 'jetpack' ),
  34. 'at_unit' => esc_html__( 'seconds', 'jetpack' ),
  35. 'hd' => esc_html__( 'High definition on by default', 'jetpack' ),
  36. 'permalink' => esc_html__( 'Link the video title to its URL on VideoPress.com', 'jetpack' ),
  37. 'autoplay' => esc_html__( 'Autoplay video on page load', 'jetpack' ),
  38. 'loop' => esc_html__( 'Loop video playback', 'jetpack' ),
  39. 'freedom' => esc_html__( 'Use only Open Source codecs (may degrade performance)', 'jetpack' ),
  40. 'flashonly' => esc_html__( 'Use legacy Flash Player (not recommended)', 'jetpack' ),
  41. )
  42. ) );
  43. add_editor_style( plugins_url( 'css/videopress-editor-style.css', __FILE__ ) );
  44. }
  45. add_action( 'admin_notices', 'videopress_handle_editor_view_js' );
  46. /**
  47. * WordPress Editor Views
  48. */
  49. function videopress_editor_view_js_templates() {
  50. /**
  51. * This template uses the following parameters, and displays the video as an iframe:
  52. * - data.guid // The guid of the video.
  53. * - data.width // The width of the iframe.
  54. * - data.height // The height of the iframe.
  55. * - data.urlargs // Arguments serialized into a get string.
  56. *
  57. * In addition, the calling script will need to ensure that the following
  58. * JS file is added to the header of the editor iframe:
  59. * - https://s0.wp.com/wp-content/plugins/video/assets/js/next/videopress-iframe.js
  60. */
  61. ?>
  62. <script type="text/html" id="tmpl-videopress_iframe_vnext">
  63. <div class="tmpl-videopress_iframe_next" style="max-height:{{ data.height }}px;">
  64. <div class="videopress-editor-wrapper" style="padding-top:{{ data.ratio }}%;">
  65. <iframe style="display: block;" width="{{ data.width }}" height="{{ data.height }}" src="https://videopress.com/embed/{{ data.guid }}?{{ data.urlargs }}" frameborder='0' allowfullscreen></iframe>
  66. </div>
  67. </div>
  68. </script>
  69. <?php
  70. }
  71. /*************************************************\
  72. | This is the chunk that handles overriding core |
  73. | media stuff so VideoPress can display natively. |
  74. \*************************************************/
  75. /**
  76. * Media Grid:
  77. * Filter out any videopress video posters that we've downloaded,
  78. * so that they don't seem to display twice.
  79. */
  80. add_filter( 'ajax_query_attachments_args', 'videopress_ajax_query_attachments_args' );
  81. function videopress_ajax_query_attachments_args( $args ) {
  82. $meta_query = array(
  83. array(
  84. 'key' => 'videopress_poster_image',
  85. 'compare' => 'NOT EXISTS',
  86. ),
  87. );
  88. // If there was already a meta query, let's AND it via
  89. // nesting it with our new one. No need to specify the
  90. // relation, as it defaults to AND.
  91. if ( ! empty( $args['meta_query'] ) ) {
  92. $meta_query[] = $args['meta_query'];
  93. }
  94. $args['meta_query'] = $meta_query;
  95. return $args;
  96. }
  97. /**
  98. * Media List:
  99. * Do the same as ^^ but for the list view.
  100. */
  101. add_action( 'pre_get_posts', 'videopress_media_list_table_query' );
  102. function videopress_media_list_table_query( $query ) {
  103. if (
  104. ! function_exists( 'get_current_screen' )
  105. || is_null( get_current_screen() )
  106. ) {
  107. return;
  108. }
  109. if ( is_admin() && $query->is_main_query() && ( 'upload' === get_current_screen()->id ) ) {
  110. $meta_query = array(
  111. array(
  112. 'key' => 'videopress_poster_image',
  113. 'compare' => 'NOT EXISTS',
  114. ),
  115. );
  116. if ( $old_meta_query = $query->get( 'meta_query' ) ) {
  117. $meta_query[] = $old_meta_query;
  118. }
  119. $query->set( 'meta_query', $meta_query );
  120. }
  121. }
  122. /**
  123. * Make sure that any Video that has a VideoPress GUID passes that data back.
  124. */
  125. add_filter( 'wp_prepare_attachment_for_js', 'videopress_prepare_attachment_for_js' );
  126. function videopress_prepare_attachment_for_js( $post ) {
  127. if ( 'video' === $post['type'] ) {
  128. $guid = get_post_meta( $post['id'], 'videopress_guid' );
  129. if ( $guid ) {
  130. $post['videopress_guid'] = $guid;
  131. }
  132. }
  133. return $post;
  134. }
  135. /**
  136. * Wherever the Media Modal is deployed, also deploy our overrides.
  137. */
  138. add_action( 'wp_enqueue_media', 'add_videopress_media_overrides' );
  139. function add_videopress_media_overrides() {
  140. add_action( 'admin_print_footer_scripts', 'videopress_override_media_templates', 11 );
  141. }
  142. /**
  143. * Our video overrides!
  144. *
  145. * We have a template for the iframe to get injected.
  146. */
  147. function videopress_override_media_templates(){
  148. ?>
  149. <script type="text/html" id="tmpl-videopress_iframe_vnext">
  150. <iframe style="display: block; max-width: 100%;" width="{{ data.width }}" height="{{ data.height }}" src="https://videopress.com/embed/{{ data.guid }}?{{ data.urlargs }}" frameborder='0' allowfullscreen></iframe>
  151. </script>
  152. <script>
  153. (function( media ){
  154. // This handles the media library modal attachment details display.
  155. if ( 'undefined' !== typeof media.view.Attachment.Details.TwoColumn ) {
  156. var TwoColumn = media.view.Attachment.Details.TwoColumn,
  157. old_render = TwoColumn.prototype.render,
  158. vp_template = wp.template('videopress_iframe_vnext');
  159. TwoColumn.prototype.render = function() {
  160. // Have the original renderer run first.
  161. old_render.apply( this, arguments );
  162. // Now our stuff!
  163. if ( 'video' === this.model.get('type') ) {
  164. if ( this.model.get('videopress_guid') ) {
  165. this.$('.attachment-media-view .thumbnail-video').html( vp_template( {
  166. guid : this.model.get('videopress_guid'),
  167. width : this.model.get('width'),
  168. height : this.model.get('height')
  169. }));
  170. }
  171. }
  172. };
  173. } else { /* console.log( 'media.view.Attachment.Details.TwoColumn undefined' ); */ }
  174. // This handles the recreating of the core video shortcode when editing the mce embed.
  175. if ( 'undefined' !== typeof media.video ) {
  176. media.video.defaults.videopress_guid = '';
  177. // For some reason, even though we're not currently changing anything, the following proxy
  178. // function is necessary to include the above default `videopress_guid` param. ¯\_(ツ)_/¯
  179. var old_video_shortcode = media.video.shortcode;
  180. media.video.shortcode = function( model ) {
  181. // model.videopress_guid = 'FOOBAR';
  182. return old_video_shortcode( model );
  183. };
  184. } else { /* console.log( 'media.video undefined' ); */ }
  185. })( wp.media );
  186. </script>
  187. <?php
  188. }
  189. /**
  190. * Properly inject VideoPress data into Core shortcodes, and
  191. * generate videopress shortcodes for purely remote videos.
  192. */
  193. add_filter( 'media_send_to_editor', 'videopress_media_send_to_editor', 10, 3 );
  194. function videopress_media_send_to_editor( $html, $id, $attachment ) {
  195. $videopress_guid = get_post_meta( $id, 'videopress_guid', true );
  196. if ( $videopress_guid && videopress_is_valid_guid( $videopress_guid ) ) {
  197. if ( '[video ' === substr( $html, 0, 7 ) ) {
  198. $html = sprintf( '[videopress %1$s]', esc_attr( $videopress_guid ) );
  199. } elseif ( '<a href=' === substr( $html, 0, 8 ) ) {
  200. // We got here because `wp_attachment_is()` returned false for
  201. // video, because there isn't a local copy of the file.
  202. $html = sprintf( '[videopress %1$s]', esc_attr( $videopress_guid ) );
  203. }
  204. } elseif ( videopress_is_attachment_without_guid( $id ) ) {
  205. $html = sprintf( '[videopress postid=%d]', $id );
  206. }
  207. return $html;
  208. }