Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
55.81% covered (warning)
55.81%
48 / 86
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
WPCOM_REST_API_V2_Endpoint_Podcast_Player
57.83% covered (warning)
57.83%
48 / 83
0.00% covered (danger)
0.00%
0 / 6
35.20
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 register_routes
90.57% covered (success)
90.57%
48 / 53
0.00% covered (danger)
0.00%
0 / 1
1.00
 get_tracks_quantity
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 get_player_data
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
42
 prepare_for_response
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 get_item_schema
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * Podcast Player API
4 *
5 * @package automattic/jetpack
6 * @since 8.4.0
7 */
8
9if ( ! defined( 'ABSPATH' ) ) {
10    exit( 0 );
11}
12
13/**
14 * Fetch podcast feeds and parse data for the Podcast Player block.
15 *
16 * @since 8.4.0
17 */
18class WPCOM_REST_API_V2_Endpoint_Podcast_Player extends WP_REST_Controller {
19    /**
20     * Constructor.
21     */
22    public function __construct() {
23        $this->namespace = 'wpcom/v2';
24        $this->rest_base = 'podcast-player';
25        // This endpoint *does not* need to connect directly to Jetpack sites.
26        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
27    }
28
29    /**
30     * Register the route.
31     */
32    public function register_routes() {
33        // GET /sites/<blog_id>/podcast-player - Returns feed data.
34        register_rest_route(
35            $this->namespace,
36            '/' . $this->rest_base,
37            array(
38                array(
39                    'methods'             => WP_REST_Server::READABLE,
40                    'callback'            => array( $this, 'get_player_data' ),
41                    'permission_callback' => function () {
42                        return current_user_can( 'edit_posts' );
43                    },
44                    'args'                => array(
45                        'url'             => array(
46                            'description'       => __( 'The Podcast RSS feed URL.', 'jetpack' ),
47                            'type'              => 'string',
48                            'required'          => 'true',
49                            'validate_callback' => function ( $param ) {
50                                return wp_http_validate_url( $param );
51                            },
52                        ),
53                        'guids'           => array(
54                            'description'       => __( 'A list of unique identifiers for fetching specific podcast episodes.', 'jetpack' ),
55                            'type'              => 'array',
56                            'required'          => 'false',
57                            'validate_callback' => function ( $guids ) {
58                                return is_array( $guids );
59                            },
60                            'sanitize_callback' => function ( $guids ) {
61                                    return array_map( 'sanitize_text_field', $guids );
62                            },
63                        ),
64                        'episode-options' => array(
65                            'description' => __( 'Whether we should return the episodes list for use in the selection UI', 'jetpack' ),
66                            'type'        => 'boolean',
67                            'required'    => 'false',
68                        ),
69                    ),
70                    'schema'              => array( $this, 'get_public_item_schema' ),
71                ),
72            )
73        );
74
75        // GET /sites/<blog_id>/podcast-player/track-quantity - Returns number of tracks.
76        register_rest_route(
77            $this->namespace,
78            '/' . $this->rest_base . '/track-quantity',
79            array(
80                array(
81                    'methods'             => WP_REST_Server::READABLE,
82                    'callback'            => array( $this, 'get_tracks_quantity' ),
83                    'permission_callback' => function () {
84                        return current_user_can( 'edit_posts' );
85                    },
86                ),
87            )
88        );
89    }
90
91    /**
92     * Retrieves tracks quantity
93     *
94     * @return Integer number of tracks.
95     * */
96    public function get_tracks_quantity() {
97        if ( ! class_exists( 'Jetpack_Podcast_Helper' ) ) {
98            require_once JETPACK__PLUGIN_DIR . '/_inc/lib/class-jetpack-podcast-helper.php';
99        }
100
101        return rest_ensure_response( Jetpack_Podcast_Helper::get_tracks_quantity() );
102    }
103
104    /**
105     * Retrieves data needed to display a podcast player from RSS feed.
106     *
107     * @param WP_REST_Request $request The REST API request data.
108     * @return WP_REST_Response The REST API response.
109     */
110    public function get_player_data( $request ) {
111        if ( ! class_exists( 'Jetpack_Podcast_Helper' ) ) {
112            require_once JETPACK__PLUGIN_DIR . '/_inc/lib/class-jetpack-podcast-helper.php';
113        }
114
115        $helper = new Jetpack_Podcast_Helper( $request['url'] );
116
117        $args = array();
118
119        if ( isset( $request['guids'] ) ) {
120            $args['guids'] = $request['guids'];
121        }
122
123        if ( isset( $request['episode-options'] ) && $request['episode-options'] ) {
124            $args['episode-options'] = true;
125        }
126
127        $player_data = $helper->get_player_data( $args );
128
129        if ( is_wp_error( $player_data ) ) {
130            return rest_ensure_response( $player_data );
131        }
132
133        $player_data = $this->prepare_for_response( $player_data, $request );
134        return rest_ensure_response( $player_data );
135    }
136
137    /**
138     * Filters out data based on ?_fields= request parameter
139     *
140     * @param array           $player_data Data for the player.
141     * @param WP_REST_Request $request The request.
142     * @return array filtered $player_data
143     */
144    public function prepare_for_response( $player_data, $request ) {
145        if ( ! is_callable( array( $this, 'get_fields_for_response' ) ) ) {
146            return $player_data;
147        }
148
149        $fields = $this->get_fields_for_response( $request );
150
151        $response_data = array();
152        foreach ( $player_data as $field => $value ) {
153            if ( in_array( $field, $fields, true ) ) {
154                $response_data[ $field ] = $value;
155            }
156        }
157
158        return $response_data;
159    }
160
161    /**
162     * Retrieves the response schema, conforming to JSON Schema.
163     *
164     * @return array
165     */
166    public function get_item_schema() {
167        if ( ! class_exists( 'Jetpack_Podcast_Helper' ) ) {
168            require_once JETPACK__PLUGIN_DIR . '/_inc/lib/class-jetpack-podcast-helper.php';
169        }
170
171        return Jetpack_Podcast_Helper::get_player_data_schema();
172    }
173}
174wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Podcast_Player' );