Reputation: 11
I am trying to add Google Recaptcha to my custom SilverStripe form.
I have generated Google public and private keys but I do not know where to put them to show a captcha on my website.
Here is my current code:
ContactPage
class ContactPage extends Page
{
private static $db = array(
'TelCustomerSupport' => 'Varchar',
'TelProjectSupport' => 'Varchar',
'OfficeName' => 'Text',
'OfficeStreetAddress' => 'Text',
'OfficeAddressLocality' => 'Text',
'OfficePostalCode' => 'Varchar',
'OfficeMapLink' => 'Text',
'OfficeLatitude' => 'Text',
'OfficeLongitude' => 'Text',
);
public function getCMSFields()
{
$fields = parent::getCMSFields();
// Add extra fields
$fields->addFieldToTab("Root.Main", new TextField('TelCustomerSupport', 'Phone - Customer, Trade & Retail Support'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('TelProjectSupport', 'Phone - Project Support'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeName'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeStreetAddress'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeAddressLocality'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficePostalCode'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeMapLink'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeLatitude'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeLongitude'), "Content");
return $fields;
}
}
class ContactPage_Controller extends NetSuitePage_Controller
{
private static $allowed_actions = array('ContactForm');
// Generate the form
public function ContactForm()
{
// Create fields
$fields = new FieldList(
TextField::create("FirstName")->setTitle(_t('Contact.FIRSTNAME')),
TextField::create("LastName")->setTitle(_t('Contact.LASTNAME')),
EmailField::create("Email")->setTitle(_t('Contact.EMAILADDRESS')),
TextField::create("Phone")->setTitle(_t('Contact.PHONENUMBER')),
DropdownField::create('Iam', _t('Contact.IAMA'), $this->translateNetsuiteConfigArray('Contact', 'Iam')),
TextField::create("SendSubject")->setTitle(_t('Contact.SUBJECT')),
HoneyPotField::create("Subject2")->setTitle('Subject2'),
TextareaField::create("Message")->setTitle(_t('Contact.MESSAGE'))->setColumns(30)->setRows(10)
new RecaptchaField('MyCaptcha')
);
// Create actions
$submitbutton = new FormAction('doContactForm', _t('Contact.SEND'));
$submitbutton->addExtraClass('btn btn-black');
$actions = new FieldList(
$submitbutton
);
$validator = ZenValidator::create();
$validator->addRequiredFields(array('FirstName', 'LastName', 'Email', 'Phone', 'Iam', 'SendSubject', 'Message'));
$validator->setConstraint('FirstName', Constraint_length::create('max', 32));
$validator->setConstraint('LastName', Constraint_length::create('max', 32));
$validator->setConstraint('Phone', Constraint_length::create('min', 7));
$validator->setConstraint('Email', Constraint_type::create('email'));
$validator->setConstraint('Phone', Constraint_type::create('digits'));
$form = new Form($this, 'ContactForm', $fields, $actions, $validator);
$form->addExtraClass('contact-form');
$form->setFormMethod('POST', true);
return $form;
}
// Deal with form submission
public function doContactForm($data, $form)
{
$submission = new ContactFormSubmission();
$form->saveInto($submission);
$submission->write();
$data['path'] = print_r($this->refererTracker->retrieveAll(), true);
$email = new Email();
$email->setTemplate('ContactFormEmail');
$email->populateTemplate($data);
$email->setTo($this->getNetsuiteConfig('Contact', 'Emails'));
$email->setFrom("[email protected]");
$email->setSubject('[warmup.co.uk] New contact from the website');
$email->populateTemplate($data);
$email->send();
$post = $this->getNetsuiteConfig('Contact');
$post->firstname = $data['FirstName'];
$post->lastname = $data['LastName'];
$post->email = $data['Email'];
$post->phone = $data['Phone'];
$post->custentity116 = $data['Iam'];
$post->custentitysubject_contact_us = $data['SendSubject'];
$post->custentitymessage_contact_us = $data['Message'];
// Check for success
if ($this->queueNetSuitePost($post)) {
return $this->redirect(Director::get_current_page()->Link()."?success=1");
}
// Redirect back with form data and error message
Session::set('FormInfo.' . $form->FormName() . '.data', $data);
Session::set('FormInfo.'.$form->FormName().'.errors', array());
$form->sessionMessage("Netsuite error", 'bad');
return $this->redirectBack();
}
// Returns true if form submitted successfully
public function Success()
{
return isset($_REQUEST['success']) && $_REQUEST['success'] == "1";
}
public function getCurrentSubsite()
{
$subsite = Subsite::currentSubsite();
if($subsite) {
return $subsite->Title;
}
return $subsite;
}
}
ContactFormSubmission
class ContactFormSubmission extends DataObject {
private static $db = array(
'FirstName' => 'Text',
'LastName' => 'Text',
'Email' => 'Text',
'Phone' => 'Text',
'Iam' => 'Text',
'Subject' => 'Text',
'Message' => 'Text'
);
}
How do I correctly add Google Recaptcha to my form?
Upvotes: 1
Views: 2181
Reputation: 39
Add
new LiteralField('recaptcha_bubble', '<div id="recaptcha_bubble" class="field"></div>')
in your forms field list Then add the google javascript with
Requirements::javascript("https://www.google.com/recaptcha/api.js?onload=recaptchaCallback&render=explicit&hl=en-GB");
After that add the function to your javascript
var recaptchaCallback = function () {
var elementExists = document.getElementById('recaptcha_bubble');
if (null != elementExists) {
grecaptcha.render('recaptcha_bubble', {
'sitekey' : 'the site key here'
});
}};
When the form will be submitted with the variable 'g-recaptcha-response'
function getPostUrlContents($url, $fields){
$result = null;
$ch = curl_init();
$timeout = 30;
$fields_string = '';
foreach($fields as $key=>$value) {
$fields_string .= $key.'='.$value.'&';
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, rtrim($fields_string, '&'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
public function checkGoogle_recaptcha_Response($code) {
$result = $this->getPostUrlContents(
'https://www.google.com/recaptcha/api/siteverify',
array(
'secret' => urlencode('secret key here'),
'response' => urlencode($code)
)
);
if (!$result) return false;
$gResult = json_decode($result, true);
if ($gResult['success']) {
return true;
}
return false;
}
public function yourForm(SS_HTTPRequest $request) {
$vars = $request->postVars();
if (!$this->checkGoogle_recaptcha_Response($vars['g-recaptcha-response'])) {
// throw error
} else {
//not a robot, do something with request
}
}
Upvotes: 0
Reputation: 15794
We can add Google Nocaptcha to our form using the SilverStripe Nocaptcha module.
The easiest way to install this module is through composer
with the following command:
composer require undefinedoffset/silverstripe-nocaptcha
After installing the module be sure to call dev/build?flush=all
.
Next we must set the spam protector to NocaptchaProtector
through our site config.yml file, as well as set the Nocaptcha
keys.
mysite/_config/config.yml
# ...
FormSpamProtectionExtension:
default_spam_protector: NocaptchaProtector
NocaptchaField:
site_key: "YOUR_SITE_KEY"
secret_key: "YOUR_SECRET_KEY"
The keys are retrieved through Google when setting up a new Nocaptcha
account.
Make sure to call ?flush=all
after adding these settings.
We are now ready to enable spam protection on our form. To do this we simply call $form->enableSpamProtection()
in our form function:
public function ContactForm()
{
// Create fields
$fields = FieldList::create(
// ...
);
// Create actions
$actions = FieldList::create(
// ...
);
$validator = ZenValidator::create();
$form = Form::create($this, 'ContactForm', $fields, $actions, $validator);
$form->enableSpamProtection();
return $form;
}
Google Nocaptcha should now be enabled on our form.
Upvotes: 2