Completed
Push — v2/videopress ( 946a33...00803f )
by George
35:29
created

VideoPress_CLI   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 26
Duplicated Lines 19.23 %

Coupling/Cohesion

Components 0
Dependencies 0
Metric Value
wmc 3
lcom 0
cbo 0
dl 5
loc 26
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
A import() 5 11 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $matches of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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