Skip to main content

Read Benecaster’s analytics numbers instead of copying its SQL

Free Intermediate

A drill-down that works out its own rows drifts away from the headline figure above it. Read through Benecaster’s analytics functions and your add-on’s numbers are Benecaster’s numbers, including downloads older than 30 days, which survive only as daily totals.

This example adds a REST route that returns a show’s win-back list — cancelled subscribers whose podcast app is still checking the feed — next to a year of tracked downloads by app. It uses benecaster_get_winback_leads() and benecaster_get_downloads_by(); benecaster_get_download_total() and benecaster_get_show_benchmarks() work the same way.

Code

<?php
add_action( 'rest_api_init', function () {
    register_rest_route( 'my-analytics/v1', '/shows/(?P<id>\d+)/winback', [
        'methods'             => 'GET',
        'permission_callback' => fn() => current_user_can( 'manage_options' ), // it names users
        'callback'            => function ( WP_REST_Request $request ) {
            $show_id = (int) $request['id'];

            $leads = benecaster_get_winback_leads( $show_id, [ 'limit' => 50 ] );
            if ( null === $leads ) {
                return [ 'logging' => false ]; // log switched off: no data, not zero
            }

            return [
                'logging' => true,
                'leads'   => array_map( fn( $lead ) => [
                    'user'      => get_userdata( $lead['user_id'] )?->display_name,
                    'tier'      => $lead['tier_slug'],
                    'last_seen' => wp_date( 'j M Y, H:i', strtotime( $lead['last_polled_at'] . ' UTC' ) ),
                    'app'       => $lead['app'],
                ], $leads ),
                // A year of tracked downloads by app — the daily totals are included.
                'by_app'  => benecaster_get_downloads_by( 'app', $show_id, [
                    'date_from' => gmdate( 'Y-m-d', strtotime( '-1 year' ) ),
                ] ),
            ];
        },
    ] );
} );

View on GitHub →

Need this built rather than just documented? See our services →