pictcode / app / Plugin / Recaptcha / View / Helper / RecaptchaHelper.php @ 48ae03cf
履歴 | 表示 | アノテート | ダウンロード (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 | } |