Captcha (reCAPTCHA) для osCommerce 2.3.4 (для Contact Us, Login и Create Account pages)
1. Get your API keys at https://www.google.com/recaptcha/admin/create?app=php.
2. Copy the new file from the catalog/ folder to your osCommerce shop:
catalog/includes/functions/recaptchalib.php
3. Modify the catalog/includes/configure.php file.
Add to the end of the file:
// reCAPTCHA - start
define('RECAPTCHA_PUBLIC_KEY', 'your_public_key'); // replace your_public_key with your reCAPTCHA
public key (from the API Signup Page https://www.google.com/recaptcha/admin/create?app=php)
define('RECAPTCHA_PRIVATE_KEY', 'your_private_key'); // replace your_private_key with your
reCAPTCHA private key (from the API Signup Page https://www.google.com/recaptcha/admin/create?
app=php)
define('RECAPTCHA_THEME', 'white'); // red, white, blackglass, clean
// reCAPTCHA - end
4. Modify the catalog/includes/languages/english.php file.
Add to the end of the file:
// reCAPTCHA - start
define('RECAPTCHA_INTRO', 'Type the characters you see in the picture below.');
define('RECAPTCHA_ERROR', 'The characters you entered didn\'t match the word verification. Please
try again.');
// reCAPTCHA - end
5. Modify the catalog/includes/languages/russian.php file.
Add to the end of the file:
// reCAPTCHA - start
define('RECAPTCHA_INTRO', 'Напишите символы, которые вы видите на изображении ниже.');
define('RECAPTCHA_ERROR', 'Введенные символы не соответствуют проверочному слову. Пожалуйста, введите его снова.');
// reCAPTCHA - end
6. Modify the catalog/contact_us.php file.
Find:
require('includes/application_top.php');
Add after:
require(DIR_WS_FUNCTIONS . 'recaptchalib.php'); // reCAPTCHA
Find:
if (isset($HTTP_GET_VARS['action']) && ($HTTP_GET_VARS['action'] == 'send') && isset($HTTP_POST_VARS['formid']) && ($HTTP_POST_VARS['formid'] == $sessiontoken)) {
$error = false;
$name = tep_db_prepare_input($HTTP_POST_VARS['name']);
$email_address = tep_db_prepare_input($HTTP_POST_VARS['email']);
$enquiry = tep_db_prepare_input($HTTP_POST_VARS['enquiry']);
if (!tep_validate_email($email_address)) {
$error = true;
$messageStack->add('contact', ENTRY_EMAIL_ADDRESS_CHECK_ERROR);
}
$actionRecorder = new actionRecorder('ar_contact_us', (tep_session_is_registered('customer_id') ? $customer_id : null), $name);
if (!$actionRecorder->canPerform()) {
$error = true;
$actionRecorder->record(false);
$messageStack->add('contact', sprintf(ERROR_ACTION_RECORDER, (defined('MODULE_ACTION_RECORDER_CONTACT_US_EMAIL_MINUTES') ? (int)MODULE_ACTION_RECORDER_CONTACT_US_EMAIL_MINUTES : 15)));
}
if ($error == false) {
tep_mail(STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS, EMAIL_SUBJECT, $enquiry, $name, $email_address);
$actionRecorder->record();
tep_redirect(tep_href_link(FILENAME_CONTACT_US, 'action=success'));
}
}
Replace with:
if (isset($HTTP_GET_VARS['action']) && ($HTTP_GET_VARS['action'] == 'send') && isset($HTTP_POST_VARS['formid']) && ($HTTP_POST_VARS['formid'] == $sessiontoken)) {
$error = false;
// reCAPTCHA - start
$resp = recaptcha_check_answer(RECAPTCHA_PRIVATE_KEY, $HTTP_SERVER_VARS['REMOTE_ADDR'],
$HTTP_POST_VARS['recaptcha_challenge_field'], $HTTP_POST_VARS['recaptcha_response_field']);
if ($resp->is_valid) {
$name = tep_db_prepare_input($HTTP_POST_VARS['name']);
$email_address = tep_db_prepare_input($HTTP_POST_VARS['email']);
$enquiry = tep_db_prepare_input($HTTP_POST_VARS['enquiry']);
$subject = tep_db_prepare_input($_POST['subject']);
$phone = tep_db_prepare_input($_POST['phone']);
$date = 'Date Sent: ' . date("d M Y H:i:s");
$orders_id = tep_not_null($_POST['orders_id']) ? $_POST['orders_id'] : false;
$xipaddress = $_SERVER["REMOTE_ADDR"];
$subject = $subject ? $subject : EMAIL_SUBJECT;
if (strlen($name) < ENTRY_LAST_NAME_MIN_LENGTH) {
$error = true;
$messageStack->add('contact', ENTRY_LAST_NAME_ERROR);
}
if (strlen($enquiry) < 8) {
$error = true;
$messageStack->add('contact', ENTRY_ERROR_ENQUIRY);
}
if (!tep_validate_email($email_address)) {
$error = true;
$messageStack->add('contact', ENTRY_EMAIL_ADDRESS_CHECK_ERROR);
}
$actionRecorder = new actionRecorder('ar_contact_us', (tep_session_is_registered('customer_id') ? $customer_id : null), $name);
if (!$actionRecorder->canPerform()) {
$error = true;
$actionRecorder->record(false);
$messageStack->add('contact', sprintf(ERROR_ACTION_RECORDER, (defined('MODULE_ACTION_RECORDER_CONTACT_US_EMAIL_MINUTES') ? (int)MODULE_ACTION_RECORDER_CONTACT_US_EMAIL_MINUTES : 15)));
}
if ($error == false) {
$enquiry = MESSAGE_FROM . $name . "\n" . $date . "\n" . ($phone ? ENTRY_TELEPHONE_NUMBER . $phone . "\n" : '' ) . ($customer_id ? MAIL_CLIENT_ID . $customer_id . "\n" : '') . ($orders_id ? MAIL_ORDER_ID . $orders_id . "\n" : '') . "\n" . MAIL_IP . $xipaddress . '.' . "\n\n" . ENTRY_ENQUIRY . "\n" . $enquiry;
tep_mail(STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS, EMAIL_SUBJECT, $enquiry, $name, $email_address);
$actionRecorder->record();
tep_redirect(tep_href_link(FILENAME_CONTACT_US, 'action=success'));
}
} else {
$error = true;
$messageStack->add('contact', RECAPTCHA_ERROR);
}
}
if (!is_object($lng)) {
include(DIR_WS_CLASSES . 'language.php');
$lng = new language();
}
foreach ($lng->catalog_languages as $code => $languages) {
if ($languages['id'] == $languages_id) break;
}
// reCAPTCHA - end
Find:
<tr>
<td class="fieldKey" valign="top"><?php echo ENTRY_ENQUIRY; ?></td>
<td class="fieldValue"><?php echo tep_draw_textarea_field('enquiry', 'soft', 50, 17); ?></td>
</tr>
Add after:
<!-- reCAPTCHA - start -->
<tr>
<td></td>
<td class="fieldKey"><?php echo RECAPTCHA_INTRO; ?></td>
</tr>
<tr>
<td></td>
<td><?php echo recaptcha_get_html(RECAPTCHA_PUBLIC_KEY); ?></td>
</tr>
<!-- reCAPTCHA - end -->
7. Modify the catalog/includes/template_top.php file.
Find:
<link rel="stylesheet" type="text/css" href="stylesheet.css" />
Add after:
<!-- reCAPTCHA - start -->
<script type="text/javascript">
var RecaptchaOptions = { theme : '<?php echo RECAPTCHA_THEME ?>', lang : '<?php echo in_array($code,
array('en', 'nl', 'fr', 'de', 'pt', 'ru', 'es', 'tr')) ? $code : 'en' ?>' };
</script>
<!-- reCAPTCHA - end -->
8.1. Modify the catalog/login.php file.
Find:
require('includes/application_top.php');
Add after:
require(DIR_WS_FUNCTIONS . 'recaptchalib.php'); // reCAPTCHA
Find:
require(DIR_WS_LANGUAGES . $language . '/' . FILENAME_LOGIN);
Add after:
// reCAPTCHA - start
if (!is_object($lng)) {
//include(DIR_WS_CLASSES . 'language.php');
$lng = new language();
}
foreach ($lng->catalog_languages as $code => $languages) {
if ($languages['id'] == $languages_id) break;
}
// reCAPTCHA - end
Find:
$('#loginModules .contentContainer').each(function(index, element) {
login_modules_counter++;
if ( login_modules_counter == 1 ) {
if ( $(this).hasClass('grid_8') && ((index+1) != login_modules_total) ) {
$(this).addClass('alpha');
} else {
login_modules_counter = 0;
}
} else {
if ( $(this).hasClass('grid_8') ) {
$(this).addClass('omega');
}
login_modules_counter = 0;
}
});
Replace with:
$('#loginModules .contentContainer').each(function(index, element) {
login_modules_counter++;
if ( login_modules_counter == 1 ) {
if ( $(this).hasClass('grid_8') && ((index+1) != login_modules_total) ) {
$(this).addClass('alpha');
$(this).css('width', '52%');
} else {
login_modules_counter = 0;
}
} else {
if ( $(this).hasClass('grid_8') ) {
$(this).addClass('omega');
$(this).css('width', '46%');
}
login_modules_counter = 0;
}
});
8.2 Modify the catalog/includes/modules/content/login/cm_login_form.php file.
Find:
function execute() {
global $HTTP_GET_VARS, $HTTP_POST_VARS, $sessiontoken, $login_customer_id, $messageStack, $oscTemplate;
$error = false;
if (isset($HTTP_GET_VARS['action']) && ($HTTP_GET_VARS['action'] == 'process') && isset($HTTP_POST_VARS['formid']) && ($HTTP_POST_VARS['formid'] == $sessiontoken)) {
$email_address = tep_db_prepare_input($HTTP_POST_VARS['email_address']);
$password = tep_db_prepare_input($HTTP_POST_VARS['password']);
// Check if email exists
$customer_query = tep_db_query("select customers_id, customers_password from " . TABLE_CUSTOMERS . " where customers_email_address = '" . tep_db_input($email_address) . "' limit 1");
if (!tep_db_num_rows($customer_query)) {
$error = true;
} else {
$customer = tep_db_fetch_array($customer_query);
// Check that password is good
if (!tep_validate_password($password, $customer['customers_password'])) {
$error = true;
} else {
// set $login_customer_id globally and perform post login code in catalog/login.php
$login_customer_id = (int)$customer['customers_id'];
// migrate old hashed password to new phpass password
if (tep_password_type($customer['customers_password']) != 'phpass') {
tep_db_query("update " . TABLE_CUSTOMERS . " set customers_password = '" . tep_encrypt_password($password) . "' where customers_id = '" . (int)$login_customer_id . "'");
}
}
}
}
if ($error == true) {
$messageStack->add('login', MODULE_CONTENT_LOGIN_TEXT_LOGIN_ERROR);
}
ob_start();
include(DIR_WS_MODULES . 'content/' . $this->group . '/templates/login_form.php');
$template = ob_get_clean();
$oscTemplate->addContent($template, $this->group);
}
Replace with:
function execute() {
global $HTTP_GET_VARS, $HTTP_POST_VARS, $sessiontoken, $login_customer_id, $messageStack, $oscTemplate;
$error = false;
if (isset($HTTP_GET_VARS['action']) && ($HTTP_GET_VARS['action'] == 'process') && isset($HTTP_POST_VARS['formid']) && ($HTTP_POST_VARS['formid'] == $sessiontoken)) {
// reCAPTCHA - start
$resp = recaptcha_check_answer(RECAPTCHA_PRIVATE_KEY, tep_get_ip_address(),
$HTTP_POST_VARS['recaptcha_challenge_field'], $HTTP_POST_VARS['recaptcha_response_field']);
if ($resp->is_valid) {
$email_address = tep_db_prepare_input($HTTP_POST_VARS['email_address']);
$password = tep_db_prepare_input($HTTP_POST_VARS['password']);
// Check if email exists
$customer_query = tep_db_query("select customers_id, customers_password from " . TABLE_CUSTOMERS . " where customers_email_address = '" . tep_db_input($email_address) . "' limit 1");
if (!tep_db_num_rows($customer_query)) {
$error = true;
} else {
$customer = tep_db_fetch_array($customer_query);
// Check that password is good
if (!tep_validate_password($password, $customer['customers_password'])) {
$error = true;
} else {
// set $login_customer_id globally and perform post login code in catalog/login.php
$login_customer_id = (int)$customer['customers_id'];
// migrate old hashed password to new phpass password
if (tep_password_type($customer['customers_password']) != 'phpass') {
tep_db_query("update " . TABLE_CUSTOMERS . " set customers_password = '" . tep_encrypt_password($password) . "' where customers_id = '" . (int)$login_customer_id . "'");
}
}
}
} else {
$error = true;
}
}
if ($error == true) {
if ($resp->is_valid) {
$messageStack->add('login', MODULE_CONTENT_LOGIN_TEXT_LOGIN_ERROR);
} else {
$messageStack->add('login', RECAPTCHA_ERROR);
}
}
// reCAPTCHA - end
ob_start();
include(DIR_WS_MODULES . 'content/' . $this->group . '/templates/login_form.php');
$template = ob_get_clean();
$oscTemplate->addContent($template, $this->group);
}
8.3 Modify the catalog/includes/modules/content/login/templates/login_form.php file.
Find:
<tr>
<td class="fieldKey"><?php echo ENTRY_PASSWORD; ?></td>
<td class="fieldValue"><?php echo tep_draw_password_field('password'); ?></td>
</tr>
</table>
Add after </tr>:
<!-- reCAPTCHA - start -->
<tr>
<td class="fieldKey" colspan="2"><?php echo RECAPTCHA_INTRO; ?></td>
</tr>
<!-- reCAPTCHA - end -->
Add after </table>:
<?php echo recaptcha_get_html(RECAPTCHA_PUBLIC_KEY); ?>
9. Modify the catalog/create_account.php file.
Find:
require('includes/application_top.php');
Add after:
require(DIR_WS_FUNCTIONS . 'recaptchalib.php'); // reCAPTCHA
Find:
$error = false;
Add after:
// reCAPTCHA - start
$resp = recaptcha_check_answer(RECAPTCHA_PRIVATE_KEY, $HTTP_SERVER_VARS['REMOTE_ADDR'],
$HTTP_POST_VARS['recaptcha_challenge_field'], $HTTP_POST_VARS['recaptcha_response_field']);
if (!$resp->is_valid) {
$error = true;
$messageStack->add('create_account', RECAPTCHA_ERROR);
}
// reCAPTCHA - end
Find:
tep_redirect(tep_href_link(FILENAME_CREATE_ACCOUNT_SUCCESS, '', 'SSL'));
}
}
Add after:
// reCAPTCHA - start
if (!is_object($lng)) {
include(DIR_WS_CLASSES . 'language.php');
$lng = new language();
}
foreach ($lng->catalog_languages as $code => $languages) {
f ($languages['id'] == $languages_id) break;
}
// reCAPTCHA - end
Find:
<tr>
<td class="fieldKey"><?php echo ENTRY_PASSWORD_CONFIRMATION; ?></td>
<td class="fieldValue"><?php echo tep_draw_password_field('confirmation') . ' ' . (tep_not_null(ENTRY_PASSWORD_CONFIRMATION_TEXT) ? '<span class="inputRequirement">' . ENTRY_PASSWORD_CONFIRMATION_TEXT . '</span>': ''); ?></td>
</tr>
Add after:
<!-- reCAPTCHA - start -->
<tr>
<td><?php echo tep_draw_separator('pixel_trans.gif', '100%', '10'); ?></td>
</tr>
<tr>
<td width="10%"></td>
<td class="fieldKey"><?php echo RECAPTCHA_INTRO . '<br>' .
recaptcha_get_html(RECAPTCHA_PUBLIC_KEY); ?></td>
<td width="10%"></td>
</tr>
<!-- reCAPTCHA - end -->
Создайте файл
recaptchalib.php и положите его в
/includes/functions/<?php
define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api");
define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api");
define("RECAPTCHA_VERIFY_SERVER", "www.google.com");
/**
* Encodes the given data into a query string format
* @param $data - array of string elements to be encoded
* @return string - encoded request
*/
function _recaptcha_qsencode ($data) {
$req = "";
foreach ( $data as $key => $value )
$req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
// Cut the last '&'
$req=substr($req,0,strlen($req)-1);
return $req;
}
/**
* Submits an HTTP POST to a reCAPTCHA server
* @param string $host
* @param string $path
* @param array $data
* @param int port
* @return array response
*/
function _recaptcha_http_post($host, $path, $data, $port = 80) {
$req = _recaptcha_qsencode ($data);
$http_request = "POST $path HTTP/1.0\r\n";
$http_request .= "Host: $host\r\n";
$http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
$http_request .= "Content-Length: " . strlen($req) . "\r\n";
$http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
$http_request .= "\r\n";
$http_request .= $req;
$response = '';
if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
die ('Could not open socket');
}
fwrite($fs, $http_request);
while ( !feof($fs) )
$response .= fgets($fs, 1160); // One TCP-IP packet
fclose($fs);
$response = explode("\r\n\r\n", $response, 2);
return $response;
}
/**
* Gets the challenge HTML (javascript and non-javascript version).
* This is called from the browser, and the resulting reCAPTCHA HTML widget
* is embedded within the HTML form it was called from.
* @param string $pubkey A public key for reCAPTCHA
* @param string $error The error given by reCAPTCHA (optional, default is null)
* @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)
* @return string - The HTML to be embedded in the user's form.
*/
function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
{
if ($pubkey == null || $pubkey == '') {
die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
}
if ($use_ssl) {
$server = RECAPTCHA_API_SECURE_SERVER;
} else {
$server = RECAPTCHA_API_SERVER;
}
$errorpart = "";
if ($error) {
$errorpart = "&error=" . $error;
}
return '<script type="text/javascript" src="'. $server . '/challenge?k=' . $pubkey . $errorpart . '"></script>
<noscript>
<iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
</noscript>';
}
/**
* A ReCaptchaResponse is returned from recaptcha_check_answer()
*/
class ReCaptchaResponse {
var $is_valid;
var $error;
}
/**
* Calls an HTTP POST function to verify if the user's guess was correct
* @param string $privkey
* @param string $remoteip
* @param string $challenge
* @param string $response
* @param array $extra_params an array of extra variables to post to the server
* @return ReCaptchaResponse
*/
function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
{
if ($privkey == null || $privkey == '') {
die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
}
if ($remoteip == null || $remoteip == '') {
die ("For security reasons, you must pass the remote ip to reCAPTCHA");
}
//discard spam submissions
if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
$recaptcha_response = new ReCaptchaResponse();
$recaptcha_response->is_valid = false;
$recaptcha_response->error = 'incorrect-captcha-sol';
return $recaptcha_response;
}
$response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
array (
'privatekey' => $privkey,
'remoteip' => $remoteip,
'challenge' => $challenge,
'response' => $response
) + $extra_params
);
$answers = explode ("\n", $response [1]);
$recaptcha_response = new ReCaptchaResponse();
if (trim ($answers [0]) == 'true') {
$recaptcha_response->is_valid = true;
}
else {
$recaptcha_response->is_valid = false;
$recaptcha_response->error = $answers [1];
}
return $recaptcha_response;
}
/**
* gets a URL where the user can sign up for reCAPTCHA. If your application
* has a configuration page where you enter a key, you should provide a link
* using this function.
* @param string $domain The domain where the page is hosted
* @param string $appname The name of your application
*/
function recaptcha_get_signup_url ($domain = null, $appname = null) {
return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname));
}
function _recaptcha_aes_pad($val) {
$block_size = 16;
$numpad = $block_size - (strlen ($val) % $block_size);
return str_pad($val, strlen ($val) + $numpad, chr($numpad));
}
/* Mailhide related code */
function _recaptcha_aes_encrypt($val,$ky) {
if (! function_exists ("mcrypt_encrypt")) {
die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");
}
$mode=MCRYPT_MODE_CBC;
$enc=MCRYPT_RIJNDAEL_128;
$val=_recaptcha_aes_pad($val);
return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
}
function _recaptcha_mailhide_urlbase64 ($x) {
return strtr(base64_encode ($x), '+/', '-_');
}
/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
function recaptcha_mailhide_url($pubkey, $privkey, $email) {
if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
"you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>");
}
$ky = pack('H*', $privkey);
$cryptmail = _recaptcha_aes_encrypt ($email, $ky);
return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
}
/**
* gets the parts of the email to expose to the user.
* eg, given johndoe@example,com return ["john", "example.com"].
* the email is then displayed as [email protected]
*/
function _recaptcha_mailhide_email_parts ($email) {
$arr = preg_split("/@/", $email );
if (strlen ($arr[0]) <= 4) {
$arr[0] = substr ($arr[0], 0, 1);
} else if (strlen ($arr[0]) <= 6) {
$arr[0] = substr ($arr[0], 0, 3);
} else {
$arr[0] = substr ($arr[0], 0, 4);
}
return $arr;
}
/**
* Gets html to display an email address given a public an private key.
* to get a key, go to:
*
* http://www.google.com/recaptcha/mailhide/apikey
*/
function recaptcha_mailhide_html($pubkey, $privkey, $email) {
$emailparts = _recaptcha_mailhide_email_parts ($email);
$url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) .
"' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]);
}
?>