MailChimp for WordPress - Version 1.5

Version Description

  • 18 December 2013 =
  • Added: BIRTHDAY fields will now be formatted in the DD/MM format automatically
  • Added: The plugin will now try to automatically format ADDRESS fields.
  • Added: Form fields will now keep their value when a validation error occurs
  • Improved: Cache headers for CSS file
  • Improved: Added notice when no lists selected and using sign-up checkboxes
  • Improved: Various code improvements
  • Fixed: Error when activating Pro with the Lite plugin still activated.
  • Fixed: BuddyPress & MultiSite checkbox not automatically added
Download this release

Release Info

Developer DvanKooten
Plugin Icon 128x128 MailChimp for WordPress
Version 1.5
Comparing to
See all releases

Code changes from version 1.4.8 to 1.5

assets/css/admin.css CHANGED
@@ -8,6 +8,13 @@
8
  box-sizing: border-box;
9
  }
10
 
 
 
 
 
 
 
 
11
  .valigntop{ vertical-align: top !important; }
12
 
13
  .mc4wp-box{ margin-bottom:20px; }
8
  box-sizing: border-box;
9
  }
10
 
11
+ .mc4wp-info {
12
+ padding: 5px 15px;
13
+ color: #3a87ad;
14
+ background-color: #d9edf7;
15
+ border-color: #bce8f1;
16
+ }
17
+
18
  .valigntop{ vertical-align: top !important; }
19
 
20
  .mc4wp-box{ margin-bottom:20px; }
assets/css/css.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
  // Set headers to serve CSS and encourage browser caching
3
  $expires = 31536000; // cache time: 1 year
4
- header('Content-Type: text/css; charset: UTF-8');
5
- header("Cache-Control: public, max-age=" . $expires);
6
  header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT');
7
 
8
  if(isset($_GET['checkbox'])) {
1
  <?php
2
  // Set headers to serve CSS and encourage browser caching
3
  $expires = 31536000; // cache time: 1 year
4
+ header('Content-Type: text/css');
5
+ header("Cache-Control: max-age=" . $expires);
6
  header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT');
7
 
8
  if(isset($_GET['checkbox'])) {
assets/css/form-theme-base.css CHANGED
@@ -71,6 +71,8 @@
71
  background:none;
72
  text-shadow:none;
73
  filter: none;
 
 
74
  }
75
 
76
  .mc4wp-form input[type="submit"]:focus, .mc4wp-form button:focus {
71
  background:none;
72
  text-shadow:none;
73
  filter: none;
74
+ height: auto;
75
+ width: auto;
76
  }
77
 
78
  .mc4wp-form input[type="submit"]:focus, .mc4wp-form button:focus {
assets/js/forms.js ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function() {
2
+
3
+ function populateFields(container, data, basename) {
4
+
5
+ for(var key in data) {
6
+
7
+ var name = key;
8
+ var value = data[key];
9
+
10
+ // no need to set empty values
11
+ if(value == "") {
12
+ continue;
13
+ }
14
+
15
+ // handle array name attributes
16
+ if(typeof(basename) !== "undefined") {
17
+ name = basename + "[" + key + "]";
18
+ }
19
+
20
+ if(value.constructor == Array) {
21
+ name += '[]';
22
+ } else if(typeof value == "object") {
23
+ populateFields(container, value, name);
24
+ continue;
25
+ }
26
+
27
+ // populate field
28
+ var elements = container.querySelectorAll('input[name="'+ name +'"], select[name="'+ name +'"], textarea[name="'+ name +'"]');
29
+
30
+ // Dirty: abandon if we did not find the element
31
+ if(!elements) {
32
+ return;
33
+ }
34
+
35
+ // loop through found elements to set their values
36
+ for(var i = 0; i < elements.length; i++) {
37
+
38
+ var element = elements[i];
39
+
40
+ // check element type
41
+ switch(element.type || element.tagName) {
42
+ case 'text':
43
+ case 'email':
44
+ case 'date':
45
+ case 'tel':
46
+ element.value = value;
47
+ element.className = element.className.replace('placeholdersjs','');
48
+ break;
49
+
50
+ case 'radio':
51
+ element.checked = (element.value === value);
52
+ break;
53
+
54
+ case 'checkbox':
55
+ for(var j = 0; j < value.length; j++) {
56
+ element.checked = (element.value === value[j]);
57
+ }
58
+ break;
59
+
60
+ case 'select-multiple':
61
+ var values = value.constructor == Array ? value : [value];
62
+
63
+ for(var k = 0; k < element.options.length; k++)
64
+ {
65
+ for(var l = 0; l < values.length; l++)
66
+ {
67
+ element.options[k].selected |= (element.options[k].value == values[l]);
68
+ }
69
+ }
70
+ break;
71
+
72
+ case 'select':
73
+ case 'select-one':
74
+ element.value = value.toString() || value;
75
+ break;
76
+ }
77
+ }
78
+
79
+
80
+ }
81
+
82
+ }
83
+
84
+ // scroll to submitted form element
85
+ var formElement = document.getElementById('mc4wp-form-' + mc4wp.submittedFormId);
86
+
87
+ if(!formElement) {
88
+ return;
89
+ }
90
+
91
+ if(mc4wp.success == false) {
92
+ populateFields(formElement, mc4wp.postData);
93
+ }
94
+
95
+ var scrollToHeight = 0;
96
+ var obj = formElement;
97
+ var windowHeight = window.innerHeight;
98
+
99
+ if (obj.offsetParent) {
100
+ do {
101
+ scrollToHeight += obj.offsetTop;
102
+ } while (obj = obj.offsetParent);
103
+ } else {
104
+ scrollToHeight = formElement.offsetTop;
105
+ }
106
+
107
+ if((windowHeight - 100) > formElement.clientHeight) {
108
+ // vertically center the form
109
+ scrollToHeight = scrollToHeight - ((windowHeight - formElement.clientHeight) / 2);
110
+ } else {
111
+ // scroll a little above the form
112
+ scrollToHeight = scrollToHeight - 100;
113
+ }
114
+
115
+ if(window.jQuery !== undefined) {
116
+ var animationTime = (500 + (scrollToHeight / 2));
117
+ jQuery('html, body').animate({ scrollTop: scrollToHeight }, animationTime);
118
+ } else {
119
+ window.scrollTo(0, scrollToHeight);
120
+ }
121
+
122
+
123
+
124
+ })();
includes/class-admin.php CHANGED
@@ -104,8 +104,8 @@ class MC4WP_Lite_Admin
104
  "registration_form" => "Registration form"
105
  );
