Author: garak
Date: 2010-04-07 14:36:06 +0200 (Wed, 07 Apr 2010)
New Revision: 29030

Added:
   plugins/sfReCaptchaPlugin/branches/
   plugins/sfReCaptchaPlugin/branches/1.1/
   plugins/sfReCaptchaPlugin/branches/1.1/LICENSE
   plugins/sfReCaptchaPlugin/branches/1.1/README
   plugins/sfReCaptchaPlugin/branches/1.1/lib/
   plugins/sfReCaptchaPlugin/branches/1.1/lib/form/
   plugins/sfReCaptchaPlugin/branches/1.1/lib/form/reCaptchaForm.class.php
   plugins/sfReCaptchaPlugin/branches/1.1/lib/helper/
   plugins/sfReCaptchaPlugin/branches/1.1/lib/helper/recaptchaHelper.php
   plugins/sfReCaptchaPlugin/branches/1.1/lib/recaptchalib.php
   plugins/sfReCaptchaPlugin/branches/1.1/lib/validator/
   
plugins/sfReCaptchaPlugin/branches/1.1/lib/validator/sfValidatorSchemaReCaptcha.class.php
   plugins/sfReCaptchaPlugin/branches/1.1/modules/
   plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/
   plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/actions/
   
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/actions/actions.class.php
   plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/templates/
   
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/templates/indexSuccess.php
   
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/templates/mailhideSuccess.php
   plugins/sfReCaptchaPlugin/branches/1.3/
   plugins/sfReCaptchaPlugin/branches/1.3/LICENSE
   plugins/sfReCaptchaPlugin/branches/1.3/README
   plugins/sfReCaptchaPlugin/branches/1.3/lib/
   plugins/sfReCaptchaPlugin/branches/1.3/lib/form/
   plugins/sfReCaptchaPlugin/branches/1.3/lib/form/reCaptchaForm.class.php
   plugins/sfReCaptchaPlugin/branches/1.3/lib/helper/
   plugins/sfReCaptchaPlugin/branches/1.3/lib/helper/recaptchaHelper.php
   plugins/sfReCaptchaPlugin/branches/1.3/lib/validator/
   
plugins/sfReCaptchaPlugin/branches/1.3/lib/validator/sfValidatorSchemaReCaptcha.class.php
   plugins/sfReCaptchaPlugin/branches/1.3/modules/
   plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/
   plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/actions/
   
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/actions/actions.class.php
   plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/templates/
   
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/templates/indexSuccess.php
   
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/templates/mailhideSuccess.php
Log:
[sfReCaptchaPlugin] added 1.1 and 1.3 branches


Added: plugins/sfReCaptchaPlugin/branches/1.1/LICENSE
===================================================================
--- plugins/sfReCaptchaPlugin/branches/1.1/LICENSE                              
(rev 0)
+++ plugins/sfReCaptchaPlugin/branches/1.1/LICENSE      2010-04-07 12:36:06 UTC 
(rev 29030)
@@ -0,0 +1,19 @@
+Copyright (c) 2008 Arthur Koziel <[email protected]>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file

Added: plugins/sfReCaptchaPlugin/branches/1.1/README
===================================================================
--- plugins/sfReCaptchaPlugin/branches/1.1/README                               
(rev 0)
+++ plugins/sfReCaptchaPlugin/branches/1.1/README       2010-04-07 12:36:06 UTC 
(rev 29030)
@@ -0,0 +1 @@
+For more information about the reCaptchaPlugin, navigate to 
http://trac.symfony-project.com/wiki/sfReCaptchaPlugin
\ No newline at end of file

Added: plugins/sfReCaptchaPlugin/branches/1.1/lib/form/reCaptchaForm.class.php
===================================================================
--- plugins/sfReCaptchaPlugin/branches/1.1/lib/form/reCaptchaForm.class.php     
                        (rev 0)
+++ plugins/sfReCaptchaPlugin/branches/1.1/lib/form/reCaptchaForm.class.php     
2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,16 @@
+<?php
+
+class reCaptchaForm extends sfForm
+{      
+       public function configure()
+       {
+               $this->setWidgets(array('response' => new sfWidgetFormInput()));
+               
+               $this->validatorSchema->setPostValidator(
+                       new sfValidatorSchemaReCaptcha('challenge', 'response')
+               );
+               
+               $this->validatorSchema->setOption('allow_extra_fields', true);
+               $this->validatorSchema->setOption('filter_extra_fields', false);
+       }
+}

Added: plugins/sfReCaptchaPlugin/branches/1.1/lib/helper/recaptchaHelper.php
===================================================================
--- plugins/sfReCaptchaPlugin/branches/1.1/lib/helper/recaptchaHelper.php       
                        (rev 0)
+++ plugins/sfReCaptchaPlugin/branches/1.1/lib/helper/recaptchaHelper.php       
2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,3 @@
+<?php
+
+require_once 
(sfConfig::get('sf_plugins_dir').'/sfReCaptchaPlugin/lib/recaptchalib.php');

