Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
47.97% covered (danger)
47.97%
59 / 123
42.86% covered (danger)
42.86%
3 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
WPCOM_REST_API_V2_Endpoint_Mailchimp
49.17% covered (danger)
49.17%
59 / 120
42.86% covered (danger)
42.86%
3 / 7
92.49
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 register_routes
100.00% covered (success)
100.00%
49 / 49
100.00% covered (success)
100.00%
1 / 1
1
 is_connected
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 get_mailchimp_status
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
30
 get_mailchimp_groups
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
30
 get_mailchimp_settings
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
30
 update_mailchimp_settings
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * API endpoints to interact with WordPress.com
4 * to get info from the Mailchimp API for use with the Mailchimp block.
5 *
6 * @package automattic/jetpack
7 */
8
9use Automattic\Jetpack\Connection\Client;
10use Automattic\Jetpack\Connection\Manager as Connection_Manager;
11use Automattic\Jetpack\Status\Host;
12
13if ( ! defined( 'ABSPATH' ) ) {
14    exit( 0 );
15}
16
17/**
18 * Mailchimp: Get Mailchimp Status.
19 * API to determine if current site has linked Mailchimp account and mailing list selected.
20 * This API is meant to be used in Jetpack and on WPCOM.
21 *
22 * @since 7.1
23 */
24class WPCOM_REST_API_V2_Endpoint_Mailchimp extends WP_REST_Controller {
25    /**
26     * Constructor.
27     */
28    public function __construct() {
29        $this->namespace                    = 'wpcom/v2';
30        $this->rest_base                    = 'mailchimp';
31        $this->wpcom_is_wpcom_only_endpoint = true;
32
33        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
34    }
35
36    /**
37     * Called automatically on `rest_api_init()`.
38     */
39    public function register_routes() {
40        register_rest_route(
41            $this->namespace,
42            $this->rest_base,
43            array(
44                array(
45                    'methods'             => WP_REST_Server::READABLE,
46                    'callback'            => array( $this, 'get_mailchimp_status' ),
47                    'permission_callback' => '__return_true',
48                ),
49            )
50        );
51        register_rest_route(
52            $this->namespace,
53            $this->rest_base . '/groups',
54            array(
55                array(
56                    'methods'             => WP_REST_Server::READABLE,
57                    'callback'            => array( $this, 'get_mailchimp_groups' ),
58                    'permission_callback' => '__return_true',
59                ),
60            )
61        );
62        register_rest_route(
63            $this->namespace,
64            $this->rest_base . '/settings',
65            array(
66                array(
67                    'methods'             => WP_REST_Server::READABLE,
68                    'callback'            => array( $this, 'get_mailchimp_settings' ),
69                    'permission_callback' => function () {
70                        return current_user_can( 'manage_options' );
71                    },
72                ),
73                array(
74                    'methods'             => WP_REST_Server::EDITABLE,
75                    'callback'            => array( $this, 'update_mailchimp_settings' ),
76                    'permission_callback' => function () {
77                        return current_user_can( 'manage_options' );
78                    },
79                    'args'                => array(
80                        'follower_list_id' => array(
81                            'type'              => 'string',
82                            'required'          => true,
83                            'sanitize_callback' => 'sanitize_text_field',
84                        ),
85                    ),
86                ),
87            )
88        );
89    }
90
91    /**
92     * Check if MailChimp is set up properly.
93     *
94     * @return bool
95     */
96    private function is_connected() {
97        $option = get_option( 'jetpack_mailchimp' );
98        if ( ! $option ) {
99            return false;
100        }
101        $data = json_decode( $option, true );
102        if ( ! $data ) {
103            return false;
104        }
105        return isset( $data['follower_list_id'] ) && isset( $data['keyring_id'] );
106    }
107
108    /**
109     * Get the status of current blog's Mailchimp connection
110     *
111     * @return mixed
112     * code:string (connected|unconnected),
113     * connect_url:string
114     * site_id:int
115     */
116    public function get_mailchimp_status() {
117        $is_wpcom = ( defined( 'IS_WPCOM' ) && IS_WPCOM );
118        $site_id  = $is_wpcom ? get_current_blog_id() : Jetpack_Options::get_option( 'id' );
119        if ( ! $site_id ) {
120            return new WP_Error(
121                'unavailable_site_id',
122                __( 'Sorry, something is wrong with your Jetpack connection.', 'jetpack' ),
123                403
124            );
125        }
126        $connect_url = '/wp-admin/options-writing.php';
127        return array(
128            'code'        => $this->is_connected() ? 'connected' : 'not_connected',
129            'connect_url' => $connect_url,
130            'site_id'     => $site_id,
131        );
132    }
133
134    /**
135     * Get all Mailchimp groups for the accounted connected to the current blog
136     *
137     * @return mixed
138     * groups:array
139     * site_id:int
140     */
141    public function get_mailchimp_groups() {
142        $is_wpcom = ( defined( 'IS_WPCOM' ) && IS_WPCOM );
143        $site_id  = $is_wpcom ? get_current_blog_id() : Jetpack_Options::get_option( 'id' );
144        if ( ! $site_id ) {
145            return new WP_Error(
146                'unavailable_site_id',
147                __( 'Sorry, something is wrong with your Jetpack connection.', 'jetpack' ),
148                403
149            );
150        }
151
152        // Do not attempt to fetch groups if Mailchimp is not connected.
153        if ( ! $this->is_connected() ) {
154            return new WP_Error(
155                'mailchimp_not_connected',
156                __( 'Your site is not connected to Mailchimp yet.', 'jetpack' ),
157                403
158            );
159        }
160
161        $path    = sprintf( '/sites/%d/mailchimp/groups', absint( $site_id ) );
162        $request = Client::wpcom_json_api_request_as_blog( $path );
163        $body    = wp_remote_retrieve_body( $request );
164        return json_decode( $body );
165    }
166
167    /**
168     * Get the Mailchimp connection settings.
169     *
170     * @return mixed
171     */
172    public function get_mailchimp_settings() {
173        $site_id = Connection_Manager::get_site_id();
174        if ( is_wp_error( $site_id ) ) {
175            return new WP_Error(
176                'unavailable_site_id',
177                __( 'Sorry, something is wrong with your Jetpack connection.', 'jetpack' ),
178                403
179            );
180        }
181
182        $settings = array();
183
184        if ( ( new Host() )->is_wpcom_simple() ) {
185            require_lib( 'mailchimp' );
186            $api                   = new MailchimpApi( $site_id, get_current_user_id() );
187            $settings              = $api::get_settings( $site_id );
188            $settings['audiences'] = $api->get_lists();
189        } else {
190            $path     = sprintf( '/sites/%d/mailchimp/settings', $site_id );
191            $response = Client::wpcom_json_api_request_as_user( $path, '1.1', array(), null, 'rest' );
192            if ( ! is_wp_error( $response ) ) {
193                $settings = json_decode( wp_remote_retrieve_body( $response ), true );
194            }
195
196            $path     = sprintf( '/sites/%d/mailchimp/lists', $site_id );
197            $response = Client::wpcom_json_api_request_as_user( $path, '1.1', array(), null, 'rest' );
198            if ( ! is_wp_error( $response ) ) {
199                $settings['audiences'] = json_decode( wp_remote_retrieve_body( $response ), true );
200            }
201        }
202
203        return $settings;
204    }
205
206    /**
207     * Save the Mailchimp audience that block subscribers join.
208     *
209     * @since 16.3
210     *
211     * @param WP_REST_Request $request The request.
212     * @return array|WP_Error
213     */
214    public function update_mailchimp_settings( $request ) {
215        require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-mailchimp-helper.php';
216
217        $audience = $request['follower_list_id'];
218        $result   = Jetpack_Mailchimp_Helper::save_audience( $audience );
219        if ( is_wp_error( $result ) ) {
220            return new WP_Error( $result->get_error_code(), $result->get_error_message(), array( 'status' => 400 ) );
221        }
222
223        return array( 'follower_list_id' => $audience );
224    }
225}
226
227wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Mailchimp' );