Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
XMLRPC
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 7
420
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 init
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 xmlrpc_methods
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 create_media_item
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 update_videopress_media_item
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
42
 update_poster_image
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 authenticate_user
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * The VIdeoPress XMLRPC class
4 *
5 * @package automattic/jetpack-videopress
6 */
7
8namespace Automattic\Jetpack\VideoPress;
9
10use WP_User;
11
12/**
13 * VideoPress playback module markup generator.
14 *
15 * @since 0.1.1
16 */
17class XMLRPC {
18
19    /**
20     * Singleton XMLRPC instance.
21     *
22     * @var XMLRPC
23     **/
24    private static $instance = null;
25
26    /**
27     * The current user object.
28     *
29     * @var WP_User
30     */
31    private $current_user;
32
33    /**
34     * Private VideoPress_XMLRPC constructor.
35     *
36     * Use the VideoPress_XMLRPC::init() method to get an instance.
37     */
38    private function __construct() {
39        add_filter( 'jetpack_xmlrpc_methods', array( $this, 'xmlrpc_methods' ), 10, 3 );
40    }
41
42    /**
43     * Initialize the VideoPress_XMLRPC and get back a singleton instance.
44     *
45     * @return XMLRPC
46     */
47    public static function init() {
48        if ( self::$instance === null ) {
49            self::$instance = new XMLRPC();
50        }
51
52        return self::$instance;
53    }
54
55    /**
56     * Adds additional methods the WordPress xmlrpc API for handling VideoPress specific features
57     *
58     * @param array   $methods The Jetpack API methods.
59     * @param array   $core_methods The WordPress Core API methods (ignored).
60     * @param WP_User $user The user object the API request is signed by.
61     *
62     * @return array
63     */
64    public function xmlrpc_methods( $methods, $core_methods, $user ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
65        if ( $user && $user instanceof WP_User ) {
66            $this->current_user = $user;
67        }
68
69        $methods['jetpack.createMediaItem']             = array( $this, 'create_media_item' );
70        $methods['jetpack.updateVideoPressMediaItem']   = array( $this, 'update_videopress_media_item' );
71        $methods['jetpack.updateVideoPressPosterImage'] = array( $this, 'update_poster_image' );
72
73        return $methods;
74    }
75
76    /**
77     * This is used by the WPCOM VideoPress uploader in order to create a media item with
78     * specific meta data about an uploaded file. After this, the transcoding session will
79     * update the meta information via the update_videopress_media_item() method.
80     *
81     * Note: This method technically handles the creation of multiple media objects, though
82     * in practice this is never done.
83     *
84     * @param array $media Media items being uploaded.
85     * @return array
86     */
87    public function create_media_item( $media ) {
88        $this->authenticate_user();
89
90        foreach ( $media as & $media_item ) {
91            $title = sanitize_title( basename( $media_item['url'] ) );
92            $guid  = isset( $media['guid'] ) ? $media['guid'] : null;
93
94            $media_id = videopress_create_new_media_item( $title, $guid );
95
96            wp_update_attachment_metadata(
97                $media_id,
98                array(
99                    'original' => array(
100                        'url' => $media_item['url'],
101                    ),
102                )
103            );
104
105            $media_item['post'] = get_post( $media_id );
106        }
107
108        return array( 'media' => $media );
109    }
110
111    /**
112     * Update VideoPress metadata for a media item.
113     *
114     * @param array $request Media item to update.
115     *
116     * @return bool
117     */
118    public function update_videopress_media_item( $request ) {
119        $this->authenticate_user();
120
121        $id     = $request['post_id'];
122        $status = $request['status'];
123        $format = $request['format'];
124        $info   = $request['info'];
125
126        $attachment = get_post( $id );
127        if ( ! $attachment ) {
128            return false;
129        }
130
131        $attachment->guid           = $info['original'];
132        $attachment->post_mime_type = 'video/videopress';
133
134        wp_update_post( $attachment );
135
136        // Update the vp guid and set it to a direct meta property.
137        update_post_meta( $id, 'videopress_guid', $info['guid'] );
138
139        $meta = wp_get_attachment_metadata( $id );
140
141        $meta['width']             = $info['width'];
142        $meta['height']            = $info['height'];
143        $meta['original']['url']   = $info['original'];
144        $meta['videopress']        = $info;
145        $meta['videopress']['url'] = 'https://videopress.com/v/' . $info['guid'];
146
147        // Update file statuses
148        if ( ! empty( $format ) ) {
149            $meta['file_statuses'][ $format ] = $status;
150        }
151
152        if ( ! get_post_meta( $id, '_thumbnail_id', true ) ) {
153            // Update the poster in the VideoPress info.
154            $thumbnail_id = videopress_download_poster_image( $info['poster'], $id );
155
156            if ( is_int( $thumbnail_id ) ) {
157                update_post_meta( $id, '_thumbnail_id', $thumbnail_id );
158            }
159        }
160
161        wp_update_attachment_metadata( $id, $meta );
162
163        videopress_update_meta_data( $id );
164
165        // update the meta to tell us that we're processing or complete
166        update_post_meta( $id, 'videopress_status', videopress_is_finished_processing( $id ) ? 'complete' : 'processing' );
167
168        return true;
169    }
170
171    /**
172     * Update poster image for a VideoPress media item.
173     *
174     * @param array $request The media item to update.
175     * @return bool
176     */
177    public function update_poster_image( $request ) {
178        $this->authenticate_user();
179
180        $post_id = $request['post_id'];
181        $poster  = $request['poster'];
182
183        $attachment = get_post( $post_id );
184        if ( ! $attachment ) {
185            return false;
186        }
187
188        $poster = apply_filters( 'jetpack_photon_url', $poster );
189
190        $meta                         = wp_get_attachment_metadata( $post_id );
191        $meta['videopress']['poster'] = $poster;
192        wp_update_attachment_metadata( $post_id, $meta );
193
194        // Update the poster in the VideoPress info.
195        $thumbnail_id = videopress_download_poster_image( $poster, $post_id );
196
197        if ( ! is_int( $thumbnail_id ) ) {
198            return false;
199        }
200
201        update_post_meta( $post_id, '_thumbnail_id', $thumbnail_id );
202
203        return true;
204    }
205
206    /**
207     * Check if the XML-RPC request is signed by a user token, and authenticate the user in WordPress.
208     *
209     * @return bool
210     */
211    private function authenticate_user() {
212        if ( $this->current_user ) {
213            wp_set_current_user( $this->current_user->ID );
214
215            return true;
216        }
217
218        return false;
219    }
220}