Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
WPCOM_REST_API_V2_Attachment_VideoPress_Field
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 7
182
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 register_fields
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 get_schema
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 get
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
30
 get_videopress_guid
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 is_video
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 remove_field_for_non_videos
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
1<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2/**
3 * Extend the REST API functionality for VideoPress users.
4 *
5 * @package automattic/jetpack-videopress
6 * @since-jetpack 7.1.0
7 * @since 0.3.0
8 */
9
10namespace Automattic\Jetpack\VideoPress;
11
12use Automattic\Jetpack\Connection\Manager as Jetpack_Connection;
13use WP_Post;
14use WP_REST_Request;
15use WP_REST_Response;
16
17/**
18 * Add per-attachment VideoPress data.
19 *
20 * { # Attachment Object
21 *   ...
22 *   jetpack_videopress_guid: (string) VideoPress identifier
23 *   ...
24 * }
25 *
26 * @phan-constructor-used-for-side-effects
27 */
28class WPCOM_REST_API_V2_Attachment_VideoPress_Field {
29    /**
30     * The REST Object Type to which the jetpack_videopress_guid field will be added.
31     *
32     * @var string
33     */
34    protected $object_type = 'attachment';
35
36    /**
37     * The name of the REST API field to add.
38     *
39     * @var string $field_name
40     */
41    protected $field_name = 'jetpack_videopress_guid';
42
43    /**
44     * Constructor.
45     */
46    public function __construct() {
47        add_action( 'rest_api_init', array( $this, 'register_fields' ) );
48
49        // do this again later to collect any CPTs that get registered later.
50        add_action( 'restapi_theme_init', array( $this, 'register_fields' ), 20 );
51    }
52
53    /**
54     * Registers the jetpack_videopress field and adds a filter to remove it for attachments that are not videos.
55     */
56    public function register_fields() {
57        global $wp_rest_additional_fields;
58
59        if ( ! empty( $wp_rest_additional_fields[ $this->object_type ][ $this->field_name ] ) ) {
60            return;
61        }
62
63        register_rest_field(
64            $this->object_type,
65            $this->field_name,
66            array(
67                'get_callback'    => array( $this, 'get' ),
68                'update_callback' => null,
69                'schema'          => $this->get_schema(),
70            )
71        );
72
73        add_filter( 'rest_prepare_attachment', array( $this, 'remove_field_for_non_videos' ), 10, 2 );
74    }
75
76    /**
77     * Defines data structure and what elements are visible in which contexts.
78     *
79     * @return array
80     */
81    public function get_schema() {
82        return array(
83            '$schema'     => 'http://json-schema.org/draft-04/schema#',
84            'title'       => $this->field_name,
85            'type'        => 'string',
86            'context'     => array( 'view', 'edit' ),
87            'readonly'    => true,
88            'description' => __( 'Unique VideoPress ID', 'jetpack-videopress-pkg' ),
89        );
90    }
91
92    /**
93     * Getter: Retrieve current VideoPress data for a given attachment.
94     *
95     * @param array           $attachment Response from the attachment endpoint.
96     * @param WP_REST_Request $request Request to the attachment endpoint.
97     *
98     * @return string
99     */
100    public function get( $attachment, $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
101        if ( ! isset( $attachment['id'] ) ) {
102            return array();
103        }
104
105        $blog_id = Jetpack_Connection::get_site_id();
106        if ( ! is_int( $blog_id ) ) {
107            return array();
108        }
109
110        $videopress_guid = $this->get_videopress_guid( (int) $attachment['id'], $blog_id );
111
112        if ( ! $videopress_guid ) {
113            return '';
114        }
115
116        $schema   = $this->get_schema();
117        $is_valid = rest_validate_value_from_schema( $videopress_guid, $schema, $this->field_name );
118        if ( is_wp_error( $is_valid ) ) {
119            return $is_valid;
120        }
121
122        return $videopress_guid;
123    }
124
125    /**
126     * Gets the VideoPress GUID for a given attachment.
127     *
128     * This is pulled out into a separate method to support unit test mocking.
129     *
130     * @param int $attachment_id Attachment ID.
131     * @param int $blog_id Blog ID.
132     *
133     * @return string
134     */
135    public function get_videopress_guid( $attachment_id, $blog_id ) {
136        return video_get_info_by_blogpostid( $blog_id, $attachment_id )->guid ?? '';
137    }
138
139    /**
140     * Checks if the given attachment is a video.
141     *
142     * @param object $attachment The attachment object.
143     *
144     * @return false|int
145     */
146    public function is_video( $attachment ) {
147        return wp_startswith( $attachment->post_mime_type, 'video/' );
148    }
149
150    /**
151     * Removes the jetpack_videopress_guid field from the response if the
152     * given attachment is not a video.
153     *
154     * @param WP_REST_Response $response Response from the attachment endpoint.
155     * @param WP_Post          $attachment The original attachment object.
156     *
157     * @return mixed
158     */
159    public function remove_field_for_non_videos( $response, $attachment ) {
160        if ( ! $this->is_video( $attachment ) ) {
161            unset( $response->data[ $this->field_name ] );
162        }
163
164        return $response;
165    }
166}
167
168if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
169    wpcom_rest_api_v2_load_plugin( 'Automattic\Jetpack\VideoPress\WPCOM_REST_API_V2_Attachment_VideoPress_Field' );
170}