click here to set the groups again.', 'mailchimp' ),
60 | is_multisite() ? network_admin_url('settings.php') . '?page=mailchimp' : admin_url('options-general.php') . '?page=mailchimp'
61 | ); ?>
62 |
63 |
64 |
65 |
69 |
83 | " )
42 | .appendTo( this.element );
43 |
44 | this._refreshValue();
45 | },
46 |
47 | _destroy: function() {
48 | this.element
49 | .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
50 | .removeAttr( "role" )
51 | .removeAttr( "aria-valuemin" )
52 | .removeAttr( "aria-valuemax" )
53 | .removeAttr( "aria-valuenow" );
54 |
55 | this.valueDiv.remove();
56 | },
57 |
58 | value: function( newValue ) {
59 | if ( newValue === undefined ) {
60 | return this.options.value;
61 | }
62 |
63 | this.options.value = this._constrainedValue( newValue );
64 | this._refreshValue();
65 | },
66 |
67 | _constrainedValue: function( newValue ) {
68 | if ( newValue === undefined ) {
69 | newValue = this.options.value;
70 | }
71 |
72 | this.indeterminate = newValue === false;
73 |
74 | // sanitize value
75 | if ( typeof newValue !== "number" ) {
76 | newValue = 0;
77 | }
78 |
79 | return this.indeterminate ? false :
80 | Math.min( this.options.max, Math.max( this.min, newValue ) );
81 | },
82 |
83 | _setOptions: function( options ) {
84 | // Ensure "value" option is set after other values (like max)
85 | var value = options.value;
86 | delete options.value;
87 |
88 | this._super( options );
89 |
90 | this.options.value = this._constrainedValue( value );
91 | this._refreshValue();
92 | },
93 |
94 | _setOption: function( key, value ) {
95 | if ( key === "max" ) {
96 | // Don't allow a max less than min
97 | value = Math.max( this.min, value );
98 | }
99 |
100 | this._super( key, value );
101 | },
102 |
103 | _percentage: function() {
104 | return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
105 | },
106 |
107 | _refreshValue: function() {
108 | var value = this.options.value,
109 | percentage = this._percentage();
110 |
111 | this.valueDiv
112 | .toggle( this.indeterminate || value > this.min )
113 | .toggleClass( "ui-corner-right", value === this.options.max )
114 | .width( percentage.toFixed(0) + "%" );
115 |
116 | this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
117 |
118 | if ( this.indeterminate ) {
119 | this.element.removeAttr( "aria-valuenow" );
120 | if ( !this.overlayDiv ) {
121 | this.overlayDiv = $( "" ).appendTo( this.valueDiv );
122 | }
123 | } else {
124 | this.element.attr({
125 | "aria-valuemax": this.options.max,
126 | "aria-valuenow": value
127 | });
128 | if ( this.overlayDiv ) {
129 | this.overlayDiv.remove();
130 | this.overlayDiv = null;
131 | }
132 | }
133 |
134 | if ( this.oldValue !== value ) {
135 | this.oldValue = value;
136 | this._trigger( "change" );
137 | }
138 | if ( value === this.options.max ) {
139 | this._trigger( "complete" );
140 | }
141 | }
142 | });
143 | })( jQuery );
--------------------------------------------------------------------------------
/mailchimp-api/2.0/Mailchimp/Conversations.php:
--------------------------------------------------------------------------------
1 | master = $master;
6 | }
7 |
8 | /**
9 | * Retrieve conversation metadata, includes message data for the most recent message in the conversation
10 | * @param string $list_id
11 | * @param string $leid
12 | * @param string $campaign_id
13 | * @param int $start
14 | * @param int $limit
15 | * @return associative_array Conversation data and metadata
16 | * - count int Total number of conversations, irrespective of pagination.
17 | * - data array An array of structs representing individual conversations
18 | * - unique_id string A string identifying this particular conversation
19 | * - message_count int The total number of messages in this conversation
20 | * - campaign_id string The unique identifier of the campaign this conversation is associated with (will be null if the campaign has been deleted)
21 | * - list_id string The unique identifier of the list this conversation is associated with
22 | * - unread_messages int The number of messages in this conversation which have not yet been read.
23 | * - from_label string A label representing the sender of this message.
24 | * - from_email string The email address of the sender of this message.
25 | * - subject string The subject of the message.
26 | * - timestamp string Date the message was either sent or received.
27 | * - last_message associative_array The most recent message in the conversation
28 | * - from_label string A label representing the sender of this message.
29 | * - from_email string The email address of the sender of this message.
30 | * - subject string The subject of the message.
31 | * - message string The plain-text content of the message.
32 | * - read boolean Whether or not this message has been marked as read.
33 | * - timestamp string Date the message was either sent or received.
34 | */
35 | public function getList($list_id=null, $leid=null, $campaign_id=null, $start=0, $limit=25) {
36 | $_params = array("list_id" => $list_id, "leid" => $leid, "campaign_id" => $campaign_id, "start" => $start, "limit" => $limit);
37 | return $this->master->call('conversations/list', $_params);
38 | }
39 |
40 | /**
41 | * Retrieve conversation messages
42 | * @param string $conversation_id
43 | * @param boolean $mark_as_read
44 | * @param int $start
45 | * @param int $limit
46 | * @return associative_array Message data and metadata
47 | * - count int The number of messages in this conversation, irrespective of paging.
48 | * - data array An array of structs representing each message in a conversation
49 | * - from_label string A label representing the sender of this message.
50 | * - from_email string The email address of the sender of this message.
51 | * - subject string The subject of the message.
52 | * - message string The plain-text content of the message.
53 | * - read boolean Whether or not this message has been marked as read.
54 | * - timestamp string Date the message was either sent or received.
55 | */
56 | public function messages($conversation_id, $mark_as_read=false, $start=0, $limit=25) {
57 | $_params = array("conversation_id" => $conversation_id, "mark_as_read" => $mark_as_read, "start" => $start, "limit" => $limit);
58 | return $this->master->call('conversations/messages', $_params);
59 | }
60 |
61 | /**
62 | * Reply to a conversation
63 | * @param string $conversation_id
64 | * @param string $message
65 | * @return associative_array Message data from the created message
66 | * - from_label string A label representing the sender of this message.
67 | * - from_email string The email address of the sender of this message.
68 | * - subject string The subject of the message.
69 | * - message string The plain-text content of the message.
70 | * - read boolean Whether or not this message has been marked as read.
71 | * - timestamp string Date the message was either sent or received.
72 | */
73 | public function reply($conversation_id, $message) {
74 | $_params = array("conversation_id" => $conversation_id, "message" => $message);
75 | return $this->master->call('conversations/reply', $_params);
76 | }
77 |
78 | }
79 |
80 |
81 |
--------------------------------------------------------------------------------
/mailchimp-api/2.0/Mailchimp/Gallery.php:
--------------------------------------------------------------------------------
1 | master = $master;
6 | }
7 |
8 | /**
9 | * Return a section of the image gallery
10 | * @param associative_array $opts
11 | * - type string optional the gallery type to return - images or files - default to images
12 | * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
13 | * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
14 | * - sort_by string optional field to sort by - one of size, time, name - defaults to time
15 | * - sort_dir string optional field to sort by - one of asc, desc - defaults to desc
16 | * - search_term string optional a term to search for in names
17 | * - folder_id int optional to return files that are in a specific folder. id returned by the list-folders call
18 | * @return associative_array the matching gallery items
19 | * - total int the total matching items
20 | * - data array structs for each item included in the set, including:
21 | * - id int the id of the file
22 | * - name string the file name
23 | * - time string the creation date for the item
24 | * - size int the file size in bytes
25 | * - full string the url to the actual item in the gallery
26 | * - thumb string a url for a thumbnail that can be used to represent the item, generally an image thumbnail or an icon for a file type
27 | */
28 | public function getList($opts=array()) {
29 | $_params = array("opts" => $opts);
30 | return $this->master->call('gallery/list', $_params);
31 | }
32 |
33 | /**
34 | * Return a list of the folders available to the file gallery
35 | * @param associative_array $opts
36 | * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
37 | * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
38 | * - search_term string optional a term to search for in names
39 | * @return associative_array the matching gallery folders
40 | * - total int the total matching folders
41 | * - data array structs for each folder included in the set, including:
42 | * - id int the id of the folder
43 | * - name string the file name
44 | * - file_count int the number of files in the folder
45 | */
46 | public function listFolders($opts=array()) {
47 | $_params = array("opts" => $opts);
48 | return $this->master->call('gallery/list-folders', $_params);
49 | }
50 |
51 | /**
52 | * Adds a folder to the file gallery
53 | * @param string $name
54 | * @return associative_array the new data for the created folder
55 | * - data.id int the id of the new folder
56 | */
57 | public function addFolder($name) {
58 | $_params = array("name" => $name);
59 | return $this->master->call('gallery/add-folder', $_params);
60 | }
61 |
62 | /**
63 | * Remove a folder
64 | * @param int $folder_id
65 | * @return boolean true/false for success/failure
66 | */
67 | public function removeFolder($folder_id) {
68 | $_params = array("folder_id" => $folder_id);
69 | return $this->master->call('gallery/remove-folder', $_params);
70 | }
71 |
72 | /**
73 | * Add a file to a folder
74 | * @param int $file_id
75 | * @param int $folder_id
76 | * @return boolean true/false for success/failure
77 | */
78 | public function addFileToFolder($file_id, $folder_id) {
79 | $_params = array("file_id" => $file_id, "folder_id" => $folder_id);
80 | return $this->master->call('gallery/add-file-to-folder', $_params);
81 | }
82 |
83 | /**
84 | * Remove a file from a folder
85 | * @param int $file_id
86 | * @param int $folder_id
87 | * @return boolean true/false for success/failure
88 | */
89 | public function removeFileFromFolder($file_id, $folder_id) {
90 | $_params = array("file_id" => $file_id, "folder_id" => $folder_id);
91 | return $this->master->call('gallery/remove-file-from-folder', $_params);
92 | }
93 |
94 | /**
95 | * Remove all files from a folder (Note that the files are not deleted, they are only removed from the folder)
96 | * @param int $folder_id
97 | * @return boolean true/false for success/failure
98 | */
99 | public function removeAllFilesFromFolder($folder_id) {
100 | $_params = array("folder_id" => $folder_id);
101 | return $this->master->call('gallery/remove-all-files-from-folder', $_params);
102 | }
103 |
104 | }
105 |
106 |
107 |
--------------------------------------------------------------------------------
/mailchimp-api/3.0/Mailchimp/Batch.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | class Mailchimp_Sync_Batch
10 | {
11 | /**
12 | * @var MailChimp_Sync_Mailchimp
13 | */
14 | private $MailChimp;
15 |
16 | private $operations = array();
17 | private $batch_id;
18 |
19 | public function __construct($MailChimp, $batch_id = null)
20 | {
21 | $this->MailChimp = $MailChimp;
22 | $this->batch_id = $batch_id;
23 | }
24 |
25 | /**
26 | * Add an HTTP DELETE request operation to the batch - for deleting data
27 | * @param string $id ID for the operation within the batch
28 | * @param string $method URL of the API request method
29 | * @return void
30 | */
31 | public function delete($id, $method)
32 | {
33 | $this->queueOperation('DELETE', $id, $method);
34 | }
35 |
36 | /**
37 | * Add an HTTP GET request operation to the batch - for retrieving data
38 | * @param string $id ID for the operation within the batch
39 | * @param string $method URL of the API request method
40 | * @param array $args Assoc array of arguments (usually your data)
41 | * @return void
42 | */
43 | public function get($id, $method, $args = array())
44 | {
45 | $this->queueOperation('GET', $id, $method, $args);
46 | }
47 |
48 | /**
49 | * Add an HTTP PATCH request operation to the batch - for performing partial updates
50 | * @param string $id ID for the operation within the batch
51 | * @param string $method URL of the API request method
52 | * @param array $args Assoc array of arguments (usually your data)
53 | * @return void
54 | */
55 | public function patch($id, $method, $args = array())
56 | {
57 | $this->queueOperation('PATCH', $id, $method, $args);
58 | }
59 |
60 | /**
61 | * Add an HTTP POST request operation to the batch - for creating and updating items
62 | * @param string $id ID for the operation within the batch
63 | * @param string $method URL of the API request method
64 | * @param array $args Assoc array of arguments (usually your data)
65 | * @return void
66 | */
67 | public function post($id, $method, $args = array())
68 | {
69 | $this->queueOperation('POST', $id, $method, $args);
70 | }
71 |
72 | /**
73 | * Add an HTTP PUT request operation to the batch - for creating new items
74 | * @param string $id ID for the operation within the batch
75 | * @param string $method URL of the API request method
76 | * @param array $args Assoc array of arguments (usually your data)
77 | * @return void
78 | */
79 | public function put($id, $method, $args = array())
80 | {
81 | $this->queueOperation('PUT', $id, $method, $args);
82 | }
83 |
84 | /**
85 | * Execute the batch request
86 | * @param int $timeout Request timeout in seconds (optional)
87 | * @return array|false Assoc array of API response, decoded from JSON
88 | */
89 | public function execute($timeout = 10)
90 | {
91 | $req = array('operations' => $this->operations);
92 |
93 | $result = $this->MailChimp->post('batches', $req, $timeout);
94 |
95 | if ($result && isset($result['id'])) {
96 | $this->batch_id = $result['id'];
97 | }
98 |
99 | return $result;
100 | }
101 |
102 | /**
103 | * Check the status of a batch request. If the current instance of the Batch object
104 | * was used to make the request, the batch_id is already known and is therefore optional.
105 | * @param string $batch_id ID of the batch about which to enquire
106 | * @return array|false Assoc array of API response, decoded from JSON
107 | */
108 | public function check_status($batch_id = null)
109 | {
110 | if ($batch_id === null && $this->batch_id) {
111 | $batch_id = $this->batch_id;
112 | }
113 |
114 | return $this->MailChimp->get('batches/' . $batch_id);
115 | }
116 |
117 | /**
118 | * Add an operation to the internal queue.
119 | * @param string $http_verb GET, POST, PUT, PATCH or DELETE
120 | * @param string $id ID for the operation within the batch
121 | * @param string $method URL of the API request method
122 | * @param array $args Assoc array of arguments (usually your data)
123 | * @return void
124 | */
125 | private function queueOperation($http_verb, $id, $method, $args = null)
126 | {
127 | $operation = array(
128 | 'operation_id' => $id,
129 | 'method' => $http_verb,
130 | 'path' => $method,
131 | );
132 |
133 | if ($args) {
134 | $key = ($http_verb == 'GET' ? 'params' : 'body');
135 | $operation[$key] = json_encode($args);
136 | }
137 |
138 | $this->operations[] = $operation;
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/mailchimp-api/2.0/Mailchimp/Users.php:
--------------------------------------------------------------------------------
1 | master = $master;
6 | }
7 |
8 | /**
9 | * Invite a user to your account
10 | * @param string $email
11 | * @param string $role
12 | * @param string $msg
13 | * @return associative_array the method completion status
14 | * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
15 | */
16 | public function invite($email, $role='viewer', $msg='') {
17 | $_params = array("email" => $email, "role" => $role, "msg" => $msg);
18 | return $this->master->call('users/invite', $_params);
19 | }
20 |
21 | /**
22 | * Resend an invite a user to your account. Note, if the same address has been invited multiple times, this will simpy re-send the most recent invite
23 | * @param string $email
24 | * @return associative_array the method completion status
25 | * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
26 | */
27 | public function inviteResend($email) {
28 | $_params = array("email" => $email);
29 | return $this->master->call('users/invite-resend', $_params);
30 | }
31 |
32 | /**
33 | * Revoke an invitation sent to a user to your account. Note, if the same address has been invited multiple times, this will simpy revoke the most recent invite
34 | * @param string $email
35 | * @return associative_array the method completion status
36 | * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
37 | */
38 | public function inviteRevoke($email) {
39 | $_params = array("email" => $email);
40 | return $this->master->call('users/invite-revoke', $_params);
41 | }
42 |
43 | /**
44 | * Retrieve the list of pending users invitations have been sent for.
45 | * @return array structs for each invitation, including:
46 | * - email string the email address the invitation was sent to
47 | * - role string the role that will be assigned if they accept
48 | * - sent_at string the time the invitation was sent. this will change if it's resent.
49 | * - expiration string the expiration time for the invitation. this will change if it's resent.
50 | * - msg string the welcome message included with the invitation
51 | */
52 | public function invites() {
53 | $_params = array();
54 | return $this->master->call('users/invites', $_params);
55 | }
56 |
57 | /**
58 | * Revoke access for a specified login
59 | * @param string $username
60 | * @return associative_array the method completion status
61 | * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
62 | */
63 | public function loginRevoke($username) {
64 | $_params = array("username" => $username);
65 | return $this->master->call('users/login-revoke', $_params);
66 | }
67 |
68 | /**
69 | * Retrieve the list of active logins.
70 | * @return array structs for each user, including:
71 | * - id int the login id for this login
72 | * - username string the username used to log in
73 | * - name string a display name for the account - empty first/last names will return the username
74 | * - email string the email tied to the account used for passwords resets and the ilk
75 | * - role string the role assigned to the account
76 | * - avatar string if available, the url for the login's avatar
77 | * - global_user_id int the globally unique user id for the user account connected to
78 | * - dc_unique_id string the datacenter unique id for the user account connected to, like helper/account-details
79 | */
80 | public function logins() {
81 | $_params = array();
82 | return $this->master->call('users/logins', $_params);
83 | }
84 |
85 | /**
86 | * Retrieve the profile for the login owning the provided API Key
87 | * @return associative_array the current user's details, including:
88 | * - id int the login id for this login
89 | * - username string the username used to log in
90 | * - name string a display name for the account - empty first/last names will return the username
91 | * - email string the email tied to the account used for passwords resets and the ilk
92 | * - role string the role assigned to the account
93 | * - avatar string if available, the url for the login's avatar
94 | * - global_user_id int the globally unique user id for the user account connected to
95 | * - dc_unique_id string the datacenter unique id for the user account connected to, like helper/account-details
96 | * - account_name string The name of the account to which the API key belongs
97 | */
98 | public function profile() {
99 | $_params = array();
100 | return $this->master->call('users/profile', $_params);
101 | }
102 |
103 | }
104 |
105 |
106 |
--------------------------------------------------------------------------------
/front/form.class.php:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 |
25 |
30 |
31 |
32 | admin_url( 'admin-ajax.php' ),
45 | 'nonce' => wp_create_nonce( "mailchimp_subscribe_user" )
46 | );
47 | wp_localize_script( 'mailchimp-form-js', 'mailchimp_form_captions', $l10n );
48 |
49 | add_action( 'wp_footer', array( 'WPMUDEV_MailChimp_Form', 'enqueue_scripts' ) );
50 |
51 | }
52 |
53 |
54 | public static function enqueue_scripts() {
55 | wp_enqueue_script( 'mailchimp-form-js' );
56 | }
57 |
58 |
59 | public static function render_form( $args ) {
60 | $defaults = array(
61 | 'submit_name' => 'submit-subscribe-user',
62 | 'button_text' => '',
63 | 'form_id' => '',
64 | 'subscribed_placeholder' => '',
65 | 'text' => '',
66 | 'subscribed' => false,
67 | 'firstname' => '',
68 | 'lastname' => '',
69 | 'email' => '',
70 | 'errors' => array(),
71 | 'form_class' => '',
72 | 'require_fn' => false,
73 | 'require_ln' => false
74 | );
75 |
76 | $args = wp_parse_args( $args, $defaults );
77 | extract( $args );
78 |
79 | $require_fn = $require_fn ? 1 : 0;
80 | $require_ln = $require_ln ? 1 : 0;
81 | include( apply_filters( 'mailchimp_form_template_location', MAILCHIMP_PLUGIN_DIR . 'front/form-template.php' ) );
82 | }
83 |
84 | public static function validate_ajax_form() {
85 |
86 | check_ajax_referer( 'mailchimp_subscribe_user_' . $_POST['form_id'] . $_POST['require_fn'] . $_POST['require_ln'] );
87 |
88 | $errors = self::validate_subscription_form(
89 | $_POST,
90 | array(
91 | 'require_firstname' => (bool)$_POST['require_fn'],
92 | 'require_lastname' => (bool)$_POST['require_ln']
93 | )
94 | );
95 |
96 | if ( ! empty( $errors ) )
97 | wp_send_json_error( array( 'errors' => $errors ) );
98 |
99 |
100 | $user['email'] = sanitize_email( $_POST['subscription-email'] );
101 | $user['first_name'] = sanitize_text_field( $_POST['subscription-firstname'] );
102 | $user['last_name'] = sanitize_text_field( $_POST['subscription-lastname'] );
103 |
104 | $results = mailchimp_sync()->mailchimp_add_user( $user );
105 |
106 | wp_send_json_success( $results );
107 |
108 | die();
109 | }
110 |
111 | public static function validate_subscription_form( $input, $settings ) {
112 | $default_settings = array(
113 | 'require_firstname' => false,
114 | 'require_lastname' => false
115 | );
116 |
117 |
118 | $errors = array();
119 |
120 | $settings = wp_parse_args( $settings, $default_settings );
121 |
122 | $email = sanitize_email( $input['subscription-email'] );
123 | if ( ! is_email( $email ) )
124 | $errors[] = ( __( 'Please, insert a valid email', MAILCHIMP_LANG_DOMAIN ) );
125 |
126 | $firstname = sanitize_text_field( $input['subscription-firstname'] );
127 | $firstname = ! empty( $firstname ) ? $firstname : '';
128 | if ( empty( $firstname ) && $settings['require_firstname'] )
129 | $errors[] = ( __( 'First name is required', MAILCHIMP_LANG_DOMAIN ) );
130 |
131 |
132 | $lastname = sanitize_text_field( $input['subscription-lastname'] );
133 | $lastname = ! empty( $lastname ) ? $lastname : '';
134 | if ( empty( $lastname ) && $settings['require_lastname'] )
135 | $errors[] = ( __( 'Last name is required', MAILCHIMP_LANG_DOMAIN ) );
136 |
137 | // Check if user is already subscribed and confirmed
138 | $is_subscribed = mailchimp_30_get_user_info( $email );
139 | if ( $is_subscribed && $is_subscribed['status'] === 'subscribed' )
140 | $errors[] = ( __( 'The email is already in the subscription list', MAILCHIMP_LANG_DOMAIN ) );
141 |
142 | return apply_filters( 'mailchimp_form_validate', $errors );
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/mailchimp-api/2.0/mailchimp-api-2.0.php:
--------------------------------------------------------------------------------
1 | apikey = $apikey;
37 | $dc = "us1";
38 |
39 | if ( strstr( $this->apikey, "-" ) ) {
40 | list( $key, $dc ) = explode( "-", $this->apikey, 2 );
41 | if ( ! $dc )
42 | $dc = "us1";
43 | }
44 |
45 | $this->root = str_replace('https://api', 'https://' . $dc . '.api', $this->root);
46 | $this->root = rtrim($this->root, '/') . '/';
47 |
48 | $defaults = array(
49 | 'debug' => false,
50 | 'ssl_verifypeer' => true,
51 | 'ssl_verifyhost' => 2,
52 | 'ssl_cainfo' => null
53 | );
54 |
55 | $opts = wp_parse_args( $opts, $defaults );
56 |
57 | $this->debug = $opts['debug'];
58 |
59 | if ( isset( $opts['timeout'] ) )
60 | $this->timeout = absint( $opts['timeout'] );
61 |
62 | $this->ssl_verifypeer = $opts['ssl_verifypeer'];
63 | $this->ssl_verifyhost = $opts['ssl_verifyhost'];
64 | $this->ssl_cainfo = $opts['ssl_cainfo'];
65 |
66 | $this->folders = new Mailchimp_Folders($this);
67 | $this->templates = new Mailchimp_Templates($this);
68 | $this->users = new Mailchimp_Users($this);
69 | $this->helper = new Mailchimp_Helper($this);
70 | $this->mobile = new Mailchimp_Mobile($this);
71 | $this->conversations = new Mailchimp_Conversations($this);
72 | $this->ecomm = new Mailchimp_Ecomm($this);
73 | $this->neapolitan = new Mailchimp_Neapolitan($this);
74 | $this->lists = new Mailchimp_Lists($this);
75 | $this->campaigns = new Mailchimp_Campaigns($this);
76 | $this->vip = new Mailchimp_Vip($this);
77 | $this->reports = new Mailchimp_Reports($this);
78 | $this->gallery = new Mailchimp_Gallery($this);
79 | $this->goal = new Mailchimp_Goal($this);
80 | }
81 |
82 | public function call( $url, $params ) {
83 | $params['apikey'] = $this->apikey;
84 |
85 | $params = json_encode($params);
86 |
87 | $args = array(
88 | 'timeout' => $this->timeout,
89 | 'user-agent' => 'MailChimp-PHP/2.0.4',
90 | 'blocking' => true,
91 | 'headers' => array( 'Content-Type' => 'application/json' ),
92 | 'body' => $params,
93 | 'sslverify' => $this->ssl_verifypeer,
94 | 'filename' => null
95 | );
96 |
97 | $args = apply_filters( 'mailchimp_request_args', $args );
98 |
99 | if ( $this->ssl_cainfo )
100 | $args['sslcertificates'] = $this->ssl_cainfo;
101 |
102 | $response = wp_remote_post( $this->root . $url . '.json', $args );
103 |
104 | if ( is_wp_error( $response ) ) {
105 | $this->log_errors(
106 | array( array(
107 | 'code' => $response->get_error_code(),
108 | 'message' => $response->get_error_message()
109 | ) )
110 | );
111 | return $response;
112 | }
113 |
114 | $response_body = wp_remote_retrieve_body( $response );
115 |
116 | $result = json_decode($response_body, true);
117 |
118 | if( floor( $response['response']['code'] / 100 ) >= 4 ) {
119 | $error = $this->castError($result);
120 | $this->log_errors(
121 | array( array(
122 | 'code' => $error->getCode(),
123 | 'message' => $error->getMessage()
124 | ) )
125 | );
126 | return new WP_Error( $error->getCode(), $error->getMessage() );
127 | }
128 |
129 | return $result;
130 | }
131 |
132 | public function log_errors( $errors ) {
133 | if ( ! is_array( $errors ) )
134 | $errors = array( $errors );
135 |
136 | $current_log = get_site_option( 'mailchimp_error_log' );
137 | $new_log = array();
138 |
139 |
140 | foreach ( $errors as $error ) {
141 |
142 | $code = isset( $error['code'] ) ? $error['code'] : 0;
143 | $message = isset( $error['message'] ) ? $error['message'] : '';
144 | $email = isset( $error['email'] ) ? $error['email'] : '';
145 | $date = date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), current_time( 'timestamp' ) );
146 |
147 | $new_log[] = compact( 'code', 'message', 'email', 'date' );
148 |
149 | }
150 |
151 |
152 | if ( $current_log ) {
153 |
154 | $new_log = array_merge( $current_log, $new_log );
155 |
156 | // We'll only saved the last X lines of the log
157 | $count = count( $new_log );
158 | if ( $count > MAILCHIMP_MAX_LOG_LINES ) {
159 | $new_log = array_slice( $new_log, $count - $offset - 1 );
160 | }
161 |
162 | }
163 |
164 | update_site_option( 'mailchimp_error_log', $new_log );
165 | }
166 | }
--------------------------------------------------------------------------------
/mailchimp-api/2.0/Mailchimp/Ecomm.php:
--------------------------------------------------------------------------------
1 | master = $master;
6 | }
7 |
8 | /**
9 | * Import Ecommerce Order Information to be used for Segmentation. This will generally be used by ecommerce package plugins
10 | provided by us or by 3rd part system developers.
11 | * @param associative_array $order
12 | * - id string the Order Id
13 | * - campaign_id string optional the Campaign Id to track this order against (see the "mc_cid" query string variable a campaign passes)
14 | * - email_id string optional (kind of) the Email Id of the subscriber we should attach this order to (see the "mc_eid" query string variable a campaign passes) - required if campaign_id is passed, otherwise either this or email is required. If both are provided, email_id takes precedence
15 | * - email string optional (kind of) the Email Address we should attach this order to - either this or email_id is required. If both are provided, email_id takes precedence
16 | * - total double The Order Total (ie, the full amount the customer ends up paying)
17 | * - order_date string optional the date of the order - if this is not provided, we will default the date to now. Should be in the format of 2012-12-30
18 | * - shipping double optional the total paid for Shipping Fees
19 | * - tax double optional the total tax paid
20 | * - store_id string a unique id for the store sending the order in (32 bytes max)
21 | * - store_name string optional a "nice" name for the store - typically the base web address (ie, "store.mailchimp.com"). We will automatically update this if it changes (based on store_id)
22 | * - items array structs for each individual line item including:
23 | * - line_num int optional the line number of the item on the order. We will generate these if they are not passed
24 | * - product_id int the store's internal Id for the product. Lines that do no contain this will be skipped
25 | * - sku string optional the store's internal SKU for the product. (max 30 bytes)
26 | * - product_name string the product name for the product_id associated with this item. We will auto update these as they change (based on product_id) (max 500 bytes)
27 | * - category_id int (required) the store's internal Id for the (main) category associated with this product. Our testing has found this to be a "best guess" scenario
28 | * - category_name string (required) the category name for the category_id this product is in. Our testing has found this to be a "best guess" scenario. Our plugins walk the category heirarchy up and send "Root - SubCat1 - SubCat4", etc.
29 | * - qty double optional the quantity of the item ordered - defaults to 1
30 | * - cost double optional the cost of a single item (ie, not the extended cost of the line) - defaults to 0
31 | * @return associative_array with a single entry:
32 | * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
33 | */
34 | public function orderAdd($order) {
35 | $_params = array("order" => $order);
36 | return $this->master->call('ecomm/order-add', $_params);
37 | }
38 |
39 | /**
40 | * Delete Ecommerce Order Information used for segmentation. This will generally be used by ecommerce package plugins
41 | that we provide or by 3rd part system developers.
42 | * @param string $store_id
43 | * @param string $order_id
44 | * @return associative_array with a single entry:
45 | * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
46 | */
47 | public function orderDel($store_id, $order_id) {
48 | $_params = array("store_id" => $store_id, "order_id" => $order_id);
49 | return $this->master->call('ecomm/order-del', $_params);
50 | }
51 |
52 | /**
53 | * Retrieve the Ecommerce Orders for an account
54 | * @param string $cid
55 | * @param int $start
56 | * @param int $limit
57 | * @param string $since
58 | * @return associative_array the total matching orders and the specific orders for the requested page
59 | * - total int the total matching orders
60 | * - data array structs for each order being returned
61 | * - store_id string the store id generated by the plugin used to uniquely identify a store
62 | * - store_name string the store name collected by the plugin - often the domain name
63 | * - order_id string the internal order id the store tracked this order by
64 | * - email string the email address that received this campaign and is associated with this order
65 | * - order_total double the order total
66 | * - tax_total double the total tax for the order (if collected)
67 | * - ship_total double the shipping total for the order (if collected)
68 | * - order_date string the date the order was tracked - from the store if possible, otherwise the GMT time we received it
69 | * - items array structs for each line item on this order.:
70 | * - line_num int the line number
71 | * - product_id int the product id
72 | * - product_name string the product name
73 | * - product_sku string the sku for the product
74 | * - product_category_id int the category id for the product
75 | * - product_category_name string the category name for the product
76 | * - qty int the quantity ordered
77 | * - cost double the cost of the item
78 | */
79 | public function orders($cid=null, $start=0, $limit=100, $since=null) {
80 | $_params = array("cid" => $cid, "start" => $start, "limit" => $limit, "since" => $since);
81 | return $this->master->call('ecomm/orders', $_params);
82 | }
83 |
84 | }
85 |
86 |
87 |
--------------------------------------------------------------------------------
/mailchimp-api/2.0/Mailchimp/Vip.php:
--------------------------------------------------------------------------------
1 | master = $master;
6 | }
7 |
8 | /**
9 | * Retrieve all Activity (opens/clicks) for VIPs over the past 10 days
10 | * @return array structs for each activity recorded.
11 | * - action string The action taken - either "open" or "click"
12 | * - timestamp string The datetime the action occurred in GMT
13 | * - url string IF the action is a click, the url that was clicked
14 | * - unique_id string The campaign_id of the List the Member appears on
15 | * - title string The campaign title
16 | * - list_name string The name of the List the Member appears on
17 | * - list_id string The id of the List the Member appears on
18 | * - email string The email address of the member
19 | * - fname string IF a FNAME merge field exists on the list, that value for the member
20 | * - lname string IF a LNAME merge field exists on the list, that value for the member
21 | * - member_rating int the rating of the subscriber. This will be 1 - 5 as described here
22 | * - member_since string the datetime the member was added and/or confirmed
23 | * - geo associative_array the geographic information if we have it. including:
24 | * - latitude string the latitude
25 | * - longitude string the longitude
26 | * - gmtoff string GMT offset
27 | * - dstoff string GMT offset during daylight savings (if DST not observered, will be same as gmtoff
28 | * - timezone string the timezone we've place them in
29 | * - cc string 2 digit ISO-3166 country code
30 | * - region string generally state, province, or similar
31 | */
32 | public function activity() {
33 | $_params = array();
34 | return $this->master->call('vip/activity', $_params);
35 | }
36 |
37 | /**
38 | * Add VIPs (previously called Golden Monkeys)
39 | * @param string $id
40 | * @param array $emails
41 | * - email string an email address - for new subscribers obviously this should be used
42 | * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
43 | * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
44 | * @return associative_array of data and success/error counts
45 | * - success_count int the number of successful adds
46 | * - error_count int the number of unsuccessful adds
47 | * - errors array array of error structs including:
48 | * - email associative_array whatever was passed in the email parameter
49 | * - email string the email address added
50 | * - euid string the email unique id
51 | * - leid string the list member's truly unique id
52 | * - code string the error code
53 | * - error string the error message
54 | * - data array array of structs for each member added
55 | * - email associative_array whatever was passed in the email parameter
56 | * - email string the email address added
57 | * - euid string the email unique id
58 | * - leid string the list member's truly unique id
59 | */
60 | public function add($id, $emails) {
61 | $_params = array("id" => $id, "emails" => $emails);
62 | return $this->master->call('vip/add', $_params);
63 | }
64 |
65 | /**
66 | * Remove VIPs - this does not affect list membership
67 | * @param string $id
68 | * @param array $emails
69 | * - email string an email address - for new subscribers obviously this should be used
70 | * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
71 | * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
72 | * @return associative_array of data and success/error counts
73 | * - success_count int the number of successful deletions
74 | * - error_count int the number of unsuccessful deletions
75 | * - errors array array of error structs including:
76 | * - email associative_array whatever was passed in the email parameter
77 | * - email string the email address
78 | * - euid string the email unique id
79 | * - leid string the list member's truly unique id
80 | * - code string the error code
81 | * - msg string the error message
82 | * - data array array of structs for each member deleted
83 | * - email associative_array whatever was passed in the email parameter
84 | * - email string the email address
85 | * - euid string the email unique id
86 | * - leid string the list member's truly unique id
87 | */
88 | public function del($id, $emails) {
89 | $_params = array("id" => $id, "emails" => $emails);
90 | return $this->master->call('vip/del', $_params);
91 | }
92 |
93 | /**
94 | * Retrieve all Golden Monkey(s) for an account
95 | * @return array structs for each Golden Monkey, including:
96 | * - list_id string The id of the List the Member appears on
97 | * - list_name string The name of the List the Member appears on
98 | * - email string The email address of the member
99 | * - fname string IF a FNAME merge field exists on the list, that value for the member
100 | * - lname string IF a LNAME merge field exists on the list, that value for the member
101 | * - member_rating int the rating of the subscriber. This will be 1 - 5 as described here
102 | * - member_since string the datetime the member was added and/or confirmed
103 | */
104 | public function members() {
105 | $_params = array();
106 | return $this->master->call('vip/members', $_params);
107 | }
108 |
109 | }
110 |
111 |
112 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 | require('load-grunt-tasks')(grunt);
3 | grunt.initConfig({
4 | pkg: grunt.file.readJSON('package.json'),
5 |
6 | checktextdomain: {
7 | options:{
8 | report_missing: false,
9 | text_domain: 'mailchimp',
10 | keywords: [
11 | '__:1,2d',
12 | '_e:1,2d',
13 | '_x:1,2c,3d',
14 | 'esc_html__:1,2d',
15 | 'esc_html_e:1,2d',
16 | 'esc_html_x:1,2c,3d',
17 | 'esc_attr__:1,2d',
18 | 'esc_attr_e:1,2d',
19 | 'esc_attr_x:1,2c,3d',
20 | '_ex:1,2c,3d',
21 | '_n:1,2,4d',
22 | '_nx:1,2,4c,5d',
23 | '_n_noop:1,2,3d',
24 | '_nx_noop:1,2,3c,4d'
25 | ]
26 | },
27 | files: {
28 | src: [
29 | '**/*.php', // Include all files
30 | '!node_modules/**', // Exclude node_modules/
31 | '!tests/**', // Exclude tests/
32 | '!admin/assets/shared-ui/**', // Exclude WPMU DEV Shared UI
33 | '!externals/**',
34 | '!tmp/**'
35 | ],
36 | expand: true
37 | }
38 | },
39 |
40 | copy: {
41 | main: {
42 | src: [
43 | '**',
44 | '!npm-debug.log',
45 | '!node_modules/**',
46 | '!build/**',
47 | '!bin/**',
48 | '!.git/**',
49 | '!Gruntfile.js',
50 | '!package.json',
51 | '!.gitignore',
52 | '!.gitmodules',
53 | '!sourceMap.map',
54 | '!phpunit.xml.dist',
55 | '!travis.yml',
56 | '!tests/**',
57 | '!**/Gruntfile.js',
58 | '!**/package.json',
59 | '!**/README.md',
60 | '!lite-vs-pro.txt',
61 | '!composer.json',
62 | '!vendor/**',
63 | '!tmp/**',
64 | '!**/*~'
65 | ],
66 | dest: 'build/<%= pkg.name %>/'
67 | }
68 | },
69 |
70 | // Generate POT files.
71 | makepot: {
72 | options: {
73 | type: 'wp-plugin',
74 | domainPath: 'languages',
75 | potHeaders: {
76 | 'report-msgid-bugs-to': 'https://wpmudev.org',
77 | 'language-team': 'LANGUAGE '
78 | }
79 | },
80 | dist: {
81 | options: {
82 | potFilename: 'mailchimp.pot',
83 | exclude: [
84 | 'tests/.*',
85 | 'node_modules/.*',
86 | 'includes/external/*'
87 | ]
88 | }
89 | }
90 | },
91 |
92 | clean: {
93 | main: ['build/*']
94 | },
95 |
96 | compress: {
97 | main: {
98 | options: {
99 | mode: 'zip',
100 | archive: './build/<%= pkg.name %>-<%= pkg.version %>.zip'
101 | },
102 | expand: true,
103 | cwd: 'build/<%= pkg.name %>/',
104 | src: ['**/*'],
105 | dest: '<%= pkg.name %>/'
106 | }
107 | },
108 |
109 | search: {
110 | files: {
111 | src: ['<%= pkg.main %>']
112 | },
113 | options: {
114 | logFile: 'tmp/log-search.log',
115 | searchString: /^[ \t\/*#@]*Version:(.*)$/mig,
116 | onMatch: function(match) {
117 | var regExp = /^[ \t\/*#@]*Version:(.*)$/mig;
118 | var groupedMatches = regExp.exec( match.match );
119 | var versionFound = groupedMatches[1].trim();
120 | if ( versionFound != grunt.file.readJSON('package.json').version ) {
121 | grunt.fail.fatal("Plugin version does not match with package.json version. Please, fix.");
122 | }
123 | },
124 | onComplete: function( matches ) {
125 | if ( ! matches.numMatches ) {
126 | if ( ! grunt.file.readJSON('package.json').main ) {
127 | grunt.fail.fatal("main field is not defined in package.json. Please, add the plugin main file on that field.");
128 | }
129 | else {
130 | grunt.fail.fatal("Version Plugin header not found in " + grunt.file.readJSON('package.json').main + " file or the file does not exist" );
131 | }
132 |
133 | }
134 | }
135 | }
136 | },
137 |
138 | open: {
139 | dev : {
140 | path: '<%= pkg.projectEditUrl %>',
141 | app: 'Google Chrome'
142 | }
143 | }
144 | });
145 |
146 | grunt.loadNpmTasks('grunt-search');
147 |
148 | grunt.registerTask( 'finish', function() {
149 | var json = grunt.file.readJSON('package.json');
150 | var file = './build/' + json.name + '-' + json.version + '.zip';
151 | grunt.log.writeln( 'Process finished. Browse now to: ' + json.projectEditUrl['green'].bold );
152 | grunt.log.writeln( 'And upload the zip file under: ' + file['green'].bold);
153 | grunt.log.writeln('----------');
154 | grunt.log.writeln('');
155 | grunt.log.writeln( 'Remember to tag this new version:' );
156 |
157 | var tagMessage = 'git tag -a ' + json.version + ' -m "$CHANGELOG"';
158 | var pushMessage = 'git push -u origin ' + json.version;
159 | grunt.log.writeln( tagMessage['green'] );
160 | grunt.log.writeln( pushMessage['green'] );
161 | grunt.log.writeln('----------');
162 | });
163 |
164 | grunt.registerTask('version-compare', [ 'search' ] );
165 |
166 | grunt.registerTask('build', [
167 | 'version-compare',
168 | 'clean',
169 | 'checktextdomain',
170 | 'makepot',
171 | 'copy',
172 | 'compress'
173 | ]);
174 | };
175 |
--------------------------------------------------------------------------------
/admin/assets/mailchimp-admin.js:
--------------------------------------------------------------------------------
1 | window.MailChimp = {
2 | options: {},
3 |
4 | /**
5 | * Save the responses in every iteration so
6 | * bulk status can be checked at the end of the process
7 | */
8 | bulkActions: [],
9 | progressbar:null,
10 | $progressLabel:null,
11 | processing: false,
12 | page: 1,
13 | stats: {
14 | added:0,
15 | updated:0,
16 | errors:0,
17 | total:0
18 | },
19 | init: function( options ) {
20 | if ( this.processing ) {
21 | // We are already processing
22 | return this;
23 | }
24 |
25 | var labels = jQuery.extend( {
26 | }, options.labels || {
27 | initializing: 'Initializing...',
28 | processed: 'Processed %s / %s',
29 | checkOperation: 'Checking bulk action result, operation: %s',
30 | downloadMoreInfo: 'Download more info about bulk operation',
31 | results: 'Results: Total: %s. Errors: %s'
32 | } );
33 |
34 | this.options = jQuery.extend( {
35 | total: 0,
36 | nonce: '',
37 | progressbar: '',
38 | labels: labels,
39 | progressLabel: ''
40 | }, options );
41 |
42 | this.$el = jQuery( this.options.progressbar );
43 | this.$progressLabel = jQuery( this.options.progressLabel );
44 |
45 | this.processing = true;
46 | this.showProgressBar();
47 | this.process();
48 | return this;
49 | },
50 | showProgressBar: function() {
51 | this.progressbar = this.$el.progressbar();
52 | this.progressbar.progressbar('option', 'value',false);
53 | this.setLabel( this.options.labels.initializing );
54 | this.$progressLabel.show();
55 | },
56 |
57 | process() {
58 | if ( this.getStat( 'total' ) >= this.options.total ) {
59 | // Check bulks and finish the process
60 | this.checkBulkResults();
61 | return false;
62 | }
63 |
64 | var mc = this;
65 |
66 | this.call( {
67 | action:'mailchimp_import',
68 | page: mc.page
69 | })
70 | .done( function(response) {
71 | if ( ! response.success ) {
72 | alert( response.data.message );
73 | mc.stop();
74 | }
75 | else {
76 | mc.page++;
77 | mc.updateStat( 'total', mc.getStat( 'total' ) + response.data.processed );
78 | mc.addBulkAction(response.data.bulkInfo.operation, response.data.bulkInfo.users );
79 |
80 | var total = mc.getStat( 'total' );
81 | mc.setLabel( mc.options.labels.processed, Math.min( total, mc.options.total ), mc.options.total );
82 | mc.process();
83 | }
84 | });
85 | },
86 |
87 | checkBulkResults: function() {
88 | var action = this.getNextUncheckedBulkAction();
89 | if ( ! action ) {
90 | this.finish();
91 | return;
92 | }
93 |
94 | this.setLabel( this.options.labels.checkOperation, action.operation );
95 | var mc = this;
96 |
97 | this.call({
98 | action: 'mailchimp_check_bulk_results',
99 | operation: action.operation
100 | })
101 | .done( function( response ) {
102 | if ( response.data.finished ) {
103 | // MailChimp has finished with the bulk process
104 | var result = response.data.result;
105 | mc.updateBulkAction( action.operation, result );
106 |
107 | // Update stats
108 | mc.updateStat( 'errors', mc.getStat( 'errors' ) + result.errored_operations );
109 | mc.checkBulkResults();
110 | }
111 | else {
112 | // MailChimp is still processing, let's wait a little
113 | setTimeout(function(){
114 | mc.checkBulkResults();
115 | }, 5000);
116 | }
117 | });
118 | },
119 |
120 | finish: function() {
121 | var actions = this.getBulkActions();
122 | console.log(actions);
123 | this.progressbar.progressbar( 'destroy' );
124 |
125 | // Show a list of URL links where the user can download extra information
126 | var urlLinks = jQuery( '
');
127 | var link;
128 | var listElem;
129 | for ( operation in actions ) {
130 | listElem = jQuery( '' );
131 | link = jQuery( '' )
132 | .attr( 'href', actions[operation].result.response_body_url )
133 | .text( this.options.labels.downloadMoreInfo + ' ' + operation, operation );
134 |
135 | listElem.append( link );
136 | urlLinks.append( listElem );
137 | }
138 | this.setLabel( this.options.labels.results, this.options.total, this.getStat( 'errors' ) );
139 | this.$progressLabel.append( urlLinks );
140 | },
141 |
142 | call: function( data, callback ) {
143 | var mc = this;
144 | data.nonce = this.options.nonce;
145 | return jQuery.post( ajaxurl, data )
146 | .error( function( response ) {
147 | console.log( response );
148 | mc.stop();
149 | });
150 | },
151 |
152 | updateStat: function( type, value ) {
153 | this.stats[ type ] = value;
154 | },
155 |
156 | getStat: function( type ) {
157 | if ( this.stats[ type ] ) {
158 | return this.stats[ type ];
159 | }
160 |
161 | return 0;
162 | },
163 |
164 | addBulkAction: function( operation, userIds ) {
165 | this.bulkActions[operation] = {
166 | userIds: userIds,
167 | checked: false,
168 | result: false,
169 | operation: operation
170 | };
171 | },
172 |
173 | updateBulkAction: function( operation, result ) {
174 | this.bulkActions[operation].checked = true;
175 | this.bulkActions[operation].result = result;
176 |
177 | // Update stats
178 | },
179 |
180 | getBulkActions: function() {
181 | return this.bulkActions;
182 | },
183 |
184 | getNextUncheckedBulkAction: function() {
185 | var actions = this.getBulkActions();
186 | for ( var operation in actions ) {
187 | if ( ! actions[ operation ].checked ) {
188 | return actions[ operation ];
189 | }
190 | }
191 | return false;
192 | },
193 |
194 | /**
195 | * Interrupt the process
196 | */
197 | stop: function() {
198 | this.progressbar.progressbar( 'destroy' );
199 | this.setLabel( '' );
200 | },
201 |
202 | setLabel: function( label ) {
203 | for (var i = 1; i < arguments.length; i++) {
204 | label = label.replace( '%s', arguments[i] );
205 | }
206 | this.$progressLabel.html( label );
207 | }
208 | };
209 |
--------------------------------------------------------------------------------
/mailchimp-api/2.0/Mailchimp/Templates.php:
--------------------------------------------------------------------------------
1 | master = $master;
6 | }
7 |
8 | /**
9 | * Create a new user template, NOT campaign content. These templates can then be applied while creating campaigns.
10 | * @param string $name
11 | * @param string $html
12 | * @param int $folder_id
13 | * @return associative_array with a single element:
14 | * - template_id int the new template id, otherwise an error is thrown.
15 | */
16 | public function add($name, $html, $folder_id=null) {
17 | $_params = array("name" => $name, "html" => $html, "folder_id" => $folder_id);
18 | return $this->master->call('templates/add', $_params);
19 | }
20 |
21 | /**
22 | * Delete (deactivate) a user template
23 | * @param int $template_id
24 | * @return associative_array with a single entry:
25 | * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
26 | */
27 | public function del($template_id) {
28 | $_params = array("template_id" => $template_id);
29 | return $this->master->call('templates/del', $_params);
30 | }
31 |
32 | /**
33 | * Pull details for a specific template to help support editing
34 | * @param int $template_id
35 | * @param string $type
36 | * @return associative_array info to be used when editing
37 | * - default_content associative_array the default content broken down into the named editable sections for the template - dependant upon template, so not documented
38 | * - sections associative_array the valid editable section names - dependant upon template, so not documented
39 | * - source string the full source of the template as if you exported it via our template editor
40 | * - preview string similar to the source, but the rendered version of the source from our popup preview
41 | */
42 | public function info($template_id, $type='user') {
43 | $_params = array("template_id" => $template_id, "type" => $type);
44 | return $this->master->call('templates/info', $_params);
45 | }
46 |
47 | /**
48 | * Retrieve various templates available in the system, allowing some thing similar to our template gallery to be created.
49 | * @param associative_array $types
50 | * - user boolean Custom templates for this user account. Defaults to true.
51 | * - gallery boolean Templates from our Gallery. Note that some templates that require extra configuration are withheld. (eg, the Etsy template). Defaults to false.
52 | * - base boolean Our "start from scratch" extremely basic templates. Defaults to false. As of the 9.0 update, "base" templates are no longer available via the API because they are now all saved Drag & Drop templates.
53 | * @param associative_array $filters
54 | * - category string optional for Gallery templates only, limit to a specific template category
55 | * - folder_id string user templates, limit to this folder_id
56 | * - include_inactive boolean user templates are not deleted, only set inactive. defaults to false.
57 | * - inactive_only boolean only include inactive user templates. defaults to false.
58 | * - include_drag_and_drop boolean Include templates created and saved using the new Drag & Drop editor. Note: You will not be able to edit or create new drag & drop templates via this API. This is useful only for creating a new campaign based on a drag & drop template.
59 | * @return associative_array for each type
60 | * - user array matching user templates, if requested.
61 | * - id int Id of the template
62 | * - name string Name of the template
63 | * - layout string General description of the layout of the template
64 | * - category string The category for the template, if there is one.
65 | * - preview_image string If we've generated it, the url of the preview image for the template. We do out best to keep these up to date, but Preview image urls are not guaranteed to be available
66 | * - date_created string The date/time the template was created
67 | * - active boolean whether or not the template is active and available for use.
68 | * - edit_source boolean Whether or not you are able to edit the source of a template.
69 | * - folder_id boolean if it's in one, the folder id
70 | * - gallery array matching gallery templates, if requested.
71 | * - id int Id of the template
72 | * - name string Name of the template
73 | * - layout string General description of the layout of the template
74 | * - category string The category for the template, if there is one.
75 | * - preview_image string If we've generated it, the url of the preview image for the template. We do out best to keep these up to date, but Preview image urls are not guaranteed to be available
76 | * - date_created string The date/time the template was created
77 | * - active boolean whether or not the template is active and available for use.
78 | * - edit_source boolean Whether or not you are able to edit the source of a template.
79 | * - base array matching base templates, if requested. (Will always be empty as of 9.0)
80 | */
81 | public function getList($types=array(), $filters=array()) {
82 | $_params = array("types" => $types, "filters" => $filters);
83 | return $this->master->call('templates/list', $_params);
84 | }
85 |
86 | /**
87 | * Undelete (reactivate) a user template
88 | * @param int $template_id
89 | * @return associative_array with a single entry:
90 | * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
91 | */
92 | public function undel($template_id) {
93 | $_params = array("template_id" => $template_id);
94 | return $this->master->call('templates/undel', $_params);
95 | }
96 |
97 | /**
98 | * Replace the content of a user template, NOT campaign content.
99 | * @param int $template_id
100 | * @param associative_array $values
101 | * - name string the name for the template - names must be unique and a max of 50 bytes
102 | * - html string a string specifying the entire template to be created. This is NOT campaign content. They are intended to utilize our template language.
103 | * - folder_id int the folder to put this template in - 0 or a blank values will remove it from a folder.
104 | * @return associative_array with a single entry:
105 | * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
106 | */
107 | public function update($template_id, $values) {
108 | $_params = array("template_id" => $template_id, "values" => $values);
109 | return $this->master->call('templates/update', $_params);
110 | }
111 |
112 | }
113 |
114 |
115 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MailChimp Integration
2 |
3 | **INACTIVE NOTICE: This plugin is unsupported by WPMUDEV, we've published it here for those technical types who might want to fork and maintain it for their needs.**
4 |
5 | ## Translations
6 |
7 | Translation files can be found at https://github.com/wpmudev/translations
8 |
9 | ## Mailchimp Integration ties WordPress to MailChimp for seriously powerful email marketing, growing a subscriber base and list syncing.
10 |
11 | Get far more than just easy-embed signup forms. Tap core features of MailChimp that allow you to not only build your email subscriber list – but integrates to manage your site's user database.
12 |
13 | ### Build a Massive Following
14 |
15 | MailChimp Integration helps you effectively capture new subscribers from anywhere on your site using simple customizable signup forms. The included MailChimp widget and shortcode generator make it possible to add subscription forms anywhere on your site in under 60 seconds.
16 |
17 | ### Smart Subscription Management
18 |
19 | Eliminate the frustrations associated with managing users across multiple lists. Quickly establish a fluid communication stream with MailChimp and make sure your site user list and email list are always a perfect match. Automatically subscribe new users to your mailing list, add subscribers to your site user list and trigger user removal when unsubscribing from your mailing list.
20 |
21 | ### Merge and Grow Your User Base
22 |
23 | Merge existing Subscriber and User lists with a single click. Import makes it easy to sync existing lists and works to complete missing user information, eliminate duplicates, and remove spammed and deleted users from your selected MailChimp list.
24 |
25 | ### Make Room to Expand
26 |
27 | From our simple subscription form generator to managing user lists of hundreds or even thousands, MailChimp Integration is the right fit for sites both large and small. If you’re serious about email and building a huge following, create a powerful marketing machine by expanding WordPress with MailChimp.
28 |
29 | ## Usage
30 |
31 | For help with installing plugins please refer to our [Plugin installation guide](https://premium.wpmudev.org/wpmu-manual/installing-regular-plugins-on-wpmu/). Once installed, login to your admin panel for WordPress or Multisite and activate the plugin:
32 |
33 | * On regular WordPress installs – visit **Plugins** and **Activate** the plugin. The plugin options will appear in your Settings menu. [
34 |
35 | 
36 |
37 | ](https://premium.wpmudev.org/wp-content/uploads/2009/04/mailchimp-integration-1300-single-menu.png)
38 |
39 | Plugin options in single site installs of WordPress.
40 |
41 | * For WordPress Multisite installs – Visit **Network Admin -> Plugins** and **Network Activate** the plugin. The plugin options will appear in your Network Settings menu. **Note:** When used on a multisite install, MailChimp Integration _**must**_ be network activated to work.
42 |
43 | 
44 |
45 | Plugin options on multisite installs of WordPress.
46 |
47 | ### To use:
48 |
49 | First, set up an account with [MailChimp](http://www.mailchimp.com/) (unless you already have one of course). Then you can either create a new MailChimp list for your users, e.g. Edublogs.org users, or use an existing one.
50 |
51 | 
52 |
53 | Login into your WordPress dashboard, and go to the MailChimp settings. Once you enter your MailChimp API key and click Save Changes, additional settings will become available.
54 |
55 | 
56 |
57 | 1\. Allow sub-sites to use the widget.
58 | 2\. Your MailChimp API key.
59 | 3\. Select whether users should be opted in automatically.
60 | 4\. Ignore duplicate email accounts.
61 | 5\. Select your mailing list.
62 |
63 | 1\. The _Allow widget in all subsites_ checkbox is only available when network-activated. Checking it will allow sub-site admins to place the MailChimp signup widget on their sites too. 2\. _MailChimp API Key_ is, well, your key. :) 3\. If you set _Auto Opt-in_ to "Yes", your users will not receive an email confirmation. Be careful with this: some locales have anti-spam regulations that require the double-optin. 4\. You can set _Ignore email addresses including + signs_ to "Yes" if some of your subscribers have duplicate accounts using the "+" sign. Don't want to annoy them with duplicate emails. 5\. _Mailing List_ is where you select the MailChimp list you want to sync. You can also sync all your existing WordPress users to your MailChimp list.
64 |
65 | 
66 |
67 | 1\. Select your MailChimp mailing list.
68 | 2\. Select whether users should be opted in automatically.
69 |
70 | 1\. Select your Mailing List. 2\. Select whether to _Auto Opt-in_ your users or not. 3\. Click _Import_ to synchronize your WordPress users to your MailChimp list. The bottom section of your MailChimp settings page is a very handy excerpt of the error log. It will display the most recent 100 lines right in your admin to help you with troubleshooting. It even tells you if email addresses have been banned.
71 |
72 | 
73 |
74 | Finally, if you want your users to be able to subscribe directly to your MailChimp list, you can customize how the widget form should appear under Appearance > Widgets.
75 |
76 | 
77 |
78 | ### Using MailChimp Webhooks
79 |
80 | With MailChimp webhooks, you can synchronize your MailChimp lists and WordPress users. Yes, you read that right, whenever someone subscribes to your MailChimp list, they can be automatically added as a user on your WordPress site. Booya! The settings to get this done on your WordPress site are quite simple, and appear once you have configured & saved the previous settings (eg - you have entered your MailChimp API key, selected the list you want use & saved changes):
81 |
82 | 
83 |
84 | 1\. First, enter any name you would like your webhook to have in _Specify a unique webhook key_ field. Then click _Save Changes_ at the bottom of your screen. 2\. _Your Webhook URL_ will then appear right beneath the field where you just entered the key name. That is what you must enter in your MailChimp account. 3\. Select the _Action to take when user unsubscribes from list_. You can select to either mark them as unsubscribed, or to delete them from your WordPress install. _Save Changes_ again. Now, head on over to your MailChimp account page and follow the simple directions you'll find [on this page](http://kb.mailchimp.com/integrations/other-integrations/what-are-webhooks-and-how-can-i-set-them-up) to set up your webhook. The URL you'll be entering in the Callback URL field is the one you just generated with your unique key name.
85 |
--------------------------------------------------------------------------------
/changelog.txt:
--------------------------------------------------------------------------------
1 | Plugin Name: MailChimp Sync
2 | Author: WPMU DEV
3 | Requires at least: 3.5
4 | Tested up to: 4.8
5 |
6 | Change Log:
7 | ----------------------------------------------------------------------
8 | ----------------------------------------------------------------------
9 | 1.9.7 - 2017-11-01
10 | - Fix: Deprecated code
11 |
12 | 1.9.6 - 2017-09-04
13 | ----------------------------------------------------------------------
14 | - Fix: conflict with WooCommerce plugin
15 |
16 | 1.9.4 - 2017-07-11
17 | ----------------------------------------------------------------------
18 | - Fix: Fatal error when using widget/shortcode
19 |
20 | 1.9.3 - 2017-01-13
21 | ----------------------------------------------------------------------
22 | - Added filter to modify the MailChimp API request parameters
23 |
24 | 1.9.2 - 2016-12-22
25 | ----------------------------------------------------------------------
26 | - Fix: Fatal error when inserting a wrong API Key
27 |
28 | 1.9.1 - 2016-12-21
29 | ----------------------------------------------------------------------
30 | - Fix: Capabilities issue in single installations
31 |
32 | 1.9.0 - 2016-12-19
33 | ----------------------------------------------------------------------
34 | - Enhance: Updated MailChimp API to 3.0
35 | - Updated WPMU DEV Dashboard notification
36 |
37 | 1.8.2 - 2015-08-29
38 | ----------------------------------------------------------------------
39 | - Fix: Webhook URL not working on subfolder installation
40 | - Fix: Warning on activation
41 |
42 | 1.8.1 - 2015-11-25
43 | ----------------------------------------------------------------------
44 | - Fixed: Deprecated widget notice
45 |
46 | 1.8 - 2015-08-20
47 | ----------------------------------------------------------------------
48 | - Enhance: Removed user meta to check if it's subscribed to the list in the profile page. Using API instead.
49 | - Enhance: User Profile Admin styles
50 |
51 | 1.7.3 - 2015-05-29
52 | ----------------------------------------------------------------------
53 | - Fixed: Warning when bulk subscribing users.
54 | - Added default arguments for shortcode.
55 |
56 | 1.7.2 - 2015-03-10
57 | ----------------------------------------------------------------------
58 | - Fixed: Added message error when a user is already subscribed and confirmed
59 |
60 | 1.7.1.1 - 2014-12-09
61 | ----------------------------------------------------------------------
62 | - Fixed: Undefined constant warning.
63 |
64 | 1.7.1 - 2014-12-09
65 | ----------------------------------------------------------------------
66 | - Fixed: Shortcode was always appearing on the top of the content.
67 |
68 | 1.7 - 2014-12-05
69 | ----------------------------------------------------------------------
70 | - New: Mailchimp Webhooks.
71 |
72 | 1.6.6 - 2014-11-10
73 | ----------------------------------------------------------------------
74 | - Fixed: Users details were not updated in Mailchimp List.
75 |
76 | 1.6.5 - 2014-08-28
77 | ----------------------------------------------------------------------
78 | - Enhanced: Added option that saves the last list imported.
79 | - Fixed: Fixed typo in Exception classes.
80 |
81 | 1.6.4 - 2014-08-25
82 | ----------------------------------------------------------------------
83 | - Fixed: MailChimp API errors were causing a fatal error.
84 |
85 | 1.6.3 - 2014-08-18
86 | ----------------------------------------------------------------------
87 | - Enhanced: added prefix to Mailchimp API classes.
88 | - Enhanced: Added Settings link in plugins list.
89 |
90 | 1.6.2 - 2014-05-15
91 | ----------------------------------------------------------------------
92 | - Fixed fatal error
93 |
94 | 1.6.1 - 2014-05-15
95 | ----------------------------------------------------------------------
96 | - Fixed: Widgets issues when there were more than one in the same screen
97 | - Improved forms validation
98 | - Tiny MCE plugin improved
99 | - Other minor fixes
100 |
101 | 1.6 - 2014-05-02
102 | ----------------------------------------------------------------------
103 | - curl functions replaced by wp_remote_* functions in Maiclhimp API
104 | - Better errors management
105 | - Fixed Javascript conflict
106 | - Fixed redirection in import tab to 404 page in single sites
107 |
108 | 1.5.1 - 2014-04-26
109 | ----------------------------------------------------------------------
110 | - Plugin triggered a fatal error if the API key was blank
111 |
112 | 1.5 - 2014-04-25
113 | ----------------------------------------------------------------------
114 | - Mailchimp API updated to 2.0
115 | - Better errors management
116 | - Other minor improvements
117 |
118 | 1.4 - 2014-02-11- Ignacio Cruz
119 | ----------------------------------------------------------------------
120 | - Added shortcode.
121 | - Ultimate Facebook Integration
122 | - Code refactored
123 | - Settings splitted into tabs
124 |
125 | 1.3 - 2013/10/03 - Ignacio Cruz
126 | ----------------------------------------------------------------------
127 | - Added new widget.
128 |
129 | 1.2.4 - 2013/05/14 - Ignacio Cruz
130 | ----------------------------------------------------------------------
131 | - Fixed error when error log was empty.
132 |
133 | 1.2.3 - 2013/05/10 - Ignacio Cruz
134 | ----------------------------------------------------------------------
135 | - Added an additional control when subscribing users on a list. If the
136 | user was already unsubscribed (from the mail link) it won't be subscribed again
137 | - Added a log for MailChimp API calls
138 |
139 | 1.2.2 - 2013/05/06 - Ignacio Cruz
140 | ----------------------------------------------------------------------
141 | - The import feature was using the list on the settings instead the list on the import section
142 |
143 | 1.2.1 - 14/03/2013 - Ignacio Cruz
144 | ----------------------------------------------------------------------
145 | - Fixed some PHP notices when displaying the settings and saving
146 | http://premium.wpmudev.org/forums/topic/basic-php-errors-turn-on-wp_edbug-to-see
147 | - Added styles to submit buttons
148 |
149 | 1.2 - 12/19/2012 - Aaron Edwards
150 | ----------------------------------------------------------------------
151 | - Make deleting WP users remove them from mailchimp: http://wp.mu/77
152 |
153 | 1.1.4 - 7/23/2012 - Paul Menard
154 | ----------------------------------------------------------------------
155 | - Patched error returned from MailChimp API when user already is present in MailChimp
156 | http://premium.wpmudev.org/forums/topic/mailchimp-integration#post-249269
157 |
158 | 1.1.3 - 4/15/2012 - Aaron Edwards
159 | ----------------------------------------------------------------------
160 | - Limit bulk import query to scale better for large user databases
161 |
162 | 1.1.2 - 8/05/2011 - Aaron Edwards
163 | ----------------------------------------------------------------------
164 | - Add filters for merging additional fields
165 | - Fix entity problems with bulk import of names
166 |
167 | 1.1.1 - 1/05/2011 - Aaron Edwards
168 | ----------------------------------------------------------------------
169 | - WP 3.1 Compatibility
170 |
171 | 1.1 - 12/20/2010 - Aaron Edwards
172 | ----------------------------------------------------------------------
173 | - Updated to the latest API to fix bugs
174 | - Now removes users when they or their blogs are spammed/deleted
175 | - Imports Names to MailChimp now on creation and profile updates
176 | - Works with BuddyPress now
177 | - Auto-update capable
178 |
179 | 1.0.4 - 07/20/2010 - Aaron Edwards
180 | ----------------------------------------------------------------------
181 | - Fixed compatibility with WP installs running BP (for good this time hopefully)
182 |
183 | 1.0.3 - 06/01/2010
184 | ----------------------------------------------------------------------
185 | - 3.0+ compatibility update
186 |
187 | 1.0.2 - 05/18/2010
188 | ----------------------------------------------------------------------
189 | - Now comaptible with WP installs running BP
190 |
191 | 1.0.1 - 07/13/2009
192 | ----------------------------------------------------------------------
193 | - Added option to ignore email address including a + sign.
194 |
195 | 1.0.0 - 04/29/2009
196 | ----------------------------------------------------------------------
197 | - Initial Release.
198 |
--------------------------------------------------------------------------------
/deprecated.php:
--------------------------------------------------------------------------------
1 | api ) )
23 | return $mailchimp_sync->api;
24 |
25 | require_once( 'mailchimp-api/2.0/mailchimp-api-2.0.php' );
26 | $mailchimp_apikey = get_site_option('mailchimp_apikey');
27 |
28 | $options = array(
29 | 'timeout' => apply_filters( 'mailchimp_sync_api_timeout', false )
30 | );
31 |
32 | $ssl_verifypeer = apply_filters( 'mailchimp_sync_api_ssl_verifypeer', false );
33 | if ( $ssl_verifypeer ) {
34 | $options['ssl_verifypeer'] = $ssl_verifypeer;
35 | }
36 |
37 | $ssl_verifyhost = apply_filters( 'mailchimp_sync_api_ssl_verifyhost', false );
38 | if ( $ssl_verifyhost ) {
39 | $options['ssl_verifyhost'] = $ssl_verifyhost;
40 | }
41 |
42 | $ssl_cainfo = apply_filters( 'mailchimp_sync_api_ssl_cainfo', false );
43 | if ( $ssl_cainfo ) {
44 | $options['ssl_cainfo'] = $ssl_cainfo;
45 | }
46 |
47 | $debug = apply_filters( 'mailchimp_sync_api_debug', false );
48 | if ( $debug ) {
49 | $options['debug'] = $debug;
50 | }
51 |
52 | try {
53 | $api = new WPMUDEV_Mailchimp_Sync_API_20( $mailchimp_apikey, $options );
54 | }
55 | catch ( Exception $e ) {
56 | return new WP_Error( $e->getCode(), $e->getMessage() );
57 | }
58 |
59 | // Pinging the server
60 | $ping = $api->helper->ping();
61 |
62 | if ( is_wp_error( $ping ) )
63 | return $ping;
64 |
65 | $mailchimp_sync->api = $api;
66 |
67 | return $api;
68 | }
69 |
70 | /**
71 | * Get the lists of a Mailchimp account
72 | *
73 | * @return array Lists info
74 | * @deprecated
75 | */
76 | function mailchimp_get_lists() {
77 | _deprecated_function( __FUNCTION__, '1.9', 'mailchimp_30_get_lists()' );
78 | return mailchimp_30_get_lists();
79 | }
80 |
81 | /**
82 | * @param $list_id
83 | * @deprecated
84 | * @return array
85 | */
86 | function mailchimp_get_list_groups( $list_id ) {
87 | _deprecated_function( __FUNCTION__, '1.9', 'mailchimp_30_get_list_groups()' );
88 | return mailchimp_30_get_list_groups( $list_id );
89 | }
90 |
91 | /**
92 | * Subscribe a user to a Mailchimp list
93 | *
94 | * @param String $user_email
95 | * @param String $list_id
96 | * @param Boolean $autopt
97 | * @param Array $extra Extra data
98 | * Array(
99 | * 'FNAME' => First name,
100 | * 'LNAME' => Last Name
101 | * )
102 | * @return Array Result from the server
103 | * @deprecated
104 | */
105 | function mailchimp_subscribe_user( $user_email, $list_id, $autopt = false, $merge = array(), $update = false ) {
106 | _deprecated_function( __FUNCTION__, '1.9', 'mailchimp_30_subscribe_user()' );
107 | $api = mailchimp_load_API();
108 |
109 | if ( ! $update ) {
110 | return mailchimp_30_subscribe_user( $user_email, $list_id, array( 'merge_fields' => $merge, 'autopt' => $autopt ) );
111 | }
112 | else {
113 | }
114 | }
115 |
116 | /**
117 | * Check if a user is subscribed in the list
118 | *
119 | * @param String $user_email
120 | * @param String $list_id
121 | * @return bool. True if the user is subscribed already to the list
122 | * @deprecated
123 | */
124 | function mailchimp_is_user_subscribed( $user_email, $list_id = '' ) {
125 | _deprecated_function( __FUNCTION__, '1.9', 'mailchimp_30_is_user_subscribed()' );
126 | return mailchimp_30_is_user_subscribed( $user_email, $list_id );
127 | }
128 |
129 | /**
130 | * Unsubscribe a user from a list
131 | *
132 | * @param String $user_email
133 | * @param String $list_id
134 | * @param Boolean $delete True if the user is gonna be deleted from the list (not only unsubscribed)
135 | *
136 | * @deprecated
137 | */
138 | function mailchimp_unsubscribe_user( $user_email, $list_id, $delete = false ) {
139 | _deprecated_function( __FUNCTION__, '1.9', 'mailchimp_30_unsubscribe_user()' );
140 | return mailchimp_30_unsubscribe_user( $user_email, $list_id, $delete );
141 | }
142 |
143 | /**
144 | * Update a user data in a list
145 | * @param String $user_email
146 | * @param String $list_id
147 | * @param Array $merge_vars
148 | * Array(
149 | * 'FNAME' => First name,
150 | * 'LNAME' => Last Name
151 | * )
152 | * @deprecated
153 | */
154 | function mailchimp_update_user( $user_email, $list_id, $merge_vars ) {
155 | _deprecated_function( __FUNCTION__, '1.9', 'mailchimp_30_update_user()' );
156 | return mailchimp_30_update_user( $user_email, $list_id, array( 'merge_fields' => $merge_vars ) );
157 | }
158 |
159 | /**
160 | * Return the groups that the user has selected in Settings
161 | *
162 | * @return array Array of groups
163 | * @deprecated
164 | */
165 | function mailchimp_get_interest_groups() {
166 | _deprecated_function( __FUNCTION__, '1.9', 'mailchimp_30_get_interest_groups()' );
167 | $mailchimp_mailing_list = get_site_option( 'mailchimp_mailing_list', '' );
168 | $groups = get_site_option( 'mailchimp_groups', array() );
169 |
170 | $vars = array();
171 | $merge_groups = array();
172 | if ( ! empty( $groups[ $mailchimp_mailing_list ] ) ) {
173 |
174 | foreach ( $groups[ $mailchimp_mailing_list ] as $group_id => $subgroups ) {
175 | if ( is_array( $subgroups ) && ! empty( $subgroups ) ) {
176 | $merge_groups[] = array(
177 | 'id' => $group_id,
178 | 'groups' => $subgroups
179 | );
180 | }
181 | elseif ( ! empty( $subgroups ) ) {
182 | $merge_groups[] = array(
183 | 'id' => $group_id,
184 | 'groups' => array( $subgroups )
185 | );
186 | }
187 | }
188 |
189 | $vars = $merge_groups;
190 | }
191 |
192 | return $vars;
193 | }
194 |
195 | /**
196 | * Return user data from a list
197 | *
198 | * @param String $user_email
199 | * @param String $list_id
200 | * @return Array User data / False if the user do not exist
201 | * @deprecated
202 | */
203 | function mailchimp_get_user_info( $user_email, $list_id ) {
204 | _deprecated_function( __FUNCTION__, '1.9', 'mailchimp_30_get_user_info()' );
205 | return mailchimp_30_get_user_info( $user_email, $list_id );
206 | }
207 |
208 | function mailchimp_bulk_subscribe_users( $emails, $list_id, $autopt = false, $update = false ) {
209 | _deprecated_function( __FUNCTION__, '1.9', 'mailchimp_30_bulk_subscribe_users()' );
210 | return mailchimp_30_bulk_subscribe_users( $emails );
211 | $api = mailchimp_load_API();
212 |
213 | if ( is_wp_error( $api ) )
214 | return $api;
215 |
216 | $merge_vars = array();
217 | if ( $autopt ) {
218 | $merge_vars['optin_ip'] = $_SERVER['REMOTE_ADDR'];
219 | $merge_vars['optin_time'] = current_time( 'mysql', true );
220 | }
221 |
222 | $results = $api->lists->batchSubscribe( $list_id, $emails, ! $autopt, $update );
223 |
224 | $return = array();
225 | $return['added'] = $results['adds'];
226 | $return['updated'] = $results['updates'];
227 | $return['errors'] = array();
228 |
229 | if ( $results['error_count'] ) {
230 | foreach( $results['errors'] as $error ) {
231 | $return['errors'][] = new WP_Error( $error['code'], '{' . $error['email']['email'] . '} ' . $error['error'] );
232 | }
233 | }
234 |
235 | return $return;
236 |
237 | }
238 |
239 | /**
240 | * Unsubscribe a list of users
241 | * @param Array $emails
242 | * Array(
243 | * array(
244 | * 'email' => Email
245 | * ),
246 | * ...
247 | * )
248 | * @param String $list_id
249 | * @param Boolean $autopt
250 | * @param Array $merge Array of merge vars
251 | * @return type
252 | * @deprecated
253 | */
254 | function mailchimp_bulk_unsubscribe_users( $emails, $list_id, $delete = false ) {
255 | _deprecated_function( __FUNCTION__, '1.9', 'mailchimp_30_bulk_unsubscribe_users()' );
256 | $api = mailchimp_load_API();
257 |
258 | if ( is_wp_error( $api ) )
259 | return $api;
260 |
261 | $results = $api->lists->batchUnsubscribe( $list_id, $emails, $delete );
262 |
263 | $return = array();
264 | $return['success_count'] = $results['success_count'];
265 | $return['errors'] = array();
266 |
267 | if ( $results['error_count'] ) {
268 | foreach( $results['errors'] as $error ) {
269 | $return['errors'][] = new WP_Error( $error['code'], '{' . $error['email'] . '} ' . $error['error'] );
270 | }
271 | }
272 |
273 | return $return;
274 |
275 | }
276 |
--------------------------------------------------------------------------------
/mailchimp-api/3.0/webhooks.php:
--------------------------------------------------------------------------------
1 | 1,
38 | 'mckey' => $webhooks_settings['webhook_key']
39 | ),
40 | home_url()
41 | );
42 | }
43 | else {
44 | $url = trailingslashit( site_url() ) . 'mailchimp-sync/' . $webhooks_settings['webhook_key'];
45 | }
46 |
47 |
48 | return $url;
49 | }
50 |
51 | public function parse_request() {
52 | global $wp_query;
53 | if ( ! self::is_webhooks_active() )
54 | return;
55 |
56 | $webhooks_settings = mailchimp_get_webhooks_settings();
57 |
58 | if ( get_query_var( 'mailchimp-sync' ) == 1 ) {
59 | if ( get_query_var( 'mckey' ) != $webhooks_settings['webhook_key'] ) {
60 | $this->log( sprintf( __( 'Security key specified, but not correct: %s', MAILCHIMP_LANG_DOMAIN ), get_query_var( 'mckey' ) ) );
61 | exit();
62 | }
63 |
64 | $this->trigger_webhook_action();
65 | exit();
66 | }
67 | }
68 |
69 | private function trigger_webhook_action() {
70 | $req = $_POST;
71 |
72 | if ( ! isset( $req['type'] ) ) {
73 | $this->log( __( 'Request type not defined', MAILCHIMP_LANG_DOMAIN ) );
74 | return;
75 | }
76 |
77 | $list_id = get_site_option( 'mailchimp_mailing_list' );
78 | if ( $list_id != $req['data']['list_id'] ) {
79 | $this->log( sprintf( __( 'Requested list ID [%s] is not the same than the selected one in Mailchimp Settings [%s]', MAILCHIMP_LANG_DOMAIN ), $req['data']['list_id'], $list_id ) );
80 | return;
81 | }
82 |
83 | $allowed_types = apply_filters( 'mailchimp_webhooks_allowed_types', array( 'subscribe', 'unsubscribe', 'profile', 'upemail' ) );
84 |
85 | if ( ! in_array( $req['type'], $allowed_types ) )
86 | $this->log( sprintf( __( 'Request type "%s" unknown, ignoring.', MAILCHIMP_LANG_DOMAIN ), $req['type'] ) );
87 |
88 | $function = array( $this, $req['type'] );
89 | $function = apply_filters( 'mailchimp_webhook_action_function', $function, $req );
90 |
91 | $result = call_user_func_array( $function, array( $req['data'] ) );
92 |
93 | if ( is_wp_error( $result ) )
94 | $this->log( strtoupper( $req['type'] ) . ': ' . $result->get_error_message() );
95 |
96 | }
97 |
98 | private function log( $message, $echo = true ) {
99 | mi_mailchimp_log( array( 'message' => $message ), 'webhooks' );
100 | if ( $echo ) {
101 | echo $message;
102 | }
103 | }
104 |
105 | private function subscribe( $data ) {
106 | $user_email = $data['email'];
107 |
108 | $user = get_user_by( 'email', $user_email );
109 |
110 | if ( $user )
111 | return new WP_Error( 'user_exists', sprintf( __( 'Existing user found with this email address: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
112 |
113 | $login = explode( '@', $user_email );
114 | $login = $login[0];
115 | $login = sanitize_user( $login );
116 |
117 | $user = get_user_by( 'login', $login );
118 |
119 | if ( $user )
120 | return new WP_Error( 'user_exists', sprintf( __( 'Existing user found with this user login: "%s"', MAILCHIMP_LANG_DOMAIN ), $login ) );
121 |
122 | $userdata = array(
123 | 'user_pass' => wp_generate_password( 12, false ),
124 | 'user_login' => $login,
125 | 'user_email' => $user_email,
126 | 'first_name' => $data['merges']['FNAME'],
127 | 'last_name' => $data['merges']['LNAME'],
128 | 'role' => 'subscriber'
129 | );
130 |
131 | $userdata = apply_filters( 'mailchimp_webhooks_subscribe_user', $userdata );
132 |
133 | $user_id = wp_insert_user( $userdata );
134 |
135 | if ( is_wp_error( $user_id ) )
136 | return new WP_Error( 'user_exists', sprintf( __( 'FAILED! Problem encountered trying to create new user: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
137 |
138 | $list_id = get_site_option( 'mailchimp_mailing_list' );
139 |
140 | $this->log( sprintf( __( 'SUBSCRIBE: New user created: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
141 |
142 | return true;
143 | }
144 |
145 | private function unsubscribe( $data ) {
146 | $user_email = $data['email'];
147 |
148 | $user = get_user_by( 'email', $user_email );
149 |
150 | if ( ! $user )
151 | return new WP_Error( 'user_not_exists', sprintf( __( 'User not found with this email address: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
152 |
153 | $settings = mailchimp_get_webhooks_settings();
154 | if ( 'mark' === $settings['delete_user'] ) {
155 | $this->log( sprintf( __( 'UNSUBSCRIBE: user unsubscribed from list: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
156 | }
157 | else {
158 | if ( is_multisite() ) {
159 | if ( ! function_exists( 'wp_delete_user' ) )
160 | require_once(ABSPATH . 'wp-admin/includes/ms.php');
161 |
162 | if ( is_super_admin() )
163 | return new WP_Error( 'user_not_exists', sprintf( __( 'Deleting Super Admins is not allowed: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
164 |
165 | $result = wpmu_delete_user( $user->ID );
166 | }
167 | else {
168 | if ( ! function_exists( 'wp_delete_user' ) )
169 | require_once(ABSPATH . 'wp-admin/includes/user.php');
170 |
171 | if ( current_user_can( 'manage_options' ) )
172 | return new WP_Error( 'user_not_exists', sprintf( __( 'Deleting Administrators is not allowed: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
173 |
174 | $result = wp_delete_user( $user->ID, false );
175 | }
176 |
177 | if ( ! $result )
178 | return new WP_Error( 'error_deleting_user', sprintf( __( 'FAILED: Something went wrong while trying to delete user: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
179 |
180 | $this->log( sprintf( __( 'UNSUBSCRIBE: user deleted: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
181 | }
182 |
183 | return true;
184 |
185 | }
186 |
187 | private function upemail( $data ) {
188 | $user_email = $data['old_email'];
189 |
190 | $user = get_user_by( 'email', $user_email );
191 |
192 | if ( ! $user )
193 | return new WP_Error( 'user_not_exists', sprintf( __( 'User not found with this email address: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
194 |
195 | $new_email = $data['new_email'];
196 |
197 | if ( ! is_email( $new_email ) )
198 | return new WP_Error( 'wrong_email', sprintf( __( 'The new email is not a valid one: "%s"', MAILCHIMP_LANG_DOMAIN ), $new_email ) );
199 |
200 | $userdata = array(
201 | 'ID' => $user->ID,
202 | 'user_email' => $new_email
203 | );
204 |
205 | $result = wp_update_user( $userdata );
206 |
207 | if ( ! $result )
208 | return new WP_Error( 'error_updating_email', sprintf( __( 'FAILED: Something went wrong while trying to update user email: "%s"', MAILCHIMP_LANG_DOMAIN ), $new_email ) );
209 |
210 | $this->log( sprintf( __( 'UPEMAIL: email updated: "%s" to "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email, $new_email ) );
211 |
212 | return true;
213 |
214 | }
215 |
216 | private function profile( $data ) {
217 | $user_email = $data['email'];
218 |
219 | $user = get_user_by( 'email', $user_email );
220 |
221 | if ( ! $user )
222 | return new WP_Error( 'user_not_exists', sprintf( __( 'User not found with this email address: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
223 |
224 | $userdata = array(
225 | 'ID' => $user->ID,
226 | 'first_name' => $data['merges']['FNAME'],
227 | 'last_name' => $data['merges']['LNAME'],
228 | );
229 |
230 | $result = wp_update_user( $userdata );
231 |
232 | if ( ! $result )
233 | return new WP_Error( 'error_updating_profile', sprintf( __( 'FAILED: Something went wrong while trying to update user profile: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
234 |
235 |
236 | $this->log( sprintf( __( 'PROFILE: profile updated: "%s"', MAILCHIMP_LANG_DOMAIN ), $user_email ) );
237 |
238 | return true;
239 |
240 | }
241 |
242 |
243 | }
--------------------------------------------------------------------------------
/front/widget.php:
--------------------------------------------------------------------------------
1 | success = false;
18 |
19 | /* Widget settings. */
20 | $widget_ops = array(
21 | 'classname' => 'incsub-mailchimp-widget' ,
22 | 'description' => __( 'This widget allows visitors to subscribe to a MailChimp email list (set by the network administrator).', MAILCHIMP_LANG_DOMAIN )
23 | );
24 |
25 | /* Create the widget. */
26 | parent::__construct( 'incsub-mailchimp-widget' , __( 'MailChimp', MAILCHIMP_LANG_DOMAIN ), $widget_ops );
27 |
28 | add_filter( 'mailchimp_form_require_field', array( &$this, 'set_require_field' ), 10, 3 );
29 | add_filter( 'mailchimp_form_success_redirect', array( &$this, 'set_form_success_redirect' ) );
30 | add_filter( 'mailchimp_form_subscribed_placeholder', array( &$this, 'set_form_success_placeholder' ), 10, 2 );
31 |
32 | add_action( 'init', array( $this, 'init' ) );
33 | add_action( 'init', array( $this, 'validate_widget' ) );
34 |
35 |
36 | }
37 |
38 | function init() {
39 | WPMUDEV_MailChimp_Form::enqueue_dependencies();
40 | }
41 |
42 |
43 | function validate_widget() {
44 | if ( isset( $_POST['submit-subscribe-widget-user'] ) ) {
45 |
46 | global $mailchimp_sync;
47 |
48 | $doing_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX;
49 | $errors = array();
50 |
51 | if ( ! $doing_ajax ) {
52 | if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'mailchimp_subscribe_user' ) )
53 | return false;
54 | }
55 | else {
56 | check_ajax_referer( 'mailchimp_subscribe_user', 'nonce' );
57 | }
58 |
59 | $_form_id = $_POST['form_id'];
60 | $form_id = explode( '-', $_form_id );
61 | $number = $form_id[ count( $form_id ) -1 ];
62 |
63 | $settings = $this->get_settings();
64 |
65 | if ( ! isset( $settings[ $number ] ) )
66 | return;
67 |
68 | $settings = $settings[ $number ];
69 |
70 | $errors = WPMUDEV_MailChimp_Form::validate_subscription_form( $_POST, $settings );
71 |
72 | if ( empty( $errors ) ) {
73 | $user['email'] = sanitize_email( $_POST['subscription-email'] );
74 | $user['first_name'] = sanitize_text_field( $_POST['subscription-firstname'] );
75 | $user['last_name'] = sanitize_text_field( $_POST['subscription-lastname'] );
76 |
77 | $mailchimp_sync->mailchimp_add_user( $user );
78 |
79 | if ( ! $doing_ajax ) {
80 | $redirect_to = add_query_arg( 'mailchimp-subscribed-' . $number, 'true' ) . '#' . $_form_id;
81 | wp_redirect( $redirect_to );
82 | exit;
83 | }
84 | else {
85 | $text = apply_filters( 'mailchimp_form_subscribed_placeholder', $this->args['subscribed_placeholder'], $_POST['form_id'] );
86 | wp_send_json_success( array( 'message' => $text ) );
87 | }
88 | }
89 | elseif ( ! empty( $errors ) && $doing_ajax ) {
90 | wp_send_json_error( $errors );
91 | }
92 |
93 | $this->errors[ $number ] = $errors;
94 |
95 |
96 | }
97 | }
98 |
99 |
100 | /**
101 | * How to display the widget on the screen.
102 | */
103 | function widget( $args, $instance ) {
104 |
105 | extract( $args );
106 |
107 | $title = apply_filters( 'widget_title', $instance['title'] );
108 |
109 | echo $before_widget;
110 |
111 | if ( $title )
112 | echo $before_title . $title . $after_title;
113 |
114 |
115 | $firstname = ! empty( $_POST['subscription-firstname'] ) ? stripslashes( $_POST['subscription-firstname'] ) : '';
116 | $lastname = ! empty( $_POST['subscription-lastname'] ) ? stripslashes( $_POST['subscription-lastname'] ) : '';
117 | $email = ! empty( $_POST['subscription-email'] ) ? stripslashes( $_POST['subscription-email'] ) : '';
118 |
119 | $form_id = 'incsub-mailchimp-widget-form-' . $this->number;
120 | $subscribed = isset( $_GET[ 'mailchimp-subscribed-' . $this->number ] );
121 |
122 | $submit_name = 'submit-subscribe-widget-user';
123 | $errors = isset( $this->errors[ $this->number ] ) ? $this->errors[ $this->number ] : array();
124 |
125 | $args = compact( 'submit_name', 'form_id', 'subscribed', 'firstname', 'lastname', 'email', 'errors' );
126 | $args['button_text'] = $instance['button_text'];
127 | $args['subscribed_placeholder'] = $instance['subscribed_placeholder'];
128 | $args['text'] = $instance['text'];
129 | $args['require_fn'] = $instance['require_firstname'];
130 | $args['require_ln'] = $instance['require_lastname'];
131 |
132 | WPMUDEV_MailChimp_Form::render_form( $args );
133 |
134 | echo $after_widget;
135 | }
136 |
137 | /**
138 | * Update the widget settings.
139 | */
140 | function update( $new_instance, $old_instance ) {
141 | $instance = $old_instance;
142 |
143 | /* Strip tags for title and name to remove HTML (important for text inputs). */
144 | $instance['title'] = sanitize_text_field( $new_instance['title'] );
145 | $instance['text'] = sanitize_text_field( $new_instance['text'] );
146 | $instance['button_text'] = sanitize_text_field( $new_instance['button_text'] );
147 | $instance['subscribed_placeholder'] = sanitize_text_field( $new_instance['subscribed_placeholder'] );
148 | $instance['require_firstname'] = ! empty( $new_instance['require_firstname'] ) ? true : false;
149 | $instance['require_lastname'] = ! empty( $new_instance['require_lastname'] ) ? true : false;
150 |
151 | return $instance;
152 | }
153 |
154 | /**
155 | * Displays the widget settings controls on the widget panel.
156 | * Make use of the get_field_id() and get_field_name() function
157 | * when creating your form elements. This handles the confusing stuff.
158 | */
159 | function form( $instance ) {
160 |
161 | /* Set up some default widget settings. */
162 | $defaults = array(
163 | 'title' => __( 'Subscribe to MailChimp', MAILCHIMP_LANG_DOMAIN ),
164 | 'text' => __( 'Subscribe to our MailChimp list.', MAILCHIMP_LANG_DOMAIN ),
165 | 'button_text' => __( 'Subscribe', MAILCHIMP_LANG_DOMAIN ),
166 | 'subscribed_placeholder' => __( 'Thank you, your email has been added to the list.', MAILCHIMP_LANG_DOMAIN ),
167 | 'require_firstname' => false,
168 | 'require_lastname' => false
169 | );
170 |
171 | $instance = wp_parse_args( (array) $instance, $defaults ); ?>
172 |