Constant Contact Forms - Version 1.2.4

Version Description

  • Added: Google reCAPTCHA "I am human" checkbox support for forms. See https://www.google.com/recaptcha/intro/. Will fall back to honeypot prevention if not set up.
  • Fixed: Stray quote mark in honeypot markup.
  • Fixed: missing space after placeholder attribute for inputs.
  • Fixed: Removed unintentional "Leave page" confirmation popup when saving settings.
Download this release

Release Info

Developer constantcontact
Plugin Icon 128x128 Constant Contact Forms
Version 1.2.4
Comparing to
See all releases

Code changes from version 1.2.3 to 1.2.4

Files changed (37) hide show
  1. assets/js/ctct-plugin-admin.js +3 -1
  2. assets/js/ctct-plugin-admin.min.js +1 -1
  3. assets/js/ctct-plugin-admin/builder.js +3 -1
  4. constant-contact-forms.php +4 -2
  5. includes/class-api.php +1 -0
  6. includes/class-builder-fields.php +1 -0
  7. includes/class-display.php +41 -4
  8. includes/class-notification-content.php +37 -0
  9. includes/class-process-form.php +11 -0
  10. includes/class-settings.php +29 -0
  11. includes/helper-functions.php +11 -0
  12. languages/constant-contact-forms.pot +113 -81
  13. readme.txt +7 -1
  14. vendor/recaptcha/.gitignore +3 -0
  15. vendor/recaptcha/.travis.yml +18 -0
  16. vendor/recaptcha/CONTRIBUTING.md +24 -0
  17. vendor/recaptcha/LICENSE +29 -0
  18. vendor/recaptcha/README.md +113 -0
  19. vendor/recaptcha/composer.json +28 -0
  20. vendor/recaptcha/examples/example-captcha.php +130 -0
  21. vendor/recaptcha/phpunit.xml.dist +17 -0
  22. vendor/recaptcha/src/ReCaptcha/ReCaptcha.php +98 -0
  23. vendor/recaptcha/src/ReCaptcha/RequestMethod.php +42 -0
  24. vendor/recaptcha/src/ReCaptcha/RequestMethod/Curl.php +74 -0
  25. vendor/recaptcha/src/ReCaptcha/RequestMethod/CurlPost.php +88 -0
  26. vendor/recaptcha/src/ReCaptcha/RequestMethod/Post.php +70 -0
  27. vendor/recaptcha/src/ReCaptcha/RequestMethod/Socket.php +104 -0
  28. vendor/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php +121 -0
  29. vendor/recaptcha/src/ReCaptcha/RequestParameters.php +103 -0
  30. vendor/recaptcha/src/ReCaptcha/Response.php +102 -0
  31. vendor/recaptcha/src/autoload.php +38 -0
  32. vendor/recaptcha/tests/ReCaptcha/ReCaptchaTest.php +75 -0
  33. vendor/recaptcha/tests/ReCaptcha/RequestMethod/CurlPostTest.php +63 -0
  34. vendor/recaptcha/tests/ReCaptcha/RequestMethod/PostTest.php +118 -0
  35. vendor/recaptcha/tests/ReCaptcha/RequestMethod/SocketPostTest.php +90 -0
  36. vendor/recaptcha/tests/ReCaptcha/RequestParametersTest.php +61 -0
  37. vendor/recaptcha/tests/ReCaptcha/ResponseTest.php +68 -0
assets/js/ctct-plugin-admin.js CHANGED
@@ -182,7 +182,9 @@ window.CTCTBuilder = {};
182
 
183
  // On cmb2 select changes, fire our leave warning function
184
  $( '.cmb2-wrap input, .cmb2-wrap textarea' ).on( 'input', function() {
185
- that.bindLeaveWarning();
 
 
186
  });
187
 
188
  // Disable email options on row change trigger.
182
 
183
  // On cmb2 select changes, fire our leave warning function
184
  $( '.cmb2-wrap input, .cmb2-wrap textarea' ).on( 'input', function() {
185
+ if (typeof(tinyMCE) != "undefined") {
186
+ that.bindLeaveWarning();
187
+ }
188
  });
189
 
190
  // Disable email options on row change trigger.
assets/js/ctct-plugin-admin.min.js CHANGED
@@ -1 +1 @@
1
- window.CTCTAJAX={},function(t,e,c){c.init=function(){c.handleOptinAJAX(),c.handleReviewAJAX()},c.handleOptinAJAX=function(){e("#ctct_admin_notice_tracking_optin").on("click",function(c){var n={action:"constant_contact_optin_ajax_handler",optin:e(this).is(":checked")?"on":"off"};e.ajax({url:ajaxurl,data:n,dataType:"json",success:function(t){},error:function(e,c,n){t.console&&console.log([c,n])}}),e("#ctct-privacy-modal").toggleClass("ctct-modal-open")}),e("#_ctct_data_tracking").on("click",function(t){e("#ctct-privacy-modal").toggleClass("ctct-modal-open")}),e(".ctct-modal-close").on("click",function(t){e("#_ctct_data_tracking").is(":checked")&&e("#_ctct_data_tracking").attr("checked",!1)}),e("#ctct-modal-footer-privacy a").on("click",function(c){var n={action:"constant_contact_privacy_ajax_handler",privacy_agree:e(this).attr("data-agree")};e.ajax({url:ajaxurl,data:n,dataType:"json",success:function(t){e("#ctct-privacy-modal").toggleClass("ctct-modal-open"),"false"===n.privacy_agree&&e("#_ctct_data_tracking").is(":checked")&&e("#_ctct_data_tracking").attr("checked",!1)},error:function(e,c,n){t.console&&console.log([c,n])}})})},c.handleReviewAJAX=function(){e("#ctct-admin-notice-review_request").on("click","a",function(c){var n="dismissed";e(this).hasClass("ctct-review")&&(n="reviewed");var i={action:"constant_contact_review_ajax_handler","ctct-review-action":n};e.ajax({url:ajaxurl,data:i,dataType:"json",success:function(n){t.console&&console.log(n),c.preventDefault(),e("#ctct-admin-notice-review_request").hide()},error:function(e,c,n){t.console&&console.log([c,n])}})})},e(c.init)}(window,jQuery,window.CTCTAJAX),window.CTCTBuilder={},function(t,e,c){c.init=function(){e("#cmb2-metabox-ctct_2_fields_metabox option[value='email']:selected").length&&e("#ctct-no-email-error").remove(),c.cache(),c.bindEvents(),c.selectBinds(),c.modifyFields(),e("#ctct_0_description_metabox h2.hndle").removeClass("ui-sortable-handle, hndle"),e("head").append('<style> #cmb2-metabox-ctct_2_fields_metabox a.move-up::after { content: "'+ctct_texts.move_up+'" } #cmb2-metabox-ctct_2_fields_metabox a.move-down::after { content: "'+ctct_texts.move_down+'" }</style>')},c.cache=function(){c.$c={window:e(t),body:e("body")},c.isLeaveWarningBound=!1},c.bindLeaveWarning=function(){c.isLeaveWarningBound||(e(t).bind("beforeunload",function(){return ctct_texts.leavewarning}),c.isLeaveWarningBound=!0)},c.unbindLeaveWarning=function(){e(t).unbind("beforeunload")},c.bindEvents=function(){e("#post").submit(function(){e(".ctct-email-disabled").removeClass("disabled").prop("disabled",!1),c.unbindLeaveWarning()}),e(".cmb2-wrap input, .cmb2-wrap textarea").on("input",function(){c.bindLeaveWarning()}),e(document).on("cmb2_shift_rows_complete",function(){c.modifyFields(),c.bindLeaveWarning(),c.removeDuplicateMappings()}),e(document).on("cmb2_add_row",function(t){e("#custom_fields_group_repeat .postbox").last().find(".map select").val("none"),c.modifyFields(),c.selectBinds(),c.removeDuplicateMappings()}),c.removeDuplicateMappings()},c.selectBinds=function(){e("#cmb2-metabox-ctct_2_fields_metabox .cmb2_select").change(function(){c.modifyFields(),c.removeDuplicateMappings(),c.bindLeaveWarning()})},c.modifyFields=function(){var c=!1;e("#cmb2-metabox-ctct_2_fields_metabox #custom_fields_group_repeat .cmb-repeatable-grouping").each(function(n,i){var o=e(this).find(".cmb-field-list"),a=e(o).find(".cmb-remove-group-row"),s=e(o).find(".required input[type=checkbox]"),l=s.closest(".cmb-row"),d=e(o).find(".map select option:selected"),r=d.text(),u=e(this).find("h3"),_=e(this).find("input[name*='_ctct_field_label']"),m=e(this).find("input[name*='_ctct_field_desc']");if(u.text(r),(0===_.val().length||_.hasClass("ctct-label-filled"))&&_.val(r).addClass("ctct-label-filled"),c||"email"!==e(d).val()?(e(i).find("select").removeClass("disabled ctct-email-disabled").prop("disabled",!1),l.show(),a.show()):(c=!0,s.prop("checked",!0),e(i).find("select").addClass("disabled ctct-email-disabled").prop("disabled",!0),l.hide(),a.hide()),t.ctct_admin_placeholders){var p=t.ctct_admin_placeholders[e(i).find("select").val()];p&&p.length&&m.length?m.attr("placeholder","Example: "+p):t.ctct_admin_placeholders["default"]&&m.attr("placeholder",t.ctct_admin_placeholders["default"])}})},c.removeDuplicateMappings=function(){var t=[],c="#cmb2-metabox-ctct_2_fields_metabox #custom_fields_group_repeat .cmb-repeatable-grouping select",n=e(c);n.each(function(c,n){t.push(e(n).val())}),n.children().show(),t.forEach(function(t){"custom_text_area"!=t&&"custom"!=t&&e(c+" option[value="+t+"]:not( :selected )").hide()})},e(c.init)}(window,jQuery,window.CTCTBuilder),window.CTCTForms={},function(t,e,c){c.init=function(){c.cache(),c.bindEvents()},c.cache=function(){c.$c={window:e(t),body:e("body"),disconnect:".ctct-disconnect"}},c.bindEvents=function(){e(c.$c.disconnect).on("click",function(t){confirm(ctct_texts.disconnectconfirm)})},e(c.init)}(window,jQuery,window.CTCTForms),window.CTCTModal={},function(t,e,c){c.init=function(){c.cache(),c.bindEvents()},c.cache=function(){c.$c={window:e(t),modalSelector:e(".ctct-modal"),modalClose:e(".ctct-modal-close"),textareaModal:e("#ctct-custom-textarea-modal"),textareaLink:e("#ctct-open-textarea-info")}},c.bindEvents=function(){c.$c.modalClose.click(function(){c.$c.modalSelector.removeClass("ctct-modal-open"),c.$c.modalSelector.hasClass("ctct-custom-textarea-modal")||jQuery.ajax({type:"post",dataType:"json",url:ajaxurl,data:{action:"ctct_dismiss_first_modal",ctct_is_dismissed:"true"}})}),c.$c.textareaLink.on("click",function(){c.$c.textareaModal.addClass("ctct-modal-open")})},e(c.init)}(window,jQuery,window.CTCTModal),window.CTCTNewsletter={},function(t,e,c){c.init=function(){c.submitNewsletter()},e(c.init),c.submitNewsletter=function(){e(".ctct-body #subscribe").on("submit",function(t){t.preventDefault(),console.log("connect");var c=e("#subscribe .ctct-call-to-action"),n=e(".ctct-body #subscribe")[0],i=e(".ctct-call-to-action input[type='text']")[0],o=t.target.action;i.validity.valid===!0?(e("<iframe>",{src:o+"?"+e(n).serialize(),height:0,width:0,style:"display: none;"}).appendTo(c),e("#subbutton").val("Thanks for signing up").css({"background-color":"rgb(1, 128, 0)",color:"rgb(255,255,255)"}),e("#subscribe .ctct-call-to-action-text").css({width:"70%"})):e("#subbutton").val("Error occurred")}),e(".ctct-section #subscribe").on("submit",function(t){t.preventDefault();var c=e(".section-marketing-tips"),n=e(".ctct-section #subscribe")[0],i=e(".ctct-section #subscribe input[type='text']")[0],o=t.target.action;i.validity.valid===!0?(e("<iframe>",{src:o+"?"+e(n).serialize(),height:0,width:0,style:"display: none;"}).appendTo(c),e("#subbutton").val("Thanks for signing up").css({"background-color":"rgb(1, 128, 0)"})):e("#subbutton").val("Error occurred")})}}(window,jQuery,window.CTCTNewsletter),window.CTCT_OptIns={},function(t,e,c){c.init=function(){c.cache(),c.bindEvents()},c.cache=function(){c.$c={optin_no_conn:e("#cmb2-metabox-ctct_1_optin_metabox #_ctct_opt_in_not_connected"),list:e("#cmb2-metabox-ctct_1_optin_metabox #_ctct_list"),optin:e("#cmb2-metabox-ctct_1_optin_metabox .cmb2-id--ctct-opt-in"),instruct:e("#cmb2-metabox-ctct_1_optin_metabox .cmb2-id--ctct-opt-in-instructions")}},c.bindEvents=function(){c.$c.optin_no_conn.length&&(c.toggleNoConnectionFields(),c.$c.optin_no_conn.change(function(){c.toggleNoConnectionFields()})),c.$c.list.length&&(c.toggleConnectionFields(),c.$c.list.change(function(){c.toggleConnectionFields()}))},c.toggleNoConnectionFields=function(){c.$c.optin_no_conn.prop("checked")?c.$c.instruct.slideDown():c.$c.instruct.slideUp()},c.toggleConnectionFields=function(){""!=c.$c.list.val()?(c.$c.optin.slideDown(),c.$c.instruct.slideDown()):(c.$c.optin.slideUp(),c.$c.instruct.slideUp())},e(c.init)}(window,jQuery,window.CTCT_OptIns);
1
+ window.CTCTAJAX={},function(t,e,c){c.init=function(){c.handleOptinAJAX(),c.handleReviewAJAX()},c.handleOptinAJAX=function(){e("#ctct_admin_notice_tracking_optin").on("click",function(c){var n={action:"constant_contact_optin_ajax_handler",optin:e(this).is(":checked")?"on":"off"};e.ajax({url:ajaxurl,data:n,dataType:"json",success:function(t){},error:function(e,c,n){t.console&&console.log([c,n])}}),e("#ctct-privacy-modal").toggleClass("ctct-modal-open")}),e("#_ctct_data_tracking").on("click",function(t){e("#ctct-privacy-modal").toggleClass("ctct-modal-open")}),e(".ctct-modal-close").on("click",function(t){e("#_ctct_data_tracking").is(":checked")&&e("#_ctct_data_tracking").attr("checked",!1)}),e("#ctct-modal-footer-privacy a").on("click",function(c){var n={action:"constant_contact_privacy_ajax_handler",privacy_agree:e(this).attr("data-agree")};e.ajax({url:ajaxurl,data:n,dataType:"json",success:function(t){e("#ctct-privacy-modal").toggleClass("ctct-modal-open"),"false"===n.privacy_agree&&e("#_ctct_data_tracking").is(":checked")&&e("#_ctct_data_tracking").attr("checked",!1)},error:function(e,c,n){t.console&&console.log([c,n])}})})},c.handleReviewAJAX=function(){e("#ctct-admin-notice-review_request").on("click","a",function(c){var n="dismissed";e(this).hasClass("ctct-review")&&(n="reviewed");var i={action:"constant_contact_review_ajax_handler","ctct-review-action":n};e.ajax({url:ajaxurl,data:i,dataType:"json",success:function(n){t.console&&console.log(n),c.preventDefault(),e("#ctct-admin-notice-review_request").hide()},error:function(e,c,n){t.console&&console.log([c,n])}})})},e(c.init)}(window,jQuery,window.CTCTAJAX),window.CTCTBuilder={},function(t,e,c){c.init=function(){e("#cmb2-metabox-ctct_2_fields_metabox option[value='email']:selected").length&&e("#ctct-no-email-error").remove(),c.cache(),c.bindEvents(),c.selectBinds(),c.modifyFields(),e("#ctct_0_description_metabox h2.hndle").removeClass("ui-sortable-handle, hndle"),e("head").append('<style> #cmb2-metabox-ctct_2_fields_metabox a.move-up::after { content: "'+ctct_texts.move_up+'" } #cmb2-metabox-ctct_2_fields_metabox a.move-down::after { content: "'+ctct_texts.move_down+'" }</style>')},c.cache=function(){c.$c={window:e(t),body:e("body")},c.isLeaveWarningBound=!1},c.bindLeaveWarning=function(){c.isLeaveWarningBound||(e(t).bind("beforeunload",function(){return ctct_texts.leavewarning}),c.isLeaveWarningBound=!0)},c.unbindLeaveWarning=function(){e(t).unbind("beforeunload")},c.bindEvents=function(){e("#post").submit(function(){e(".ctct-email-disabled").removeClass("disabled").prop("disabled",!1),c.unbindLeaveWarning()}),e(".cmb2-wrap input, .cmb2-wrap textarea").on("input",function(){"undefined"!=typeof tinyMCE&&c.bindLeaveWarning()}),e(document).on("cmb2_shift_rows_complete",function(){c.modifyFields(),c.bindLeaveWarning(),c.removeDuplicateMappings()}),e(document).on("cmb2_add_row",function(t){e("#custom_fields_group_repeat .postbox").last().find(".map select").val("none"),c.modifyFields(),c.selectBinds(),c.removeDuplicateMappings()}),c.removeDuplicateMappings()},c.selectBinds=function(){e("#cmb2-metabox-ctct_2_fields_metabox .cmb2_select").change(function(){c.modifyFields(),c.removeDuplicateMappings(),c.bindLeaveWarning()})},c.modifyFields=function(){var c=!1;e("#cmb2-metabox-ctct_2_fields_metabox #custom_fields_group_repeat .cmb-repeatable-grouping").each(function(n,i){var o=e(this).find(".cmb-field-list"),a=e(o).find(".cmb-remove-group-row"),s=e(o).find(".required input[type=checkbox]"),l=s.closest(".cmb-row"),d=e(o).find(".map select option:selected"),r=d.text(),u=e(this).find("h3"),_=e(this).find("input[name*='_ctct_field_label']"),m=e(this).find("input[name*='_ctct_field_desc']");if(u.text(r),(0===_.val().length||_.hasClass("ctct-label-filled"))&&_.val(r).addClass("ctct-label-filled"),c||"email"!==e(d).val()?(e(i).find("select").removeClass("disabled ctct-email-disabled").prop("disabled",!1),l.show(),a.show()):(c=!0,s.prop("checked",!0),e(i).find("select").addClass("disabled ctct-email-disabled").prop("disabled",!0),l.hide(),a.hide()),t.ctct_admin_placeholders){var p=t.ctct_admin_placeholders[e(i).find("select").val()];p&&p.length&&m.length?m.attr("placeholder","Example: "+p):t.ctct_admin_placeholders["default"]&&m.attr("placeholder",t.ctct_admin_placeholders["default"])}})},c.removeDuplicateMappings=function(){var t=[],c="#cmb2-metabox-ctct_2_fields_metabox #custom_fields_group_repeat .cmb-repeatable-grouping select",n=e(c);n.each(function(c,n){t.push(e(n).val())}),n.children().show(),t.forEach(function(t){"custom_text_area"!=t&&"custom"!=t&&e(c+" option[value="+t+"]:not( :selected )").hide()})},e(c.init)}(window,jQuery,window.CTCTBuilder),window.CTCTForms={},function(t,e,c){c.init=function(){c.cache(),c.bindEvents()},c.cache=function(){c.$c={window:e(t),body:e("body"),disconnect:".ctct-disconnect"}},c.bindEvents=function(){e(c.$c.disconnect).on("click",function(t){confirm(ctct_texts.disconnectconfirm)})},e(c.init)}(window,jQuery,window.CTCTForms),window.CTCTModal={},function(t,e,c){c.init=function(){c.cache(),c.bindEvents()},c.cache=function(){c.$c={window:e(t),modalSelector:e(".ctct-modal"),modalClose:e(".ctct-modal-close"),textareaModal:e("#ctct-custom-textarea-modal"),textareaLink:e("#ctct-open-textarea-info")}},c.bindEvents=function(){c.$c.modalClose.click(function(){c.$c.modalSelector.removeClass("ctct-modal-open"),c.$c.modalSelector.hasClass("ctct-custom-textarea-modal")||jQuery.ajax({type:"post",dataType:"json",url:ajaxurl,data:{action:"ctct_dismiss_first_modal",ctct_is_dismissed:"true"}})}),c.$c.textareaLink.on("click",function(){c.$c.textareaModal.addClass("ctct-modal-open")})},e(c.init)}(window,jQuery,window.CTCTModal),window.CTCTNewsletter={},function(t,e,c){c.init=function(){c.submitNewsletter()},e(c.init),c.submitNewsletter=function(){e(".ctct-body #subscribe").on("submit",function(t){t.preventDefault(),console.log("connect");var c=e("#subscribe .ctct-call-to-action"),n=e(".ctct-body #subscribe")[0],i=e(".ctct-call-to-action input[type='text']")[0],o=t.target.action;i.validity.valid===!0?(e("<iframe>",{src:o+"?"+e(n).serialize(),height:0,width:0,style:"display: none;"}).appendTo(c),e("#subbutton").val("Thanks for signing up").css({"background-color":"rgb(1, 128, 0)",color:"rgb(255,255,255)"}),e("#subscribe .ctct-call-to-action-text").css({width:"70%"})):e("#subbutton").val("Error occurred")}),e(".ctct-section #subscribe").on("submit",function(t){t.preventDefault();var c=e(".section-marketing-tips"),n=e(".ctct-section #subscribe")[0],i=e(".ctct-section #subscribe input[type='text']")[0],o=t.target.action;i.validity.valid===!0?(e("<iframe>",{src:o+"?"+e(n).serialize(),height:0,width:0,style:"display: none;"}).appendTo(c),e("#subbutton").val("Thanks for signing up").css({"background-color":"rgb(1, 128, 0)"})):e("#subbutton").val("Error occurred")})}}(window,jQuery,window.CTCTNewsletter),window.CTCT_OptIns={},function(t,e,c){c.init=function(){c.cache(),c.bindEvents()},c.cache=function(){c.$c={optin_no_conn:e("#cmb2-metabox-ctct_1_optin_metabox #_ctct_opt_in_not_connected"),list:e("#cmb2-metabox-ctct_1_optin_metabox #_ctct_list"),optin:e("#cmb2-metabox-ctct_1_optin_metabox .cmb2-id--ctct-opt-in"),instruct:e("#cmb2-metabox-ctct_1_optin_metabox .cmb2-id--ctct-opt-in-instructions")}},c.bindEvents=function(){c.$c.optin_no_conn.length&&(c.toggleNoConnectionFields(),c.$c.optin_no_conn.change(function(){c.toggleNoConnectionFields()})),c.$c.list.length&&(c.toggleConnectionFields(),c.$c.list.change(function(){c.toggleConnectionFields()}))},c.toggleNoConnectionFields=function(){c.$c.optin_no_conn.prop("checked")?c.$c.instruct.slideDown():c.$c.instruct.slideUp()},c.toggleConnectionFields=function(){""!=c.$c.list.val()?(c.$c.optin.slideDown(),c.$c.instruct.slideDown()):(c.$c.optin.slideUp(),c.$c.instruct.slideUp())},e(c.init)}(window,jQuery,window.CTCT_OptIns);
assets/js/ctct-plugin-admin/builder.js CHANGED
@@ -76,7 +76,9 @@ window.CTCTBuilder = {};
76
 
