Completed
Push — branch-4.0 ( 2c8fe1 )
by
unknown
54:11 queued 44:40
created

Jetpack_VideoPress::handle_editor_view_js()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 28
Code Lines 22

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 28
rs 8.8571
cc 3
eloc 22
nc 2
nop 0
1
<?php
2
/**
3
 * VideoPress in Jetpack
4
 *
5
 */
6
class Jetpack_VideoPress {
7
	public $module = 'videopress';
8
	public $option_name = 'videopress';
9
	public $version = 4;
10
11
	/**
12
	 * Singleton
13
	 */
14
	public static function init() {
15
		static $instance = false;
16
17
		if ( ! $instance )
18
			$instance = new Jetpack_VideoPress;
19
20
		return $instance;
21
	}
22
23
	function __construct() {
24
		$this->version = time(); // <s>ghost</s> cache busters!
25
		add_action( 'init', array( $this, 'on_init' ) );
26
		add_action( 'jetpack_activate_module_videopress', array( $this, 'jetpack_module_activated' ) );
27
		add_action( 'jetpack_deactivate_module_videopress', array( $this, 'jetpack_module_deactivated' ) );
28
	}
29
30
	/**
31
	 * Fires on init since is_connection_owner should wait until the user is initialized by $wp->init();
32
	 */
33
	function on_init() {
34
		$options = $this->get_options();
35
36
		// Only the connection owner can configure this module.
37
		if ( $this->is_connection_owner() ) {
38
			Jetpack::enable_module_configurable( $this->module );
39
			Jetpack::module_configuration_load( $this->module, array( $this, 'jetpack_configuration_load' ) );
40
			Jetpack::module_configuration_screen( $this->module, array( $this, 'jetpack_configuration_screen' ) );
41
		}
42
43
		// Only if the current user can manage the VideoPress library and one has been connected.
44
		if ( $this->can( 'read_videos' ) && $options['blog_id'] ) {
45
			add_action( 'wp_enqueue_media', array( $this, 'enqueue_admin_scripts' ) );
46
			add_action( 'print_media_templates', array( $this, 'print_media_templates' ) );
47
48
			// Load these at priority -1 so they're fired before Core's are.
49
			add_action( 'wp_ajax_query-attachments', array( $this, 'wp_ajax_query_attachments' ), -1 );
50
			add_action( 'wp_ajax_save-attachment', array( $this, 'wp_ajax_save_attachment' ), -1 );
51
			add_action( 'wp_ajax_save-attachment-compat', array( $this, 'wp_ajax_save_attachment' ), -1 );
52
			add_action( 'wp_ajax_delete-post', array( $this, 'wp_ajax_delete_post' ), -1 );
53
54
			add_action( 'admin_menu', array( $this, 'admin_menu' ) );
55
		}
56
57
		if ( $this->can( 'upload_videos' ) && $options['blog_id'] ) {
58
			add_action( 'wp_ajax_videopress-get-upload-token', array( $this, 'wp_ajax_videopress_get_upload_token' ) );
59
		}
60
61
		add_filter( 'videopress_shortcode_options', array( $this, 'videopress_shortcode_options' ) );
62
	}
63
64
	function wp_ajax_videopress_get_upload_token() {
65
		if ( ! $this->can( 'upload_videos' ) )
66
			return wp_send_json_error();
67
68
		$result = $this->query( 'jetpack.vpGetUploadToken' );
69
		if ( is_wp_error( $result ) )
70
			return wp_send_json_error( array( 'message' => __( 'Could not obtain a VideoPress upload token. Please try again later.', 'jetpack' ) ) );
71
72
		$response = $result;
73
		if ( empty( $response['videopress_blog_id'] ) || empty( $response['videopress_token'] ) || empty( $response[ 'videopress_action_url' ] ) )
74
			return wp_send_json_error( array( 'message' => __( 'Could not obtain a VideoPress upload token. Please try again later.', 'jetpack' ) ) );
75
76
		return wp_send_json_success( $response );
77
	}
78
79
	/**
80
	 * Get VideoPress options
81
	 */
82
	function get_options() {
83
		$defaults = array(
84
			'blogs' => array(),
85
			'blog_id' => 0,
86
			'access' => '',
87
			'allow-upload' => false,
88
			'freedom' => false,
89
			'hd' => false,
90
			'meta' => array(
91
				'max_upload_size' => 0,
92
			),
93
		);
94
95
		$options = Jetpack_Options::get_option( $this->option_name, array() );
96
97
		// If options have not been saved yet, check for older VideoPress plugin options.
98
		if ( empty( $options ) ) {
99
			$options['freedom'] = (bool) get_option( 'video_player_freedom', false );
100
			$options['hd'] = (bool) get_option( 'video_player_high_quality', false );
101
		}
102
103
		$options = array_merge( $defaults, $options );
104
		return $options;
105
	}
106
107
	/**
108
	 * Update VideoPress options
109
	 */
110
	function update_options( $options ) {
111
		Jetpack_Options::update_option( $this->option_name, $options );
112
	}
113
114
	/**
115
	 * Runs when the VideoPress module is activated.
116
	 */
117
	function jetpack_module_activated() {
118
		if ( ! $this->is_connection_owner() )
119
			return;
120
121
		$options = $this->get_options();
122
123
		// Ask WordPress.com for a list of VideoPress blogs
124
		$result = $this->query( 'jetpack.vpGetBlogs' );
125
		if ( ! is_wp_error( $result ) )
126
			$options['blogs'] = $result;
127
128
		// If there's at least one available blog, let's use it.
129
		if ( is_array( $options['blogs'] ) && count( $options['blogs'] ) > 0 )
130
			$options['blog_id'] = $options['blogs'][0]['blog_id'];
131
132
		$this->update_options( $options );
133
	}
134
135
	/**
136
	 * Runs when the VideoPress module is deactivated.
137
	 */
138
	function jetpack_module_deactivated() {
139
		Jetpack_Options::delete_option( $this->option_name );
140
	}
141
142
	/**
143
	 * Remote Query
144
	 *
145
	 * Performs a remote XML-RPC query using Jetpack's IXR Client. And also
146
	 * appends some useful stuff about this setup to the query.
147
	 *
148
	 * @return the Jetpack_IXR_Client object after querying.
149
	 */
150
	function query( $method, $args = null ) {
151
		$options = $this->get_options();
152
		Jetpack::load_xml_rpc_client();
153
		$xml = new Jetpack_IXR_Client( array(
154
			'user_id' => JETPACK_MASTER_USER, // All requests are on behalf of the connection owner.
155
		) );
156
157
		$params = array(
158
			'args' => $args,
159
			'video_blog_id' => $options['blog_id'],
160
			'caps' => array(),
161
		);
162
163
		// Let Jetpack know about our local caps.
164 View Code Duplication
		foreach ( array( 'read_videos', 'edit_videos', 'delete_videos', 'upload_videos' ) as $cap )
165
			if ( $this->can( $cap ) )
166
				$params['caps'][] = $cap;
167
168
		$xml->query( $method, $params );
169
170
		if ( $xml->isError() )
171
			return new WP_Error( 'xml_rpc_error', 'An XML-RPC error has occurred.' );
172
173
		$response = $xml->getResponse();
174
175
		// If there's any metadata with the response, save it for future use.
176
		if ( is_array( $response ) && isset( $response['meta'] ) ) {
177
			$options = $this->get_options();
178
			if ( $response['meta'] !== $options['meta'] ) {
179
				$options['meta'] = array_merge( $options['meta'], $response['meta'] );
180
				$this->update_options( $options );
181
			}
182
		}
183
184
		if ( is_array( $response ) && isset( $response['result'] ) )
185
			return $response['result'];
186
187
		return $response;
188
	}
189
190
	/**
191
	 * Runs before the VideoPress Configuration screen loads, useful
192
	 * to update options and yield errors.
193
	 */
194
	function jetpack_configuration_load() {
195
		$this->enqueue_admin_scripts();
196
197
		/**
198
		 * Save configuration
199
		 */
200
		if ( ! empty( $_POST['action'] ) && $_POST['action'] == 'videopress-save' ) {
201
			check_admin_referer( 'videopress-settings' );
202
			$options = $this->get_options();
203
204
			if ( isset( $_POST['blog_id'] ) && in_array( $_POST['blog_id'], wp_list_pluck( $options['blogs'], 'blog_id' ) ) )
205
				$options['blog_id'] = $_POST['blog_id'];
206
207
			// Allow the None setting too.
208
			if ( isset( $_POST['blog_id'] ) && $_POST['blog_id'] == 0 )
209
				$options['blog_id'] = 0;
210
211
			/**
212
			 * @see $this->can()
213
			 */
214
			if ( isset( $_POST['videopress-access'] ) && in_array( $_POST['videopress-access'], array( '', 'read', 'edit', 'delete' ) ) )
215
				$options['access'] = $_POST['videopress-access'];
216
217
			$options['freedom'] = isset( $_POST['videopress-freedom'] );
218
			$options['hd'] = isset( $_POST['videopress-hd'] );
219
220
			// Allow upload only if some level of access has been granted, and uploads were allowed.
221
			$options['allow-upload'] = false;
222
			if ( ! empty( $options['access'] ) && isset( $_POST['videopress-upload'] ) )
223
				$options['allow-upload'] = true;
224
225
			$this->update_options( $options );
226
			Jetpack::state( 'message', 'module_configured' );
227
			wp_safe_redirect( Jetpack::module_configuration_url( $this->module ) );
228
		}
229
230
		/**
231
		 * Refresh the list of available WordPress.com blogs
232
		 */
233
		if ( ! empty( $_GET['videopress'] ) && $_GET['videopress'] == 'refresh-blogs' ) {
234
			check_admin_referer( 'videopress-settings' );
235
			$options = $this->get_options();
236
237
			$result = $this->query( 'jetpack.vpGetBlogs' );
238
			if ( ! is_wp_error( $result ) ) {
239
				$options['blogs'] = $result;
240
				$this->update_options( $options );
241
			}
242
243
			wp_safe_redirect( Jetpack::module_configuration_url( $this->module ) );
244
		}
245
	}
246
247
	/**
248
	 * Renders the VideoPress Configuration screen in Jetpack.
249
	 */
250
	function jetpack_configuration_screen() {
251
		$options = $this->get_options();
252
		$refresh_url = wp_nonce_url( add_query_arg( 'videopress', 'refresh-blogs' ), 'videopress-settings' );
253
		?>
254
		<div class="narrow">
255
			<form method="post" id="videopress-settings">
256
				<input type="hidden" name="action" value="videopress-save" />
257
				<?php wp_nonce_field( 'videopress-settings' ); ?>
258
259
				<table id="menu" class="form-table">
260
					<tr>
261
						<th scope="row" colspan="2">
262
							<p><?php _e( 'Please note that the VideoPress module requires a WordPress.com account with an active <a href="http://store.wordpress.com/premium-upgrades/videopress/" target="_blank">VideoPress subscription</a>.', 'jetpack' ); ?></p>
263
						</th>
264
					</tr>
265
					<tr>
266
						<th scope="row">
267
							<label><?php _e( 'Connected WordPress.com Blog', 'jetpack' ); ?></label>
268
						</th>
269
						<td>
270
							<select name="blog_id">
271
								<option value="0" <?php selected( $options['blog_id'], 0 ); ?>> <?php esc_html_e( 'None', 'jetpack' ); ?></option>
272
								<?php foreach ( $options['blogs'] as $blog ) : ?>
0 ignored issues
show
Bug introduced by
The expression $options['blogs'] of type array|integer|string|false is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
273
								<option value="<?php echo absint( $blog['blog_id'] ); ?>" <?php selected( $options['blog_id'], $blog['blog_id'] ); ?>><?php echo esc_html( $blog['name'] ); ?> (<?php echo esc_html( $blog['domain'] ); ?>)</option>
274
								<?php endforeach; ?>
275
							</select>
276
							<p class="description"><?php _e( 'Only videos from the selected blog will be available in your media library.', 'jetpack' ); ?>
277
								<?php printf( __( '<a href="%s">Click here</a> to refresh this list.', 'jetpack' ), esc_url( $refresh_url ) ); ?>
278
							</p>
279
						</td>
280
					</tr>
281
					<tr>
282
						<th scope="row">
283
							<label><?php _e( 'Video Library Access', 'jetpack' ); ?></label>
284
						</th>
285
						<td>
286
							<label><input type="radio" name="videopress-access" value="" <?php checked( '', $options['access'] ); ?> />
287
								<?php _e( 'Do not allow other users to access my VideoPress library', 'jetpack' ); ?></label><br/>
288
							<label><input type="radio" name="videopress-access" value="read" <?php checked( 'read', $options['access'] ); ?> />
289
								<?php _e( 'Allow users to access my videos', 'jetpack' ); ?></label><br/>
290
							<label><input type="radio" name="videopress-access" value="edit" <?php checked( 'edit', $options['access'] ); ?> />
291
								<?php _e( 'Allow users to access and edit my videos', 'jetpack' ); ?></label><br/>
292
							<label><input type="radio" name="videopress-access" value="delete" <?php checked( 'delete', $options['access'] ); ?> />
293
								<?php _e( 'Allow users to access, edit, and delete my videos', 'jetpack' ); ?></label><br/><br />
294
295
							<label><input type="checkbox" name="videopress-upload" value="1" <?php checked( $options['allow-upload'] ); ?> />
296
								<?php _e( 'Allow users to upload videos', 'jetpack' ); ?></label><br />
297
						</td>
298
					</tr>
299
					<tr>
300
						<th scope="row">
301
							<label for="videopress-freedom"><?php _e( 'Free formats', 'jetpack' ); ?></label>
302
						</th>
303
						<td>
304
							<label><input type="checkbox" name="videopress-freedom" id="videopress-freedom" <?php checked( $options['freedom'] ); ?> />
305
								<?php _e( 'Only display videos in free software formats', 'jetpack' ); ?></label>
306
							<p class="description"><?php _e( 'Ogg file container with Theora video and Vorbis audio. Note that some browsers are unable to play free software video formats, including Internet Explorer and Safari.', 'jetpack' ); ?></p>
307
						</td>
308
					</tr>
309
					<tr>
310
						<th scope="row">
311
							<label for="videopress-hd"><?php _e( 'Default quality', 'jetpack' ); ?></label>
312
						</th>
313
						<td>
314
							<label><input type="checkbox" name="videopress-hd" id="videopress-hd" <?php checked( $options['hd'] ); ?> />
315
								<?php _e( 'Display higher quality video by default.', 'jetpack' ); ?></label>
316
							<p class="description"><?php _e( 'This setting may be overridden for individual videos.', 'jetpack' ); ?></p>
317
						</td>
318
					</tr>
319
				</table>
320
321
				<?php submit_button(); ?>
322
			</form>
323
		</div>
324
		<?php
325
	}
326
327
	function admin_menu() {
328
		add_media_page( __( 'VideoPress Library', 'jetpack' ), __( 'VideoPress', 'jetpack' ), 'upload_files', 'videopress-library', array( $this, 'admin_menu_library' ) );
329
	}
330
331
	function admin_menu_library() {
332
		wp_enqueue_media();
333
		$this->enqueue_admin_scripts();
334
		?>
335
		<div class="wrap" style="max-width: 600px;">
336
			<?php screen_icon(); ?>
337
	        <h2><?php _e( 'VideoPress Library', 'jetpack' ); ?></h2>
338
	        <p><?php _e( 'Use the button below to browse your VideoPress Library. Note that you can also browse your VideoPress Library while editing a post or page by using the <strong>Add Media</strong> button in the post editor.', 'jetpack' ); ?></p>
339
	        <p class="hide-if-no-js"><a href="#" id="videopress-browse" class="button"><?php _e( 'Browse Your VideoPress Library', 'jetpack' ); ?></a></p>
340
	        <p class="hide-if-js description"><?php _e( 'Please enable JavaScript support in your browser to use VideoPress.', 'jetpack' ); ?></p>
341
	    </div>
342
		<?php
343
	}
344
345
	/**
346
	 * A can of coke
347
	 *
348
	 * Similar to current_user_can, but internal to VideoPress. Returns
349
	 * true if the given VideoPress capability is allowed by the given user.
350
	 */
351
	function can( $cap, $user_id = false ) {
352
		if ( ! $user_id )
353
			$user_id = get_current_user_id();
354
355
		// Connection owners are allowed to do all the things.
356
		if ( $this->is_connection_owner( $user_id ) )
357
			return true;
358
359
		/**
360
		 * The access setting can be set by the connection owner, to allow sets
361
		 * of operations to other site users. Each access value corresponds to
362
		 * an array of things they can do.
363
		 */
364
365
		$options = $this->get_options();
366
		$map = array(
367
			'read'   => array( 'read_videos' ),
368
			'edit'   => array( 'read_videos', 'edit_videos' ),
369
			'delete' => array( 'read_videos', 'edit_videos', 'delete_videos' ),
370
		);
371
372
		if ( ! array_key_exists( $options['access'], $map ) )
373
			return false;
374
375
		if ( ! in_array( $cap, $map[ $options['access'] ] ) && 'upload_videos' != $cap )
376
			return false;
377
378
		// Additional and intrenal caps checks
379
380
		if ( ! user_can( $user_id, 'upload_files' ) )
381
			return false;
382
383
		if ( 'edit_videos' == $cap && ! user_can( $user_id, 'edit_others_posts' ) )
384
			return false;
385
386
		if ( 'delete_videos' == $cap && ! user_can( $user_id, 'delete_others_posts' ) )
387
			return false;
388
389
		if ( 'upload_videos' == $cap && ! $options['allow-upload'] )
390
			return false;
391
392
		return true;
393
	}
394
395
	/**
396
	 * Returns true if the provided user is the Jetpack connection owner.
397
	 */
398
	function is_connection_owner( $user_id = false ) {
399
		if ( ! $user_id )
400
			$user_id = get_current_user_id();
401
402
		$user_token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER );
403
		return $user_token && is_object( $user_token ) && isset( $user_token->external_user_id ) && $user_id === $user_token->external_user_id;
404
	}
