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