77
  // On cmb2 select changes, fire our leave warning function
78
  $( '.cmb2-wrap input, .cmb2-wrap textarea' ).on( 'input', function() {
79
- that.bindLeaveWarning();
 
 
80
  });
81
 
82
  // Disable email options on row change trigger.
76
 
77
  // On cmb2 select changes, fire our leave warning function
78
  $( '.cmb2-wrap input, .cmb2-wrap textarea' ).on( 'input', function() {
79
+ if (typeof(tinyMCE) != "undefined") {
80
+ that.bindLeaveWarning();
81
+ }
82
  });
83
 
84
  // Disable email options on row change trigger.
constant-contact-forms.php CHANGED
@@ -12,7 +12,7 @@
12
  * Plugin Name: Constant Contact Forms for WordPress
13
  * Plugin URI: https://www.constantcontact.com
14
  * Description: Be a better marketer. All it takes is Constant Contact email marketing.
15
- * Version: 1.2.3
16
  * Author: Constant Contact
17
  * Author URI: https://www.constantcontact.com
18
  * License: GPLv3
@@ -77,7 +77,7 @@ class Constant_Contact {
77
  * @var string
78
  * @since 1.0.0
79
  */
80
- const VERSION = '1.2.3';
81
 
82
  /**
83
  * URL of plugin directory
@@ -380,6 +380,8 @@ class Constant_Contact {
380
  'defuse-php-encryption/Key.php',
381
  'defuse-php-encryption/KeyOrPassword.php',
382
  'defuse-php-encryption/RuntimeTests.php',
 
 
383
  );
384
 
385
  // If we don't alrady have WDS_Shortcodes loaded somewhere else, load it up.
12
  * Plugin Name: Constant Contact Forms for WordPress
13
  * Plugin URI: https://www.constantcontact.com
14
  * Description: Be a better marketer. All it takes is Constant Contact email marketing.
15
+ * Version: 1.2.4
16
  * Author: Constant Contact
17
  * Author URI: https://www.constantcontact.com
18
  * License: GPLv3
77
  * @var string
78
  * @since 1.0.0
79
  */
80
+ const VERSION = '1.2.4';
81
 
82
  /**
83
  * URL of plugin directory
380
  'defuse-php-encryption/Key.php',
381
  'defuse-php-encryption/KeyOrPassword.php',
382
  'defuse-php-encryption/RuntimeTests.php',
383
+
384
+ 'recaptcha/src/autoload.php',
385
  );
386
 
387
  // If we don't alrady have WDS_Shortcodes loaded somewhere else, load it up.
includes/class-api.php CHANGED
@@ -536,6 +536,7 @@ class ConstantContact_API {
536
  switch ( $key ) {
537
  case 'email':
538
  case 'website':
 
539
  // Do nothing, as we already captured.
540
  break;
541
  case 'phone_number':
536
  switch ( $key ) {
537
  case 'email':
538
  case 'website':
539
+ case 'g-recaptcha-response':
540
  // Do nothing, as we already captured.
541
  break;
542
  case 'phone_number':
includes/class-builder-fields.php CHANGED
@@ -217,6 +217,7 @@ class ConstantContact_Builder_Fields {
217
  'id' => $this->prefix . 'opt_in',
218
  'description' => $description,
219
  'type' => 'checkbox',
 
220
  ) );
221
  }
222
 
217
  'id' => $this->prefix . 'opt_in',
218
  'description' => $description,
219
  'type' => 'checkbox',
220
+ 'before_row' => '<div><strong>' . esc_html__( 'Important: opt-in settings required for sending user submissions to ConstantContact.com', 'constant-contact-forms' ) . '</strong></div>',
221
  ) );
222
  }
223
 
includes/class-display.php CHANGED
@@ -160,8 +160,12 @@ class ConstantContact_Display {
160
  // Output our normal form fields.
161
  $return .= $this->build_form_fields( $form_data, $old_values, $req_errors );
162
 
163
- // Output a field that should not be populated, and will be visually hidden with inline CSS.
164
- $return .= $this->build_honeypot_field();
 
 
 
 
165
 
166
  // Add our hidden verification fields.
167
  $return .= $this->add_verify_fields( $form_data );
@@ -293,18 +297,51 @@ class ConstantContact_Display {
293
  return $return;
294
  }
295
 
 
 
 
 
 
 
 
296
  public function build_honeypot_field() {
297
  $return = '';
298
 
299
  $return .= sprintf(
300
  '<div id="ctct_usage" style="%s"><label for="ctct_usage_field">%s</label><input type="text" value="" name="ctct_usage_field" id="ctct_usage_field" /></div>',
301
- 'position:absolute;overflow:hidden;clip:rect(0px,0px,0px,0px);height:1px;width:1px;margin:-1px;border:0px none;padding:0px;"',
302
  esc_html__( 'Constant Contact Use.', 'constant-contact-forms' )
303
  );
304
 
305
  return $return;
306
  }
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  /**
309
  * Wrapper for single field display.
310
  *
@@ -669,7 +706,7 @@ class ConstantContact_Display {
669
  $classes = apply_filters( 'constant_contact_input_classes', $classes, $type );
670
 
671
  // Set our field as as seprate var, because we allow for only returning that.
672
- $field = '<input ' . $req_text . ' type="' . $type . '" name="' . $f_id . '" id="' . $f_id . '" value="' . $value . '" placeholder="' . $label . '"';
673
 
674
  // If we have an error.
675
  if ( $field_error ) {
160
  // Output our normal form fields.
161
  $return .= $this->build_form_fields( $form_data, $old_values, $req_errors );
162
 
163
+ if ( $this->plugin->settings->has_recaptcha() ) {
164
+ $return .= $this->build_recaptcha();
165
+ } else {
166
+ // Output a field that should not be populated, and will be visually hidden with inline CSS.
167
+ $return .= $this->build_honeypot_field();
168
+ }
169
 
170
  // Add our hidden verification fields.
171
  $return .= $this->add_verify_fields( $form_data );
297
  return $return;
298
  }
299
 
300
+ /**
301
+ * Display a honeypot spam field.
302
+ *
303
+ * @since 1.2.2
304
+ *
305
+ * @return string
306
+ */
307
  public function build_honeypot_field() {
308
  $return = '';
309
 
310
  $return .= sprintf(
311
  '<div id="ctct_usage" style="%s"><label for="ctct_usage_field">%s</label><input type="text" value="" name="ctct_usage_field" id="ctct_usage_field" /></div>',
312
+ 'position:absolute;overflow:hidden;clip:rect(0px,0px,0px,0px);height:1px;width:1px;margin:-1px;border:0px none;padding:0px;',
313
  esc_html__( 'Constant Contact Use.', 'constant-contact-forms' )
314
  );
315
 
316
  return $return;
317
  }
318
 
319
+ public function build_recaptcha() {
320
+ // If we've reached this point, we know we have our keys.
321
+ $site_key = ctct_get_settings_option( '_ctct_recaptcha_site_key' );
322
+
323
+ /**
324
+ * Filters the language code to be used with Google reCAPTCHA.
325
+ *
326
+ * See https://developers.google.com/recaptcha/docs/language for available values.
327
+ *
328
+ * @since 1.2.4
329
+ *
330
+ * @param string $value Language code to use. Default 'en'.
331
+ */
332
+ $recaptcha_lang = apply_filters( 'constant_contact_recaptcha_lang', 'en' );
333
+
334
+ $return = '';
335
+
336
+ $return .= sprintf(
337
+ '<div class="g-recaptcha" data-sitekey="%s"></div><script type="text/javascript" src="https://www.google.com/recaptcha/api.js?hl=%s"></script>',
338
+ esc_attr( $site_key ),
339
+ esc_attr( $recaptcha_lang )
340
+ );
341
+
342
+ return $return;
343
+ }
344
+
345
  /**
346
  * Wrapper for single field display.
347
  *
706
  $classes = apply_filters( 'constant_contact_input_classes', $classes, $type );
707
 
708
  // Set our field as as seprate var, because we allow for only returning that.
709
+ $field = '<input ' . $req_text . ' type="' . $type . '" name="' . $f_id . '" id="' . $f_id . '" value="' . $value . '" placeholder="' . $label . '" ';
710
 
711
  // If we have an error.
712
  if ( $field_error ) {
includes/class-notification-content.php CHANGED
@@ -157,6 +157,22 @@ class ConstantContact_Notification_Content {
157
  // @codingStandardsIgnoreLine
158
  // return __( 'Welcome to v1.0.1 of Constant Contact.', 'constant-contact-forms' );
159
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  }
161
 
162
  /**
@@ -193,6 +209,7 @@ add_filter( 'constant_contact_notifications', 'constant_contact_add_optin_notifi
193
 
194
  /**
195
  * Adds our opt-in notification to the notification system.
 
196
  * @since 1.2.0
197
  *
198
  * @param array $notifications Array of notifications pending to show.
@@ -211,3 +228,23 @@ function constant_contact_add_review_notification( $notifications = array() ) {
211
  }
212
 
213
  add_filter( 'constant_contact_notifications', 'constant_contact_add_review_notification' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  // @codingStandardsIgnoreLine
158
  // return __( 'Welcome to v1.0.1 of Constant Contact.', 'constant-contact-forms' );
159
  }
160
+
161
+ /**
162
+ * Content for the reCAPTCHA information notice.
163
+ *
164
+ * @since 1.2.4
165
+ *
166
+ * @return string
167
+ */
168
+ public function reCAPTCHA() {
169
+ ob_start();
170
+ printf(
171
+ __( 'Protect yourself from Spam &amp; Bots: New <strong>v1.2.4 Constant Contact Forms for WordPress</strong> now supports Google reCAPTCHA. Learn more and implement via <a href="%s">Settings</a>', 'constant-contact-forms' ),
172
+ admin_url( 'edit.php?post_type=ctct_forms&page=ctct_options_settings' )
173
+ );
174
+ return ob_get_clean();
175
+ }
176
  }
