Skip to content

Commit

Permalink
Merge pull request #51 from ARCANEDEV/feature-adding_invisible_captch…
Browse files Browse the repository at this point in the history
…a_support

Adding the ability to render invisible captcha
  • Loading branch information
arcanedev-maroc committed Mar 17, 2017
2 parents 7c2bcc8 + ca67d56 commit cd5c4fe
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 68 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ reCAPTCHA comes in the form of a widget that you can easily add to your blog, fo
### Features

* Framework agnostic package.
* Invisible reCaptcha supported.
* Easy setup & configuration.
* Well documented & IDE Friendly.
* Well tested with maximum code quality.
Expand Down
1 change: 1 addition & 0 deletions _docs/0-Home.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ reCAPTCHA comes in the form of a widget that you can easily add to your blog, fo
### Features

* Framework agnostic package.
* Invisible reCaptcha supported.
* Easy setup & configuration.
* Well documented & IDE Friendly.
* Well tested with maximum code quality.
Expand Down
2 changes: 0 additions & 2 deletions _docs/1-Installation-and-Setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ For more details, check the [official documentation](https://developers.google.c

You can install this package via [Composer](http://getcomposer.org/) by running this command `composer require arcanedev/no-captcha`.

> For Laravel users, please check the [Version Compatibility](2-Version-Compatibility.md) section.
## Laravel

### Setup
Expand Down
40 changes: 40 additions & 0 deletions _docs/3-Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,44 @@ echo $captcha->script();

Check the [examples folder](https://github.com/ARCANEDEV/noCAPTCHA/tree/master/examples) for more usage details.

#### Invisible Captcha

The code below explains how to enable and customize the invisible reCAPTCHA on your webpage.

```php
require_once(__DIR__ . '/../vendor/autoload.php');

use Arcanedev\NoCaptcha\NoCaptcha;

$secret = 'your-secret-key';
$sitekey = 'your-site-key';
$captcha = new NoCaptcha($secret, $sitekey);

if ( ! empty($_POST)) {
$response = $_POST[NoCaptcha::CAPTCHA_NAME];
$result = $captcha->verify($response);

echo $result === true ? 'Yay ! You are a human.' : 'No ! You are a robot.';

exit();
}
?>

<form method="POST" id="demo-form">
<?php echo $captcha->button('Send', ['data-badge' => 'inline']); ?>
</form>

<?php echo $captcha->script(); ?>

<script>
function onSubmit(token) {
document.getElementById("demo-form").submit();
}
</script>
```

**NOTE :** You need to specify the invisible version in your captcha admin page. Check this page for more details: https://developers.google.com/recaptcha/docs/versions

### Laravel

#### Views
Expand Down Expand Up @@ -169,3 +207,5 @@ if ($validator->fails()) {
// Redirect back or throw an error
}
```

> For more advanced usage, check the [official recaptcha documentation](https://developers.google.com/recaptcha/intro).
13 changes: 12 additions & 1 deletion _docs/4-Extras.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
4. [Extras](4-Extras.md)
5. [FAQ](5-FAQ.md)

## g-recaptcha tag attributes
## [reCaptcha V2] g-recaptcha tag attributes

| Attributes | Value | Default | Description |
| --------------------- | ---------------- |:-------:| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
Expand All @@ -20,6 +20,17 @@
| data-callback | | | Optional. Your callback function that's executed when the user submits a successful CAPTCHA response. The user's response, `g-recaptcha-response`, will be the input for your callback function. |
| data-expired-callback | | | Optional. Your callback function that's executed when the recaptcha response expires and the user needs to solve a new CAPTCHA. |

## [Invisible reCaptcha] g-recaptcha tag attributes.

| Attributes | Value | Default | Description |
| ------------- | --------------------------------- |:-----------:| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| data-sitekey | | | Your sitekey |
| data-badge | bottomleft / inline / bottomright | bottomright | Optional. Reposition the reCAPTCHA badge. 'inline' allows you to control the CSS. |
| data-type | audio / image | image | Optional. The type of CAPTCHA to serve. |
| data-size | compact / normal | normal | Optional. The size of the widget. |
| data-tabindex | | | Optional. The tabindex of the widget and challenge. If other elements in your page use tabindex, it should be set to make user navigation easier. |
| data-callback | | onSubmit | Optional. Your callback function that's executed when the user submits a successful CAPTCHA response. The user's response, `g-recaptcha-response`, will be the input for your callback function. |

## Examples

Check the [examples folder](https://github.com/ARCANEDEV/noCAPTCHA/tree/master/examples) for more usage details.
31 changes: 31 additions & 0 deletions examples/invisible-captcha.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

require_once(__DIR__ . '/../vendor/autoload.php');

use Arcanedev\NoCaptcha\NoCaptcha;

$secret = 'your-secret-key';
$sitekey = 'your-site-key';
$captcha = new NoCaptcha($secret, $sitekey);

if ( ! empty($_POST)) {
$response = $_POST[NoCaptcha::CAPTCHA_NAME];
$result = $captcha->verify($response);

echo $result === true ? 'Yay ! You are a human.' : 'No ! You are a robot.';

exit();
}
?>

<form method="POST" id="demo-form">
<?php echo $captcha->button('Send'); ?>
</form>

<?php echo $captcha->script(); ?>

<script>
function onSubmit(token) {
document.getElementById("demo-form").submit();
}
</script>
10 changes: 10 additions & 0 deletions src/Contracts/NoCaptcha.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ public function image($name, array $attributes = []);
*/
public function audio($name, array $attributes = []);

/**
* Display an invisible Captcha (bind the challenge to a button).
*
* @param string $value
* @param array $attributes
*
* @return string
*/
public function button($value, array $attributes = []);

/**
* Verify Response.
*
Expand Down
1 change: 1 addition & 0 deletions src/Contracts/Utilities/AttributesInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface AttributesInterface
const ATTR_TYPE = 'data-type';
const ATTR_THEME = 'data-theme';
const ATTR_SIZE = 'data-size';
const ATTR_BADGE = 'data-badge';

/* ------------------------------------------------------------------------------------------------
| Getters & Setters
Expand Down
27 changes: 22 additions & 5 deletions src/NoCaptcha.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,12 @@ public function setAttributes(
*/
public function display($name = null, array $attributes = [])
{
$output = $this->attributes->build($this->siteKey, array_merge(
$attributes = $this->attributes->build($this->siteKey, array_merge(
$this->attributes->prepareNameAttribute($name),
$attributes
));

return '<div ' . $output . '></div>';
return '<div '.$attributes.'></div>';
}

/**
Expand Down Expand Up @@ -244,6 +244,23 @@ public function audio($name = null, array $attributes = [])
);
}

/**
* Display an invisible Captcha (bind the challenge to a button).
*
* @param string $value
* @param array $attributes
*
* @return string
*/
public function button($value, array $attributes = [])
{
$attributes = $this->attributes->build($this->siteKey, array_merge([
'data-callback' => 'onSubmit',
], $attributes));

return '<button '.$attributes.'>'.$value.'</button>';
}

/**
* Verify Response.
*
Expand Down Expand Up @@ -301,7 +318,7 @@ public function script($callbackName = null)
$script = '';

if ( ! $this->scriptLoaded) {
$script = '<script src="' . $this->getScriptSrc($callbackName) . '" async defer></script>';
$script = '<script src="'.$this->getScriptSrc($callbackName).'" async defer></script>';
$this->scriptLoaded = true;
}

Expand Down Expand Up @@ -402,7 +419,7 @@ private function checkIsString($name, $value)
{
if ( ! is_string($value)) {
throw new Exceptions\ApiException(
'The ' . $name . ' must be a string value, ' . gettype($value) . ' given'
"The {$name} must be a string value, ".gettype($value).' given.'
);
}
}
Expand All @@ -418,7 +435,7 @@ private function checkIsString($name, $value)
private function checkIsNotEmpty($name, $value)
{
if (empty($value)) {
throw new Exceptions\ApiException('The ' . $name . ' must not be empty');
throw new Exceptions\ApiException("The {$name} must not be empty");
}
}

Expand Down
11 changes: 10 additions & 1 deletion src/Utilities/Attributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ private function checkAttributes()
$this->checkTypeAttribute();
$this->checkThemeAttribute();
$this->checkSizeAttribute();
$this->checkBadgeAttribute();
}

/**
Expand All @@ -227,7 +228,15 @@ private function checkThemeAttribute()
*/
private function checkSizeAttribute()
{
$this->checkDataAttribute(self::ATTR_SIZE, 'normal', ['normal', 'compact']);
$this->checkDataAttribute(self::ATTR_SIZE, 'normal', ['normal', 'compact', 'invisible']);
}

/**
* Check badge attribute.
*/
private function checkBadgeAttribute()
{
$this->checkDataAttribute(self::ATTR_BADGE, 'bottomright', ['bottomright', 'bottomleft', 'inline']);
}

/**
Expand Down
1 change: 1 addition & 0 deletions tests/LaravelTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ abstract class LaravelTestCase extends BaseTestCase
protected function getPackageProviders($app)
{
return [
\Arcanedev\LaravelHtml\HtmlServiceProvider::class,
\Arcanedev\NoCaptcha\NoCaptchaServiceProvider::class,
];
}
Expand Down
2 changes: 1 addition & 1 deletion tests/NoCaptchaServiceProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ public function it_can_provides()
\Arcanedev\NoCaptcha\Contracts\NoCaptcha::class,
];

$this->assertEquals($expected, $this->provider->provides());
$this->assertSame($expected, $this->provider->provides());
}
}
Loading

0 comments on commit cd5c4fe

Please sign in to comment.