Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 83
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Stats
0.00% covered (danger)
0.00%
0 / 83
0.00% covered (danger)
0.00%
0 / 4
342
0.00% covered (danger)
0.00%
0 / 1
 fetch_video_plays
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
30
 get_today_plays
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
42
 get_featured_stats
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
12
 prepare_featured_stats
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * Provides data stats about videos inside VideoPress
4 *
5 * @package automattic/jetpack-videopress
6 */
7
8namespace Automattic\Jetpack\VideoPress;
9
10use Automattic\Jetpack\Connection\Client;
11use WP_Error;
12
13/**
14 * Provides data stats about videos inside VideoPress
15 */
16class Stats {
17    /**
18     * Hit WPCOM video-plays stats endpoint.
19     *
20     * @param array $args Request args.
21     * @return array|WP_Error WP HTTP response on success
22     */
23    public static function fetch_video_plays( $args = array() ) {
24        $blog_id = VideoPressToken::blog_id();
25
26        $endpoint = sprintf(
27            'sites/%d/stats/video-plays?check_stats_module=false',
28            $blog_id
29        );
30
31        if ( is_array( $args ) && ! empty( $args ) ) {
32            $endpoint .= '&' . http_build_query( $args );
33        }
34
35        $result = Client::wpcom_json_api_request_as_blog( $endpoint );
36
37        if ( is_wp_error( $result ) ) {
38            return $result;
39        }
40
41        $response      = $result['http_response'];
42        $response_code = $response->get_status();
43        $response_body = json_decode( $response->get_data(), true );
44
45        if ( 200 !== $response_code ) {
46            return new WP_Error(
47                'videopress_stats_error',
48                $response_body
49            );
50        }
51
52        return array(
53            'code' => $response_code,
54            'data' => $response_body,
55        );
56    }
57
58    /**
59     * Returns the counter of today's plays for all videos.
60     *
61     * @return int|WP_Error the total of plays for today, or WP_Error on failure.
62     */
63    public static function get_today_plays() {
64        $response = self::fetch_video_plays();
65
66        if ( is_wp_error( $response ) ) {
67            return $response;
68        }
69
70        $data = $response['data'];
71
72        if ( ! $data || ! isset( $data['days'] ) || ! is_countable( $data['days'] ) || count( $data['days'] ) === 0 ) {
73            return new WP_Error(
74                'videopress_stats_error',
75                __( 'Could not find any stats from the service', 'jetpack-videopress-pkg' )
76            );
77        }
78
79        /*
80         * The only result here is today's stats
81         */
82        $today_stats = array_pop( $data['days'] );
83
84        return $today_stats['total_plays'];
85    }
86
87    /**
88     * Returns the featured stats for VideoPress.
89     *
90     * @param int    $period_count (optional) The number of days to consider.
91     * @param string $period (optional) The period to consider.
92     *
93     * @return array|WP_Error a list of stats, or WP_Error on failure.
94     */
95    public static function get_featured_stats( $period_count = 14, $period = 'day' ) {
96        $response = self::fetch_video_plays(
97            array(
98                'period'         => $period,
99                'num'            => $period_count,
100                'complete_stats' => true,
101            )
102        );
103
104        if ( is_wp_error( $response ) ) {
105            return $response;
106        }
107
108        $data = $response['data'];
109
110        if ( ! $data ) {
111            return new WP_Error(
112                'videopress_stats_error',
113                __( 'Could not find any stats from the service', 'jetpack-videopress-pkg' )
114            );
115        }
116
117        // Get only the list of dates
118        $dates = $data['days'];
119
120        // Organize the data into the planned stats
121        return self::prepare_featured_stats( $dates, $period_count, $period );
122    }
123
124    /**
125     * Prepares the featured stats for VideoPress.
126     *
127     * @param array  $dates The list of dates returned by the API.
128     * @param int    $period_count The total number of days to consider.
129     * @param string $period The period to consider.
130     * @return array a list of stats.
131     */
132    public static function prepare_featured_stats( $dates, $period_count, $period = 'day' ) {
133        /**
134         * Ensure the sorting of the dates, recent ones first.
135         * This way, the first 7 positions are from the last 7 days,
136         * and the next 7 positions are from the 7 days before it.
137         */
138        krsort( $dates );
139        $period_of_data = floor( $period_count / 2 );
140        $period         = $period === 'day' ? __( 'day', 'jetpack-videopress-pkg' ) : __( 'year', 'jetpack-videopress-pkg' );
141
142        // template for the response
143        $featured_stats = array(
144            // translators: %1$d is the number of units of time, %2$s is the period in which the units of time are measured ex. 'day' or 'year'.
145            'label'  => sprintf( _n( 'last %1$d %2$s', 'last %1$d %2$ss', (int) $period_of_data, 'jetpack-videopress-pkg' ), $period_of_data, $period ),
146            'period' => $period,
147            'data'   => array(
148                'views'       => array(
149                    'current'  => 0,
150                    'previous' => 0,
151                ),
152                'impressions' => array(
153                    'current'  => 0,
154                    'previous' => 0,
155                ),
156                'watch_time'  => array(
157                    'current'  => 0,
158                    'previous' => 0,
159                ),
160            ),
161        );
162
163        // Go through the dates to compute the stats
164        $counter = 0;
165        foreach ( $dates as $date_info ) {
166            $date_totals = $date_info['total'];
167
168            if ( $counter < floor( $period_count / 2 ) ) {
169
170                // the first 7 elements are for the current period
171                $featured_stats['data']['views']['current']       += $date_totals['views'];
172                $featured_stats['data']['impressions']['current'] += $date_totals['impressions'];
173                $featured_stats['data']['watch_time']['current']  += $date_totals['watch_time'];
174
175            } else {
176
177                // the next 7 elements are for the previous period
178                $featured_stats['data']['views']['previous']       += $date_totals['views'];
179                $featured_stats['data']['impressions']['previous'] += $date_totals['impressions'];
180                $featured_stats['data']['watch_time']['previous']  += $date_totals['watch_time'];
181
182            }
183
184            ++$counter;
185        }
186
187        return $featured_stats;
188    }
189}