Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
3 / 3
CRAP
n/a
0 / 0
Automattic\Jetpack\PremiumAnalytics\is_videopress_available
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
Automattic\Jetpack\PremiumAnalytics\configure_videopress_availability
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
Automattic\Jetpack\PremiumAnalytics\inject_videopress_script_data
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2/**
3 * VideoPress availability, shared by the widget layer and the client routes.
4 *
5 * Calypso gates its Videos module on the `videopress` plan feature, which
6 * `wpcom_site_has_feature()` answers on the WPCOM platform. That function does
7 * not exist off-platform. `Current_Plan::supports()` grants `videopress` to
8 * every plan because of the free tier, while
9 * `Product::get_site_features_from_wpcom()` can make a synchronous WPCOM
10 * request and answers entitlement rather than whether VideoPress is running.
11 * The off-platform question is therefore answered from the module or plugin.
12 *
13 * The canonical gates already exist: `VideoPress\Status::is_active()` for the
14 * off-platform branch, the WPCOM arm of `Current_Plan::supports()` for the
15 * platform one. Neither `jetpack-videopress` nor `jetpack-plans` is in this
16 * package's dependency graph, so the detection below is local by necessity.
17 * Widen the graph before writing another detector.
18 *
19 * @package automattic/jetpack-premium-analytics
20 */
21
22namespace Automattic\Jetpack\PremiumAnalytics;
23
24use Automattic\Jetpack\Constants;
25use Automattic\Jetpack\Modules;
26use Automattic\Jetpack\Status\Host;
27
28/**
29 * Filter controlling whether the VideoPress-backed surfaces are available.
30 *
31 * @var string
32 */
33const VIDEOPRESS_AVAILABLE_FILTER = 'jetpack_premium_analytics_videopress_available';
34
35/**
36 * Whether the site can produce VideoPress play data.
37 *
38 * Atomic reads the plan feature alongside Simple, not the module: wpcomsh
39 * provides `wpcom_site_has_feature()` there, and the VideoPress module has no
40 * `Auto Activate` header, so a plan that includes VideoPress routinely comes
41 * with the module off. wpcomsh grants `videopress` to every business-and-higher
42 * plan and WoA only exists on those, so the platform branch effectively gates
43 * Simple alone: an Atomic site with the module off keeps the video surfaces.
44 * That is intended — hosting is service-level on WPCOM, so the module would be
45 * a false negative there.
46 *
47 * Off-platform the question becomes "is VideoPress running here", not "is it
48 * paid for" — without the module there is no new play data to report. That is
49 * deliberately narrower than `Initial_State::has_videopress_access()`, which
50 * never looks at the module and counts the paid storage tiers instead.
51 *
52 * `Current_Plan::supports( 'videopress' )` is avoided because off-platform it
53 * returns true for every plan, thanks to the VideoPress free tier.
54 *
55 * @return bool Whether Premium Analytics treats VideoPress as available.
56 */
57function is_videopress_available() {
58    if ( ( new Host() )->is_wpcom_platform() ) {
59        $is_available = function_exists( 'wpcom_site_has_feature' ) && \wpcom_site_has_feature( 'videopress' );
60    } else {
61        // `false` skips the module registry the standalone Premium Analytics plugin
62        // does not ship, which would otherwise report every module inactive.
63        $is_available = ( new Modules() )->is_active( 'videopress', false )
64            || Constants::is_defined( 'JETPACK_VIDEOPRESS_ROOT_FILE' );
65    }
66
67    /**
68     * Filters whether Premium Analytics treats VideoPress as available.
69     *
70     * Hides the Top videos widget, the Videos report, and the video detail page
71     * when false.
72     *
73     * @param bool $is_available Whether VideoPress was detected in the current request.
74     */
75    return (bool) apply_filters( VIDEOPRESS_AVAILABLE_FILTER, $is_available );
76}
77
78/**
79 * Configures the VideoPress script data.
80 *
81 * @return void
82 */
83function configure_videopress_availability() {
84    add_filter( 'jetpack_admin_js_script_data', __NAMESPACE__ . '\\inject_videopress_script_data', 20 );
85}
86
87/**
88 * Injects the VideoPress availability flag into JetpackScriptData.
89 *
90 * The client cannot read `site.plan.features` for this: that key is only
91 * populated when the Publicize package happens to be loaded, which the
92 * standalone Premium Analytics plugin never loads.
93 *
94 * @param array $data The script data passed by the assets package.
95 * @return array
96 */
97function inject_videopress_script_data( array $data ): array {
98    if ( ! isset( $data['premium_analytics'] ) || ! is_array( $data['premium_analytics'] ) ) {
99        $data['premium_analytics'] = array();
100    }
101
102    $data['premium_analytics']['has_videopress'] = is_videopress_available();
103
104    return $data;
105}