Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
71.70% covered (warning)
71.70%
38 / 53
75.00% covered (warning)
75.00%
3 / 4
CRAP
n/a
0 / 0
Automattic\Jetpack\PremiumAnalytics\register_widget_modules_rest_route
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
Automattic\Jetpack\PremiumAnalytics\ensure_widget_registry_ready
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
Automattic\Jetpack\PremiumAnalytics\get_widget_modules_response
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
2
Automattic\Jetpack\PremiumAnalytics\add_widget_modules_to_boot_deps
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * Dashboard widget modules: REST exposure + import-map wiring.
4 *
5 * Reads get_available_widget_types() and exposes it two ways: the `/wpcom/v2/widget-modules`
6 * REST list, and the page import map, for dynamic `import()`.
7 *
8 * @package automattic/jetpack-premium-analytics
9 */
10
11namespace Automattic\Jetpack\PremiumAnalytics;
12
13require_once __DIR__ . '/rest-namespace.php';
14
15/**
16 * Register the `/wpcom/v2/widget-modules` REST route.
17 *
18 * @return void
19 */
20function register_widget_modules_rest_route() {
21    register_rest_route(
22        DASHBOARD_REST_NAMESPACE,
23        '/widget-modules',
24        array(
25            'methods'             => \WP_REST_Server::READABLE,
26            'callback'            => __NAMESPACE__ . '\\get_widget_modules_response',
27            'permission_callback' => array( Capabilities::class, 'current_user_can_view_analytics' ),
28        )
29    );
30}
31
32/**
33 * Load the widget type API and the build manifest, once, ahead of the registry's first read.
34 *
35 * Deferred to the registry's only two readers rather than run at boot: on Simple this file's
36 * registration runs on every WPCOM public-api request, and most never read the registry. The
37 * registry hydrates itself on that read, from the registration action.
38 *
39 * @return void
40 */
41function ensure_widget_registry_ready() {
42    static $ready = false;
43    if ( $ready ) {
44        return;
45    }
46    $ready = true;
47
48    require_once __DIR__ . '/widget-types.php';
49    require_once __DIR__ . '/widget-availability.php';
50
51    // REST does not load the admin build, so this require is the manifest's only route in
52    // (WOOA7S-1804). Drop it and every widget renders "Widget is no longer available" (#49961).
53    $widgets_manifest = Analytics::widget_manifest_path();
54    if ( file_exists( $widgets_manifest ) ) {
55        require_once $widgets_manifest;
56    }
57}
58
59/**
60 * Build the REST response: one record per available widget type.
61 *
62 * @return \WP_REST_Response
63 */
64function get_widget_modules_response() {
65    ensure_widget_registry_ready();
66
67    $records = array();
68
69    foreach ( get_available_widget_types() as $widget_type ) {
70        $records[] = array(
71            'name'          => $widget_type->name,
72            'render_module' => $widget_type->render_module,
73            'widget_module' => $widget_type->widget_module,
74            'presentation'  => $widget_type->presentation,
75            'category'      => $widget_type->category,
76            'title'         => $widget_type->title,
77            'description'   => $widget_type->description,
78            'help'          => $widget_type->help,
79            'icon'          => $widget_type->icon,
80            'actions'       => $widget_type->actions,
81            'keywords'      => $widget_type->keywords,
82            'textdomain'    => $widget_type->textdomain,
83            'i18n_manifest' => $widget_type->i18n_manifest,
84            'former_names'  => $widget_type->former_names,
85        );
86    }
87
88    return rest_ensure_response( $records );
89}
90
91/**
92 * Add available widget modules to the page import map as dynamic dependencies,
93 * so the client can `import()` them on demand.
94 *
95 * @param array $boot_dependencies Boot dependencies for the page.
96 * @return array Updated boot dependencies.
97 */
98function add_widget_modules_to_boot_deps( $boot_dependencies ) {
99    ensure_widget_registry_ready();
100
101    foreach ( get_available_widget_types() as $widget_type ) {
102        if ( ! empty( $widget_type->render_module ) ) {
103            $boot_dependencies[] = array(
104                'import' => 'dynamic',
105                'id'     => $widget_type->render_module,
106            );
107        }
108
109        if ( ! empty( $widget_type->widget_module ) ) {
110            $boot_dependencies[] = array(
111                'import' => 'dynamic',
112                'id'     => $widget_type->widget_module,
113            );
114        }
115    }
116
117    return $boot_dependencies;
118}
119add_filter( 'jetpack-premium-analytics-wp-admin_boot_dependencies', __NAMESPACE__ . '\\add_widget_modules_to_boot_deps' );