Jetpack_VideoPress

VideoPress in Jetpack.

Defined (1)

The class is defined in the following location(s).

/modules/videopress/videopress.php  
  1. class Jetpack_VideoPress { 
  2. public $module = 'videopress'; 
  3. public $option_name = 'videopress'; 
  4. public $version = 4; 
  5.  
  6. /** 
  7. * Singleton 
  8. */ 
  9. public static function init() { 
  10. static $instance = false; 
  11.  
  12. if ( ! $instance ) 
  13. $instance = new Jetpack_VideoPress; 
  14.  
  15. return $instance; 
  16.  
  17. function __construct() { 
  18. $this->version = time(); // <s>ghost</s> cache busters! 
  19. add_action( 'jetpack_modules_loaded', array( $this, 'jetpack_modules_loaded' ) ); 
  20. add_action( 'jetpack_activate_module_videopress', array( $this, 'jetpack_module_activated' ) ); 
  21. add_action( 'jetpack_deactivate_module_videopress', array( $this, 'jetpack_module_deactivated' ) ); 
  22.  
  23. require_once( dirname( __FILE__ ) . '/shortcode.php' ); 
  24.  
  25. /** 
  26. * After all modules have been loaded. 
  27. */ 
  28. function jetpack_modules_loaded() { 
  29. $options = $this->get_options(); 
  30.  
  31. // Only the connection owner can configure this module. 
  32. if ( $this->is_connection_owner() ) { 
  33. Jetpack::enable_module_configurable( $this->module ); 
  34. Jetpack::module_configuration_load( $this->module, array( $this, 'jetpack_configuration_load' ) ); 
  35. Jetpack::module_configuration_screen( $this->module, array( $this, 'jetpack_configuration_screen' ) ); 
  36.  
  37. // Only if the current user can manage the VideoPress library and one has been connected. 
  38. if ( $this->can( 'read_videos' ) && $options['blog_id'] ) { 
  39. add_action( 'wp_enqueue_media', array( $this, 'enqueue_admin_scripts' ) ); 
  40. add_action( 'print_media_templates', array( $this, 'print_media_templates' ) ); 
  41.  
  42. // Load these at priority -1 so they're fired before Core's are. 
  43. add_action( 'wp_ajax_query-attachments', array( $this, 'wp_ajax_query_attachments' ), -1 ); 
  44. add_action( 'wp_ajax_save-attachment', array( $this, 'wp_ajax_save_attachment' ), -1 ); 
  45. add_action( 'wp_ajax_save-attachment-compat', array( $this, 'wp_ajax_save_attachment' ), -1 ); 
  46. add_action( 'wp_ajax_delete-post', array( $this, 'wp_ajax_delete_post' ), -1 ); 
  47.  
  48. add_action( 'admin_menu', array( $this, 'admin_menu' ) ); 
  49.  
  50. if ( $this->can( 'upload_videos' ) && $options['blog_id'] ) { 
  51. add_action( 'wp_ajax_videopress-get-upload-token', array( $this, 'wp_ajax_videopress_get_upload_token' ) ); 
  52.  
  53. add_filter( 'videopress_shortcode_options', array( $this, 'videopress_shortcode_options' ) ); 
  54.  
  55. function wp_ajax_videopress_get_upload_token() { 
  56. if ( ! $this->can( 'upload_videos' ) ) 
  57. return wp_send_json_error(); 
  58.  
  59. $result = $this->query( 'jetpack.vpGetUploadToken' ); 
  60. if ( is_wp_error( $result ) ) 
  61. return wp_send_json_error( array( 'message' => __( 'Could not obtain a VideoPress upload token. Please try again later.', 'jetpack' ) ) ); 
  62.  
  63. $response = $result; 
  64. if ( empty( $response['videopress_blog_id'] ) || empty( $response['videopress_token'] ) || empty( $response[ 'videopress_action_url' ] ) ) 
  65. return wp_send_json_error( array( 'message' => __( 'Could not obtain a VideoPress upload token. Please try again later.', 'jetpack' ) ) ); 
  66.  
  67. return wp_send_json_success( $response ); 
  68.  
  69. /** 
  70. * Get VideoPress options 
  71. */ 
  72. function get_options() { 
  73. $defaults = array( 
  74. 'blogs' => array(),  
  75. 'blog_id' => 0,  
  76. 'access' => '',  
  77. 'allow-upload' => false,  
  78. 'freedom' => false,  
  79. 'hd' => false,  
  80. 'meta' => array( 
  81. 'max_upload_size' => 0,  
  82. ),  
  83. ); 
  84.  
  85. $options = Jetpack_Options::get_option( $this->option_name, array() ); 
  86.  
  87. // If options have not been saved yet, check for older VideoPress plugin options. 
  88. if ( empty( $options ) ) { 
  89. $options['freedom'] = (bool) get_option( 'video_player_freedom', false ); 
  90. $options['hd'] = (bool) get_option( 'video_player_high_quality', false ); 
  91.  
  92. $options = array_merge( $defaults, $options ); 
  93. return $options; 
  94.  
  95. /** 
  96. * Update VideoPress options 
  97. */ 
  98. function update_options( $options ) { 
  99. Jetpack_Options::update_option( $this->option_name, $options ); 
  100.  
  101. /** 
  102. * Runs when the VideoPress module is activated. 
  103. */ 
  104. function jetpack_module_activated() { 
  105. if ( ! $this->is_connection_owner() ) 
  106. return; 
  107.  
  108. $options = $this->get_options(); 
  109.  
  110. // Ask WordPress.com for a list of VideoPress blogs 
  111. $result = $this->query( 'jetpack.vpGetBlogs' ); 
  112. if ( ! is_wp_error( $result ) ) 
  113. $options['blogs'] = $result; 
  114.  
  115. // If there's at least one available blog, let's use it. 
  116. if ( is_array( $options['blogs'] ) && count( $options['blogs'] ) > 0 ) 
  117. $options['blog_id'] = $options['blogs'][0]['blog_id']; 
  118.  
  119. $this->update_options( $options ); 
  120.  
  121. /** 
  122. * Runs when the VideoPress module is deactivated. 
  123. */ 
  124. function jetpack_module_deactivated() { 
  125. Jetpack_Options::delete_option( $this->option_name ); 
  126.  
  127. /** 
  128. * Remote Query 
  129. * Performs a remote XML-RPC query using Jetpack's IXR Client. And also 
  130. * appends some useful stuff about this setup to the query. 
  131. * @return the Jetpack_IXR_Client object after querying. 
  132. */ 
  133. function query( $method, $args = null ) { 
  134. $options = $this->get_options(); 
  135. Jetpack::load_xml_rpc_client(); 
  136. $xml = new Jetpack_IXR_Client( array( 
  137. 'user_id' => JETPACK_MASTER_USER, // All requests are on behalf of the connection owner. 
  138. ) ); 
  139.  
  140. $params = array( 
  141. 'args' => $args,  
  142. 'video_blog_id' => $options['blog_id'],  
  143. 'caps' => array(),  
  144. ); 
  145.  
  146. // Let Jetpack know about our local caps. 
  147. foreach ( array( 'read_videos', 'edit_videos', 'delete_videos', 'upload_videos' ) as $cap ) 
  148. if ( $this->can( $cap ) ) 
  149. $params['caps'][] = $cap; 
  150.  
  151. $xml->query( $method, $params ); 
  152.  
  153. if ( $xml->isError() ) 
  154. return new WP_Error( 'xml_rpc_error', 'An XML-RPC error has occurred.' ); 
  155.  
  156. $response = $xml->getResponse(); 
  157.  
  158. // If there's any metadata with the response, save it for future use. 
  159. if ( is_array( $response ) && isset( $response['meta'] ) ) { 
  160. $options = $this->get_options(); 
  161. if ( $response['meta'] !== $options['meta'] ) { 
  162. $options['meta'] = array_merge( $options['meta'], $response['meta'] ); 
  163. $this->update_options( $options ); 
  164.  
  165. if ( is_array( $response ) && isset( $response['result'] ) ) 
  166. return $response['result']; 
  167.  
  168. return $response; 
  169.  
  170. /** 
  171. * Runs before the VideoPress Configuration screen loads, useful 
  172. * to update options and yield errors. 
  173. */ 
  174. function jetpack_configuration_load() { 
  175. $this->enqueue_admin_scripts(); 
  176.  
  177. /** 
  178. * Save configuration 
  179. */ 
  180. if ( ! empty( $_POST['action'] ) && $_POST['action'] == 'videopress-save' ) { 
  181. check_admin_referer( 'videopress-settings' ); 
  182. $options = $this->get_options(); 
  183.  
  184. if ( isset( $_POST['blog_id'] ) && in_array( $_POST['blog_id'], wp_list_pluck( $options['blogs'], 'blog_id' ) ) ) 
  185. $options['blog_id'] = $_POST['blog_id']; 
  186.  
  187. // Allow the None setting too. 
  188. if ( isset( $_POST['blog_id'] ) && $_POST['blog_id'] == 0 ) 
  189. $options['blog_id'] = 0; 
  190.  
  191. /** 
  192. * @see $this->can() 
  193. */ 
  194. if ( isset( $_POST['videopress-access'] ) && in_array( $_POST['videopress-access'], array( '', 'read', 'edit', 'delete' ) ) ) 
  195. $options['access'] = $_POST['videopress-access']; 
  196.  
  197. $options['freedom'] = isset( $_POST['videopress-freedom'] ); 
  198. $options['hd'] = isset( $_POST['videopress-hd'] ); 
  199.  
  200. // Allow upload only if some level of access has been granted, and uploads were allowed. 
  201. $options['allow-upload'] = false; 
  202. if ( ! empty( $options['access'] ) && isset( $_POST['videopress-upload'] ) ) 
  203. $options['allow-upload'] = true; 
  204.  
  205. $this->update_options( $options ); 
  206. Jetpack::state( 'message', 'module_configured' ); 
  207. wp_safe_redirect( Jetpack::module_configuration_url( $this->module ) ); 
  208.  
  209. /** 
  210. * Refresh the list of available WordPress.com blogs 
  211. */ 
  212. if ( ! empty( $_GET['videopress'] ) && $_GET['videopress'] == 'refresh-blogs' ) { 
  213. check_admin_referer( 'videopress-settings' ); 
  214. $options = $this->get_options(); 
  215.  
  216. $result = $this->query( 'jetpack.vpGetBlogs' ); 
  217. if ( ! is_wp_error( $result ) ) { 
  218. $options['blogs'] = $result; 
  219. $this->update_options( $options ); 
  220.  
  221. wp_safe_redirect( Jetpack::module_configuration_url( $this->module ) ); 
  222.  
  223. /** 
  224. * Renders the VideoPress Configuration screen in Jetpack. 
  225. */ 
  226. function jetpack_configuration_screen() { 
  227. $options = $this->get_options(); 
  228. $refresh_url = wp_nonce_url( add_query_arg( 'videopress', 'refresh-blogs' ), 'videopress-settings' ); 
  229. ?> 
  230. <div class="narrow"> 
  231. <form method="post" id="videopress-settings"> 
  232. <input type="hidden" name="action" value="videopress-save" /> 
  233. <?php wp_nonce_field( 'videopress-settings' ); ?> 
  234.  
  235. <table id="menu" class="form-table"> 
  236. <tr> 
  237. <th scope="row" colspan="2"> 
  238. <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> 
  239. </th> 
  240. </tr> 
  241. <tr> 
  242. <th scope="row"> 
  243. <label><?php _e( 'Connected WordPress.com Blog', 'jetpack' ); ?></label> 
  244. </th> 
  245. <td> 
  246. <select name="blog_id"> 
  247. <option value="0" <?php selected( $options['blog_id'], 0 ); ?>> <?php esc_html_e( 'None', 'jetpack' ); ?></option> 
  248. <?php foreach ( $options['blogs'] as $blog ) : ?> 
  249. <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> 
  250. <?php endforeach; ?> 
  251. </select> 
  252. <p class="description"><?php _e( 'Only videos from the selected blog will be available in your media library.', 'jetpack' ); ?> 
  253. <?php printf( __( '<a href="%s">Click here</a> to refresh this list.', 'jetpack' ), esc_url( $refresh_url ) ); ?> 
  254. </p> 
  255. </td> 
  256. </tr> 
  257. <tr> 
  258. <th scope="row"> 
  259. <label><?php _e( 'Video Library Access', 'jetpack' ); ?></label> 
  260. </th> 
  261. <td> 
  262. <label><input type="radio" name="videopress-access" value="" <?php checked( '', $options['access'] ); ?> /> 
  263. <?php _e( 'Do not allow other users to access my VideoPress library', 'jetpack' ); ?></label><br/> 
  264. <label><input type="radio" name="videopress-access" value="read" <?php checked( 'read', $options['access'] ); ?> /> 
  265. <?php _e( 'Allow users to access my videos', 'jetpack' ); ?></label><br/> 
  266. <label><input type="radio" name="videopress-access" value="edit" <?php checked( 'edit', $options['access'] ); ?> /> 
  267. <?php _e( 'Allow users to access and edit my videos', 'jetpack' ); ?></label><br/> 
  268. <label><input type="radio" name="videopress-access" value="delete" <?php checked( 'delete', $options['access'] ); ?> /> 
  269. <?php _e( 'Allow users to access, edit, and delete my videos', 'jetpack' ); ?></label><br/><br /> 
  270.  
  271. <label><input type="checkbox" name="videopress-upload" value="1" <?php checked( $options['allow-upload'] ); ?> /> 
  272. <?php _e( 'Allow users to upload videos', 'jetpack' ); ?></label><br /> 
  273. </td> 
  274. </tr> 
  275. <tr> 
  276. <th scope="row"> 
  277. <label for="videopress-freedom"><?php _e( 'Free formats', 'jetpack' ); ?></label> 
  278. </th> 
  279. <td> 
  280. <label><input type="checkbox" name="videopress-freedom" id="videopress-freedom" <?php checked( $options['freedom'] ); ?> /> 
  281. <?php _e( 'Only display videos in free software formats', 'jetpack' ); ?></label> 
  282. <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> 
  283. </td> 
  284. </tr> 
  285. <tr> 
  286. <th scope="row"> 
  287. <label for="videopress-hd"><?php _e( 'Default quality', 'jetpack' ); ?></label> 
  288. </th> 
  289. <td> 
  290. <label><input type="checkbox" name="videopress-hd" id="videopress-hd" <?php checked( $options['hd'] ); ?> /> 
  291. <?php _e( 'Display higher quality video by default.', 'jetpack' ); ?></label> 
  292. <p class="description"><?php _e( 'This setting may be overridden for individual videos.', 'jetpack' ); ?></p> 
  293. </td> 
  294. </tr> 
  295. </table> 
  296.  
  297. <?php submit_button(); ?> 
  298. </form> 
  299. </div> 
  300. <?php 
  301.  
  302. function admin_menu() { 
  303. add_media_page( __( 'VideoPress Library', 'jetpack' ), __( 'VideoPress', 'jetpack' ), 'upload_files', 'videopress-library', array( $this, 'admin_menu_library' ) ); 
  304.  
  305. function admin_menu_library() { 
  306. wp_enqueue_media(); 
  307. $this->enqueue_admin_scripts(); 
  308. ?> 
  309. <div class="wrap" style="max-width: 600px;"> 
  310. <?php screen_icon(); ?> 
  311. <h2><?php _e( 'VideoPress Library', 'jetpack' ); ?></h2> 
  312. <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> 
  313. <p class="hide-if-no-js"><a href="#" id="videopress-browse" class="button"><?php _e( 'Browse Your VideoPress Library', 'jetpack' ); ?></a></p> 
  314. <p class="hide-if-js description"><?php _e( 'Please enable JavaScript support in your browser to use VideoPress.', 'jetpack' ); ?></p> 
  315. </div> 
  316. <?php 
  317.  
  318. /** 
  319. * A can of coke 
  320. * Similar to current_user_can, but internal to VideoPress. Returns 
  321. * true if the given VideoPress capability is allowed by the given user. 
  322. */ 
  323. function can( $cap, $user_id = false ) { 
  324. if ( ! $user_id ) 
  325. $user_id = get_current_user_id(); 
  326.  
  327. // Connection owners are allowed to do all the things. 
  328. if ( $this->is_connection_owner( $user_id ) ) 
  329. return true; 
  330.  
  331. /** 
  332. * The access setting can be set by the connection owner, to allow sets 
  333. * of operations to other site users. Each access value corresponds to 
  334. * an array of things they can do. 
  335. */ 
  336.  
  337. $options = $this->get_options(); 
  338. $map = array( 
  339. 'read' => array( 'read_videos' ),  
  340. 'edit' => array( 'read_videos', 'edit_videos' ),  
  341. 'delete' => array( 'read_videos', 'edit_videos', 'delete_videos' ),  
  342. ); 
  343.  
  344. if ( ! array_key_exists( $options['access'], $map ) ) 
  345. return false; 
  346.  
  347. if ( ! in_array( $cap, $map[ $options['access'] ] ) && 'upload_videos' != $cap ) 
  348. return false; 
  349.  
  350. // Additional and intrenal caps checks 
  351.  
  352. if ( ! user_can( $user_id, 'upload_files' ) ) 
  353. return false; 
  354.  
  355. if ( 'edit_videos' == $cap && ! user_can( $user_id, 'edit_others_posts' ) ) 
  356. return false; 
  357.  
  358. if ( 'delete_videos' == $cap && ! user_can( $user_id, 'delete_others_posts' ) ) 
  359. return false; 
  360.  
  361. if ( 'upload_videos' == $cap && ! $options['allow-upload'] ) 
  362. return false; 
  363.  
  364. return true; 
  365.  
  366. /** 
  367. * Returns true if the provided user is the Jetpack connection owner. 
  368. */ 
  369. function is_connection_owner( $user_id = false ) { 
  370. if ( ! $user_id ) 
  371. $user_id = get_current_user_id(); 
  372.  
  373. $user_token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER ); 
  374. return $user_token && is_object( $user_token ) && isset( $user_token->external_user_id ) && $user_id === $user_token->external_user_id; 
  375.  
  376. /** 
  377. * Our custom AJAX callback for the query-attachments action 
  378. * used in the media modal. By-passed if not for VideoPress. 
  379. */ 
  380. function wp_ajax_query_attachments() { 
  381.  
  382. // Watch for VideoPress calls 
  383. if ( ! isset( $_POST['query']['videopress'] ) ) 
  384. return; 
  385.  
  386. if ( ! $this->can( 'read_videos' ) ) 
  387. return wp_send_json_error( 'permission denied' ); 
  388.  
  389. // Get and sanitize query arguments. 
  390. $query_args = $this->sanitize_wp_query_args( $_POST['query'] ); 
  391.  
  392. // Fire a remote WP_Query 
  393. $result = $this->query( 'jetpack.vpQuery', $query_args ); 
  394.  
  395. if ( is_wp_error( $result ) ) 
  396. return wp_send_json_error( 'xml rpc request error' ); 
  397.  
  398. $items = $result; 
  399. $shortcode_handler = Jetpack_VideoPress_Shortcode::init(); 
  400.  
  401. foreach ( $items as $key => $item ) { 
  402.  
  403. // Check local permissions 
  404. if ( ! $this->can( 'edit_videos' ) ) 
  405. unset( $item['vp_nonces']['update'] ); 
  406.  
  407. if ( ! $this->can( 'delete_videos' ) ) 
  408. unset( $item['vp_nonces']['delete'] ); 
  409.  
  410. // Add a second pair of nonces for the .org blog. 
  411. $item['nonces'] = array(); 
  412. if ( ! empty( $item['vp_nonces']['update'] ) ) 
  413. $item['nonces']['update'] = wp_create_nonce( 'update-videopress-post_' . $item['id'] ); 
  414.  
  415. if ( ! empty( $item['vp_nonces']['delete'] ) ) 
  416. $item['nonces']['delete'] = wp_create_nonce( 'delete-videopress-post_' . $item['id'] ); 
  417.  
  418. $item['vp_embed'] = $shortcode_handler->shortcode_callback( array( 
  419. $item['vp_guid'],  
  420. 'autoplay' => true,  
  421. 'flashonly' => true,  
  422. 'w' => 440,  
  423. ) ); 
  424.  
  425. $items[ $key ] = $item; 
  426.  
  427. wp_send_json_success( $items ); 
  428.  
  429. /** 
  430. * Sanitize user-provided WP_Query arguments 
  431. * These might be sent to the VideoPress server, for a remote WP_Query 
  432. * call so let's make sure they're sanitized and safe to send. 
  433. */ 
  434. function sanitize_wp_query_args( $args ) { 
  435. $args = shortcode_atts( array( 
  436. 'posts_per_page' => 40,  
  437. 'orderby' => 'date',  
  438. 'order' => 'desc',  
  439. 'paged' => 1,  
  440. 's' => '',  
  441. ), (array) $args, 'wpvideo' ); 
  442.  
  443. $args['posts_per_page'] = absint( $args['posts_per_page'] ); 
  444.  
  445. $args['orderby'] = strtolower( $args['orderby'] ); 
  446. $args['orderby'] = ( in_array( $args['orderby'], array( 'date' ) ) ) ? $args['orderby'] : 'date'; 
  447.  
  448. $args['order'] = strtolower( $args['order'] ); 
  449. $args['order'] = ( in_array( $args['order'], array( 'asc', 'desc' ) ) ) ? $args['order'] : 'desc'; 
  450.  
  451. $args['paged'] = absint( $args['paged'] ); 
  452. $args['s'] = sanitize_text_field( $args['s'] ); 
  453. return $args; 
  454.  
  455. /** 
  456. * Custom AJAX callback for the save-attachment action. If the request was 
  457. * not for a VideoPress object, core's fallback action will kick in. 
  458. */ 
  459. function wp_ajax_save_attachment() { 
  460. if ( ! isset( $_POST['is_videopress'] ) ) 
  461. return; 
  462.  
  463. if ( ! $this->can( 'edit_videos' ) ) 
  464. return wp_send_json_error( 'permission denied' ); 
  465.  
  466. $post_id = 0; 
  467. if ( ! isset( $_POST['id'] ) || ! $post_id = absint( $_POST['id'] ) ) 
  468. wp_send_json_error(); 
  469.  
  470. if ( ! isset( $_POST['vp_nonces']['update'] ) ) 
  471. wp_send_json_error(); 
  472.  
  473. check_ajax_referer( 'update-videopress-post_' . $post_id, 'nonce' ); 
  474.  
  475. $changes = ( ! empty( $_POST['changes'] ) ) ? (array) $_POST['changes'] : array(); 
  476. $changes = shortcode_atts( array( 
  477. 'title' => null,  
  478. 'caption' => null,  
  479. 'description' => null,  
  480.  
  481. 'vp_share' => null,  
  482. 'vp_rating' => null,  
  483. ), $changes, 'wpvideo' ); 
  484.  
  485. if ( ! is_null( $changes['vp_share'] ) ) 
  486. $changes['vp_share'] = (bool) $changes['vp_share']; 
  487.  
  488. if ( ! is_null( $changes['vp_rating'] ) ) 
  489. $changes['vp_rating'] = ( array_key_exists( $changes['vp_rating'], $this->get_available_ratings() ) ) ? $changes['vp_rating'] : null; 
  490.  
  491. // Remove null-values 
  492. foreach ( $changes as $key => $value ) 
  493. if ( is_null( $value ) ) 
  494. unset( $changes[ $key ] ); 
  495.  
  496. $result = $this->query( 'jetpack.vpSaveAttachment', array( 
  497. 'post_id' => $post_id,  
  498. 'changes' => $changes,  
  499. 'nonce' => $_POST['vp_nonces']['update'],  
  500. ) ); 
  501.  
  502. if ( is_wp_error( $result ) ) 
  503. return wp_send_json_error( 'xml rpc request error' ); 
  504.  
  505. wp_send_json_success(); 
  506.  
  507. /** 
  508. * Custom AJAX callback for the delete-post action, only for VideoPress objects. 
  509. */ 
  510. function wp_ajax_delete_post() { 
  511. if ( ! isset( $_POST['is_videopress'] ) ) 
  512. return; 
  513.  
  514. if ( ! $this->can( 'delete_videos' ) ) 
  515. return wp_send_json_error( 'permission denied' ); 
  516.  
  517. $post_id = 0; 
  518. if ( ! isset( $_POST['id'] ) || ! $post_id = absint( $_POST['id'] ) ) 
  519. wp_send_json_error(); 
  520.  
  521. if ( ! isset( $_POST['vp_nonces']['delete'] ) ) 
  522. wp_send_json_error(); 
  523.  
  524. check_ajax_referer( 'delete-videopress-post_' . $post_id ); 
  525.  
  526. $result = $this->query( 'jetpack.vpDeleteAttachment', array( 
  527. 'post_id' => $post_id,  
  528. 'nonce' => $_POST['vp_nonces']['delete'],  
  529. ) ); 
  530.  
  531. if ( is_wp_error( $result ) ) 
  532. return wp_send_json_error( 'xml rpc request error' ); 
  533.  
  534. wp_send_json_success(); 
  535.  
  536. /** 
  537. * Register VideoPress admin scripts. 
  538. */ 
  539. function enqueue_admin_scripts() { 
  540. if ( did_action( 'videopress_enqueue_admin_scripts' ) ) 
  541. return; 
  542.  
  543. wp_enqueue_script( 'videopress-admin', plugins_url( 'videopress-admin.js', __FILE__ ), array( 'jquery', 'media-views', 'media-models' ), $this->version ); 
  544. wp_enqueue_style( 'videopress-admin', plugins_url( 'videopress-admin.css', __FILE__ ), array(), $this->version ); 
  545.  
  546. $caps = array(); 
  547. foreach( array( 'read_videos', 'edit_videos', 'delete_videos', 'upload_videos' ) as $cap ) 
  548. $caps[ $cap ] = $this->can( $cap ); 
  549.  
  550. $l10n = array( 
  551. 'selectVideoFile' => __( 'Please select a video file to upload.', 'jetpack' ),  
  552. 'videoUploading' => __( 'Your video is uploading... Please do not close this window.', 'jetpack' ),  
  553. 'unknownError' => __( 'An unknown error has occurred. Please try again later.', 'jetpack' ),  
  554. 'videoUploaded' => __( 'Your video has successfully been uploaded. It will appear in your VideoPress Library shortly.', 'jetpack' ),  
  555. 'VideoPressLibraryRouter' => __( 'VideoPress Library', 'jetpack' ),  
  556. 'uploadVideoRouter' => __( 'Upload a Video', 'jetpack' ),  
  557. 'insertVideoButton' => __( 'Insert Video', 'jetpack' ),  
  558.  
  559. ); 
  560.  
  561. wp_localize_script( 'videopress-admin', 'VideoPressAdminSettings', array( 
  562. 'caps' => $caps,  
  563. 'l10n' => $l10n,  
  564. ) ); 
  565.  
  566. /** 
  567. * Fires after VideoPress scripts are enqueued in the dashboard. 
  568. * @since 2.5.0 
  569. */ 
  570. do_action( 'videopress_enqueue_admin_scripts' ); 
  571.  
  572. /** 
  573. * Get an array of available ratings. Keys are options, values are labels. 
  574. */ 
  575. function get_available_ratings() { 
  576. return array( 
  577. 'G' => 'G',  
  578. 'PG-13' => 'PG-13',  
  579. 'R-17' => 'R',  
  580. 'X-18' => 'X',  
  581. ); 
  582.  
  583. /** 
  584. * Additional VideoPress media templates. 
  585. */ 
  586. function print_media_templates() { 
  587. $options = $this->get_options(); 
  588. ?> 
  589. <script type="text/html" id="tmpl-videopress-attachment"> 
  590. <# if ( data.vp_ogg_url ) { #> 
  591. <label class="setting vp-setting"> 
  592. <span><?php _e( 'Ogg File URL', 'jetpack' ); ?></span> 
  593. <input type="text" value="{{ data.vp_ogg_url }}" onclick="this.focus();this.select();" readonly /> 
  594. <p class="help"><?php _e( 'Location of the Ogg video file.', 'jetpack' ); ?></p> 
  595. </label> 
  596. <# } #> 
  597.  
  598. <label class="setting vp-setting"> 
  599. <span><?php _e( 'Share', 'jetpack' ); ?></span> 
  600. <input class="vp-checkbox" type="checkbox" <# if ( '1' === data.vp_share ) { #>checked<# } #> <# if ( ! data.can.save ) { #>disabled<# } #> /> 
  601. <label> 
  602. <?php _e( 'Display share menu and allow viewers to embed or download this video', 'jetpack' ); ?> 
  603. </label> 
  604. <input class="vp-checkbox-text" type="text" value="{{ data.vp_share }}" data-setting="vp_share" style="display:none;" /> 
  605. </label> 
  606.  
  607. <label class="setting vp-setting"> 
  608. <span><?php _e( 'Rating', 'jetpack' ); ?></span> 
  609.  
  610. <?php foreach ( $this->get_available_ratings() as $value => $label ) : ?> 
  611. <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 ); ?>" 
  612. <# if ( '<?php echo esc_attr( $value ); ?>' === data.vp_rating ) { #>checked<# } #> 
  613. <# if ( ! data.can.save ) { #>disabled<# } #> /> 
  614. <label for="vp-rating-<?php echo sanitize_html_class( $value ); ?>"><?php echo esc_html( $label ); ?></label> 
  615. <?php endforeach; ?> 
  616.  
  617. <input class="vp-radio-text" type="text" value="{{ data.vp_rating }}" data-setting="vp_rating" style="display:none;" /> 
  618. </label> 
  619.  
  620. <label class="setting vp-setting"> 
  621. <span><?php _e( 'Shortcode', 'jetpack' ); ?></span> 
  622. <input type="text" value="[wpvideo {{ data.vp_guid }}]" onclick="this.focus();this.select();" readonly /> 
  623. </label> 
  624.  
  625. <label class="setting vp-setting vp-preview"> 
  626. <span><?php _e( 'Preview', 'jetpack' ); ?></span> 
  627. <# if ( ! data.vp_thumbnail_url ) { #> 
  628. <span class="videopress-preview-unavailable"><?php esc_html_e( 'The preview is unavailable while this video is being processed.', 'jetpack' ); ?></span> 
  629. <# } else { #> 
  630. <a href="#" class="videopress-preview" id="videopress-thumbnail-{{ data.vp_guid }}" data-videopress-guid="{{ data.vp_guid }}"><img src="{{ data.vp_thumbnail_url }}" /></a> 
  631. <# } #> 
  632. </label> 
  633. </script> 
  634.  
  635. <script type="text/html" id="tmpl-videopress-media-modal"> 
  636. <div class="videopress-modal"> 
  637. <p><?php _e( 'Video Preview:', 'jetpack' ); ?></p> 
  638. <div class="videopress-video-container">{{{ data.video }}}</div> 
  639. <p class="submit"> 
  640. <a class="videopress-modal-close button" href="#"><?php _e( 'Close', 'jetpack' ); ?></a> 
  641. </p> 
  642. </div> 
  643. <div class="videopress-modal-backdrop"></div> 
  644. </script> 
  645.  
  646. <script type="text/html" id="tmpl-videopress-uploader"> 
  647. <div class="videopress-errors"></div> 
  648. <form class="videopress-upload-form" action="" method="post" target="videopress_upload_frame" enctype="multipart/form-data"> 
  649. <input type="hidden" name="action" value="videopress_upload" /> 
  650. <input type="hidden" name="videopress_blog_id" value="0" /> 
  651. <input type="hidden" name="videopress_token" value="0" /> 
  652. <?php $formats = 'ogv, mp4, m4v, mov, wmv, avi, mpg, 3gp, 3g2'; ?> 
  653. <?php 
  654. $max_upload_size = 0; 
  655. if ( ! empty( $options['meta']['max_upload_size'] ) ) 
  656. $max_upload_size = absint( $options['meta']['max_upload_size'] ); 
  657.  
  658. $upload_size_unit = $max_upload_size; 
  659. $byte_sizes = array( 'KB', 'MB', 'GB' ); 
  660.  
  661. for ( $u = -1; $upload_size_unit > 1024 && $u < count( $byte_sizes ) - 1; $u++ ) 
  662. $upload_size_unit /= 1024; 
  663.  
  664. if ( $u < 0 ) { 
  665. $upload_size_unit = 0; 
  666. $u = 0; 
  667. } else { 
  668. $upload_size_unit = (int) $upload_size_unit; 
  669. ?> 
  670. <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> 
  671.  
  672. <input type="file" name="videopress_file" /> 
  673. <?php submit_button( __( 'Upload Video', 'jetpack' ) ); ?> 
  674. </form> 
  675. <iframe width="0" height="0" name="videopress_upload_frame"></iframe> 
  676. </script> 
  677. <?php 
  678.  
  679. /** 
  680. * Filters the VideoPress shortcode options, makes sure that 
  681. * the settings set in Jetpack's VideoPress module are applied. 
  682. */ 
  683. function videopress_shortcode_options( $options ) { 
  684. $videopress_options = $this->get_options(); 
  685.  
  686. if ( false === $options['freedom'] ) 
  687. $options['freedom'] = $videopress_options['freedom']; 
  688.  
  689. $options['hd'] = $videopress_options['hd']; 
  690.  
  691. return $options;