├── .gitignore ├── .gitmodules ├── style.css ├── scripts ├── js │ ├── admin.js │ └── global.js ├── ajax.php └── recaptchalib.php ├── changelog.txt ├── README.md ├── languages └── contact_widget.pot └── contact-form.php /.gitignore: -------------------------------------------------------------------------------- 1 | .idea* 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "dash-notice"] 2 | path = dash-notice 3 | url = git@bitbucket.org:incsub/wpmudev-dashboard-notification.git 4 | branch = master 5 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | #wp-contact-form input, #wp-contact-form textarea { 2 | padding: 5px; 3 | width: 95%; 4 | } 5 | 6 | #wp-contact-form label { 7 | display: block; 8 | font-weight: bold; 9 | } 10 | 11 | div#cw-recaptcha_widget { 12 | margin: 10px 0; 13 | width: 210px; 14 | } 15 | 16 | div#recaptcha_image { 17 | max-width: 90%; 18 | } 19 | 20 | div#cw-recaptcha_widget #recaptcha_image img { 21 | cursor: pointer; 22 | height: 46px; 23 | width: 210px; 24 | float: left; 25 | } 26 | 27 | .cw_inactive { 28 | color: #ccc; 29 | } 30 | 31 | .g-recaptcha { 32 | max-width: 100%; 33 | } 34 | 35 | .cw-message { 36 | font-size: medium; 37 | font-weight: 500; 38 | } 39 | 40 | .widget.Contact_form { 41 | padding-top: 0; 42 | padding-bottom: 0; 43 | } 44 | 45 | #form-fields label { 46 | max-width: 90%; 47 | display: inline-block; 48 | } -------------------------------------------------------------------------------- /scripts/js/admin.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | $(function () { 3 | 4 | var _bound = false; 5 | 6 | function _check_generic_from_enabled($chk) { 7 | var $parent = $chk.parents(".cw_generic_from_container"); 8 | var $target = $parent.find(".cw_generic_from_options"); 9 | if ($chk.is(":checked")) { 10 | $target.show(); 11 | } else { 12 | $target.hide(); 13 | } 14 | } 15 | 16 | function _show_captcha_keys() { 17 | var $me = $(this); 18 | var $target = $me.parents(".cw_captcha").find(".cw_captcha_keys"); 19 | if ($me.is(":checked")) $target.show(); 20 | else $target.hide(); 21 | } 22 | 23 | function _init_generic_forms() { 24 | $('.cw_generic_from_container :checkbox.cw-contact_form_generic_from').each(function () { 25 | var $me = $(this); 26 | _check_generic_from_enabled($me); 27 | }); 28 | $(".cw_captcha :checkbox").each(_show_captcha_keys); 29 | } 30 | 31 | function init() { 32 | $(document).ajaxComplete(_init_generic_forms); 33 | $(document).on('click', '.cw_generic_from_container :checkbox.cw-contact_form_generic_from', function () { 34 | _check_generic_from_enabled($(this)); 35 | }); 36 | $(document).on('click', ".cw_captcha :checkbox", _show_captcha_keys); 37 | _init_generic_forms(); 38 | _bound = true; 39 | } 40 | 41 | if (!_bound) init(); 42 | 43 | }); 44 | })(jQuery); 45 | jQuery(document).ready(function(){ 46 | jQuery('body').on('change', 'input[type=radio].recaptcha-version', function () { 47 | if (this.value == 'old') { 48 | jQuery('.old-recaptcha-settings').show(); 49 | jQuery('.new-recaptcha-settings').hide(); 50 | } 51 | else if (this.value == 'new') { 52 | jQuery('.old-recaptcha-settings').hide(); 53 | jQuery('.new-recaptcha-settings').show(); 54 | } 55 | }); 56 | }); -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | Plugin Name: Contact Widget 2 | 3 | Change Log: 4 | ---------------------------------------------------------------------- 5 | 6 | 2.2.1 - 2017-09-04 7 | -------- 8 | - Fix: deprecated constructor notice 9 | 10 | 11 | 2.2 - 2015-02-20 - Umesh Kumar 12 | -------- 13 | 14 | Important - After updating plugin, please save widget settings once 15 | 16 | - Fixed: API Key registration Link 17 | - Fixed: Enqueue script warning 18 | - Fixed: Old Recaptcha image styling 19 | - Fixed: Do not submit private key through form 20 | - New: Choose from new or Old ReCaptcha lib 21 | 22 | 2.1.5, 2013-10-28 23 | -------- 24 | - Regardless of CAPTCHA settings, don't apply it unless we have API keys. 25 | - Adding the conditional API error message. 26 | 27 | 2.1.4, 2013-09-12 28 | -------- 29 | - Improved filtering. 30 | - Javascript cleanup. 31 | 32 | 2.1.3, 2012-10-03 33 | -------- 34 | - Do not explicitly include pluggables. 35 | - Properly enqueueing scripts and styles, with optional fallback. 36 | 37 | 2.1.2, 2012-07-06 38 | -------- 39 | - Fix for error processing filter. 40 | 41 | 2.1.1, 2012-07-05 42 | -------- 43 | - Fix for unprotected forms. 44 | 45 | 2.1, 2012-06-27 46 | -------- 47 | - Added output modification filters for headers, subject and message. 48 | - Added appearance and behavior modifying hooks to allow custom changes. 49 | - Added ReCaptcha keys settings fields. 50 | 51 | 2.0, 2012-05-03 52 | -------- 53 | - Partial rewrite to discard deprecated API calls. 54 | - Allowing multiple widgets. 55 | - Fixed plugin conflict with pop up. 56 | 57 | 1.3.1, 2011-12-04 58 | -------- 59 | - Prepared the plugin for l10n. 60 | - Fixed double escaping issue. 61 | 62 | 1.3 63 | -------- 64 | - Added generic "From" options. 65 | 66 | 1.2.2 67 | -------- 68 | - Do not clear user-supplied text in compact mode. 69 | 70 | 1.2.1 71 | -------- 72 | - Fix showing up in Update Notifications 73 | 74 | 1.2 75 | --- 76 | - Added CAPTCHA refresh options 77 | - Added Compact display mode 78 | - Some markup fixes 79 | 80 | 1.1 81 | --- 82 | - Partial rewrite to better support various setups. 83 | 84 | 1.0.2 85 | --- 86 | - Add Update Notifications code 87 | 88 | 1.0.1 89 | --- 90 | - Added link to recaptcha to keep with license 91 | -------------------------------------------------------------------------------- /scripts/js/global.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | 3 | function cw_submit_form() { 4 | var $me = jQuery(this); 5 | var $form = $me.parents("form.wp-contact-form"); 6 | var str = $form.serialize(); 7 | jQuery.post(_cw_ajaxurl, { 8 | "action": "cw_send_mail", 9 | "data": str 10 | }, function (data) { 11 | var status = 0; 12 | var msg = ''; 13 | try { 14 | status = parseInt(data.status, 10); 15 | } catch (e) { 16 | status = 0; 17 | } 18 | try { 19 | msg = data.message; 20 | } catch (e) { 21 | msg = ''; 22 | } 23 | if (status) { 24 | jQuery(':input', $form).not(':button, :submit, :reset, :hidden').val(''); 25 | $form.trigger('cw-mail_sent'); 26 | } 27 | $form.find('.cw-message').html(msg); 28 | if (typeof Recaptcha != 'undefined') { 29 | Recaptcha.reload(); 30 | } else if ( typeof grecaptcha != 'undefined' ) { 31 | grecaptcha.reset(); 32 | } 33 | }, 'json'); 34 | return false; 35 | } 36 | 37 | function cw_spawn_captcha() { 38 | if (typeof Recaptcha == "undefined") return; 39 | 40 | var $me = $(this); 41 | var $new = $me.parents("form.wp-contact-form"); 42 | if (!$new.is(".cw-has_captcha")) return; 43 | 44 | var $old = $("#cw-recaptcha_widget").parents("form.wp-contact-form"); 45 | if ($new.attr("id") == $old.attr("id")) return; 46 | 47 | Recaptcha.destroy(); 48 | $new.append($("#cw-recaptcha_widget")); 49 | if ($new.is(".cw-compact_form")) $("#cw_refresh").hide(); 50 | else $("#cw_refresh a").text($new.find(".cw-refresh_link").val()).show(); 51 | Recaptcha.create( 52 | '6LcHObsSAAAAAIfHD_wQ92EWdOV0JTcIN8tYxN07', 53 | 'cw-recaptcha_widget', 54 | RecaptchaOptions 55 | ); 56 | $("#recaptcha_image").attr("title", $new.find(".cw-refresh_message").val()); 57 | } 58 | 59 | 60 | $(function () { 61 | 62 | if (typeof Recaptcha != "undefined") { 63 | $("#recaptcha_image").click(Recaptcha.reload); 64 | } 65 | 66 | // Initialize forms 67 | $("form.wp-contact-form").each(function () { 68 | var $form = $(this); 69 | if (!$form.length) return true; 70 | 71 | if ($form.find("#cw-recaptcha_widget").length) { 72 | if ($form.is(".cw-compact_form")) $("#cw_refresh").hide(); 73 | else $("#cw_refresh a").text($form.find(".cw-refresh_link").val()).show(); 74 | 75 | $("#recaptcha_image").attr("title", $form.find(".cw-refresh_message").val()); 76 | } 77 | $form.find('input:button[name="submit"]').bind('click', cw_submit_form); // Bind submission 78 | $form.find(":input").bind('focus', cw_spawn_captcha); 79 | 80 | if (!$form.is(".cw-compact_form")) return true; // Compacting forms below 81 | 82 | $form.find("label").each(function () { 83 | var $me = $(this); 84 | $me.hide(); 85 | if (!$me.attr("for")) return true; 86 | var $obj = $("#" + $me.attr("for")); 87 | if (!$obj.length) return true; 88 | $obj 89 | .addClass('cw_inactive') 90 | .val($me.text()) 91 | .focus(function () { 92 | if ($obj.val() == $me.text()) $obj.val(''); 93 | $obj.removeClass('cw_inactive'); 94 | }) 95 | .blur(function () { 96 | if ($obj.val()) return true; 97 | $obj.addClass('cw_inactive').val($me.text()); 98 | }) 99 | ; 100 | }); 101 | }); 102 | 103 | 104 | }); 105 | })(jQuery); 106 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Contact Widget 2 | 3 | **INACTIVE NOTICE: This plugin is unsupported by WPMUDEV, we've published it here for those technical types who might want to fork and maintain it for their needs.** 4 | 5 | ## Translations 6 | 7 | Translation files can be found at https://github.com/wpmudev/translations 8 | 9 | ## Contact Widget is a simple yet powerful contact form for use in any widgetized area of your site. 10 | 11 | Help your visitors get in touch with you using this quick and easy contact solution. 12 | 13 | ![Contact Widget](http://premium.wpmudev.org/wp-content/uploads/2010/07/contact-widget1.png) 14 | 15 | Offers a clean and simple contact form. 16 | 17 | ### Contact Widget is easy to use 18 | 19 | Don't waste time trying to figure out complex contact forms. Simply install and activate Contact Widget and drag-and-drop the contact form onto any widgetized area of your site. Whether you're running a single blog or a Multisite installation, Contact Widget provides a simple contact form that does it all: 20 | 21 | * Widget title – Label your contact form with a personalized title 22 | * Subject, from and message labels – customize your contact form 23 | * Admin email – Choose which email address you would like the form to forward messages to 24 | * Success message – Thank your visitors for their message 25 | * Text after the form – Personalise your contact form 26 | * Custom CSS – Customize the look and feel of your contact form 27 | * Captcha – Enable Captcha and fight spam 28 | 29 | Add a contact form to any widget area on your site and give your users a fast way to ask questions, make a suggestion or get more information. 30 | 31 | ## Usage 32 | 33 | ### To Get Started 34 | 35 | Start by reading [Installing plugins](https://premium.wpmudev.org/project/wpmu-manual/installing-regular-plugins-on-wpmu/) section in our comprehensive [WordPress and WordPress Multisite Manual](https://premium.wpmudev.org/manuals/) if you are new to WordPress. 36 | 37 | Once installed go to Plugins in the network admin dashboard and Network Activate the Users Widget plugin. 38 | 39 | ### To Use: 40 | 41 | Once activated, just go to _Appearance > Widgets_ in the admin area of your site, where you’ll now see the Contact Widget. 42 | 43 | ![Contact Widget - widgets section](https://premium.wpmudev.org/wp-content/uploads/2010/07/Contact-Widget-widgets-section.png) 44 | 45 | Simply drag the widget to an available sidebar and you’ll be presented with several settings. 46 | 47 | ![Contact Widget - widget settings](https://premium.wpmudev.org/wp-content/uploads/2010/07/Contact-Widget-widget-settings.png) 48 | 49 | You can optionally enter a _Widget Title_. Enter a _Subject label_ to be used for the email. Enter a _From label_ to be used for email address the email is sent "from". Or you can tick the '_Use generic "from" address_' option, which will display a few additional options for the "from" address. 50 | 51 | ![Contact Widget - from address](https://premium.wpmudev.org/wp-content/uploads/2010/07/Contact-Widget-from-address.png) 52 | 53 | Options available when Enabled. 54 | 55 | Enter a _Message label_ for the email. Enter the text you would like to use for the _Send Message button text_. Optionally, you can specify an _Admin email_. The plugin will use the default admin email otherwise. Enter a _Success message_ that will be displayed when the user successfully sends a message. Optionally, you can also add some content to the form by adding content to the _Text after the form_ field. You can also add your own CSS to style the contact form by entering your code in the _Custom CSS_ field. The plugin uses a class of wp-contact-form for the form. So for example, you could use the following CSS to display input fields in a block format: 56 | 57 | wp-contact-form input {display: block;} 58 | 59 | ##### CAPTCHA options 60 | 61 | Contact Widget provides a feature to include a CAPTCHA form utilizing Google's free reCAPTCHA service. You'll need to create a Google account to access their API in order to use this feature. A link is provided to easily set that up. Ticking the _Enable CAPTCHA_ option will enable the use of the CAPTCHA features. Enter your Public key. Enter your Private key. Optionally, enter a link you'd like displayed for the '_Refresh CAPTCHA link_'. Also option, you can enter a message you'd like displayed for the '_Refresh CAPTCHA message_'. This is the message displayed when a user moves their mouse over the CAPTCHA image. Tick the _Compact mode_ option to enable a special mode where the form fields are neatly Press the _Save_ button to ensure your changes are saved. 62 | 63 | ### User Experience 64 | 65 | When you view your site you will now see the widget displayed in your sidebar. Here’s an example of how it could look using Twenty Twelve theme. 66 | 67 | ![Contact Widget - front-end](https://premium.wpmudev.org/wp-content/uploads/2010/07/Contact-Widget-front-end.png) 68 | 69 | Here's how it could look with the _Compact mode_ enabled. 70 | 71 | ![Contact Widget - compact mode](https://premium.wpmudev.org/wp-content/uploads/2010/07/Contact-Widget-compact-mode.png) 72 | -------------------------------------------------------------------------------- /scripts/ajax.php: -------------------------------------------------------------------------------- 1 | check_answer( 21 | $secret, 22 | $_SERVER["REMOTE_ADDR"], 23 | $_POST["recaptcha_challenge_field"], 24 | $_POST["recaptcha_response_field"] 25 | ); 26 | } else { 27 | $response = ! empty( $_POST["g-recaptcha-response"] ) ? $_POST["g-recaptcha-response"] : ''; 28 | $resp = $reCaptcha->verifyResponse( 29 | $_SERVER["REMOTE_ADDR"], 30 | $response 31 | ); 32 | } 33 | if ( $resp->success ) { 34 | $resp->is_valid = 1; 35 | } 36 | } 37 | 38 | if ( empty( $_POST ) ) { 39 | return; 40 | } 41 | $email = ! empty( $_POST['email'] ) ? $_POST['email'] : ''; 42 | $subject = ! empty( $_POST['subject'] ) ? cw_validate_subject( stripslashes( $_POST['subject'] ) ) : ''; 43 | $message = ! empty( $_POST['message'] ) ? stripslashes( $_POST['message'] ) : ''; 44 | 45 | $error = ''; 46 | 47 | if ( ! $subject ) { 48 | $error .= '

