File indexing completed on 2024-12-22 05:36:18
0001 <?php 0002 namespace Cgsmith\Validate; 0003 0004 /** 0005 * Class Recaptcha 0006 * Handle validation against Google API 0007 * 0008 * @package Cgsmith 0009 * @license MIT 0010 * @author Chris Smith 0011 * @link https://github.com/google/recaptcha 0012 */ 0013 class Recaptcha extends \Zend_Validate_Abstract 0014 { 0015 /** @var string secret key */ 0016 protected $_secretKey; 0017 0018 /** @const string invalid captcha */ 0019 const INVALID_CAPTCHA = 'invalidCaptcha'; 0020 0021 /** @const string invalid captcha */ 0022 const CAPTCHA_EMPTY = 'captchaEmpty'; 0023 0024 /** @const string URL to where requests are posted */ 0025 const SITE_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify'; 0026 0027 /** @const string http method for communicating with google */ 0028 const POST_METHOD = 'POST'; 0029 0030 /** @const string peer key for communication */ 0031 const PEER_KEY = 'www.google.com'; 0032 0033 /** @const string default name for captcha result in $_POST array */ 0034 const CAPTCHA_NAME = 'g-recaptcha-response'; 0035 0036 protected $_messageTemplates = array( 0037 self::INVALID_CAPTCHA => 'The captcha was invalid', 0038 self::CAPTCHA_EMPTY => 'The captcha must be completed' 0039 ); 0040 0041 /** 0042 * @param $options 0043 */ 0044 public function __construct($options) { 0045 $this->_secretKey = $options['secretKey']; 0046 } 0047 0048 /** 0049 * Validate our form's element 0050 * 0051 * @param mixed $value 0052 * @param null $context 0053 * @return bool 0054 */ 0055 public function isValid($value, $context = null) 0056 { 0057 if (empty($value) AND (false == isset($context[self::CAPTCHA_NAME]))) { 0058 $this->_error(self::CAPTCHA_EMPTY); 0059 return false; 0060 } 0061 0062 if (empty($value)) { 0063 $this->_value = $context[self::CAPTCHA_NAME]; 0064 } else { 0065 $this->_value = $value; 0066 } 0067 0068 if (false == $this->_verify($this->_value)) { 0069 $this->_error(self::INVALID_CAPTCHA); 0070 return false; 0071 } 0072 0073 return true; 0074 } 0075 0076 /** 0077 * Calls the reCAPTCHA siteverify API to verify whether the user passes the captcha test. 0078 * 0079 * @param mixed $value 0080 * @return boolean 0081 * @link https://github.com/google/recaptcha 0082 */ 0083 protected function _verify($value) 0084 { 0085 $queryString = http_build_query(array( 0086 'secret' => $this->_secretKey, 0087 'response' => $value, 0088 'remoteIp' => $_SERVER['REMOTE_ADDR'] 0089 )); 0090 0091 /** 0092 * PHP 5.6.0 changed the way you specify the peer name for SSL context options. 0093 * Using "CN_name" will still work, but it will raise deprecated errors. 0094 */ 0095 $peerKey = version_compare(PHP_VERSION, '5.6.0', '<') ? 'CN_name' : 'peer_name'; 0096 $context = stream_context_create(array( 0097 'http' => array( 0098 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 0099 'method' => self::POST_METHOD, 0100 'content' => $queryString, 0101 'verify_peer' => true, 0102 $peerKey => self::PEER_KEY 0103 ) 0104 )); 0105 $jsonObject = json_decode(file_get_contents(self::SITE_VERIFY_URL,false,$context)); 0106 0107 return $jsonObject->success; 0108 } 0109 }