chrisdempsey
9/8/2014 - 2:54 PM

Sweet Captcha FormIt Hook for MODX

Sweet Captcha FormIt Hook for MODX

<?php 

/*
 * Define you SweetCaptcha credentials.
 * Don't have any? Sign up at http://sweetcaptcha.com and get them by email
 * 
 * Source: https://github.com/sweetcaptcha/sweetcaptcha-sdk-php/blob/master/sweetcaptcha.php
 *
 */

define('SWEETCAPTCHA_APP_ID', 500000); // your application id (change me)
define('SWEETCAPTCHA_KEY', 'changeme'); // your application key (change me)
define('SWEETCAPTCHA_SECRET', 'changeme'); // your application secret (change me)
define('SWEETCAPTCHA_PUBLIC_URL', 'sweetcaptcha.php'); // public http url to this file


/////==== Do not change below here ===/////

/**
 * Handles remote negotiation with Sweetcaptcha.com.
 *
 * @version 1.1.0
 * @updated November 14, 2013
 */

$sweetcaptcha = new Sweetcaptcha(
  SWEETCAPTCHA_APP_ID, 
  SWEETCAPTCHA_KEY, 
  SWEETCAPTCHA_SECRET, 
  SWEETCAPTCHA_PUBLIC_URL
);

if (isset($_POST['ajax']) and $method = $_POST['ajax']) {
  echo $sweetcaptcha->$method(isset($_POST['params']) ? $_POST['params'] : array());
}

class Sweetcaptcha {
  
  private $appid;
  private $key;
  private $secret;
  private $path;
  
  const API_URL = 'sweetcaptcha.com';
  const API_PORT = 80;
  
  function __construct($appid, $key, $secret, $path) {
    $this->appid = $appid;
    $this->key = $key;
    $this->secret = $secret;
    $this->path = $path;
  }
  
  private function api($method, $params) {
    
    $basic = array(
      'method'      => $method,
      'appid'       => $this->appid,
      'key'         => $this->key,
      'path'        => $this->path,
      'user_ip'     => $_SERVER['REMOTE_ADDR'],
      'platform'    => 'php'
    );
    
    return $this->call(array_merge(isset($params[0]) ? $params[0] : $params, $basic));
  }
  
  private function call($params) {
    $param_data = "";   
    foreach ($params as $param_name => $param_value) {
      $param_data .= urlencode($param_name) .'='. urlencode($param_value) .'&'; 
    }
    
    if (!($fs = fsockopen(self::API_URL, self::API_PORT, $errno, $errstr, 10))) {
      die ("Couldn't connect to server");
    }
    
    $req = "POST /api.php HTTP/1.0\r\n";
    $req .= "Host: ".self::API_URL."\r\n";
    $req .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $req .= "Referer: " . $_SERVER['HTTP_HOST']. "\r\n";
    $req .= "Content-Length: " . strlen($param_data) . "\r\n\r\n";
    $req .= $param_data;    
  
    $response = '';
    fwrite($fs, $req);
    
    while (!feof($fs)) {
      $response .= fgets($fs, 1160);
    }
    
    fclose($fs);
    
    $response = explode("\r\n\r\n", $response, 2);
    
    return $response[1];  
  }
  
  public function __call($method, $params) {
    return $this->api($method, $params);
  }
}

?>
<?php
/**
 * SwtCaptchaHTML
 *
 * DESCRIPTION
 *
 * This Snippet returns the HTML output of sweetcaptcha
 *
 * PROPERTIES:
 *
 * None
 *
 * USAGE:
 *
 * [[SwtCaptchaHTML]] returns date in default format
 *
 */

// require sweetcaptcha php sdk
require_once('sweetcaptcha.php');

// output sweetcaptcha html
return $sweetcaptcha->get_html();
<?php
/**
 * SwtCaptchaFormItHook
 *
 * DESCRIPTION
 *
 * This Snippet is a hook for FormIt.  It validates the submitted value for sweetcaptcha and returns true or false.
 *
 * PROPERTIES:
 *
 * None
 *
 * USAGE:
 *
 * [[!FormIt? &hooks=`SwtCaptchaFormItHook,etc,etc` &emailSubject=`subject` etc.
 *
 */

// require sweetcaptcha php sdk
require_once('sweetcaptcha.php');

if (empty($_POST)) {
	return false;
} else { 
	// validate sweetcapcha
	if (isset($_POST['sckey']) and isset($_POST['scvalue']) and $sweetcaptcha->check(array('sckey' => $_POST['sckey'], 'scvalue' => $_POST['scvalue'])) == "true") {
    		return true;
	} else {
		$modx->setPlaceholder('scerror','Anti-spam answer incorrect.');
		return false;
	}
}
Collection of code blocks to create a FormIt Hook for Sweet Captcha.

Sweet Captcha - Fun and Human Friendly Captcha: http://sweetcaptcha.com/ (requires no cost account to be set up).


01 SwtCaptchaFormItHook.php - Hook to validate Sweet Captcha
02 SwtCaptchaHTML.php - Output Sweet Captcha HTML
03 sweetcaptcha.php -  01 SwtCaptchaFormItHook.php assumes sweetcaptcha.php is in your web root directory.

Note: 03 sweetcaptcha.php requires your account credentials to be defined by updating the placeholders at the 
start of the file.

Example Usage:

[[!FormIt? &hooks=`SwtCaptchaFormItHook`]]

<form action="[[~[[*id]]]]" method="post" id="fm-enquiry">

	<h3>Anti-spam</h3>
	[[!SwtCaptchaHTML]] [[- output the sweetcaptcha HTML block ]]
	[[+scerror:notempty=`<span class="error">[[+scerror]]</span>`]] [[- placeholder for error message created by incorrect submission ]]

</form>

Notes

- The FormIt call deliberately includes only the hook property relating to sweetcaptcha, you should include any other properties
  you would normally use.
- Remember to include the [[+scerror]] placeholder shown in the example above.  You can customise the error wrapper as required
  and change the error message which is hard coded in 01 SwtCaptchaFormItHook.php because I was lazy.  You could create a new Namespace
  then create a new System Setting and change:
  
  $modx->setPlaceholder('scerror','Anti-spam answer incorrect.');
  
  to
  
  $error = $modx->getOption('error_sweetcaptcha');
  $modx->setPlaceholder('scerror', $error);