' . __( 'Please enter a subject.', 'contact_widget' ) . '

'; 49 | } 50 | 51 | if ( ! $email ) { 52 | $error .= '

' . __( 'Please enter an e-mail address.', 'contact_widget' ) . '

'; 53 | } 54 | 55 | if ( $email && ! cw_validate_email( $email ) ) { 56 | $error .= '

' . __( 'Please enter a valid e-mail address.', 'contact_widget' ) . '

'; 57 | } 58 | 59 | /** 60 | * Validate email address 61 | * 62 | * @param $email 63 | * 64 | * @return bool|mixed 65 | */ 66 | function cw_validate_email( $email ) { 67 | 68 | if ( function_exists( 'filter_var' ) && defined( 'FILTER_VALIDATE_EMAIL' ) ) { 69 | return filter_var( $email, FILTER_VALIDATE_EMAIL ); 70 | } 71 | 72 | $regex = '/([a-z0-9_.-]+)' . 73 | '@' . 74 | '([a-z0-9.-]+){1,255}' . 75 | '.' . 76 | "([a-z]+){2,10}/i"; 77 | 78 | if ( $email == '' ) { 79 | return false; 80 | } else { 81 | $eregi = preg_replace( $regex, '', $email ); 82 | } 83 | 84 | return empty( $eregi ) ? true : false; 85 | } 86 | 87 | function cw_validate_subject( $subject ) { 88 | return str_ireplace( array( "\r", "\n", "%0a", "%0d" ), '', stripslashes( $subject ) ); 89 | } 90 | 91 | if ( $_data['contact_form_captcha'] == 'on' ) { 92 | if ( empty( $resp->is_valid ) || ! $resp->is_valid ) { 93 | $error .= '

