MailChimp for WordPress - Version 2.2

Version Description

  • December 9, 2014 =

Fixes

  • "Select at least one list" notice appearing when unselecting any MailChimp list in Form settings
  • If an error occurs, textareas will no longer lose their value

Improvements

  • Improved the way form submissions are handled
  • Minor code & documentation improvements
  • Updated Dutch, French, Portugese and Spanish translations

Additions

  • Added sign-up checkbox integration for WooCommerce checkout.
  • Added sign-up checkbox integration for Easy Digital Downloads checkout.
  • The entered email will now be appended to the URL when redirecting to another page
Download this release

Release Info

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

Code changes from version 2.1.7 to 2.2

Files changed (45) hide show
  1. assets/css/admin.css +14 -14
  2. assets/css/admin.min.css +1 -1
  3. assets/js/admin.js +33 -25
  4. assets/js/admin.min.js +1 -1
  5. assets/js/form-request.js +4 -0
  6. assets/js/form-request.min.js +1 -1
  7. includes/class-admin.php +10 -7
  8. includes/class-checkbox-manager.php +26 -10
  9. includes/class-form-manager.php +14 -10
  10. includes/class-form-request.php +343 -235
  11. includes/class-mailchimp.php +13 -2
  12. includes/class-plugin.php +2 -0
  13. includes/functions/general.php +15 -9
  14. includes/functions/template.php +2 -2
  15. includes/integrations/class-edd.php +82 -0
  16. includes/integrations/class-integration.php +101 -21
  17. includes/integrations/class-woocommerce.php +91 -0
  18. includes/views/api-settings.php +1 -1
  19. includes/views/checkbox-settings.php +11 -2
  20. includes/views/form-settings.php +1 -1
  21. languages/mailchimp-for-wp-af_ZA.po +268 -170
  22. languages/mailchimp-for-wp-bg_BG.po +269 -171
  23. languages/mailchimp-for-wp-cs_CZ.po +277 -179
  24. languages/mailchimp-for-wp-da_DK.po +268 -170
  25. languages/mailchimp-for-wp-de_DE.po +276 -178
  26. languages/mailchimp-for-wp-el_GR.po +268 -170
  27. languages/mailchimp-for-wp-es_ES.po +321 -222
  28. languages/mailchimp-for-wp-fi_FI.po +268 -170
  29. languages/mailchimp-for-wp-fr_FR.po +351 -250
  30. languages/mailchimp-for-wp-gl_ES.po +268 -170
  31. languages/mailchimp-for-wp-he_IL.po +268 -170
  32. languages/mailchimp-for-wp-hu_HU.po +279 -181
  33. languages/mailchimp-for-wp-it_IT.po +278 -180
  34. languages/mailchimp-for-wp-ja_JP.po +268 -170
  35. languages/mailchimp-for-wp-lt_LT.po +268 -170
  36. languages/mailchimp-for-wp-ms_MY.po +268 -170
  37. languages/mailchimp-for-wp-nl_NL.po +278 -180
  38. languages/mailchimp-for-wp-no_NO.po +270 -172
  39. languages/mailchimp-for-wp-pl_PL.po +268 -170
  40. languages/mailchimp-for-wp-pt_BR.po +300 -201
  41. languages/mailchimp-for-wp-ro_RO.po +268 -170
  42. languages/mailchimp-for-wp-ru_RU.po +269 -171
  43. languages/mailchimp-for-wp-sk_SK.po +276 -178
  44. languages/mailchimp-for-wp-sl_SI.po +268 -170
  45. languages/mailchimp-for-wp-sr_RS.po +176 -87
assets/css/admin.css CHANGED
@@ -19,7 +19,7 @@
19
  vertical-align: top !important;
20
  }
21
 
22
- #mc4wp .mc4wp-box{
23
  margin-bottom:20px;
24
  }
25
 
@@ -67,7 +67,7 @@
67
  color:#aaa;
68
  }
69
 
70
- #mc4wp span.status{
71
  display:inline-block;
72
  padding:3px 6px;
73
  color:white;
@@ -75,28 +75,28 @@
75
  font-weight:bold;
76
  }
77
 
78
- #mc4wp span.positive{
79
  background-color:green;
80
  }
81
 
82
- #mc4wp span.negative{
83
  background-color:lightGrey;
84
  }
85
 
86
- #mc4wp table th{
87
  text-align:left;
88
  }
89
 
90
- #mc4wp table.form-table tr td:first-child,
91
- #mc4wp table.form-table tr th:first-child{
92
  padding-left:0;
93
  }
94
 
95
- #mc4wptd.nowrap{
96
  white-space: nowrap
97
  }
98
 
99
- #mc4wp td.desc{
100
  font-style:italic;
101
  font-size:11px;
102
  }
@@ -109,7 +109,7 @@
109
  margin: 1em 0 !important;
110
  }
111
 
112
- #mc4wp .mc4wp-col {
113
  float:left;
114
  -webkit-box-sizing: border-box;
115
  -moz-box-sizing:border-box;
@@ -118,11 +118,11 @@
118
  padding:0 5px;
119
  }
120
 
121
- #mc4wp .mc4wp-first{
122
  padding-left:0;
123
  }
124
 
125
- #mc4wp .mc4wp-last{
126
  padding-right:0;
127
  }
128
 
@@ -158,7 +158,7 @@ table.mc4wp-help tr:hover {
158
  background-color: #ddd;
159
  }
160
 
161
- #mc4wp .wp-list-table code {
162
  float:right;
163
  }
164
 
@@ -178,7 +178,7 @@ table.mc4wp-help tr:hover {
178
  margin-top:25px;
179
  padding-top: 25px;
180
  }
181
- #mc4wp .wp-list-table code {
182
  float: none;
183
  }
184
 
19
  vertical-align: top !important;
20
  }
21
 
22
+ #mc4wp-admin .mc4wp-box{
23
  margin-bottom:20px;
24
  }
25
 
67
  color:#aaa;
68
  }
69
 
70
+ #mc4wp-admin span.status{
71
  display:inline-block;
72
  padding:3px 6px;
73
  color:white;
75
  font-weight:bold;
76
  }
77
 
78
+ #mc4wp-admin span.positive{
79
  background-color:green;
80
  }
81
 
82
+ #mc4wp-admin span.negative{
83
  background-color:lightGrey;
84
  }
85
 
86
+ #mc4wp-admin table th{
87
  text-align:left;
88
  }
89
 
90
+ #mc4wp-admin table.form-table tr td:first-child,
91
+ #mc4wp-admin table.form-table tr th:first-child{
92
  padding-left:0;
93
  }
94
 
95
+ #mc4wp-admin td.nowrap{
96
  white-space: nowrap
97
  }
98
 
99
+ #mc4wp-admin td.desc{
100
  font-style:italic;
101
  font-size:11px;
102
  }
109
  margin: 1em 0 !important;
110
  }
111
 
112
+ #mc4wp-admin .mc4wp-col {
113
  float:left;
114
  -webkit-box-sizing: border-box;
115
  -moz-box-sizing:border-box;
118
  padding:0 5px;
119
  }
120
 
121
+ #mc4wp-admin .mc4wp-first{
122
  padding-left:0;
123
  }
124
 
125
+ #mc4wp-admin .mc4wp-last{
126
  padding-right:0;
127
  }
128
 
158
  background-color: #ddd;
159
  }
160
 
161
+ #mc4wp-admin .wp-list-table code {
162
  float:right;
163
  }
164
 
178
  margin-top:25px;
179
  padding-top: 25px;
180
  }
181
+ #mc4wp-admin .wp-list-table code {
182
  float: none;
183
  }
184
 
