PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-videopress / src / class-data.php
jetpack / jetpack_vendor / automattic / jetpack-videopress / src Last commit date
js 2 months ago tus 1 month ago videopress-divi 2 months ago videopress-divi-5 2 months ago class-access-control.php 5 days ago class-admin-ui.php 2 weeks ago class-ajax.php 1 month ago class-attachment-handler.php 1 month ago class-block-editor-content.php 1 month ago class-block-editor-extensions.php 2 weeks ago class-block-replacement.php 9 months ago class-caption-tracks.php 1 month ago class-data.php 1 month ago class-divi.php 2 months ago class-initial-state.php 2 weeks ago class-initializer.php 5 days ago class-jwt-token-bridge.php 2 years ago class-module-control.php 3 years ago class-options.php 2 years ago class-package-version.php 5 days ago class-plan.php 2 years ago class-rest-controller.php 1 month ago class-site.php 3 years ago class-stats.php 1 year ago class-status.php 9 months ago class-upload-exception.php 3 years ago class-uploader-rest-endpoints.php 2 weeks ago class-uploader.php 1 month ago class-utils.php 3 months ago class-video-block-email-renderer.php 2 months ago class-videopress-rest-api-v1-features.php 6 months ago class-videopress-rest-api-v1-settings.php 1 month ago class-videopress-rest-api-v1-site.php 2 weeks ago class-videopress-rest-api-v1-stats.php 3 years ago class-videopresstoken.php 1 month ago class-wpcom-rest-api-v2-attachment-field-videopress.php 9 months ago class-wpcom-rest-api-v2-attachment-videopress-data.php 1 month ago class-wpcom-rest-api-v2-endpoint-videopress-caption-tracks.php 1 month ago class-wpcom-rest-api-v2-endpoint-videopress.php 2 weeks ago class-xmlrpc.php 1 month ago utility-functions.php 4 weeks ago
class-data.php
456 lines
1 <?php
2 /**
3 * The Data class.
4 * This class provides methods for data VideoPress access and manipulation.
5 *
6 * @package automattic/jetpack-videopress
7 */
8
9 namespace Automattic\Jetpack\VideoPress;
10
11 use Automattic\Jetpack\Connection\Manager as Connection_Manager;
12 use Automattic\Jetpack\Status\Host;
13 use WP_REST_Request;
14 /**
15 * The Data class.
16 */
17 class Data {
18
19 /**
20 * Gets the Jetpack blog ID
21 *
22 * @return int The blog ID
23 */
24 public static function get_blog_id() {
25 return VideoPressToken::blog_id();
26 }
27
28 /**
29 * Gets the VideoPress site privacy configuration.
30 *
31 * @return boolean If all the videos are private on the site
32 */
33 public static function get_videopress_videos_private_for_site() {
34 /**
35 * If it's a Simple site, returns the site privacy setting.
36 */
37 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
38 return video_is_private_wpcom_blog( get_current_blog_id() );
39 }
40 /**
41 * If it's a private Atomic site, the default setting is private as well.
42 */
43 if ( ( new Host() )->is_woa_site() ) {
44 if ( ( intval( get_option( 'blog_public', '' ) ) === -1 ) ) {
45 return true;
46 }
47 }
48
49 /* If it's a Jetpack site or a public Atomic site, check the settings */
50 return boolval( get_option( 'videopress_private_enabled_for_site', false ) );
51 }
52
53 /**
54 * Gets whether auto-generated subtitles are disabled for the site.
55 *
56 * Subtitles are generated by default, so this opt-out option defaults to false.
57 *
58 * @return boolean If auto-generated subtitles should be skipped for new videos.
59 */
60 public static function get_videopress_auto_subtitles_disabled() {
61 return boolval( get_option( 'videopress_auto_subtitles_disabled', false ) );
62 }
63
64 /**
65 * Gets the VideoPress Settings.
66 *
67 * @return array The settings as an associative array.
68 */
69 public static function get_videopress_settings() {
70 $site_type = 'jetpack';
71 $site_is_private = false;
72
73 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
74 $site_type = 'simple';
75 $site_is_private = video_is_private_wpcom_blog( get_current_blog_id() );
76 } elseif ( ( new Host() )->is_woa_site() ) {
77 $site_type = 'atomic';
78 $site_is_private = intval( get_option( 'blog_public', '' ) ) === -1;
79 }
80
81 return array(
82 'videopress_videos_private_for_site' => self::get_videopress_videos_private_for_site(),
83 'videopress_auto_subtitles_disabled' => self::get_videopress_auto_subtitles_disabled(),
84 'site_is_private' => $site_is_private,
85 'site_type' => $site_type,
86 );
87 }
88
89 /**
90 * Gets the video data
91 *
92 * @param boolean $is_videopress - True when getting VideoPress data.
93 * @return array
94 */
95 public static function get_video_data( $is_videopress = true ) {
96 $video_data = array(
97 'videos' => array(),
98 'total' => 0,
99 'totalPages' => 0,
100 'query' => array(
101 'order' => 'desc',
102 'orderBy' => 'date',
103 'itemsPerPage' => 6,
104 'page' => 1,
105 ),
106 );
107
108 $args = array(
109 'order' => $video_data['query']['order'],
110 'orderby' => $video_data['query']['orderBy'],
111 'per_page' => $video_data['query']['itemsPerPage'],
112 'page' => $video_data['query']['page'],
113 );
114
115 if ( $is_videopress ) {
116 $args['mime_type'] = 'video/videopress';
117 } else {
118 $args['media_type'] = 'video';
119 $args['no_videopress'] = true;
120 }
121
122 // Do an internal request for the media list
123 $request = new WP_REST_Request( 'GET', '/wp/v2/media' );
124 $request->set_query_params( $args );
125 $response = rest_do_request( $request );
126
127 if ( $response->is_error() ) {
128 // @todo: error handling
129 return $video_data;
130 }
131
132 // load the real values
133 $video_data['videos'] = $response->get_data();
134 $headers = $response->get_headers();
135
136 if ( isset( $headers['X-WP-Total'] ) ) {
137 $video_data['total'] = $headers['X-WP-Total'];
138 }
139
140 if ( isset( $headers['X-WP-TotalPages'] ) ) {
141 $video_data['totalPages'] = $headers['X-WP-TotalPages'];
142 }
143
144 return $video_data;
145 }
146
147 /**
148 * Gets the user data
149 *
150 * @return array
151 */
152 public static function get_user_data() {
153 $user_data = array(
154 'items' => array(),
155 'pagination' => array(
156 'total' => 0,
157 'totalPages' => 1,
158 ),
159 'query' => array(
160 'order' => 'asc',
161 'orderBy' => 'name',
162 ),
163 '_meta' => array(
164 'relyOnInitialState' => true,
165 ),
166 );
167
168 $args = array(
169 'order' => $user_data['query']['order'],
170 'orderby' => $user_data['query']['orderBy'],
171 );
172
173 // Do an internal request for the user list
174 $request = new WP_REST_Request( 'GET', '/wp/v2/users' );
175 $request->set_query_params( $args );
176 $response = rest_do_request( $request );
177
178 if ( $response->is_error() ) {
179 // @todo: error handling
180 return $user_data;
181 }
182
183 // load the real values
184 $user_data['items'] = $response->get_data();
185 $headers = $response->get_headers();
186
187 if ( isset( $headers['X-WP-Total'] ) ) {
188 $user_data['pagination']['total'] = $headers['X-WP-Total'];
189 }
190
191 if ( isset( $headers['X-WP-TotalPages'] ) ) {
192 $user_data['pagination']['totalPages'] = $headers['X-WP-TotalPages'];
193 }
194
195 return $user_data;
196 }
197
198 /**
199 * Gets the VideoPress used storage space in bytes
200 *
201 * @return int the used storage space
202 */
203 public static function get_storage_used() {
204 $site_data = Site::get_site_info();
205 if ( is_wp_error( $site_data ) ) {
206 return 0;
207 }
208
209 if ( isset( $site_data['options'] ) && isset( $site_data['options']['videopress_storage_used'] ) ) {
210 return intval( round( $site_data['options']['videopress_storage_used'] * 1024 * 1024 ) );
211 } else {
212 return 0;
213 }
214 }
215
216 /**
217 * Return all the initial state that depends on a valid site connection
218 *
219 * @return array
220 */
221 public static function get_connected_initial_state() {
222 return array(
223 'videos' => array(
224 'storageUsed' => self::get_storage_used(),
225 ),
226 'purchases' => array(
227 'items' => Site::get_purchases(),
228 'isFetching' => false,
229 ),
230 );
231 }
232
233 /**
234 * Checks if the site has as connected owner
235 */
236 public static function has_connected_owner() {
237 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
238 return true;
239 }
240
241 if ( ( new Connection_Manager() )->has_connected_owner() ) {
242 return true;
243 }
244
245 return false;
246 }
247
248 /**
249 * Checks if the user is able to perform actions that modify data
250 */
251 public static function can_perform_action() {
252 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
253 return true;
254 }
255
256 $connection = new Connection_Manager();
257
258 return (
259 $connection->is_connected() &&
260 self::has_connected_owner() &&
261 $connection->is_user_connected()
262 );
263 }
264
265 /**
266 * Return the initial state of the VideoPress app,
267 * used to render initially the app in the frontend.
268 *
269 * @return array
270 */
271 public static function get_initial_state() {
272 $videopress_data = self::get_video_data();
273 $local_videos_data = self::get_video_data( false );
274
275 // Tweak local videos data.
276 $local_videos = array_map(
277 function ( $video ) {
278 $video = (array) $video;
279 $id = $video['id'];
280 $media_details = $video['media_details'];
281 $jetpack_videopress = $video['jetpack_videopress'];
282 $read_error = null;
283
284 // In malformed files, the media_details or jetpack_videopress properties are not arrays.
285 if ( ! is_array( $media_details ) || ! is_array( $jetpack_videopress ) ) {
286 $media_details = (array) $media_details;
287 $jetpack_videopress = (array) $jetpack_videopress;
288 $read_error = Upload_Exception::ERROR_MALFORMED_FILE;
289 }
290
291 // Check if video is already uploaded to VideoPress or has some error.
292 try {
293 $uploader = new Uploader( $id );
294 $is_uploaded_to_videopress = $uploader->is_uploaded();
295 } catch ( Upload_Exception $e ) {
296 $is_uploaded_to_videopress = false;
297 $read_error = $e->getCode();
298 }
299
300 $upload_date = $video['date'];
301 $url = $video['source_url'];
302
303 $title = $jetpack_videopress['title'];
304 $description = $jetpack_videopress['description'];
305 $caption = $jetpack_videopress['caption'];
306
307 $width = $media_details['width'] ?? null;
308 $height = $media_details['height'] ?? null;
309 $duration = $media_details['length'] ?? null;
310
311 return array(
312 'id' => $id,
313 'title' => $title,
314 'description' => $description,
315 'caption' => $caption,
316 'width' => $width,
317 'height' => $height,
318 'url' => $url,
319 'uploadDate' => $upload_date,
320 'duration' => $duration,
321 'isUploadedToVideoPress' => $is_uploaded_to_videopress,
322 'readError' => $read_error,
323 );
324 },
325 $local_videos_data['videos']
326 );
327
328 // Tweak VideoPress videos data.
329 $videos = array_map(
330 array( __CLASS__, 'prepare_videopress_video_data' ),
331 $videopress_data['videos']
332 );
333
334 $site_settings = self::get_videopress_settings();
335
336 $initial_state = array(
337 'users' => self::get_user_data(),
338 'siteSettings' => array(
339 'videoPressVideosPrivateForSite' => $site_settings['videopress_videos_private_for_site'],
340 'siteIsPrivate' => $site_settings['site_is_private'],
341 'siteType' => $site_settings['site_type'],
342 ),
343 'videos' => array(
344 'uploadedVideoCount' => $videopress_data['total'],
345 'items' => $videos,
346 'isFetching' => false,
347 'isFetchingUploadedVideoCount' => false,
348 'pagination' => array(
349 'totalPages' => $videopress_data['totalPages'],
350 'total' => $videopress_data['total'],
351 ),
352 'query' => $videopress_data['query'],
353 '_meta' => array(
354 'processedAllVideosBeingRemoved' => true,
355 'relyOnInitialState' => true,
356 ),
357 ),
358 'localVideos' => array(
359 'uploadedVideoCount' => $local_videos_data['total'],
360 'items' => $local_videos,
361 'isFetching' => false,
362 'isFetchingUploadedVideoCount' => false,
363 'pagination' => array(
364 'totalPages' => $local_videos_data['totalPages'],
365 'total' => $local_videos_data['total'],
366 ),
367 'query' => $local_videos_data['query'],
368 '_meta' => array(
369 'relyOnInitialState' => true,
370 ),
371 ),
372 );
373
374 if ( self::has_connected_owner() ) {
375 return array_merge_recursive( $initial_state, self::get_connected_initial_state() );
376 }
377
378 return $initial_state;
379 }
380
381 /**
382 * Maps a single VideoPress video, as returned by the media REST endpoint, to
383 * the shape consumed by the VideoPress dashboard app.
384 *
385 * Videos that are still processing (or otherwise have partial metadata) come
386 * back without `videopress`, `width` or `height` in their media_details, so
387 * every nested access is coalesced to avoid undefined-key and offset-on-null
388 * warnings.
389 *
390 * @param array|object $video A single video entry from the media REST endpoint.
391 * @return array The video data formatted for the dashboard app.
392 */
393 private static function prepare_videopress_video_data( $video ) {
394 $video = (array) $video;
395 $id = $video['id'];
396 $guid = $video['jetpack_videopress_guid'];
397 $media_details = (array) $video['media_details'];
398 $jetpack_videopress = (array) $video['jetpack_videopress'];
399
400 $videopress_media_details = $media_details['videopress'] ?? array();
401 $width = $media_details['width'] ?? null;
402 $height = $media_details['height'] ?? null;
403
404 $title = $jetpack_videopress['title'];
405 $description = $jetpack_videopress['description'];
406 $caption = $jetpack_videopress['caption'];
407 $rating = $jetpack_videopress['rating'];
408 $allow_download = $jetpack_videopress['allow_download'];
409 $display_embed = $jetpack_videopress['display_embed'];
410 $privacy_setting = $jetpack_videopress['privacy_setting'];
411 $needs_playback_token = $jetpack_videopress['needs_playback_token'];
412 $is_private = $jetpack_videopress['is_private'];
413
414 $original = $videopress_media_details['original'] ?? null;
415 $poster = ( ! $needs_playback_token ) ? ( $videopress_media_details['poster'] ?? null ) : null;
416 $upload_date = $videopress_media_details['upload_date'] ?? null;
417 $duration = $videopress_media_details['duration'] ?? null;
418 $file_url_base = $videopress_media_details['file_url_base'] ?? null;
419 $finished = $videopress_media_details['finished'] ?? null;
420 $files = $videopress_media_details['files'] ?? null;
421 $filename = $original !== null ? basename( $original ) : null;
422
423 if ( isset( $files['dvd']['original_img'] ) && isset( $file_url_base['https'] ) && $privacy_setting !== 1 ) {
424 $thumbnail = $file_url_base['https'] . $files['dvd']['original_img'];
425 } else {
426 $thumbnail = null;
427 }
428
429 return array(
430 'id' => $id,
431 'guid' => $guid,
432 'title' => $title,
433 'description' => $description,
434 'caption' => $caption,
435 'url' => $original,
436 'uploadDate' => $upload_date,
437 'duration' => $duration,
438 'isPrivate' => $is_private,
439 'posterImage' => $poster,
440 'allowDownload' => $allow_download,
441 'displayEmbed' => $display_embed,
442 'rating' => $rating,
443 'privacySetting' => $privacy_setting,
444 'needsPlaybackToken' => $needs_playback_token,
445 'width' => $width,
446 'height' => $height,
447 'poster' => array(
448 'src' => $poster,
449 ),
450 'thumbnail' => $thumbnail,
451 'finished' => $finished,
452 'filename' => $filename,
453 );
454 }
455 }
456