' . __( 'Please enter a valid captcha.', 'contact_widget' ) . '

'; 94 | } 95 | } 96 | 97 | $error = apply_filters( 'contact_form-validate_fields', $error, $_data ); 98 | 99 | //If any errors, return 100 | if ( $error ) { 101 | echo json_encode( array( 102 | "status" => 0, 103 | "message" => $error 104 | ) ); 105 | } 106 | 107 | if ( ! $error ) { 108 | $custom_email = trim( $_data['contact_form_admin_email'] ); 109 | $admin_email = $custom_email ? $custom_email : get_option( 'admin_email' ); 110 | $headers = 'MIME-Version: 1.0\r\n'; 111 | $headers .= 'Content-type: text/html; charset=utf-8\r\n'; 112 | 113 | if ( $_data['contact_form_generic_from'] == 'on' ) { 114 | $hostname = preg_replace( '/^www\./', '', parse_url( site_url(), PHP_URL_HOST ) ); 115 | $user = trim( $_data['contact_form_generic_from_user'] ); 116 | $user = $user ? preg_replace( '/[^-a-z0-9_.]/', '', strtolower( $user ) ) : 'noreply'; 117 | $from = "{$user}@{$hostname}"; 118 | $reply_to = ( $_data['contact_form_generic_from_reply_to'] == 'on' ) ? $email : $from; 119 | if ( $_data['contact_form_generic_from_body'] == 'on' ) { 120 | $message = "From: {$email}\n
\n{$message}"; 121 | } 122 | } else { 123 | $reply_to = $from = $email; 124 | } 125 | 126 | $headers .= "To: Site admin <{$admin_email}>\r\n"; 127 | $headers .= "From: <{$from}>\r\n"; 128 | $headers .= "Reply-To: <{$reply_to}>\r\n"; 129 | 130 | $headers = apply_filters( 'contact_form-mail_headers', $headers ); 131 | $subject = apply_filters( 'contact_form-mail_subject', $subject ); 132 | $message = apply_filters( 'contact_form-mail_message', $message ); 133 | 134 | $mail = wp_mail( $admin_email, $subject, $message, $headers ); 135 | if ( $mail ) { 136 | $success = @$_data['contact_form_success_message'] ? '