assets/css/admin.min.css CHANGED
@@ -1 +1 @@
1
- #mc4wp-content{float:left;width:65%}#mc4wp-sidebar{float:left;width:33%;margin-left:2%;border-left:1px solid #ccc;padding:0 0 0 2%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.valigntop{vertical-align:top!important}#mc4wp .mc4wp-box{margin-bottom:20px}#mc4wp-upgrade-box{background:#222;color:#ddd;padding:20px}#mc4wp-upgrade-box h3{margin:0;color:#fff}#mc4wp-fw h4{margin-top:0}#mc4wp-fw p{margin-bottom:1em}#mc4wp-fw-fields{display:none}#mc4wp-fw-preview{font-family:"Courier New",Courier,monospace;min-height:200px;font-size:11px;background:#fff;z-index:99}#mc4wp-lists{margin:0}#mc4wp-lists input{margin-right:5px}.mc4wp-settings tr.pro-feature td,.mc4wp-settings tr.pro-feature th,.pro-feature{color:#aaa}#mc4wp span.status{display:inline-block;padding:3px 6px;color:#fff;font-size:12px;font-weight:700}#mc4wp span.positive{background-color:green}#mc4wp span.negative{background-color:lightGrey}#mc4wp table th{text-align:left}#mc4wp table.form-table tr td:first-child,#mc4wp table.form-table tr th:first-child{padding-left:0}#mc4wptd.nowrap{white-space:nowrap}#mc4wp td.desc{font-style:italic;font-size:11px}.mc4wp-notice{padding:6px 8px;color:#31708f;background:#d9edf7;border:1px solid #bce8f1;margin:1em 0!important}#mc4wp .mc4wp-col{float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:50%;padding:0 5px}#mc4wp .mc4wp-first{padding-left:0}#mc4wp .mc4wp-last{padding-right:0}.mc4wp-well{background:#fff;padding:10px;border:1px solid #ccc}.mc4wp-title{font-size:1.4em;margin:1.6em 0 1em;padding:0 0 6px;border-bottom:1px solid #ddd}table.mc4wp-help,table.mc4wp-help td,table.mc4wp-help th{border:1px solid #ddd;border-collapse:collapse;font-size:12px}table.mc4wp-help td,table.mc4wp-help th{vertical-align:text-top;text-align:left;padding:5px 10px}table.mc4wp-help tr:hover{background-color:#ddd}#mc4wp .wp-list-table code{float:right}@media(max-width:1279px){#mc4wp-content,#mc4wp-sidebar{float:none;width:100%;padding:0;margin:0}#mc4wp-sidebar{border-left:0;border-top:1px solid #ccc;margin-top:25px;padding-top:25px}#mc4wp .wp-list-table code{float:none}}@media(max-width:719px){.mc4wp-hide-smallscreens{display:none}}
1
+ #mc4wp-content{float:left;width:65%}#mc4wp-sidebar{float:left;width:33%;margin-left:2%;border-left:1px solid #ccc;padding:0 0 0 2%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.valigntop{vertical-align:top!important}#mc4wp-admin .mc4wp-box{margin-bottom:20px}#mc4wp-upgrade-box{background:#222;color:#ddd;padding:20px}#mc4wp-upgrade-box h3{margin:0;color:#fff}#mc4wp-fw h4{margin-top:0}#mc4wp-fw p{margin-bottom:1em}#mc4wp-fw-fields{display:none}#mc4wp-fw-preview{font-family:"Courier New",Courier,monospace;min-height:200px;font-size:11px;background:#fff;z-index:99}#mc4wp-lists{margin:0}#mc4wp-lists input{margin-right:5px}.mc4wp-settings tr.pro-feature td,.mc4wp-settings tr.pro-feature th,.pro-feature{color:#aaa}#mc4wp-admin span.status{display:inline-block;padding:3px 6px;color:#fff;font-size:12px;font-weight:700}#mc4wp-admin span.positive{background-color:green}#mc4wp-admin span.negative{background-color:lightGrey}#mc4wp-admin table th{text-align:left}#mc4wp-admin table.form-table tr td:first-child,#mc4wp-admin table.form-table tr th:first-child{padding-left:0}#mc4wp-admin td.nowrap{white-space:nowrap}#mc4wp-admin td.desc{font-style:italic;font-size:11px}.mc4wp-notice{padding:6px 8px;color:#31708f;background:#d9edf7;border:1px solid #bce8f1;margin:1em 0!important}#mc4wp-admin .mc4wp-col{float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:50%;padding:0 5px}#mc4wp-admin .mc4wp-first{padding-left:0}#mc4wp-admin .mc4wp-last{padding-right:0}.mc4wp-well{background:#fff;padding:10px;border:1px solid #ccc}.mc4wp-title{font-size:1.4em;margin:1.6em 0 1em;padding:0 0 6px;border-bottom:1px solid #ddd}table.mc4wp-help,table.mc4wp-help td,table.mc4wp-help th{border:1px solid #ddd;border-collapse:collapse;font-size:12px}table.mc4wp-help td,table.mc4wp-help th{vertical-align:text-top;text-align:left;padding:5px 10px}table.mc4wp-help tr:hover{background-color:#ddd}#mc4wp-admin .wp-list-table code{float:right}@media(max-width:1279px){#mc4wp-content,#mc4wp-sidebar{float:none;width:100%;padding:0;margin:0}#mc4wp-sidebar{border-left:0;border-top:1px solid #ccc;margin-top:25px;padding-top:25px}#mc4wp-admin .wp-list-table code{float:none}}@media(max-width:719px){.mc4wp-hide-smallscreens{display:none}}
assets/js/admin.js CHANGED
@@ -1,27 +1,37 @@
1
- (function($) {
2
 
3
- $("tr.pro-feature, tr.pro-feature td :radio").change(function() {
4
- this.checked = false;
5
- alert("This option is only available in the premium version of MailChimp for WordPress.");
6
- event.stopPropagation();
7
- });
 
 
 
8
 
9
- $("tr.pro-feature, tr.pro-feature label").click(function() {
10
- alert("This option is only available in the premium version of MailChimp for WordPress.");
11
  event.stopPropagation();
12
- });
13
 
14
- (function() {
15
- $lists = $("#mc4wp-lists :input");
16
- $lists.change( toggleNotices );
17
 
18
- function toggleNotices() {
19
- var hasListSelected = $lists.filter(':checked').length > 0;
 
 
 
 
 
 
20
  $(".mc4wp-notice.no-lists-selected").toggle( ! hasListSelected );
21
- $('#mc4wp-fw-mailchimp-fields').toggle( hasListSelected );
22
  }
23
- })();
 
 
24
 
 
 
25
  $(document).delegate('#mc4wpformmarkup', 'keydown', function(e) {
26
  var keyCode = e.keyCode || e.which;
27
 
@@ -302,13 +312,13 @@
302
  'select': [ 'label', 'required', 'wrap-p', 'values'],
303
  'radio': [ 'label', 'required', 'wrap-p', 'values'],
304
  'date': [ 'label', 'required', 'wrap-p', 'value']
305
- }
306
 
307
  // map MailChimp field types to HTML5 field type
308
  var fieldTypesMap = {
309
  'text': 'text', 'email': 'email', 'phone': 'tel', 'address': 'text', 'number': 'number',
310
  'dropdown': 'select', 'date': 'date', 'birthday': 'date', 'radio': 'radio', 'checkbox': 'checkbox'
311
- }
312
 
313
  if(fieldTypesMap[data.field_type] != undefined) {
314
  fieldType = fieldTypesMap[data.field_type];
@@ -322,7 +332,7 @@
322
  var visibleRows = visibleRowsMap["default"];
323
  }
324
 
325
- for(var i = 0, count = visibleRows.length; i < count; i++) {
326
  $wizardFields.find('p.row.' + visibleRows[i]).show();
327
  }
328
 
@@ -339,7 +349,7 @@
339
  $required.attr('checked', data.req);
340
 
341
  if($multipleValues.is(":visible") && data.choices) {
342
- for(var i = 0, count = data.choices.length; i < count; i++) {
343
  $("<input />").attr('type', 'text').addClass('widefat').data('value', data.choices[i]).attr('placeholder', 'Label for "' + data.choices[i] + '" (or leave empty)').attr('value', data.choices[i]).appendTo($multipleValues);
344
  }
345
  }
@@ -364,7 +374,6 @@
364
  function updateCodePreview()
365
  {
366
  var $code = $("<div></div>");
367
- var inputs = [];
368
  var $input;
369
 
370
  switch(fieldType) {
@@ -386,8 +395,7 @@
386
  // add options to select
387
  $multipleValues.find(":input").each(function() {
388
  if($(this).val().length > 0) {
389
- $el = $("<option />").val($(this).data("value")).text($(this).val());
390
- $el.appendTo($input);
391
  }
392
  });
393
  break;
@@ -480,8 +488,8 @@
480
 
481
  // fallback, just append
482
  if(!result) {
483
- $formContent = $("#mc4wpformmarkup");
484
- $formContent.val($formContent.val() + "\n" + $codePreview.val());
485
  }
486
  }
487
 
1
+ (function($) {
2
 
3
+ var $context = $('#mc4wp-admin');
4
+
5
+ function proOnlyNotice() {
6
+
7
+ // prevent checking of radio buttons
8
+ if( typeof this.checked === 'boolean' ) {
9
+ this.checked = false;
10
+ }
11
 
12
+ alert( mc4wp.strings.pro_only );
 
13
  event.stopPropagation();
14
+ }
15
 
16
+ $context.find(".pro-feature, .pro-feature label, .pro-feature :radio").click(proOnlyNotice);
 
 
17
 
18
+ $context.find('input[name$="[show_at_woocommerce_checkout]"]').change(function() {
19
+ $context.find('tr#woocommerce-settings').toggle( $(this).prop( 'checked') );
20
+ });
21
+
22
+ var $listInputs = $("#mc4wp-lists").find(':input');
23
+ $listInputs.change(
24
+ function() {
25
+ var hasListSelected = $listInputs.filter(':checked').length > 0;
26
  $(".mc4wp-notice.no-lists-selected").toggle( ! hasListSelected );
27
+ $('#mc4wp-fw-fields, #mc4wp-fw-mailchimp-fields').toggle( hasListSelected );
28
  }
29
+ );
30
+
31
+
32
 
33
+
34
+ // Allow tabs inside the form mark-up
35
  $(document).delegate('#mc4wpformmarkup', 'keydown', function(e) {
36
  var keyCode = e.keyCode || e.which;
37
 
312
  'select': [ 'label', 'required', 'wrap-p', 'values'],
313
  'radio': [ 'label', 'required', 'wrap-p', 'values'],
314
  'date': [ 'label', 'required', 'wrap-p', 'value']
315
+ };
316
 
317
  // map MailChimp field types to HTML5 field type
318
  var fieldTypesMap = {
319
  'text': 'text', 'email': 'email', 'phone': 'tel', 'address': 'text', 'number': 'number',
320
  'dropdown': 'select', 'date': 'date', 'birthday': 'date', 'radio': 'radio', 'checkbox': 'checkbox'
321
+ };
322
 
323
  if(fieldTypesMap[data.field_type] != undefined) {
324
  fieldType = fieldTypesMap[data.field_type];
332
  var visibleRows = visibleRowsMap["default"];
333
  }
334
 
335
+ for(var i = 0; i < visibleRows.length; i++) {
336
  $wizardFields.find('p.row.' + visibleRows[i]).show();
337
  }
338
 
349
  $required.attr('checked', data.req);
350
 
351
  if($multipleValues.is(":visible") && data.choices) {
352
+ for(var i = 0; i < data.choices.length; i++) {
353
  $("<input />").attr('type', 'text').addClass('widefat').data('value', data.choices[i]).attr('placeholder', 'Label for "' + data.choices[i] + '" (or leave empty)').attr('value', data.choices[i]).appendTo($multipleValues);
354
  }
355
  }
374
  function updateCodePreview()
375
  {
376
  var $code = $("<div></div>");
 
377
  var $input;
378
 
379
  switch(fieldType) {
395
  // add options to select
396
  $multipleValues.find(":input").each(function() {
397
  if($(this).val().length > 0) {
398
+ $("<option />").val($(this).data("value")).text($(this).val()).appendTo($input);
 
399
  }
400
  });
401
  break;
488
 
489
  // fallback, just append
490
  if(!result) {
491
+ var $formContent = $("#mc4wpformmarkup");
492
+ $("#mc4wpformmarkup").val($formContent.val() + "\n" + $codePreview.val());
493
  }
494
  }
495
 
assets/js/admin.min.js CHANGED
@@ -1 +1 @@
1
- !function(a){a("tr.pro-feature, tr.pro-feature td :radio").change(function(){this.checked=!1,alert("This option is only available in the premium version of MailChimp for WordPress."),event.stopPropagation()}),a("tr.pro-feature, tr.pro-feature label").click(function(){alert("This option is only available in the premium version of MailChimp for WordPress."),event.stopPropagation()}),function(){function b(){var b=$lists.filter(":checked").length>0;a(".mc4wp-notice.no-lists-selected").toggle(!b),a("#mc4wp-fw-mailchimp-fields").toggle(b)}$lists=a("#mc4wp-lists :input"),$lists.change(b)}(),a(document).delegate("#mc4wpformmarkup","keydown",function(b){var c=b.keyCode||b.which;if(9==c){b.preventDefault();var d=this.selectionStart,e=this.selectionEnd;a(this).val(a(this).val().substring(0,d)+" "+a(this).val().substring(e)),this.selectionStart=this.selectionEnd=d+1}}),function(){"undefined"!=typeof QTags&&(QTags.addButton("mc4wp_paragraph","<p>","<p>","</p>","paragraph","Paragraph tag",1),QTags.addButton("mc4wp_label","label","<label>","</label>","label","Label tag",2),QTags.addButton("mc4wp_response","form response","{response}","","response","Shows the form response"),QTags.addButton("mc4wp_subscriber_count","# of subscribers","{subscriber_count}","","subscribers","Shows number of subscribers of selected list(s)"),1==window.mc4wp.has_captcha_plugin&&QTags.addButton("mc4wp_captcha","CAPTCHA","{captcha}","","captcha","Display a CAPTCHA field"))}(),function(){function b(){o.find("option").not(".default").remove(),n.filter(":checked").each(function(){for(var b=a(this).data("list-fields"),c=a(this).data("list-groupings"),d=0,e=b.length;e>d;d++){var f=b[d];if(0==p.find("option[value='"+f.tag+"']").length){var g=f.name.length>25?f.name.substring(0,25)+"..":f.name;f.req&&(g+="*");var h=a("<option />").text(g).val(f.tag).data("list-field",f);d>3&&h.text("(PRO ONLY) "+g).attr("disabled","disabled").data("field",null),p.append(h)}}for(var d=0,i=c.length;i>d;d++){var j=c[d];if(0==q.find("option[value='"+j.id+"']").length){var g=j.name.length>25?j.name.substring(0,25)+"..":j.name,h=a("<option />").text(g).val(j.id).data("list-grouping",j);d>=1&&h.text("(PRO ONLY) "+g).attr("disabled","disabled").data("list-grouping",null),q.append(h)}}})}function c(){d();var b=a(this).find(":selected");switch(b.val()){case"submit":l="submit",t.text("Button text"),r.find("p.row").filter(".value, .wrap-p").show();break;case"lists":l="lists",r.find(".wrap-p").show(),j();break;default:var c=b.data("list-field");if(c)return h(c);var c=b.data("list-grouping");if(c)return f(c)}j()}function d(){r.find(".row :input").each(function(){a(this).is(":checkbox")?this.checked=!0:this.value=""}),r.find("p.row").hide(),u.find(":input").remove(),r.show(),l="text",m="",t.html("Initial value <small>(optional)</small>")}function e(b){for(var c=0,d=b.length;d>c;c++)a("<input />").attr("type","text").addClass("widefat").data("value",b[c].name).attr("placeholder",'Label for "'+b[c].name+'" (or leave empty)').attr("value",b[c].name).appendTo(u)}function f(a){switch(r.find("p.row").filter(".values, .label, .wrap-p").show(),v.val(a.name+":"),m="GROUPINGS["+a.id+"]",e(a.groups),a.form_field){case"radio":l="radio";break;case"hidden":r.find("p.row").filter(".values, .label, .wrap-p").hide(),r.find("p.row.value").show();for(var b=0,c=a.groups.length;c>b;b++)s.val(s.val()+a.groups[b].name+",");l="hidden";break;case"dropdown":l="select";break;default:l="checkbox",m+="[]"}j()}function g(){var b="";return n.each(function(){var c=a(this).val(),d=a(this).parent("label").text(),e="";a(this).is(":checked")&&(e+="checked "),b+="<label>\n",b+=' <input type="checkbox" name="_mc4wp_lists[]" value="'+c+'" '+e+" /> "+d+"\n",b+="</label>\n"}),b}function h(b){var c={"default":["label","value","placeholder","required","wrap-p"],select:["label","required","wrap-p","values"],radio:["label","required","wrap-p","values"],date:["label","required","wrap-p","value"]},d={text:"text",email:"email",phone:"tel",address:"text",number:"number",dropdown:"select",date:"date",birthday:"date",radio:"radio",checkbox:"checkbox"};if(l=void 0!=d[b.field_type]?d[b.field_type]:"text",void 0!=c[l])var e=c[l];else var e=c["default"];for(var f=0,g=e.length;g>f;f++)r.find("p.row."+e[f]).show();if(l=l,m=b.tag,w.val("Your "+b.name.toLowerCase()),v.val(b.name+":"),x.attr("checked",b.req),u.is(":visible")&&b.choices)for(var f=0,g=b.choices.length;g>f;f++)a("<input />").attr("type","text").addClass("widefat").data("value",b.choices[f]).attr("placeholder",'Label for "'+b.choices[f]+'" (or leave empty)').attr("value",b.choices[f]).appendTo(u);j()}function i(a){a=html_beautify(a),z.val(a)}function j(){var b,c=a("<div></div>");switch(l){case"lists":var d=g();return y.is(":visible:checked")&&(d="<p>"+d+"</p>"),i(d);case"select":b=a("<select />"),u.find(":input").each(function(){a(this).val().length>0&&($el=a("<option />").val(a(this).data("value")).text(a(this).val()),$el.appendTo(b))});break;case"radio":case"checkbox":u.find(":input").each(function(){a(this).val().length>0&&(b=a("<input />").attr("type",l).attr("name",m).val(a(this).data("value")),x.is(":visible:checked")&&b.attr("required",!0),c.append(b),b.wrap("<label />"),a("<span />").text(a(this).val()+" ").insertAfter(b))});break;case"textarea":b=a("<textarea />");break;default:b=a("<input />").attr("type",l)}"radio"!=l&&"checkbox"!=l&&(m.length>0&&b.attr("name",m),s.is(":visible")&&s.val().length>0&&("textarea"==l?b.text(s.val()):b.attr("value",s.val())),w.is(":visible")&&w.val().length>0&&b.attr("placeholder",w.val()),x.is(":visible:checked")&&b.attr("required",!0),c.append(b)),v.is(":visible")&&v.val().length>0&&a("<label />").text(v.val()).prependTo(c),y.is(":visible:checked")&&c.wrapInner(a("<p />"));var d=c.html();i(d)}function k(){var b=!1;"undefined"!=typeof wpActiveEditor&&"undefined"!=typeof QTags&&QTags.insertContent&&(b=QTags.insertContent(z.val())),b||($formContent=a("#mc4wpformmarkup"),$formContent.val($formContent.val()+"\n"+z.val()))}var l,m,n=a("#mc4wp-lists :input"),o=a("#mc4wp-fw-mailchimp-fields"),p=a("#mc4wp-fw-mailchimp-fields .merge-fields"),q=a("#mc4wp-fw-mailchimp-fields .groupings"),r=a("#mc4wp-fw-fields"),s=a("#mc4wp-fw-value"),t=a("#mc4wp-fw-value-label"),u=a("#mc4wp-fw-values"),v=a("#mc4wp-fw-label"),w=a("#mc4wp-fw-placeholder"),x=a("#mc4wp-fw-required"),y=a("#mc4wp-fw-wrap-p"),z=a("#mc4wp-fw-preview");n.change(b),o.change(c),r.change(j),a("#mc4wp-fw-add-to-form").click(k),b()}()}(jQuery);
1
+ !function(a){function b(){"boolean"==typeof this.checked&&(this.checked=!1),alert(mc4wp.strings.pro_only),event.stopPropagation()}var c=a("#mc4wp-admin");c.find(".pro-feature, .pro-feature label, .pro-feature :radio").click(b),c.find('input[name$="[show_at_woocommerce_checkout]"]').change(function(){c.find("tr#woocommerce-settings").toggle(a(this).prop("checked"))});var d=a("#mc4wp-lists").find(":input");d.change(function(){var b=d.filter(":checked").length>0;a(".mc4wp-notice.no-lists-selected").toggle(!b),a("#mc4wp-fw-fields, #mc4wp-fw-mailchimp-fields").toggle(b)}),a(document).delegate("#mc4wpformmarkup","keydown",function(b){var c=b.keyCode||b.which;if(9==c){b.preventDefault();var d=this.selectionStart,e=this.selectionEnd;a(this).val(a(this).val().substring(0,d)+" "+a(this).val().substring(e)),this.selectionStart=this.selectionEnd=d+1}}),function(){"undefined"!=typeof QTags&&(QTags.addButton("mc4wp_paragraph","<p>","<p>","</p>","paragraph","Paragraph tag",1),QTags.addButton("mc4wp_label","label","<label>","</label>","label","Label tag",2),QTags.addButton("mc4wp_response","form response","{response}","","response","Shows the form response"),QTags.addButton("mc4wp_subscriber_count","# of subscribers","{subscriber_count}","","subscribers","Shows number of subscribers of selected list(s)"),1==window.mc4wp.has_captcha_plugin&&QTags.addButton("mc4wp_captcha","CAPTCHA","{captcha}","","captcha","Display a CAPTCHA field"))}(),function(){function b(){o.find("option").not(".default").remove(),n.filter(":checked").each(function(){for(var b=a(this).data("list-fields"),c=a(this).data("list-groupings"),d=0,e=b.length;e>d;d++){var f=b[d];if(0==p.find("option[value='"+f.tag+"']").length){var g=f.name.length>25?f.name.substring(0,25)+"..":f.name;f.req&&(g+="*");var h=a("<option />").text(g).val(f.tag).data("list-field",f);d>3&&h.text("(PRO ONLY) "+g).attr("disabled","disabled").data("field",null),p.append(h)}}for(var d=0,i=c.length;i>d;d++){var j=c[d];if(0==q.find("option[value='"+j.id+"']").length){var g=j.name.length>25?j.name.substring(0,25)+"..":j.name,h=a("<option />").text(g).val(j.id).data("list-grouping",j);d>=1&&h.text("(PRO ONLY) "+g).attr("disabled","disabled").data("list-grouping",null),q.append(h)}}})}function c(){d();var b=a(this).find(":selected");switch(b.val()){case"submit":l="submit",t.text("Button text"),r.find("p.row").filter(".value, .wrap-p").show();break;case"lists":l="lists",r.find(".wrap-p").show(),j();break;default:var c=b.data("list-field");if(c)return h(c);var c=b.data("list-grouping");if(c)return f(c)}j()}function d(){r.find(".row :input").each(function(){a(this).is(":checkbox")?this.checked=!0:this.value=""}),r.find("p.row").hide(),u.find(":input").remove(),r.show(),l="text",m="",t.html("Initial value <small>(optional)</small>")}function e(b){for(var c=0,d=b.length;d>c;c++)a("<input />").attr("type","text").addClass("widefat").data("value",b[c].name).attr("placeholder",'Label for "'+b[c].name+'" (or leave empty)').attr("value",b[c].name).appendTo(u)}function f(a){switch(r.find("p.row").filter(".values, .label, .wrap-p").show(),v.val(a.name+":"),m="GROUPINGS["+a.id+"]",e(a.groups),a.form_field){case"radio":l="radio";break;case"hidden":r.find("p.row").filter(".values, .label, .wrap-p").hide(),r.find("p.row.value").show();for(var b=0,c=a.groups.length;c>b;b++)s.val(s.val()+a.groups[b].name+",");l="hidden";break;case"dropdown":l="select";break;default:l="checkbox",m+="[]"}j()}function g(){var b="";return n.each(function(){var c=a(this).val(),d=a(this).parent("label").text(),e="";a(this).is(":checked")&&(e+="checked "),b+="<label>\n",b+=' <input type="checkbox" name="_mc4wp_lists[]" value="'+c+'" '+e+" /> "+d+"\n",b+="</label>\n"}),b}function h(b){var c={"default":["label","value","placeholder","required","wrap-p"],select:["label","required","wrap-p","values"],radio:["label","required","wrap-p","values"],date:["label","required","wrap-p","value"]},d={text:"text",email:"email",phone:"tel",address:"text",number:"number",dropdown:"select",date:"date",birthday:"date",radio:"radio",checkbox:"checkbox"};if(l=void 0!=d[b.field_type]?d[b.field_type]:"text",void 0!=c[l])var e=c[l];else var e=c["default"];for(var f=0;f<e.length;f++)r.find("p.row."+e[f]).show();if(l=l,m=b.tag,w.val("Your "+b.name.toLowerCase()),v.val(b.name+":"),x.attr("checked",b.req),u.is(":visible")&&b.choices)for(var f=0;f<b.choices.length;f++)a("<input />").attr("type","text").addClass("widefat").data("value",b.choices[f]).attr("placeholder",'Label for "'+b.choices[f]+'" (or leave empty)').attr("value",b.choices[f]).appendTo(u);j()}function i(a){a=html_beautify(a),z.val(a)}function j(){var b,c=a("<div></div>");switch(l){case"lists":var d=g();return y.is(":visible:checked")&&(d="<p>"+d+"</p>"),i(d);case"select":b=a("<select />"),u.find(":input").each(function(){a(this).val().length>0&&a("<option />").val(a(this).data("value")).text(a(this).val()).appendTo(b)});break;case"radio":case"checkbox":u.find(":input").each(function(){a(this).val().length>0&&(b=a("<input />").attr("type",l).attr("name",m).val(a(this).data("value")),x.is(":visible:checked")&&b.attr("required",!0),c.append(b),b.wrap("<label />"),a("<span />").text(a(this).val()+" ").insertAfter(b))});break;case"textarea":b=a("<textarea />");break;default:b=a("<input />").attr("type",l)}"radio"!=l&&"checkbox"!=l&&(m.length>0&&b.attr("name",m),s.is(":visible")&&s.val().length>0&&("textarea"==l?b.text(s.val()):b.attr("value",s.val())),w.is(":visible")&&w.val().length>0&&b.attr("placeholder",w.val()),x.is(":visible:checked")&&b.attr("required",!0),c.append(b)),v.is(":visible")&&v.val().length>0&&a("<label />").text(v.val()).prependTo(c),y.is(":visible:checked")&&c.wrapInner(a("<p />"));var d=c.html();i(d)}function k(){var b=!1;if("undefined"!=typeof wpActiveEditor&&"undefined"!=typeof QTags&&QTags.insertContent&&(b=QTags.insertContent(z.val())),!b){var c=a("#mc4wpformmarkup");a("#mc4wpformmarkup").val(c.val()+"\n"+z.val())}}var l,m,n=a("#mc4wp-lists :input"),o=a("#mc4wp-fw-mailchimp-fields"),p=a("#mc4wp-fw-mailchimp-fields .merge-fields"),q=a("#mc4wp-fw-mailchimp-fields .groupings"),r=a("#mc4wp-fw-fields"),s=a("#mc4wp-fw-value"),t=a("#mc4wp-fw-value-label"),u=a("#mc4wp-fw-values"),v=a("#mc4wp-fw-label"),w=a("#mc4wp-fw-placeholder"),x=a("#mc4wp-fw-required"),y=a("#mc4wp-fw-wrap-p"),z=a("#mc4wp-fw-preview");n.change(b),o.change(c),r.change(j),a("#mc4wp-fw-add-to-form").click(k),b()}()}(jQuery);
assets/js/form-request.js CHANGED
@@ -159,6 +159,10 @@ window.mc4wpFormRequest = (function() {
159
  case 'select-one':
160
  element.value = value.toString() || value;
161
  break;
 
 
 
 
162
  }
163
  }
164
 
159
  case 'select-one':
160
  element.value = value.toString() || value;
161
  break;
162
+
163
+ case 'textarea':
164
+ element.innerText = value;
165
+ break;
166
  }
167
  }
168
 
assets/js/form-request.min.js CHANGED
@@ -1 +1 @@
1
- window.mc4wpFormRequest=function(){function a(){c(window,"load",b)}function b(){if(e=document.getElementById("mc4wp-form-"+mc4wpFormRequestData.submittedFormId)){0==mc4wpFormRequestData.success&&d(e,mc4wpFormRequestData.postData);var a=0,b=e,c=window.innerHeight;if(b.offsetParent){do a+=b.offsetTop;while(b=b.offsetParent)}else a=e.offsetTop;a-=c-80>e.clientHeight?(c-e.clientHeight)/2:80,void 0!==window.jQuery?jQuery("html, body").animate({scrollTop:a},800):window.scrollTo(0,a)}}function c(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent("on"+b,c)}function d(a,b,c){for(var e in b){var f=e,g=b[e];if(""!=g){if("undefined"!=typeof c&&(f=c+"["+e+"]"),g.constructor==Array)f+="[]";else if("object"==typeof g){d(a,g,f);continue}var h=a.querySelectorAll('input[name="'+f+'"], select[name="'+f+'"], textarea[name="'+f+'"]');if(!h)return;for(var i=0;i<h.length;i++){var j=h[i];switch(j.type||j.tagName){case"text":case"email":case"date":case"tel":j.value=g,j.className=j.className.replace("placeholdersjs","");break;case"radio":j.checked=j.value===g;break;case"checkbox":for(var k=0;k<g.length;k++){var l=j.value===g[k];if(l){j.checked=j.value===g[k];break}j.checked=!1}break;case"select-multiple":for(var m=g.constructor==Array?g:[g],n=0;n<j.options.length;n++)for(var o=0;o<m.length;o++)j.options[n].selected|=j.options[n].value==m[o];break;case"select":case"select-one":j.value=g.toString()||g}}}}}var e;return{init:function(){a()}}}(),mc4wpFormRequest.init();
1
+ window.mc4wpFormRequest=function(){function a(){c(window,"load",b)}function b(){if(e=document.getElementById("mc4wp-form-"+mc4wpFormRequestData.submittedFormId)){0==mc4wpFormRequestData.success&&d(e,mc4wpFormRequestData.postData);var a=0,b=e,c=window.innerHeight;if(b.offsetParent){do a+=b.offsetTop;while(b=b.offsetParent)}else a=e.offsetTop;a-=c-80>e.clientHeight?(c-e.clientHeight)/2:80,void 0!==window.jQuery?jQuery("html, body").animate({scrollTop:a},800):window.scrollTo(0,a)}}function c(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent("on"+b,c)}function d(a,b,c){for(var e in b){var f=e,g=b[e];if(""!=g){if("undefined"!=typeof c&&(f=c+"["+e+"]"),g.constructor==Array)f+="[]";else if("object"==typeof g){d(a,g,f);continue}var h=a.querySelectorAll('input[name="'+f+'"], select[name="'+f+'"], textarea[name="'+f+'"]');if(!h)return;for(var i=0;i<h.length;i++){var j=h[i];switch(j.type||j.tagName){case"text":case"email":case"date":case"tel":j.value=g,j.className=j.className.replace("placeholdersjs","");break;case"radio":j.checked=j.value===g;break;case"checkbox":for(var k=0;k<g.length;k++){var l=j.value===g[k];if(l){j.checked=j.value===g[k];break}j.checked=!1}break;case"select-multiple":for(var m=g.constructor==Array?g:[g],n=0;n<j.options.length;n++)for(var o=0;o<m.length;o++)j.options[n].selected|=j.options[n].value==m[o];break;case"select":case"select-one":j.value=g.toString()||g;break;case"textarea":j.innerText=g}}}}}var e;return{init:function(){a()}}}(),mc4wpFormRequest.init();
includes/class-admin.php CHANGED
@@ -294,7 +294,10 @@ class MC4WP_Lite_Admin
294
  wp_enqueue_script( array( 'jquery', 'mc4wp-beautifyhtml', 'mc4wp-admin' ) );
295
  wp_localize_script( 'mc4wp-admin', 'mc4wp',
296
  array(
297
- 'has_captcha_plugin' => $this->has_captcha_plugin
 
 
 
298
  )
299
  );
300
  }
@@ -323,13 +326,13 @@ class MC4WP_Lite_Admin
323
  $checkbox_plugins['bbpress_forms'] = "bbPress";
324
  }
325
 
326
- if ( class_exists( 'Easy_Digital_Downloads' ) ) {
327
- $checkbox_plugins['_edd_checkout'] = __( '(PRO ONLY)', 'mailchimp-for-wp' ) . ' ' . "Easy Digital Downloads checkout";
328
- }
329
 
330
- if ( class_exists( 'Woocommerce' ) ) {
331
- $checkbox_plugins['_woocommerce_checkout'] = __( '(PRO ONLY)', 'mailchimp-for-wp' ) . ' ' . "WooCommerce checkout";
332
- }
333
 
334
  return $checkbox_plugins;
335
  }
294
  wp_enqueue_script( array( 'jquery', 'mc4wp-beautifyhtml', 'mc4wp-admin' ) );
295
  wp_localize_script( 'mc4wp-admin', 'mc4wp',
296
  array(
297
+ 'has_captcha_plugin' => $this->has_captcha_plugin,
298
+ 'strings' => array(
299
+ 'pro_only' => __( 'This option is only available in MailChimp for WordPress Pro.', 'mailchimp-for-wp' )
300
+ )
301
  )
302
  );
303
  }
326
  $checkbox_plugins['bbpress_forms'] = "bbPress";
327
  }
328
 
329
+ if ( class_exists( 'WooCommerce' ) ) {
330
+ $checkbox_plugins['woocommerce_checkout'] = sprintf( __( '%s checkout', 'mailchimp-for-wp' ), 'WooCommerce' );
331
+ }
332
 
333
+ if ( class_exists( 'Easy_Digital_Downloads' ) ) {
334
+ $checkbox_plugins['edd_checkout'] = sprintf( __( '%s checkout', 'mailchimp-for-wp' ), 'Easy Digital Downloads' );
335
+ }
336
 
337
  return $checkbox_plugins;
338
  }
