pictcode / app / Plugin / Recaptcha / View / Helper / RecaptchaHelper.php @ 787484d2
履歴 | 表示 | アノテート | ダウンロード (7.615 KB)
| 1 | 
      <?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 | 
      }  |