PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | modules/videopress/class.jetpack-videopress.php +483 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,483 @@
1 +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 +
3 +use Automattic\Jetpack\Assets;
4 +use Automattic\Jetpack\Current_Plan;
5 +use Automattic\Jetpack\Status;
6 +use Automattic\Jetpack\VideoPress\Attachment_Handler;
7 +use Automattic\Jetpack\VideoPress\Jwt_Token_Bridge;
8 +use Automattic\Jetpack\VideoPress\Options as VideoPress_Options;
9 +
10 +if ( ! defined( 'ABSPATH' ) ) {
11 + exit( 0 );
12 +}
13 +
14 +/**
15 + * VideoPress in Jetpack
16 + */
17 +class Jetpack_VideoPress {
18 + /**
19 + * Module name.
20 + *
21 + * @var string
22 + */
23 + public $module = 'videopress';
24 +
25 + /**
26 + * Singleton
27 + */
28 + public static function init() {
29 + static $instance = false;
30 +
31 + if ( ! $instance ) {
32 + $instance = new Jetpack_VideoPress();
33 + }
34 +
35 + return $instance;
36 + }
37 +
38 + /**
39 + * Jetpack_VideoPress constructor.
40 + *
41 + * Sets up the initializer and makes sure that videopress activates and deactivates properly.
42 + */
43 + private function __construct() {
44 + add_action( 'init', array( $this, 'on_init' ) );
45 + add_action( 'jetpack_deactivate_module_videopress', array( $this, 'jetpack_module_deactivated' ) );
46 + }
47 +
48 + /**
49 + * Fires on init
50 + */
51 + public function on_init() {
52 + add_action( 'wp_enqueue_media', array( $this, 'enqueue_admin_scripts' ) );
53 + add_filter( 'plupload_default_settings', array( $this, 'videopress_pluploder_config' ) );
54 +
55 + add_action( 'admin_print_footer_scripts', array( $this, 'print_in_footer_open_media_add_new' ) );
56 + add_action( 'admin_head', array( $this, 'enqueue_admin_styles' ) );
57 + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_media_new_scripts' ) );
58 +
59 + VideoPress_Scheduler::init();
60 + }
61 +
62 + /**
63 + * Enqueues the jwt bridge script.
64 + *
65 + * @deprecated 11.3
66 + */
67 + public function enqueue_jwt_token_bridge() {
68 + _deprecated_function( __METHOD__, 'jetpack-11.3', 'Automattic\Jetpack\VideoPress\Jwt_Token_Bridge::enqueue_jwt_token_bridge' );
69 + return Jwt_Token_Bridge::enqueue_jwt_token_bridge();
70 + }
71 +
72 + /**
73 + * Enqueues the script that routes media-new.php video uploads to VideoPress.
74 + *
75 + * The classic uploader on media-new.php builds a raw plupload.Uploader
76 + * (via plupload-handlers) instead of wp.Uploader, so the override in
77 + * videopress-plupload.js never engages there. This companion script
78 + * registers the same videopress_check_uploads plupload filter and
79 + * re-targets video uploads to VideoPress. The filter is injected into the
80 + * uploader settings through the plupload_init filter, which
81 + * media_upload_form() applies when it renders later in the request.
82 + *
83 + * @param string $hook_suffix The current admin page.
84 + */
85 + public function enqueue_media_new_scripts( $hook_suffix ) {
86 + if ( 'media-new.php' !== $hook_suffix ) {
87 + return;
88 + }
89 +
90 + if ( ! $this->is_videopress_enabled() ) {
91 + return;
92 + }
93 +
94 + // Version with the served file's mtime so browsers and page caches pick
95 + // up new builds even when JETPACK__VERSION has not changed (branch
96 + // testing, beta builds).
97 + $script_relative = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG
98 + ? 'modules/videopress/js/videopress-media-new.js'
99 + : '_inc/build/videopress/js/videopress-media-new.min.js';
100 + $script_path = JETPACK__PLUGIN_DIR . $script_relative;
101 + $script_version = file_exists( $script_path ) ? (string) filemtime( $script_path ) : JETPACK__VERSION;
102 +
103 + wp_enqueue_script(
104 + 'videopress-media-new',
105 + Assets::get_file_url_for_environment(
106 + '_inc/build/videopress/js/videopress-media-new.min.js',
107 + 'modules/videopress/js/videopress-media-new.js'
108 + ),
109 + array(
110 + 'jquery',
111 + 'plupload-handlers',
112 + ),
113 + $script_version,
114 + true
115 + );
116 +
117 + wp_localize_script( 'videopress-media-new', 'videoPressMediaNew', $this->get_media_new_upload_limits() );
118 +
119 + add_filter( 'plupload_init', array( $this, 'videopress_pluploder_config' ) );
120 + }
121 +
122 + /**
123 + * Returns the free-plan upload limit data used by the media-new.php script.
124 + *
125 + * The free plan includes a single video upload, so the script needs to know
126 + * whether the site has a paid VideoPress plan, whether the free upload has
127 + * already been used, and where to send the user to upgrade. Mirrors the
128 + * checks behind the VideoPress dashboard's upgrade notice: the paid check
129 + * matches Admin_UI::initial_state()'s paidFeatures, and the used check
130 + * matches the dashboard's VideoPress video count (video/videopress
131 + * attachments).
132 + *
133 + * @return array
134 + */
135 + public function get_media_new_upload_limits() {
136 + $has_videopress_purchase = Current_Plan::supports( 'videopress-1tb-storage' )
137 + || Current_Plan::supports( 'videopress-unlimited-storage' )
138 + || ( function_exists( 'wpcom_site_has_feature' ) && wpcom_site_has_feature( 'videopress' ) );
139 +
140 + $has_used_video = false;
141 + if ( ! $has_videopress_purchase ) {
142 + $videopress_videos = get_posts(
143 + array(
144 + 'post_type' => 'attachment',
145 + 'post_status' => 'inherit',
146 + 'post_mime_type' => 'video/videopress',
147 + 'posts_per_page' => 1,
148 + 'fields' => 'ids',
149 + )
150 + );
151 +
152 + $has_used_video = count( $videopress_videos ) > 0;
153 + }
154 +
155 + $upgrade_url = sprintf(
156 + 'https://wordpress.com/checkout/%s/jetpack_videopress?redirect_to=%s',
157 + rawurlencode( ( new Status() )->get_site_suffix() ),
158 + rawurlencode( admin_url( 'media-new.php' ) )
159 + );
160 +
161 + $allowed_html = array(
162 + 'a' => array( 'href' => array() ),
163 + );
164 +
165 + return array(
166 + 'hasVideoPressPurchase' => $has_videopress_purchase,
167 + 'hasUsedVideo' => $has_used_video,
168 + 'strings' => array(
169 + 'usedVideoUpload' => sprintf(
170 + wp_kses(
171 + /* translators: %s is the url to upgrade the VideoPress plan */
172 + __( 'You have used your free video upload. The free plan includes one video upload. <a href="%s">Upgrade now</a> to unlock unlimited videos, 1TB of storage, and more!', 'jetpack' ),
173 + $allowed_html
174 + ),
175 + esc_url( $upgrade_url )
176 + ),
177 + 'multipleVideos' => sprintf(
178 + wp_kses(
179 + /* translators: %s is the url to upgrade the VideoPress plan */
180 + __( 'The free plan includes one video upload. <a href="%s">Upgrade now</a> to upload more videos and unlock unlimited videos, 1TB of storage, and more!', 'jetpack' ),
181 + $allowed_html
182 + ),
183 + esc_url( $upgrade_url )
184 + ),
185 + 'multipleVideosSelected' => sprintf(
186 + wp_kses(
187 + /* translators: %s is the url to upgrade the VideoPress plan */
188 + __( 'Uploading multiple videos requires a paid plan. The free plan includes one video upload. <a href="%s">Upgrade now</a> to unlock unlimited videos, 1TB of storage, and more!', 'jetpack' ),
189 + $allowed_html
190 + ),
191 + esc_url( $upgrade_url )
192 + ),
193 + ),
194 + );
195 + }
196 +
197 + /**
198 + * Runs when the VideoPress module is deactivated.
199 + */
200 + public function jetpack_module_deactivated() {
201 + VideoPress_Options::delete_options();
202 + }
203 +
204 + /**
205 + * Similar to current_user_can, but internal to VideoPress.
206 + *
207 + * @param string $cap Capability name.
208 + * @param int $user_id User ID.
209 + * @return bool Returns true if the given VideoPress capability is allowed by the given user.
210 + */
211 + public function can( $cap, $user_id = false ) {
212 + if ( ! $user_id ) {
213 + $user_id = get_current_user_id();
214 + }
215 +
216 + // Connection owners are allowed to do all the things.
217 + if ( Jetpack::connection()->is_connection_owner( $user_id ) ) {
218 + return true;
219 + }
220 +
221 + // Additional and internal caps checks
222 + if ( ! user_can( $user_id, 'upload_files' ) ) {
223 + return false;
224 + }
225 +
226 + if ( 'edit_videos' === $cap && ! user_can( $user_id, 'edit_others_posts' ) ) {
227 + return false;
228 + }
229 +
230 + if ( 'delete_videos' === $cap && ! user_can( $user_id, 'delete_others_posts' ) ) {
231 + return false;
232 + }
233 +
234 + return true;
235 + }
236 +
237 + /**
238 + * Register and enqueue VideoPress admin styles.
239 + */
240 + public function enqueue_admin_styles() {
241 + wp_register_style( 'videopress-admin', plugins_url( 'videopress-admin.css', __FILE__ ), array(), JETPACK__VERSION );
242 + wp_enqueue_style( 'videopress-admin' );
243 + }
244 +
245 + /**
246 + * Attempts to delete a VideoPress video from wp.com.
247 + * Will block the deletion from continuing if certain errors return from the wp.com API.
248 + *
249 + * @param Boolean $delete if the deletion should occur or not (unused).
250 + * @param WP_Post $post the post object.
251 + *
252 + * @deprecated 11.3
253 + *
254 + * @return null|WP_Error|Boolean null if deletion should continue.
255 + */
256 + public function delete_video_wpcom( $delete, $post ) {
257 + _deprecated_function( __METHOD__, 'jetpack-11.3', 'Automattic\Jetpack\VideoPress\Attachment_Handler::delete_video_wpcom' );
258 + return Attachment_Handler::delete_video_wpcom( $delete, $post );
259 + }
260 +
261 + /**
262 + * Register VideoPress admin scripts.
263 + */
264 + public function enqueue_admin_scripts() {
265 + if ( did_action( 'videopress_enqueue_admin_scripts' ) ) {
266 + return;
267 + }
268 +
269 + if ( $this->should_override_media_uploader() ) {
270 + wp_enqueue_script(
271 + 'videopress-plupload',
272 + Assets::get_file_url_for_environment(
273 + '_inc/build/videopress/js/videopress-plupload.min.js',
274 + 'modules/videopress/js/videopress-plupload.js'
275 + ),
276 + array(
277 + 'jquery',
278 + 'wp-plupload',
279 + ),
280 + JETPACK__VERSION,
281 + true
282 + );
283 +
284 + wp_enqueue_script(
285 + 'videopress-uploader',
286 + Assets::get_file_url_for_environment(
287 + '_inc/build/videopress/js/videopress-uploader.min.js',
288 + 'modules/videopress/js/videopress-uploader.js'
289 + ),
290 + array(
291 + 'videopress-plupload',
292 + ),
293 + JETPACK__VERSION,
294 + true
295 + );
296 +
297 + wp_enqueue_script(
298 + 'media-video-widget-extensions',
299 + Assets::get_file_url_for_environment(
300 + '_inc/build/videopress/js/media-video-widget-extensions.min.js',
301 + 'modules/videopress/js/media-video-widget-extensions.js'
302 + ),
303 + array(),
304 + JETPACK__VERSION,
305 + true
306 + );
307 + }
308 +
309 + /**
310 + * Fires after VideoPress scripts are enqueued in the dashboard.
311 + *
312 + * @since 2.5.0
313 + */
314 + do_action( 'videopress_enqueue_admin_scripts' );
315 + }
316 +
317 + /**
318 + * Returns the VideoPress URL for the give post id, otherwise returns the provided default.
319 + *
320 + * This is an attachment-based filter handler.
321 + *
322 + * @deprecated 11.3
323 + *
324 + * @param string $default The default return value if post id is not a VideoPress video.
325 + * @param int $post_id The post id for the current attachment.
326 + */
327 + public function maybe_get_attached_url_for_videopress( $default, $post_id ) {
328 + _deprecated_function( __METHOD__, 'jetpack-11.3', 'Automattic\Jetpack\VideoPress\Attachment_Handler::maybe_get_attached_url_for_videopress' );
329 + return Attachment_Handler::maybe_get_attached_url_for_videopress( $default, $post_id );
330 + }
331 +
332 + /**
333 + * Modify the default plupload config to turn on VideoPress specific filters.
334 + *
335 + * @param array $config The plupload config.
336 + */
337 + public function videopress_pluploder_config( $config ) {
338 +
339 + if ( ! isset( $config['filters']['max_file_size'] ) ) {
340 + $config['filters']['max_file_size'] = wp_max_upload_size() . 'b';
341 + }
342 +
343 + $config['filters']['videopress_check_uploads'] = $config['filters']['max_file_size'];
344 +
345 + // We're doing our own check in the videopress_check_uploads filter.
346 + unset( $config['filters']['max_file_size'] );
347 +
348 + return $config;
349 + }
350 +
351 + /**
352 + * Helper function to determine if the media uploader should be overridden.
353 + *
354 + * The rules are simple, only try to load the script when on the edit post or new post pages.
355 + *
356 + * @return bool
357 + */
358 + protected function should_override_media_uploader() {
359 + global $pagenow;
360 +
361 + // Only load in the admin
362 + if ( ! is_admin() ) {
363 + return false;
364 + }
365 +
366 + $acceptable_pages = array(
367 + 'post-new.php',
368 + 'post.php',
369 + 'upload.php',
370 + 'customize.php',
371 + );
372 +
373 + // Only load on the post, new post, or upload pages.
374 + if ( ! in_array( $pagenow, $acceptable_pages, true ) ) {
375 + return false;
376 + }
377 +
378 + return $this->is_videopress_enabled();
379 + }
380 +
381 + /**
382 + * Detects if VideoPress is enabled.
383 + *
384 + * @return bool
385 + */
386 + protected function is_videopress_enabled() {
387 + $options = VideoPress_Options::get_options();
388 +
389 + return $options['shadow_blog_id'] > 0;
390 + }
391 +
392 + /**
393 + * A work-around / hack to make it possible to go to the media library with the add new box open.
394 + *
395 + * @return bool
396 + */
397 + public function print_in_footer_open_media_add_new() {
398 + global $pagenow;
399 +
400 + // Only load in the admin
401 + if ( ! is_admin() ) {
402 + return false;
403 + }
404 +
405 + if ( $pagenow !== 'upload.php' ) {
406 + return false;
407 + }
408 +
409 + if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'add-new' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
410 + return false;
411 + }
412 +
413 + ?>
414 + <script type="text/javascript">
415 + ( function( $ ) {
416 + window.setTimeout( function() {
417 + $('#wp-media-grid .page-title-action').click();
418 + }, 500 );
419 +
420 + }( jQuery ) );
421 + </script>
422 + <?php
423 + }
424 +
425 + /**
426 + * Makes sure that all video mimes are added in, as multi site installs can remove them.
427 + *
428 + * @deprecated 11.3
429 + *
430 + * @param array $existing_mimes Mime types to extend/filter.
431 + * @return array
432 + */
433 + public function add_video_upload_mimes( $existing_mimes = array() ) {
434 + _deprecated_function( __METHOD__, 'jetpack-11.3', 'Automattic\Jetpack\VideoPress\Attachment_Handler::add_video_upload_mimes' );
435 + return Attachment_Handler::add_video_upload_mimes( $existing_mimes );
436 + }
437 +
438 + /**
439 + * Filter designed to get rid of non video mime types.
440 + *
441 + * @deprecated 11.3
442 + *
443 + * @param string $value Mime type to filter.
444 + * @return int
445 + */
446 + public function filter_video_mimes( $value ) {
447 + _deprecated_function( __METHOD__, 'jetpack-11.3', 'Automattic\Jetpack\VideoPress\Attachment_Handler::filter_video_mimes' );
448 + return Attachment_Handler::filter_video_mimes( $value );
449 + }
450 +
451 + /**
452 + * Filter the mime type icon.
453 + *
454 + * @param string $icon Icon path.
455 + * @param string $mime Mime type.
456 + * @param int $post_id Post ID.
457 + *
458 + * @deprecated 11.3
459 + *
460 + * @return string
461 + */
462 + public function wp_mime_type_icon( $icon, $mime, $post_id ) {
463 + _deprecated_function( __METHOD__, 'jetpack-11.3', 'Automattic\Jetpack\VideoPress\Attachment_Handler::wp_mime_type_icon' );
464 + return Attachment_Handler::wp_mime_type_icon( $icon, $mime, $post_id );
465 + }
466 +
467 + /**
468 + * Filter the list of supported video formats.
469 + *
470 + * @param array $extensions Supported video formats.
471 + *
472 + * @deprecated 11.3
473 + *
474 + * @return array
475 + */
476 + public function add_videopress_extenstion( $extensions ) {
477 + _deprecated_function( __METHOD__, 'jetpack-11.3', 'Automattic\Jetpack\VideoPress\Attachment_Handler::add_videopress_extenstion' );
478 + return Attachment_Handler::add_videopress_extenstion( $extensions );
479 + }
480 +}
481 +
482 +// Initialize the module.
483 +Jetpack_VideoPress::init();