Added: plugins/sfReCaptchaPlugin/branches/1.1/lib/recaptchalib.php
===================================================================
--- plugins/sfReCaptchaPlugin/branches/1.1/lib/recaptchalib.php                 
        (rev 0)
+++ plugins/sfReCaptchaPlugin/branches/1.1/lib/recaptchalib.php 2010-04-07 
12:36:06 UTC (rev 29030)
@@ -0,0 +1,277 @@
+<?php
+/*
+ * This is a PHP library that handles calling reCAPTCHA.
+ *    - Documentation and latest version
+ *          http://recaptcha.net/plugins/php/
+ *    - Get a reCAPTCHA API Key
+ *          http://recaptcha.net/api/getkey
+ *    - Discussion group
+ *          http://groups.google.com/group/recaptcha
+ *
+ * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
+ * AUTHORS:
+ *   Mike Crawford
+ *   Ben Maurer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * The reCAPTCHA server URL's
+ */
+define("RECAPTCHA_API_SERVER", "http://api.recaptcha.net";);
+define("RECAPTCHA_API_SECURE_SERVER", "https://api-secure.recaptcha.net";);
+define("RECAPTCHA_VERIFY_SERVER", "api-verify.recaptcha.net");
+
+/**
+ * Encodes the given data into a query string format
+ * @param $data - array of string elements to be encoded
+ * @return string - encoded request
+ */
+function _recaptcha_qsencode ($data) {
+        $req = "";
+        foreach ( $data as $key => $value )
+                $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
+
+        // Cut the last '&'
+        $req=substr($req,0,strlen($req)-1);
+        return $req;
+}
+
+
+
+/**
+ * Submits an HTTP POST to a reCAPTCHA server
+ * @param string $host
+ * @param string $path
+ * @param array $data
+ * @param int port
+ * @return array response
+ */
+function _recaptcha_http_post($host, $path, $data, $port = 80) {
+
+        $req = _recaptcha_qsencode ($data);
+
+        $http_request  = "POST $path HTTP/1.0\r\n";
+        $http_request .= "Host: $host\r\n";
+        $http_request .= "Content-Type: 
application/x-www-form-urlencoded;\r\n";
+        $http_request .= "Content-Length: " . strlen($req) . "\r\n";
+        $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
+        $http_request .= "\r\n";
+        $http_request .= $req;
+
+        $response = '';
+        if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) 
{
+                die ('Could not open socket');
+        }
+
+        fwrite($fs, $http_request);
+
+        while ( !feof($fs) )
+                $response .= fgets($fs, 1160); // One TCP-IP packet
+        fclose($fs);
+        $response = explode("\r\n\r\n", $response, 2);
+
+        return $response;
+}
+
+
+
+/**
+ * Gets the challenge HTML (javascript and non-javascript version).
+ * This is called from the browser, and the resulting reCAPTCHA HTML widget
+ * is embedded within the HTML form it was called from.
+ * @param string $pubkey A public key for reCAPTCHA
+ * @param string $error The error given by reCAPTCHA (optional, default is 
null)
+ * @param boolean $use_ssl Should the request be made over ssl? (optional, 
default is false)
+
+ * @return string - The HTML to be embedded in the user's form.
+ */
+function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
+{
+       if ($pubkey == null || $pubkey == '') {
+               die ("To use reCAPTCHA you must get an API key from <a 
href='http://recaptcha.net/api/getkey'>http://recaptcha.net/api/getkey</a>");
+       }
+       
+       if ($use_ssl) {
+                $server = RECAPTCHA_API_SECURE_SERVER;
+        } else {
+                $server = RECAPTCHA_API_SERVER;
+        }
+
+        $errorpart = "";
+        if ($error) {
+           $errorpart = "&amp;error=" . $error;
+        }
+        return '<script type="text/javascript" src="'. $server . 
'/challenge?k=' . $pubkey . $errorpart . '"></script>
+
+       <noscript>
+               <iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart 
. '" height="300" width="500" frameborder="0"></iframe><br/>
+               <textarea name="recaptcha_challenge_field" rows="3" 
cols="40"></textarea>
+               <input type="hidden" name="recaptcha_response_field" 
value="manual_challenge"/>
+       </noscript>';
+}
+
+
+
+
+/**
+ * A ReCaptchaResponse is returned from recaptcha_check_answer()
+ */
+class ReCaptchaResponse {
+        var $is_valid;
+        var $error;
+}
+
+
+/**
+  * Calls an HTTP POST function to verify if the user's guess was correct
+  * @param string $privkey
+  * @param string $remoteip
+  * @param string $challenge
+  * @param string $response
+  * @param array $extra_params an array of extra variables to post to the 
server
+  * @return ReCaptchaResponse
+  */
+function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, 
$extra_params = array())
+{
+       if ($privkey == null || $privkey == '') {
+               die ("To use reCAPTCHA you must get an API key from <a 
href='http://recaptcha.net/api/getkey'>http://recaptcha.net/api/getkey</a>");
+       }
+
+       if ($remoteip == null || $remoteip == '') {
+               die ("For security reasons, you must pass the remote ip to 
reCAPTCHA");
+       }
+
+       
+       
+        //discard spam submissions
+        if ($challenge == null || strlen($challenge) == 0 || $response == null 
|| strlen($response) == 0) {
+                $recaptcha_response = new ReCaptchaResponse();
+                $recaptcha_response->is_valid = false;
+                $recaptcha_response->error = 'incorrect-captcha-sol';
+                return $recaptcha_response;
+        }
+
+        $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/verify",
+                                          array (
+                                                 'privatekey' => $privkey,
+                                                 'remoteip' => $remoteip,
+                                                 'challenge' => $challenge,
+                                                 'response' => $response
+                                                 ) + $extra_params
+                                          );
+
+        $answers = explode ("\n", $response [1]);
+        $recaptcha_response = new ReCaptchaResponse();
+
+        if (trim ($answers [0]) == 'true') {
+                $recaptcha_response->is_valid = true;
+        }
+        else {
+                $recaptcha_response->is_valid = false;
+                $recaptcha_response->error = $answers [1];
+        }
+        return $recaptcha_response;
+
+}
+
+/**
+ * gets a URL where the user can sign up for reCAPTCHA. If your application
+ * has a configuration page where you enter a key, you should provide a link
+ * using this function.
+ * @param string $domain The domain where the page is hosted
+ * @param string $appname The name of your application
+ */
+function recaptcha_get_signup_url ($domain = null, $appname = null) {
+       return "http://recaptcha.net/api/getkey?"; .  _recaptcha_qsencode (array 
('domain' => $domain, 'app' => $appname));
+}
+
+function _recaptcha_aes_pad($val) {
+       $block_size = 16;
+       $numpad = $block_size - (strlen ($val) % $block_size);
+       return str_pad($val, strlen ($val) + $numpad, chr($numpad));
+}
+
+/* Mailhide related code */
+
+function _recaptcha_aes_encrypt($val,$ky) {
+       if (! function_exists ("mcrypt_encrypt")) {
+               die ("To use reCAPTCHA Mailhide, you need to have the mcrypt 
php module installed.");
+       }
+       $mode=MCRYPT_MODE_CBC;   
+       $enc=MCRYPT_RIJNDAEL_128;
+       $val=_recaptcha_aes_pad($val);
+       return mcrypt_encrypt($enc, $ky, $val, $mode, 
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+}
+
+
+function _recaptcha_mailhide_urlbase64 ($x) {
+       return strtr(base64_encode ($x), '+/', '-_');
+}
+
+/* gets the reCAPTCHA Mailhide url for a given email, public key and private 
key */
+function recaptcha_mailhide_url($pubkey, $privkey, $email) {
+       if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == 
null) {
+               die ("To use reCAPTCHA Mailhide, you have to sign up for a 
public and private key, " .
+                    "you can do so at <a 
href='http://mailhide.recaptcha.net/apikey'>http://mailhide.recaptcha.net/apikey</a>");
+       }
+       
+
+       $ky = pack('H*', $privkey);
+       $cryptmail = _recaptcha_aes_encrypt ($email, $ky);
+       
+       return "http://mailhide.recaptcha.net/d?k="; . $pubkey . "&c=" . 
_recaptcha_mailhide_urlbase64 ($cryptmail);
+}
+
+/**
+ * gets the parts of the email to expose to the user.
+ * eg, given john...@example,com return ["john", "example.com"].
+ * the email is then displayed as [email protected]
+ */
+function _recaptcha_mailhide_email_parts ($email) {
+       $arr = preg_split("/@/", $email );
+
+       if (strlen ($arr[0]) <= 4) {
+               $arr[0] = substr ($arr[0], 0, 1);
+       } else if (strlen ($arr[0]) <= 6) {
+               $arr[0] = substr ($arr[0], 0, 3);
+       } else {
+               $arr[0] = substr ($arr[0], 0, 4);
+       }
+       return $arr;
+}
+
+/**
+ * Gets html to display an email address given a public an private key.
+ * to get a key, go to:
+ *
+ * http://mailhide.recaptcha.net/apikey
+ */
+function recaptcha_mailhide_html($pubkey, $privkey, $email) {
+       $emailparts = _recaptcha_mailhide_email_parts ($email);
+       $url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
+       
+       return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) 
.
+               "' 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]);
+
+}
+
+
+?>

Added: 
plugins/sfReCaptchaPlugin/branches/1.1/lib/validator/sfValidatorSchemaReCaptcha.class.php
===================================================================
--- 
plugins/sfReCaptchaPlugin/branches/1.1/lib/validator/sfValidatorSchemaReCaptcha.class.php
                           (rev 0)
+++ 
plugins/sfReCaptchaPlugin/branches/1.1/lib/validator/sfValidatorSchemaReCaptcha.class.php
   2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * sfValidatorSchemaReCaptcha validates a reCAPTCHA (recaptcha.net).
+ *
+ * @author Arthur Koziel <[email protected]>
+ */
+class sfValidatorSchemaReCaptcha extends sfValidatorSchema
+{
+  /**
+   * Constructor.
+   *
+   * Available options:
+   *
+   *  * challange_field:    The challange field name
+   *  * response_field:     The response field name
+   *  * throw_global_error: Whether to throw a global error (false by default) 
or an error tied to the response field
+   *
+   * @param string $challengeField The challange field name
+   * @param string $responseField The response field name
+   * @param array  $options An array of options
+   * @param array  $messages An array of error messages
+   *
+   * @see sfValidatorBase
+   */
+  public function __construct($challengeField, $responseField, $options = 
array(), $messages = array())
+  {
+    $this->addOption('challenge_field', $challengeField);
+    $this->addOption('response_field', $responseField);
+
+    $this->addOption('throw_global_error', false);
+
+    parent::__construct(null, $options, $messages);
+  }
+
+  /**
+   * @see sfValidatorBase
+   */
+  protected function doClean($values)
+  { 
+    if (!is_array($values))
+    {
+      throw new InvalidArgumentException('You must pass an array parameter to 
the clean() method');
+    }
+  
+    require_once 
(sfConfig::get('sf_plugins_dir').'/sfReCaptchaPlugin/lib/recaptchalib.php');
+  
+    $challengeValue = $values[$this->getOption('challenge_field')];
+    $responseValue = $values[$this->getOption('response_field')];
+    
+    $resp = recaptcha_check_answer (sfConfig::get('app_recaptcha_privatekey'),
+                                    $_SERVER["REMOTE_ADDR"],
+                                    $challengeValue,
+                                    $responseValue
+    );
+
+    if (!$resp->is_valid)
+    {
+      $error = new sfValidatorError($this, $resp->error, array(
+        'challenge_field'  => $this->getOption('challenge_field'),
+        'response_field' => $this->getOption('response_field')
+      ));
+      if ($this->getOption('throw_global_error'))
+      {
+        throw $error;
+      }
+
+      throw new sfValidatorErrorSchema($this, 
+        array($this->getOption('response_field') => $error)
+      );
+    }
+
+    return $values;
+  }
+
+  /**
+   * @see sfValidatorBase
+   */
+  public function asString($indent = 0)
+  {
+    throw new Exception('Unable to convert a sfValidatorSchemaReCaptcha to 
string.');
+  }
+}

Added: 
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/actions/actions.class.php
===================================================================
--- 
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/actions/actions.class.php
                          (rev 0)
+++ 
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/actions/actions.class.php
  2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * recaptcha actions.
+ *
+ * @author Arthur Koziel <[email protected]>
+ */
+class recaptchaActions extends sfActions
+{
+ /**
+  * Executes index action
+  *
+  * @param sfRequest $request A request object
+  */
+  public function executeIndex($request)
+  {
+    $this->form = new reCaptchaForm();
+
+    if ($request->isMethod('post'))
+    {  
+                       $requestData = array(
+                               'challenge' => 
$this->getRequestParameter('recaptcha_challenge_field'),
+        'response' => $this->getRequestParameter('recaptcha_response_field')
+      );
+
+                       $this->form->bind($requestData);
+                       if ($this->form->isValid()) 
+                       {
+                               // captcha is valid
+                       }
+    }
+  }
+  
+  public function executeMailhide()
+  {
+  }
+}

Added: 
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/templates/indexSuccess.php
===================================================================
--- 
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/templates/indexSuccess.php
                         (rev 0)
+++ 
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/templates/indexSuccess.php
 2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,8 @@
+<?php use_helper('recaptcha') ?>
+
+<form action="<?php echo url_for('recaptcha/index') ?>" method="POST">
+  <?php echo recaptcha_get_html(sfConfig::get('app_recaptcha_publickey'), 
+    $form['response']->getError()); ?>
+  
+  <input type="submit" />
+</form>
\ No newline at end of file

Added: 
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/templates/mailhideSuccess.php
===================================================================
--- 
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/templates/mailhideSuccess.php
                              (rev 0)
+++ 
plugins/sfReCaptchaPlugin/branches/1.1/modules/recaptcha/templates/mailhideSuccess.php
      2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,4 @@
+<?php use_helper('recaptcha'); ?>
+
+<?php echo recaptcha_mailhide_html(sfConfig::get('app_mailhide_publickey'), 
+  sfConfig::get('app_mailhide_privatekey'), "[email protected]"); ?>
\ No newline at end of file

Added: plugins/sfReCaptchaPlugin/branches/1.3/LICENSE
===================================================================
--- plugins/sfReCaptchaPlugin/branches/1.3/LICENSE                              
(rev 0)
+++ plugins/sfReCaptchaPlugin/branches/1.3/LICENSE      2010-04-07 12:36:06 UTC 
(rev 29030)
@@ -0,0 +1,19 @@
+Copyright (c) 2008 Arthur Koziel <[email protected]>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file

Added: plugins/sfReCaptchaPlugin/branches/1.3/README
===================================================================
--- plugins/sfReCaptchaPlugin/branches/1.3/README                               
(rev 0)
+++ plugins/sfReCaptchaPlugin/branches/1.3/README       2010-04-07 12:36:06 UTC 
(rev 29030)
@@ -0,0 +1,107 @@
+sfReCaptcha plugin
+==================
+
+The reCAPTCHA project takes unOCRable bits of text and uses people to decipher
+them via CAPTCHA tests.
+Answers are verified by juxtaposing deciphered texts with the undeciphered.
+By implementing reCAPTCHA you are helping digitize books.
+
+The `sfReCaptcha` plugin integrates the reCAPTCHA service in symfony.
+It comes with a custom validator as well as an example module which 
demonstrates the usage.
+
+For more information on reCAPTCHA visit 
[recaptcha.net](http://www.recaptcha.net).
+
+Installation
+------------
+
+To install the plugin, navigate to your symfony project root and run:
+
+    $ symfony plugin-install 
http://plugins.symfony-project.com/sfReCaptchaPlugin
+
+
+In order to use the reCAPTCHA or Mailhide service, you first need to sign up 
and
+get an API key.
+You can do this [here](http://recaptcha.net/api/getkey?app=php) for reCAPTCHA 
and
+[here](http://mailhide.recaptcha.net/apikey) for Mailhide.
+
+>**NOTE** If you're using a name-based virtual host like `http://jobeet`, the
+>API key registration will fail because the reCAPTCHA service doesn't identify
+>your `ServerName` as a valid URI.
+
+To handle this, simply append a `.tld` to your `ServerName` variable (e.g.
+`ServerName askeet.org`).
+
+Insert your API keys in your applications `app.yml`:
+
+    [yml]
+    all:
+      recaptcha:
+        publickey:  "foo"
+        privatekey: "bar"
+      mailhide:
+        publickey:  "foo"
+        privatekey: "bar"
+
+Example
+-------
+
+You need to enable the `recaptcha` module in your applications `settings.yml`:
+
+    [yml]
+    all:
+      .settings:
+        enabled_modules:        [default, recaptcha]
+
+and clear your cache afterwards:
+
+    $ symfony cc
+
+You can use the reCaptchaForm, like in the example provided in the example 
module.
+You can try it by navigating to:
+
+    http://foobar.com/frontend_dev.php/recaptcha
+
+or for Mailhide example, to:
+
+    http://foobar.com/frontend_dev.php/recaptcha/mailhide
+
+Anyway, since CAPTCHA is not testable, you should consider a different 
approach.
+First, define another key in your `app.yml`, under `recaptcha`:
+
+    [yml]
+    all:
+      recaptcha:
+        active:     true
+        publickey:  "foo"
+        privatekey: "bar"
+      mailhide:
+        publickey:  "foo"
+        privatekey: "bar"
+    test:
+      recaptcha:
+        active:     false
+
+Now you can put the following code in the `configure()` method of your form:
+
+    [php]
+    // reCaptcha
+    if (sfConfig::get('app_recaptcha_active', false))
+    {
+      $this->setWidget('response', new sfWidgetFormInput());
+      $this->validatorSchema->setPostValidator(
+        new sfValidatorSchemaReCaptcha('challenge', 'response')
+      );
+      $this->validatorSchema->setOption('allow_extra_fields', true);
+      $this->validatorSchema->setOption('filter_extra_fields', false);
+    }
+
+And the following code in your template:
+
+    [php]
+    <?php use_helper('recaptcha') ?>
+    [...]
+    <?php if (sfConfig::get('app_recaptcha_active', false)): ?>
+    <?php echo recaptcha_get_html(sfConfig::get('app_recaptcha_publickey'), 
$form['response']->getError()) ?>
+    <?php endif ?>
+
+So, you can safely test your forms, without worrying about CAPTCHAs.
\ No newline at end of file

Added: plugins/sfReCaptchaPlugin/branches/1.3/lib/form/reCaptchaForm.class.php
===================================================================
--- plugins/sfReCaptchaPlugin/branches/1.3/lib/form/reCaptchaForm.class.php     
                        (rev 0)
+++ plugins/sfReCaptchaPlugin/branches/1.3/lib/form/reCaptchaForm.class.php     
2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,16 @@
+<?php
+
+class reCaptchaForm extends sfForm
+{
+  public function configure()
+  {
+    $this->setWidget('response', new sfWidgetFormInput());
+
+    $this->validatorSchema->setPostValidator(
+      new sfValidatorSchemaReCaptcha('challenge', 'response')
+    );
+
+    $this->validatorSchema->setOption('allow_extra_fields', true);
+    $this->validatorSchema->setOption('filter_extra_fields', false);
+  }
+}

Added: plugins/sfReCaptchaPlugin/branches/1.3/lib/helper/recaptchaHelper.php
===================================================================
--- plugins/sfReCaptchaPlugin/branches/1.3/lib/helper/recaptchaHelper.php       
                        (rev 0)
+++ plugins/sfReCaptchaPlugin/branches/1.3/lib/helper/recaptchaHelper.php       
2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,305 @@
+<?php
+/**
+ * reCAPTCHA symfony helper.
+ * Mostly from http://recaptcha.net/plugins/php/
+ * @author Massimiliano Arione
+ *
+ *
+ * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
+ * AUTHORS:
+ *   Mike Crawford
+ *   Ben Maurer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * The reCAPTCHA server URL's
+ */
+define('RECAPTCHA_API_SERVER', 'http://api.recaptcha.net');
+define('RECAPTCHA_API_SECURE_SERVER', 'https://api-secure.recaptcha.net');
+define('RECAPTCHA_VERIFY_SERVER', 'api-verify.recaptcha.net');
+
+/**
+ * Encodes the given data into a query string format
+ * @param $data - array of string elements to be encoded
+ * @return string - encoded request
+ */
+function _recaptcha_qsencode($data)
+{
+  $req = '';
+  foreach ($data as $key => $value)
+  {
+    $req .= $key . '=' . urlencode(stripslashes($value)) . '&';
+  }
+  // Cut the last '&'
+  $req = substr($req, 0, strlen($req) - 1);
+
+  return $req;
+}
+
+/**
+ * Submits an HTTP POST to a reCAPTCHA server
+ * @param string $host
+ * @param string $path
+ * @param array $data
+ * @param int port
+ * @return array response
+ */
+function _recaptcha_http_post($host, $path, $data, $port = 80)
+{
+
+  $req = _recaptcha_qsencode($data);
+
+  $http_request  = "POST $path HTTP/1.0\r\n";
+  $http_request .= "Host: $host\r\n";
+  $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
+  $http_request .= "Content-Length: " . strlen($req) . "\r\n";
+  $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
+  $http_request .= "\r\n";
+  $http_request .= $req;
+
+  $response = '';
+  if (false == $fs = @fsockopen($host, $port, $errno, $errstr, 10))
+  {
+    die('Could not open socket');
+  }
+
+  fwrite($fs, $http_request);
+
+  while (!feof($fs))
+  {
+    $response .= fgets($fs, 1160); // One TCP-IP packet
+  }
+  fclose($fs);
+  $response = explode("\r\n\r\n", $response, 2);
+
+  return $response;
+}
+
+/**
+ * Gets the challenge HTML (javascript and non-javascript version).
+ * This is called from the browser, and the resulting reCAPTCHA HTML widget
+ * is embedded within the HTML form it was called from.
+ * @param string $pubkey A public key for reCAPTCHA
+ * @param string $error The error given by reCAPTCHA (optional, default is 
null)
+ * @param boolean $use_ssl Should the request be made over ssl? (optional, 
default is false)
+ * @param boolean $strict  use XHTML strict (avoid iframe)
+ * @return string - The HTML to be embedded in the user's form.
+ */
+function recaptcha_get_html($pubkey, $error = null, $use_ssl = false, $strict 
= false)
+{
+  if ($pubkey == null || $pubkey == '')
+  {
+    throw new Exception('To use reCAPTCHA you must get an API key from <a 
href="http://recaptcha.net/api/getkey";>http://recaptcha.net/api/getkey</a>');
+  }
+
+  if ($use_ssl)
+  {
+    $server = RECAPTCHA_API_SECURE_SERVER;
+  }
+  else
+  {
+    $server = RECAPTCHA_API_SERVER;
+  }
+
+  $errorpart = '';
+  if ($error)
+  {
+    $errorpart = '&amp;error=' . $error;
+  }
+
+  $html = '<script type="text/javascript" src="'. $server . '/challenge?k=' . 
$pubkey . $errorpart . '"></script><noscript>';
+
+  if ($strict)
+  {
+    $html .= '<div><object style="width:500px;height:300px" type="text/html" 
data="'. $server . '/noscript?k=' . $pubkey . $errorpart . '"></object>' .
+      '<textarea name="recaptcha_challenge_field" rows="3" 
cols="40"></textarea>' .
+      '<input type="hidden" name="recaptcha_response_field" 
value="manual_challenge"/></div>' .
+      '</noscript>';
+  }
+  else
+  {
+    $html .= '<iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart 
. '" height="300" width="500" frameborder="0"></iframe>' .
+      '<textarea name="recaptcha_challenge_field" rows="3" 
cols="40"></textarea>' .
+      '<input type="hidden" name="recaptcha_response_field" 
value="manual_challenge"/>' .
+      '</noscript>';
+  }
+
+  return $html;
+}
+
+
+/**
+ * A ReCaptchaResponse is returned from recaptcha_check_answer()
+ */
+class ReCaptchaResponse
+{
+  public $is_valid;
+  public $error;
+}
+
+
+/**
+  * Calls an HTTP POST function to verify if the user's guess was correct
+  * @param string $privkey
+  * @param string $remoteip
+  * @param string $challenge
+  * @param string $response
+  * @param array $extra_params an array of extra variables to post to the 
server
+  * @return ReCaptchaResponse
+  */
+function recaptcha_check_answer($privkey, $remoteip, $challenge, $response, 
$extra_params = array())
+{
+  if ($privkey == null || $privkey == '')
+  {
+    throw new Exception('To use reCAPTCHA you must get an API key from <a 
href="http://recaptcha.net/api/getkey";>http://recaptcha.net/api/getkey</a>');
+  }
+
+  if ($remoteip == null || $remoteip == '')
+  {
+    throw new Exception('For security reasons, you must pass the remote ip to 
reCAPTCHA');
+  }
+
+  //discard spam submissions
+  if ($challenge == null || strlen($challenge) == 0 || $response == null || 
strlen($response) == 0)
+  {
+    $recaptcha_response = new ReCaptchaResponse();
+    $recaptcha_response->is_valid = false;
+    $recaptcha_response->error = 'incorrect-captcha-sol';
+    return $recaptcha_response;
+  }
+
+  $response = _recaptcha_http_post(RECAPTCHA_VERIFY_SERVER, "/verify", array(
+    'privatekey' => $privkey,
+    'remoteip'   => $remoteip,
+    'challenge'  => $challenge,
+    'response'   => $response
+  ) + $extra_params);
+
+  $answers = explode("\n", $response[1]);
+  $recaptcha_response = new ReCaptchaResponse();
+
+  if (trim($answers[0]) == 'true')
+  {
+    $recaptcha_response->is_valid = true;
+  }
+  else
+  {
+    $recaptcha_response->is_valid = false;
+    $recaptcha_response->error = $answers[1];
+  }
+
+  return $recaptcha_response;
+}
+
+/**
+ * gets a URL where the user can sign up for reCAPTCHA. If your application
+ * has a configuration page where you enter a key, you should provide a link
+ * using this function.
+ * @param string $domain The domain where the page is hosted
+ * @param string $appname The name of your application
+ */
+function recaptcha_get_signup_url($domain = null, $appname = null)
+{
+  return 'http://recaptcha.net/api/getkey?' .  
_recaptcha_qsencode(array('domain' => $domain, 'app' => $appname));
+}
+
+function _recaptcha_aes_pad($val)
+{
+  $block_size = 16;
+  $numpad = $block_size - (strlen($val) % $block_size);
+
+  return str_pad($val, strlen($val) + $numpad, chr($numpad));
+}
+
+/* Mailhide related code */
+
+function _recaptcha_aes_encrypt($val,$ky)
+{
+  if (!function_exists('mcrypt_encrypt'))
+  {
+    throw new Exception('To use reCAPTCHA Mailhide, you need to have the 
mcrypt php module installed.');
+  }
+  $mode = MCRYPT_MODE_CBC;
+  $enc = MCRYPT_RIJNDAEL_128;
+  $val = _recaptcha_aes_pad($val);
+
+  return mcrypt_encrypt($enc, $ky, $val, $mode, 
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+}
+
+function _recaptcha_mailhide_urlbase64($x)
+{
+  return strtr(base64_encode($x), '+/', '-_');
+}
+
+/* gets the reCAPTCHA Mailhide url for a given email, public key and private 
key */
+function recaptcha_mailhide_url($pubkey, $privkey, $email)
+{
+  if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null)
+  {
+    throw new Exception('To use reCAPTCHA Mailhide, you have to sign up for a 
public and private key, ' .
+                        'you can do so at <a 
href="http://mailhide.recaptcha.net/apikey";>http://mailhide.recaptcha.net/apikey</a>');
+  }
+
+  $ky = pack('H*', $privkey);
+  $cryptmail = _recaptcha_aes_encrypt($email, $ky);
+
+  return 'http://mailhide.recaptcha.net/d?k=' . $pubkey . '&c=' . 
_recaptcha_mailhide_urlbase64 ($cryptmail);
+}
+
+/**
+ * gets the parts of the email to expose to the user.
+ * eg, given john...@example,com return ["john", "example.com"].
+ * the email is then displayed as [email protected]
+ */
+function _recaptcha_mailhide_email_parts($email)
+{
+  $arr = preg_split('/@/', $email);
+
+  if (strlen($arr[0]) <= 4)
+  {
+    $arr[0] = substr($arr[0], 0, 1);
+  }
+  else if (strlen($arr[0]) <= 6)
+  {
+    $arr[0] = substr($arr[0], 0, 3);
+  }
+  else
+  {
+    $arr[0] = substr($arr[0], 0, 4);
+  }
+
+  return $arr;
+}
+
+/**
+ * Gets html to display an email address given a public an private key.
+ * to get a key, go to:
+ *
+ * http://mailhide.recaptcha.net/apikey
+ */
+function recaptcha_mailhide_html($pubkey, $privkey, $email)
+{
+  $emailparts = _recaptcha_mailhide_email_parts($email);
+  $url = recaptcha_mailhide_url($pubkey, $privkey, $email);
+
+  return htmlentities($emailparts[0]) . '<a href="' . htmlentities($url) .
+    '" 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]);
+}

Added: 
plugins/sfReCaptchaPlugin/branches/1.3/lib/validator/sfValidatorSchemaReCaptcha.class.php
===================================================================
--- 
plugins/sfReCaptchaPlugin/branches/1.3/lib/validator/sfValidatorSchemaReCaptcha.class.php
                           (rev 0)
+++ 
plugins/sfReCaptchaPlugin/branches/1.3/lib/validator/sfValidatorSchemaReCaptcha.class.php
   2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * sfValidatorSchemaReCaptcha validates a reCAPTCHA (recaptcha.net).
+ *
+ * @author Arthur Koziel <[email protected]>
+ */
+class sfValidatorSchemaReCaptcha extends sfValidatorSchema
+{
+  /**
+   * Constructor.
+   *
+   * Available options:
+   *
+   *  * challange_field:    The challange field name
+   *  * response_field:     The response field name
+   *  * throw_global_error: Whether to throw a global error (false by default) 
or an error tied to the response field
+   *
+   * @param string $challengeField The challange field name
+   * @param string $responseField The response field name
+   * @param array  $options An array of options
+   * @param array  $messages An array of error messages
+   *
+   * @see sfValidatorBase
+   */
+  public function __construct($challengeField, $responseField, $options = 
array(), $messages = array())
+  {
+    $this->addOption('challenge_field', $challengeField);
+    $this->addOption('response_field', $responseField);
+
+    $this->addOption('throw_global_error', false);
+
+    parent::__construct(null, $options, $messages);
+  }
+
+  /**
+   * @see sfValidatorBase
+   */
+  protected function doClean($values)
+  {
+    if (!is_array($values))
+    {
+      throw new InvalidArgumentException('You must pass an array parameter to 
the clean() method');
+    }
+
+    sfProjectConfiguration::getActive()->loadHelpers('recaptcha');
+
+    $challengeValue = $values[$this->getOption('challenge_field')];
+    $responseValue = $values[$this->getOption('response_field')];
+
+    $resp = recaptcha_check_answer(sfConfig::get('app_recaptcha_privatekey'),
+                                   $_SERVER['REMOTE_ADDR'],
+                                   $challengeValue,
+                                   $responseValue
+    );
+
+    if (!$resp->is_valid)
+    {
+      $error = new sfValidatorError($this, $resp->error, array(
+        'challenge_field' => $this->getOption('challenge_field'),
+        'response_field'  => $this->getOption('response_field'),
+      ));
+      if ($this->getOption('throw_global_error'))
+      {
+        throw $error;
+      }
+
+      throw new sfValidatorErrorSchema($this,
+        array($this->getOption('response_field') => $error)
+      );
+    }
+
+    return $values;
+  }
+
+  /**
+   * @see sfValidatorBase
+   */
+  public function asString($indent = 0)
+  {
+    throw new Exception('Unable to convert a sfValidatorSchemaReCaptcha to 
string.');
+  }
+}

Added: 
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/actions/actions.class.php
===================================================================
--- 
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/actions/actions.class.php
                          (rev 0)
+++ 
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/actions/actions.class.php
  2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * recaptcha actions.
+ *
+ * @author Arthur Koziel <[email protected]>
+ */
+class recaptchaActions extends sfActions
+{
+  /**
+   * Executes index action
+   * @param sfRequest $request A request object
+   */
+  public function executeIndex(sfWebRequest $request)
+  {
+    $this->form = new reCaptchaForm();
+
+    if ($request->isMethod(sfWebRequest::POST))
+    {  
+      $requestData = array(
+        'challenge' => $this->getRequestParameter('recaptcha_challenge_field'),
+        'response'  => $this->getRequestParameter('recaptcha_response_field'),
+      );
+
+      $this->form->bind($requestData);
+      if ($this->form->isValid()) 
+      {
+        // captcha is valid
+      }
+    }
+  }
+  
+  public function executeMailhide()
+  {
+  }
+}

Added: 
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/templates/indexSuccess.php
===================================================================
--- 
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/templates/indexSuccess.php
                         (rev 0)
+++ 
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/templates/indexSuccess.php
 2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,6 @@
+<?php use_helper('recaptcha') ?>
+
+<form action="<?php echo url_for('recaptcha/index') ?>" method="post">
+  <?php echo recaptcha_get_html(sfConfig::get('app_recaptcha_publickey'), 
$form['response']->getError()) ?>
+  <input type="submit" />
+</form>

Added: 
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/templates/mailhideSuccess.php
===================================================================
--- 
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/templates/mailhideSuccess.php
                              (rev 0)
+++ 
plugins/sfReCaptchaPlugin/branches/1.3/modules/recaptcha/templates/mailhideSuccess.php
      2010-04-07 12:36:06 UTC (rev 29030)
@@ -0,0 +1,4 @@
+<?php use_helper('recaptcha'); ?>
+
+<?php echo recaptcha_mailhide_html(sfConfig::get('app_mailhide_publickey'), 
+  sfConfig::get('app_mailhide_privatekey'), '[email protected]') ?>

-- 
You received this message because you are subscribed to the Google Groups 
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/symfony-svn?hl=en.

Reply via email to