Tuesday, June 2

Hacking QContacts

For the "Contact us" portion of our sites, we use QContacts instead of the plain Joomla contact module. The main reason is because it has the ability to add more fields to the email form. However, I decided a couple things needed to be changed.

  1. It uses a captcha type field using the php secureimage stuff. We need to use something that's ADA Compliant, so I wanted to use ReCaptcha.
  2. We have a big, complex site and every page has a "Contact Webmaster" link. Although it specifically says in bold print right at the top of the form to include the link of the page you're talking about, guess how many people do. Yes, about 1%. So, I wanted to add a referring link to the email.
Luckily, the code for QContacts is pretty straightforward. There were only two files I needed to change, and one I needed to add (for the ReCaptcha).

ReCaptcha Replacement

Using the recaptcha site as a reference, first we edit the file: /components/com_qcontacts/views/contact/tmpl/default_form.php. This is the page containing the actual form (and the hardest to find the first time). I put the recaptchalib.php file into the same place the original securimage.php file was (com_qcontacts/includes/secureimage). Down near the bottom, there will be the captcha code. it starts
if ($this->params->get('captcha')) {
which the following would replace the original code:
require_once JPATH_COMPONENT . DS . 'includes' . DS . 'securimage' . DS . 'recaptchalib.php';
$publickey = "..."; // you got this from the signup page
echo recaptcha_get_html($publickey);
}
Simple enough. Now, we need to validate the user input. This is in the file com_qcontacts/models/contact.php.

Near the top (around line 40 or so) will start the function __construct(). We need to add the following line:
$this->_data->captcha = JRequest::getString('recaptcha_response_field', '', 'post');
This gets the recaptcha_response_field as a post variable from the previous page. This should replace the existing captcha line. But wait, there's more!

Farther down in the code in this same file is the function __validateInputs and in here is where the captcha is validated. We need to replace the code after
if($sc) {
With
require_once JPATH_COMPONENT . DS . 'includes' . DS . 'securimage' . DS . 'recaptchalib.php';
$privatekey = "...";
$resp = recaptcha_check_answer ($privatekey,
$_SERVER["REMOTE_ADDR"],
$_POST["recaptcha_challenge_field"],
$captcha);

if (!$resp->is_valid) {
$this->setError( JText::_('Security code was incorrect, please try again', true));
return false;
}
So, fairly simple. In the Joomla backend, when you enable captcha, it will be replaced with ReCaptcha. None of the other parameters have any effect anymore. Now for #2.

Adding Referrer

This one is much simpler. We'll start with the same file as the last one (com_qcontacts/views/contact/tmpl/default_form.php).

At the end of the form, add:
<input type="hidden" name="refer" value="<?=$_SERVER['HTTP_REFERER']?>" />
Now on the other page (com_qcontacts/models/contact.php), add a line to function __construct again:
$this->_data->refer = JRequest::getString('refer', '', 'post');
Then find a line in the email creation section. I stuck the code after the show_ip param so it'd be at the end of the email.
$body .= "\r\n\r\n" . JText::_('Referring Page').': '.$this->_data->refer;
And that's it!

2 comments:

Unknown said...

Excellent article, couldn't have added reCaptcha without it. Not being picky, just found a couple of things along the way you might want to clear up:

- the recaptchalib.php file goes in com_qcontacts/includes/secureimage, not com_qcontacts/includes.

- I found the form submission code in models/contact.php, not models/category.php.

- in contact.php the "$this->_data->captcha = ... " line you have there needs to replace or go after the existing line. Might want to make that clearer.

- missing an opening ' in the first line of the validateInputs function. "DS . recaptchalib.php' " needs to be "DS . 'recaptchalib.php' "

Unknown said...

Excellent work... you cover almost everything about Captcha Code