405
406
	/**
407
	 * Our custom AJAX callback for the query-attachments action
408
	 * used in the media modal. By-passed if not for VideoPress.
409
	 */
410
	function wp_ajax_query_attachments() {
411
412
		// Watch for VideoPress calls
413
		if ( ! isset( $_POST['query']['videopress'] ) )
414
			return;
415
416
		if ( ! $this->can( 'read_videos' ) )
417
			return wp_send_json_error( 'permission denied' );
418
419
		// Get and sanitize query arguments.
420
		$query_args = $this->sanitize_wp_query_args( $_POST['query'] );
421
422
		// Fire a remote WP_Query
423
		$result = $this->query( 'jetpack.vpQuery', $query_args );
424
425
		if ( is_wp_error( $result ) )
426
			return wp_send_json_error( 'xml rpc request error' );
427
428
		$items = $result;
429
430
		foreach ( $items as $key => $item ) {
431
432
			// Check local permissions
433
			if ( ! $this->can( 'edit_videos' ) )
434
				unset( $item['vp_nonces']['update'] );
435
436
			if ( ! $this->can( 'delete_videos' ) )
437
				unset( $item['vp_nonces']['delete'] );
438
439
			// Add a second pair of nonces for the .org blog.
440
			$item['nonces'] = array();
441 View Code Duplication
			if ( ! empty( $item['vp_nonces']['update'] ) )
442
				$item['nonces']['update'] = wp_create_nonce( 'update-videopress-post_' . $item['id'] );
443
444 View Code Duplication
			if ( ! empty( $item['vp_nonces']['delete'] ) )
445
				$item['nonces']['delete'] = wp_create_nonce( 'delete-videopress-post_' . $item['id'] );
446
447
			$item['vp_embed'] = videopress_shortcode_callback( array(
448
				$item['vp_guid'],
449
				'autoplay' => true,
450
				'flashonly' => true,
451
				'w' => 440,
452
			) );
453
454
			$items[ $key ] = $item;
455
		}
456
457
		wp_send_json_success( $items );
458
	}
