PluginProbe ʕ •ᴥ•ʔ
MC4WP: Mailchimp for WordPress / 4.1.1
MC4WP: Mailchimp for WordPress v4.1.1
4.13.0 4.12.6 4.12.4 4.12.5 4.12.3 4.12.2 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3 2.3.1 2.3.10 2.3.11 2.3.12 2.3.13 2.3.14 2.3.15 2.3.16 2.3.17 2.3.18 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.3.8 3.0.10 3.0.11 3.0.12 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.11 4.1.12 4.1.13 4.1.14 4.1.15 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.10.0 4.10.1 4.10.2 4.10.3 4.10.4 4.10.5 4.10.6 4.10.7 4.10.8 4.10.9 4.11.0 4.11.1 4.12.0 4.12.1 4.2 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.3 4.3.1 4.3.2 4.3.3 4.4 4.5.0 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.1 4.6.2 4.7 4.7.1 4.7.2 4.7.3 4.7.4 4.7.5 4.7.6 4.7.7 4.7.8 4.8 4.8.1 4.8.10 4.8.11 4.8.12 4.8.2 4.8.3 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.8.9 4.9.0 4.9.1 4.9.10 4.9.11 4.9.12 4.9.13 4.9.14 4.9.15 4.9.16 4.9.17 4.9.18 4.9.19 4.9.2 4.9.20 4.9.21 4.9.3 4.9.4 4.9.5 4.9.6 4.9.7 4.9.8 4.9.9 trunk 1.1.5 1.2.1 1.2.3 1.2.4 1.2.5 1.3 1.3.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8
mailchimp-for-wp / includes / class-mailchimp.php
mailchimp-for-wp / includes Last commit date
admin 9 years ago api 9 years ago forms 9 years ago integrations 9 years ago mailchimp 9 years ago views 9 years ago class-array-bag.php 10 years ago class-container.php 10 years ago class-debug-log-reader.php 9 years ago class-debug-log.php 9 years ago class-dynamic-content-tags.php 9 years ago class-field-formatter.php 9 years ago class-field-guesser.php 9 years ago class-list-data-mapper.php 9 years ago class-mailchimp.php 9 years ago class-plugin.php 10 years ago class-queue-job.php 10 years ago class-queue.php 9 years ago class-request.php 10 years ago class-tools.php 9 years ago class-validator.php 10 years ago class-visitor-tracking.php 9 years ago default-actions.php 9 years ago default-filters.php 9 years ago deprecated-functions.php 9 years ago functions.php 9 years ago
class-mailchimp.php
425 lines
1 <?php
2
3 /**
4 * Class MC4WP_MailChimp
5 *
6 * @access private
7 * @ignore
8 */
9 class MC4WP_MailChimp {
10
11 /**
12 * @var MC4WP_API_v3
13 */
14 public $api;
15
16 /**
17 * @var string
18 */
19 public $error_code = '';
20
21 /**
22 * @var string
23 */
24 public $error_message = '';
25
26 /**
27 * MC4WP_MailChimp constructor.
28 */
29 public function __construct() {
30 $this->api = mc4wp( 'api' );
31 }
32
33 /**
34 *
35 * Sends a subscription request to the MailChimp API
36 *
37 * @param string $list_id The list id to subscribe to
38 * @param string $email_address The email address to subscribe
39 * @param array $args
40 * @param boolean $update_existing Update information if this email is already on list?
41 * @param boolean $replace_interests Replace interest groupings, only if update_existing is true.
42 *
43 * @return object
44 */
45 public function list_subscribe( $list_id, $email_address, array $args = array(), $update_existing = false, $replace_interests = true ) {
46 $this->reset_error();
47
48 $default_args = array(
49 'status' => 'pending',
50 'email_address' => $email_address,
51 'interests' => array(),
52 'merge_fields' => array(),
53 );
54 $already_on_list = false;
55
56 // setup default args
57 $args = $args + $default_args;
58
59 // first, check if subscriber is already on the given list
60 try {
61 $existing_member_data = $this->api->get_list_member( $list_id, $email_address );
62
63 if( $existing_member_data->status === 'subscribed' ) {
64 $already_on_list = true;
65
66 // if we're not supposed to update, bail.
67 if( ! $update_existing ) {
68 $this->error_code = 214;
69 $this->error_message = 'That subscriber already exists.';
70 return null;
71 }
72
73 $args['status'] = 'subscribed';
74
75 // this key only exists if list actually has interests
76 if( isset( $existing_member_data->interests ) ) {
77 $existing_interests = (array) $existing_member_data->interests;
78
79 // if replace, assume all existing interests disabled
80 if( $replace_interests ) {
81 $existing_interests = array_fill_keys( array_keys( $existing_interests ), false );
82 }
83
84 $args['interests'] = $args['interests'] + $existing_interests;
85 }
86 } else {
87 // delete list member so we can re-add it...
88 $this->api->delete_list_member( $list_id, $email_address );
89 }
90 } catch ( MC4WP_API_Resource_Not_Found_Exception $e ) {
91 // subscriber does not exist (not an issue in this case)
92 } catch( MC4WP_API_Exception $e ) {
93 // other errors.
94 $this->error_code = $e->getCode();
95 $this->error_message = $e;
96 return null;
97 }
98
99 try {
100 $data = $this->api->add_list_member( $list_id, $args );
101 } catch ( MC4WP_API_Exception $e ) {
102 $this->error_code = $e->getCode();
103 $this->error_message = $e;
104 return null;
105 }
106
107 $data->was_already_on_list = $already_on_list;
108
109 return $data;
110 }
111
112 /**
113 *
114 * @param string $list_id
115 * @param string $email_address
116 *
117 * @return boolean
118 */
119 public function list_unsubscribe( $list_id, $email_address ) {
120 $this->reset_error();
121
122 try {
123 $this->api->update_list_member( $list_id, $email_address, array( 'status' => 'unsubscribed' ) );
124 } catch( MC4WP_API_Resource_Not_Found_Exception $e ) {
125 // if email wasn't even on the list: great.
126 return true;
127 } catch( MC4WP_API_Exception $e ) {
128 $this->error_code = $e->getCode();
129 $this->error_message = $e;
130 return false;
131 }
132
133 return true;
134 }
135
136 /**
137 * Checks if an email address is on a given list with status "subscribed"
138 *
139 * @param string $list_id
140 * @param string $email_address
141 *
142 * @return boolean
143 */
144 public function list_has_subscriber( $list_id, $email_address ) {
145 try{
146 $data = $this->api->get_list_member( $list_id, $email_address );
147 } catch( MC4WP_API_Resource_Not_Found_Exception $e ) {
148 return false;
149 }
150
151 return ! empty( $data->id ) && $data->status === 'subscribed';
152 }
153
154
155 /**
156 * Empty the Lists cache
157 */
158 public function empty_cache() {
159 delete_transient( 'mc4wp_mailchimp_lists_v3' );
160 delete_transient( 'mc4wp_list_counts' );
161 delete_option( 'mc4wp_mailchimp_lists_v3_fallback' );
162 }
163
164 /**
165 * Get MailChimp lists from cache.
166 *
167 * @param boolean $force Force a result, by hitting remote API.
168 * @return array
169 */
170 public function get_cached_lists( $force = false ) {
171
172 // then, get from option cache
173 $cached_lists = get_option( 'mc4wp_mailchimp_lists_v3_fallback' );
174 if( is_array( $cached_lists ) ) {
175 return $cached_lists;
176 }
177
178 return $force ? $this->fetch_lists() : array();
179 }
180
181 /**
182 * Get MailChimp lists, from cache or remote API.
183 *
184 * The following data sources are tried in the following order.
185 *
186 * - Transient Cache (5 days)
187 * - Remote MailChimp API
188 * - Option Cache (forever)
189 *
190 * @return array
191 */
192 public function get_lists() {
193
194 // first, try to get from transient.
195 $lists = get_transient( 'mc4wp_mailchimp_lists_v3' );
196 if( is_array( $lists ) ) {
197 return $lists;
198 }
199
200 // then, fetch from MailChimp API.
201 $lists = $this->fetch_lists();
202 if( ! empty( $lists ) ) {
203 return $lists;
204 }
205
206 // if that failed, get from option cache.
207 return $this->get_cached_lists();
208 }
209
210 /**
211 * @param string $list_id
212 *
213 * @return MC4WP_MailChimp_List
214 */
215 private function fetch_list( $list_id ) {
216 $list_data = $this->api->get_list( $list_id, array( 'fields' => 'id,name,stats' ) );
217
218 // create local object
219 $list = new MC4WP_MailChimp_List( $list_data->id, $list_data->name );
220 $list->subscriber_count = $list_data->stats->member_count;
221
222 // parse web_id from the "link" response header
223 $headers = $this->api->get_last_response_headers();
224 $link_header = $headers['link'];
225 preg_match( '/\?id=(\d+)/', $link_header, $matches );
226 if( ! empty( $matches[1] ) ) {
227 $list->web_id = $matches[1];
228 };
229
230 // get merge fields (if any)
231 if( $list_data->stats->merge_field_count > 0 ) {
232 $field_data = $this->api->get_list_merge_fields( $list->id, array( 'count' => 100, 'fields' => 'merge_fields.name,merge_fields.tag,merge_fields.type,merge_fields.required,merge_fields.default_value,merge_fields.options,merge_fields.public' ) );
233
234 // hydrate data into object
235 foreach( $field_data as $data ) {
236 $object = MC4WP_MailChimp_Merge_Field::from_data( $data );
237 $list->merge_fields[] = $object;
238 }
239 }
240
241 // get interest categories
242 $interest_categories_data = $this->api->get_list_interest_categories( $list->id, array( 'count' => 100, 'fields' => 'categories.id,categories.title,categories.type' ) );
243 foreach( $interest_categories_data as $interest_category_data ) {
244 $interest_category = MC4WP_MailChimp_Interest_Category::from_data( $interest_category_data );
245
246 // fetch groups for this interest
247 $interests_data = $this->api->get_list_interest_category_interests( $list->id, $interest_category->id, array( 'count' => 100, 'fields' => 'interests.id,interests.name') );
248 foreach( $interests_data as $interest_data ) {
249 $interest_category->interests[ $interest_data->id ] = $interest_data->name;
250 }
251
252 $list->interest_categories[] = $interest_category;
253 }
254
255 return $list;
256 }
257
258
259
260 /**
261 * @return array
262 */
263 public function fetch_lists() {
264
265 // try to increase time limit as this can take a while
266 @set_time_limit(600);
267
268 try{
269 $lists_data = $this->api->get_lists( array( 'count' => 500, 'fields' => 'lists.id' ) );
270 } catch( MC4WP_API_Exception $e ) {
271 return array();
272 }
273
274 $list_ids = wp_list_pluck( $lists_data, 'id' );
275
276 /**
277 * @var MC4WP_MailChimp_List[]
278 */
279 $lists = array();
280 foreach ( $list_ids as $list_id ) {
281 try {
282 $lists["{$list_id}"] = $this->fetch_list( $list_id );
283 } catch( MC4WP_API_Exception $e ) {
284 continue;
285 }
286 }
287
288 // store lists in transients
289 if( ! empty( $lists ) ) {
290 set_transient( 'mc4wp_mailchimp_lists_v3', $lists, ( 60 * 60 * 24 * 5 ) ); // 5 days
291 update_option( 'mc4wp_mailchimp_lists_v3_fallback', $lists, false ); // forever
292 }
293
294 return $lists;
295 }
296
297 /**
298 * Get a given MailChimp list
299 *
300 * @param string $list_id
301 *
302 * @return MC4WP_MailChimp_List
303 */
304 public function get_list( $list_id ) {
305 $lists = $this->get_cached_lists( true );
306
307 if( isset( $lists["{$list_id}"] ) ) {
308 return $lists["{$list_id}"];
309 }
310
311 return new MC4WP_MailChimp_List( '', 'Unknown List' );
312 }
313
314 /**
315 * Get an array of list_id => number of subscribers
316 *
317 * @return array
318 */
319 public function get_subscriber_counts() {
320
321 // get from transient
322 $list_counts = get_transient( 'mc4wp_list_counts' );
323 if( is_array( $list_counts ) ) {
324 return $list_counts;
325 }
326
327 // transient not valid, fetch from API
328 try {
329 $lists = $this->api->get_lists( array( 'count' => 100, 'fields' => 'lists.id,lists.stats' ) );
330 } catch( MC4WP_API_Exception $e ) {
331 return array();
332 }
333
334 $list_counts = array();
335
336 // we got a valid response
337 foreach ( $lists as $list ) {
338 $list_counts["{$list->id}"] = $list->stats->member_count;
339 }
340
341 $seconds = 3600;
342
343 /**
344 * Filters the cache time for MailChimp lists configuration, in seconds. Defaults to 3600 seconds (1 hour).
345 *
346 * @since 2.0
347 * @param int $seconds
348 */
349 $transient_lifetime = (int) apply_filters( 'mc4wp_lists_count_cache_time', $seconds );
350 set_transient( 'mc4wp_list_counts', $list_counts, $transient_lifetime );
351
352 // bail
353 return $list_counts;
354 }
355
356
357 /**
358 * Returns number of subscribers on given lists.
359 *
360 * @param array|string $list_ids Array of list ID's, or single string.
361 * @return int Total # subscribers for given lists.
362 */
363 public function get_subscriber_count( $list_ids ) {
364
365 // make sure we're getting an array
366 if( ! is_array( $list_ids ) ) {
367 $list_ids = array( $list_ids );
368 }
369
370 // if we got an empty array, return 0
371 if( empty( $list_ids ) ) {
372 return 0;
373 }
374
375 // get total number of subscribers for all lists
376 $counts = $this->get_subscriber_counts();
377
378 // start calculating subscribers count for all given list ID's combined
379 $count = 0;
380 foreach ( $list_ids as $id ) {
381 $count += ( isset( $counts["{$id}"] ) ) ? $counts["{$id}"] : 0;
382 }
383
384 /**
385 * Filters the total subscriber_count for the given List ID's.
386 *
387 * @since 2.0
388 * @param string $count
389 * @param array $list_ids
390 */
391 return apply_filters( 'mc4wp_subscriber_count', $count, $list_ids );
392 }
393
394 /**
395 * Resets error properties.
396 */
397 public function reset_error() {
398 $this->error_message = '';
399 $this->error_code = '';
400 }
401
402 /**
403 * @return bool
404 */
405 public function has_error() {
406 return ! empty( $this->error_code );
407 }
408
409 /**
410 * @return string
411 */
412 public function get_error_message() {
413 return $this->error_message;
414 }
415
416 /**
417 * @return string
418 */
419 public function get_error_code() {
420 return $this->error_code;
421 }
422
423
424 }
425