' . $_data['contact_form_success_message'] . '

' : '

' . __( 'Your message has been sent. Thank you!', 'contact_widget' ) . '

'; 137 | echo json_encode( array( 138 | "status" => 1, 139 | "message" => $success, 140 | ) ); 141 | } else { 142 | echo json_encode( array( 143 | "status" => 0, 144 | "message" => '

' . __( 'Mail not sent', 'contact_widget' ) . '

' 145 | ) ); 146 | } 147 | } 148 | 149 | ?> -------------------------------------------------------------------------------- /languages/contact_widget.pot: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Contact Form 2 | # This file is distributed under the same license as the Contact Form package. 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: Contact Form 2.2\n" 6 | "POT-Creation-Date: 2015-02-20 05:09:48+00:00\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2015-02-20 HO:MI+ZONE\n" 11 | "Last-Translator: Umesh Kumar \n" 12 | "Language-Team: WPMU Dev\n" 13 | 14 | #: contact-form.php:68 contact-form.php:69 contact-form.php:445 15 | msgid "Contact Form" 16 | msgstr "" 17 | 18 | #: contact-form.php:123 19 | msgid "Widget title:" 20 | msgstr "" 21 | 22 | #: contact-form.php:127 23 | msgid "Subject label:" 24 | msgstr "" 25 | 26 | #: contact-form.php:131 27 | msgid "From label:" 28 | msgstr "" 29 | 30 | #: contact-form.php:135 31 | msgid "Use generic "from" address:" 32 | msgstr "" 33 | 34 | #: contact-form.php:138 contact-form.php:181 contact-form.php:267 35 | msgid "Enable" 36 | msgstr "" 37 | 38 | #: contact-form.php:146 39 | msgid "Use senders email as Reply-To address?" 40 | msgstr "" 41 | 42 | #: contact-form.php:150 43 | msgid "Add senders email to message body?" 44 | msgstr "" 45 | 46 | #: contact-form.php:154 47 | msgid "Message label:" 48 | msgstr "" 49 | 50 | #: contact-form.php:158 51 | msgid "Send Message button text:" 52 | msgstr "" 53 | 54 | #: contact-form.php:162 55 | msgid "Admin email (optional):" 56 | msgstr "" 57 | 58 | #: contact-form.php:166 59 | msgid "Success message:" 60 | msgstr "" 61 | 62 | #: contact-form.php:170 63 | msgid "Text after the form:" 64 | msgstr "" 65 | 66 | #: contact-form.php:174 67 | msgid "Custom CSS:" 68 | msgstr "" 69 | 70 | #: contact-form.php:178 71 | msgid "Enable CAPTCHA:" 72 | msgstr "" 73 | 74 | #: contact-form.php:186 75 | msgid "To start using ReCaptcha protection, you will first need to generate a set of API keys here." 76 | msgstr "" 77 | 78 | #: contact-form.php:191 79 | msgid "Please, remember that your submissions will not be protected until you set up the API keys." 80 | msgstr "" 81 | 82 | #: contact-form.php:194 83 | msgid "Site Key" 84 | msgstr "" 85 | 86 | #: contact-form.php:197 87 | msgid "Secret Key" 88 | msgstr "" 89 | 90 | #: contact-form.php:204 91 | msgid "ReCaptcha Version:" 92 | msgstr "" 93 | 94 | #: contact-form.php:208 95 | msgid "Old" 96 | msgstr "" 97 | 98 | #: contact-form.php:213 99 | msgid "New" 100 | msgstr "" 101 | 102 | #: contact-form.php:219 103 | msgid "Refresh CAPTCHA link:" 104 | msgstr "" 105 | 106 | #: contact-form.php:224 107 | msgid "Refresh CAPTCHA message:" 108 | msgstr "" 109 | 110 | #: contact-form.php:227 111 | msgid "This is the message that will appear when user rolls over CAPTCHA image" 112 | msgstr "" 113 | 114 | #: contact-form.php:230 115 | msgid "Captcha input label:" 116 | msgstr "" 117 | 118 | #: contact-form.php:236 119 | msgid "Recaptcha Theme:" 120 | msgstr "" 121 | 122 | #: contact-form.php:240 123 | msgid "Light" 124 | msgstr "" 125 | 126 | #: contact-form.php:245 127 | msgid "Dark" 128 | msgstr "" 129 | 130 | #: contact-form.php:250 131 | msgid "Recaptcha Type:" 132 | msgstr "" 133 | 134 | #: contact-form.php:254 135 | msgid "Image" 136 | msgstr "" 137 | 138 | #: contact-form.php:259 139 | msgid "Audio" 140 | msgstr "" 141 | 142 | #: contact-form.php:264 143 | msgid "Compact mode:" 144 | msgstr "" 145 | 146 | #: contact-form.php:302 contact-form.php:460 147 | msgid "Click to refresh" 148 | msgstr "" 149 | 150 | #: contact-form.php:303 contact-form.php:461 151 | msgid "Reload Captcha" 152 | msgstr "" 153 | 154 | #: contact-form.php:305 contact-form.php:462 155 | msgid "Type the characters you see in image above" 156 | msgstr "" 157 | 158 | #: contact-form.php:417 159 | msgid "Incorrect please try again" 160 | msgstr "" 161 | 162 | #: contact-form.php:446 163 | msgid "Subject" 164 | msgstr "" 165 | 166 | #: contact-form.php:447 167 | msgid "From" 168 | msgstr "" 169 | 170 | #: contact-form.php:448 171 | msgid "Message" 172 | msgstr "" 173 | 174 | #: contact-form.php:449 175 | msgid "Send Message" 176 | msgstr "" 177 | 178 | #: contact-form.php:451 179 | msgid "Mail sent!" 180 | msgstr "" 181 | 182 | #: scripts/ajax.php:48 183 | msgid "Please enter a subject." 184 | msgstr "" 185 | 186 | #: scripts/ajax.php:52 187 | msgid "Please enter an e-mail address." 188 | msgstr "" 189 | 190 | #: scripts/ajax.php:56 191 | msgid "Please enter a valid e-mail address." 192 | msgstr "" 193 | 194 | #: scripts/ajax.php:93 195 | msgid "Please enter a valid captcha." 196 | msgstr "" 197 | 198 | #: scripts/ajax.php:136 199 | msgid "Your message has been sent. Thank you!" 200 | msgstr "" 201 | 202 | #: scripts/ajax.php:144 203 | msgid "Mail not sent" 204 | msgstr "" 205 | #. Plugin Name of the plugin/theme 206 | msgid "Contact Form" 207 | msgstr "" 208 | 209 | #. Plugin URI of the plugin/theme 210 | msgid "http://premium.wpmudev.org/project/contact-widget" 211 | msgstr "" 212 | 213 | #. Description of the plugin/theme 214 | msgid "Adds a contact form widget to your blog." 215 | msgstr "" 216 | 217 | #. Author of the plugin/theme 218 | msgid "WPMU DEV" 219 | msgstr "" 220 | 221 | #. Author URI of the plugin/theme 222 | msgid "http://premium.wpmudev.org/" 223 | msgstr "" 224 | -------------------------------------------------------------------------------- /scripts/recaptchalib.php: -------------------------------------------------------------------------------- 1 | " . self::$_signupUrl . "" ); 63 | } 64 | $this->_secret = $secret; 65 | } 66 | 67 | /** 68 | * Encodes the given data into a query string format. 69 | * 70 | * @param array $data array of string elements to be encoded. 71 | * 72 | * @return string - encoded request. 73 | */ 74 | private function _encodeQS( $data ) { 75 | $req = ""; 76 | foreach ( $data as $key => $value ) { 77 | $req .= $key . '=' . urlencode( stripslashes( $value ) ) . '&'; 78 | } 79 | 80 | // Cut the last '&' 81 | $req = substr( $req, 0, strlen( $req ) - 1 ); 82 | 83 | return $req; 84 | } 85 | 86 | /** 87 | * Submits an HTTP GET to a reCAPTCHA server. 88 | * 89 | * @param string $path url path to recaptcha server. 90 | * @param array $data array of parameters to be sent. 91 | * 92 | * @return array response 93 | */ 94 | private function _submitHTTPGet( $path, $data ) { 95 | $req = $this->_encodeQS( $data ); 96 | $response = file_get_contents( $path . $req ); 97 | 98 | return $response; 99 | } 100 | 101 | /** 102 | * Calls the reCAPTCHA siteverify API to verify whether the user passes 103 | * CAPTCHA test. 104 | * 105 | * @param string $remoteIp IP address of end user. 106 | * @param string $response response string from recaptcha verification. 107 | * 108 | * @return ReCaptchaResponse 109 | */ 110 | public function verifyResponse( $remoteIp, $response ) { 111 | // Discard empty solution submissions 112 | if ( $response == null || strlen( $response ) == 0 ) { 113 | $recaptchaResponse = new ReCaptchaResponse(); 114 | $recaptchaResponse->success = false; 115 | $recaptchaResponse->errorCodes = 'missing-input'; 116 | 117 | return $recaptchaResponse; 118 | } 119 | 120 | $getResponse = $this->_submitHttpGet( 121 | self::$_siteVerifyUrl, 122 | array( 123 | 'secret' => $this->_secret, 124 | 'remoteip' => $remoteIp, 125 | 'v' => self::$_version, 126 | 'response' => $response 127 | ) 128 | ); 129 | $answers = json_decode( $getResponse, true ); 130 | $recaptchaResponse = new ReCaptchaResponse(); 131 | 132 | if ( trim( $answers ['success'] ) == true ) { 133 | $recaptchaResponse->success = true; 134 | } else { 135 | $recaptchaResponse->success = false; 136 | $recaptchaResponse->errorCodes = !empty( $answers ['error-codes'] ) ? $answers ['error-codes'] : ''; 137 | } 138 | 139 | return $recaptchaResponse; 140 | } 141 | 142 | /** 143 | * Submits an HTTP POST to a reCAPTCHA server 144 | * 145 | * @param string $host 146 | * @param string $path 147 | * @param array $data 148 | * @param int port 149 | * 150 | * @return array response 151 | */ 152 | function _http_post( $host, $path, $data, $port = 80 ) { 153 | 154 | $req = $this->_encodeQS( $data ); 155 | 156 | $http_request = "POST $path HTTP/1.0\r\n"; 157 | $http_request .= "Host: $host\r\n"; 158 | $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; 159 | $http_request .= "Content-Length: " . strlen( $req ) . "\r\n"; 160 | $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; 161 | $http_request .= "\r\n"; 162 | $http_request .= $req; 163 | 164 | $response = ''; 165 | if ( false == ( $fs = @fsockopen( $host, $port, $errno, $errstr, 10 ) ) ) { 166 | die ( 'Could not open socket' ); 167 | } 168 | 169 | fwrite( $fs, $http_request ); 170 | 171 | while ( ! feof( $fs ) ) { 172 | $response .= fgets( $fs, 1160 ); 173 | } // One TCP-IP packet 174 | fclose( $fs ); 175 | $response = explode( "\r\n\r\n", $response, 2 ); 176 | 177 | return $response; 178 | } 179 | 180 | /** 181 | * Calls an HTTP POST function to verify if the user's guess was correct 182 | * 183 | * @param string $privkey 184 | * @param string $remoteip 185 | * @param string $challenge 186 | * @param string $response 187 | * @param array $extra_params an array of extra variables to post to the server 188 | * 189 | * @return ReCaptchaResponse 190 | */ 191 | function check_answer( $privkey, $remoteip, $challenge, $response, $extra_params = array() ) { 192 | if ( $privkey == null || $privkey == '' ) { 193 | die ( "To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create" ); 194 | } 195 | 196 | if ( $remoteip == null || $remoteip == '' ) { 197 | die ( "For security reasons, you must pass the remote ip to reCAPTCHA" ); 198 | } 199 | 200 | 201 | //discard spam submissions 202 | if ( $challenge == null || strlen( $challenge ) == 0 || $response == null || strlen( $response ) == 0 ) { 203 | $recaptcha_response = new ReCaptchaResponse(); 204 | $recaptcha_response->is_valid = false; 205 | $recaptcha_response->error = 'incorrect-captcha-sol'; 206 | 207 | return $recaptcha_response; 208 | } 209 | 210 | $response = $this->_http_post( RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", 211 | array( 212 | 'privatekey' => $privkey, 213 | 'remoteip' => $remoteip, 214 | 'challenge' => $challenge, 215 | 'response' => $response 216 | ) + $extra_params 217 | ); 218 | 219 | $answers = explode( "\n", $response [1] ); 220 | $recaptcha_response = new ReCaptchaResponse(); 221 | 222 | if ( trim( $answers [0] ) == 'true' ) { 223 | $recaptcha_response->is_valid = true; 224 | } else { 225 | $recaptcha_response->is_valid = false; 226 | $recaptcha_response->error = $answers [1]; 227 | } 228 | 229 | return $recaptcha_response; 230 | 231 | } 232 | 233 | /** 234 | * gets a URL where the user can sign up for reCAPTCHA. If your application 235 | * has a configuration page where you enter a key, you should provide a link 236 | * using this function. 237 | * 238 | * @param string $domain The domain where the page is hosted 239 | * @param string $appname The name of your application 240 | */ 241 | function _get_signup_url( $domain = null, $appname = null ) { 242 | return "https://www.google.com/recaptcha/admin/create?" . $this->_encodeQS( array( 243 | 'domains' => $domain, 244 | 'app' => $appname 245 | ) ); 246 | } 247 | 248 | function _aes_pad( $val ) { 249 | $block_size = 16; 250 | $numpad = $block_size - ( strlen( $val ) % $block_size ); 251 | 252 | return str_pad( $val, strlen( $val ) + $numpad, chr( $numpad ) ); 253 | } 254 | 255 | /* Mailhide related code */ 256 | 257 | function _aes_encrypt( $val, $ky ) { 258 | if ( ! function_exists( "mcrypt_encrypt" ) ) { 259 | die ( "To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed." ); 260 | } 261 | $mode = MCRYPT_MODE_CBC; 262 | $enc = MCRYPT_RIJNDAEL_128; 263 | $val = $this->_aes_pad( $val ); 264 | 265 | return mcrypt_encrypt( $enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ); 266 | } 267 | 268 | 269 | function _mailhide_urlbase64( $x ) { 270 | return strtr( base64_encode( $x ), '+/', '-_' ); 271 | } 272 | 273 | /* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ 274 | function _mailhide_url( $pubkey, $privkey, $email ) { 275 | if ( $pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null ) { 276 | die ( "To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . 277 | "you can do so at http://www.google.com/recaptcha/mailhide/apikey" ); 278 | } 279 | 280 | 281 | $ky = pack( 'H*', $privkey ); 282 | $cryptmail = $this->_aes_encrypt( $email, $ky ); 283 | 284 | return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . $this->_mailhide_urlbase64( $cryptmail ); 285 | } 286 | 287 | /** 288 | * gets the parts of the email to expose to the user. 289 | * eg, given johndoe@example,com return ["john", "example.com"]. 290 | * the email is then displayed as john...@example.com 291 | */ 292 | function _mailhide_email_parts( $email ) { 293 | $arr = preg_split( "/@/", $email ); 294 | 295 | if ( strlen( $arr[0] ) <= 4 ) { 296 | $arr[0] = substr( $arr[0], 0, 1 ); 297 | } else if ( strlen( $arr[0] ) <= 6 ) { 298 | $arr[0] = substr( $arr[0], 0, 3 ); 299 | } else { 300 | $arr[0] = substr( $arr[0], 0, 4 ); 301 | } 302 | 303 | return $arr; 304 | } 305 | 306 | /** 307 | * Gets html to display an email address given a public an private key. 308 | * to get a key, go to: 309 | * 310 | * http://www.google.com/recaptcha/mailhide/apikey 311 | */ 312 | function _mailhide_html( $pubkey, $privkey, $email ) { 313 | $emailparts = $this->_mailhide_email_parts( $email ); 314 | $url = $this->_mailhide_url( $pubkey, $privkey, $email ); 315 | 316 | return htmlentities( $emailparts[0] ) . "...@" . htmlentities( $emailparts [1] ); 318 | 319 | } 320 | } 321 | 322 | ?> -------------------------------------------------------------------------------- /contact-form.php: -------------------------------------------------------------------------------- 1 | __CLASS__, 'description' => __( 'Contact Form', 'contact_widget' ) ); 69 | parent::__construct( __CLASS__, __( 'Contact Form', 'contact_widget' ), $widget_ops ); 70 | 71 | add_action( 'admin_print_scripts-widgets.php', array( $this, 'js_load_scripts' ) ); 72 | if ( ! is_admin() ) { 73 | add_action( 'wp_print_scripts', array( $this, 'enqueue_frontend_dependencies' ) ); 74 | } 75 | } 76 | 77 | function enqueue_frontend_dependencies() { 78 | if ( ! is_active_widget( false, false, $this->id_base ) ) { 79 | return false; 80 | } 81 | if ( ! defined( 'CW_SCRIPT_INCLUDED' ) ) { 82 | wp_enqueue_script( 'contact-form', plugins_url( '/scripts/js/global.js', __FILE__ ), array( 'jquery' ) ); 83 | define( 'CW_SCRIPT_INCLUDED', true, true ); 84 | } 85 | if ( ! defined( 'CW_STYLE_INCLUDED' ) ) { 86 | wp_enqueue_style( 'contact-form', plugins_url( '/style.css', __FILE__ ) ); 87 | define( 'CW_STYLE_INCLUDED', true, true ); 88 | } 89 | } 90 | 91 | function js_load_scripts() { 92 | wp_enqueue_script( 'contact_widget-admin', plugins_url( '/scripts/js/admin.js', __FILE__ ), array( 'jquery' ) ); 93 | } 94 | 95 | public static function register() { 96 | register_widget( __CLASS__ ); 97 | } 98 | 99 | public static function get_instance_data( $instance_id ) { 100 | $instances = get_option( 'widget_' . __CLASS__ ); 101 | $data = isset( $instances[ $instance_id ] ) ? $instances[ $instance_id ] : array(); 102 | 103 | return $data; 104 | } 105 | 106 | /** 107 | * Outputs the options form on admin 108 | * 109 | * @param array $instance The widget options 110 | */ 111 | function form( $instance ) { 112 | $data = $this->_get_data( $instance ); 113 | extract( $data ); 114 | 115 | $hostname = preg_replace( '/^www\./', '', parse_url( site_url(), PHP_URL_HOST ) ); 116 | $captcha = ( $contact_form_captcha == 'on' ) ? 'checked="checked"' : ''; 117 | $compact_mode = ( $contact_form_compact == 'on' ) ? 'checked="checked"' : ''; 118 | $contact_form_generic_from = ( $contact_form_generic_from == 'on' ) ? 'checked="checked"' : ''; 119 | $contact_form_generic_from_reply_to = ( $contact_form_generic_from_reply_to == 'on' ) ? 'checked="checked"' : ''; 120 | $contact_form_generic_from_body = ( $contact_form_generic_from_body == 'on' ) ? 'checked="checked"' : ''; 121 | ?> 122 |

123 |
124 | 125 |

126 |

127 |
128 | 129 |

130 |

131 |
132 | 133 |

134 |

135 |
136 | 137 | /> 138 | 139 |
140 | 152 |

153 |

154 |
155 | 156 |

157 |

158 |
159 | 160 |

161 |

162 |
163 | 164 |

165 |

166 |
167 | 168 |

169 |

170 |
171 | 172 |

173 |

174 |
175 | 176 |

177 |

178 | 179 |
180 | 181 | /> 182 |
183 |

not be protected until you set up the API keys.', 'contact_widget' ); ?>
192 | 193 |
194 | 195 | 196 |
197 | 198 | 199 |
200 | 201 |

202 |
203 |

204 | 205 |
206 | 210 |
211 | 215 |

216 |
217 |
218 |

219 | 220 | 221 |

222 | 223 |

224 | 225 | 226 |
227 | 228 |

229 |

230 | 231 | 232 |

233 |
234 |
235 |

236 | 237 |
238 | 242 |
243 | 247 |

248 | 249 |

250 | 251 |
252 | 256 |
257 | 261 |

262 |
263 |

264 | 265 |
266 | 267 | /> 268 |

269 | $value ) { 281 | $instance[ $key ] = in_array( $key, $this->_kses ) ? wp_kses_post( $value ) : strip_tags( $value ); 282 | if ( $key == 'contact_form_private_key' ) { 283 | update_option( 'wpmu_contact_form_private_key', $value ); 284 | } elseif ( $key == 'contact_form_recaptcha_version' ) { 285 | update_option( 'wpmu_contact_form_recaptcha_version', $value ); 286 | } 287 | } 288 | 289 | return $this->_get_data( $instance ); 290 | } 291 | 292 | /** 293 | * Outputs the content of the widget 294 | * 295 | * @param array $args 296 | * @param array $instance 297 | */ 298 | function widget( $args, $instance ) { 299 | $data = $this->_get_data( $instance ); 300 | $cw_uniqid = md5( serialize( $data ) . uniqid() ); 301 | extract( $data ); 302 | $contact_form_refresh_message = ! empty( $contact_form_refresh_message ) ? $contact_form_refresh_message : __( 'Click to refresh', 'contact_widget' ); 303 | $contact_form_refresh_link = ! empty( $contact_form_refresh_link ) ? $contact_form_refresh_link : __( 'Reload Captcha', 'contact_widget' ); 304 | $contact_form_submit_label = ! empty( $contact_form_submit_label ) ? $contact_form_submit_label : $data['contact_form_submit_label']; 305 | $contact_form_response_field = ! empty( $contact_form_response_field ) ? $contact_form_response_field : __( 'Type the characters you see in image above', 'contact_widget' ); 306 | $contact_form_recaptcha_version = ! empty( $contact_form_recaptcha_version ) ? $contact_form_recaptcha_version : 'old'; 307 | $contact_form_recaptcha_theme = ! empty( $contact_form_recaptcha_theme ) ? $contact_form_recaptcha_theme : 'light'; 308 | $contact_form_recaptcha_type = ! empty( $contact_form_recaptcha_type ) ? $contact_form_recaptcha_type : 'image'; 309 | 310 | $contact_form_compact = ( 'on' == $contact_form_compact ) ? 1 : 0; 311 | $contact_form_captcha = ( 'on' == $contact_form_captcha ) ? 1 : 0; 312 | $publickey = $contact_form_public_key; 313 | //Reduce number of rows for textare in 2013 314 | $theme = wp_get_theme(); 315 | $rows = 5; 316 | $cols = 25; 317 | if ( trim( $theme ) == 'Twenty Thirteen' ) { 318 | $rows = 2; 319 | $cols = 20; 320 | } 321 | 322 | $plugin_dir = rtrim( dirname( __FILE__ ), '/' ) . '/'; 323 | echo $args['before_widget']; 324 | echo $args['before_title'] . esc_html( $contact_form_widget_title ) . $args['after_title']; 325 | ?> 326 | 329 | 330 | 331 | 335 | 336 | 337 | 341 | 342 | 345 | 346 |
347 |
348 | 349 |
350 | 351 |
352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 |
360 | 361 | 362 | 363 | 364 |
365 | 366 | 367 | 368 | 369 | 370 |
371 | 372 | 373 | 381 | 382 | 389 | 405 |
407 |
408 |
409 | 410 |
412 | 413 | 414 |
415 |
416 | __( 'Contact Form', 'contact_widget' ), 426 | 'contact_form_subject_label' => __( 'Subject', 'contact_widget' ), 427 | 'contact_form_from_label' => __( 'From', 'contact_widget' ), 428 | 'contact_form_message_label' => __( 'Message', 'contact_widget' ), 429 | 'contact_form_submit_label' => __( 'Send Message', 'contact_widget' ), 430 | 'contact_form_admin_email' => get_option( 'admin_email' ), 431 | 'contact_form_success_message' => __( 'Mail sent!', 'contact_widget' ), 432 | 'contact_form_generic_from' => false, 433 | 'contact_form_generic_from_user' => 'noreply', 434 | 'contact_form_generic_from_reply_to' => '', 435 | 'contact_form_generic_from_body' => '', 436 | 'contact_form_text_after' => '', 437 | 'contact_form_custom_css' => '', 438 | 'contact_form_captcha' => 'on', 439 | 'contact_form_compact' => '', 440 | 'contact_form_refresh_message' => __( 'Click to refresh', 'contact_widget' ), 441 | 'contact_form_refresh_link' => __( 'Reload Captcha', 'contact_widget' ), 442 | 'contact_form_response_field' => __( 'Type the characters you see in image above', 'contact_widget' ), 443 | 'contact_form_public_key' => '', 444 | 'contact_form_private_key' => '', 445 | 'contact_form_recaptcha_version' => 'old', 446 | 'contact_form_recaptcha_theme' => 'light', 447 | 'contact_form_recaptcha_type' => 'image', 448 | ) 449 | ); 450 | } 451 | 452 | } // End class 453 | 454 | //Register WPMU Dev Notification 455 | if ( is_admin() && file_exists( WC_PLUGIN_BASE_DIR . '/dash-notice/wpmudev-dash-notification.php' ) ) { 456 | // Dashboard notification 457 | global $wpmudev_notices; 458 | if ( ! is_array( $wpmudev_notices ) ) { 459 | $wpmudev_notices = array(); 460 | } 461 | $wpmudev_notices[] = array( 462 | 'id' => 151, 463 | 'name' => 'Contact Form' 464 | ); 465 | require_once WC_PLUGIN_BASE_DIR . '/dash-notice/wpmudev-dash-notification.php'; 466 | } 467 | --------------------------------------------------------------------------------