177
 
178
  /**
209
 
210
  /**
211
  * Adds our opt-in notification to the notification system.
212
+ *
213
  * @since 1.2.0
214
  *
215
  * @param array $notifications Array of notifications pending to show.
228
  }
229
 
230
  add_filter( 'constant_contact_notifications', 'constant_contact_add_review_notification' );
231
+
232
+ /**
233
+ * Adds our reCAPTCHA informational admin notice.
234
+ *
235
+ * @since 1.2.4
236
+ *
237
+ * @param array $notifications Array of notifications pending to show.
238
+ * @return array Array of notifications to show.
239
+ */
240
+ function constant_contact_add_reCAPTCHA_notification( $notifications = array() ) {
241
+
242
+ $notifications[] = array(
243
+ 'ID' => 'reCAPTCHA',
244
+ 'callback' => array( 'ConstantContact_Notification_Content', 'reCAPTCHA' ),
245
+ 'require_cb' => 'constant_contact_maybe_display_reCAPTCHA_notification',
246
+ );
247
+
248
+ return $notifications;
249
+ }
250
+ add_filter( 'constant_contact_notifications', 'constant_contact_add_reCAPTCHA_notification' );
includes/class-process-form.php CHANGED
@@ -143,6 +143,17 @@ class ConstantContact_Process_Form {
143
  return;
144
  }
145
 
 
 
 
 
 
 
 
 
 
 
 
146
  // Verify our nonce first.
147
  if (
148
  ! isset( $data['ctct_form'] ) ||
143
  return;
144
  }
145
 
146
+ if ( isset( $data['g-recaptcha-response'] ) ) {
147
+ $secret = ctct_get_settings_option( '_ctct_recaptcha_secret_key' );
148
+ $recaptcha = new \ReCaptcha\ReCaptcha( $secret );
149
+
150
+ $resp = $recaptcha->verify( $data['g-recaptcha-response'], $_SERVER['REMOTE_ADDR'] );
151
+
152
+ if ( ! $resp->isSuccess() ) {
153
+ return;
154
+ }
155
+ }
156
+
157
  // Verify our nonce first.
158
  if (
159
  ! isset( $data['ctct_form'] ) ||
includes/class-settings.php CHANGED
@@ -333,6 +333,24 @@ class ConstantContact_Settings {
333
  }
334
  }
335
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
  }
337
 
