Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 63
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Videopress_Attachment_Metadata
0.00% covered (danger)
0.00%
0 / 61
0.00% covered (danger)
0.00%
0 / 7
930
0.00% covered (danger)
0.00%
0 / 1
 persist_metadata
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
132
 is_videopress_media
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 is_display_embed_valid
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 is_allow_download_valid
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 is_privacy_setting_valid
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 validate_result
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
30
 build_wpcom_api_request_values
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2/**
3 * Handle the VideoPress metadata properties.
4 *
5 * @package Jetpack
6 */
7
8use Automattic\Jetpack\Connection\Client;
9
10if ( ! defined( 'ABSPATH' ) ) {
11    exit( 0 );
12}
13
14/**
15 * Class Videopress_Attachment_Metadata
16 */
17class Videopress_Attachment_Metadata {
18
19    /**
20     * Persist the VideoPress metadata information, including rating and display_embed.
21     *
22     * @param string|int $post_id         The post id.
23     * @param string     $guid            VideoPress Guid.
24     * @param string     $post_title      The post title.
25     * @param string     $caption         Video caption.
26     * @param string     $post_excerpt    The post excerpt.
27     * @param string     $rating          The rating.
28     * @param int        $display_embed   The display_embed.
29     * @param int        $allow_download  Allow video downloads.
30     * @param int        $privacy_setting The video privacy setting.
31     *
32     * @return bool|\WP_Error
33     */
34    public static function persist_metadata( $post_id, $guid, $post_title, $caption, $post_excerpt, $rating, $display_embed, $allow_download, $privacy_setting ) {
35        $post_id = absint( $post_id );
36
37        $args = array(
38            'method'  => 'POST',
39            'headers' => array( 'content-type' => 'application/json' ),
40        );
41
42        // Keep null values to avoid accidental unset.
43        $display_embed   = null === $display_embed ? null : (int) $display_embed;
44        $allow_download  = null === $allow_download ? null : (int) $allow_download;
45        $privacy_setting = null === $privacy_setting ? null : (int) $privacy_setting;
46
47        $values         = self::build_wpcom_api_request_values( $post_title, $caption, $post_excerpt, $rating, $display_embed, $allow_download, $privacy_setting );
48        $endpoint       = 'videos';
49        $values['guid'] = $guid;
50
51        $result = Client::wpcom_json_api_request_as_blog( $endpoint, '2', $args, wp_json_encode( $values ), 'wpcom' );
52
53        $validated_result = self::validate_result( $result );
54        if ( true !== $validated_result ) {
55            return $validated_result;
56        }
57
58        // If we are in WPCOM, then we don't need to make anything else since we've already updated the video information.
59        if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
60            return true;
61        }
62
63        $meta = wp_get_attachment_metadata( $post_id );
64
65        if ( isset( $values['display_embed'] ) ) {
66            $meta['videopress']['display_embed'] = (bool) $values['display_embed']; // convert it to bool since that's how we store it on wp-admin side.
67        }
68
69        if ( isset( $values['allow_download'] ) ) {
70            $meta['videopress']['allow_download'] = (bool) $values['allow_download'];
71        }
72
73        if ( isset( $values['rating'] ) ) {
74            $meta['videopress']['rating'] = $values['rating'];
75        }
76
77        if ( isset( $values['privacy_setting'] ) ) {
78            $meta['videopress']['privacy_setting'] = $values['privacy_setting'];
79        }
80
81        wp_update_attachment_metadata( $post_id, $meta );
82
83        return true;
84    }
85
86    /**
87     * Check if the given media item is a VideoPress file.
88     *
89     * @param stdClass $item The media item.
90     *
91     * @return bool
92     */
93    public static function is_videopress_media( $item ) {
94        if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
95            return str_starts_with( $item->mime_type, 'video/' );
96        }
97
98        // Else, we are in Jetpack and we need to check if the video is video/videopress.
99        return 'video/videopress' === $item->mime_type;
100    }
101
102    /**
103     * Check if display_embed has valid values.
104     *
105     * @param mixed $display_embed The input display embed.
106     *
107     * @return bool
108     */
109    private static function is_display_embed_valid( $display_embed ) {
110        return in_array( $display_embed, array( 0, 1 ), true );
111    }
112
113    /**
114     * Check if allow_download has valid values
115     *
116     * @param mixed $allow_download The value to test.
117     * @return bool
118     */
119    private static function is_allow_download_valid( $allow_download ) {
120        return in_array( $allow_download, array( 0, 1 ), true );
121    }
122
123    /**
124     * Check if privacy_setting has valid values
125     *
126     * @param mixed $privacy_setting The value to test.
127     * @return bool
128     */
129    private static function is_privacy_setting_valid( $privacy_setting ) {
130        return in_array( $privacy_setting, array( VIDEOPRESS_PRIVACY::IS_PUBLIC, VIDEOPRESS_PRIVACY::IS_PRIVATE, VIDEOPRESS_PRIVACY::SITE_DEFAULT ), true );
131    }
132
133    /**
134     * Validate the response received from WPCOM.
135     *
136     * @param array|\WP_Error $result The result returned by the client.
137     */
138    private static function validate_result( $result ) {
139        $response_code = isset( $result['response']['code'] ) ? $result['response']['code'] : 500;
140
141        // When Client::wpcom_json_api_request_as_blog is called in WPCOM, bad response codes are not converted to WP_Error.
142        // Because of this, we need to manually check the response code to check if the direct API call is 200 (OK).
143        if ( 200 === $response_code && ! is_wp_error( $result ) ) {
144            return true;
145        }
146
147        $error_message = __(
148            'There was an issue saving your updates to the VideoPress service. Please try again later.',
149            'jetpack'
150        );
151
152        $error_code = $response_code;
153
154        if ( is_wp_error( $result ) ) {
155            $error_code = $result->get_error_code();
156        }
157
158        return new \WP_Error( $error_code, $error_message );
159    }
160
161    /**
162     * Build the request values that will be passed to the WPCOM API.
163     *
164     * @param string $post_title The video title.
165     * @param string $caption The video caption.
166     * @param string $post_excerpt The except.
167     * @param string $rating The video rating.
168     * @param string $display_embed The video display_embed.
169     * @param int    $allow_download The video allow_download.
170     * @param int    $privacy_setting The video privacy setting.
171     *
172     * @return array
173     */
174    private static function build_wpcom_api_request_values( $post_title, $caption, $post_excerpt, $rating, $display_embed, $allow_download, $privacy_setting ) {
175        $values = array();
176
177        // Add the video title & description in, so that we save it properly.
178        if ( isset( $post_title ) ) {
179            $values['title'] = trim( wp_strip_all_tags( $post_title ) );
180        }
181
182        if ( isset( $caption ) ) {
183            $values['caption'] = trim( wp_strip_all_tags( $caption ) );
184        }
185
186        if ( isset( $post_excerpt ) ) {
187            $values['description'] = trim( wp_strip_all_tags( $post_excerpt ) );
188        }
189
190        if ( isset( $rating ) ) {
191            $values['rating'] = $rating;
192        }
193
194        if ( self::is_display_embed_valid( $display_embed ) ) {
195            $values['display_embed'] = $display_embed;
196        }
197
198        if ( self::is_allow_download_valid( $allow_download ) ) {
199            $values['allow_download'] = $allow_download;
200        }
201
202        if ( self::is_privacy_setting_valid( $privacy_setting ) ) {
203            $values['privacy_setting'] = $privacy_setting;
204        }
205
206        return $values;
207    }
208}