PageRenderTime 29ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/jetpack/modules/videopress/class.jetpack-videopress.php

https://gitlab.com/chernushov881/charity-fund
PHP | 428 lines | 235 code | 70 blank | 123 comment | 32 complexity | 293afc3ae1a06a989dce06fd149b59a3 MD5 | raw file
  1. <?php
  2. use Automattic\Jetpack\Assets;
  3. use Automattic\Jetpack\Connection\Client;
  4. /**
  5. * VideoPress in Jetpack
  6. */
  7. class Jetpack_VideoPress {
  8. /** @var string */
  9. public $module = 'videopress';
  10. /** @var int */
  11. public $version = 5;
  12. /**
  13. * Singleton
  14. */
  15. public static function init() {
  16. static $instance = false;
  17. if ( ! $instance ) {
  18. $instance = new Jetpack_VideoPress();
  19. }
  20. return $instance;
  21. }
  22. /**
  23. * Jetpack_VideoPress constructor.
  24. *
  25. * Sets up the initializer and makes sure that videopress activates and deactivates properly.
  26. */
  27. private function __construct() {
  28. // $this->version = time(); // <s>ghost</s> cache busters!
  29. add_action( 'init', array( $this, 'on_init' ) );
  30. add_action( 'jetpack_deactivate_module_videopress', array( $this, 'jetpack_module_deactivated' ) );
  31. }
  32. /**
  33. * Fires on init
  34. */
  35. public function on_init() {
  36. add_action( 'wp_enqueue_media', array( $this, 'enqueue_admin_scripts' ) );
  37. add_filter( 'plupload_default_settings', array( $this, 'videopress_pluploder_config' ) );
  38. add_filter( 'wp_get_attachment_url', array( $this, 'maybe_get_attached_url_for_videopress' ), 10, 2 );
  39. add_filter( 'get_attached_file', array( $this, 'maybe_get_attached_url_for_videopress' ), 10, 2 );
  40. if ( Jetpack_Plan::supports( 'videopress' ) ) {
  41. add_filter( 'upload_mimes', array( $this, 'add_video_upload_mimes' ), 999 );
  42. }
  43. add_action( 'admin_print_footer_scripts', array( $this, 'print_in_footer_open_media_add_new' ) );
  44. add_action( 'admin_head', array( $this, 'enqueue_admin_styles' ) );
  45. add_filter( 'pre_delete_attachment', array( $this, 'delete_video_wpcom' ), 10, 2 );
  46. add_filter( 'wp_mime_type_icon', array( $this, 'wp_mime_type_icon' ), 10, 3 );
  47. add_filter( 'wp_video_extensions', array( $this, 'add_videopress_extenstion' ) );
  48. VideoPress_Scheduler::init();
  49. VideoPress_XMLRPC::init();
  50. if ( $this->is_videopress_enabled() ) {
  51. add_action( 'admin_notices', array( $this, 'media_new_page_admin_notice' ) );
  52. }
  53. }
  54. /**
  55. * The media-new.php page isn't supported for uploading to VideoPress.
  56. *
  57. * There is either a technical reason for this (bulk uploader isn't overridable),
  58. * or it is an intentional way to give site owners an option for uploading videos that bypass VideoPress.
  59. */
  60. public function media_new_page_admin_notice() {
  61. global $pagenow;
  62. if ( 'media-new.php' === $pagenow ) {
  63. echo '<div class="notice notice-warning is-dismissible">' .
  64. '<p>' .
  65. wp_kses(
  66. sprintf(
  67. /* translators: %s is the url to the Media Library */
  68. __( 'VideoPress uploads are not supported here. To upload to VideoPress, add your videos from the <a href="%s">Media Library</a> or the block editor using the Video block.', 'jetpack' ),
  69. esc_url( admin_url( 'upload.php' ) )
  70. ),
  71. array(
  72. 'a' => array( 'href' => array() ),
  73. )
  74. ) .
  75. '</p>' .
  76. '</div>';
  77. }
  78. }
  79. /**
  80. * Runs when the VideoPress module is deactivated.
  81. */
  82. public function jetpack_module_deactivated() {
  83. VideoPress_Options::delete_options();
  84. }
  85. /**
  86. * A can of coke
  87. *
  88. * Similar to current_user_can, but internal to VideoPress. Returns
  89. * true if the given VideoPress capability is allowed by the given user.
  90. */
  91. public function can( $cap, $user_id = false ) {
  92. if ( ! $user_id ) {
  93. $user_id = get_current_user_id();
  94. }
  95. // Connection owners are allowed to do all the things.
  96. if ( Jetpack::connection()->is_connection_owner( $user_id ) ) {
  97. return true;
  98. }
  99. // Additional and internal caps checks
  100. if ( ! user_can( $user_id, 'upload_files' ) ) {
  101. return false;
  102. }
  103. if ( 'edit_videos' == $cap && ! user_can( $user_id, 'edit_others_posts' ) ) {
  104. return false;
  105. }
  106. if ( 'delete_videos' == $cap && ! user_can( $user_id, 'delete_others_posts' ) ) {
  107. return false;
  108. }
  109. return true;
  110. }
  111. /**
  112. * Register and enqueue VideoPress admin styles.
  113. */
  114. public function enqueue_admin_styles() {
  115. wp_register_style( 'videopress-admin', plugins_url( 'videopress-admin.css', __FILE__ ), array(), $this->version );
  116. wp_enqueue_style( 'videopress-admin' );
  117. }
  118. /**
  119. * Attempts to delete a VideoPress video from wp.com.
  120. * Will block the deletion from continuing if certain errors return from the wp.com API.
  121. *
  122. * @param Boolean $delete if the deletion should occur or not (unused).
  123. * @param WP_Post $post the post object.
  124. *
  125. * @return null|WP_Error|Boolean null if deletion should continue.
  126. */
  127. public function delete_video_wpcom( $delete, $post ) {
  128. if ( ! is_videopress_attachment( $post->ID ) ) {
  129. return null;
  130. }
  131. $guid = get_post_meta( $post->ID, 'videopress_guid', true );
  132. if ( empty( $guid ) ) {
  133. $this->delete_video_poster_attachment( $post->ID );
  134. return null;
  135. }
  136. // Phone home and have wp.com delete the VideoPress entry and files.
  137. $wpcom_response = Client::wpcom_json_api_request_as_blog(
  138. sprintf( '/videos/%s/delete', $guid ),
  139. '1.1',
  140. array( 'method' => 'POST' )
  141. );
  142. if ( is_wp_error( $wpcom_response ) ) {
  143. return $wpcom_response;
  144. }
  145. // Upon success or a 404 (video already deleted on wp.com), return null to allow the deletion to continue.
  146. if ( 200 === $wpcom_response['response']['code'] || 404 === $wpcom_response['response']['code'] ) {
  147. $this->delete_video_poster_attachment( $post->ID );
  148. return null;
  149. }
  150. // Otherwise we stop the deletion from proceeding.
  151. return false;
  152. }
  153. /**
  154. * Deletes a video poster attachment if it exists.
  155. *
  156. * @param int $attachment_id the WP attachment id.
  157. */
  158. private function delete_video_poster_attachment( $attachment_id ) {
  159. $thumbnail_id = get_post_meta( $attachment_id, '_thumbnail_id', true );
  160. if ( ! empty( $thumbnail_id ) ) {
  161. // Let's ensure this is a VP poster image before we delete it.
  162. if ( '1' === get_post_meta( $thumbnail_id, 'videopress_poster_image', true ) ) {
  163. // This call triggers the `delete_video_wpcom` filter again but it bails early at the is_videopress_attachment() check.
  164. wp_delete_attachment( $thumbnail_id );
  165. }
  166. }
  167. }
  168. /**
  169. * Register VideoPress admin scripts.
  170. */
  171. public function enqueue_admin_scripts() {
  172. if ( did_action( 'videopress_enqueue_admin_scripts' ) ) {
  173. return;
  174. }
  175. if ( $this->should_override_media_uploader() ) {
  176. wp_enqueue_script(
  177. 'videopress-plupload',
  178. Assets::get_file_url_for_environment(
  179. '_inc/build/videopress/js/videopress-plupload.min.js',
  180. 'modules/videopress/js/videopress-plupload.js'
  181. ),
  182. array(
  183. 'jquery',
  184. 'wp-plupload',
  185. ),
  186. $this->version
  187. );
  188. wp_enqueue_script(
  189. 'videopress-uploader',
  190. Assets::get_file_url_for_environment(
  191. '_inc/build/videopress/js/videopress-uploader.min.js',
  192. 'modules/videopress/js/videopress-uploader.js'
  193. ),
  194. array(
  195. 'videopress-plupload',
  196. ),
  197. $this->version
  198. );
  199. wp_enqueue_script(
  200. 'media-video-widget-extensions',
  201. Assets::get_file_url_for_environment(
  202. '_inc/build/videopress/js/media-video-widget-extensions.min.js',
  203. 'modules/videopress/js/media-video-widget-extensions.js'
  204. ),
  205. array(),
  206. $this->version,
  207. true
  208. );
  209. }
  210. /**
  211. * Fires after VideoPress scripts are enqueued in the dashboard.
  212. *
  213. * @since 2.5.0
  214. */
  215. do_action( 'videopress_enqueue_admin_scripts' );
  216. }
  217. /**
  218. * Returns the VideoPress URL for the give post id, otherwise returns the provided default.
  219. *
  220. * This is an attachment-based filter handler.
  221. *
  222. * @param string $default The default return value if post id is not a VideoPress video.
  223. * @param int $post_id The post id for the current attachment.
  224. */
  225. public function maybe_get_attached_url_for_videopress( $default, $post_id ) {
  226. $videopress_url = videopress_get_attachment_url( $post_id );
  227. if ( null !== $videopress_url ) {
  228. return $videopress_url;
  229. }
  230. return $default;
  231. }
  232. /**
  233. * Modify the default plupload config to turn on videopress specific filters.
  234. */
  235. public function videopress_pluploder_config( $config ) {
  236. if ( ! isset( $config['filters']['max_file_size'] ) ) {
  237. $config['filters']['max_file_size'] = wp_max_upload_size() . 'b';
  238. }
  239. $config['filters']['videopress_check_uploads'] = $config['filters']['max_file_size'];
  240. // We're doing our own check in the videopress_check_uploads filter.
  241. unset( $config['filters']['max_file_size'] );
  242. return $config;
  243. }
  244. /**
  245. * Helper function to determine if the media uploader should be overridden.
  246. *
  247. * The rules are simple, only try to load the script when on the edit post or new post pages.
  248. *
  249. * @return bool
  250. */
  251. protected function should_override_media_uploader() {
  252. global $pagenow;
  253. // Only load in the admin
  254. if ( ! is_admin() ) {
  255. return false;
  256. }
  257. $acceptable_pages = array(
  258. 'post-new.php',
  259. 'post.php',
  260. 'upload.php',
  261. 'customize.php',
  262. );
  263. // Only load on the post, new post, or upload pages.
  264. if ( ! in_array( $pagenow, $acceptable_pages ) ) {
  265. return false;
  266. }
  267. return $this->is_videopress_enabled();
  268. }
  269. /**
  270. * Detects if VideoPress is enabled.
  271. *
  272. * @return bool
  273. */
  274. protected function is_videopress_enabled() {
  275. $options = VideoPress_Options::get_options();
  276. return $options['shadow_blog_id'] > 0;
  277. }
  278. /**
  279. * A work-around / hack to make it possible to go to the media library with the add new box open.
  280. *
  281. * @return bool
  282. */
  283. public function print_in_footer_open_media_add_new() {
  284. global $pagenow;
  285. // Only load in the admin
  286. if ( ! is_admin() ) {
  287. return false;
  288. }
  289. if ( $pagenow !== 'upload.php' ) {
  290. return false;
  291. }
  292. if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'add-new' ) {
  293. return false;
  294. }
  295. ?>
  296. <script type="text/javascript">
  297. ( function( $ ) {
  298. window.setTimeout( function() {
  299. $('#wp-media-grid .page-title-action').click();
  300. }, 500 );
  301. }( jQuery ) );
  302. </script>
  303. <?php
  304. }
  305. /**
  306. * Makes sure that all video mimes are added in, as multi site installs can remove them.
  307. *
  308. * @param array $existing_mimes
  309. * @return array
  310. */
  311. public function add_video_upload_mimes( $existing_mimes = array() ) {
  312. $mime_types = wp_get_mime_types();
  313. $video_types = array_filter( $mime_types, array( $this, 'filter_video_mimes' ) );
  314. foreach ( $video_types as $key => $value ) {
  315. $existing_mimes[ $key ] = $value;
  316. }
  317. // Make sure that videopress mimes are considered videos.
  318. $existing_mimes['videopress'] = 'video/videopress';
  319. return $existing_mimes;
  320. }
  321. /**
  322. * Filter designed to get rid of non video mime types.
  323. *
  324. * @param string $value
  325. * @return int
  326. */
  327. public function filter_video_mimes( $value ) {
  328. return preg_match( '@^video/@', $value );
  329. }
  330. /**
  331. * @param string $icon
  332. * @param string $mime
  333. * @param int $post_id
  334. *
  335. * @return string
  336. */
  337. public function wp_mime_type_icon( $icon, $mime, $post_id ) {
  338. if ( $mime !== 'video/videopress' ) {
  339. return $icon;
  340. }
  341. $status = get_post_meta( $post_id, 'videopress_status', true );
  342. if ( $status === 'complete' ) {
  343. return $icon;
  344. }
  345. return 'https://wordpress.com/wp-content/mu-plugins/videopress/images/media-video-processing-icon.png';
  346. }
  347. /**
  348. * @param array $extensions
  349. *
  350. * @return array
  351. */
  352. public function add_videopress_extenstion( $extensions ) {
  353. $extensions[] = 'videopress';
  354. return $extensions;
  355. }
  356. }
  357. // Initialize the module.
  358. Jetpack_VideoPress::init();