338
  /**
@@ -766,6 +784,17 @@ class ConstantContact_Settings {
766
  $output = preg_replace( '@<section class=header>.*?</section>@si', '', $output );
767
  return $output;
768
  }
 
 
 
 
 
 
 
 
 
 
 
769
  }
770
  }
771
 
333
  }
334
  }
335
  }
336
+
337
+ $before_recaptcha = sprintf(
338
+ '<hr/><h2>%s</h2>%s',
339
+ esc_html__( 'Google reCAPTCHA', 'constant-contact-forms' ),
340
+ '<div class="discover-recaptcha">' . __( 'Learn more and get an <a href="https://www.google.com/recaptcha/intro/" target="_blank">API site key</a>', 'constant-contact-forms' ) . '</div>'
341
+ );
342
+ $cmb->add_field( array(
343
+ 'name' => __( 'Site Key', 'constant-contact-forms' ),
344
+ 'id' => '_ctct_recaptcha_site_key',
345
+ 'type' => 'text',
346
+ 'before_row' => $before_recaptcha,
347
+ ) );
348
+
349
+ $cmb->add_field( array(
350
+ 'name' => __( 'Secret Key', 'constant-contact-forms' ),
351
+ 'id' => '_ctct_recaptcha_secret_key',
352
+ 'type' => 'text',
353
+ ) );
354
  }
355
 
356
  /**
784
  $output = preg_replace( '@<section class=header>.*?</section>@si', '', $output );
785
  return $output;
786
  }
787
+ return '';
788
+ }
789
+
790
+ public function has_recaptcha() {
791
+ $site_key = ctct_get_settings_option( '_ctct_recaptcha_site_key', '' );
792
+ $secret_key = ctct_get_settings_option( '_ctct_recaptcha_secret_key', '' );
793
+
794
+ if ( $site_key && $secret_key ) {
795
+ return true;
796
+ }
797
+ return false;
798
  }
799
  }
800
 
includes/helper-functions.php CHANGED
@@ -163,6 +163,17 @@ function constant_contact_maybe_display_review_notification() {
163
  return true;
164
  }
165
 
 
 
 
 
 
 
 
 
 
 
 
166
  /**
167
  * Handle the optin checkbox for the admin notice.
168
  *
163
  return true;
164
  }
165
 
166
+ /**
167
+ * Whether or not to show our reCAPTCHA info notice. Should only show
168
+ *
169
+ * @since 1.2.4
170
+ *
171
+ * @return bool
172
+ */
173
+ function constant_contact_maybe_display_reCAPTCHA_notification() {
174
+ return true;
175
+ }
176
+
177
  /**
178
  * Handle the optin checkbox for the admin notice.
179
  *
languages/constant-contact-forms.pot CHANGED
@@ -3,14 +3,14 @@ msgid ""
3
  msgstr ""
4
  "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
5
  "Project-Id-Version: Constant Contact Forms for WordPress\n"
6
- "POT-Creation-Date: 2017-02-23 22:39-0600\n"
7
  "PO-Revision-Date: 2017-01-12 14:46-0600\n"
8
  "Last-Translator: Michael Beckwith <michael.d.beckwith@gmail.com>\n"
9
  "Language-Team: Constant Contact\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
- "X-Generator: Poedit 1.8.12\n"
14
  "X-Poedit-Basepath: ..\n"
15
  "X-Poedit-WPHeader: constant-contact-forms.php\n"
16
  "X-Poedit-SourceCharset: UTF-8\n"
@@ -35,7 +35,7 @@ msgid ""
35
  "website administrator should be able to assist in updating your PHP version."
36
  msgstr ""
37
 
38
- #: constant-contact-forms.php:552
39
  msgid "Error loading license."
40
  msgstr ""
41
 
@@ -266,7 +266,7 @@ msgstr ""
266
  msgid "License"
267
  msgstr ""
268
 
269
- #: includes/class-admin.php:204 includes/class-settings.php:653
270
  msgid "Settings updated."
271
  msgstr ""
272
 
@@ -274,7 +274,7 @@ msgstr ""
274
  msgid "Description"
275
  msgstr ""
276
 
277
- #: includes/class-admin.php:243 includes/class-builder-fields.php:431
278
  msgid "Shortcode"
279
  msgstr ""
280
 
@@ -302,7 +302,7 @@ msgstr ""
302
  msgid "Contact type not returned"
303
  msgstr ""
304
 
305
- #: includes/class-api.php:683
306
  msgid ""
307
  "Your API access token is invalid. Reconnect to Constant Contact to receive a "
308
  "new token."
@@ -356,156 +356,162 @@ msgstr ""
356
  msgid "Show Opt-in checkbox"
357
  msgstr ""
358
 
359
- #: includes/class-builder-fields.php:233
 
 
 
 
 
 
360
  msgid "Your Business Name"
361
  msgstr ""
362
 
363
- #: includes/class-builder-fields.php:236 includes/class-settings.php:311
364
  msgid "Opt-in Affirmation"
365
  msgstr ""
366
 
367
- #: includes/class-builder-fields.php:239
368
  #, php-format
369
  msgid ""
370
  "Example: Yes, I would like to receive emails from %s. (You can unsubscribe "
371
  "anytime)"
372
  msgstr ""
373
 
374
- #: includes/class-builder-fields.php:256
375
  msgid "Form Fields"
376
  msgstr ""
377
 
378
- #: includes/class-builder-fields.php:265
379
  msgid "Add Fields"
380
  msgstr ""
381
 
382
- #: includes/class-builder-fields.php:272
383
  msgid ""
384
  "Create a field for each piece of information you want to collect. Good "
385
  "basics include email address, first name, and last name."
386
  msgstr ""
387
 
388
- #: includes/class-builder-fields.php:283
389
  msgid "Field {#}"
390
  msgstr ""
391
 
392
- #: includes/class-builder-fields.php:284
393
  msgid "Add Another Field"
394
  msgstr ""
395
 
396
- #: includes/class-builder-fields.php:285
397
  msgid "Remove Field"
398
  msgstr ""
399
 
400
- #: includes/class-builder-fields.php:296
401
  msgid "A brief description of this field (optional)"
402
  msgstr ""
403
 
404
- #: includes/class-builder-fields.php:301
405
  msgid "Email (required)"
406
  msgstr ""
407
 
408
- #: includes/class-builder-fields.php:302
409
  msgid "c.contact@example.com"
410
  msgstr ""
411
 
412
- #: includes/class-builder-fields.php:305
413
  msgid "First Name"
414
  msgstr ""
415
 
416
- #: includes/class-builder-fields.php:306
417
  msgid "John"
418
  msgstr ""
419
 
420
- #: includes/class-builder-fields.php:309
421
  msgid "Last Name"
422
  msgstr ""
423
 
424
- #: includes/class-builder-fields.php:310
425
  msgid "Smith"
426
  msgstr ""
427
 
428
- #: includes/class-builder-fields.php:313
429
  msgid "Phone Number"
430
  msgstr ""
431
 
432
- #: includes/class-builder-fields.php:314
433
  msgid "(555) 272-3342"
434
  msgstr ""
435
 
436
- #: includes/class-builder-fields.php:317
437
  msgid "Address"
438
  msgstr ""
439
 
440
- #: includes/class-builder-fields.php:318
441
  msgid "4115 S. Main Rd."
442
  msgstr ""
443
 
444
- #: includes/class-builder-fields.php:321
445
  msgid "Job Title"
446
  msgstr ""
447
 
448
- #: includes/class-builder-fields.php:322
449
  msgid "Project Manager"
450
  msgstr ""
451
 
452
- #: includes/class-builder-fields.php:325
453
  msgid "Company"
454
  msgstr ""
455
 
456
- #: includes/class-builder-fields.php:326
457
  msgid "Acme Manufacturing"
458
  msgstr ""
459
 
460
- #: includes/class-builder-fields.php:329
461
  msgid "Website"
462
  msgstr ""
463
 
464
- #: includes/class-builder-fields.php:330
465
  msgid "http://www.example.com"
466
  msgstr ""
467
 
468
- #: includes/class-builder-fields.php:346
469
  msgid "Custom Text Field"
470
  msgstr ""
471
 
472
- #: includes/class-builder-fields.php:347
473
  msgid "A custom text field"
474
  msgstr ""
475
 
476
- #: includes/class-builder-fields.php:350
477
  msgid "Custom Text Area"
478
  msgstr ""
479
 
480
- #: includes/class-builder-fields.php:351
481
  msgid "A large custom text field"
482
  msgstr ""
483
 
484
- #: includes/class-builder-fields.php:386
485
  msgid "Select a Field"
486
  msgstr ""
487
 
488
- #: includes/class-builder-fields.php:397
489
  msgid "Field Label"
490
  msgstr ""
491
 
492
- #: includes/class-builder-fields.php:400
493
  msgid "Email"
494
  msgstr ""
495
 
496
- #: includes/class-builder-fields.php:405
497
  msgid "Field Description"
498
  msgstr ""
499
 
500
- #: includes/class-builder-fields.php:409
501
  msgid "Ex: Enter email address"
502
  msgstr ""
503
 
504
- #: includes/class-builder-fields.php:415
505
  msgid "Required"
506
  msgstr ""
507
 
508
- #: includes/class-builder-fields.php:442
509
  msgid ""
510
  "Shortcode to embed - <em><small>You can copy and paste this in a post to "
511
  "display your form.</small></em>"
@@ -709,7 +715,7 @@ msgstr ""
709
  msgid "New Form"
710
  msgstr ""
711
 
712
- #: includes/class-cpts.php:78 includes/class-display.php:540
713
  msgid "Edit Form"
714
  msgstr ""
715
 
@@ -940,103 +946,103 @@ msgstr ""
940
  msgid "%s (last modified %s ago)"
941
  msgstr ""
942
 
943
- #: includes/class-display.php:302
944
  msgid "Constant Contact Use."
945
  msgstr ""
946
 
947
- #: includes/class-display.php:365 includes/class-display.php:1168
948
  msgid "Error: Please correct your entry."
949
  msgstr ""
950
 
951
- #: includes/class-display.php:367
952
  msgid " Error: Please fill out this field."
953
  msgstr ""
954
 
955
- #: includes/class-display.php:768
956
  msgid "Send"
957
  msgstr ""
958
 
959
- #: includes/class-display.php:881
960
  msgid "Street Address"
961
  msgstr ""
962
 
963
- #: includes/class-display.php:882
964
  msgid "Address Line 2"
965
  msgstr ""
966
 
967
- #: includes/class-display.php:883
968
  msgid "City"
969
  msgstr ""
970
 
971
- #: includes/class-display.php:884
972
  msgid "State"
973
  msgstr ""
974
 
975
- #: includes/class-display.php:885
976
  msgid "ZIP Code"
977
  msgstr ""
978
 
979
- #: includes/class-display.php:941
980
  msgid "Month"
981
  msgstr ""
982
 
983
- #: includes/class-display.php:942
984
  msgid "Day"
985
  msgstr ""
986
 
987
- #: includes/class-display.php:943
988
  msgid "Year"
989
  msgstr ""
990
 
991
- #: includes/class-display.php:1064
992
  msgid "January"
993
  msgstr ""
994
 
995
- #: includes/class-display.php:1065
996
  msgid "February"
997
  msgstr ""
998
 
999
- #: includes/class-display.php:1066
1000
  msgid "March"
1001
  msgstr ""
1002
 
1003
- #: includes/class-display.php:1067
1004
  msgid "April"
1005
  msgstr ""
1006
 
1007
- #: includes/class-display.php:1068
1008
  msgid "May"
1009
  msgstr ""
1010
 
1011
- #: includes/class-display.php:1069
1012
  msgid "June"
1013
  msgstr ""
1014
 
1015
- #: includes/class-display.php:1070
1016
  msgid "July "
1017
  msgstr ""
1018
 
1019
- #: includes/class-display.php:1071
1020
  msgid "August"
1021
  msgstr ""
1022
 
1023
- #: includes/class-display.php:1072
1024
  msgid "September"
1025
  msgstr ""
1026
 
1027
- #: includes/class-display.php:1073
1028
  msgid "October"
1029
  msgstr ""
1030
 
1031
- #: includes/class-display.php:1074
1032
  msgid "November"
1033
  msgstr ""
1034
 
1035
- #: includes/class-display.php:1075
1036
  msgid "December"
1037
  msgstr ""
1038
 
1039
- #: includes/class-display.php:1232
1040
  #, php-format
1041
  msgid ""
1042
  "By submitting this form, you are granting: %s, permission to email you. You "
@@ -1113,7 +1119,7 @@ msgstr ""
1113
 
1114
  #: includes/class-notification-content.php:105
1115
  #: includes/class-notification-content.php:128 includes/class-optin.php:117
1116
- #: includes/class-settings.php:736
1117
  msgid "Constant Contact logo"
1118
  msgstr ""
1119
 
@@ -1136,36 +1142,44 @@ msgid ""
1136
  "our plugin and lets you provide us useful feedback."
1137
  msgstr ""
1138
 
 
 
 
 
 
 
 
 
1139
  #: includes/class-notifications.php:404
1140
  msgid "Dismiss this notice."
1141
  msgstr ""
1142
 
1143
- #: includes/class-optin.php:125 includes/class-settings.php:744
1144
  msgid "Agree"
1145
  msgstr ""
1146
 
1147
- #: includes/class-optin.php:126 includes/class-settings.php:745
1148
  msgid "Disagree"
1149
  msgstr ""
1150
 
1151
- #: includes/class-process-form.php:154 includes/class-process-form.php:574
1152
  msgid ""
1153
  "We had trouble processing your submission. Please review your entries and "
1154
  "try again."
1155
  msgstr ""
1156
 
1157
- #: includes/class-process-form.php:163 includes/class-process-form.php:172
1158
- #: includes/class-process-form.php:181
1159
  msgid ""
1160
  "We had trouble processing your submission. Make sure you haven't changed the "
1161
  "required Form ID and try again."
1162
  msgstr ""
1163
 
1164
- #: includes/class-process-form.php:543
1165
  msgid "There was an error sending your form."
1166
  msgstr ""
1167
 
1168
- #: includes/class-process-form.php:557
1169
  msgid "Your information has been submitted."
1170
  msgstr ""
1171
 
@@ -1229,19 +1243,37 @@ msgstr ""
1229
  msgid "Disclosure Address"
1230
  msgstr ""
1231
 
1232
- #: includes/class-settings.php:349
1233
- msgid "Add a checkbox to the comment field in your posts"
 
 
 
 
 
 
 
 
 
 
1234
  msgstr ""
1235
 
1236
  #: includes/class-settings.php:350
 
 
 
 
 
 
 
 
1237
  msgid "Add a checkbox to the main WordPress login page"
1238
  msgstr ""
1239
 
1240
- #: includes/class-settings.php:355
1241
  msgid "Add a checkbox to the WordPress user registration page"
1242
  msgstr ""
1243
 
1244
- #: includes/class-settings.php:444
1245
  msgid "Sign up to our newsletter."
1246
  msgstr ""
1247
 
3
  msgstr ""
4
  "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
5
  "Project-Id-Version: Constant Contact Forms for WordPress\n"
6
+ "POT-Creation-Date: 2017-03-30 16:49-0500\n"
7
  "PO-Revision-Date: 2017-01-12 14:46-0600\n"
8
  "Last-Translator: Michael Beckwith <michael.d.beckwith@gmail.com>\n"
9
  "Language-Team: Constant Contact\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
+ "X-Generator: Poedit 2.0\n"
14
  "X-Poedit-Basepath: ..\n"
15
  "X-Poedit-WPHeader: constant-contact-forms.php\n"
16
  "X-Poedit-SourceCharset: UTF-8\n"
35
  "website administrator should be able to assist in updating your PHP version."
36
  msgstr ""
37
 
38
+ #: constant-contact-forms.php:554
39
  msgid "Error loading license."
40
  msgstr ""
41
 
266
  msgid "License"
267
  msgstr ""
268
 
269
+ #: includes/class-admin.php:204 includes/class-settings.php:671
270
  msgid "Settings updated."
271
  msgstr ""
272
 
274
  msgid "Description"
275
  msgstr ""
276
 
277
+ #: includes/class-admin.php:243 includes/class-builder-fields.php:432
278
  msgid "Shortcode"
279
  msgstr ""
280
 
302
  msgid "Contact type not returned"
303
  msgstr ""
304
 
305
+ #: includes/class-api.php:684
306
  msgid ""
307
  "Your API access token is invalid. Reconnect to Constant Contact to receive a "
308
  "new token."
356
  msgid "Show Opt-in checkbox"
357
  msgstr ""
358
 
359
+ #: includes/class-builder-fields.php:220
360
+ msgid ""
361
+ "Important: opt-in settings required for sending user submissions to "
362
+ "ConstantContact.com"
363
+ msgstr ""
364
+
365
+ #: includes/class-builder-fields.php:234
366
  msgid "Your Business Name"
367
  msgstr ""
368
 
369
+ #: includes/class-builder-fields.php:237 includes/class-settings.php:311
370
  msgid "Opt-in Affirmation"
371
  msgstr ""
372
 
373
+ #: includes/class-builder-fields.php:240
374
  #, php-format
375
  msgid ""
376
  "Example: Yes, I would like to receive emails from %s. (You can unsubscribe "
377
  "anytime)"
378
  msgstr ""
379
 
380
+ #: includes/class-builder-fields.php:257
381
  msgid "Form Fields"
382
  msgstr ""
383
 
384
+ #: includes/class-builder-fields.php:266
385
  msgid "Add Fields"
386
  msgstr ""
387
 
388
+ #: includes/class-builder-fields.php:273
389
  msgid ""
390
  "Create a field for each piece of information you want to collect. Good "
391
  "basics include email address, first name, and last name."
392
  msgstr ""
393
 
394
+ #: includes/class-builder-fields.php:284
395
  msgid "Field {#}"
396
  msgstr ""
397
 
398
+ #: includes/class-builder-fields.php:285
399
  msgid "Add Another Field"
400
  msgstr ""
401
 
402
+ #: includes/class-builder-fields.php:286
403
  msgid "Remove Field"
404
  msgstr ""
405
 
406
+ #: includes/class-builder-fields.php:297
407
  msgid "A brief description of this field (optional)"
408
  msgstr ""
409
 
410
+ #: includes/class-builder-fields.php:302
411
  msgid "Email (required)"
412
  msgstr ""
413
 
414
+ #: includes/class-builder-fields.php:303
415
  msgid "c.contact@example.com"
416
  msgstr ""
417
 
418
+ #: includes/class-builder-fields.php:306
419
  msgid "First Name"
420
  msgstr ""
421
 
422
+ #: includes/class-builder-fields.php:307
423
  msgid "John"
424
  msgstr ""
425
 
426
+ #: includes/class-builder-fields.php:310
427
  msgid "Last Name"
428
  msgstr ""
429
 
430
+ #: includes/class-builder-fields.php:311
431
  msgid "Smith"
432
  msgstr ""
433
 
434
+ #: includes/class-builder-fields.php:314
435
  msgid "Phone Number"
436
  msgstr ""
437
 
438
+ #: includes/class-builder-fields.php:315
439
  msgid "(555) 272-3342"
440
  msgstr ""
441
 
442
+ #: includes/class-builder-fields.php:318
443
  msgid "Address"
444
  msgstr ""
445
 
446
+ #: includes/class-builder-fields.php:319
447
  msgid "4115 S. Main Rd."
448
  msgstr ""
449
 
450
+ #: includes/class-builder-fields.php:322
451
  msgid "Job Title"
452
  msgstr ""
453
 
454
+ #: includes/class-builder-fields.php:323
455
  msgid "Project Manager"
456
  msgstr ""
457
 
458
+ #: includes/class-builder-fields.php:326
459
  msgid "Company"
460
  msgstr ""
461
 
462
+ #: includes/class-builder-fields.php:327
463
  msgid "Acme Manufacturing"
464
  msgstr ""
465
 
466
+ #: includes/class-builder-fields.php:330
467
  msgid "Website"
468
  msgstr ""
469
 
470
+ #: includes/class-builder-fields.php:331
471
  msgid "http://www.example.com"
472
  msgstr ""
473
 
474
+ #: includes/class-builder-fields.php:347
475
  msgid "Custom Text Field"
476
  msgstr ""
477
 
478
+ #: includes/class-builder-fields.php:348
479
  msgid "A custom text field"
480
  msgstr ""
481
 
482
+ #: includes/class-builder-fields.php:351
483
  msgid "Custom Text Area"
484
  msgstr ""
485
 
486
+ #: includes/class-builder-fields.php:352
487
  msgid "A large custom text field"
488
  msgstr ""
489
 
490
+ #: includes/class-builder-fields.php:387
491
  msgid "Select a Field"
492
  msgstr ""
493
 
494
+ #: includes/class-builder-fields.php:398
495
  msgid "Field Label"
496
  msgstr ""
497
 
498
+ #: includes/class-builder-fields.php:401
499
  msgid "Email"
500
  msgstr ""
501
 
502
+ #: includes/class-builder-fields.php:406
503
  msgid "Field Description"
504
  msgstr ""
505
 
506
+ #: includes/class-builder-fields.php:410
507
  msgid "Ex: Enter email address"
508
  msgstr ""
509
 
510
+ #: includes/class-builder-fields.php:416
511
  msgid "Required"
512
  msgstr ""
513
 
514
+ #: includes/class-builder-fields.php:443
515
  msgid ""
516
  "Shortcode to embed - <em><small>You can copy and paste this in a post to "
517
  "display your form.</small></em>"
715
  msgid "New Form"
716
  msgstr ""
717
 
718
+ #: includes/class-cpts.php:78 includes/class-display.php:577
719
  msgid "Edit Form"
720
  msgstr ""
721
 
946
  msgid "%s (last modified %s ago)"
947
  msgstr ""
948
 
949
+ #: includes/class-display.php:313
950
  msgid "Constant Contact Use."
951
  msgstr ""
952
 
953
+ #: includes/class-display.php:402 includes/class-display.php:1205
954
  msgid "Error: Please correct your entry."
955
  msgstr ""
956
 
957
+ #: includes/class-display.php:404
958
  msgid " Error: Please fill out this field."
959
  msgstr ""
960
 
961
+ #: includes/class-display.php:805
962
  msgid "Send"
963
  msgstr ""
964
 
965
+ #: includes/class-display.php:918
966
  msgid "Street Address"
967
  msgstr ""
968
 
969
+ #: includes/class-display.php:919
970
  msgid "Address Line 2"
971
  msgstr ""
972
 
973
+ #: includes/class-display.php:920
974
  msgid "City"
975
  msgstr ""
976
 
977
+ #: includes/class-display.php:921
978
  msgid "State"
979
  msgstr ""
980
 
981
+ #: includes/class-display.php:922
982
  msgid "ZIP Code"
983
  msgstr ""
984
 
985
+ #: includes/class-display.php:978
986
  msgid "Month"
987
  msgstr ""
988
 
989
+ #: includes/class-display.php:979
990
  msgid "Day"
991
  msgstr ""
992
 
993
+ #: includes/class-display.php:980
994
  msgid "Year"
995
  msgstr ""
996
 
997
+ #: includes/class-display.php:1101
998
  msgid "January"
999
  msgstr ""
1000
 
1001
+ #: includes/class-display.php:1102
1002
  msgid "February"
1003
  msgstr ""
1004
 
1005
+ #: includes/class-display.php:1103
1006
  msgid "March"
1007
  msgstr ""
1008
 
1009
+ #: includes/class-display.php:1104
1010
  msgid "April"
1011
  msgstr ""
1012
 
1013
+ #: includes/class-display.php:1105
1014
  msgid "May"
1015
  msgstr ""
1016
 
1017
+ #: includes/class-display.php:1106
1018
  msgid "June"
1019
  msgstr ""
1020
 
1021
+ #: includes/class-display.php:1107
1022
  msgid "July "
1023
  msgstr ""
1024
 
1025
+ #: includes/class-display.php:1108
1026
  msgid "August"
1027
  msgstr ""
1028
 
1029
+ #: includes/class-display.php:1109
1030
  msgid "September"
1031
  msgstr ""
1032
 
1033
+ #: includes/class-display.php:1110
1034
  msgid "October"
1035
  msgstr ""
1036
 
1037
+ #: includes/class-display.php:1111
1038
  msgid "November"
1039
  msgstr ""
1040
 
1041
+ #: includes/class-display.php:1112
1042
  msgid "December"
1043
  msgstr ""
1044
 
1045
+ #: includes/class-display.php:1269
1046
  #, php-format
1047
  msgid ""
1048
  "By submitting this form, you are granting: %s, permission to email you. You "
1119
 
1120
  #: includes/class-notification-content.php:105
1121
  #: includes/class-notification-content.php:128 includes/class-optin.php:117
1122
+ #: includes/class-settings.php:754
1123
  msgid "Constant Contact logo"
1124
  msgstr ""
1125
 
1142
  "our plugin and lets you provide us useful feedback."
1143
  msgstr ""
1144
 
1145
+ #: includes/class-notification-content.php:171
1146
+ #, php-format
1147
+ msgid ""
1148
+ "Protect yourself from Spam &amp; Bots: New <strong>v1.2.4 Constant Contact "
1149
+ "Forms for WordPress</strong> now supports Google reCAPTCHA. Learn more and "
1150
+ "implement via <a href=\"%s\">Settings</a>"
1151
+ msgstr ""
1152
+
1153
  #: includes/class-notifications.php:404
1154
  msgid "Dismiss this notice."
1155
  msgstr ""
1156
 
1157
+ #: includes/class-optin.php:125 includes/class-settings.php:762
1158
  msgid "Agree"
1159
  msgstr ""
1160
 
1161
+ #: includes/class-optin.php:126 includes/class-settings.php:763
1162
  msgid "Disagree"
1163
  msgstr ""
1164
 
1165
+ #: includes/class-process-form.php:165 includes/class-process-form.php:585
1166
  msgid ""
1167
  "We had trouble processing your submission. Please review your entries and "
1168
  "try again."
1169
  msgstr ""
1170
 
1171
+ #: includes/class-process-form.php:174 includes/class-process-form.php:183
1172
+ #: includes/class-process-form.php:192
1173
  msgid ""
1174
  "We had trouble processing your submission. Make sure you haven't changed the "
1175
  "required Form ID and try again."
1176
  msgstr ""
1177
 
1178
+ #: includes/class-process-form.php:554
1179
  msgid "There was an error sending your form."
1180
  msgstr ""
1181
 
1182
+ #: includes/class-process-form.php:568
1183
  msgid "Your information has been submitted."
1184
  msgstr ""
1185
 
1243
  msgid "Disclosure Address"
1244
  msgstr ""
1245
 
1246
+ #: includes/class-settings.php:339
1247
+ msgid "Google reCAPTCHA"
1248
+ msgstr ""
1249
+
1250
+ #: includes/class-settings.php:340
1251
+ msgid ""
1252
+ "Learn more and get an <a href=\"https://www.google.com/recaptcha/intro/\" "
1253
+ "target=\"_blank\">API site key</a>"
1254
+ msgstr ""
1255
+
1256
+ #: includes/class-settings.php:343
1257
+ msgid "Site Key"
1258
  msgstr ""
1259
 
1260
  #: includes/class-settings.php:350
1261
+ msgid "Secret Key"
1262
+ msgstr ""
1263
+
1264
+ #: includes/class-settings.php:367
1265
+ msgid "Add a checkbox to the comment field in your posts"
1266
+ msgstr ""
1267
+
1268
+ #: includes/class-settings.php:368
1269
  msgid "Add a checkbox to the main WordPress login page"
1270
  msgstr ""
1271
 
1272
+ #: includes/class-settings.php:373
1273
  msgid "Add a checkbox to the WordPress user registration page"
1274
  msgstr ""
1275
 
1276
+ #: includes/class-settings.php:462
1277
  msgid "Sign up to our newsletter."
1278
  msgstr ""
1279
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: constantcontact
3
  Tags: capture, contacts, constant contact, constant contact form, constant contact newsletter, constant contact official, contact forms, email, form, forms, marketing, mobile, newsletter, opt-in, plugin, signup, subscribe, subscription, widget
4
  Requires at least: 4.0.0
5
  Tested up to: 4.7.2
6
- Stable tag: 1.2.3
7
  License: GPLv2
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -33,6 +33,12 @@ BONUS: If you have a Constant Contact account, all new email addresses that you
33
 
34
  == Changelog ==
35
 
 
 
 
 
 
 
36
  = 1.2.3 =
37
  * Fixed: Attempt to process forms that have provided a custom url via filter.
38
  * Fixed: Clean up class attributes regarding validation errors in text inputs.
3
  Tags: capture, contacts, constant contact, constant contact form, constant contact newsletter, constant contact official, contact forms, email, form, forms, marketing, mobile, newsletter, opt-in, plugin, signup, subscribe, subscription, widget
4
  Requires at least: 4.0.0
5
  Tested up to: 4.7.2
6
+ Stable tag: 1.2.4
7
  License: GPLv2
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
33
 
34
  == Changelog ==
35
 
36
+ = 1.2.4 =
37
+ * Added: Google reCAPTCHA "I am human" checkbox support for forms. See https://www.google.com/recaptcha/intro/. Will fall back to honeypot prevention if not set up.
38
+ * Fixed: Stray quote mark in honeypot markup.
39
+ * Fixed: missing space after placeholder attribute for inputs.
40
+ * Fixed: Removed unintentional "Leave page" confirmation popup when saving settings.
41
+
42
  = 1.2.3 =
43
  * Fixed: Attempt to process forms that have provided a custom url via filter.
44
  * Fixed: Clean up class attributes regarding validation errors in text inputs.
vendor/recaptcha/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /composer.lock
2
+ /nbproject/private/
3
+ /vendor/
vendor/recaptcha/.travis.yml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ language: php
2
+
3
+ sudo: false
4
+
5
+ php:
6
+ - 5.3
7
+ - 5.4
8
+ - 5.5
9
+ - 5.6
10
+ - hhvm
11
+
12
+ before_script:
13
+ - composer install
14
+ - phpenv version-name | grep ^5.[34] && echo "extension=apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini ; true
15
+ - phpenv version-name | grep ^5.[34] && echo "apc.enable_cli=1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini ; true
16
+
17
+ script:
18
+ - vendor/bin/phpunit
vendor/recaptcha/CONTRIBUTING.md ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Want to contribute? Great! First, read this page (including the small print at the end).
2
+
3
+ ### Before you contribute
4
+ Before we can use your code, you must sign the
5
+ [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1)
6
+ (CLA), which you can do online. The CLA is necessary mainly because you own the
7
+ copyright to your changes, even after your contribution becomes part of our
8
+ codebase, so we need your permission to use and distribute your code. We also
9
+ need to be sure of various other things—for instance that you'll tell us if you
10
+ know that your code infringes on other people's patents. You don't have to sign
11
+ the CLA until after you've submitted your code for review and a member has
12
+ approved it, but you must do it before we can put your code into our codebase.
13
+ Before you start working on a larger contribution, you should get in touch with
14
+ us first through the issue tracker with your idea so that we can help out and
15
+ possibly guide you. Coordinating up front makes it much easier to avoid
16
+ frustration later on.
17
+
18
+ ### Code reviews
19
+ All submissions, including submissions by project members, require review. We
20
+ use GitHub pull requests for this purpose.
21
+
22
+ ### The small print
23
+ Contributions made by corporations are covered by a different agreement than
24
+ the one above, the Software Grant and Corporate Contributor License Agreement.
vendor/recaptcha/LICENSE ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright 2014, Google Inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are
6
+ met:
7
+
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+ * Redistributions in binary form must reproduce the above
11
+ copyright notice, this list of conditions and the following disclaimer
12
+ in the documentation and/or other materials provided with the
13
+ distribution.
14
+ * Neither the name of Google Inc. nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
vendor/recaptcha/README.md ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # reCAPTCHA PHP client library
2
+
3
+ [![Build Status](https://travis-ci.org/google/recaptcha.svg)](https://travis-ci.org/google/recaptcha)
4
+ [![Latest Stable Version](https://poser.pugx.org/google/recaptcha/v/stable.svg)](https://packagist.org/packages/google/recaptcha)
5
+ [![Total Downloads](https://poser.pugx.org/google/recaptcha/downloads.svg)](https://packagist.org/packages/google/recaptcha)
6
+
7
+ * Project page: http://www.google.com/recaptcha/
8
+ * Repository: https://github.com/google/recaptcha
9
+ * Version: 1.1.2
10
+ * License: BSD, see [LICENSE](LICENSE)
11
+
12
+ ## Description
13
+
14
+ reCAPTCHA is a free CAPTCHA service that protect websites from spam and abuse.
15
+ This is Google authored code that provides plugins for third-party integration
16
+ with reCAPTCHA.
17
+
18
+ ## Installation
19
+
20
+ ### Composer (Recommended)
21
+
22
+ [Composer](https://getcomposer.org/) is a widely used dependency manager for PHP
23
+ packages. This reCAPTCHA client is available on Packagist as
24
+ [`google/recaptcha`](https://packagist.org/packages/google/recaptcha) and can be
25
+ installed either by running the `composer require` command or adding the library
26
+ to your `composer.json`. To enable Composer for you project, refer to the
27
+ project's [Getting Started](https://getcomposer.org/doc/00-intro.md)
28
+ documentation.
29
+
30
+ To add this dependency using the command, run the following from within your
31
+ project directory:
32
+ ```
33
+ composer require google/recaptcha "~1.1"
34
+ ```
35
+
36
+ Alternatively, add the dependency directly to your `composer.json` file:
37
+ ```json
38
+ "require": {
39
+ "google/recaptcha": "~1.1"
40
+ }
41
+ ```
42
+
43
+ ### Direct download (no Composer)
44
+
45
+ If you wish to install the library manually (i.e. without Composer), then you
46
+ can use the links on the main project page to either clone the repo or download
47
+ the [ZIP file](https://github.com/google/recaptcha/archive/master.zip). For
48
+ convenience, an autoloader script is provided in `src/autoload.php` which you
49
+ can require into your script instead of Composer's `vendor/autoload.php`. For
50
+ example:
51
+
52
+ ```php
53
+ require('/path/to/recaptcha/src/autoload.php');
54
+ $recaptcha = new \ReCaptcha\ReCaptcha($secret);
55
+ ```
56
+
57
+ The classes in the project are structured according to the
58
+ [PSR-4](http://www.php-fig.org/psr/psr-4/) standard, so you may of course also
59
+ use your own autoloader or require the needed files directly in your code.
60
+
61
+ ### Development install
62
+
63
+ If you would like to contribute to this project or run the unit tests on within
64
+ your own environment you will need to install the development dependencies, in
65
+ this case that means [PHPUnit](https://phpunit.de/). If you clone the repo and
66
+ run `composer install` from within the repo, this will also grab PHPUnit and all
67
+ its dependencies for you. If you only need the autoloader installed, then you
68
+ can always specify to Composer not to run in development mode, e.g. `composer
69
+ install --no-dev`.
70
+
71
+ *Note:* These dependencies are only required for development, there's no
72
+ requirement for them to be included in your production code.
73
+
74
+ ## Usage
75
+
76
+ First, register keys for your site at https://www.google.com/recaptcha/admin
77
+
78
+ When your app receives a form submission containing the `g-recaptcha-response`
79
+ field, you can verify it using:
80
+ ```php
81
+ <?php
82
+ $recaptcha = new \ReCaptcha\ReCaptcha($secret);
83
+ $resp = $recaptcha->verify($gRecaptchaResponse, $remoteIp);
84
+ if ($resp->isSuccess()) {
85
+ // verified!
86
+ } else {
87
+ $errors = $resp->getErrorCodes();
88
+ }
89
+ ```
90
+
91
+ You can see an end-to-end working example in
92
+ [examples/example-captcha.php](examples/example-captcha.php)
93
+
94
+ ## Upgrading
95
+
96
+ ### From 1.0.0
97
+
98
+ The previous version of this client is still available on the `1.0.0` tag [in
99
+ this repo](https://github.com/google/recaptcha/tree/1.0.0) but it is purely for
100
+ reference and will not receive any updates.
101
+
102
+ The major changes in 1.1.0 are:
103
+ * installation now via Composer;
104
+ * class loading also via Composer;
105
+ * classes now namespaced;
106
+ * old method call was `$rc->verifyResponse($remoteIp, $response)`, new call is
107
+ `$rc->verify($response, $remoteIp)`
108
+
109
+ ## Contributing
110
+
111
+ We accept contributions via GitHub Pull Requests, but all contributors need to
112
+ be covered by the standard Google Contributor License Agreement. You can find
113
+ instructions for this in [CONTRIBUTING](CONTRIBUTING.md)
vendor/recaptcha/composer.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "google/recaptcha",
3
+ "description": "Client library for reCAPTCHA, a free service that protect websites from spam and abuse.",
4
+ "type": "library",
5
+ "keywords": ["recaptcha", "captcha", "spam", "abuse"],
6
+ "homepage": "http://www.google.com/recaptcha/",
7
+ "license": "BSD-3-Clause",
8
+ "support": {
9
+ "forum": "https://groups.google.com/forum/#!forum/recaptcha",
10
+ "source": "https://github.com/google/recaptcha"
11
+ },
12
+ "require": {
13
+ "php": ">=5.3.2"
14
+ },
15
+ "require-dev": {
16
+ "phpunit/phpunit": "4.5.*"
17
+ },
18
+ "autoload": {
19
+ "psr-4": {
20
+ "ReCaptcha\\": "src/ReCaptcha"
21
+ }
22
+ },
23
+ "extra": {
24
+ "branch-alias": {
25
+ "dev-master": "1.1.x-dev"
26
+ }
27
+ }
28
+ }
vendor/recaptcha/examples/example-captcha.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Working sample code to accompany the library. The instructions here assume
4
+ * you've just cloned the repo. If you've installed via composer, you will want
5
+ * to adjust the path to the autoloader.
6
+ *
7
+ * 1. Run the server. For example, under Linux you can probably use:
8
+ * /usr/bin/php -S "localhost:8000" "examples/example-captcha.php"
9
+ * 2. Point your browser at http://localhost:8000
10
+ * 3. Follow the instructions
11
+ *
12
+ * @copyright Copyright (c) 2015, Google Inc.
13
+ * @link http://www.google.com/recaptcha
14
+ *
15
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ * of this software and associated documentation files (the "Software"), to deal
17
+ * in the Software without restriction, including without limitation the rights
18
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ * copies of the Software, and to permit persons to whom the Software is
20
+ * furnished to do so, subject to the following conditions:
21
+ *
22
+ * The above copyright notice and this permission notice shall be included in
23
+ * all copies or substantial portions of the Software.
24
+ *
25
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31
+ * THE SOFTWARE.
32
+ */
33
+ // Initiate the autoloader. The file should be generated by Composer.
34
+ // You will provide your own autoloader or require the files directly if you did
35
+ // not install via Composer.
36
+ require_once __DIR__ . '/../vendor/autoload.php';
37
+
38
+ // Register API keys at https://www.google.com/recaptcha/admin
39
+ $siteKey = '';
40
+ $secret = '';
41
+
42
+ // reCAPTCHA supported 40+ languages listed here: https://developers.google.com/recaptcha/docs/language
43
+ $lang = 'en';
44
+ ?>
45
+ <html>
46
+ <head>
47
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
48
+ <title>reCAPTCHA Example</title>
49
+ <link rel="shortcut icon" href="//www.gstatic.com/recaptcha/admin/favicon.ico" type="image/x-icon"/>
50
+ <style type="text/css">
51
+ body {
52
+ margin: 1em 5em 0 5em;
53
+ font-family: sans-serif;
54
+ }
55
+ fieldset {
56
+ display: inline;
57
+ padding: 1em;
58
+ }
59
+ </style>
60
+ </head>
61
+ <body>
62
+ <h1>reCAPTCHA Example</h1>
63
+ <?php if ($siteKey === '' || $secret === ''): ?>
64
+ <h2>Add your keys</h2>
65
+ <p>If you do not have keys already then visit <tt>
66
+ <a href = "https://www.google.com/recaptcha/admin">
67
+ https://www.google.com/recaptcha/admin</a></tt> to generate them.
68
+ Edit this file and set the respective keys in <tt>$siteKey</tt> and
69
+ <tt>$secret</tt>. Reload the page after this.</p>
70
+ <?php
71
+ elseif (isset($_POST['g-recaptcha-response'])):
72
+ // The POST data here is unfiltered because this is an example.
73
+ // In production, *always* sanitise and validate your input'
74
+ ?>
75
+ <h2><tt>POST</tt> data</h2>
76
+ <tt><pre><?php var_export($_POST); ?></pre></tt>
77
+ <?php
78
+ // If the form submission includes the "g-captcha-response" field
79
+ // Create an instance of the service using your secret
80
+ $recaptcha = new \ReCaptcha\ReCaptcha($secret);
81
+
82
+ // If file_get_contents() is locked down on your PHP installation to disallow
83
+ // its use with URLs, then you can use the alternative request method instead.
84
+ // This makes use of fsockopen() instead.
85
+ // $recaptcha = new \ReCaptcha\ReCaptcha($secret, new \ReCaptcha\RequestMethod\SocketPost());
86
+
87
+ // Make the call to verify the response and also pass the user's IP address
88
+ $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);
89
+
90
+ if ($resp->isSuccess()):
91
+ // If the response is a success, that's it!
92
+ ?>
93
+ <h2>Success!</h2>
94
+ <p>That's it. Everything is working. Go integrate this into your real project.</p>
95
+ <p><a href="/">Try again</a></p>
96
+ <?php
97
+ else:
98
+ // If it's not successful, then one or more error codes will be returned.
99
+ ?>
100
+ <h2>Something went wrong</h2>
101
+ <p>The following error was returned: <?php
102
+ foreach ($resp->getErrorCodes() as $code) {
103
+ echo '<tt>' , $code , '</tt> ';
104
+ }
105
+ ?></p>
106
+ <p>Check the error code reference at <tt><a href="https://developers.google.com/recaptcha/docs/verify#error-code-reference">https://developers.google.com/recaptcha/docs/verify#error-code-reference</a></tt>.
107
+ <p><strong>Note:</strong> Error code <tt>missing-input-response</tt> may mean the user just didn't complete the reCAPTCHA.</p>
108
+ <p><a href="/">Try again</a></p>
109
+ <?php
110
+ endif;
111
+ else:
112
+ // Add the g-recaptcha tag to the form you want to include the reCAPTCHA element
113
+ ?>
114
+ <p>Complete the reCAPTCHA then submit the form.</p>
115
+ <form action="/" method="post">
116
+ <fieldset>
117
+ <legend>An example form</legend>
118
+ <p>Example input A: <input type="text" name="ex-a" value="foo"></p>
119
+ <p>Example input B: <input type="text" name="ex-b" value="bar"></p>
120
+
121
+ <div class="g-recaptcha" data-sitekey="<?php echo $siteKey; ?>"></div>
122
+ <script type="text/javascript"
123
+ src="https://www.google.com/recaptcha/api.js?hl=<?php echo $lang; ?>">
124
+ </script>
125
+ <p><input type="submit" value="Submit" /></p>
126
+ </fieldset>
127
+ </form>
128
+ <?php endif; ?>
129
+ </body>
130
+ </html>
vendor/recaptcha/phpunit.xml.dist ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.4/phpunit.xsd"
4
+ colors="true"
5
+ verbose="true"
6
+ bootstrap="src/autoload.php">
7
+ <testsuites>
8
+ <testsuite name="reCAPTCHA Test Suite">
9
+ <directory>tests/ReCaptcha/</directory>
10
+ </testsuite>
11
+ </testsuites>
12
+ <filter>
13
+ <whitelist>
14
+ <directory suffix=".php">src/ReCaptcha/</directory>
15
+ </whitelist>
16
+ </filter>
17
+ </phpunit>
vendor/recaptcha/src/ReCaptcha/ReCaptcha.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha;
28
+
29
+ /**
30
+ * reCAPTCHA client.
31
+ */
32
+ class ReCaptcha
33
+ {
34
+ /**
35
+ * Version of this client library.
36
+ * @const string
37
+ */
38
+ const VERSION = 'php_1.1.2';
39
+
40
+ /**
41
+ * Shared secret for the site.
42
+ * @var string
43
+ */
44
+ private $secret;
45
+
46
+ /**
47
+ * Method used to communicate with service. Defaults to POST request.
48
+ * @var RequestMethod
49
+ */
50
+ private $requestMethod;
51
+
52
+ /**
53
+ * Create a configured instance to use the reCAPTCHA service.
54
+ *
55
+ * @param string $secret shared secret between site and reCAPTCHA server.
56
+ * @param RequestMethod $requestMethod method used to send the request. Defaults to POST.
57
+ * @throws \RuntimeException if $secret is invalid
58
+ */
59
+ public function __construct($secret, RequestMethod $requestMethod = null)
60
+ {
61
+ if (empty($secret)) {
62
+ throw new \RuntimeException('No secret provided');
63
+ }
64
+
65
+ if (!is_string($secret)) {
66
+ throw new \RuntimeException('The provided secret must be a string');
67
+ }
68
+
69
+ $this->secret = $secret;
70
+
71
+ if (!is_null($requestMethod)) {
72
+ $this->requestMethod = $requestMethod;
73
+ } else {
74
+ $this->requestMethod = new RequestMethod\Post();
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Calls the reCAPTCHA siteverify API to verify whether the user passes
80
+ * CAPTCHA test.
81
+ *
82
+ * @param string $response The value of 'g-recaptcha-response' in the submitted form.
83
+ * @param string $remoteIp The end user's IP address.
84
+ * @return Response Response from the service.
85
+ */
86
+ public function verify($response, $remoteIp = null)
87
+ {
88
+ // Discard empty solution submissions
89
+ if (empty($response)) {
90
+ $recaptchaResponse = new Response(false, array('missing-input-response'));
91
+ return $recaptchaResponse;
92
+ }
93
+
94
+ $params = new RequestParameters($this->secret, $response, $remoteIp, self::VERSION);
95
+ $rawResponse = $this->requestMethod->submit($params);
96
+ return Response::fromJson($rawResponse);
97
+ }
98
+ }
vendor/recaptcha/src/ReCaptcha/RequestMethod.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha;
28
+
29
+ /**
30
+ * Method used to send the request to the service.
31
+ */
32
+ interface RequestMethod
33
+ {
34
+
35
+ /**
36
+ * Submit the request with the specified parameters.
37
+ *
38
+ * @param RequestParameters $params Request parameters
39
+ * @return string Body of the reCAPTCHA response
40
+ */
41
+ public function submit(RequestParameters $params);
42
+ }
vendor/recaptcha/src/ReCaptcha/RequestMethod/Curl.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha\RequestMethod;
28
+
29
+ /**
30
+ * Convenience wrapper around the cURL functions to allow mocking.
31
+ */
32
+ class Curl
33
+ {
34
+
35
+ /**
36
+ * @see http://php.net/curl_init
37
+ * @param string $url
38
+ * @return resource cURL handle
39
+ */
40
+ public function init($url = null)
41
+ {
42
+ return curl_init($url);
43
+ }
44
+
45
+ /**
46
+ * @see http://php.net/curl_setopt_array
47
+ * @param resource $ch
48
+ * @param array $options
49
+ * @return bool
50
+ */
51
+ public function setoptArray($ch, array $options)
52
+ {
53
+ return curl_setopt_array($ch, $options);
54
+ }
55
+
56
+ /**
57
+ * @see http://php.net/curl_exec
58
+ * @param resource $ch
59
+ * @return mixed
60
+ */
61
+ public function exec($ch)
62
+ {
63
+ return curl_exec($ch);
64
+ }
65
+
66
+ /**
67
+ * @see http://php.net/curl_close
68
+ * @param resource $ch
69
+ */
70
+ public function close($ch)
71
+ {
72
+ curl_close($ch);
73
+ }
74
+ }
vendor/recaptcha/src/ReCaptcha/RequestMethod/CurlPost.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha\RequestMethod;
28
+
29
+ use ReCaptcha\RequestMethod;
30
+ use ReCaptcha\RequestParameters;
31
+
32
+ /**
33
+ * Sends cURL request to the reCAPTCHA service.
34
+ * Note: this requires the cURL extension to be enabled in PHP
35
+ * @see http://php.net/manual/en/book.curl.php
36
+ */
37
+ class CurlPost implements RequestMethod
38
+ {
39
+ /**
40
+ * URL to which requests are sent via cURL.
41
+ * @const string
42
+ */
43
+ const SITE_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';
44
+
45
+ /**
46
+ * Curl connection to the reCAPTCHA service
47
+ * @var Curl
48
+ */
49
+ private $curl;
50
+
51
+ public function __construct(Curl $curl = null)
52
+ {
53
+ if (!is_null($curl)) {
54
+ $this->curl = $curl;
55
+ } else {
56
+ $this->curl = new Curl();
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Submit the cURL request with the specified parameters.
62
+ *
63
+ * @param RequestParameters $params Request parameters
64
+ * @return string Body of the reCAPTCHA response
65
+ */
66
+ public function submit(RequestParameters $params)
67
+ {
68
+ $handle = $this->curl->init(self::SITE_VERIFY_URL);
69
+
70
+ $options = array(
71
+ CURLOPT_POST => true,
72
+ CURLOPT_POSTFIELDS => $params->toQueryString(),
73
+ CURLOPT_HTTPHEADER => array(
74
+ 'Content-Type: application/x-www-form-urlencoded'
75
+ ),
76
+ CURLINFO_HEADER_OUT => false,
77
+ CURLOPT_HEADER => false,
78
+ CURLOPT_RETURNTRANSFER => true,
79
+ CURLOPT_SSL_VERIFYPEER => true
80
+ );
81
+ $this->curl->setoptArray($handle, $options);
82
+
83
+ $response = $this->curl->exec($handle);
84
+ $this->curl->close($handle);
85
+
86
+ return $response;
87
+ }
88
+ }
vendor/recaptcha/src/ReCaptcha/RequestMethod/Post.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha\RequestMethod;
28
+
29
+ use ReCaptcha\RequestMethod;
30
+ use ReCaptcha\RequestParameters;
31
+
32
+ /**
33
+ * Sends POST requests to the reCAPTCHA service.
34
+ */
35
+ class Post implements RequestMethod
36
+ {
37
+ /**
38
+ * URL to which requests are POSTed.
39
+ * @const string
40
+ */
41
+ const SITE_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';
42
+
43
+ /**
44
+ * Submit the POST request with the specified parameters.
45
+ *
46
+ * @param RequestParameters $params Request parameters
47
+ * @return string Body of the reCAPTCHA response
48
+ */
49
+ public function submit(RequestParameters $params)
50
+ {
51
+ /**
52
+ * PHP 5.6.0 changed the way you specify the peer name for SSL context options.
53
+ * Using "CN_name" will still work, but it will raise deprecated errors.
54
+ */
55
+ $peer_key = version_compare(PHP_VERSION, '5.6.0', '<') ? 'CN_name' : 'peer_name';
56
+ $options = array(
57
+ 'http' => array(
58
+ 'header' => "Content-type: application/x-www-form-urlencoded\r\n",
59
+ 'method' => 'POST',
60
+ 'content' => $params->toQueryString(),
61
+ // Force the peer to validate (not needed in 5.6.0+, but still works)
62
+ 'verify_peer' => true,
63
+ // Force the peer validation to use www.google.com
64
+ $peer_key => 'www.google.com',
65
+ ),
66
+ );
67
+ $context = stream_context_create($options);
68
+ return file_get_contents(self::SITE_VERIFY_URL, false, $context);
69
+ }
70
+ }
vendor/recaptcha/src/ReCaptcha/RequestMethod/Socket.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha\RequestMethod;
28
+
29
+ /**
30
+ * Convenience wrapper around native socket and file functions to allow for
31
+ * mocking.
32
+ */
33
+ class Socket
34
+ {
35
+ private $handle = null;
36
+
37
+ /**
38
+ * fsockopen
39
+ *
40
+ * @see http://php.net/fsockopen
41
+ * @param string $hostname
42
+ * @param int $port
43
+ * @param int $errno
44
+ * @param string $errstr
45
+ * @param float $timeout
46
+ * @return resource
47
+ */
48
+ public function fsockopen($hostname, $port = -1, &$errno = 0, &$errstr = '', $timeout = null)
49
+ {
50
+ $this->handle = fsockopen($hostname, $port, $errno, $errstr, (is_null($timeout) ? ini_get("default_socket_timeout") : $timeout));
51
+
52
+ if ($this->handle != false && $errno === 0 && $errstr === '') {
53
+ return $this->handle;
54
+ }
55
+ return false;
56
+ }
57
+
58
+ /**
59
+ * fwrite
60
+ *
61
+ * @see http://php.net/fwrite
62
+ * @param string $string
63
+ * @param int $length
64
+ * @return int | bool
65
+ */
66
+ public function fwrite($string, $length = null)
67
+ {
68
+ return fwrite($this->handle, $string, (is_null($length) ? strlen($string) : $length));
69
+ }
70
+
71
+ /**
72
+ * fgets
73
+ *
74
+ * @see http://php.net/fgets
75
+ * @param int $length
76
+ * @return string
77
+ */
78
+ public function fgets($length = null)
79
+ {
80
+ return fgets($this->handle, $length);
81
+ }
82
+
83
+ /**
84
+ * feof
85
+ *
86
+ * @see http://php.net/feof
87
+ * @return bool
88
+ */
89
+ public function feof()
90
+ {
91
+ return feof($this->handle);
92
+ }
93
+
94
+ /**
95
+ * fclose
96
+ *
97
+ * @see http://php.net/fclose
98
+ * @return bool
99
+ */
100
+ public function fclose()
101
+ {
102
+ return fclose($this->handle);
103
+ }
104
+ }
vendor/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha\RequestMethod;
28
+
29
+ use ReCaptcha\RequestMethod;
30
+ use ReCaptcha\RequestParameters;
31
+
32
+ /**
33
+ * Sends a POST request to the reCAPTCHA service, but makes use of fsockopen()
34
+ * instead of get_file_contents(). This is to account for people who may be on
35
+ * servers where allow_furl_open is disabled.
36
+ */
37
+ class SocketPost implements RequestMethod
38
+ {
39
+ /**
40
+ * reCAPTCHA service host.
41
+ * @const string
42
+ */
43
+ const RECAPTCHA_HOST = 'www.google.com';
44
+
45
+ /**
46
+ * @const string reCAPTCHA service path
47
+ */
48
+ const SITE_VERIFY_PATH = '/recaptcha/api/siteverify';
49
+
50
+ /**
51
+ * @const string Bad request error
52
+ */
53
+ const BAD_REQUEST = '{"success": false, "error-codes": ["invalid-request"]}';
54
+
55
+ /**
56
+ * @const string Bad response error
57
+ */
58
+ const BAD_RESPONSE = '{"success": false, "error-codes": ["invalid-response"]}';
59
+
60
+ /**
61
+ * Socket to the reCAPTCHA service
62
+ * @var Socket
63
+ */
64
+ private $socket;
65
+
66
+ /**
67
+ * Constructor
68
+ *
69
+ * @param \ReCaptcha\RequestMethod\Socket $socket optional socket, injectable for testing
70
+ */
71
+ public function __construct(Socket $socket = null)
72
+ {
73
+ if (!is_null($socket)) {
74
+ $this->socket = $socket;
75
+ } else {
76
+ $this->socket = new Socket();
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Submit the POST request with the specified parameters.
82
+ *
83
+ * @param RequestParameters $params Request parameters
84
+ * @return string Body of the reCAPTCHA response
85
+ */
86
+ public function submit(RequestParameters $params)
87
+ {
88
+ $errno = 0;
89
+ $errstr = '';
90
+
91
+ if (false === $this->socket->fsockopen('ssl://' . self::RECAPTCHA_HOST, 443, $errno, $errstr, 30)) {
92
+ return self::BAD_REQUEST;
93
+ }
94
+
95
+ $content = $params->toQueryString();
96
+
97
+ $request = "POST " . self::SITE_VERIFY_PATH . " HTTP/1.1\r\n";
98
+ $request .= "Host: " . self::RECAPTCHA_HOST . "\r\n";
99
+ $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
100
+ $request .= "Content-length: " . strlen($content) . "\r\n";
101
+ $request .= "Connection: close\r\n\r\n";
102
+ $request .= $content . "\r\n\r\n";
103
+
104
+ $this->socket->fwrite($request);
105
+ $response = '';
106
+
107
+ while (!$this->socket->feof()) {
108
+ $response .= $this->socket->fgets(4096);
109
+ }
110
+
111
+ $this->socket->fclose();
112
+
113
+ if (0 !== strpos($response, 'HTTP/1.1 200 OK')) {
114
+ return self::BAD_RESPONSE;
115
+ }
116
+
117
+ $parts = preg_split("#\n\s*\n#Uis", $response);
118
+
119
+ return $parts[1];
120
+ }
121
+ }
vendor/recaptcha/src/ReCaptcha/RequestParameters.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha;
28
+
29
+ /**
30
+ * Stores and formats the parameters for the request to the reCAPTCHA service.
31
+ */
32
+ class RequestParameters
33
+ {
34
+ /**
35
+ * Site secret.
36
+ * @var string
37
+ */
38
+ private $secret;
39
+
40
+ /**
41
+ * Form response.
42
+ * @var string
43
+ */
44
+ private $response;
45
+
46
+ /**
47
+ * Remote user's IP address.
48
+ * @var string
49
+ */
50
+ private $remoteIp;
51
+
52
+ /**
53
+ * Client version.
54
+ * @var string
55
+ */
56
+ private $version;
57
+
58
+ /**
59
+ * Initialise parameters.
60
+ *
61
+ * @param string $secret Site secret.
62
+ * @param string $response Value from g-captcha-response form field.
63
+ * @param string $remoteIp User's IP address.
64
+ * @param string $version Version of this client library.
65
+ */
66
+ public function __construct($secret, $response, $remoteIp = null, $version = null)
67
+ {
68
+ $this->secret = $secret;
69
+ $this->response = $response;
70
+ $this->remoteIp = $remoteIp;
71
+ $this->version = $version;
72
+ }
73
+
74
+ /**
75
+ * Array representation.
76
+ *
77
+ * @return array Array formatted parameters.
78
+ */
79
+ public function toArray()
80
+ {
81
+ $params = array('secret' => $this->secret, 'response' => $this->response);
82
+
83
+ if (!is_null($this->remoteIp)) {
84
+ $params['remoteip'] = $this->remoteIp;
85
+ }
86
+
87
+ if (!is_null($this->version)) {
88
+ $params['version'] = $this->version;
89
+ }
90
+
91
+ return $params;
92
+ }
93
+
94
+ /**
95
+ * Query string representation for HTTP request.
96
+ *
97
+ * @return string Query string formatted parameters.
98
+ */
99
+ public function toQueryString()
100
+ {
101
+ return http_build_query($this->toArray(), '', '&');
102
+ }
103
+ }
vendor/recaptcha/src/ReCaptcha/Response.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha;
28
+
29
+ /**
30
+ * The response returned from the service.
31
+ */
32
+ class Response
33
+ {
34
+ /**
35
+ * Success or failure.
36
+ * @var boolean
37
+ */
38
+ private $success = false;
39
+
40
+ /**
41
+ * Error code strings.
42
+ * @var array
43
+ */
44
+ private $errorCodes = array();
45
+
46
+ /**
47
+ * Build the response from the expected JSON returned by the service.
48
+ *
49
+ * @param string $json
50
+ * @return \ReCaptcha\Response
51
+ */
52
+ public static function fromJson($json)
53
+ {
54
+ $responseData = json_decode($json, true);
55
+
56
+ if (!$responseData) {
57
+ return new Response(false, array('invalid-json'));
58
+ }
59
+
60
+ if (isset($responseData['success']) && $responseData['success'] == true) {
61
+ return new Response(true);
62
+ }
63
+
64
+ if (isset($responseData['error-codes']) && is_array($responseData['error-codes'])) {
65
+ return new Response(false, $responseData['error-codes']);
66
+ }
67
+
68
+ return new Response(false);
69
+ }
70
+
71
+ /**
72
+ * Constructor.
73
+ *
74
+ * @param boolean $success
75
+ * @param array $errorCodes
76
+ */
77
+ public function __construct($success, array $errorCodes = array())
78
+ {
79
+ $this->success = $success;
80
+ $this->errorCodes = $errorCodes;
81
+ }
82
+
83
+ /**
84
+ * Is success?
85
+ *
86
+ * @return boolean
87
+ */
88
+ public function isSuccess()
89
+ {
90
+ return $this->success;
91
+ }
92
+
93
+ /**
94
+ * Get error codes.
95
+ *
96
+ * @return array
97
+ */
98
+ public function getErrorCodes()
99
+ {
100
+ return $this->errorCodes;
101
+ }
102
+ }
vendor/recaptcha/src/autoload.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* An autoloader for ReCaptcha\Foo classes. This should be required()
4
+ * by the user before attempting to instantiate any of the ReCaptcha
5
+ * classes.
6
+ */
7
+
8
+ spl_autoload_register(function ($class) {
9
+ if (substr($class, 0, 10) !== 'ReCaptcha\\') {
10
+ /* If the class does not lie under the "ReCaptcha" namespace,
11
+ * then we can exit immediately.
12
+ */
13
+ return;
14
+ }
15
+
16
+ /* All of the classes have names like "ReCaptcha\Foo", so we need
17
+ * to replace the backslashes with frontslashes if we want the
18
+ * name to map directly to a location in the filesystem.
19
+ */
20
+ $class = str_replace('\\', '/', $class);
21
+
22
+ /* First, check under the current directory. It is important that
23
+ * we look here first, so that we don't waste time searching for
24
+ * test classes in the common case.
25
+ */
26
+ $path = dirname(__FILE__).'/'.$class.'.php';
27
+ if (is_readable($path)) {
28
+ require_once $path;
29
+ }
30
+
31
+ /* If we didn't find what we're looking for already, maybe it's
32
+ * a test class?
33
+ */
34
+ $path = dirname(__FILE__).'/../tests/'.$class.'.php';
35
+ if (is_readable($path)) {
36
+ require_once $path;
37
+ }
38
+ });
vendor/recaptcha/tests/ReCaptcha/ReCaptchaTest.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha;
28
+
29
+ class ReCaptchaTest extends \PHPUnit_Framework_TestCase
30
+ {
31
+
32
+ /**
33
+ * @expectedException \RuntimeException
34
+ * @dataProvider invalidSecretProvider
35
+ */
36
+ public function testExceptionThrownOnInvalidSecret($invalid)
37
+ {
38
+ $rc = new ReCaptcha($invalid);
39
+ }
40
+
41
+ public function invalidSecretProvider()
42
+ {
43
+ return array(
44
+ array(''),
45
+ array(null),
46
+ array(0),
47
+ array(new \stdClass()),
48
+ array(array()),
49
+ );
50
+ }
51
+
52
+ public function testVerifyReturnsErrorOnMissingResponse()
53
+ {
54
+ $rc = new ReCaptcha('secret');
55
+ $response = $rc->verify('');
56
+ $this->assertFalse($response->isSuccess());
57
+ $this->assertEquals(array('missing-input-response'), $response->getErrorCodes());
58
+ }
59
+
60
+ public function testVerifyReturnsResponse()
61
+ {
62
+ $method = $this->getMock('\\ReCaptcha\\RequestMethod', array('submit'));
63
+ $method->expects($this->once())
64
+ ->method('submit')
65
+ ->with($this->callback(function ($params) {
66
+
67
+ return true;
68
+ }))
69
+ ->will($this->returnValue('{"success": true}'));
70
+ ;
71
+ $rc = new ReCaptcha('secret', $method);
72
+ $response = $rc->verify('response');
73
+ $this->assertTrue($response->isSuccess());
74
+ }
75
+ }
vendor/recaptcha/tests/ReCaptcha/RequestMethod/CurlPostTest.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha\RequestMethod;
28
+
29
+ use \ReCaptcha\RequestParameters;
30
+
31
+ class CurlPostTest extends \PHPUnit_Framework_TestCase
32
+ {
33
+
34
+ protected function setUp()
35
+ {
36
+ if (!extension_loaded('curl')) {
37
+ $this->markTestSkipped(
38
+ 'The cURL extension is not available.'
39
+ );
40
+ }
41
+ }
42
+
43
+ public function testSubmit()
44
+ {
45
+ $curl = $this->getMock('\\ReCaptcha\\RequestMethod\\Curl',
46
+ array('init', 'setoptArray', 'exec', 'close'));
47
+ $curl->expects($this->once())
48
+ ->method('init')
49
+ ->willReturn(new \stdClass);
50
+ $curl->expects($this->once())
51
+ ->method('setoptArray')
52
+ ->willReturn(true);
53
+ $curl->expects($this->once())
54
+ ->method('exec')
55
+ ->willReturn('RESPONSEBODY');
56
+ $curl->expects($this->once())
57
+ ->method('close');
58
+
59
+ $pc = new CurlPost($curl);
60
+ $response = $pc->submit(new RequestParameters("secret", "response"));
61
+ $this->assertEquals('RESPONSEBODY', $response);
62
+ }
63
+ }
vendor/recaptcha/tests/ReCaptcha/RequestMethod/PostTest.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha\RequestMethod;
28
+
29
+ use ReCaptcha\RequestParameters;
30
+
31
+ class PostTest extends \PHPUnit_Framework_TestCase
32
+ {
33
+ public static $assert = null;
34
+ protected $parameters = null;
35
+ protected $runcount = 0;
36
+
37
+ public function setUp()
38
+ {
39
+ $this->parameters = new RequestParameters("secret", "response", "remoteip", "version");
40
+ }
41
+
42
+ public function tearDown()
43
+ {
44
+ self::$assert = null;
45
+ }
46
+
47
+ public function testHTTPContextOptions()
48
+ {
49
+ $req = new Post();
50
+ self::$assert = array($this, "httpContextOptionsCallback");
51
+ $req->submit($this->parameters);
52
+ $this->assertEquals(1, $this->runcount, "The assertion was ran");
53
+ }
54
+
55
+ public function testSSLContextOptions()
56
+ {
57
+ $req = new Post();
58
+ self::$assert = array($this, "sslContextOptionsCallback");
59
+ $req->submit($this->parameters);
60
+ $this->assertEquals(1, $this->runcount, "The assertion was ran");
61
+ }
62
+
63
+ public function httpContextOptionsCallback(array $args)
64
+ {
65
+ $this->runcount++;
66
+ $this->assertCommonOptions($args);
67
+
68
+ $options = stream_context_get_options($args[2]);
69
+ $this->assertArrayHasKey('http', $options);
70
+
71
+ $this->assertArrayHasKey('method', $options['http']);
72
+ $this->assertEquals("POST", $options['http']['method']);
73
+
74
+ $this->assertArrayHasKey('content', $options['http']);
75
+ $this->assertEquals($this->parameters->toQueryString(), $options['http']['content']);
76
+
77
+ $this->assertArrayHasKey('header', $options['http']);
78
+ $headers = array(
79
+ "Content-type: application/x-www-form-urlencoded",
80
+ );
81
+ foreach ($headers as $header) {
82
+ $this->assertContains($header, $options['http']['header']);
83
+ }
84
+ }
85
+
86
+ public function sslContextOptionsCallback(array $args)
87
+ {
88
+ $this->runcount++;
89
+ $this->assertCommonOptions($args);
90
+
91
+ $options = stream_context_get_options($args[2]);
92
+ $this->assertArrayHasKey('http', $options);
93
+ $this->assertArrayHasKey('verify_peer', $options['http']);
94
+ $this->assertTrue($options['http']['verify_peer']);
95
+
96
+ $key = version_compare(PHP_VERSION, "5.6.0", "<") ? "CN_name" : "peer_name";
97
+
98
+ $this->assertArrayHasKey($key, $options['http']);
99
+ $this->assertEquals("www.google.com", $options['http'][$key]);
100
+ }
101
+
102
+ protected function assertCommonOptions(array $args)
103
+ {
104
+ $this->assertCount(3, $args);
105
+ $this->assertStringStartsWith("https://www.google.com/", $args[0]);
106
+ $this->assertFalse($args[1]);
107
+ $this->assertTrue(is_resource($args[2]), "The context options should be a resource");
108
+ }
109
+ }
110
+
111
+ function file_get_contents()
112
+ {
113
+ if (PostTest::$assert) {
114
+ return call_user_func(PostTest::$assert, func_get_args());
115
+ }
116
+ // Since we can't represent maxlen in userland...
117
+ return call_user_func_array('file_get_contents', func_get_args());
118
+ }
vendor/recaptcha/tests/ReCaptcha/RequestMethod/SocketPostTest.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha\RequestMethod;
28
+
29
+ use ReCaptcha\RequestParameters;
30
+
31
+ class SocketPostTest extends \PHPUnit_Framework_TestCase
32
+ {
33
+
34
+ public function testSubmitSuccess()
35
+ {
36
+ $socket = $this->getMock('\\ReCaptcha\\RequestMethod\\Socket', array('fsockopen', 'fwrite', 'fgets', 'feof', 'fclose'));
37
+ $socket->expects($this->once())
38
+ ->method('fsockopen')
39
+ ->willReturn(true);
40
+ $socket->expects($this->once())
41
+ ->method('fwrite');
42
+ $socket->expects($this->once())
43
+ ->method('fgets')
44
+ ->willReturn("HTTP/1.1 200 OK\n\nRESPONSEBODY");
45
+ $socket->expects($this->exactly(2))
46
+ ->method('feof')
47
+ ->will($this->onConsecutiveCalls(false, true));
48
+ $socket->expects($this->once())
49
+ ->method('fclose')
50
+ ->willReturn(true);
51
+
52
+ $ps = new SocketPost($socket);
53
+ $response = $ps->submit(new RequestParameters("secret", "response", "remoteip", "version"));
54
+ $this->assertEquals('RESPONSEBODY', $response);
55
+ }
56
+
57
+ public function testSubmitBadResponse()
58
+ {
59
+ $socket = $this->getMock('\\ReCaptcha\\RequestMethod\\Socket', array('fsockopen', 'fwrite', 'fgets', 'feof', 'fclose'));
60
+ $socket->expects($this->once())
61
+ ->method('fsockopen')
62
+ ->willReturn(true);
63
+ $socket->expects($this->once())
64
+ ->method('fwrite');
65
+ $socket->expects($this->once())
66
+ ->method('fgets')
67
+ ->willReturn("HTTP/1.1 500 NOPEn\\nBOBBINS");
68
+ $socket->expects($this->exactly(2))
69
+ ->method('feof')
70
+ ->will($this->onConsecutiveCalls(false, true));
71
+ $socket->expects($this->once())
72
+ ->method('fclose')
73
+ ->willReturn(true);
74
+
75
+ $ps = new SocketPost($socket);
76
+ $response = $ps->submit(new RequestParameters("secret", "response", "remoteip", "version"));
77
+ $this->assertEquals(SocketPost::BAD_RESPONSE, $response);
78
+ }
79
+
80
+ public function testSubmitBadRequest()
81
+ {
82
+ $socket = $this->getMock('\\ReCaptcha\\RequestMethod\\Socket', array('fsockopen'));
83
+ $socket->expects($this->once())
84
+ ->method('fsockopen')
85
+ ->willReturn(false);
86
+ $ps = new SocketPost($socket);
87
+ $response = $ps->submit(new RequestParameters("secret", "response", "remoteip", "version"));
88
+ $this->assertEquals(SocketPost::BAD_REQUEST, $response);
89
+ }
90
+ }
vendor/recaptcha/tests/ReCaptcha/RequestParametersTest.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha;
28
+
29
+ class RequestParametersTest extends \PHPUnit_Framework_TestCase
30
+ {
31
+
32
+ public function provideValidData()
33
+ {
34
+ return array(
35
+ array('SECRET', 'RESPONSE', 'REMOTEIP', 'VERSION',
36
+ array('secret' => 'SECRET', 'response' => 'RESPONSE', 'remoteip' => 'REMOTEIP', 'version' => 'VERSION'),
37
+ 'secret=SECRET&response=RESPONSE&remoteip=REMOTEIP&version=VERSION'),
38
+ array('SECRET', 'RESPONSE', null, null,
39
+ array('secret' => 'SECRET', 'response' => 'RESPONSE'),
40
+ 'secret=SECRET&response=RESPONSE'),
41
+ );
42
+ }
43
+
44
+ /**
45
+ * @dataProvider provideValidData
46
+ */
47
+ public function testToArray($secret, $response, $remoteIp, $version, $expectedArray, $expectedQuery)
48
+ {
49
+ $params = new RequestParameters($secret, $response, $remoteIp, $version);
50
+ $this->assertEquals($params->toArray(), $expectedArray);
51
+ }
52
+
53
+ /**
54
+ * @dataProvider provideValidData
55
+ */
56
+ public function testToQueryString($secret, $response, $remoteIp, $version, $expectedArray, $expectedQuery)
57
+ {
58
+ $params = new RequestParameters($secret, $response, $remoteIp, $version);
59
+ $this->assertEquals($params->toQueryString(), $expectedQuery);
60
+ }
61
+ }
vendor/recaptcha/tests/ReCaptcha/ResponseTest.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha;
28
+
29
+ class ResponseTest extends \PHPUnit_Framework_TestCase
30
+ {
31
+
32
+ /**
33
+ * @dataProvider provideJson
34
+ */
35
+ public function testFromJson($json, $success, $errorCodes)
36
+ {
37
+ $response = Response::fromJson($json);
38
+ $this->assertEquals($success, $response->isSuccess());
39
+ $this->assertEquals($errorCodes, $response->getErrorCodes());
40
+ }
41
+
42
+ public function provideJson()
43
+ {
44
+ return array(
45
+ array('{"success": true}', true, array()),
46
+ array('{"success": false, "error-codes": ["test"]}', false, array('test')),
47
+ array('{"success": true, "error-codes": ["test"]}', true, array()),
48
+ array('{"success": false}', false, array()),
49
+ array('BAD JSON', false, array('invalid-json')),
50
+ );
51
+ }
52
+
53
+ public function testIsSuccess()
54
+ {
55
+ $response = new Response(true);
56
+ $this->assertTrue($response->isSuccess());
57
+
58
+ $response = new Response(false);
59
+ $this->assertFalse($response->isSuccess());
60
+ }
61
+
62
+ public function testGetErrorCodes()
63
+ {
64
+ $errorCodes = array('test');
65
+ $response = new Response(true, $errorCodes);
66
+ $this->assertEquals($errorCodes, $response->getErrorCodes());
67
+ }
68
+ }