459
460
	/**
461
	 * Sanitize user-provided WP_Query arguments
462
	 *
463
	 * These might be sent to the VideoPress server, for a remote WP_Query
464
	 * call so let's make sure they're sanitized and safe to send.
465
	 */
466
	function sanitize_wp_query_args( $args ) {
467
		$args = shortcode_atts( array(
468
			'posts_per_page' => 40,
469
			'orderby' => 'date',
470
			'order' => 'desc',
471
			'paged' => 1,
472
			's' => '',
473
		), (array) $args, 'wpvideo' );
474
475
		$args['posts_per_page'] = absint( $args['posts_per_page'] );
476
477
		$args['orderby'] = strtolower( $args['orderby'] );
478
		$args['orderby'] = ( in_array( $args['orderby'], array( 'date' ) ) ) ? $args['orderby'] : 'date';
479
480
		$args['order'] = strtolower( $args['order'] );
481
		$args['order'] = ( in_array( $args['order'], array( 'asc', 'desc' ) ) ) ? $args['order'] : 'desc';
482
483
		$args['paged'] = absint( $args['paged'] );
484
		$args['s'] = sanitize_text_field( $args['s'] );
485
		return $args;
486
	}
487
488
	/**
489
	 * Custom AJAX callback for the save-attachment action. If the request was
490
	 * not for a VideoPress object, core's fallback action will kick in.
491
	 */
