Açıklama Yok

class.videopress-gutenberg.php 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
  2. /**
  3. * Block Editor functionality for VideoPress users.
  4. *
  5. * @package automattic/jetpack
  6. */
  7. use Automattic\Jetpack\Assets;
  8. use Automattic\Jetpack\Blocks;
  9. /**
  10. * Register a VideoPress extension to replace the default Core Video block.
  11. */
  12. class VideoPress_Gutenberg {
  13. /**
  14. * Singleton
  15. */
  16. public static function init() {
  17. static $instance = false;
  18. if ( ! $instance ) {
  19. $instance = new VideoPress_Gutenberg();
  20. }
  21. return $instance;
  22. }
  23. /**
  24. * VideoPress_Gutenberg constructor.
  25. *
  26. * Initialize the VideoPress Gutenberg extension
  27. */
  28. private function __construct() {
  29. add_action( 'init', array( $this, 'register_video_block_with_videopress' ) );
  30. add_action( 'jetpack_register_gutenberg_extensions', array( $this, 'set_extension_availability' ) );
  31. add_action( 'enqueue_block_editor_assets', array( $this, 'override_video_upload' ) );
  32. }
  33. /**
  34. * Get site's ID.
  35. *
  36. * @return int $blog_id Site ID.
  37. */
  38. private static function get_blog_id() {
  39. if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
  40. return get_current_blog_id();
  41. } elseif ( method_exists( 'Jetpack', 'is_active' ) && Jetpack::is_active() ) {
  42. /**
  43. * We're intentionally not using `get_current_blog_id` because it was returning unexpected values.
  44. *
  45. * @see https://github.com/Automattic/jetpack/pull/11193#issuecomment-457883886
  46. * @see https://github.com/Automattic/jetpack/pull/11193/commits/215cf789f3d8bd03ff9eb1bbdb693acb8831d273
  47. */
  48. return Jetpack_Options::get_option( 'id' );
  49. }
  50. return null;
  51. }
  52. /**
  53. * Used to check whether VideoPress is enabled for given site.
  54. *
  55. * @todo Create a global `jetpack_check_module_availability( $module )` helper so we can re-use it on other modules.
  56. * This global helper should be created in a file synced with WordPress.com so we can use it there too.
  57. * @see https://github.com/Automattic/jetpack/pull/11321#discussion_r255477815
  58. *
  59. * @return array Associative array indicating if the module is available (key `available`) and the reason why it is
  60. * unavailable (key `unavailable_reason`)
  61. */
  62. public function check_videopress_availability() {
  63. if (
  64. defined( 'IS_WPCOM' ) && IS_WPCOM &&
  65. function_exists( 'require_lib' )
  66. ) {
  67. require_lib( 'wpforteams' );
  68. if ( WPForTeams\Workspace\is_part_of_active_workspace( self::get_blog_id() ) ) {
  69. return array( 'available' => true );
  70. }
  71. }
  72. // It is available on Simple Sites having the appropriate a plan.
  73. if (
  74. defined( 'IS_WPCOM' ) && IS_WPCOM
  75. && method_exists( 'Store_Product_List', 'get_site_specific_features_data' )
  76. ) {
  77. $features = Store_Product_List::get_site_specific_features_data();
  78. if ( in_array( 'videopress', $features['active'], true ) ) {
  79. return array( 'available' => true );
  80. } else {
  81. return array(
  82. 'available' => false,
  83. 'unavailable_reason' => 'missing_plan',
  84. );
  85. }
  86. }
  87. // It is available on Jetpack Sites having the module active.
  88. if (
  89. method_exists( 'Jetpack', 'is_connection_ready' ) && Jetpack::is_connection_ready()
  90. && method_exists( 'Jetpack', 'is_module_active' )
  91. && method_exists( 'Jetpack_Plan', 'supports' )
  92. ) {
  93. if ( Jetpack::is_module_active( 'videopress' ) ) {
  94. return array( 'available' => true );
  95. } elseif ( ! Jetpack_Plan::supports( 'videopress' ) ) {
  96. return array(
  97. 'available' => false,
  98. 'unavailable_reason' => 'missing_plan',
  99. );
  100. } else {
  101. return array(
  102. 'available' => false,
  103. 'unavailable_reason' => 'missing_module',
  104. );
  105. }
  106. }
  107. return array(
  108. 'available' => false,
  109. 'unavailable_reason' => 'unknown',
  110. );
  111. }
  112. /**
  113. * Set the Jetpack Gutenberg extension availability.
  114. */
  115. public function set_extension_availability() {
  116. $availability = $this->check_videopress_availability();
  117. if ( $availability['available'] ) {
  118. Jetpack_Gutenberg::set_extension_available( 'jetpack/videopress' );
  119. } else {
  120. Jetpack_Gutenberg::set_extension_unavailable( 'jetpack/videopress', $availability['unavailable_reason'] );
  121. }
  122. }
  123. /**
  124. * Register the core video block as a dynamic block.
  125. *
  126. * It defines a server-side rendering that adds VideoPress support to the core video block.
  127. */
  128. public function register_video_block_with_videopress() {
  129. Blocks::jetpack_register_block(
  130. 'core/video',
  131. array(
  132. 'render_callback' => array( $this, 'render_video_block_with_videopress' ),
  133. )
  134. );
  135. }
  136. /**
  137. * Render the core video block replacing the src attribute with the VideoPress URL
  138. *
  139. * @param array $attributes Array containing the video block attributes.
  140. * @param string $content String containing the video block content.
  141. *
  142. * @return string
  143. */
  144. public function render_video_block_with_videopress( $attributes, $content ) {
  145. if ( ! isset( $attributes['id'] ) || isset( $attributes['guid'] ) ) {
  146. return $content;
  147. }
  148. $blog_id = self::get_blog_id();
  149. if ( ! isset( $blog_id ) ) {
  150. return $content;
  151. }
  152. $post_id = absint( $attributes['id'] );
  153. $videopress_id = video_get_info_by_blogpostid( $blog_id, $post_id )->guid;
  154. $videopress_data = videopress_get_video_details( $videopress_id );
  155. if ( empty( $videopress_data->file_url_base->https ) || empty( $videopress_data->files->hd->mp4 ) ) {
  156. return $content;
  157. }
  158. $videopress_url = $videopress_data->file_url_base->https . $videopress_data->files->hd->mp4;
  159. $pattern = '/(\s)src=([\'"])(?:(?!\2).)+?\2/';
  160. return preg_replace(
  161. $pattern,
  162. sprintf(
  163. '\1src="%1$s"',
  164. esc_url_raw( $videopress_url )
  165. ),
  166. $content,
  167. 1
  168. );
  169. }
  170. /**
  171. * Replaces the video uploaded in the block editor.
  172. *
  173. * Enqueues a script that registers an API fetch middleware replacing the video uploads in Gutenberg so they are
  174. * uploaded against the WP.com API media endpoint and thus transcoded by VideoPress.
  175. */
  176. public function override_video_upload() {
  177. // Bail if Jetpack is not connected or VideoPress module is not active.
  178. if ( ! Jetpack::is_connection_ready() || ! Jetpack::is_module_active( 'videopress' ) ) {
  179. return;
  180. }
  181. wp_enqueue_script(
  182. 'jetpack-videopress-gutenberg-override-video-upload',
  183. Assets::get_file_url_for_environment(
  184. '_inc/build/videopress/js/gutenberg-video-upload.min.js',
  185. 'modules/videopress/js/gutenberg-video-upload.js'
  186. ),
  187. array( 'wp-api-fetch', 'wp-polyfill', 'lodash' ),
  188. JETPACK__VERSION,
  189. false
  190. );
  191. }
  192. }
  193. VideoPress_Gutenberg::init();