106
 
107
- if(is_multisite()) $checkbox_plugins['ms_form'] = "MultiSite forms";
108
- if(class_exists("BuddyPress")) $checkbox_plugins['bp_form'] = "BuddyPress registration";
109
  if(class_exists('bbPress')) $checkbox_plugins['bbpress_forms'] = "bbPress";
110
 
111
  if ( class_exists( 'Easy_Digital_Downloads' ) ) $checkbox_plugins['_edd_checkout'] = "(PRO ONLY) Easy Digital Downloads checkout";
@@ -138,6 +138,7 @@ class MC4WP_Lite_Admin
138
  {
139
  $opts = mc4wp_get_options('checkbox');
140
  $lists = $this->get_mailchimp_lists();
 
141
  $tab = 'checkbox-settings';
142
  include_once MC4WP_LITE_PLUGIN_DIR . 'includes/views/checkbox-settings.php';
143
  }
104
  "registration_form" => "Registration form"
105
  );
106
 
107
+ if(is_multisite()) $checkbox_plugins['multisite_form'] = "MultiSite forms";
108
+ if(class_exists("BuddyPress")) $checkbox_plugins['buddypress_form'] = "BuddyPress registration";
109
  if(class_exists('bbPress')) $checkbox_plugins['bbpress_forms'] = "bbPress";
110
 
111
  if ( class_exists( 'Easy_Digital_Downloads' ) ) $checkbox_plugins['_edd_checkout'] = "(PRO ONLY) Easy Digital Downloads checkout";
138
  {
139
  $opts = mc4wp_get_options('checkbox');
140
  $lists = $this->get_mailchimp_lists();
141
+
142
  $tab = 'checkbox-settings';
143
  include_once MC4WP_LITE_PLUGIN_DIR . 'includes/views/checkbox-settings.php';
144
  }
includes/class-checkbox.php CHANGED
@@ -21,7 +21,7 @@ class MC4WP_Lite_Checkbox
21
  {
22
  $opts = mc4wp_get_options('checkbox');
23
 
24
- add_action('init', array($this, 'on_init'));
25
 
26
  // load checkbox css if necessary
27
  if ( $opts['css'] ) {
@@ -69,19 +69,19 @@ class MC4WP_Lite_Checkbox
69
  add_action('bbp_new_reply', array($this, 'subscribe_from_bbpress_new_reply'), 10, 5);
70
  }
71
 
72
- /* Other actions... catch-all */
73
- if(isset($_POST['mc4wp-try-subscribe']) && $_POST['mc4wp-try-subscribe']) {
74
- add_action('init', array($this, 'subscribe_from_whatever'));
75
- }
76
-
77
  }
78
 
79
- public function on_init()
80
  {
81
  if(function_exists("wpcf7_add_shortcode")) {
82
  wpcf7_add_shortcode('mc4wp_checkbox', array($this, 'get_checkbox'));
83
  add_action('wpcf7_mail_sent', array($this, 'subscribe_from_cf7'));
84
  }
 
 
 
 
 
85
  }
86
 
87
  public function get_checkbox($args = array())
@@ -361,7 +361,15 @@ class MC4WP_Lite_Checkbox
361
 
362
  $lists = $opts['lists'];
363
 
364
- if(empty($lists)) {
 
 
 
 
 
 
 
 
365
  return 'no_lists_selected';
366
  }
367
 
21
  {
22
  $opts = mc4wp_get_options('checkbox');
23
 
24
+ add_action('init', array($this, 'initialize'));
25
 
26
  // load checkbox css if necessary
27
  if ( $opts['css'] ) {
69
  add_action('bbp_new_reply', array($this, 'subscribe_from_bbpress_new_reply'), 10, 5);
70
  }
71
 
 
 
 
 
 
72
  }
73
 
74
+ public function initialize()
75
  {
76
  if(function_exists("wpcf7_add_shortcode")) {
77
  wpcf7_add_shortcode('mc4wp_checkbox', array($this, 'get_checkbox'));
78
  add_action('wpcf7_mail_sent', array($this, 'subscribe_from_cf7'));
79
  }
80
+
81
+ // catch-all (for manual integrations with third-party forms)
82
+ if(isset($_POST['mc4wp-try-subscribe']) && $_POST['mc4wp-try-subscribe']) {
83
+ $this->subscribe_from_whatever();
84
+ }
85
  }
86
 
87
  public function get_checkbox($args = array())
361
 
362
  $lists = $opts['lists'];
363
 
