1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Things that still need doing: |
5
|
|
|
* - Is there a way to use a query arg to hide the share link? That'd be useful. |
6
|
|
|
* - Load in the JS to resize the iframe to set the height automagically and such. |
7
|
|
|
* - The secondary extension for `wpvideo` works, but on saving changes the shortcode to `videopress` -- nbd. |
8
|
|
|
* - Should we handle other display methods apart from iframe in the editor? |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* WordPress Editor Views |
13
|
|
|
*/ |
14
|
|
|
function videopress_editor_view_js_templates() { |
15
|
|
|
if ( ! isset( get_current_screen()->id ) || get_current_screen()->base != 'post' ) { |
16
|
|
|
return; |
17
|
|
|
} |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* This template uses the following parameters, and displays the video as an iframe: |
21
|
|
|
* - data.guid // The guid of the video. |
22
|
|
|
* - data.width // The width of the iframe. |
23
|
|
|
* - data.height // The height of the iframe. |
24
|
|
|
* - data.urlargs // Arguments serialized into a get string. |
25
|
|
|
* |
26
|
|
|
* In addition, the calling script will need to ensure that the following |
27
|
|
|
* JS file is added to the header of the editor iframe: |
28
|
|
|
* - https://s0.wp.com/wp-content/plugins/video/assets/js/next/videopress-iframe.js |
29
|
|
|
*/ |
30
|
|
|
?> |
31
|
|
|
<script type="text/html" id="tmpl-videopress_iframe_vnext"> |
32
|
|
|
<div class="tmpl-videopress_iframe_next"> |
33
|
|
|
<iframe style="display: block;" width="{{ data.width }}" height="{{ data.height }}" src="https://videopress.com/embed/{{ data.guid }}?{{ data.urlargs }}" frameborder='0' allowfullscreen></iframe> |
34
|
|
|
</div> |
35
|
|
|
</script> |
36
|
|
|
<?php |
37
|
|
|
} |
38
|
|
|
add_action( 'admin_print_footer_scripts', 'videopress_editor_view_js_templates' ); |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* WordPress Shortcode Editor View JS Code |
42
|
|
|
* |
43
|
|
|
* For convenience and readability, this is printed out in the |
44
|
|
|
* footer, but ideally should be enqueued seperately. |
45
|
|
|
*/ |
46
|
|
|
function videopress_editor_view_footer_scripts() { |
47
|
|
|
global $content_width; |
48
|
|
|
if ( ! isset( get_current_screen()->id ) || get_current_screen()->base != 'post' ) { |
49
|
|
|
return; |
50
|
|
|
} |
51
|
|
|
?> |
52
|
|
|
<script> |
53
|
|
|
/* global tinyMCE, console */ |
54
|
|
|
(function( $, wp ){ |
55
|
|
|
wp.mce = wp.mce || {}; |
56
|
|
|
wp.mce.videopress_wp_view_renderer = { |
57
|
|
|
shortcode_string : 'videopress', |
58
|
|
|
shortcode_data : {}, |
59
|
|
|
template : wp.template( 'videopress_iframe_vnext' ), |
60
|
|
|
getContent : function() { |
61
|
|
|
var urlargs = 'for=<?php echo esc_js( parse_url( home_url(), PHP_URL_HOST ) ); ?>', |
62
|
|
|
named = this.shortcode.attrs.named, |
63
|
|
|
options, key, width; |
64
|
|
|
|
65
|
|
|
for ( key in named ) { |
66
|
|
|
switch ( key ) { |
67
|
|
|
case 'at' : |
68
|
|
|
if ( parseInt( named[ key ], 10 ) ) { |
69
|
|
|
urlargs += '&' + key + '=' + parseInt( named[ key ], 10 ); |
70
|
|
|
} // Else omit, as it's the default. |
71
|
|
|
break; |
72
|
|
|
case 'permalink' : |
73
|
|
|
if ( 'false' === named[ key ] ) { |
74
|
|
|
urlargs += '&' + key + '=0'; |
75
|
|
|
} // Else omit, as it's the default. |
76
|
|
|
break; |
77
|
|
|
case 'hd' : |
78
|
|
|
case 'loop' : |
79
|
|
|
case 'autoplay' : |
80
|
|
|
if ( 'true' === named[ key ] ) { |
81
|
|
|
urlargs += '&' + key + '=1'; |
82
|
|
|
} // Else omit, as it's the default. |
83
|
|
|
break; |
84
|
|
|
default: |
85
|
|
|
// Unknown parameters? Ditch it! |
86
|
|
|
break; |
87
|
|
|
} |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
options = { |
91
|
|
|
width : <?php echo esc_js( $content_width ); ?>, |
92
|
|
|
height : <?php echo esc_js( intval( $content_width * 0.5625 ) ); /* 0.5625 = 9/16 -- a 16:9 HD aspect ratio */ ?>, |
93
|
|
|
guid : this.shortcode.attrs.numeric[0], |
94
|
|
|
urlargs : urlargs |
95
|
|
|
}; |
96
|
|
|
|
97
|
|
|
if ( typeof named.w !== 'undefined' ) { |
98
|
|
|
width = parseInt( named.w, 10 ); |
99
|
|
|
if ( width > 60 && width < <?php echo esc_js( $content_width ); ?> ) { |
100
|
|
|
options.width = width; |
101
|
|
|
options.height = parseInt( width * 0.5625, 10 ); |
102
|
|
|
} |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
return this.template( options ); |
106
|
|
|
}, |
107
|
|
|
edit: function( data, update ) { |
108
|
|
|
var shortcode_data = wp.shortcode.next( this.shortcode_string, data ), |
109
|
|
|
values = shortcode_data.shortcode.attrs.named; |
110
|
|
|
|
111
|
|
|
values.guid = shortcode_data.shortcode.attrs.numeric[0]; |
112
|
|
|
|
113
|
|
|
wp.mce.videopress_wp_view_renderer.popupwindow( tinyMCE.activeEditor, values ); |
114
|
|
|
}, |
115
|
|
|
popupwindow: function( editor, values, onsubmit_callback ){ |
116
|
|
|
var renderer = this, |
117
|
|
|
key; |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Populate the defaults. |
121
|
|
|
*/ |
122
|
|
|
values = $.extend( { |
123
|
|
|
w : '', |
124
|
|
|
at : 0, |
125
|
|
|
permalink : false, |
126
|
|
|
hd : true, |
127
|
|
|
loop : true, |
128
|
|
|
freedom : true, |
129
|
|
|
autoplay : true, |
130
|
|
|
flashonly : true |
131
|
|
|
}, values ); |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Set up a fallback onsubmit callback handler. |
135
|
|
|
* |
136
|
|
|
* A custom one can be provided as the third argument if desired. |
137
|
|
|
*/ |
138
|
|
|
if ( typeof onsubmit_callback !== 'function' ) { |
139
|
|
|
onsubmit_callback = function( e ) { |
140
|
|
|
var s = '[' + renderer.shortcode_string, |
141
|
|
|
i; |
142
|
|
|
for ( i in e.data ) { |
143
|
|
|
switch( i ) { |
144
|
|
|
case 'guid' : |
145
|
|
|
s += ' ' + e.data.guid; |
146
|
|
|
break; |
147
|
|
|
case 'w' : |
148
|
|
|
case 'at' : |
149
|
|
|
if ( parseInt( e.data[ i ], 10 ) ) { |
150
|
|
|
s += ' ' + i + '="' + parseInt( e.data[ i ], 10 ) + '"'; |
151
|
|
|
} // Else omit, as it's the default. |
152
|
|
|
break; |
153
|
|
|
case 'permalink' : |
154
|
|
|
if ( ! e.data[ i ] ) { |
155
|
|
|
s += ' ' + i + '="false"'; |
156
|
|
|
} // Else omit, as it's the default. |
157
|
|
|
break; |
158
|
|
|
case 'hd' : |
159
|
|
|
case 'loop' : |
160
|
|
|
case 'freedom' : |
161
|
|
|
case 'autoplay' : |
162
|
|
|
case 'flashonly' : |
163
|
|
|
if ( e.data[ i ] ) { |
164
|
|
|
s += ' ' + i + '="true"'; |
165
|
|
|
} // Else omit, as it's the default. |
166
|
|
|
break; |
167
|
|
|
default: |
168
|
|
|
// Unknown parameters? Ditch it! |
169
|
|
|
break; |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
s += ']'; |
173
|
|
|
editor.insertContent( s ); |
174
|
|
|
}; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Cast the checked options to true or false as needed. |
179
|
|
|
*/ |
180
|
|
|
for ( key in values ) { |
181
|
|
|
switch ( key ) { |
182
|
|
|
case 'permalink' : |
183
|
|
|
if ( $.inArray( values[ key ], [ false, 'false', '0' ] ) ) { |
184
|
|
|
values[ key ] = false; |
185
|
|
|
} else { |
186
|
|
|
values[ key ] = true; |
187
|
|
|
} |
188
|
|
|
break; |
189
|
|
|
case 'hd' : |
190
|
|
|
case 'loop' : |
191
|
|
|
case 'freedom' : |
192
|
|
|
case 'autoplay' : |
193
|
|
|
case 'flashonly' : |
194
|
|
|
if ( $.inArray( values[ key ], [ true, 'true', '1' ] ) ) { |
195
|
|
|
values[ key ] = true; |
196
|
|
|
} else { |
197
|
|
|
values[ key ] = false; |
198
|
|
|
} |
199
|
|
|
break; |
200
|
|
|
default: |
201
|
|
|
break; |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Declare the fields that will show in the popup when editing the shortcode. |
207
|
|
|
*/ |
208
|
|
|
editor.windowManager.open( { |
209
|
|
|
title : '<?php echo esc_js( __( 'VideoPress Shortcode', 'jetpack' ) ); ?>', // This should be internationalized via wp_localize_script |
210
|
|
|
body : [ |
211
|
|
|
{ |
212
|
|
|
type : 'textbox', |
213
|
|
|
name : 'guid', |
214
|
|
|
label : '<?php echo esc_js( __( 'Video GUID', 'jetpack' ) ); ?>', |
215
|
|
|
value : values.guid |
216
|
|
|
}, |
217
|
|
|
{ |
218
|
|
|
type : 'textbox', |
219
|
|
|
name : 'w', |
220
|
|
|
label : '<?php echo esc_js( __( 'Width (in pixels)', 'jetpack' ) ); ?>', |
221
|
|
|
value : values.w |
222
|
|
|
}, |
223
|
|
|
{ |
224
|
|
|
type : 'textbox', |
225
|
|
|
name : 'at', |
226
|
|
|
label : '<?php echo esc_js( __( 'Start how many seconds in?', 'jetpack' ) ); ?>', |
227
|
|
|
value : values.at |
228
|
|
|
}, |
229
|
|
|
{ |
230
|
|
|
type : 'checkbox', |
231
|
|
|
name : 'hd', |
232
|
|
|
label : '<?php echo esc_js( __( 'Default to High Definition version?', 'jetpack' ) ); ?>', |
233
|
|
|
checked : values.hd |
234
|
|
|
}, |
235
|
|
|
{ |
236
|
|
|
type : 'checkbox', |
237
|
|
|
name : 'permalink', |
238
|
|
|
label : '<?php echo esc_js( __( 'Link the video title to the video\'s URL on VideoPress.com?', 'jetpack' ) ); ?>', |
239
|
|
|
checked : values.permalink |
240
|
|
|
}, |
241
|
|
|
{ |
242
|
|
|
type : 'checkbox', |
243
|
|
|
name : 'autoplay', |
244
|
|
|
label : '<?php echo esc_js( __( 'Autoplay video on load?', 'jetpack' ) ); ?>', |
245
|
|
|
checked : values.autoplay |
246
|
|
|
}, |
247
|
|
|
{ |
248
|
|
|
type : 'checkbox', |
249
|
|
|
name : 'loop', |
250
|
|
|
label : '<?php echo esc_js( __( 'Loop playback indefinitely?', 'jetpack' ) ); ?>', |
251
|
|
|
checked : values.loop |
252
|
|
|
}, |
253
|
|
|
{ |
254
|
|
|
type : 'checkbox', |
255
|
|
|
name : 'freedom', |
256
|
|
|
label : '<?php echo esc_js( __( 'Use only Open Source codecs? (this may degrade performance)', 'jetpack' ) ); ?>', |
257
|
|
|
checked : values.freedom |
258
|
|
|
}, |
259
|
|
|
{ |
260
|
|
|
type : 'checkbox', |
261
|
|
|
name : 'flashonly', |
262
|
|
|
label : '<?php echo esc_js( __( 'Use the legacy flash player? (not recommended)', 'jetpack' ) ); ?>', |
263
|
|
|
checked : values.flashonly |
264
|
|
|
} |
265
|
|
|
], |
266
|
|
|
onsubmit : onsubmit_callback |
267
|
|
|
} ); |
268
|
|
|
} |
269
|
|
|
}; |
270
|
|
|
wp.mce.views.register( 'videopress', wp.mce.videopress_wp_view_renderer ); |
271
|
|
|
|
272
|
|
|
// Extend the videopress one to also handle `wpvideo` instances. |
273
|
|
|
wp.mce.wpvideo_wp_view_renderer = _.extend( {}, wp.mce.videopress_wp_view_renderer, { |
274
|
|
|
shortcode_string : 'wpvideo' |
275
|
|
|
}); |
276
|
|
|
wp.mce.views.register( 'wpvideo', wp.mce.wpvideo_wp_view_renderer ); |
277
|
|
|
}( jQuery, wp )); |
278
|
|
|
</script> |
279
|
|
|
<?php |
280
|
|
|
} |
281
|
|
|
add_action( 'admin_print_footer_scripts', 'videopress_editor_view_footer_scripts' ); |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* Similar to `media_sideload_image` -- but returns an ID. |
285
|
|
|
* |
286
|
|
|
* @param $url |
287
|
|
|
* @param $attachment_id |
288
|
|
|
* |
289
|
|
|
* @return int|mixed|object|WP_Error |
290
|
|
|
*/ |
291
|
|
|
function videopress_download_poster_image( $url, $attachment_id ) { |
292
|
|
|
// Set variables for storage, fix file filename for query strings. |
293
|
|
|
preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $url, $matches ); |
294
|
|
|
if ( ! $matches ) { |
|
|
|
|
295
|
|
|
return new WP_Error( 'image_sideload_failed', __( 'Invalid image URL' ) ); |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
$file_array = array(); |
299
|
|
|
$file_array['name'] = basename( $matches[0] ); |
300
|
|
|
$file_array['tmp_name'] = download_url( $url ); |
301
|
|
|
|
302
|
|
|
// If error storing temporarily, return the error. |
303
|
|
|
if ( is_wp_error( $file_array['tmp_name'] ) ) { |
304
|
|
|
return $file_array['tmp_name']; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
// Do the validation and storage stuff. |
308
|
|
|
return media_handle_sideload( $file_array, $attachment_id, null ); |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
/** |
312
|
|
|
* Creates a local media library item of a remote VideoPress video. |
313
|
|
|
* |
314
|
|
|
* @param $guid |
315
|
|
|
* @param int $parent_id |
316
|
|
|
* |
317
|
|
|
* @return int|object |
318
|
|
|
*/ |
319
|
|
|
function create_local_media_library_for_videopress_guid( $guid, $parent_id = 0 ) { |
320
|
|
|
$vp_data = videopress_get_video_details( $guid ); |
321
|
|
|
if ( ! $vp_data || is_wp_error( $vp_data ) ) { |
322
|
|
|
return $vp_data; |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
$args = array( |
326
|
|
|
'post_date' => $vp_data->upload_date, |
327
|
|
|
'post_title' => wp_kses( $vp_data->title, array() ), |
328
|
|
|
'post_content' => wp_kses( $vp_data->description, array() ), |
329
|
|
|
'post_mime_type' => 'video/videopress', |
330
|
|
|
); |
331
|
|
|
|
332
|
|
|
$attachment_id = wp_insert_attachment( $args, null, $parent_id ); |
333
|
|
|
|
334
|
|
|
if ( ! is_wp_error( $attachment_id ) ) { |
335
|
|
|
update_post_meta( $attachment_id, 'videopress_guid', $guid ); |
336
|
|
|
wp_update_attachment_metadata( $attachment_id, array( |
337
|
|
|
'width' => $vp_data->width, |
338
|
|
|
'height' => $vp_data->height, |
339
|
|
|
) ); |
340
|
|
|
|
341
|
|
|
$thumbnail_id = videopress_download_poster_image( $vp_data->poster, $attachment_id ); |
342
|
|
|
update_post_meta( $attachment_id, '_thumbnail_id', $thumbnail_id ); |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
return $attachment_id; |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
if ( defined( 'WP_CLI' ) && WP_CLI ) { |
349
|
|
|
|
350
|
|
|
/** |
351
|
|
|
* Manage and import VideoPress videos. |
352
|
|
|
*/ |
353
|
|
|
class VideoPress_CLI extends WP_CLI_Command { |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* Import a VideoPress Video |
357
|
|
|
* |
358
|
|
|
* ## OPTIONS |
359
|
|
|
* |
360
|
|
|
* <guid>: Import the video with the specified guid |
361
|
|
|
* |
362
|
|
|
* ## EXAMPLES |
363
|
|
|
* |
364
|
|
|
* wp videopress import kUJmAcSf |
365
|
|
|
* |
366
|
|
|
*/ |
367
|
|
|
public function import( $args ) { |
368
|
|
|
$guid = $args[0]; |
369
|
|
|
|
370
|
|
|
$attachment_id = create_local_media_library_for_videopress_guid( $guid ); |
371
|
|
|
|
372
|
|
View Code Duplication |
if ( $attachment_id && ! is_wp_error( $attachment_id ) ) { |
373
|
|
|
WP_CLI::success( sprintf( __( 'The video has been imported as Attachment ID %d', 'jetpack' ), $attachment_id ) ); |
374
|
|
|
} else { |
375
|
|
|
WP_CLI::error( __( 'An error has been encountered.', 'jetpack' ) ); |
376
|
|
|
} |
377
|
|
|
} |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
WP_CLI::add_command( 'videopress', 'VideoPress_CLI' ); |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.