Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitriy Brusenskiy committed Jan 27, 2017
1 parent 3057f99 commit b410ee8
Show file tree
Hide file tree
Showing 5 changed files with 287 additions and 0 deletions.
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#Google ReCaptcha v2.0 Yii 2.x.x extension
[![Latest Stable Version](https://poser.pugx.org/brussens/yii2-recaptcha/v/stable)](https://packagist.org/packages/brussens/yii2-recaptcha)
[![Total Downloads](https://poser.pugx.org/brussens/yii2-recaptcha/downloads)](https://packagist.org/packages/brussens/yii2-recaptcha)
[![License](https://poser.pugx.org/brussens/yii2-recaptcha/license)](https://packagist.org/packages/brussens/yii2-recaptcha)
##Install
Either run
```
php composer.phar require --prefer-dist brussens/yii2-recaptcha "*"
```

or add

```
"brussens/yii2-recaptcha": "*"
```

to the require section of your `composer.json` file.

Add to your config file:
```php
'components' => [
...
'recaptcha' => [
'class' => 'brussens\\yii2\\extensions\\recaptcha\\Component',
'siteKey' => '!!!Insert your public key here!!!',
'secretKey' => '!!!Insert your secret key here!!!'
],
...
],
```

Add in your model validation rules
```php
public function rules()
{
return [
...
['verifyCode', \brussens\yii2\extensions\recaptcha\Validator::className()],
...
];
}
```

Add in your view
```php
echo $form->field($model, 'verifyCode')->widget(\brussens\yii2\extensions\recaptcha\Widget::className());
```

If you use Pjax or multiple widgets on page
```php
echo $form->field($model, 'verifyCode')->widget(
\brussens\yii2\extensions\recaptcha\Widget::className(), [
'options' => [
'id' => 'insert-unique-widget-id'
]
]);
```
26 changes: 26 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "brussens/yii2-recaptcha",
"description": "Google ReCaptcha v2.0 Yii 2.x.x extension",
"license": "MIT",
"type": "yii2-extension",
"version":"1.0.0",
"keywords": ["yii2", "yii", "recaptcha", "google"],
"authors": [
{
"name": "Brusensky Dmitry",
"email": "brussens@nativeweb.ru",
"url": "http://nativeweb.ru"
}
],
"minimum-stability": "dev",
"require": {
"php": ">=5.4.0",
"yiisoft/yii2": "*",
"google/recaptcha": "~1.1"
},
"autoload": {
"psr-4": {
"brussens\\yii2\\extensions\\recaptcha\\": "src"
}
}
}
40 changes: 40 additions & 0 deletions src/Component.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/**
* Google ReCaptcha v 2.0 Yii 2.x.x extension component.
* Class Component
* @author Brusenskiy Dmitry <brussens@nativeweb.ru>
* @since 1.0.0
* @version 1.0.0
* @link https://github.com/brussens/yii2-recaptcha <Repostory>
* @copyright 2017 Brusenskiy Dmitry
* @license http://opensource.org/licenses/MIT MIT
* @package brussens\yii2\extensions\recaptcha
*/
namespace brussens\yii2\extensions\recaptcha;
use yii\base\InvalidConfigException;

class Component extends \yii\base\Component
{
/**
* Recaptcha site secret key.
* @var
*/
public $secretKey;
/**
* Recaptcha site public key.
* @var
*/
public $siteKey;
/**
* @throws InvalidConfigException
*/
public function init()
{
if(!$this->secretKey) {
throw new InvalidConfigException('Required `secretKey` param isn\'t set .');
}
if(!$this->siteKey) {
throw new InvalidConfigException('Required `siteKey` param isn\'t set .');
}
}
}
60 changes: 60 additions & 0 deletions src/Validator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
* Google ReCaptcha v 2.0 Yii 2.x.x extension validator.
* Class Validator
* @author Brusenskiy Dmitry <brussens@nativeweb.ru>
* @since 1.0.0
* @version 1.0.0
* @link https://github.com/brussens/yii2-recaptcha <Repostory>
* @copyright 2017 Brusenskiy Dmitry
* @license http://opensource.org/licenses/MIT MIT
* @package brussens\yii2\extensions\recaptcha
*/
namespace brussens\yii2\extensions\recaptcha;
use Yii;
use ReCaptcha\ReCaptcha;
class Validator extends \yii\validators\Validator
{
/**
* @var bool
*/
public $skipOnEmpty = false;
/**
* @inheritdoc
*/
public function init()
{
parent::init();
if (!$this->message) {
$this->message = Yii::t('yii', 'The verification code is incorrect.');
}
}
/**
* @param mixed $value
* @return array|null
*/
protected function validateValue($value)
{
$request = Yii::$app->getRequest();
$value = $request->post('g-recaptcha-response');
if(!$value) {
return [Yii::t('yii', '{attribute} cannot be blank.'), []];
}
$recaptcha = new ReCaptcha(Yii::$app->recaptcha->secretKey);
$response = $recaptcha->verify($value, Yii::$app->getRequest()->getUserIP());
return $response->isSuccess() ? null : [$this->message, []];
}
/**
* @param \yii\base\Model $model
* @param string $attribute
* @param \yii\web\View $view
* @return string
*/
public function clientValidateAttribute($model, $attribute, $view)
{
$message = Yii::t('yii', '{attribute} cannot be blank.', [
'attribute' => $model->getAttributeLabel($attribute)
]);
return "(function(messages){if(!grecaptcha.getResponse()){messages.push('{$message}');}})(messages);";
}
}
104 changes: 104 additions & 0 deletions src/Widget.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php
/**
* Google ReCaptcha v 2.0 Yii 2.x.x extension widget.
* Class Widget
* @author Brusenskiy Dmitry <brussens@nativeweb.ru>
* @since 1.0.0
* @version 1.0.0
* @link https://github.com/brussens/yii2-recaptcha <Repostory>
* @copyright 2017 Brusenskiy Dmitry
* @license http://opensource.org/licenses/MIT MIT
* @package brussens\yii2\extensions\recaptcha
*/
namespace brussens\yii2\extensions\recaptcha;
use Yii;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\widgets\InputWidget;
use yii\helpers\Json;
class Widget extends InputWidget
{
/**
* Except languages.
*/
const EXCEPT = ['zh-HK','zh-CN','zh-TW','en-GB','fr-CA','de-AT','de-CH','pt-BR','pt-PT','es-419'];
/**
* Options of JS script.
* @see https://developers.google.com/recaptcha/docs/display#js_api
* @var array
*/
public $clientOptions = [];
/**
* Flag of rendering noscript section.
* @var bool
*/
public $renderNoScript = true;
/**
* @inheritdoc
*/
public function run()
{
parent::run();
$this->registerScripts();

echo $this->hasModel() ?
Html::activeHiddenInput($this->model, $this->attribute, $this->options) :
Html::hiddenInput($this->name, $this->value, $this->options);

echo Html::tag('div', null, [
'id' => $this->options['id'] . '-recaptcha-container'
]);
if($this->renderNoScript) {
$this->renderNoScript();
}
}
/**
* Registration client scripts.
*/
protected function registerScripts()
{
$view = $this->getView();
$view->registerJsFile(
"//www.google.com/recaptcha/api.js?hl=" . $this->getLanguagePrefix(),
['position' => $view::POS_HEAD, 'async' => true, 'defer' => true]
);

$options = ArrayHelper::merge(['sitekey' => Yii::$app->recaptcha->siteKey], $this->clientOptions);
$view->registerJs(
'grecaptcha.render("' . $this->options['id'] . '-recaptcha-container", ' . Json::encode($options) . ');',
$view::POS_LOAD
);
}
/**
* Rendering noscript section.
*/
protected function renderNoScript()
{
echo Html::beginTag('noscript');
echo Html::tag('iframe', null, [
'src' => 'https://www.google.com/recaptcha/api/fallback?k=' . Yii::$app->recaptcha->siteKey,
'frameborder' => 0,
'width' => '302px',
'height' => '423px',
'scrolling' => 'no',
'border-style' => 'none'
]);
echo Html::textarea('g-recaptcha-response', null, [
'class' => 'form-control',
'style' => 'margin-top: 15px'
]);
echo Html::endTag('noscript');
}
/**
* Normalize language code.
* @return string
*/
protected function getLanguagePrefix()
{
$language = Yii::$app->language;
if(!in_array($language, self::EXCEPT) && preg_match('/[a-z]+-[A-Z0-9]+/', $language)) {
$language = explode('-', $language)[0];
}
return $language;
}
}

0 comments on commit b410ee8

Please sign in to comment.