pictcode / app / Plugin / Recaptcha / View / Helper / RecaptchaHelper.php @ b3a58ce1
履歴 | 表示 | アノテート | ダウンロード (7.615 KB)
| 1 | b3a58ce1 | hasse | <?php
 | 
      
|---|---|---|---|
| 2 | /**
 | 
      ||
| 3 |  * Copyright 2009-2014, Cake Development Corporation (http://cakedc.com)
 | 
      ||
| 4 |  *
 | 
      ||
| 5 |  * Licensed under The MIT License
 | 
      ||
| 6 |  * Redistributions of files must retain the above copyright notice.
 | 
      ||
| 7 |  *
 | 
      ||
| 8 |  * @copyright Copyright 2009-2014, Cake Development Corporation (http://cakedc.com)
 | 
      ||
| 9 |  * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
 | 
      ||
| 10 |  */
 | 
      ||
| 11 | |||
| 12 | /**
 | 
      ||
| 13 |  * CakePHP Recaptcha helper
 | 
      ||
| 14 |  *
 | 
      ||
| 15 |  * @package recaptcha
 | 
      ||
| 16 |  * @subpackage recaptcha.views.helpers
 | 
      ||
| 17 |  */
 | 
      ||
| 18 | class RecaptchaHelper extends AppHelper {  | 
      ||
| 19 | |||
| 20 | /**
 | 
      ||
| 21 |  * Secure API Url
 | 
      ||
| 22 |  *
 | 
      ||
| 23 |  * @var string
 | 
      ||
| 24 |  */
 | 
      ||
| 25 | public $secureApiUrl = 'https://www.google.com/recaptcha/api';  | 
      ||
| 26 | |||
| 27 | /**
 | 
      ||
| 28 |  * API Url
 | 
      ||
| 29 |  *
 | 
      ||
| 30 |  * @var string
 | 
      ||
| 31 |  */
 | 
      ||
| 32 | public $apiUrl = 'http://www.google.com/recaptcha/api';  | 
      ||
| 33 | |||
| 34 | /**
 | 
      ||
| 35 |  * View helpers
 | 
      ||
| 36 |  *
 | 
      ||
| 37 |  * @var array
 | 
      ||
| 38 |  */
 | 
      ||
| 39 | public $helpers = array('Form', 'Html');  | 
      ||
| 40 | |||
| 41 | /**
 | 
      ||
| 42 |  * Displays the Recaptcha input
 | 
      ||
| 43 |  *
 | 
      ||
| 44 |  * @param array $options An array of options
 | 
      ||
| 45 |  *
 | 
      ||
| 46 |  * ### Options:
 | 
      ||
| 47 |  *
 | 
      ||
| 48 |  * - `element` String, name of the view element that can be used instead of the hardcoded HTML structure from this helper
 | 
      ||
| 49 |  * - `publicKey` String, default is read from Configure::read('Recaptcha.publicKey'), you can override it here
 | 
      ||
| 50 |  * - `error` String, optional error message that is displayed using Form::error()
 | 
      ||
| 51 |  * - `ssl` Boolean, use SSL or not, default is true
 | 
      ||
| 52 |  * - `div` Array of options for the div tag the recaptcha is wrapped with, set to false if you want to disable it
 | 
      ||
| 53 |  * - `recaptchaOptions` assoc array of options to pass into RecaptchaOptions var, like 'theme', 'lang'
 | 
      ||
| 54 |  *    or 'custom_translations' to runtime configure the widget.
 | 
      ||
| 55 |  *
 | 
      ||
| 56 |  * @return string The resulting mark up
 | 
      ||
| 57 |  * @access public
 | 
      ||
| 58 |  */
 | 
      ||
| 59 | public function display($options = array()) {  | 
      ||
| 60 | $defaults = array(  | 
      ||
| 61 | 'element' => null,  | 
      ||
| 62 | 'publicKey' => Configure::read('Recaptcha.publicKey'),  | 
      ||
| 63 | 'error' => null,  | 
      ||
| 64 | 'ssl' => true,  | 
      ||
| 65 | 'error' => false,  | 
      ||
| 66 | 'div' => array(  | 
      ||
| 67 | 'class' => 'recaptcha'),  | 
      ||
| 68 | 'recaptchaOptions' => array(  | 
      ||
| 69 | 'theme' => 'red',  | 
      ||
| 70 | 'lang' => 'en',  | 
      ||
| 71 | 'custom_translations' => array()  | 
      ||
| 72 | )  | 
      ||
| 73 | );  | 
      ||
| 74 | |||
| 75 | $options = Set::merge($defaults, $options);  | 
      ||
| 76 | extract($options);  | 
      ||
| 77 | |||
| 78 | if ($ssl) {  | 
      ||
| 79 | $server = $this->secureApiUrl;  | 
      ||
| 80 |                 } else {
 | 
      ||
| 81 | $server = $this->apiUrl;  | 
      ||
| 82 | }  | 
      ||
| 83 | |||
| 84 | $errorpart = "";  | 
      ||
| 85 | if ($error) {  | 
      ||
| 86 | $errorpart = "&error=" . $error;  | 
      ||
| 87 | }  | 
      ||
| 88 | |||
| 89 | if (!empty($element)) {  | 
      ||
| 90 | $elementOptions = array();  | 
      ||
| 91 | if (is_array($element)) {  | 
      ||
| 92 | $keys = array_keys($element);  | 
      ||
| 93 | $elementOptions = $element[$keys[0]];  | 
      ||
| 94 | }  | 
      ||
| 95 | |||
| 96 | return $this->View->element($element, $elementOptions);  | 
      ||
| 97 | }  | 
      ||
| 98 | |||
| 99 | $jsonOptions = preg_replace('/"callback":"([^"\r\n]*)"/', '"callback":$1', json_encode($recaptchaOptions));  | 
      ||
| 100 | unset($recaptchaOptions);  | 
      ||
| 101 | |||
| 102 | if (empty($this->params['isAjax'])) {  | 
      ||
| 103 | $configScript = sprintf('var RecaptchaOptions = %s', $jsonOptions);  | 
      ||
| 104 | echo $this->Html->scriptBlock($configScript);  | 
      ||
| 105 | |||
| 106 | $script = '';  | 
      ||
| 107 | $script .= '<script type="text/javascript" src="' . $server . '/challenge?k=' . $publicKey . '"></script>';  | 
      ||
| 108 | $script .= '<noscript>';  | 
      ||
| 109 | $script .= ' <iframe src="' . $server . '/noscript?k=' . $publicKey . '" height="300" width="500" frameborder="0"></iframe><br/>';  | 
      ||
| 110 | $script .= ' <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>';  | 
      ||
| 111 | $script .= ' <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>';  | 
      ||
| 112 | $script .= '</noscript>';  | 
      ||
| 113 | |||
| 114 | if (!empty($error)) {  | 
      ||
| 115 | $script .= $this->Form->error($error);  | 
      ||
| 116 | }  | 
      ||
| 117 | |||
| 118 | if ($options['div'] != false) {  | 
      ||
| 119 | $script = $this->Html->tag('div', $script, $options['div']);  | 
      ||
| 120 | }  | 
      ||
| 121 | |||
| 122 | $this->Form->unlockField('recaptcha_challenge_field');  | 
      ||
| 123 | $this->Form->unlockField('recaptcha_response_field');  | 
      ||
| 124 | |||
| 125 | return $script;  | 
      ||
| 126 | }  | 
      ||
| 127 | |||
| 128 | $id = uniqid('recaptcha-');  | 
      ||
| 129 | |||
| 130 | $script = '';  | 
      ||
| 131 | $script .= '<div id="' . $id . '"></div>';  | 
      ||
| 132 | $script .= '<script>';  | 
      ||
| 133 | $script .= 'if (window.Recaptcha == undefined) {';  | 
      ||
| 134 | $script .= ' (function() {';  | 
      ||
| 135 | $script .= ' var headID = document.getElementsByTagName("head")[0];';  | 
      ||
| 136 | $script .= ' var newScript = document.createElement("script");';  | 
      ||
| 137 | $script .= ' newScript.type = "text/javascript";';  | 
      ||
| 138 | $script .= ' newScript.onload = function() {';  | 
      ||
| 139 | $script .= ' Recaptcha.create("' . $publicKey . '", "' . $id . '", ' . $jsonOptions . ');';  | 
      ||
| 140 | $script .= ' Recaptcha.focus_response_field();';  | 
      ||
| 141 | $script .= ' };';  | 
      ||
| 142 | $script .= ' newScript.src = "' . $server . '/js/recaptcha_ajax.js"';  | 
      ||
| 143 | $script .= ' headID.appendChild(newScript);';  | 
      ||
| 144 | $script .= ' })();';  | 
      ||
| 145 | $script .= '} else {';  | 
      ||
| 146 | $script .= ' setTimeout(\'Recaptcha.create("' . $publicKey . '", "' . $id . '", ' . $jsonOptions . ')\', 1000);';  | 
      ||
| 147 | $script .= '}';  | 
      ||
| 148 | $script .= '</script>';  | 
      ||
| 149 | |||
| 150 | return $script;  | 
      ||
| 151 | }  | 
      ||
| 152 | |||
| 153 | /**
 | 
      ||
| 154 |  * Recaptcha signup URL
 | 
      ||
| 155 |  *
 | 
      ||
| 156 |  * @param string $appName An application name
 | 
      ||
| 157 |  * @return string A signup url
 | 
      ||
| 158 |  */
 | 
      ||
| 159 | public function signupUrl($appName = null) {  | 
      ||
| 160 | return "http://recaptcha.net/api/getkey?domain=" . WWW_ROOT . '&app=' . urlencode($appName);  | 
      ||
| 161 | }  | 
      ||
| 162 | |||
| 163 | /**
 | 
      ||
| 164 |  * AES Pad
 | 
      ||
| 165 |  *
 | 
      ||
| 166 |  * @param string $val A value to pad
 | 
      ||
| 167 |  * @return string
 | 
      ||
| 168 |  */
 | 
      ||
| 169 | private function __aesPad($val) {  | 
      ||
| 170 | $blockSize = 16;  | 
      ||
| 171 | $numpad = $blockSize - (strlen($val) % $blockSize);  | 
      ||
| 172 | return str_pad($val, strlen($val) + $numpad, chr($numpad));  | 
      ||
| 173 | }  | 
      ||
| 174 | |||
| 175 | /**
 | 
      ||
| 176 |  * AES Encryption
 | 
      ||
| 177 |  *
 | 
      ||
| 178 |  * @param string $value A value
 | 
      ||
| 179 |  * @param string $key A key to use
 | 
      ||
| 180 |  * @return string
 | 
      ||
| 181 |  * @throws Exception
 | 
      ||
| 182 |  */
 | 
      ||
| 183 | private function __aesEncrypt($value, $key) {  | 
      ||
| 184 | if (!function_exists('mcrypt_encrypt')) {  | 
      ||
| 185 | throw new Exception(__d('recaptcha', 'To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.', true));  | 
      ||
| 186 | }  | 
      ||
| 187 | |||
| 188 | $mode = MCRYPT_MODE_CBC;  | 
      ||
| 189 | $encryption = MCRYPT_RIJNDAEL_128;  | 
      ||
| 190 | $value = $this->__aesPad($value);  | 
      ||
| 191 | |||
| 192 | return mcrypt_encrypt($encryption, $key, $value, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");  | 
      ||
| 193 | }  | 
      ||
| 194 | |||
| 195 | /**
 | 
      ||
| 196 |  * Mail-hide URL
 | 
      ||
| 197 |  *
 | 
      ||
| 198 |  * @param string $x An input string
 | 
      ||
| 199 |  * @return string A base 64 encrypted string
 | 
      ||
| 200 |  */
 | 
      ||
| 201 | private function __mailhideUrlbase64($x) {  | 
      ||
| 202 | return strtr(base64_encode($x), '+/', '-_');  | 
      ||
| 203 | }  | 
      ||
| 204 | |||
| 205 | /**
 | 
      ||
| 206 |  * Gets the reCAPTCHA Mailhide url for a given email
 | 
      ||
| 207 |  *
 | 
      ||
| 208 |  * @param string $email An email address
 | 
      ||
| 209 |  * @return string
 | 
      ||
| 210 |  * @throws Exception
 | 
      ||
| 211 |  */
 | 
      ||
| 212 | public function mailHideUrl($email = null) {  | 
      ||
| 213 | $publicKey = Configure::read('Recaptcha.mailHide.publicKey');  | 
      ||
| 214 | $privateKey = Configure::read('Recaptcha.mailHide.privateKey');  | 
      ||
| 215 | |||
| 216 | if ($publicKey == '' || $publicKey == null || $privateKey == "" || $privateKey == null) {  | 
      ||
| 217 | throw new Exception(__d('recaptcha', "You need to set a private and public mail hide key. Please visit http://mailhide.recaptcha.net/apikey", true));  | 
      ||
| 218 | }  | 
      ||
| 219 | |||
| 220 | $key = pack('H*', $privateKey);  | 
      ||
| 221 | $cryptmail = $this->__aesEncrypt($email, $key);  | 
      ||
| 222 | |||
| 223 | return "http://mailhide.recaptcha.net/d?k=" . $publicKey . "&c=" . $this->__mailhideUrlbase64($cryptmail);  | 
      ||
| 224 | }  | 
      ||
| 225 | |||
| 226 | /**
 | 
      ||
| 227 |  * Get a part of the email to show
 | 
      ||
| 228 |  *
 | 
      ||
| 229 |  * Given johndoe@example,com return ["john", "example.com"].
 | 
      ||
| 230 |  * the email is then displayed as john...@example.com
 | 
      ||
| 231 |  *
 | 
      ||
| 232 |  * @param string $email an email address
 | 
      ||
| 233 |  * @return array
 | 
      ||
| 234 |  */
 | 
      ||
| 235 | private function __hideEmailParts($email) {  | 
      ||
| 236 | $array = preg_split("/@/", $email );  | 
      ||
| 237 | |||
| 238 | if (strlen($array[0]) <= 4) {  | 
      ||
| 239 | $array[0] = substr($array[0], 0, 1);  | 
      ||
| 240 | } elseif (strlen($array[0]) <= 6) {  | 
      ||
| 241 | $array[0] = substr($array[0], 0, 3);  | 
      ||
| 242 |                 } else {
 | 
      ||
| 243 | $array[0] = substr($array[0], 0, 4);  | 
      ||
| 244 | }  | 
      ||
| 245 | return $array;  | 
      ||
| 246 | }  | 
      ||
| 247 | |||
| 248 | /**
 | 
      ||
| 249 |  * Gets html to display an email address given a public an private key to get a key go to:
 | 
      ||
| 250 |  * http://mailhide.recaptcha.net/apikey
 | 
      ||
| 251 |  *
 | 
      ||
| 252 |  * @param string $email An email address
 | 
      ||
| 253 |  * @return string
 | 
      ||
| 254 |  */
 | 
      ||
| 255 | public function mailHide($email) {  | 
      ||
| 256 | $emailparts = $this->__hideEmailParts($email);  | 
      ||
| 257 | $url = $this->mailHideUrl($email);  | 
      ||
| 258 | |||
| 259 | return htmlentities($emailparts[0]) . "<a href='" . htmlentities($url) .  | 
      ||
| 260 | "' 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]);  | 
      ||
| 261 | }  | 
      ||
| 262 | |||
| 263 | }  |