364
+ if(!$lists || empty($lists)) {
365
+ if( ( !defined("DOING_AJAX") || !DOING_AJAX ) && current_user_can('manage_options')) {
366
+ wp_die('
367
+ <h3>MailChimp for WP - Error</h3>
368
+ <p>Please select a list to subscribe to in the <a href="'. admin_url('admin.php?page=mc4wp-lite-checkbox-settings') .'">checkbox settings</a>.</p>
369
+ <p style="font-style:italic; font-size:12px;">This message is only visible to administrators for debugging purposes.</p>
370
+ ', "Error - MailChimp for WP", array('back_link' => true));
371
+ }
372
+
373
  return 'no_lists_selected';
374
  }
375
 
includes/class-form.php CHANGED
@@ -20,6 +20,9 @@ class MC4WP_Lite_Form {
20
  }
21
 
22
  private function __construct() {
 
 
 
23
  $opts = mc4wp_get_options('form');
24
 
25
  if($opts['css']) {
@@ -27,24 +30,29 @@ class MC4WP_Lite_Form {
27
  }
28
 
29
  add_shortcode( 'mc4wp_form', array( $this, 'output_form' ) );
 
 
30
  add_shortcode( 'mc4wp-form', array( $this, 'output_form' ) );
31
 
32
  // enable shortcodes in text widgets
33
  add_filter( 'widget_text', 'shortcode_unautop' );
34
  add_filter( 'widget_text', 'do_shortcode', 11 );
35
 
36
- if ( isset( $_POST['mc4wp_form_submit'] ) ) {
 
37
  $this->ensure_backwards_compatibility();
38
  add_action( 'init', array( $this, 'submit' ) );
39
- add_action( 'wp_footer', array( $this, 'print_scroll_js' ), 99);
40
  }
41
 
42
- add_action( 'wp_enqueue_scripts', array($this, 'register_scripts' ) );
43
  }
44
 
45
- public function register_scripts()
46
  {
 
47
  wp_register_script( 'mc4wp-placeholders', plugins_url('mailchimp-for-wp/assets/js/placeholders.min.js'), array(), MC4WP_LITE_VERSION, true );
 
 
 
48
  }
49
 
50
  public function add_stylesheets($stylesheets) {
@@ -82,17 +90,26 @@ class MC4WP_Lite_Form {
82
  // replace special values
83
  $form_markup = str_replace( array( '%N%', '{n}' ), $this->form_instance_number, $form_markup );
84
  $form_markup = mc4wp_replace_variables( $form_markup, array_values( $opts['lists'] ) );
 
 
85
  $form_markup = apply_filters('mc4wp_form_content', $form_markup);
 
 
 
 
86
  $content .= $form_markup;
87
 
 
 
 
88
  // hidden fields
89
- $content .= '<textarea name="mc4wp_required_but_not_really" style="display: none;"></textarea>';
90
- $content .= '<input type="hidden" name="mc4wp_form_submit" value="1" />';
91
- $content .= '<input type="hidden" name="mc4wp_form_instance" value="'. $this->form_instance_number .'" />';
92
- $content .= '<input type="hidden" name="mc4wp_form_nonce" value="'. wp_create_nonce( '_mc4wp_form_nonce' ) .'" />';
93
  }
94
 
95
- if ( $this->form_instance_number == $this->submitted_form_instance ) {
96
 
97
  if ( $this->success ) {
98
  $content .= '<div class="mc4wp-alert mc4wp-success">' . __( $opts['text_success'] ) . '</div>';
@@ -101,18 +118,13 @@ class MC4WP_Lite_Form {
101
  $api = mc4wp_get_api();
102
  $e = $this->error;
103
 
104
- if ( $e == 'already_subscribed' ) {
105
- $text = ( empty( $opts['text_already_subscribed'] ) ) ? $api->get_error_message() : $opts['text_already_subscribed'];
106
- $content .= '<div class="mc4wp-alert mc4wp-notice">'. __( $text ) .'</div>';
107
- } elseif ( isset( $opts['text_' . $e] ) && !empty( $opts['text_'. $e] ) ) {
108
- $content .= '<div class="mc4wp-alert mc4wp-error">' . __( $opts['text_' . $e] ) . '</div>';
109
- }
110
-
111
- if ( current_user_can( 'manage_options' ) ) {
112
 
113
- if ( $api->has_error() ) {
114
- $content .= '<div class="mc4wp-alert mc4wp-error"><strong>Admin notice:</strong> '. $api->get_error_message() . '</div>';
115
- }
116
  }
117
 
118
  }
@@ -138,78 +150,51 @@ class MC4WP_Lite_Form {
138
  return $content;
139
  }
140
 
 
 
 
 
 
 
141
  public function submit() {
142
- $opts = mc4wp_get_options('form');
143
- $this->submitted_form_instance = (int) $_POST['mc4wp_form_instance'];
144
 
145
- if ( !isset( $_POST['mc4wp_form_nonce'] ) || !wp_verify_nonce( $_POST['mc4wp_form_nonce'], '_mc4wp_form_nonce' ) ) {
 
146
  $this->error = 'invalid_nonce';
147
  return false;
148
  }
149
 
150
- if ( !isset( $_POST['EMAIL'] ) || !is_email( $_POST['EMAIL'] ) ) {
151
- // no (valid) e-mail address has been given
152
- $this->error = 'invalid_email';
153
  return false;
154
  }
155
 
156
- if ( isset( $_POST['mc4wp_required_but_not_really'] ) && !empty( $_POST['mc4wp_required_but_not_really'] ) ) {
157
- // spam bot filled the honeypot field
158
- return false;
 
 
 
 
159
  }
160
 
161
- $email = $_POST['EMAIL'];
162
-
163
- // setup merge vars
164
- $merge_vars = array();
165
-
166
- foreach ( $_POST as $name => $value ) {
167
-
168
- // only add uppercases fields to merge variables array
169
- if ( !empty( $name ) && $name == 'EMAIL' || $name !== strtoupper( $name ) ) { continue; }
170
-
171
- if ( $name === 'GROUPINGS' ) {
172
-
173
- $groupings = $value;
174
-
175
- // malformed
176
- if ( !is_array( $groupings ) ) { continue; }
177
-
178
- // setup groupings array
179
- $merge_vars['GROUPINGS'] = array();
180
-
181
- foreach ( $groupings as $grouping_id_or_name => $groups ) {
182
-
183
- $grouping = array();
184
-
185
- if ( is_numeric( $grouping_id_or_name ) ) {
186
- $grouping['id'] = $grouping_id_or_name;
187
- } else {
188
- $grouping['name'] = $grouping_id_or_name;
189
- }
190
-
191
- if ( !is_array( $groups ) ) {
192
- $grouping['groups'] = explode( ',', $groups );
193
- } else {
194
- $grouping['groups'] = $groups;
195
- }
196
-
197
- // add grouping to array
198
- $merge_vars['GROUPINGS'][] = $grouping;
199
- }
200
-
201
- if ( empty( $merge_vars['GROUPINGS'] ) ) { unset( $merge_vars['GROUPINGS'] ); }
202
-
203
- } else {
204
- $merge_vars[$name] = $value;
205
- }
206
 
207
- }
 
 
 
 
 
 
 
208
 
209
- $result = $this->subscribe( $email, $merge_vars );
210
 
211
- if ( $result === true ) {
212
- $this->success = true;
213
 
214
  // check if we want to redirect the visitor
215
  if ( !empty( $opts['redirect'] ) ) {
@@ -220,9 +205,6 @@ class MC4WP_Lite_Form {
220
  return true;
221
  } else {
222
 
223
- $this->success = false;
224
- $this->error = $result;
225
-
226
  return false;
227
  }
228
  }
@@ -236,19 +218,6 @@ class MC4WP_Lite_Form {
236
  */
237
  public function ensure_backwards_compatibility() {
238
 
239
- // upercase $_POST variables
240
- foreach ( $_POST as $name => $value ) {
241
-
242
- // skip mc4wp internal vars
243
- if ($name == strtoupper($name) || in_array( $name, array( 'mc4wp_form_instance', 'mc4wp_form_nonce', 'mc4wp_required_but_not_really', 'mc4wp_form_submit' ) ) ) {
244
- continue;
245
- }
246
-
247
- $ucname = strtoupper( $name );
248
- $_POST[$ucname] = $value;
249
- unset( $_POST[$name] );
250
- }
251
-
252
  // detect old style GROUPINGS, then fix it.
253
  if ( isset( $_POST['GROUPINGS'] ) && is_array( $_POST['GROUPINGS'] ) && isset( $_POST['GROUPINGS'][0] ) ) {
254
 
@@ -280,29 +249,108 @@ class MC4WP_Lite_Form {
280
  return;
281
  }
282
 
283
- public function subscribe( $email, array $merge_vars = array() ) {
284
- $api = mc4wp_get_api();
285
- $opts = mc4wp_get_options('form');
286
 
287
- $lists = $opts['lists'];
 
288
 
289
- if ( empty( $lists ) ) {
290
- return 'no_lists_selected';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  }
292
 
293
- // guess FNAME and LNAME
294
- if ( isset( $merge_vars['NAME'] ) && !isset( $merge_vars['FNAME'] ) && !isset( $merge_vars['LNAME'] ) ) {
295
 
296
- $strpos = strpos( $merge_vars['NAME'], ' ' );
297
 
298
- if ( $strpos ) {
299
- $merge_vars['FNAME'] = trim( substr( $merge_vars['NAME'], 0, $strpos ) );
300
- $merge_vars['LNAME'] = trim( substr( $merge_vars['NAME'], $strpos ) );
301
  } else {
302
  $merge_vars['FNAME'] = $merge_vars['NAME'];
303
  }
304
  }
305
 
 
 
 
 
 
 
 
 
 
306
  do_action('mc4wp_before_subscribe', $email, $merge_vars, 0);
307
 
308
  $result = false;
@@ -310,66 +358,26 @@ class MC4WP_Lite_Form {
310
  $lists = apply_filters('mc4wp_lists', $lists, $merge_vars);
311
 
312
  foreach ( $lists as $list_id ) {
313
-
314
  $list_merge_vars = apply_filters('mc4wp_merge_vars', $merge_vars, 0, $list_id);
315
  $result = $api->subscribe( $list_id, $email, $list_merge_vars, $email_type, $opts['double_optin'] );
316
-
317
- if($result === true) {
318
- $from_url = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
319
- do_action('mc4wp_subscribe_form', $email, $list_id, 0, $merge_vars, $from_url);
320
- }
321
  }
322
 
323
  do_action('mc4wp_after_subscribe', $email, $merge_vars, 0, $result);
324
 
 
325
  if ( $result === true ) {
 
 
 
 
 
326
  $this->success = true;
327
  } else {
328
  $this->success = false;
329
  $this->error = $result;
330
  }
331
 
332
- // flawed
333
- // this will only return the result of the last list a subscribe attempt has been sent to
334
- return $result;
335
- }
336
-
337
- public function print_scroll_js() {
338
- $form_id = $_POST['mc4wp_form_instance'];
339
- ?><script type="text/javascript">(function(){var e=document.getElementById("mc4wp-form-<?php echo esc_js($form_id); ?>");if(!e){return}var t=0;var n=e;var r=window.innerHeight;if(n.offsetParent){do{t+=n.offsetTop}while(n=n.offsetParent)}else{t=e.offsetTop}if(r>e.clientHeight){t=t-(r-e.clientHeight)/2}if(window.jQuery!==undefined){var i=500+t;jQuery("html, body").animate({scrollTop:t},i)}else{window.scrollTo(0,t)}})()</script><?php
340
- /*?><script>
341
- (function() {
342
- var element = document.getElementById('mc4wp-form-<?php echo esc_js($form_id); ?>');
343
-
344
- if(!element) {
345
- return;
346
- }
347
-
348
- var scrollToHeight = 0;
349
- var obj = element;
350
- var windowHeight = window.innerHeight;
351
-
352
- if (obj.offsetParent) {
353
- do {
354
- scrollToHeight += obj.offsetTop;
355
- } while (obj = obj.offsetParent);
356
- } else {
357
- scrollToHeight = element.offsetTop;
358
- }
359
-
360
- if(windowHeight > element.clientHeight) {
361
- scrollToHeight = scrollToHeight - ((windowHeight - element.clientHeight) / 2);
362
- }
363
-
364
- if(window.jQuery !== undefined) {
365
- var animationTime = (500 + scrollToHeight);
366
- jQuery('html, body').animate({ scrollTop: scrollToHeight }, animationTime);
367
- } else {
368
- window.scrollTo(0, scrollToHeight);
369
- }
370
- })();
371
- </script>
372
- <?php*/
373
  }
374
 
375
  }
20
  }
21
 
22
  private function __construct() {
23
+
24
+ add_action('init', array($this, 'initialize') );
25
+
26
  $opts = mc4wp_get_options('form');
27
 
28
  if($opts['css']) {
30
  }
31
 
32
  add_shortcode( 'mc4wp_form', array( $this, 'output_form' ) );
33
+
34
+ // do not use, just here for backwards compatibility. removed in 2.0.
35
  add_shortcode( 'mc4wp-form', array( $this, 'output_form' ) );
36
 
37
  // enable shortcodes in text widgets
38
  add_filter( 'widget_text', 'shortcode_unautop' );
39
  add_filter( 'widget_text', 'do_shortcode', 11 );
40
 
41
+ // has a MC4WP form been submitted?
42
+ if ( isset( $_POST['_mc4wp_form_submit'] ) ) {
43
  $this->ensure_backwards_compatibility();
44
  add_action( 'init', array( $this, 'submit' ) );
 
45
  }
46
 
 
47
  }
48
 
49
+ public function initialize()
50
  {
51
+ // register placeholder script, which will later be enqueued for IE only
52
  wp_register_script( 'mc4wp-placeholders', plugins_url('mailchimp-for-wp/assets/js/placeholders.min.js'), array(), MC4WP_LITE_VERSION, true );
53
+
54
+ // register non-AJAX script (that handles form submissions)
55
+ wp_register_script( 'mc4wp-forms', plugins_url('mailchimp-for-wp/assets/js/forms.js'), array(), MC4WP_LITE_VERSION, true );
56
  }
57
 
58
  public function add_stylesheets($stylesheets) {
90
  // replace special values
91
  $form_markup = str_replace( array( '%N%', '{n}' ), $this->form_instance_number, $form_markup );
92
  $form_markup = mc4wp_replace_variables( $form_markup, array_values( $opts['lists'] ) );
93
+
94
+ // allow plugins to alter form content
95
  $form_markup = apply_filters('mc4wp_form_content', $form_markup);
96
+
97
+ // allow plugins to add form fields
98
+ do_action('mc4wp_before_form_fields', 0);
99
+
100
  $content .= $form_markup;
101
 
102
+ // allow plugins to add form fields
103
+ do_action('mc4wp_after_form_fields', 0);
104
+
105
  // hidden fields
106
+ $content .= '<textarea name="_mc4wp_required_but_not_really" style="display: none;"></textarea>';
107
+ $content .= '<input type="hidden" name="_mc4wp_form_submit" value="1" />';
108
+ $content .= '<input type="hidden" name="_mc4wp_form_instance" value="'. $this->form_instance_number .'" />';
109
+ $content .= '<input type="hidden" name="_mc4wp_form_nonce" value="'. wp_create_nonce( '_mc4wp_form_nonce' ) .'" />';
110
  }
111
 
112
+ if ( $this->form_instance_number === $this->submitted_form_instance ) {
113
 
114
  if ( $this->success ) {
115
  $content .= '<div class="mc4wp-alert mc4wp-success">' . __( $opts['text_success'] ) . '</div>';
118
  $api = mc4wp_get_api();
119
  $e = $this->error;
120
 
121
+ $error_type = ($e == 'already_subscribed') ? 'notice' : 'error';
122
+ $error_message = __($opts['text_' . $e], 'mailchimp-for-wp');
123
+ $content .= '<div class="mc4wp-alert mc4wp-'. $error_type .'">'. $error_message . '</div>';
 
 
 
 
 
124
 
125
+ // show the eror returned by MailChimp?
126
+ if ( $api->has_error() && current_user_can( 'manage_options' ) ) {
127
+ $content .= '<div class="mc4wp-alert mc4wp-error"><strong>Admin notice:</strong> '. $api->get_error_message() . '</div>';
128
  }
129
 
130
  }
150
  return $content;
151
  }
152
 
153
+ /**
154
+ * Submits the form
155
+ * Creates a subscribe request from the posted data
156
+ *
157
+ * @return boolean
158
+ */
159
  public function submit() {
160
+ // store number of submitted form
161
+ $this->submitted_form_instance = absint($_POST['_mc4wp_form_instance']);
162
 
163
+ // validate form nonce
164
+ if ( !isset( $_POST['_mc4wp_form_nonce'] ) || !wp_verify_nonce( $_POST['_mc4wp_form_nonce'], '_mc4wp_form_nonce' ) ) {
165
  $this->error = 'invalid_nonce';
166
  return false;
167
  }
168
 
169
+ // ensure honeypot was not filed
170
+ if ( isset( $_POST['_mc4wp_required_but_not_really'] ) && !empty( $_POST['_mc4wp_required_but_not_really'] ) ) {
171
+ $this->error = 'spam';
172
  return false;
173
  }
174
 
175
+ // setup array of data entered by user
176
+ // not manipulating anything yet.
177
+ $data = array();
178
+ foreach($_POST as $name => $value) {
179
+ if($name[0] !== '_') {
180
+ $data[$name] = $value;
181
+ }
182
  }
183
 
184
+ $success = $this->subscribe($data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
+ // enqueue scripts (in footer)
187
+ wp_enqueue_script( 'mc4wp-forms' );
188
+ wp_localize_script( 'mc4wp-forms', 'mc4wp', array(
189
+ 'success' => ($success) ? 1 : 0,
190
+ 'submittedFormId' => $this->submitted_form_instance,
191
+ 'postData' => $data
192
+ )
193
+ );
194
 
195
+ if ($success) {
196
 
197
+ $opts = mc4wp_get_options('form');
 
198
 
199
  // check if we want to redirect the visitor
200
  if ( !empty( $opts['redirect'] ) ) {
205
  return true;
206
  } else {
207
 
 
 
 
208
  return false;
209
  }
210
  }
218
  */
219
  public function ensure_backwards_compatibility() {
220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  // detect old style GROUPINGS, then fix it.
222
  if ( isset( $_POST['GROUPINGS'] ) && is_array( $_POST['GROUPINGS'] ) && isset( $_POST['GROUPINGS'][0] ) ) {
223
 
249
  return;
250
  }
251
 
252
+ public function subscribe( array $data ) {
 
 
253
 
254
+ $email = null;
255
+ $merge_vars = array();
256
 
257
+ foreach ( $data as $name => $value ) {
258
+
259
+ // uppercase all variables
260
+ $name = trim(strtoupper($name));
261
+ $value = (is_scalar($value)) ? trim($value) : $value;
262
+
263
+ if( $name === 'EMAIL' && is_email($value) ) {
264
+ // set the email address
265
+ $email = $value;
266
+ } else if ( $name === 'GROUPINGS' ) {
267
+
268
+ $groupings = $value;
269
+
270
+ // malformed
271
+ if ( !is_array( $groupings ) ) { continue; }
272
+
273
+ // setup groupings array
274
+ $merge_vars['GROUPINGS'] = array();
275
+
276
+ foreach ( $groupings as $grouping_id_or_name => $groups ) {
277
+
278
+ $grouping = array();
279
+
280
+ if ( is_numeric( $grouping_id_or_name ) ) {
281
+ $grouping['id'] = $grouping_id_or_name;
282
+ } else {
283
+ $grouping['name'] = $grouping_id_or_name;
284
+ }
285
+
286
+ if ( !is_array( $groups ) ) {
287
+ $grouping['groups'] = explode( ',', $groups );
288
+ } else {
289
+ $grouping['groups'] = $groups;
290
+ }
291
+
292
+ // add grouping to array
293
+ $merge_vars['GROUPINGS'][] = $grouping;
294
+ }
295
+
296
+ if ( empty( $merge_vars['GROUPINGS'] ) ) { unset( $merge_vars['GROUPINGS'] ); }
297
+
298
+ } else if($name === 'BIRTHDAY') {
299
+ // format birthdays in the DD/MM format required by MailChimp
300
+ $merge_vars['BIRTHDAY'] = date('d/m', strtotime( $value ) );
301
+ } else if($name === 'ADDRESS') {
302
+
303
+ if(!isset($value['addr1'])) {
304
+ // addr1, addr2, city, state, zip, country
305
+ $addr_pieces = explode(',', $value);
306
+
307
+ // try to fill it.... this is a long shot
308
+ $merge_vars['ADDRESS'] = array(
309
+ 'addr1' => $addr_pieces[0],
310
+ 'city' => (isset($addr_pieces[1])) ? $addr_pieces[1] : '',
311
+ 'state' => (isset($addr_pieces[2])) ? $addr_pieces[2] : '',
312
+ 'zip' => (isset($addr_pieces[3])) ? $addr_pieces[3] : ''
313
+ );
314
+
315
+ } else {
316
+ // form contains the necessary fields already: perfection
317
+ $merge_vars['ADDRESS'] = $value;
318
+ }
319
+
320
+ } else {
321
+ // just add to merge vars array
322
+ $merge_vars[$name] = $value;
323
+ }
324
+ }
325
+
326
+ // check if an email address has been found
327
+ if( !$email ) {
328
+ $this->error = 'invalid_email';
329
+ return false;
330
  }
331
 
332
+ // Try to guess FNAME and LNAME if they are not given, but NAME is
333
+ if(isset($merge_vars['NAME']) && !isset($merge_vars['FNAME']) && !isset($merge_vars['LNAME'])) {
334
 
335
+ $strpos = strpos($merge_vars['NAME'], ' ');
336
 
337
+ if($strpos) {
338
+ $merge_vars['FNAME'] = substr($merge_vars['NAME'], 0, $strpos);
339
+ $merge_vars['LNAME'] = substr($merge_vars['NAME'], $strpos);
340
  } else {
341
  $merge_vars['FNAME'] = $merge_vars['NAME'];
342
  }
343
  }
344
 
345
+ $api = mc4wp_get_api();
346
+ $opts = mc4wp_get_options('form');
347
+
348
+ $lists = $opts['lists'];
349
+
350
+ if ( empty( $lists ) ) {
351
+ return false;
352
+ }
353
+
354
  do_action('mc4wp_before_subscribe', $email, $merge_vars, 0);
355
 
356
  $result = false;
358
  $lists = apply_filters('mc4wp_lists', $lists, $merge_vars);
359
 
360
  foreach ( $lists as $list_id ) {
 
361
  $list_merge_vars = apply_filters('mc4wp_merge_vars', $merge_vars, 0, $list_id);
362
  $result = $api->subscribe( $list_id, $email, $list_merge_vars, $email_type, $opts['double_optin'] );
 
 
 
 
 
363
  }
364
 
365
  do_action('mc4wp_after_subscribe', $email, $merge_vars, 0, $result);
366
 
367
+ // flawed, will only check the result of the last list
368
  if ( $result === true ) {
369
+
370
+ // do not use... will be removed in 2.0
371
+ $from_url = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
372
+ do_action('mc4wp_subscribe_form', $email, $list_id, 0, $merge_vars, $from_url);
373
+
374
  $this->success = true;
375
  } else {
376
  $this->success = false;
377
  $this->error = $result;
378
  }
379
 
380
+ return $this->success;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
  }
382
 
383
  }
includes/class-plugin.php CHANGED
@@ -68,8 +68,6 @@ class MC4WP_Lite {
68
  update_option('mc4wp_transfered_old_widgets', true);
69
  }
70
 
71
-
72
-
73
 
74
  // transfer old options to new options format
75
  if (isset( $options['mailchimp_api_key'] )) {
68
  update_option('mc4wp_transfered_old_widgets', true);
69
  }
70
 
 
 
71
 
72
  // transfer old options to new options format
73
  if (isset( $options['mailchimp_api_key'] )) {
includes/class-widget.php CHANGED
@@ -11,8 +11,8 @@ class MC4WP_Lite_Widget extends WP_Widget {
11
  function __construct() {
12
  parent::__construct(
13
  'MC4WP_Widget', // Base ID
14
- __( 'MailChimp Sign-Up Form', 'mailchimp-for-wp' ), // Name
15
- array( 'description' => __( 'Displays your MailChimp sign-up form', 'mailchimp-for-wp' ), ) // Args
16
  );
17
  }
18
 
11
  function __construct() {
12
  parent::__construct(
13
  'MC4WP_Widget', // Base ID
14
+ __( 'MailChimp for WP Form', 'mailchimp-for-wp' ), // Name
15
+ array( 'description' => __( 'Displays your MailChimp for WordPress sign-up form', 'mailchimp-for-wp' ), ) // Args
16
  );
17
  }
18
 
includes/views/checkbox-settings.php CHANGED
@@ -12,6 +12,12 @@
12
  <form action="options.php" method="post">
13
  <?php settings_fields( 'mc4wp_lite_checkbox_settings' ); ?>
14
 
 
 
 
 
 
 
15
  <table class="form-table">
16
  <tr valign="top">
17
  <th scope="row">Lists</th>
12
  <form action="options.php" method="post">
13
  <?php settings_fields( 'mc4wp_lite_checkbox_settings' ); ?>
14
 
15
+ <?php if(empty($opts['lists'])) { ?>
16
+ <div class="mc4wp-info">
17
+ <p>If you want to use sign-up checkboxes, select at least one MailChimp list to subscribe people to.</p>
18
+ </div>
19
+ <?php } ?>
20
+
21
  <table class="form-table">
22
  <tr valign="top">
23
  <th scope="row">Lists</th>
mailchimp-for-wp.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: MailChimp for WordPress Lite
4
  Plugin URI: http://dannyvankooten.com/mailchimp-for-wordpress/
5
  Description: Lite version of MailChimp for WordPress. Adds various sign-up methods to your website.
6
- Version: 1.4.8
7
  Author: Danny van Kooten
8
  Author URI: http://dannyvanKooten.com
9
  License: GPL v3
@@ -39,12 +39,11 @@ if(!function_exists('is_plugin_active')) {
39
  if(!is_plugin_active('mailchimp-for-wp-pro/mailchimp-for-wp-pro.php')
40
  && !(is_admin() && isset($_GET['action']) && $_GET['action'] == 'activate' && isset($_GET['plugin']) && $_GET['plugin'] == 'mailchimp-for-wp-pro/mailchimp-for-wp-pro.php') ) {
41
 
42
- define("MC4WP_LITE_VERSION", "1.4.8");
43
  define("MC4WP_LITE_PLUGIN_DIR", plugin_dir_path(__FILE__));
44
 
45
  require_once MC4WP_LITE_PLUGIN_DIR . 'includes/functions.php';
46
-
47
- include_once MC4WP_LITE_PLUGIN_DIR . 'includes/class-plugin.php';
48
  MC4WP_Lite::init();
49
 
50
  if(is_admin() && (!defined("DOING_AJAX") || !DOING_AJAX)) {
3
  Plugin Name: MailChimp for WordPress Lite
4
  Plugin URI: http://dannyvankooten.com/mailchimp-for-wordpress/
5
  Description: Lite version of MailChimp for WordPress. Adds various sign-up methods to your website.
6
+ Version: 1.5
7
  Author: Danny van Kooten
8
  Author URI: http://dannyvanKooten.com
9
  License: GPL v3
39
  if(!is_plugin_active('mailchimp-for-wp-pro/mailchimp-for-wp-pro.php')
40
  && !(is_admin() && isset($_GET['action']) && $_GET['action'] == 'activate' && isset($_GET['plugin']) && $_GET['plugin'] == 'mailchimp-for-wp-pro/mailchimp-for-wp-pro.php') ) {
41
 
42
+ define("MC4WP_LITE_VERSION", "1.5");
43
  define("MC4WP_LITE_PLUGIN_DIR", plugin_dir_path(__FILE__));
44
 
45
  require_once MC4WP_LITE_PLUGIN_DIR . 'includes/functions.php';
46
+ require_once MC4WP_LITE_PLUGIN_DIR . 'includes/class-plugin.php';
 
47
  MC4WP_Lite::init();
48
 
49
  if(is_admin() && (!defined("DOING_AJAX") || !DOING_AJAX)) {
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === MailChimp for WordPress ===
2
  Contributors: DvanKooten
3
  Donate link: http://dannyvankooten.com/donate/
4
- Tags: mailchimp, widget, form, checkbox, sign-up form, mandrill, buddypress, multisite, bbpress, contact form 7, newsletter, mailinglist, cf7
5
  Requires at least: 3.1
6
  Tested up to: 3.8
7
- Stable tag: 1.4.8
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -74,25 +74,35 @@ If you like the plugin, upgrade to [MailChimp for WordPress Pro](http://dannyvan
74
 
75
  > **Is there a premium version of this plugin?**
76
  >
77
- > Yes, there is and you will love it. Some Pro features are:
78
  >
79
- > 1. (Multiple) AJAX powered forms (no page reload after submitting)
80
- > 1. Design beautiful forms from your admin panel, no CSS knowledge required!
81
- > 1. Reports, learn when, where and how your visitors subscribed.
82
- > 1. Easily add *all* your MailChimp list fields to your forms using the add-field tool.
83
- > 1. Priority support
84
  >
85
- > [More information](http://dannyvankooten.com/mailchimp-for-wordpress/?utm_source=wp-plugin-repo&utm_medium=link&utm_campaign=faq-link) | [Demo](http://dannyvankooten.com/mailchimp-for-wordpress/demo/?utm_source=wp-plugin-repo&utm_medium=link&utm_campaign=faq-link)
86
 
87
  = How to display a form in posts or pages? =
88
  Use the `[mc4wp_form]` shortcode.
89
 
90
  = How to display a form in widget areas like a sidebar? =
91
- Use the *MailChimp Sign-Up Form* Widget that comes with the plugin.
92
 
93
  = How to display a form in my template files? =
94
  Use the `mc4wp_form()` function.
95
 
 
 
 
 
 
 
 
 
 
 
 
96
  = The form shows a success message but subscribers are not added to my list(s)? =
97
  If the form shows a success message, it means MailChimp accepted the sign-up request and will take over from there. MailChimp could have a slight delay sending the confirmation email though, just be patient.
98
 
@@ -186,6 +196,16 @@ Your theme folder can be found by browsing to `/wp-content/themes/your-theme-nam
186
 
187
  == Changelog ==
188
 
 
 
 
 
 
 
 
 
 
 
189
  = 1.4.8 - 10 December 2013 =
190
  * Fixed: "bug" that fetched lists again on every plugin settings page - huge performance improvements on the settings pages.
191
  * Improved: Longer cache time for combined CSS file.
1
  === MailChimp for WordPress ===
2
  Contributors: DvanKooten
3
  Donate link: http://dannyvankooten.com/donate/
4
+ Tags: mailchimp,form,shortcode,widget,checkbox,comment,newsletter,buddypress,multisite,bbpress,woocommerce,easy digital downloads,contact form,contact form 7
5
  Requires at least: 3.1
6
  Tested up to: 3.8
7
+ Stable tag: 1.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
74
 
75
  > **Is there a premium version of this plugin?**
76
  >
77
+ > Yes, you will love it. Some Pro features are:
78
  >
79
+ > 1. Multiple forms, each subscribing to one or multiple MailChimp list(s).
80
+ > 1. AJAX - no page reload after submitting a sign-up form.
81
+ > 1. Custom color themes and a custom form styles designer.
82
+ > 1. Statistics & log, learn when, where and how your visitors subscribed.
 
83
  >
84
+ > [More Pro features](http://dannyvankooten.com/mailchimp-for-wordpress/?utm_source=wp-plugin-repo&utm_medium=link&utm_campaign=faq-link) | [Demo](http://dannyvankooten.com/mailchimp-for-wordpress/demo/?utm_source=wp-plugin-repo&utm_medium=link&utm_campaign=faq-link)
85
 
86
  = How to display a form in posts or pages? =
87
  Use the `[mc4wp_form]` shortcode.
88
 
89
  = How to display a form in widget areas like a sidebar? =
90
+ Use the **MailChimp for WP Form** Widget that comes with the plugin.
91
 
92
  = How to display a form in my template files? =
93
  Use the `mc4wp_form()` function.
94
 
95
+ `
96
+ if( function_exists( 'mc4wp_form' ) ) {
97
+ mc4wp_form();
98
+ }
99
+ `
100
+
101
+ = Oops. Something went wrong. =
102
+ `Admin notice: FNAME must be provided - Please enter a value`
103
+
104
+ Your selected MailChimp list requires a field named **FNAME**. Either go into your MailChimp list settings and make the FNAME field optional or add it to your form (using the *Add MailChimp field** select box).
105
+
106
  = The form shows a success message but subscribers are not added to my list(s)? =
107
  If the form shows a success message, it means MailChimp accepted the sign-up request and will take over from there. MailChimp could have a slight delay sending the confirmation email though, just be patient.
108
 
196
 
197
  == Changelog ==
198
 
199
+ = 1.5 - 18 December 2013 =
200
+ * Added: BIRTHDAY fields will now be formatted in the DD/MM format automatically
201
+ * Added: The plugin will now try to automatically format ADDRESS fields.
202
+ * Added: Form fields will now keep their value when a validation error occurs
203
+ * Improved: Cache headers for CSS file
204
+ * Improved: Added notice when no lists selected and using sign-up checkboxes
205
+ * Improved: Various code improvements
206
+ * Fixed: Error when activating Pro with the Lite plugin still activated.
207
+ * Fixed: BuddyPress & MultiSite checkbox not automatically added
208
+
209
  = 1.4.8 - 10 December 2013 =
210
  * Fixed: "bug" that fetched lists again on every plugin settings page - huge performance improvements on the settings pages.
211
  * Improved: Longer cache time for combined CSS file.