492
	function wp_ajax_save_attachment() {
493
		if ( ! isset( $_POST['is_videopress'] ) )
494
			return;
495
496
		if ( ! $this->can( 'edit_videos' ) )
497
			return wp_send_json_error( 'permission denied' );
498
499
		$post_id = 0;
500 View Code Duplication
		if ( ! isset( $_POST['id'] ) || ! $post_id = absint( $_POST['id'] ) )
501
			wp_send_json_error();
502
503
		if ( ! isset( $_POST['vp_nonces']['update'] ) )
504
			wp_send_json_error();
505
506
		check_ajax_referer( 'update-videopress-post_' . $post_id, 'nonce' );
507
508
		$changes = ( ! empty( $_POST['changes'] ) ) ? (array) $_POST['changes'] : array();
509
		$changes = shortcode_atts( array(
510
			'title' => null,
511
			'caption' => null,
512
			'description' => null,
513
514
			'vp_share' => null,
515
			'vp_rating' => null,
516
		), $changes, 'wpvideo' );
517
518
		if ( ! is_null( $changes['vp_share'] ) )
519
			$changes['vp_share'] = (bool) $changes['vp_share'];
520
521
		if ( ! is_null( $changes['vp_rating'] ) )
522
			$changes['vp_rating'] = ( array_key_exists( $changes['vp_rating'], $this->get_available_ratings() ) ) ? $changes['vp_rating'] : null;
523
524
		// Remove null-values
525
		foreach ( $changes as $key => $value )
526
			if ( is_null( $value ) )
527
				unset( $changes[ $key ] );
528
529
		$result = $this->query( 'jetpack.vpSaveAttachment', array(
530
			'post_id' => $post_id,
531
			'changes' => $changes,
532
			'nonce' => $_POST['vp_nonces']['update'],
533
		) );
534
535
		if ( is_wp_error( $result ) )
536
			return wp_send_json_error( 'xml rpc request error' );
537
538
		wp_send_json_success();
539
	}
