Skip to content

Instantly share code, notes, and snippets.

@henrikbjorn
Created May 9, 2011 10:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henrikbjorn/962347 to your computer and use it in GitHub Desktop.
Save henrikbjorn/962347 to your computer and use it in GitHub Desktop.
<?php
//...
$builder->add('recaptcha', 'recaptcha', array(
'private_key' => 'private_key_here_required',
'public_key' => 'public_key_here_required',
))
//...
<service id="form.type.recaptcha" class="Comways\GamingBundle\Form\Type\RecaptchaType" scope="request">
<tag name="form.type" alias="recaptcha" />
<argument type="service" id="request" />
</service>
{% block recaptcha_widget %}
{% spaceless %}
<script type="text/javascript">
var RecaptchaOptions = {{ widget_options|default({})|json_encode|raw }};
</script>
<script type="text/javascript" src="http://www.google.com/recaptcha/api/challenge?k={{ public_key }}"></script>
<noscript>
<iframe src="http://www.google.com/recaptcha/api/noscript?k={{ public_key }}" height="300" width="500" frameborder="0"></iframe>
{{ form_widget(form.recaptcha_challenge_field) }}
{{ form_widget(form.recaptcha_response_field) }}
</noscript>
{% endspaceless %}
{% endblock %}
<?php
namespace Comways\GamingBundle\Form\DataTransformer;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\DataTransformer\TransformationFailedException;
/**
* Transforms the request into the right fields for validating the
* recaptcha field.
*
* @author Henrik Bjornskov <henrik@bjrnskov.dk>
*/
class RecaptchaTransformer implements \Symfony\Component\Form\DataTransformerInterface
{
/**
* @var Request
*/
protected $request;
/**
* @var string
*/
protected $privateKey;
/**
* @param Request $request
* @param string $privateKey
*/
public function __construct(Request $request, $privateKey)
{
$this->request = $request;
$this->privateKey = $privateKey;
}
/**
* @param mixed $value
* @return mixed
*/
public function transform($value)
{
return $value;
}
/**
* Transforms the value from the request and validates the fields according to the api
*
* @param array $array
* @return array
*/
public function reverseTransform($array)
{
$request = $this->request->request;
$params = array(
'remoteip' => $this->request->server->get('REMOVE_ADDR', '127.0.0.1'),
'privatekey' => $this->privateKey,
'challenge' => $request->get('recaptcha_challenge_field', $array['recaptcha_challenge_field']),
'response' => $request->get('recaptcha_response_field', $array['recaptcha_response_field']),
);
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'content' => http_build_query($params),
'header' => array(
'Content-Type: application/x-www-form-urlencoded',
),
),
));
$result = file_get_contents('http://www.google.com/recaptcha/api/verify', false, $context);
if (false !== strpos($result, 'true', 0)) {
return array(
'recaptcha_response_field' => 'manual_challenge',
'recaptcha_challenge_field' => '',
);
}
throw new TransformationFailedException('The entered Recaptcha code is invalid');
}
}
<?php
namespace Comways\GamingBundle\Form\Type;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\HttpFoundation\Request;
use Comways\GamingBundle\Form\DataTransformer\RecaptchaTransformer;
/**
* A ReCaptcha type for use with Google ReCatpcha services. It embeds two fields that are used
* for manual validation and show of the widget.
*
* The DataTransformer takes the entered request information and validates them agains the
* Google Recaptcha API.
*
* example:
* $builder->add('recaptcha', 'recaptcha', array(
* 'private_key' => 'private_key_here_required',
* 'public_key' => 'public_key_here_required',
* ))
*
*
* @author Henrik Bjornskov <henrik@bjrnskov.dk>
*/
class RecaptchaType extends \Symfony\Component\Form\AbstractType
{
/**
* @var Request
*/
protected $request;
/**
* @param Request $request
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Configures the Type
*
* @param FormBuilder $builder
* @param array $options
*/
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('recaptcha_challenge_field', 'text')
->add('recaptcha_response_field', 'hidden', array(
'data' => 'manual_challenge',
))
;
$builder->prependClientTransformer(new RecaptchaTransformer($this->request, $options['private_key']));
$builder
->setAttribute('public_key', $options['public_key'])
->setAttribute('widget_options', $options['widget_options'])
;
}
/**
* Options for this type
*
* @param array $options
* @return array
*/
public function getDefaultOptions(array $options)
{
return array(
'csrf_protection' => false,
'required' => false,
'error_bubbling' => false,
'property_path' => false,
'private_key' => null,
'public_key' => null,
'widget_options' => array(),
);
}
/**
* Sets attributes for use with the renderer
*
* @param FormView $view
* @param FormInterface $form
*/
public function buildView(FormView $view, FormInterface $form)
{
$view->set('public_key', $form->getAttribute('public_key'));
$view->set('widget_options', $form->getAttribute('widget_options'));
}
/**
* Because this have property_path = null and it shouldnt be written this parent
* is a field.
*
* @return string
*/
public function getParent(array $options)
{
return 'form';
}
/**
* Used to identify the rendering block
*
* @return string
*/
public function getName()
{
return 'recaptcha';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment