Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 62
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Services
0.00% covered (danger)
0.00%
0 / 62
0.00% covered (danger)
0.00%
0 / 4
132
0.00% covered (danger)
0.00%
0 / 1
 wpcom_get_all
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
6
 get_all
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
20
 fetch_and_cache_services
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
20
 clear_cache
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Publicize Services class.
4 *
5 * @package automattic/jetpack-publicize
6 */
7
8namespace Automattic\Jetpack\Publicize;
9
10use Automattic\Jetpack\Publicize\REST_API\Proxy_Requests;
11use WP_REST_Request;
12
13/**
14 * Publicize Services class.
15 */
16class Services {
17
18    const SERVICES_TRANSIENT = 'jetpack_social_services_list_v2';
19
20    /**
21     * Get the available publicize services. Meant to be called directly only on WPCOM.
22     *
23     * @return array
24     */
25    public static function wpcom_get_all() {
26        // Ensure that we are on WPCOM.
27        Publicize_Utils::assert_is_wpcom( __METHOD__ );
28
29        require_lib( 'external-connections' );
30
31        $external_connections = \WPCOM_External_Connections::init();
32
33        $services = $external_connections->get_external_services_list( 'publicize', get_current_blog_id() );
34
35        $items = array();
36
37        foreach ( $services as $service ) {
38            // Set the fields as per the schema in Services_Controller.
39            $items[] = array(
40                'id'          => $service['ID'],
41                'description' => $service['description'],
42                'label'       => $service['label'],
43                'status'      => $service['status'] ?? 'ok',
44                'supports'    => array(
45                    'additional_users'      => $service['multiple_external_user_ID_support'],
46                    'additional_users_only' => $service['external_users_only'],
47                ),
48                'url'         => $service['connect_URL'],
49            );
50        }
51
52        return $items;
53    }
54
55    /**
56     * Get all services.
57     *
58     * @param array $args Arguments
59     *                - 'ignore_cache': bool Whether to ignore the cache and fetch the connections from the API.
60     * @return array
61     */
62    public static function get_all( $args = array() ) {
63
64        if ( Publicize_Utils::is_wpcom() ) {
65            $services = self::wpcom_get_all();
66        } else {
67
68            $ignore_cache = $args['ignore_cache'] ?? false;
69
70            $services = get_transient( self::SERVICES_TRANSIENT );
71
72            if ( $ignore_cache || false === $services ) {
73                $services = self::fetch_and_cache_services();
74            }
75            // This is here for backwards compatibility
76            // TODO Remove this array_map() call after April 2025 release of Jetpack.
77            return array_map(
78                function ( $service ) {
79                    global $publicize;
80
81                    return array_merge(
82                        $service,
83                        array(
84                            'ID'                  => $service['id'],
85                            'connect_URL'         => $publicize->connect_url( $service['id'], 'connect' ),
86                            'external_users_only' => $service['supports']['additional_users_only'],
87                            'multiple_external_user_ID_support' => $service['supports']['additional_users'],
88                        )
89                    );
90                },
91                $services
92            );
93        }
94
95        return $services;
96    }
97
98    /**
99     * Fetch services from the REST API and cache them.
100     *
101     * @return array
102     */
103    public static function fetch_and_cache_services() {
104        $proxy = new Proxy_Requests( 'publicize/services' );
105
106        $request = new WP_REST_Request( 'GET' );
107
108        $response = $proxy->proxy_request_to_wpcom_as_user( $request );
109
110        if ( is_wp_error( $response ) ) {
111            // @todo log error.
112            return array();
113        }
114
115        if ( is_array( $response ) ) {
116            /**
117             * Let us set the connect URL to null.
118             *
119             * Reason:
120             * We do not want to cache the connect URL, as it's user-specific,
121             * but the services are for all users.
122             * The intention is to get the connect URL on demand via an API call when needed.
123             */
124            $services = array_map(
125                function ( $service ) {
126                    return array_merge(
127                        $service,
128                        array(
129                            'url' => null,
130                        )
131                    );
132                },
133                $response
134            );
135
136            if ( ! set_transient( self::SERVICES_TRANSIENT, $services, DAY_IN_SECONDS ) ) {
137                // If the transient has beeen set in another request, the call to set_transient can fail.
138                // If so, we can delete the transient and try again.
139                self::clear_cache();
140
141                set_transient( self::SERVICES_TRANSIENT, $services, DAY_IN_SECONDS );
142            }
143        }
144
145        return $response;
146    }
147
148    /**
149     * Clear the services cache.
150     */
151    public static function clear_cache() {
152        delete_transient( self::SERVICES_TRANSIENT );
153    }
154}