540
541
	/**
542
	 * Custom AJAX callback for the delete-post action, only for VideoPress objects.
543
	 */
544
	function wp_ajax_delete_post() {
545
		if ( ! isset( $_POST['is_videopress'] ) )
546
			return;
547
548
		if ( ! $this->can( 'delete_videos' ) )
549
			return wp_send_json_error( 'permission denied' );
550
551
		$post_id = 0;
552 View Code Duplication
		if ( ! isset( $_POST['id'] ) || ! $post_id = absint( $_POST['id'] ) )
553
			wp_send_json_error();
554
555
		if ( ! isset( $_POST['vp_nonces']['delete'] ) )
556
			wp_send_json_error();
557
558
		check_ajax_referer( 'delete-videopress-post_' . $post_id );
559
560
		$result = $this->query( 'jetpack.vpDeleteAttachment', array(
561
			'post_id' => $post_id,
562
			'nonce' => $_POST['vp_nonces']['delete'],
563
		) );
564
565
		if ( is_wp_error( $result ) )
566
			return wp_send_json_error( 'xml rpc request error' );
567
568
		wp_send_json_success();
569
	}
570
571
	/**
572
	 * Register VideoPress admin scripts.
573
	 */
574
	function enqueue_admin_scripts() {
575
		if ( did_action( 'videopress_enqueue_admin_scripts' ) )
576
			return;
577
578
		wp_enqueue_script( 'videopress-admin', plugins_url( 'js/videopress-admin.js', __FILE__ ), array( 'jquery', 'media-views', 'media-models' ), $this->version );
579
		wp_enqueue_style( 'videopress-admin', plugins_url( 'videopress-admin.css', __FILE__ ), array(), $this->version );
580
581
		$caps = array();
582 View Code Duplication
		foreach( array( 'read_videos', 'edit_videos', 'delete_videos', 'upload_videos' ) as $cap )
583
			$caps[ $cap ] = $this->can( $cap );
584
585
		$l10n = array(
586
			'selectVideoFile' => __( 'Please select a video file to upload.', 'jetpack' ),
587
			'videoUploading' => __( 'Your video is uploading... Please do not close this window.', 'jetpack' ),
588
			'unknownError' => __( 'An unknown error has occurred. Please try again later.', 'jetpack' ),
589
			'videoUploaded' => __( 'Your video has successfully been uploaded. It will appear in your VideoPress Library shortly.', 'jetpack' ),
590
			'VideoPressLibraryRouter' => __( 'VideoPress Library', 'jetpack' ),
591
			'uploadVideoRouter' => __( 'Upload a Video', 'jetpack' ),
592
			'insertVideoButton' => __( 'Insert Video', 'jetpack' ),
593
594
		);
595
596
		wp_localize_script( 'videopress-admin', 'VideoPressAdminSettings', array(
597
			'caps' => $caps,
598
			'l10n' => $l10n,
599
		) );
600
		
601
		/**
602
		 * Fires after VideoPress scripts are enqueued in the dashboard.
603
		 *
604
		 * @since 2.5.0
605
		 */
606
		do_action( 'videopress_enqueue_admin_scripts' );
607
	}
