CommunityID/libs/Zend/Service/ReCaptcha.php

507 lines
12 KiB
PHP

<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Service
* @subpackage ReCaptcha
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/** @see Zend_Service_Abstract */
require_once 'Zend/Service/Abstract.php';
/** @see Zend_Json */
require_once 'Zend/Json.php';
/** @see Zend_Service_ReCaptcha_Response */
require_once 'Zend/Service/ReCaptcha/Response.php';
/**
* Zend_Service_ReCaptcha
*
* @category Zend
* @package Zend_Service
* @subpackage ReCaptcha
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: ReCaptcha.php 16971 2009-07-22 18:05:45Z mikaelkael $
*/
class Zend_Service_ReCaptcha extends Zend_Service_Abstract
{
/**
* URI to the regular API
*
* @var string
*/
const API_SERVER = 'http://api.recaptcha.net';
/**
* URI to the secure API
*
* @var string
*/
const API_SECURE_SERVER = 'https://api-secure.recaptcha.net';
/**
* URI to the verify server
*
* @var string
*/
const VERIFY_SERVER = 'http://api-verify.recaptcha.net/verify';
/**
* Public key used when displaying the captcha
*
* @var string
*/
protected $_publicKey = null;
/**
* Private key used when verifying user input
*
* @var string
*/
protected $_privateKey = null;
/**
* Ip address used when verifying user input
*
* @var string
*/
protected $_ip = null;
/**
* Parameters for the object
*
* @var array
*/
protected $_params = array(
'ssl' => false, /* Use SSL or not when generating the recaptcha */
'error' => null, /* The error message to display in the recaptcha */
'xhtml' => false /* Enable XHTML output (this will not be XHTML Strict
compliant since the IFRAME is necessary when
Javascript is disabled) */
);
/**
* Options for tailoring reCaptcha
*
* See the different options on http://recaptcha.net/apidocs/captcha/client.html
*
* @var array
*/
protected $_options = array(
'theme' => 'red',
'lang' => 'en',
);
/**
* Response from the verify server
*
* @var Zend_Service_ReCaptcha_Response
*/
protected $_response = null;
/**
* Class constructor
*
* @param string $publicKey
* @param string $privateKey
* @param array $params
* @param array $options
* @param string $ip
* @param array|Zend_Config $params
*/
public function __construct($publicKey = null, $privateKey = null,
$params = null, $options = null, $ip = null)
{
if ($publicKey !== null) {
$this->setPublicKey($publicKey);
}
if ($privateKey !== null) {
$this->setPrivateKey($privateKey);
}
if ($ip !== null) {
$this->setIp($ip);
} else if (isset($_SERVER['REMOTE_ADDR'])) {
$this->setIp($_SERVER['REMOTE_ADDR']);
}
if ($params !== null) {
$this->setParams($params);
}
if ($options !== null) {
$this->setOptions($options);
}
}
/**
* Serialize as string
*
* When the instance is used as a string it will display the recaptcha.
* Since we can't throw exceptions within this method we will trigger
* a user warning instead.
*
* @return string
*/
public function __toString()
{
try {
$return = $this->getHtml();
} catch (Exception $e) {
$return = '';
trigger_error($e->getMessage(), E_USER_WARNING);
}
return $return;
}
/**
* Set the ip property
*
* @param string $ip
* @return Zend_Service_ReCaptcha
*/
public function setIp($ip)
{
$this->_ip = $ip;
return $this;
}
/**
* Get the ip property
*
* @return string
*/
public function getIp()
{
return $this->_ip;
}
/**
* Set a single parameter
*
* @param string $key
* @param string $value
* @return Zend_Service_ReCaptcha
*/
public function setParam($key, $value)
{
$this->_params[$key] = $value;
return $this;
}
/**
* Set parameters
*
* @param array|Zend_Config $params
* @return Zend_Service_ReCaptcha
* @throws Zend_Service_ReCaptcha_Exception
*/
public function setParams($params)
{
if ($params instanceof Zend_Config) {
$params = $params->toArray();
}
if (is_array($params)) {
foreach ($params as $k => $v) {
$this->setParam($k, $v);
}
} else {
/** @see Zend_Service_ReCaptcha_Exception */
require_once 'Zend/Service/ReCaptcha/Exception.php';
throw new Zend_Service_ReCaptcha_Exception(
'Expected array or Zend_Config object'
);
}
return $this;
}
/**
* Get the parameter array
*
* @return array
*/
public function getParams()
{
return $this->_params;
}
/**
* Get a single parameter
*
* @param string $key
* @return mixed
*/
public function getParam($key)
{
return $this->_params[$key];
}
/**
* Set a single option
*
* @param string $key
* @param string $value
* @return Zend_Service_ReCaptcha
*/
public function setOption($key, $value)
{
$this->_options[$key] = $value;
return $this;
}
/**
* Set options
*
* @param array|Zend_Config $options
* @return Zend_Service_ReCaptcha
* @throws Zend_Service_ReCaptcha_Exception
*/
public function setOptions($options)
{
if ($options instanceof Zend_Config) {
$options = $options->toArray();
}
if (is_array($options)) {
foreach ($options as $k => $v) {
$this->setOption($k, $v);
}
} else {
/** @see Zend_Service_ReCaptcha_Exception */
require_once 'Zend/Service/ReCaptcha/Exception.php';
throw new Zend_Service_ReCaptcha_Exception(
'Expected array or Zend_Config object'
);
}
return $this;
}
/**
* Get the options array
*
* @return array
*/
public function getOptions()
{
return $this->_options;
}
/**
* Get a single option
*
* @param string $key
* @return mixed
*/
public function getOption($key)
{
return $this->_options[$key];
}
/**
* Get the public key
*
* @return string
*/
public function getPublicKey()
{
return $this->_publicKey;
}
/**
* Set the public key
*
* @param string $publicKey
* @return Zend_Service_ReCaptcha
*/
public function setPublicKey($publicKey)
{
$this->_publicKey = $publicKey;
return $this;
}
/**
* Get the private key
*
* @return string
*/
public function getPrivateKey()
{
return $this->_privateKey;
}
/**
* Set the private key
*
* @param string $privateKey
* @return Zend_Service_ReCaptcha
*/
public function setPrivateKey($privateKey)
{
$this->_privateKey = $privateKey;
return $this;
}
/**
* Get the HTML code for the captcha
*
* This method uses the public key to fetch a recaptcha form.
*
* @return string
* @throws Zend_Service_ReCaptcha_Exception
*/
public function getHtml()
{
if ($this->_publicKey === null) {
/** @see Zend_Service_ReCaptcha_Exception */
require_once 'Zend/Service/ReCaptcha/Exception.php';
throw new Zend_Service_ReCaptcha_Exception('Missing public key');
}
$host = self::API_SERVER;
if ((bool) $this->_params['ssl'] === true) {
$host = self::API_SECURE_SERVER;
}
$htmlBreak = '<br>';
$htmlInputClosing = '>';
if ((bool) $this->_params['xhtml'] === true) {
$htmlBreak = '<br />';
$htmlInputClosing = '/>';
}
$errorPart = '';
if (!empty($this->_params['error'])) {
$errorPart = '&error=' . urlencode($this->_params['error']);
}
$reCaptchaOptions = '';
if (!empty($this->_options)) {
$encoded = Zend_Json::encode($this->_options);
$reCaptchaOptions = <<<SCRIPT
<script type="text/javascript">
var RecaptchaOptions = {$encoded};
</script>
SCRIPT;
}
$return = $reCaptchaOptions;
$return .= <<<HTML
<script type="text/javascript"
src="{$host}/challenge?k={$this->_publicKey}{$errorPart}">
</script>
HTML;
$return .= <<<HTML
<noscript>
<iframe src="{$host}/noscript?k={$this->_publicKey}{$errorPart}"
height="300" width="500" frameborder="0"></iframe>{$htmlBreak}
<textarea name="recaptcha_challenge_field" rows="3" cols="40">
</textarea>
<input type="hidden" name="recaptcha_response_field"
value="manual_challenge"{$htmlInputClosing}
</noscript>
HTML;
return $return;
}
/**
* Post a solution to the verify server
*
* @param string $challengeField
* @param string $responseField
* @return Zend_Http_Response
* @throws Zend_Service_ReCaptcha_Exception
*/
protected function _post($challengeField, $responseField)
{
if ($this->_privateKey === null) {
/** @see Zend_Service_ReCaptcha_Exception */
require_once 'Zend/Service/ReCaptcha/Exception.php';
throw new Zend_Service_ReCaptcha_Exception('Missing private key');
}
if ($this->_ip === null) {
/** @see Zend_Service_ReCaptcha_Exception */
require_once 'Zend/Service/ReCaptcha/Exception.php';
throw new Zend_Service_ReCaptcha_Exception('Missing ip address');
}
if (empty($challengeField)) {
/** @see Zend_Service_ReCaptcha_Exception */
require_once 'Zend/Service/ReCaptcha/Exception.php';
throw new Zend_Service_ReCaptcha_Exception('Missing challenge field');
}
if (empty($responseField)) {
/** @see Zend_Service_ReCaptcha_Exception */
require_once 'Zend/Service/ReCaptcha/Exception.php';
throw new Zend_Service_ReCaptcha_Exception('Missing response field');
}
/* Fetch an instance of the http client */
$httpClient = self::getHttpClient();
$postParams = array('privatekey' => $this->_privateKey,
'remoteip' => $this->_ip,
'challenge' => $challengeField,
'response' => $responseField);
/* Make the POST and return the response */
return $httpClient->setUri(self::VERIFY_SERVER)
->setParameterPost($postParams)
->request(Zend_Http_Client::POST);
}
/**
* Verify the user input
*
* This method calls up the post method and returns a
* Zend_Service_ReCaptcha_Response object.
*
* @param string $challengeField
* @param string $responseField
* @return Zend_Service_ReCaptcha_Response
*/
public function verify($challengeField, $responseField)
{
$response = $this->_post($challengeField, $responseField);
return new Zend_Service_ReCaptcha_Response(null, null, $response);
}
}