├── .gitignore ├── gmt-mailchimp-wp-rest-api.php ├── README.md └── includes ├── api.php └── options.php /.gitignore: -------------------------------------------------------------------------------- 1 | # Node 2 | node_modules 3 | test/results 4 | test/coverage 5 | 6 | ## OS X 7 | .DS_Store 8 | ._* 9 | .Spotlight-V100 10 | .Trashes -------------------------------------------------------------------------------- /gmt-mailchimp-wp-rest-api.php: -------------------------------------------------------------------------------- 1 | MailChimp API` in the Dashboard. 15 | 16 | **Required Fields** 17 | 18 | - `API Key` - Your [API key from Mailchimp](https://mailchimp.com/help/about-api-keys/). 19 | - `List ID` - The [ID of the list/audience](https://mailchimp.com/help/find-audience-id/) that you want to add subscribers to. 20 | 21 | **Optional Fields** 22 | 23 | - `Form Key`/`Form Secret` - If you're using a form to submit to the API, adding a hidden key/secret field to the form can help minimize bulk robot submissions. Details on how to use it in the `Sign Up Form` section below. 24 | - `Honeypot` - The `name of a hidden` field you can add to your field to help detect bot form submissions without inconveniencing real humans. Details on how to use it in the `Sign Up Form` section below. 25 | - `Allowed Domains` - You can restrict use of the API to only calls that happen from an allowed list of domains. Separate allowed domains with a comma. 26 | - `Blocked Emails` - You can block certain email addresses from subscribing to your email list. Separate blocked emails with a comma. 27 | 28 | **API Details** 29 | 30 | You can find a list of categories and interest groups at the bottom of the settings page. It includes category and group IDs that you will need to add users to these groups with the API. 31 | 32 | 33 | 34 | ## The Endpoints 35 | 36 | The *GMT Mailchimp WP Rest API* supports two endpoints. 37 | 38 | ### `/subscribe` 39 | 40 | Add a new subscriber or update an existing one. 41 | 42 | **HTTP Method:** `POST` 43 | 44 | **Endpoint** 45 | 46 | ```bash 47 | /wp-json/gmt-mailchimp/v1/subscribe 48 | ``` 49 | 50 | **Parameters** 51 | 52 | Pass these along as query string parameters on your endpoint. 53 | 54 | | Parameter | Description | Value | Example | Required | 55 | |-----------------|---------------------------------------------|---------|----------------------|----------| 56 | | `email` | The subscriber email address | String | `hi@there.com` | Yes | 57 | | `merge` | Any merge tags to add (ex `FNAME`) | String | `merge[FNAME]=chris` | No | 58 | | `group` | Any interest groups to add | Boolean | `group[1234]=1` | No | 59 | | `tag` | Any tags to add | Boolean | `tag[5678]=1` | No | 60 | | `
` | `` (from your settings) | String | `1234=abcdef` | No | 61 | | `` | A honeypot value if enabled in settings | String | ` ` | No | 62 | | `do-not-create` | Only update existing user, do not subscribe | Boolean | `1` | No | 63 | | `u` | Remove user from provided interest groups | Boolean | `1` | No | 64 | 65 | **Sample API Calls** 66 | 67 | ```bash 68 | # Add a subscriber 69 | /wp-json/gmt-mailchimp/v1/subscribe?email=developer@awesomewebsites.com&merge[FNAME]=Chris&group[1234]=1 70 | 71 | # Remove existing subscriber from a group 72 | /wp-json/gmt-mailchimp/v1/subscribe?email=developer@awesomewebsites.com&group[abcde]=0&u=1&do-not-create=1 73 | ``` 74 | 75 | **Sample Response** 76 | 77 | The API will return a JSON object with a code, status, and message. 78 | 79 | ```json 80 | { 81 | "code": 400, 82 | "status": "disallowed_domain", 83 | "message": "This domain is not whitelisted." 84 | } 85 | ``` 86 | 87 | **Status Codes** 88 | 89 | | `code` | `status` | `message` | 90 | |--------|---------------------|-----------------------------------------------------------------------------| 91 | | `400` | `disallowed_domain` | This domain is not whitelisted. | 92 | | `400` | `failed` | Unable to subscribe at this time. Please try again. | 93 | | `400` | `failed` | Please use a valid email address. | 94 | | `400` | `invalid_user` | This subscriber does not exist. | 95 | | `400` | `unsubscribed` | You had previously unsubscribed and cannot be resubscribed using this form. | 96 | | `200` | `success` | You're now subscribed. | 97 | | `202` | `pending` | Almost there! To complete your subscription, please click the confirmation link in the email that was just sent to your inbox. | 98 | 99 | 100 | ### `/count` 101 | 102 | Get the subscriber count for a list/audience or interest group. 103 | 104 | **HTTP Method:** `GET` 105 | 106 | **Endpoint** 107 | 108 | ```bash 109 | /wp-json/gmt-mailchimp/v1/count 110 | ``` 111 | 112 | **Parameters** 113 | 114 | Pass these along as query string parameters on your endpoint. 115 | 116 | If you do not provide `category` or `id` parameters, it will return to the subscriber count for the entire list/audience. 117 | 118 | | Parameter | Description | Value | Example | Required | 119 | |--------------|-------------------------------------------|---------|------------|----------| 120 | | `category` | An interest group category ID | String | `12345` | No | 121 | | `id` | An interest group ID | String | `abcde` | No | 122 | | `round` | The value to round down to, if any | Integer | `10`/`100` | No | 123 | 124 | *The `round` parameter will round down by the specified place value. For example, `round=100` will round `7982` down to `7900`, while `round=10` will round it down to `7980`.* 125 | 126 | **Sample API Calls** 127 | 128 | ```bash 129 | # Get subscriber count for an interest group 130 | /wp-json/gmt-mailchimp/v1/count?category=12345&id=abcde 131 | 132 | # Get subscriber count for entire list/audience, and round by 100 133 | /wp-json/gmt-mailchimp/v1/count?round=100 134 | ``` 135 | 136 | **Sample Response** 137 | 138 | The API will return a JSON object with a code, status, and message. 139 | 140 | ```json 141 | { 142 | "code": 400, 143 | "status": "success", 144 | "message": 7982 145 | } 146 | ``` 147 | 148 | **Status Codes** 149 | 150 | | `code` | `status` | `message` | 151 | |--------|-----------|---------------------------------------------------| 152 | | `400` | `failed` | Unable to get subscriber count. Please try again. | 153 | | `200` | `success` | `` | 154 | 155 | 156 | 157 | ## Sign Up Form 158 | 159 | You can use the *GMT Mailchimp WP Rest API* to provide a more customized Mailchimp signup experience. 160 | 161 | ### Required Fields 162 | 163 | The only required field is an email address. 164 | 165 | ```html 166 | 167 | ``` 168 | 169 | ### Field Names 170 | 171 | For ease-of-use, you may want to use the API parameter names as the field names. This lets you use a serialize method to create your query string instead of having to manually map fields. 172 | 173 | For example, use `group[]` for interest groups and `merge[]` for merge fields. 174 | 175 | ```html 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | ``` 185 | 186 | ### Honeypot 187 | 188 | A honeypot is a field that you visually hide in the markup, but that form bots will still see and try to fill out. 189 | 190 | If this field has a value, you can assume the submitter was a bot and not a real person. The *GMT Mailchimp WP Rest API* will ignore API calls with a value for parameters that match your honeypot field name. 191 | 192 | **Sample HTML** 193 | 194 | Give the field a name that sounds real, but with a label telling humans not to fill out (important for screen reader users). 195 | 196 | ```html 197 | 198 | 199 | 200 |
201 | 202 | 203 |
204 | 205 | 206 | 207 | ``` 208 | 209 | **Sample CSS** 210 | 211 | You want to hide this field *visually only*. That means you should *NOT* use `display: none` to hide it. 212 | 213 | ```css 214 | /* 215 | * Hide only visually, but have it available for screen readers: 216 | * @link https://snook.ca/archives/html_and_css/hiding-content-for-accessibility 217 | * 218 | * 1. For long content, line feeds are not interpreted as spaces and small width 219 | * causes content to wrap 1 word per line: 220 | * https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe 221 | */ 222 | .gotcha { 223 | border: 0; 224 | clip: rect(0 0 0 0); 225 | height: 1px; 226 | margin: -1px; 227 | overflow: hidden; 228 | padding: 0; 229 | position: absolute; 230 | white-space: nowrap; 231 | /* 1 */ 232 | width: 1px; 233 | } 234 | ``` -------------------------------------------------------------------------------- /includes/api.php: -------------------------------------------------------------------------------- 1 | $val) { 20 | $mc_params['body'] = array('email_address' => $email); 21 | $request = wp_remote_request( $base_url . $tag . '/members', $mc_params ); 22 | } 23 | 24 | } 25 | 26 | /** 27 | * Check if an email address is on the block list 28 | * @param String $email The subscriber email 29 | * @param String $block_list The list of blocked emails 30 | * @return Boolean If true, email is blocked 31 | */ 32 | function gmt_mailchimp_wp_rest_api_is_blocked($email, $block_list) { 33 | 34 | // Clean up the email 35 | $email = trim($email); 36 | $email_parts = explode('@', $email); 37 | $email_no_plus = explode('+', $email_parts[0]); 38 | $emails = array( 39 | $email, 40 | $email_no_plus[0] . '@' . $email_parts[1], 41 | str_replace ('.', '', $email_no_plus[0]) . '@' . $email_parts[1], 42 | ); 43 | 44 | // Convert block list to an array 45 | $block_list_arr = explode(',', $block_list); 46 | 47 | // Check for matches 48 | return count(array_intersect($emails, $block_list_arr)) > 0; 49 | 50 | } 51 | 52 | /** 53 | * Subscriber a user 54 | * @param Object $request The request data 55 | * @return JSON WP Response Object 56 | */ 57 | function gmt_mailchimp_wp_rest_api_subscribe_user($request) { 58 | 59 | // Variables 60 | $options = mailchimp_rest_api_get_theme_options(); 61 | $params = $request->get_params(); 62 | 63 | // Check domain whitelist 64 | if (!empty($options['mailchimp_origin'])) { 65 | $origin = $request->get_header('origin'); 66 | if (empty($origin) || !in_array($origin, explode(',', $options['mailchimp_origin']))) { 67 | return new WP_REST_Response(array( 68 | 'code' => 400, 69 | 'status' => 'disallowed_domain', 70 | 'message' => 'This domain is not whitelisted.' 71 | ), 400); 72 | } 73 | } 74 | 75 | // Check key/secret 76 | if ( !empty($options['mailchimp_form_key']) && !empty($options['mailchimp_form_secret']) && (!isset($params[$options['mailchimp_form_key']]) || empty($params[$options['mailchimp_form_key']]) || $params[$options['mailchimp_form_key']] !== $options['mailchimp_form_secret']) ) { 77 | return new WP_REST_Response(array( 78 | 'code' => 400, 79 | 'status' => 'failed', 80 | 'message' => 'Unable to subscribe at this time. Please try again.' 81 | ), 400); 82 | } 83 | 84 | // Check honeypot field 85 | if ( !empty($options['mailchimp_honeypot']) && isset($params[$options['mailchimp_honeypot']]) && !empty($params[$options['mailchimp_honeypot']]) ) { 86 | return new WP_REST_Response(array( 87 | 'code' => 400, 88 | 'status' => 'failed', 89 | 'message' => 'Unable to subscribe at this time. Please try again.' 90 | ), 400); 91 | } 92 | 93 | // If email is invalid 94 | if ( empty( filter_var( $params['email'], FILTER_VALIDATE_EMAIL ) ) ) { 95 | return new WP_REST_Response(array( 96 | 'code' => 400, 97 | 'status' => 'failed', 98 | 'message' => 'Please use a valid email address.' 99 | ), 400); 100 | } 101 | 102 | // If subscriber email is blocked, fail silently (bwhahaha) 103 | if (!empty($options['mailchimp_blocked_emails']) && gmt_mailchimp_wp_rest_api_is_blocked($params['email'], $options['mailchimp_blocked_emails'])) { 104 | return new WP_REST_Response(array( 105 | 'code' => 200, 106 | 'status' => 'success', 107 | 'message' => 'Success.' 108 | ), 200); 109 | 110 | } 111 | 112 | // Create merge fields array 113 | $merge_fields = new stdClass(); 114 | if ( !empty( $params['merge'] ) ) { 115 | foreach ( $params['merge'] as $key => $merge_field ) { 116 | $merge_fields->$key = $merge_field; 117 | } 118 | } 119 | 120 | // Create interest groups array 121 | $join = $params['u'] ? false : true; 122 | $groups = new stdClass(); 123 | if ( !empty( $params['group'] ) ) { 124 | foreach ( $params['group'] as $key => $group ) { 125 | $groups->$key = $join; 126 | } 127 | } 128 | 129 | // Create API call 130 | $shards = explode( '-', $options['mailchimp_api_key'] ); 131 | $url = 'https://' . $shards[1] . '.api.mailchimp.com/3.0/lists/' . $options['mailchimp_list_id'] . '/members/' . md5( $params['email'] ); 132 | $tags_url = 'https://' . $shards[1] . '.api.mailchimp.com/3.0/lists/' . $options['mailchimp_list_id'] . '/segments/'; 133 | $body_params = array( 134 | 'status' => 'subscribed', 135 | 'merge_fields' => $merge_fields, 136 | 'interests' => $groups, 137 | ); 138 | if ( !$params['do-not-create'] ) { 139 | $body_params['email_address'] = $params['email']; 140 | $body_params['status_if_new'] = 'subscribed'; 141 | } 142 | $mc_params = array( 143 | 'headers' => array( 144 | 'Authorization' => 'Basic ' . base64_encode( 'mailchimp' . ':' . $options['mailchimp_api_key'] ) 145 | ), 146 | 'method' => 'PUT', 147 | 'body' => json_encode($body_params), 148 | ); 149 | 150 | // Add or edit the subscriber 151 | $request = wp_remote_request( $url, $mc_params ); 152 | $response = wp_remote_retrieve_body( $request ); 153 | $data = json_decode( $response, true ); 154 | 155 | // If there was an error 156 | if ( array_key_exists( 'status', $data ) && $data['status'] >= 400 ) { 157 | 158 | // If user doesn't exist and they shouldn't be created, bail 159 | if ( $params['do-not-create'] && $data['title'] === 'Invalid Resource' ) { 160 | return new WP_REST_Response(array( 161 | 'code' => 400, 162 | 'status' => 'invalid_user', 163 | 'message' => 'This subscriber does not exist.' 164 | ), 400); 165 | } 166 | 167 | // If user previously unsubscribed, resend confirmation email 168 | if ( $data['title'] === 'Member In Compliance State' ) { 169 | 170 | // Send the API call 171 | $body_params['status'] = 'pending'; 172 | $mc_params['body'] = json_encode($body_params); 173 | $request = wp_remote_request( $url, $mc_params ); 174 | $response = wp_remote_retrieve_body( $request ); 175 | $data = json_decode( $response, true ); 176 | 177 | // If there's an error 178 | if ( array_key_exists( 'status', $data ) && $data['status'] >= 400 ) { 179 | return new WP_REST_Response(array( 180 | 'code' => 400, 181 | 'status' => 'unsubscribed', 182 | 'message' => 'You had previously unsubscribed and cannot be resubscribed using this form.' 183 | ), 400); 184 | } 185 | 186 | // Add tags 187 | gmt_mailchimp_wp_rest_api_add_tags_to_user($tags_url, $mc_params, $params['email'], $params['tag']); 188 | 189 | // Otherwise, partial success 190 | return new WP_REST_Response(array( 191 | 'code' => 202, 192 | 'status' => 'subscribed', 193 | 'message' => 'Almost there! To complete your subscription, please click the confirmation link in the email that was just sent to your inbox.' 194 | ), 202); 195 | 196 | } 197 | 198 | // Otherwise, throw a generic error 199 | return new WP_REST_Response(array( 200 | 'code' => 400, 201 | 'status' => 'failed', 202 | 'message' => 'Unable to subscribe at this time. Please try again.' 203 | ), 400); 204 | 205 | } 206 | 207 | // Add tags 208 | gmt_mailchimp_wp_rest_api_add_tags_to_user($tags_url, $mc_params, $params['email'], $params['tag']); 209 | 210 | // Return a success message 211 | return new WP_REST_Response(array( 212 | 'code' => 200, 213 | 'status' => 'success', 214 | 'message' => 'You\'re now subscribed.' 215 | ), 200); 216 | 217 | } 218 | 219 | /** 220 | * Round a number down to nearest value (10, 100, etc) 221 | * @param Integer $num The number to round 222 | * @param Integer $precision The precision to round by 223 | * @return Integer The rounded number 224 | */ 225 | function gmt_mailchimp_wp_rest_api_round($num, $precision) { 226 | $num = intval($num); 227 | if (empty($precision)) return $num; 228 | $precision = intval($precision); 229 | return number_format(floor($num / $precision) * $precision); 230 | } 231 | 232 | 233 | /** 234 | * Get the number of total subscribers on the list 235 | * @param Array $options The API options 236 | * @param Array $params The request parameters 237 | * @return JSON The WP API response 238 | */ 239 | function gmt_mailchimp_wp_rest_api_get_all_subscribers($options, $params) { 240 | 241 | // Create API call 242 | $shards = explode( '-', $options['mailchimp_api_key'] ); 243 | $url = 'https://' . $shards[1] . '.api.mailchimp.com/3.0/lists/' . $options['mailchimp_list_id'] . '/'; 244 | $mc_params = array( 245 | 'headers' => array( 246 | 'Authorization' => 'Basic ' . base64_encode( 'mailchimp' . ':' . $options['mailchimp_api_key'] ) 247 | ), 248 | ); 249 | 250 | // Make the request 251 | $request = wp_remote_get( $url, $mc_params ); 252 | $response = wp_remote_retrieve_body( $request ); 253 | $data = json_decode( $response, true ); 254 | 255 | // If something went wrong, throw an error 256 | if ( !array_key_exists( 'stats', $data ) || !array_key_exists( 'member_count', $data['stats'] ) ) { 257 | return new WP_REST_Response(array( 258 | 'code' => 400, 259 | 'status' => 'failed', 260 | 'message' => 'Unable to get subscriber count. Please try again.' 261 | ), 400); 262 | } 263 | 264 | // Otherwise, return success 265 | return new WP_REST_Response(array( 266 | 'code' => 200, 267 | 'status' => 'success', 268 | 'message' => gmt_mailchimp_wp_rest_api_round($data['stats']['member_count'], $params['round']), 269 | ), 200); 270 | 271 | } 272 | 273 | 274 | /** 275 | * Get the number of total subscribers on the list 276 | * @param Array $options The API options 277 | * @param Array $params The request parameters 278 | * @return JSON The WP API response 279 | */ 280 | function gmt_mailchimp_wp_rest_api_get_subscribers_by_group($options, $params) { 281 | 282 | // Create API call 283 | $shards = explode( '-', $options['mailchimp_api_key'] ); 284 | $url = 'https://' . $shards[1] . '.api.mailchimp.com/3.0/lists/' . $options['mailchimp_list_id'] . '/interest-categories/' . $params['category'] . '/interests/' . $params['id']; 285 | $mc_params = array( 286 | 'headers' => array( 287 | 'Authorization' => 'Basic ' . base64_encode( 'mailchimp' . ':' . $options['mailchimp_api_key'] ) 288 | ), 289 | ); 290 | 291 | // Make the request 292 | $request = wp_remote_get( $url, $mc_params ); 293 | $response = wp_remote_retrieve_body( $request ); 294 | $data = json_decode( $response, true ); 295 | 296 | // If something went wrong, throw an error 297 | if ( !array_key_exists( 'subscriber_count', $data ) ) { 298 | return new WP_REST_Response(array( 299 | 'code' => 400, 300 | 'status' => 'failed', 301 | 'message' => 'Unable to get subscriber count. Please try again.' 302 | ), 400); 303 | } 304 | 305 | return new WP_REST_Response(array( 306 | 'code' => 200, 307 | 'status' => 'success', 308 | 'message' => gmt_mailchimp_wp_rest_api_round($data['subscriber_count'], $params['round']), 309 | ), 200); 310 | 311 | } 312 | 313 | 314 | /** 315 | * Get the subscriber count 316 | * @param Array $request The request data 317 | * @return JSON WP Response Object 318 | */ 319 | function gmt_mailchimp_wp_rest_api_subscriber_count($request) { 320 | 321 | // Variables 322 | $options = mailchimp_rest_api_get_theme_options(); 323 | $params = $request->get_params(); 324 | 325 | // Check domain whitelist 326 | if (!empty($options['origin'])) { 327 | $origin = $request->get_header('origin'); 328 | if (empty($origin) || !in_array($origin, explode(',', $options['origin']))) { 329 | return new WP_REST_Response(array( 330 | 'code' => 400, 331 | 'status' => 'disallowed_domain', 332 | 'message' => 'This domain is not whitelisted.' 333 | ), 400); 334 | } 335 | } 336 | 337 | // If not interest group details are provided, get all subscribers 338 | if (empty($params['category']) || empty($params['id'])) { 339 | return gmt_mailchimp_wp_rest_api_get_all_subscribers($options, $params); 340 | } 341 | 342 | // Otherwise, get subscribers for an interest group 343 | return gmt_mailchimp_wp_rest_api_get_subscribers_by_group($options, $params); 344 | 345 | } 346 | 347 | 348 | function gmt_mailchimp_wp_rest_api_register_routes () { 349 | 350 | // Add subscribers 351 | register_rest_route('gmt-mailchimp/v1', '/subscribe', array( 352 | 'methods' => 'POST', 353 | 'callback' => 'gmt_mailchimp_wp_rest_api_subscribe_user', 354 | )); 355 | 356 | // Get subscriber count 357 | register_rest_route('gmt-mailchimp/v1', '/count', array( 358 | 'methods' => 'GET', 359 | 'callback' => 'gmt_mailchimp_wp_rest_api_subscriber_count', 360 | )); 361 | 362 | } 363 | add_action('rest_api_init', 'gmt_mailchimp_wp_rest_api_register_routes'); -------------------------------------------------------------------------------- /includes/options.php: -------------------------------------------------------------------------------- 1 | 27 | 28 | 29 | 35 | 36 | 37 | 43 | 44 | 45 | 51 | 52 | 53 | 59 | 60 | 61 | 67 | 68 | 69 | 75 | 76 | 77 | '', 93 | 'mailchimp_list_id' => '', 94 | 'mailchimp_form_key' => '', 95 | 'mailchimp_form_secret' => '', 96 | 'mailchimp_honeypot' => '', 97 | 'mailchimp_origin' => '', 98 | 'mailchimp_blocked_emails' => '', 99 | ); 100 | 101 | $defaults = apply_filters( 'mailchimp_rest_api_default_theme_options', $defaults ); 102 | 103 | $options = wp_parse_args( $saved, $defaults ); 104 | $options = array_intersect_key( $options, $defaults ); 105 | 106 | return $options; 107 | } 108 | 109 | // Sanitize and validate updated theme options 110 | function mailchimp_rest_api_theme_options_validate( $input ) { 111 | $output = array(); 112 | 113 | if ( isset( $input['mailchimp_api_key'] ) && ! empty( $input['mailchimp_api_key'] ) ) 114 | $output['mailchimp_api_key'] = wp_filter_nohtml_kses( $input['mailchimp_api_key'] ); 115 | 116 | if ( isset( $input['mailchimp_list_id'] ) && ! empty( $input['mailchimp_list_id'] ) ) 117 | $output['mailchimp_list_id'] = wp_filter_nohtml_kses( $input['mailchimp_list_id'] ); 118 | 119 | if ( isset( $input['mailchimp_form_key'] ) && ! empty( $input['mailchimp_form_key'] ) ) 120 | $output['mailchimp_form_key'] = wp_filter_nohtml_kses( $input['mailchimp_form_key'] ); 121 | 122 | if ( isset( $input['mailchimp_form_secret'] ) && ! empty( $input['mailchimp_form_secret'] ) ) 123 | $output['mailchimp_form_secret'] = wp_filter_nohtml_kses( $input['mailchimp_form_secret'] ); 124 | 125 | if ( isset( $input['mailchimp_honeypot'] ) && ! empty( $input['mailchimp_honeypot'] ) ) 126 | $output['mailchimp_honeypot'] = wp_filter_nohtml_kses( $input['mailchimp_honeypot'] ); 127 | 128 | if ( isset( $input['mailchimp_origin'] ) && ! empty( $input['mailchimp_origin'] ) ) 129 | $output['mailchimp_origin'] = wp_filter_nohtml_kses( str_replace(' ', '', $input['mailchimp_origin']) ); 130 | 131 | if ( isset( $input['mailchimp_blocked_emails'] ) && ! empty( $input['mailchimp_blocked_emails'] ) ) 132 | $output['mailchimp_blocked_emails'] = wp_filter_nohtml_kses( str_replace(' ', '', $input['mailchimp_blocked_emails']) ); 133 | 134 | return apply_filters( 'mailchimp_rest_api_theme_options_validate', $output, $input ); 135 | } 136 | 137 | 138 | 139 | /** 140 | * Get data from the MailChimp API 141 | * @param string $group The group ID 142 | * @return array Data from the MailChimp API 143 | */ 144 | function mailchimp_rest_api_get_mailchimp_group_data($group = null) { 145 | 146 | $options = mailchimp_rest_api_get_theme_options(); 147 | 148 | if (empty($options['mailchimp_api_key']) || empty($options['mailchimp_list_id'])) return; 149 | 150 | // Create API call 151 | $shards = explode( '-', $options['mailchimp_api_key'] ); 152 | $url = 'https://' . $shards[1] . '.api.mailchimp.com/3.0/lists/' . $options['mailchimp_list_id'] . '/interest-categories' . ( empty( $group ) ? '' : '/' . $group . '/interests?count=99' ); 153 | $params = array( 154 | 'headers' => array( 155 | 'Authorization' => 'Basic ' . base64_encode( 'mailchimp' . ':' . $options['mailchimp_api_key'] ) 156 | ), 157 | ); 158 | 159 | // Get data from MailChimp 160 | $request = wp_remote_get( $url, $params ); 161 | $response = wp_remote_retrieve_body( $request ); 162 | $data = json_decode( $response, true ); 163 | 164 | // If request fails, bail 165 | if ( empty( $group ) ) { 166 | if ( !array_key_exists( 'categories', $data ) || !is_array( $data['categories'] ) || empty( $data['categories'] ) ) return array(); 167 | } else { 168 | if ( !array_key_exists( 'interests', $data ) || !is_array( $data['interests'] ) || empty( $data['interests'] ) ) return array(); 169 | } 170 | 171 | return $data; 172 | 173 | } 174 | 175 | /** 176 | * Get data from the MailChimp API 177 | * @param string $group The group ID 178 | * @return array Data from the MailChimp API 179 | */ 180 | function mailchimp_rest_api_get_mailchimp_tag_data($group = null) { 181 | 182 | $options = mailchimp_rest_api_get_theme_options(); 183 | 184 | if (empty($options['mailchimp_api_key']) || empty($options['mailchimp_list_id'])) return; 185 | 186 | // Create API call 187 | $shards = explode( '-', $options['mailchimp_api_key'] ); 188 | $url = 'https://' . $shards[1] . '.api.mailchimp.com/3.0/lists/' . $options['mailchimp_list_id'] . '/segments?type=static&count=1000'; 189 | $params = array( 190 | 'headers' => array( 191 | 'Authorization' => 'Basic ' . base64_encode( 'mailchimp' . ':' . $options['mailchimp_api_key'] ) 192 | ), 193 | ); 194 | 195 | // Get data from MailChimp 196 | $request = wp_remote_get( $url, $params ); 197 | $response = wp_remote_retrieve_body( $request ); 198 | $data = json_decode( $response, true ); 199 | 200 | // If request fails, bail 201 | // if ( empty( $group ) ) { 202 | // if ( !array_key_exists( 'categories', $data ) || !is_array( $data['categories'] ) || empty( $data['categories'] ) ) return array(); 203 | // } else { 204 | if ( !array_key_exists( 'segments', $data ) || !is_array( $data['segments'] ) || empty( $data['segments'] ) ) return array(); 205 | // } 206 | 207 | return $data; 208 | 209 | } 210 | 211 | /** 212 | * Render interest groups 213 | * @param array $details Saved data 214 | */ 215 | function mailchimp_rest_api_get_interest_groups() { 216 | 217 | // Variables 218 | $categories = mailchimp_rest_api_get_mailchimp_group_data(); 219 | $html = '

' . __('Groups', 'mailchimp_rest_api') . '

'; 220 | 221 | foreach ( $categories['categories'] as $category ) { 222 | $html .= 223 | '' . esc_html($category['title']) . ' (' . $category['id'] . ')' . 224 | '
    '; 225 | $groups = mailchimp_rest_api_get_mailchimp_group_data($category['id']); 226 | 227 | foreach ($groups['interests'] as $group) { 228 | $html .= 229 | '
  • ' . 230 | esc_html($group['name']) . ': ' . esc_attr($group['id']) . 231 | '
  • '; 232 | } 233 | $html .= '
'; 234 | 235 | } 236 | 237 | echo $html; 238 | } 239 | 240 | 241 | 242 | /** 243 | * Render interest groups 244 | * @param array $details Saved data 245 | */ 246 | function mailchimp_rest_api_get_tags() { 247 | 248 | // Variables 249 | $tags = mailchimp_rest_api_get_mailchimp_tag_data(); 250 | $html = '

' . __('Tags', 'mailchimp_rest_api') . '

'; 251 | 252 | foreach ($tags['segments'] as $tag) { 253 | $html .= '
  • ' . $tag['name'] . ': ' . $tag['id'] . '
  • '; 254 | } 255 | 256 | echo '
      ' . $html . '
    '; 257 | } 258 | 259 | 260 | 261 | /** 262 | * Theme Options Menu 263 | * Each option field requires its own add_settings_field function. 264 | */ 265 | 266 | // Create theme options menu 267 | // The content that's rendered on the menu page. 268 | function mailchimp_rest_api_theme_options_render_page() { 269 | ?> 270 |
    271 |

    272 | 273 | 274 | 281 | 282 |
    283 |