608
609
	/**
610
	 * Get an array of available ratings. Keys are options, values are labels.
611
	 */
612
	function get_available_ratings() {
613
		return array(
614
			'G' => 'G',
615
			'PG-13' => 'PG-13',
616
			'R-17' => 'R',
617
			'X-18' => 'X',
618
		);
619
	}
620
621
	/**
622
	 * Additional VideoPress media templates.
623
	 */
624
	function print_media_templates() {
625
		$options = $this->get_options();
626
		?>
627
		<script type="text/html" id="tmpl-videopress-attachment">
628
			<# if ( data.vp_ogg_url ) { #>
629
			<label class="setting vp-setting">
630
				<span><?php _e( 'Ogg File URL', 'jetpack' ); ?></span>
631
				<input type="text" value="{{ data.vp_ogg_url }}" onclick="this.focus();this.select();" readonly />
632
				<p class="help"><?php _e( 'Location of the Ogg video file.', 'jetpack' ); ?></p>
633
			</label>
634
			<# } #>
635
636
			<label class="setting vp-setting">
637
				<span><?php _e( 'Share', 'jetpack' ); ?></span>
638
				<input class="vp-checkbox" type="checkbox" <# if ( '1' === data.vp_share ) { #>checked<# } #> <# if ( ! data.can.save ) { #>disabled<# } #> />
639
				<label>
640
					<?php _e( 'Display share menu and allow viewers to embed or download this video', 'jetpack' ); ?>
641
				</label>
642
				<input class="vp-checkbox-text" type="text" value="{{ data.vp_share }}" data-setting="vp_share" style="display:none;" />
643
			</label>
644
645
			<label class="setting vp-setting">
646
				<span><?php _e( 'Rating', 'jetpack' ); ?></span>
647
648
				<?php foreach ( $this->get_available_ratings() as $value => $label ) : ?>
649
				<input class="vp-radio" type="radio" name="vp-radio-group" id="vp-rating-<?php echo sanitize_html_class( $value ); ?>" value="<?php echo esc_attr( $value ); ?>"
650
					<# if ( '<?php echo esc_attr( $value ); ?>' === data.vp_rating ) { #>checked<# } #>
651
					<# if ( ! data.can.save ) { #>disabled<# } #> />
652
				<label for="vp-rating-<?php echo sanitize_html_class( $value ); ?>"><?php echo esc_html( $label ); ?></label>
653
				<?php endforeach; ?>
654
655
				<input class="vp-radio-text" type="text" value="{{ data.vp_rating }}" data-setting="vp_rating" style="display:none;" />
656
			</label>
657
658
			<label class="setting vp-setting">
659
				<span><?php _e( 'Shortcode', 'jetpack' ); ?></span>
660
				<input type="text" value="[wpvideo {{ data.vp_guid }}]" onclick="this.focus();this.select();" readonly />
661
			</label>
662
663
			<label class="setting vp-setting vp-preview">
664
				<span><?php _e( 'Preview', 'jetpack' ); ?></span>
665
				<# if ( ! data.vp_thumbnail_url ) { #>
666
					<span class="videopress-preview-unavailable"><?php esc_html_e( 'The preview is unavailable while this video is being processed.', 'jetpack' ); ?></span>
667
				<# } else { #>
668
				<a href="#" class="videopress-preview" id="videopress-thumbnail-{{ data.vp_guid }}" data-videopress-guid="{{ data.vp_guid }}"><img src="{{ data.vp_thumbnail_url }}" /></a>
669
				<# } #>
670
			</label>
671
		</script>
672
673
		<script type="text/html" id="tmpl-videopress-media-modal">
674
			<div class="videopress-modal">
675
				<p><?php _e( 'Video Preview:', 'jetpack' ); ?></p>
676
				<div class="videopress-video-container">{{{ data.video }}}</div>
677
				<p class="submit">
678
					<a class="videopress-modal-close button" href="#"><?php _e( 'Close', 'jetpack' ); ?></a>
679
				</p>
680
			</div>
681
			<div class="videopress-modal-backdrop"></div>
682
		</script>
683
684
		<script type="text/html" id="tmpl-videopress-uploader">
685
			<div class="videopress-errors"></div>
686
			<form class="videopress-upload-form" action="" method="post" target="videopress_upload_frame" enctype="multipart/form-data">
687
				<input type="hidden" name="action" value="videopress_upload" />
688
				<input type="hidden" name="videopress_blog_id" value="0" />
689
				<input type="hidden" name="videopress_token" value="0" />
690
				<?php $formats = 'ogv, mp4, m4v, mov, wmv, avi, mpg, 3gp, 3g2'; ?>
691
				<?php
692
					$max_upload_size = 0;
693
					if ( ! empty( $options['meta']['max_upload_size'] ) )
694
						$max_upload_size = absint( $options['meta']['max_upload_size'] );
695
696
					$upload_size_unit = $max_upload_size;
697
					$byte_sizes = array( 'KB', 'MB', 'GB' );
698
699
					for ( $u = -1; $upload_size_unit > 1024 && $u < count( $byte_sizes ) - 1; $u++ )
700
						$upload_size_unit /= 1024;
701
702
					if ( $u < 0 ) {
703
						$upload_size_unit = 0;
704
						$u = 0;
705
					} else {
706
						$upload_size_unit = (int) $upload_size_unit;
707
					}
708
				?>
709
				<p><?php printf( __( 'Use the form below to upload a video to your VideoPress Library. The following video formats are supported: %s. Maximum upload file size is %d%s.', 'jetpack' ), esc_html( $formats ), esc_html( $upload_size_unit ), esc_html( $byte_sizes[ $u ] ) ); ?></p>
710
711
				<input type="file" name="videopress_file" />
712
				<?php submit_button( __( 'Upload Video', 'jetpack' ) ); ?>
713
			</form>
714
			<iframe width="0" height="0" name="videopress_upload_frame"></iframe>
715
		</script>
716
		<?php
717
	}
718
719
	/**
720
	 * Filters the VideoPress shortcode options, makes sure that
721
	 * the settings set in Jetpack's VideoPress module are applied.
722
	 */
723
	function videopress_shortcode_options( $options ) {
724
		$videopress_options = $this->get_options();
725
726
		if ( false === $options['freedom'] )
727
			$options['freedom'] = $videopress_options['freedom'];
728
729
		$options['hd'] = $videopress_options['hd'];
730
731
		return $options;
732
	}
733
734
}
735
736
// Initialize the module.
737
Jetpack_VideoPress::init();
738