includes/class-checkbox-manager.php CHANGED
@@ -1,11 +1,14 @@
1
  <?php
2
 
3
- if( ! defined("MC4WP_LITE_VERSION") ) {
4
  header( 'Status: 403 Forbidden' );
5
  header( 'HTTP/1.1 403 Forbidden' );
6
  exit;
7
  }
8
 
 
 
 
9
  class MC4WP_Lite_Checkbox_Manager
10
  {
11
  /**
@@ -13,39 +16,44 @@ class MC4WP_Lite_Checkbox_Manager
13
  */
14
  public $integrations = array();
15
 
 
 
 
 
 
16
  /**
17
  * Constructor
18
  */
19
  public function __construct()
20
  {
21
- $opts = mc4wp_get_options( 'checkbox' );
22
 
23
  // load checkbox css if necessary
24
  add_action( 'wp_enqueue_scripts', array( $this, 'load_stylesheet' ) );
25
  add_action( 'login_enqueue_scripts', array( $this, 'load_stylesheet' ) );
26
 
27
  // Load WP Comment Form Integration
28
- if ( $opts['show_at_comment_form'] ) {
29
  $this->integrations['comment_form'] = new MC4WP_Comment_Form_Integration();
30
  }
31
 
32
  // Load WordPress Registration Form Integration
33
- if ( $opts['show_at_registration_form'] ) {
34
  $this->integrations['registration_form'] = new MC4WP_Registration_Form_Integration();
35
  }
36
 
37
  // Load BuddyPress Integration
38
- if ( $opts['show_at_buddypress_form'] ) {
39
  $this->integrations['buddypress_form'] = new MC4WP_BuddyPress_Integration();
40
  }
41
 
42
  // Load MultiSite Integration
43
- if ( $opts['show_at_multisite_form'] ) {
44
  $this->integrations['multisite_form'] = new MC4WP_MultiSite_Integration();
45
  }
46
 
47
  // Load bbPress Integration
48
- if ( $opts['show_at_bbpress_forms'] ) {
49
  $this->integrations['bbpress_forms'] = new MC4WP_bbPress_Integration();
50
  }
51
 
@@ -59,6 +67,16 @@ class MC4WP_Lite_Checkbox_Manager
59
  $this->integrations['events_manager'] = new MC4WP_Events_Manager_Integration();
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
62
  // Always load General Integration
63
  $this->integrations['general'] = new MC4WP_General_Integration();
64
  }
@@ -68,9 +86,7 @@ class MC4WP_Lite_Checkbox_Manager
68
  */
69
  public function load_stylesheet( ) {
70
 
71
- $opts = mc4wp_get_options( 'checkbox' );
72
-
73
- if( $opts['css'] == false ) {
74
  return false;
75
  }
76
 
1
  <?php
2
 
3
+ if( ! defined( 'MC4WP_LITE_VERSION' ) ) {
4
  header( 'Status: 403 Forbidden' );
5
  header( 'HTTP/1.1 403 Forbidden' );
6
  exit;
7
  }
8
 
9
+ /**
10
+ * Takes care of all the sign-up checkboxes
11
+ */
12
  class MC4WP_Lite_Checkbox_Manager
13
  {
14
  /**
16
  */
17
  public $integrations = array();
18
 
19
+ /**
20
+ * @var array Array of checkbox options
21
+ */
22
+ private $options;
23
+
24
  /**
25
  * Constructor
26
  */
27
  public function __construct()
28
  {
29
+ $this->options = mc4wp_get_options( 'checkbox' );
30
 
31
  // load checkbox css if necessary
32
  add_action( 'wp_enqueue_scripts', array( $this, 'load_stylesheet' ) );
33
  add_action( 'login_enqueue_scripts', array( $this, 'load_stylesheet' ) );
34
 
35
  // Load WP Comment Form Integration
36
+ if ( $this->options['show_at_comment_form'] ) {
37
  $this->integrations['comment_form'] = new MC4WP_Comment_Form_Integration();
38
  }
39
 
40
  // Load WordPress Registration Form Integration
41
+ if ( $this->options['show_at_registration_form'] ) {
42
  $this->integrations['registration_form'] = new MC4WP_Registration_Form_Integration();
43
  }
44
 
45
  // Load BuddyPress Integration
46
+ if ( $this->options['show_at_buddypress_form'] ) {
47
  $this->integrations['buddypress_form'] = new MC4WP_BuddyPress_Integration();
48
  }
49
 
50
  // Load MultiSite Integration
51
+ if ( $this->options['show_at_multisite_form'] ) {
52
  $this->integrations['multisite_form'] = new MC4WP_MultiSite_Integration();
53
  }
54
 
55
  // Load bbPress Integration
56
+ if ( $this->options['show_at_bbpress_forms'] ) {
57
  $this->integrations['bbpress_forms'] = new MC4WP_bbPress_Integration();
58
  }
59
 
67
  $this->integrations['events_manager'] = new MC4WP_Events_Manager_Integration();
68
  }
69
 
70
+ // Load WooCommerce Integration
71
+ if ( $this->options['show_at_woocommerce_checkout'] ) {
72
+ $this->integrations['woocommerce'] = new MC4WP_WooCommerce_Integration();
73
+ }
74
+
75
+ // Load EDD Integration
76
+ if ( $this->options['show_at_edd_checkout'] ) {
77
+ $this->integrations['easy_digital_downloads'] = new MC4WP_EDD_Integration();
78
+ }
79
+
80
  // Always load General Integration
81
  $this->integrations['general'] = new MC4WP_General_Integration();
82
  }
86
  */
87
  public function load_stylesheet( ) {
88
 
89
+ if( $this->options['css'] == false ) {
 
 
90
  return false;
91
  }
92
 
includes/class-form-manager.php CHANGED
@@ -37,11 +37,6 @@ class MC4WP_Lite_Form_Manager {
37
  // load checkbox css if necessary
38
  add_action('wp_enqueue_scripts', array( $this, 'load_stylesheet' ) );
39
 
40
- // has a MC4WP form been submitted?
41
- if ( isset( $_POST['_mc4wp_form_submit'] ) ) {
42
- $this->form_request = new MC4WP_Lite_Form_Request;
43
- }
44
-
45
  /**
46
  * @deprecated
47
  */
@@ -57,11 +52,20 @@ class MC4WP_Lite_Form_Manager {
57
  {
58
  $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
59
 
60
- // register placeholder script, which will later be enqueued for IE only
61
- wp_register_script( 'mc4wp-placeholders', MC4WP_LITE_PLUGIN_URL . 'assets/js/placeholders.min.js', array(), MC4WP_LITE_VERSION, true );
 
 
 
 
 
 
 
 
 
 
 
62
 
63
- // register non-AJAX script (that handles form submissions)
64
- wp_register_script( 'mc4wp-form-request', MC4WP_LITE_PLUGIN_URL . 'assets/js/form-request' . $suffix . '.js', array(), MC4WP_LITE_VERSION, true );
65
  }
66
 
67
  /**
@@ -205,7 +209,7 @@ class MC4WP_Lite_Form_Manager {
205
  wp_localize_script( 'mc4wp-form-request', 'mc4wpFormRequestData', array(
206
  'success' => ( $this->form_request->is_successful() ) ? 1 : 0,
207
  'submittedFormId' => $this->form_request->get_form_instance_number(),
208
- 'postData' => stripslashes_deep( $_POST )
209
  )
210
  );
211
 
37
  // load checkbox css if necessary
38
  add_action('wp_enqueue_scripts', array( $this, 'load_stylesheet' ) );
39
 
 
 
 
 
 
40
  /**
41
  * @deprecated
42
  */
52
  {
53
  $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
54
 
55
+ // has a MC4WP form been submitted?
56
+ if ( isset( $_POST['_mc4wp_form_submit'] ) ) {
57
+ $this->form_request = new MC4WP_Lite_Form_Request;
58
+ }
59
+
60
+ // frontend only
61
+ if( ! is_admin() ) {
62
+ // register placeholder script, which will later be enqueued for IE only
63
+ wp_register_script( 'mc4wp-placeholders', MC4WP_LITE_PLUGIN_URL . 'assets/js/placeholders.min.js', array(), MC4WP_LITE_VERSION, true );
64
+
65
+ // register non-AJAX script (that handles form submissions)
66
+ wp_register_script( 'mc4wp-form-request', MC4WP_LITE_PLUGIN_URL . 'assets/js/form-request' . $suffix . '.js', array(), MC4WP_LITE_VERSION, true );
67
+ }
68
 
 
 
69
  }
70
 
71
  /**
209
  wp_localize_script( 'mc4wp-form-request', 'mc4wpFormRequestData', array(
210
  'success' => ( $this->form_request->is_successful() ) ? 1 : 0,
211
  'submittedFormId' => $this->form_request->get_form_instance_number(),
212
+ 'postData' => $this->form_request->get_data()
213
  )
214
  );
215
 
includes/class-form-request.php CHANGED
@@ -18,17 +18,17 @@ class MC4WP_Lite_Form_Request {
18
  /**
19
  * @var array
20
  */
21
- private $posted_data = array();
22
 
23
  /**
24
- * @var bool
25
  */
26
  private $success = false;
27
 
28
  /**
29
- * @var string
30
  */
31
- private $error_code = 'error';
32
 
33
  /**
34
  * @var array The form options
@@ -36,20 +36,24 @@ class MC4WP_Lite_Form_Request {
36
  private $form_options;
37
 
38
  /**
39
- * Constructor
40
- *
41
- * Hooks into the `init` action to start the process of subscribing the person who filled out the form
42
  */
43
- public function __construct() {
44
 
45
- // store number of submitted form
46
- $this->form_instance_number = absint( $_POST['_mc4wp_form_instance'] );
 
 
47
 
48
- // store form options
49
- $this->form_options = mc4wp_get_options( 'form' );
 
 
50
 
51
- add_action( 'init', array( $this, 'act' ) );
52
- }
 
 
53
 
54
  /**
55
  * @return bool
@@ -59,58 +63,104 @@ class MC4WP_Lite_Form_Request {
59
  }
60
 
61
  /**
62
- * @return string
63
  */
64
- public function get_error_code() {
65
- return $this->error_code;
66
  }
67
 
68
  /**
69
  * @return array
70
  */
71
- public function get_posted_data() {
72
- return $this->posted_data;
73
  }
74
 
75
  /**
76
- * @return int
77
  */
78
- public function get_form_instance_number() {
79
- return $this->form_instance_number;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  }
81
 
82
  /**
83
- * Acts on the submitted data
84
- * - Validates internal fields
85
- * - Formats email and merge_vars
86
- * - Sends off the subscribe request to MailChimp
87
- * - Returns state
88
  *
89
- * @return bool True on success, false on failure.
 
 
 
 
 
 
 
90
  */
91
- public function act() {
92
 
93
  // detect caching plugin
94
  $using_caching = ( defined( 'WP_CACHE' ) && WP_CACHE );
95
 
96
- // validate form nonce
97
- if ( ! $using_caching && ( ! isset( $_POST['_mc4wp_form_nonce'] ) || ! wp_verify_nonce( $_POST['_mc4wp_form_nonce'], '_mc4wp_form_nonce' ) ) ) {
98
  $this->error_code = 'invalid_nonce';
99
  return false;
100
  }
101
 
102
  // ensure honeypot was not filed
103
- if ( isset( $_POST['_mc4wp_required_but_not_really'] ) && ! empty( $_POST['_mc4wp_required_but_not_really'] ) ) {
104
  $this->error_code = 'spam';
105
  return false;
106
  }
107
 
108
  // check if captcha was present and valid
109
- if( isset( $_POST['_mc4wp_has_captcha'] ) && $_POST['_mc4wp_has_captcha'] == 1 && function_exists( 'cptch_check_custom_form' ) && cptch_check_custom_form() !== true ) {
110
  $this->error_code = 'invalid_captcha';
111
  return false;
112
  }
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  /**
115
  * @filter mc4wp_valid_form_request
116
  *
@@ -118,226 +168,282 @@ class MC4WP_Lite_Form_Request {
118
  * Return true if the form is valid or an error string if it isn't.
119
  * Use the `mc4wp_form_messages` filter to register custom error messages.
120
  */
121
- $valid_form_request = apply_filters( 'mc4wp_valid_form_request', true );
122
  if( $valid_form_request !== true ) {
123
  $this->error_code = $valid_form_request;
124
  return false;
125
  }
126
 
127
- // get entered form data (sanitized)
128
- $this->sanitize_form_data();
129
- $data = $this->get_posted_data();
130
-
131
- // validate email
132
- if( ! isset( $data['EMAIL'] ) || ! is_string( $data['EMAIL'] ) || ! is_email( $data['EMAIL'] ) ) {
133
- $this->error_code = 'invalid_email';
134
- return false;
135
- }
136
-
137
- // setup merge_vars array
138
- $merge_vars = $data;
139
 
140
- // take email out of $data array, use the rest as merge_vars
141
- $email = $merge_vars['EMAIL'];
142
- unset( $merge_vars['EMAIL'] );
 
 
 
 
 
 
 
 
 
143
 
144
- // validate groupings
145
- if( isset( $data['GROUPINGS'] ) && is_array( $data['GROUPINGS'] ) ) {
146
- $merge_vars['GROUPINGS'] = $this->format_groupings_data( $data['GROUPINGS'] );
147
- }
148
 
149
- // subscribe the given email / data combination
150
- $this->success = $this->subscribe( $email, $merge_vars );
151
 
152
- // do stuff on success
153
- if( true === $this->success ) {
154
 
155
- // check if we want to redirect the visitor
156
- if ( ! empty( $this->form_options['redirect'] ) ) {
157
- wp_redirect( $this->form_options['redirect'] );
158
- exit;
159
  }
160
 
161
- // return true on success
162
- return true;
 
 
 
163
  }
164
 
165
- /**
166
- * @action mc4wp_form_error_{ERROR_CODE}
167
- *
168
- * Use to hook into various sign-up errors. Hook names are:
169
- *
170
- * - mc4wp_form_error_error General errors
171
- * - mc4wp_form_error_invalid_email Invalid email address
172
- * - mc4wp_form_error_already_subscribed Email is already on selected list(s)
173
- * - mc4wp_form_error_required_field_missing One or more required fields are missing
174
- * - mc4wp_form_error_no_lists_selected No MailChimp lists were selected
175
- *
176
- * @param int $form_id The ID of the submitted form
177
- * @param string $email The email of the subscriber
178
- * @param array $merge_vars Additional list fields, like FNAME etc (if any)
179
- */
180
- do_action( 'mc4wp_form_error_' . $this->get_error_code(), 0, $email, $merge_vars );
181
 
182
- // return false on failure
183
- return false;
184
  }
185
 
186
  /**
187
- * Format GROUPINGS data according to the MailChimp API requirements
188
  *
189
- * @param $data
190
  *
 
191
  * @return array
192
  */
193
- private function format_groupings_data( $data ) {
194
-
195
- $sanitized_data = array();
196
-
197
- foreach ( $data as $grouping_id_or_name => $groups ) {
198
 
199
- $grouping = array();
 
200
 
201
- // set key: grouping id or name
202
- if ( is_numeric( $grouping_id_or_name ) ) {
203
- $grouping['id'] = absint( $grouping_id_or_name );
 
204
  } else {
205
- $grouping['name'] = sanitize_text_field( $grouping_id_or_name );
206
  }
 
207
 
208
- // comma separated list should become an array
209
- if( ! is_array( $groups ) ) {
210
- $groups = sanitize_text_field( $groups );
211
- $groups = explode( ',', $groups );
212
- }
 
 
213
 
214
- $grouping['groups'] = $groups;
 
215
 
216
- // add grouping to array
217
- $sanitized_data[] = $grouping;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  }
219
 
220
- return $sanitized_data;
221
  }
222
 
223
  /**
224
- * Get and sanitize posted form data
225
- *
226
- * - Strips internal MailChimp for WP variables from the posted data array
227
- * - Strips ignored fields
228
- * - Converts keys to uppercase
229
- * - Trims scalar values and strips slashes
230
  *
231
  * @return array
232
  */
233
- private function sanitize_form_data() {
234
 
235
- $data = array();
236
 
237
- // Ignore those fields, we don't need them
238
- $ignored_fields = array( 'CPTCH_NUMBER', 'CNTCTFRM_CONTACT_ACTION', 'CPTCH_RESULT', 'CPTCH_TIME' );
 
239
 
240
- foreach( $_POST as $key => $value ) {
241
 
242
- // Sanitize key
243
- $key = trim( strtoupper( $key ) );
244
 
245
- // Skip field if it starts with _ or if it's in ignored_fields array
246
- if( $key[0] === '_' || in_array( $key, $ignored_fields ) ) {
 
 
247
  continue;
248
  }
249
 
250
- // Sanitize value if it's scalar
251
- $value = ( is_scalar( $value ) ) ? sanitize_text_field( $value ) : $value;
252
 
253
- // Add value to array
254
- $data[ $key ] = $value;
255
- }
256
 
257
- // strip slashes on everything
258
- $data = stripslashes_deep( $data );
 
 
259
 
260
- // store data somewhere safe
261
- $this->posted_data = $data;
262
- }
 
 
 
 
263
 
264
- /**
265
- * Subscribes the given email and additional list fields
266
- *
267
- * - Guesses FNAME and LNAME, if not set but NAME is.
268
- * - Adds OPTIN_IP field
269
- * - Validates merge_vars according to selected list(s) requirements
270
- * - Checks if a list was selected or given in form
271
- *
272
- * @param string $email
273
- * @param array $merge_vars
274
- *
275
- * @return bool
276
- */
277
- private function subscribe( $email, $merge_vars = array() ) {
278
 
279
- // Try to guess FNAME and LNAME if they are not given, but NAME is
280
- if( isset( $merge_vars['NAME'] ) && ! isset( $merge_vars['FNAME'] ) && ! isset( $merge_vars['LNAME'] ) ) {
281
 
282
- $strpos = strpos($merge_vars['NAME'], ' ');
283
- if( $strpos !== false ) {
284
- $merge_vars['FNAME'] = substr( $merge_vars['NAME'], 0, $strpos );
285
- $merge_vars['LNAME'] = substr( $merge_vars['NAME'], $strpos );
286
- } else {
287
- $merge_vars['FNAME'] = $merge_vars['NAME'];
288
  }
289
- }
290
 
291
- // set ip address
292
- if( ! isset( $merge_vars['OPTIN_IP'] ) && isset( $_SERVER['REMOTE_ADDR'] ) ) {
293
- $merge_vars['OPTIN_IP'] = $_SERVER['REMOTE_ADDR'];
294
- }
295
 
296
- // set correct mc_language field
297
- if( isset( $merge_vars['MC_LANGUAGE'] ) && strlen( $merge_vars['MC_LANGUAGE'] ) > 2 && ! in_array( $merge_vars['MC_LANGUAGE'] , array( 'fr_CA', 'es_ES', 'pt_PT' ) ) ) {
298
- $merge_vars['MC_LANGUAGE'] = strtolower( substr( $merge_vars['MC_LANGUAGE'], 0, 2 ) );
299
- }
300
 
301
- $api = mc4wp_get_api();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
 
303
- // get lists to subscribe to
304
- $lists = $this->get_lists();
305
 
306
- if ( empty( $lists ) ) {
307
- $this->error_code = 'no_lists_selected';
308
- return false;
309
  }
310
 
311
- // validate fields according to mailchimp list field types
312
- $merge_vars = $this->validate_merge_vars( $merge_vars );
313
- if( false === $merge_vars ) {
314
- return false;
 
 
 
315
  }
316
 
317
- do_action( 'mc4wp_before_subscribe', $email, $merge_vars, 0 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
 
319
  $result = false;
320
  $email_type = $this->get_email_type();
321
 
322
- foreach ( $lists as $list_id ) {
 
323
  // allow plugins to alter merge vars for each individual list
324
- $list_merge_vars = apply_filters( 'mc4wp_merge_vars', $merge_vars, 0, $list_id );
 
325
 
326
  // send a subscribe request to MailChimp for each list
327
- $result = $api->subscribe( $list_id, $email, $list_merge_vars, $email_type, $this->form_options['double_optin'] );
328
  }
329
 
330
- do_action( 'mc4wp_after_subscribe', $email, $merge_vars, 0, $result );
331
 
332
  if ( $result !== true ) {
333
  // subscribe request failed, store error.
334
  $this->success = false;
335
  $this->error_code = $result;
 
336
  return false;
337
  }
338
 
 
 
339
  // store user email in a cookie
340
- $this->set_email_cookie( $email );
 
 
 
 
 
 
 
341
 
342
  // Store success result
343
  $this->success = true;
@@ -346,74 +452,78 @@ class MC4WP_Lite_Form_Request {
346
  }
347
 
348
  /**
349
- * Validates the posted fields against merge_vars of selected list(s)
350
  *
351
- * @param array $data
 
352
  *
353
- * @return array|boolean Array of data on success, false on error
354
  */
355
- private function validate_merge_vars( array $data ) {
356
 
357
- $list_ids = $this->get_lists();
358
- $mailchimp = new MC4WP_MailChimp();
359
 
360
- foreach( $list_ids as $list_id ) {
361
 
362
- $list = $mailchimp->get_list( $list_id, false, true );
 
 
 
363
 
364
- // make sure list was found
365
- if( ! is_object( $list ) ) {
366
- continue;
367
- }
368
 
369
- // loop through list fields
370
- foreach( $list->merge_vars as $merge_var ) {
371
 
372
- // skip email field, it's validated elsewhere
373
- if( $merge_var->tag === 'EMAIL' ) {
374
- continue;
375
- }
376
-
377
- $posted_value = ( isset( $data[ $merge_var->tag ] ) && '' !== $data[ $merge_var->tag ] ) ? $data[ $merge_var->tag ] : '';
378
 
379
- // check if required field is given
380
- if( $merge_var->req && '' === $posted_value ) {
381
- $this->error_code = 'required_field_missing';
382
- return false;
383
- }
 
 
384
 
385
- // format birthday fields in MM/DD format, required by MailChimp
386
- if( $merge_var->field_type === 'birthday' && $posted_value !== '' ) {
387
- $data[ $merge_var->tag ] = date( 'm/d', strtotime( $data[ $merge_var->tag ] ) );
388
  }
389
 
390
- // format address fields
391
- if( $merge_var->field_type === 'address' && $posted_value !== '' ) {
392
 
393
- if( ! isset( $posted_value['addr1'] ) ) {
 
 
 
 
 
 
 
 
394
 
395
- // addr1, addr2, city, state, zip, country
396
- $address_pieces = explode( ',', $posted_value );
397
 
398
- // try to fill it.... this is a long shot
399
- $data[ $merge_var->tag ] = array(
400
- 'addr1' => $address_pieces[0],
401
- 'city' => ( isset( $address_pieces[1] ) ) ? $address_pieces[1] : '',
402
- 'state' => ( isset( $address_pieces[2] ) ) ? $address_pieces[2] : '',
403
- 'zip' => ( isset( $address_pieces[3] ) ) ? $address_pieces[3] : ''
404
- );
405
 
406
- } else {
407
- // form contains the necessary fields already: perfection
408
- $data[ $merge_var->tag ] = $posted_value;
409
- }
410
- }
 
 
411
 
 
 
 
412
 
413
- }
 
 
414
  }
415
 
416
- return $data;
 
417
  }
418
 
419
  /**
@@ -433,7 +543,7 @@ class MC4WP_Lite_Form_Request {
433
  // allow plugins to override this email type
434
  $email_type = apply_filters( 'mc4wp_email_type', $email_type );
435
 
436
- return $email_type;
437
  }
438
 
439
  /**
@@ -461,7 +571,7 @@ class MC4WP_Lite_Form_Request {
461
  // allow plugins to alter the lists to subscribe to
462
  $lists = apply_filters( 'mc4wp_lists', $lists );
463
 
464
- return $lists;
465
  }
466
 
467
  /**
@@ -474,6 +584,7 @@ class MC4WP_Lite_Form_Request {
474
  /**
475
  * @filter `mc4wp_cookie_expiration_time`
476
  * @expects timestamp
 
477
  *
478
  * Timestamp indicating when the email cookie expires, defaults to 30 days
479
  */
@@ -487,13 +598,13 @@ class MC4WP_Lite_Form_Request {
487
  *
488
  * @return string
489
  */
490
- public function get_response_html() {
491
 
492
  // get all form messages
493
  $messages = $this->get_form_messages();
494
 
495
  // retrieve correct message
496
- $type = ( $this->is_successful() ) ? 'success' : $this->get_error_code();
497
  $message = ( isset( $messages[ $type ] ) ) ? $messages[ $type ] : $messages['error'];
498
 
499
  /**
@@ -503,18 +614,15 @@ class MC4WP_Lite_Form_Request {
503
  *
504
  * Used to alter the error message, don't use. Use `mc4wp_form_messages` instead.
505
  */
506
- $message['text'] = apply_filters('mc4wp_form_error_message', $message['text'], $this->get_error_code() );
507
 
508
  $html = '<div class="mc4wp-alert mc4wp-'. $message['type'].'">' . $message['text'] . '</div>';
509
 
510
  // show additional MailChimp API errors to administrators
511
- if( false === $this->is_successful() && current_user_can( 'manage_options' ) ) {
512
-
513
- // show MailChimp error message (if any) to administrators
514
- $api = mc4wp_get_api();
515
 
516
- if( $api->has_error() ) {
517
- $html .= '<div class="mc4wp-alert mc4wp-error"><strong>' . __( 'MailChimp Error:', 'mailchimp-for-wp' ) . '</strong><br />'. $api->get_error_message() . '</div>';
518
  }
519
  }
520
 
@@ -533,7 +641,6 @@ class MC4WP_Lite_Form_Request {
533
  * ...
534
  * );
535
  *
536
- * @param int $form_id
537
  * @return array
538
  */
539
  public function get_form_messages() {
@@ -571,12 +678,13 @@ class MC4WP_Lite_Form_Request {
571
 
572
  /**
573
  * @filter mc4wp_form_messages
 
574
  *
575
  * Allows registering custom form messages, useful if you're using custom validation using the `mc4wp_valid_form_request` filter.
576
  */
577
- $messages = apply_filters( 'mc4wp_form_messages', $messages );
578
 
579
- return $messages;
580
  }
581
 
582
 
18
  /**
19
  * @var array
20
  */
21
+ private $data = array();
22
 
23
  /**
24
+ * @var bool Guilty until proven otherwise.
25
  */
26
  private $success = false;
27
 
28
  /**
29
+ * @var bool Guilty until proven otherwise.
30
  */
31
+ private $is_valid = false;
32
 
33
  /**
34
  * @var array The form options
36
  private $form_options;
37
 
38
  /**
39
+ * @var array
 
 
40
  */
41
+ private $lists_fields_map = array();
42
 
43
+ /**
44
+ * @var array
45
+ */
46
+ private $unmapped_fields = array();
47
 
48
+ /**
49
+ * @var string
50
+ */
51
+ private $error_code = 'error';
52
 
53
+ /**
54
+ * @var string
55
+ */
56
+ private $mailchimp_error = '';
57
 
58
  /**
59
  * @return bool
63
  }
64
 
65
  /**
66
+ * @return int
67
  */
68
+ public function get_form_instance_number() {
69
+ return $this->form_instance_number;
70
  }
71
 
72
  /**
73
  * @return array
74
  */
75
+ public function get_data() {
76
+ return $this->data;
77
  }
78
 
79
  /**
80
+ * Constructor
81
  */
82
+ public function __construct() {
83
+
84
+ // uppercase all POST keys
85
+ $this->data = array_change_key_case( $_POST, CASE_UPPER );
86
+
87
+ // store number of submitted form
88
+ $this->form_instance_number = absint( $this->data['_MC4WP_FORM_INSTANCE'] );
89
+ $this->form_options = mc4wp_get_options( 'form' );
90
+
91
+ $this->is_valid = $this->validate();
92
+
93
+ // normalize posted data
94
+ $this->data = $this->sanitize();
95
+
96
+ if( $this->is_valid ) {
97
+
98
+ // add some data to the posted data, like FNAME and LNAME
99
+ $this->guess_missing_fields( $this->data );
100
+
101
+ // map fields to corresponding MailChimp lists
102
+ if( $this->map_data() ) {
103
+
104
+ // subscribe using the processed data
105
+ $this->success = $this->subscribe( $this->lists_fields_map );
106
+ }
107
+ }
108
+
109
+ // send HTTP response
110
+ $this->send_http_response();
111
+
112
+ return $this->success;
113
  }
114
 
115
  /**
116
+ * Validates the request
 
 
 
 
117
  *
118
+ * - Nonce validity
119
+ * - Honeypot
120
+ * - Captcha
121
+ * - Email address
122
+ * - Lists (POST and options)
123
+ * - Additional validation using a filter.
124
+ *
125
+ * @return bool
126
  */
127
+ private function validate() {
128
 
129
  // detect caching plugin
130
  $using_caching = ( defined( 'WP_CACHE' ) && WP_CACHE );
131
 
132
+ // validate form nonce, but only if not using caching
133
+ if ( ! $using_caching && ( ! isset( $this->data['_MC4WP_FORM_NONCE'] ) || ! wp_verify_nonce( $this->data['_MC4WP_FORM_NONCE'], '_mc4wp_form_nonce' ) ) ) {
134
  $this->error_code = 'invalid_nonce';
135
  return false;
136
  }
137
 
138
  // ensure honeypot was not filed
139
+ if ( isset( $this->data['_MC4WP_REQUIRED_BUT_NOT_REALLY'] ) && ! empty( $this->data['_MC4WP_REQUIRED_BUT_NOT_REALLY'] ) ) {
140
  $this->error_code = 'spam';
141
  return false;
142
  }
143
 
144
  // check if captcha was present and valid
145
+ if( isset( $this->data['_MC4WP_HAS_CAPTCHA'] ) && $this->data['_MC4WP_HAS_CAPTCHA'] == 1 && function_exists( 'cptch_check_custom_form' ) && cptch_check_custom_form() !== true ) {
146
  $this->error_code = 'invalid_captcha';
147
  return false;
148
  }
149
 
150
+ // validate email
151
+ if( ! isset( $this->data['EMAIL'] ) || ! is_string( $this->data['EMAIL'] ) || ! is_email( $this->data['EMAIL'] ) ) {
152
+ $this->error_code = 'invalid_email';
153
+ return false;
154
+ }
155
+
156
+ // get lists to subscribe to
157
+ $lists = $this->get_lists();
158
+
159
+ if ( empty( $lists ) ) {
160
+ $this->error_code = 'no_lists_selected';
161
+ return false;
162
+ }
163
+
164
  /**
165
  * @filter mc4wp_valid_form_request
166
  *
168
  * Return true if the form is valid or an error string if it isn't.
169
  * Use the `mc4wp_form_messages` filter to register custom error messages.
170
  */
171
+ $valid_form_request = apply_filters( 'mc4wp_valid_form_request', true, $this->data );
172
  if( $valid_form_request !== true ) {
173
  $this->error_code = $valid_form_request;
174
  return false;
175
  }
176
 
177
+ return true;
178
+ }
 
 
 
 
 
 
 
 
 
 
179
 
180
+ /**
181
+ * Sanitize the request data.
182
+ *
183
+ * - Strips internal variables
184
+ * - Strip ignored fields
185
+ * - Sanitize scalar values
186
+ * - Strip slashes on everything
187
+ *
188
+ * @return array
189
+ */
190
+ private function sanitize() {
191
+ $data = array();
192
 
193
+ // Ignore those fields, we don't need them
194
+ $ignored_fields = array( 'CPTCH_NUMBER', 'CNTCTFRM_CONTACT_ACTION', 'CPTCH_RESULT', 'CPTCH_TIME' );
 
 
195
 
196
+ foreach( $this->data as $key => $value ) {
 
197
 
198
+ // Sanitize key
199
+ $key = trim( $key );
200
 
201
+ // Skip field if it starts with _ or if it's in ignored_fields array
202
+ if( $key[0] === '_' || in_array( $key, $ignored_fields ) ) {
203
+ continue;
 
204
  }
205
 
206
+ // Sanitize value
207
+ $value = ( is_scalar( $value ) ) ? sanitize_text_field( $value ) : $value;
208
+
209
+ // Add value to array
210
+ $data[ $key ] = $value;
211
  }
212
 
213
+ // strip slashes on everything
214
+ $data = stripslashes_deep( $data );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
 
216
+ // store data somewhere safe
217
+ return $data;
218
  }
219
 
220
  /**
221
+ * Guesses the value of some fields.
222
  *
223
+ * - FNAME and LNAME, if NAME is given
224
  *
225
+ * @param array $data
226
  * @return array
227
  */
228
+ public function guess_missing_fields( $data ) {
 
 
 
 
229
 
230
+ // fill FNAME and LNAME if they're not set, but NAME is.
231
+ if( isset( $data['NAME'] ) && ! isset( $data['FNAME'] ) && ! isset( $data['LNAME'] ) ) {
232
 
233
+ $strpos = strpos( $data['NAME'], ' ' );
234
+ if( $strpos !== false ) {
235
+ $data['FNAME'] = substr( $data['NAME'], 0, $strpos );
236
+ $data['LNAME'] = substr( $data['NAME'], $strpos );
237
  } else {
238
+ $data['FNAME'] = $data['NAME'];
239
  }
240
+ }
241
 
242
+ return $data;
243
+ }
244
+
245
+ /**
246
+ * Send HTTP response
247
+ */
248
+ public function send_http_response() {
249
 
250
+ // do stuff on success, non-AJAX only
251
+ if( $this->success ) {
252
 
253
+ // check if we want to redirect the visitor
254
+ if ( ! empty( $this->form_options['redirect'] ) ) {
255
+
256
+ $redirect_url = add_query_arg( array( 'mc4wp_email' => urlencode( $this->data['EMAIL'] ) ), $this->form_options['redirect'] );
257
+ wp_redirect( $redirect_url );
258
+ exit;
259
+ }
260
+
261
+ } else {
262
+
263
+ /**
264
+ * @action mc4wp_form_error_{ERROR_CODE}
265
+ *
266
+ * Use to hook into various sign-up errors. Hook names are:
267
+ *
268
+ * - mc4wp_form_error_error General errors
269
+ * - mc4wp_form_error_invalid_email Invalid email address
270
+ * - mc4wp_form_error_already_subscribed Email is already on selected list(s)
271
+ * - mc4wp_form_error_required_field_missing One or more required fields are missing
272
+ * - mc4wp_form_error_no_lists_selected No MailChimp lists were selected
273
+ *
274
+ * @param int $form_id The ID of the submitted form (PRO ONLY)
275
+ * @param string $email The email of the subscriber
276
+ * @param array $data Additional list fields, like FNAME etc (if any)
277
+ */
278
+ do_action( 'mc4wp_form_error_' . $this->error_code, 0, $this->data['EMAIL'], $this->data );
279
  }
280
 
 
281
  }
282
 
283
  /**
284
+ * Maps the received data to MailChimp lists
 
 
 
 
 
285
  *
286
  * @return array
287
  */
288
+ private function map_data() {
289
 
290
+ $data = $this->data;
291
 
292
+ $map = array();
293
+ $mapped_fields = array( 'EMAIL' );
294
+ $unmapped_fields = array();
295
 
296
+ $mailchimp = new MC4WP_MailChimp();
297
 
298
+ // loop through selected lists
299
+ foreach( $this->get_lists() as $list_id ) {
300
 
301
+ $list = $mailchimp->get_list( $list_id, false, true );
302
+
303
+ // skip this list if it's unexisting
304
+ if( ! is_object( $list ) || ! isset( $list->merge_vars ) ) {
305
  continue;
306
  }
307
 
308
+ // start with empty list map
309
+ $list_map = array();
310
 
311
+ // loop through other list fields
312
+ foreach( $list->merge_vars as $field ) {
 
313
 
314
+ // skip EMAIL field
315
+ if( $field->tag === 'EMAIL' ) {
316
+ continue;
317
+ }
318
 
319
+ // check if field is required
320
+ if( $field->req ) {
321
+ if( ! isset( $data[ $field->tag ] ) || '' === $data[ $field->tag ] ) {
322
+ $this->error_code = 'required_field_missing';
323
+ return false;
324
+ }
325
+ }
326
 
327
+ // if field is not set, continue.
328
+ if( ! isset( $data[ $field->tag ] ) ) {
329
+ continue;
330
+ }
 
 
 
 
 
 
 
 
 
 
331
 
332
+ // grab field value from data
333
+ $field_value = $data[ $field->tag ];
334
 
335
+ $field_value = $this->format_field_value( $field_value, $field->field_type );
336
+
337
+ // add field value to map
338
+ $mapped_fields[] = $field->tag;
339
+ $list_map[ $field->tag ] = $field_value;
 
340
  }
 
341
 
342
+ // loop through list groupings if GROUPINGS data was sent
343
+ if( isset( $data['GROUPINGS'] ) && is_array( $data['GROUPINGS'] ) && ! empty( $list->interest_groupings ) ) {
 
 
344
 
345
+ $list_map['GROUPINGS'] = array();
 
 
 
346
 
347
+ foreach( $list->interest_groupings as $grouping ) {
348
+
349
+ // check if data for this group was sent
350
+ if( isset( $data['GROUPINGS'][$grouping->id] ) ) {
351
+ $group_data = $data['GROUPINGS'][$grouping->id];
352
+ } elseif( isset( $data['GROUPINGS'][$grouping->name] ) ) {
353
+ $group_data = $data['GROUPINGS'][$grouping->name];
354
+ } else {
355
+ // no data for this grouping was sent, just continue.
356
+ continue;
357
+ }
358
+
359
+ // format new grouping
360
+ $grouping = array(
361
+ 'id' => $grouping->id,
362
+ 'groups' => $group_data
363
+ );
364
+
365
+ // make sure groups is an array
366
+ if( ! is_array( $grouping['groups'] ) ) {
367
+ $grouping['groups'] = sanitize_text_field( $grouping['groups'] );
368
+ $grouping['groups'] = explode( ',', $grouping['groups'] );
369
+ }
370
+
371
+ $list_map['GROUPINGS'][] = $grouping;
372
+
373
+ }
374
+
375
+ // unset GROUPINGS if no grouping data was found for this list
376
+ if( 0 === count( $list_map['GROUPINGS'] ) ) {
377
+ unset( $list_map['GROUPINGS'] );
378
+ }
379
+ }
380
+
381
+ // add to total map
382
+ $map[ $list_id ] = $list_map;
383
 
 
 
384
 
 
 
 
385
  }
386
 
387
+ // loop through data to find unmapped fields
388
+ if( count( $mapped_fields ) < count( $data ) ) {
389
+ foreach( $data as $field_key => $field_value ) {
390
+ if( ! in_array( $field_key, $mapped_fields ) ) {
391
+ $unmapped_fields[ $field_key ] = $field_value;
392
+ }
393
+ }
394
  }
395
 
396
+ $this->unmapped_fields = $unmapped_fields;
397
+ $this->lists_fields_map = $map;
398
+ return true;
399
+ }
400
+
401
+ /**
402
+ * Subscribes the given email and additional list fields
403
+ *
404
+ * @param array $lists_data
405
+ * @return bool
406
+ */
407
+ private function subscribe( $lists_data ) {
408
+
409
+ $api = mc4wp_get_api();
410
+
411
+ do_action( 'mc4wp_before_subscribe', $this->data['EMAIL'], $this->data, 0 );
412
 
413
  $result = false;
414
  $email_type = $this->get_email_type();
415
 
416
+ foreach ( $lists_data as $list_id => $list_field_data ) {
417
+
418
  // allow plugins to alter merge vars for each individual list
419
+ $list_merge_vars = $this->get_list_merge_vars( $list_field_data );
420
+ $list_merge_vars = apply_filters( 'mc4wp_merge_vars', $list_merge_vars, 0, $list_id );
421
 
422
  // send a subscribe request to MailChimp for each list
423
+ $result = $api->subscribe( $list_id, $this->data['EMAIL'], $list_merge_vars, $email_type, $this->form_options['double_optin'], $this->form_options['update_existing'], $this->form_options['replace_interests'], $this->form_options['send_welcome'] );
424
  }
425
 
426
+ do_action( 'mc4wp_after_subscribe', $this->data['EMAIL'], $this->data, 0, $result );
427
 
428
  if ( $result !== true ) {
429
  // subscribe request failed, store error.
430
  $this->success = false;
431
  $this->error_code = $result;
432
+ $this->mailchimp_error = $api->get_error_message();
433
  return false;
434
  }
435
 
436
+ // subscription succeeded
437
+
438
  // store user email in a cookie
439
+ $this->set_email_cookie( $this->data['EMAIL'] );
440
+
441
+ /**
442
+ * @deprecated Don't use, will be removed in v2.0
443
+ * TODO: remove this
444
+ */
445
+ $from_url = ( isset( $_SERVER['HTTP_REFERER'] ) ) ? $_SERVER['HTTP_REFERER'] : '';
446
+ do_action( 'mc4wp_subscribe_form', $this->data['EMAIL'], array_keys( $lists_data ), 0, $this->data, $from_url );
447
 
448
  // Store success result
449
  $this->success = true;
452
  }
453
 
454
  /**
455
+ * Format field value according to its type
456
  *
457
+ * @param $field_type
458
+ * @param $field_value
459
  *
460
+ * @return array|string
461
  */
462
+ private function format_field_value( $field_value, $field_type ) {
463
 
464
+ $field_type = strtolower( $field_type );
 
465
 
466
+ switch( $field_type ) {
467
 
468
+ // birthday fields need to be MM/DD for the MailChimp API
469
+ case 'birthday':
470
+ $field_value = (string) date( 'm/d', strtotime( $field_value ) );
471
+ break;
472
 
473
+ case 'address':
 
 
 
474
 
475
+ // auto-format if addr1 is not set
476
+ if( ! isset( $field_value['addr1'] ) ) {
477
 
478
+ // addr1, addr2, city, state, zip, country
479
+ $address_pieces = explode( ',', $field_value );
 
 
 
 
480
 
481
+ // try to fill it.... this is a long shot
482
+ $field_value = array(
483
+ 'addr1' => $address_pieces[0],
484
+ 'city' => ( isset( $address_pieces[1] ) ) ? $address_pieces[1] : '',
485
+ 'state' => ( isset( $address_pieces[2] ) ) ? $address_pieces[2] : '',
486
+ 'zip' => ( isset( $address_pieces[3] ) ) ? $address_pieces[3] : ''
487
+ );
488
 
 
 
 
489
  }
490
 
491
+ break;
492
+ }
493
 
494
+ /**
495
+ * @filter `mc4wp_format_field_value`
496
+ * @param mixed $field_value
497
+ * @param string $field_type
498
+ * @expects mixed
499
+ *
500
+ * Format a field value according to its MailChimp field type
501
+ */
502
+ $field_value = apply_filters( 'mc4wp_format_field_value', $field_value, $field_type );
503
 
504
+ return $field_value;
505
+ }
506
 
 
 
 
 
 
 
 
507
 
508
+ /**
509
+ * Adds global fields like OPTIN_IP, MC_LANGUAGE, OPTIN_DATE, etc to the list of user-submitted field data.
510
+ *
511
+ * @param $field_data
512
+ * @return array
513
+ */
514
+ private function get_list_merge_vars( $field_data ) {
515
 
516
+ $merge_vars = array(
517
+ 'OPTIN_IP' => sanitize_text_field( $_SERVER['REMOTE_ADDR'] )
518
+ );
519
 
520
+ // add MC_LANGUAGE
521
+ if( isset( $field_data['MC_LANGUAGE'] ) ) {
522
+ $field_data['MC_LANGUAGE'] = strtolower( substr( $field_data['MC_LANGUAGE'], 0, 2 ) );
523
  }
524
 
525
+ $merge_vars = array_merge( $merge_vars, $field_data );
526
+ return $merge_vars;
527
  }
528
 
529
  /**
543
  // allow plugins to override this email type
544
  $email_type = apply_filters( 'mc4wp_email_type', $email_type );
545
 
546
+ return (string) $email_type;
547
  }
548
 
549
  /**
571
  // allow plugins to alter the lists to subscribe to
572
  $lists = apply_filters( 'mc4wp_lists', $lists );
573
 
574
+ return (array) $lists;
575
  }
576
 
577
  /**
584
  /**
585
  * @filter `mc4wp_cookie_expiration_time`
586
  * @expects timestamp
587
+ * @default timestamp for 30 days from now
588
  *
589
  * Timestamp indicating when the email cookie expires, defaults to 30 days
590
  */
598
  *
599
  * @return string
600
  */
601
+ public function get_response_html( ) {
602
 
603
  // get all form messages
604
  $messages = $this->get_form_messages();
605
 
606
  // retrieve correct message
607
+ $type = ( $this->success ) ? 'success' : $this->error_code;
608
  $message = ( isset( $messages[ $type ] ) ) ? $messages[ $type ] : $messages['error'];
609
 
610
  /**
614
  *
615
  * Used to alter the error message, don't use. Use `mc4wp_form_messages` instead.
616
  */
617
+ $message['text'] = apply_filters('mc4wp_form_error_message', $message['text'], $this->error_code );
618
 
619
  $html = '<div class="mc4wp-alert mc4wp-'. $message['type'].'">' . $message['text'] . '</div>';
620
 
621
  // show additional MailChimp API errors to administrators
622
+ if( ! $this->success && current_user_can( 'manage_options' ) ) {
 
 
 
623
 
624
+ if( '' !== $this->mailchimp_error ) {
625
+ $html .= '<div class="mc4wp-alert mc4wp-error"><strong>Admin notice:</strong> '. $this->mailchimp_error . '</div>';
626
  }
627
  }
628
 
641
  * ...
642
  * );
643
  *
 
644
  * @return array
645
  */
646
  public function get_form_messages() {
678
 
679
  /**
680
  * @filter mc4wp_form_messages
681
+ * @expects array
682
  *
683
  * Allows registering custom form messages, useful if you're using custom validation using the `mc4wp_valid_form_request` filter.
684
  */
685
+ $messages = apply_filters( 'mc4wp_form_messages', $messages, 0 );
686
 
687
+ return (array) $messages;
688
  }
689
 
690
 
includes/class-mailchimp.php CHANGED
@@ -11,6 +11,9 @@ class MC4WP_MailChimp {
11
  * Get MailChimp lists
12
  * Try cache first, then try API, then try fallback cache.
13
  *
 
 
 
14
  * @return array
15
  */
16
  public function get_lists( $force_renewal = false, $force_fallback = false ) {
@@ -82,6 +85,8 @@ class MC4WP_MailChimp {
82
  * Get a given MailChimp list
83
  *
84
  * @param int $list_id
 
 
85
  *
86
  * @return bool
87
  */
@@ -104,7 +109,7 @@ class MC4WP_MailChimp {
104
  public function get_list_name( $id ) {
105
  $list = $this->get_list( $id );
106
 
107
- if( is_object( $list ) ) {
108
  return $list->name;
109
  }
110
 
@@ -114,7 +119,7 @@ class MC4WP_MailChimp {
114
  /**
115
  * Returns number of subscribers on given lists.
116
  *
117
- * @param array $list_ids of list id's.
118
  * @return int Sum of subscribers for given lists.
119
  */
120
  public function get_subscriber_count( $list_ids ) {
@@ -162,6 +167,8 @@ class MC4WP_MailChimp {
162
 
163
  /**
164
  * Build the group array object which will be stored in cache
 
 
165
  * @return object
166
  */
167
  public function strip_unnecessary_group_properties( $group ) {
@@ -172,6 +179,8 @@ class MC4WP_MailChimp {
172
 
173
  /**
174
  * Build the groupings array object which will be stored in cache
 
 
175
  * @return object
176
  */
177
  public function strip_unnecessary_grouping_properties( $grouping ) {
@@ -185,6 +194,8 @@ class MC4WP_MailChimp {
185
 
186
  /**
187
  * Build the merge_var array object which will be stored in cache
 
 
188
  * @return object
189
  */
190
  public function strip_unnecessary_merge_vars_properties( $merge_var ) {
11
  * Get MailChimp lists
12
  * Try cache first, then try API, then try fallback cache.
13
  *
14
+ * @param bool $force_renewal
15
+ * @param bool $force_fallback
16
+ *
17
  * @return array
18
  */
19
  public function get_lists( $force_renewal = false, $force_fallback = false ) {
85
  * Get a given MailChimp list
86
  *
87
  * @param int $list_id
88
+ * @param bool $force_renewal
89
+ * @param bool $force_fallback
90
  *
91
  * @return bool
92
  */
109
  public function get_list_name( $id ) {
110
  $list = $this->get_list( $id );
111
 
112
+ if( is_object( $list ) && isset( $list->name ) ) {
113
  return $list->name;
114
  }
115
 
119
  /**
120
  * Returns number of subscribers on given lists.
121
  *
122
+ * @param array $list_ids Array of list id's.
123
  * @return int Sum of subscribers for given lists.
124
  */
125
  public function get_subscriber_count( $list_ids ) {
167
 
168
  /**
169
  * Build the group array object which will be stored in cache
170
+ *
171
+ * @param object $group
172
  * @return object
173
  */
174
  public function strip_unnecessary_group_properties( $group ) {
179
 
180
  /**
181
  * Build the groupings array object which will be stored in cache
182
+ *
183
+ * @param object $grouping
184
  * @return object
185
  */
186
  public function strip_unnecessary_grouping_properties( $grouping ) {
194
 
195
  /**
196
  * Build the merge_var array object which will be stored in cache
197
+ *
198
+ * @param object $merge_var
199
  * @return object
200
  */
201
  public function strip_unnecessary_merge_vars_properties( $merge_var ) {
includes/class-plugin.php CHANGED
@@ -67,6 +67,8 @@ class MC4WP_Lite {
67
  'MC4WP_General_Integration' => 'integrations/class-general.php',
68
  'MC4WP_MultiSite_Integration' => 'integrations/class-multisite.php',
69
  'MC4WP_Registration_Form_Integration' => 'integrations/class-registration-form.php',
 
 
70
  );
71
 
72
  }
67
  'MC4WP_General_Integration' => 'integrations/class-general.php',
68
  'MC4WP_MultiSite_Integration' => 'integrations/class-multisite.php',
69
  'MC4WP_Registration_Form_Integration' => 'integrations/class-registration-form.php',
70
+ 'MC4WP_WooCommerce_Integration' => 'integrations/class-woocommerce.php',
71
+ 'MC4WP_EDD_Integration' => 'integrations/class-edd.php'
72
  );
73
 
74
  }
includes/functions/general.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- if( ! defined("MC4WP_LITE_VERSION") ) {
4
  header( 'Status: 403 Forbidden' );
5
  header( 'HTTP/1.1 403 Forbidden' );
6
  exit;
@@ -13,7 +13,7 @@ if( ! defined("MC4WP_LITE_VERSION") ) {
13
  * @param string $key
14
  * @return array
15
  */
16
- function mc4wp_get_options( $key = null ) {
17
  static $options = null;
18
 
19
  if( null === $options ) {
@@ -35,12 +35,15 @@ function mc4wp_get_options( $key = null ) {
35
  'show_at_multisite_form' => 0,
36
  'show_at_buddypress_form' => 0,
37
  'show_at_bbpress_forms' => 0,
 
 
38
  'lists' => array(),
39
- 'double_optin' => 1
 
40
  ),
41
  'form' => array(
42
  'css' => 'default',
43
- 'markup' => "<p>\n\t<label for=\"mc4wp_email\">{$email_label}: </label>\n\t<input type=\"email\" id=\"mc4wp_email\" name=\"EMAIL\" placeholder=\"{$email_placeholder}\" required />\n</p>\n\n<p>\n\t<input type=\"submit\" value=\"{$signup_button}\" />\n</p>",
44
  'text_success' => __( 'Thank you, your sign-up request was successful! Please check your e-mail inbox.', 'mailchimp-for-wp' ),
45
  'text_error' => __( 'Oops. Something went wrong. Please try again later.', 'mailchimp-for-wp' ),
46
  'text_invalid_email' => __( 'Please provide a valid email address.', 'mailchimp-for-wp' ),
@@ -50,7 +53,10 @@ function mc4wp_get_options( $key = null ) {
50
  'redirect' => '',
51
  'lists' => array(),
52
  'double_optin' => 1,
53
- 'hide_after_success' => 0
 
 
 
54
  )
55
  );
56
 
@@ -62,18 +68,18 @@ function mc4wp_get_options( $key = null ) {
62
 
63
  $options = array();
64
  foreach ( $db_keys_option_keys as $db_key => $option_key ) {
65
- $option = get_option( $db_key, false );
66
 
67
  // add option to database to prevent query on every pageload
68
- if ( $option === false ) {
69
  add_option( $db_key, $defaults[$option_key] );
70
  }
71
 
72
- $options[$option_key] = array_merge( $defaults[$option_key], (array) $option );
73
  }
74
  }
75
 
76
- if( null !== $key ) {
77
  return $options[$key];
78
  }
79
 
1
  <?php
2
 
3
+ if( ! defined( 'MC4WP_LITE_VERSION' ) ) {
4
  header( 'Status: 403 Forbidden' );
5
  header( 'HTTP/1.1 403 Forbidden' );
6
  exit;
13
  * @param string $key
14
  * @return array
15
  */
16
+ function mc4wp_get_options( $key = '' ) {
17
  static $options = null;
18
 
19
  if( null === $options ) {
35
  'show_at_multisite_form' => 0,
36
  'show_at_buddypress_form' => 0,
37
  'show_at_bbpress_forms' => 0,
38
+ 'show_at_woocommerce_checkout' => 0,
39
+ 'show_at_edd_checkout' => 0,
40
  'lists' => array(),
41
+ 'double_optin' => 1,
42
+ 'woocommerce_position' => 'order'
43
  ),
44
  'form' => array(
45
  'css' => 'default',
46
+ 'markup' => "<p>\n\t<label>{$email_label}: </label>\n\t<input type=\"email\" id=\"mc4wp_email\" name=\"EMAIL\" placeholder=\"{$email_placeholder}\" required />\n</p>\n\n<p>\n\t<input type=\"submit\" value=\"{$signup_button}\" />\n</p>",
47
  'text_success' => __( 'Thank you, your sign-up request was successful! Please check your e-mail inbox.', 'mailchimp-for-wp' ),
48
  'text_error' => __( 'Oops. Something went wrong. Please try again later.', 'mailchimp-for-wp' ),
49
  'text_invalid_email' => __( 'Please provide a valid email address.', 'mailchimp-for-wp' ),
53
  'redirect' => '',
54
  'lists' => array(),
55
  'double_optin' => 1,
56
+ 'hide_after_success' => 0,
57
+ 'update_existing' => false,
58
+ 'replace_interests' => true,
59
+ 'send_welcome' => false
60
  )
61
  );
62
 
68
 
69
  $options = array();
70
  foreach ( $db_keys_option_keys as $db_key => $option_key ) {
71
+ $option = (array) get_option( $db_key, array() );
72
 
73
  // add option to database to prevent query on every pageload
74
+ if ( count( $option ) === 0 ) {
75
  add_option( $db_key, $defaults[$option_key] );
76
  }
77
 
78
+ $options[$option_key] = array_merge( $defaults[$option_key], $option );
79
  }
80
  }
81
 
82
+ if( '' !== $key ) {
83
  return $options[$key];
84
  }
85
 
includes/functions/template.php CHANGED
@@ -67,8 +67,8 @@ function mc4wp_replace_variables( $text, $list_ids = array() ) {
67
  }
68
 
69
  // replace {email} tag
70
- if( isset( $_GET['email'] ) ) {
71
- $email = esc_attr( $_GET['email'] );
72
  } elseif( isset( $_COOKIE['mc4wp_email'] ) ) {
73
  $email = esc_attr( $_COOKIE['mc4wp_email'] );
74
  } else {
67
  }
68
 
69
  // replace {email} tag
70
+ if( isset( $_GET['mc4wp_email'] ) ) {
71
+ $email = esc_attr( $_GET['mc4wp_email'] );
72
  } elseif( isset( $_COOKIE['mc4wp_email'] ) ) {
73
  $email = esc_attr( $_COOKIE['mc4wp_email'] );
74
  } else {
includes/integrations/class-edd.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // prevent direct file access
4
+ if( ! defined( 'MC4WP_LITE_VERSION' ) ) {
5
+ header( 'Status: 403 Forbidden' );
6
+ header( 'HTTP/1.1 403 Forbidden' );
7
+ exit;
8
+ }
9
+
10
+ class MC4WP_EDD_Integration extends MC4WP_Integration {
11
+
12
+ /**
13
+ * @var string
14
+ */
15
+ protected $type = 'edd_checkout';
16
+
17
+ /**
18
+ * Constructor
19
+ */
20
+ public function __construct() {
21
+
22
+ parent::__construct();
23
+
24
+ add_action( 'edd_purchase_form_user_info', array( $this, 'output_checkbox' ) );
25
+ add_action( 'edd_payment_meta', array( $this, 'save_checkbox_value' ) );
26
+ add_action( 'edd_complete_purchase', array( $this, 'subscribe_from_edd'), 50);
27
+ }
28
+
29
+ /**
30
+ * @param array $meta
31
+ *
32
+ * @return array
33
+ */
34
+ public function save_checkbox_value( $meta ) {
35
+
36
+ // don't save anything if the checkbox was not checked
37
+ if( ! $this->checkbox_was_checked() ) {
38
+ return $meta;
39
+ }
40
+
41
+ $meta['_mc4wp_optin'] = 1;
42
+ return $meta;
43
+ }
44
+
45
+ /**
46
+ * @param int $payment_id The ID of the payment
47
+ *
48
+ * @return bool|string
49
+ */
50
+ public function subscribe_from_edd( $payment_id ) {
51
+
52
+ $meta = edd_get_payment_meta( $payment_id );
53
+
54
+ if( ! is_array( $meta ) || ! isset( $meta['_mc4wp_optin'] ) || ! $meta['_mc4wp_optin'] ) {
55
+ return false;
56
+ }
57
+
58
+ $email = (string) edd_get_payment_user_email( $payment_id );
59
+ $merge_vars = array();
60
+
61
+ // add first and last name to merge vars, if given
62
+ $user_info = (array) edd_get_payment_meta_user_info( $payment_id );
63
+
64
+ if( isset( $user_info['first_name'] ) && isset( $user_info['last_name'] ) ) {
65
+ $merge_vars['NAME'] = $user_info['first_name'] . ' ' . $user_info['last_name'];
66
+ }
67
+
68
+ if( isset( $user_info['first_name'] ) ) {
69
+ $merge_vars['FNAME'] = $user_info['first_name'];
70
+ }
71
+
72
+ if( isset( $user_info['last_name'] ) ) {
73
+ $merge_vars['LNAME'] = $user_info['last_name'];
74
+ }
75
+
76
+
77
+
78
+ return $this->subscribe( $email, $merge_vars, $this->type );
79
+ }
80
+
81
+ }
82
+
includes/integrations/class-integration.php CHANGED
@@ -18,6 +18,11 @@ abstract class MC4WP_Integration {
18
  */
19
  protected $checkbox_name = '_mc4wp_subscribe';
20
 
 
 
 
 
 
21
  /**
22
  * Constructor
23
  */
@@ -25,6 +30,54 @@ abstract class MC4WP_Integration {
25
  $this->checkbox_name = '_mc4wp_subscribe' . '_' . $this->type;
26
  }
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  /**
29
  * Was the honeypot filled?
30
  *
@@ -54,38 +107,27 @@ abstract class MC4WP_Integration {
54
 
55
  /**
56
  * Outputs a checkbox
57
- *
58
- * @param string $hook
59
  */
60
  public function output_checkbox() {
61
  echo $this->get_checkbox();
62
  }
63
 
64
  /**
65
- * @param mixed $hook Array or string
66
  * @return string
67
  */
68
  public function get_checkbox( $args = array() ) {
69
 
70
- $opts = mc4wp_get_options( 'checkbox' );
71
-
72
- $checked = $opts['precheck'] ? "checked" : '';
73
 
74
  // set label text
75
  if ( isset( $args['labels'][0] ) ) {
76
  // cf 7 shortcode
77
  $label = $args['labels'][0];
78
- } else if ( isset( $opts['text_' . $this->type . '_label'] ) && ! empty( $opts['text_' . $this->type . '_label'] ) ) {
79
- // custom label text was set
80
- $label = __( $opts['text_' . $this->type . '_label'], 'mailchimp-for-wp' );
81
  } else {
82
- // default label text
83
- $label = __( $opts['label'], 'mailchimp-for-wp' );
84
  }
85
 
86
- // replace label variables
87
- $label = mc4wp_replace_variables( $label, $opts['lists'] );
88
-
89
  // CF7 checkbox?
90
  if( is_array( $args ) && isset( $args['type'] ) ) {
91
 
@@ -105,7 +147,7 @@ abstract class MC4WP_Integration {
105
  // checkbox
106
  $content .= '<p id="mc4wp-checkbox">';
107
  $content .= '<label>';
108
- $content .= '<input type="checkbox" name="'. $this->checkbox_name .'" value="1" '. $checked . ' /> ';
109
  $content .= $label;
110
  $content .= '</label>';
111
  $content .= '</p>';
@@ -124,7 +166,7 @@ abstract class MC4WP_Integration {
124
  protected function get_lists() {
125
 
126
  // get checkbox lists options
127
- $opts = mc4wp_get_options( 'checkbox' );
128
  $lists = $opts['lists'];
129
 
130
  // get lists from form, if set.
@@ -134,6 +176,9 @@ abstract class MC4WP_Integration {
134
 
135
  // make sure lists is an array
136
  if( ! is_array( $lists ) ) {
 
 
 
137
  $lists = array( $lists );
138
  }
139
 
@@ -142,22 +187,23 @@ abstract class MC4WP_Integration {
142
  // allow plugins to filter final
143
  $lists = apply_filters( 'mc4wp_lists', $lists );
144
 
145
- return $lists;
146
  }
147
 
 
148
  /**
149
  * Makes a subscription request
150
  *
151
  * @param string $email
152
  * @param array $merge_vars
153
  * @param string $signup_type
154
- * @param int $comment_ID
155
  * @return boolean
156
  */
157
  protected function subscribe( $email, array $merge_vars = array(), $signup_type = 'comment', $comment_id = null ) {
158
 
159
  $api = mc4wp_get_api();
160
- $opts = mc4wp_get_options( 'checkbox' );
161
  $lists = $this->get_lists();
162
 
163
  if( empty( $lists) ) {
@@ -188,23 +234,57 @@ abstract class MC4WP_Integration {
188
 
189
  // set ip address
190
  if( ! isset( $merge_vars['OPTIN_IP'] ) && isset( $_SERVER['REMOTE_ADDR'] ) ) {
191
- $merge_vars['OPTIN_IP'] = $_SERVER['REMOTE_ADDR'];
192
  }
193
 
194
  $result = false;
 
 
 
 
 
 
 
 
 
195
  $merge_vars = apply_filters( 'mc4wp_merge_vars', $merge_vars, $signup_type );
 
 
 
 
 
 
 
 
196
  $email_type = apply_filters( 'mc4wp_email_type', 'html' );
197
 
 
 
 
 
 
 
 
198
  do_action( 'mc4wp_before_subscribe', $email, $merge_vars );
199
 
200
  foreach( $lists as $list_id ) {
201
  $result = $api->subscribe( $list_id, $email, $merge_vars, $email_type, $opts['double_optin'], false, true );
202
  }
203
 
 
 
 
 
 
 
 
 
204
  do_action( 'mc4wp_after_subscribe', $email, $merge_vars, $result );
205
 
206
  if ( $result === true ) {
207
- $from_url = ( isset($_SERVER['HTTP_REFERER'] ) ) ? $_SERVER['HTTP_REFERER'] : '';
 
 
208
  do_action( 'mc4wp_subscribe_checkbox', $email, $lists, $signup_type, $merge_vars, $comment_id, $from_url );
209
  }
210
 
18
  */
19
  protected $checkbox_name = '_mc4wp_subscribe';
20
 
21
+ /**
22
+ * @var array
23
+ */
24
+ private $options;
25
+
26
  /**
27
  * Constructor
28
  */
30
  $this->checkbox_name = '_mc4wp_subscribe' . '_' . $this->type;
31
  }
32
 
33
+ /**
34
+ * Get the checkbox options
35
+ *
36
+ * @return array
37
+ */
38
+ public function get_options() {
39
+
40
+ if( $this->options === null ) {
41
+ $this->options = mc4wp_get_options( 'checkbox' );
42
+ }
43
+
44
+ return $this->options;
45
+ }
46
+
47
+ /**
48
+ * Should the checkbox be pre-checked?
49
+ *
50
+ * @return bool
51
+ */
52
+ public function is_prechecked() {
53
+ $opts = $this->get_options();
54
+ return (bool) $opts['precheck'];
55
+ }
56
+
57
+ /**
58
+ * Get the text for the label element
59
+ *
60
+ * @return string
61
+ */
62
+ public function get_label_text() {
63
+
64
+ $opts = $this->get_options();
65
+
66
+ // Get general label text
67
+ $label = $opts['label'];
68
+
69
+ // Override label text if a specific text for this integration is set
70
+ if ( isset( $opts['text_' . $this->type . '_label'] ) && ! empty( $opts['text_' . $this->type . '_label'] ) ) {
71
+ // custom label text was set
72
+ $label = $opts['text_' . $this->type . '_label'];
73
+ }
74
+
75
+ // replace label variables
76
+ $label = mc4wp_replace_variables( $label, $opts['lists'] );
77
+
78